X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/da54e1d87c054ad572b5ce20acc153e274a0b46c..refs/pull/5676/head:/resources/js/wysiwyg/utils/table-map.ts diff --git a/resources/js/wysiwyg/utils/table-map.ts b/resources/js/wysiwyg/utils/table-map.ts index 2b7eba62c..dfe21b936 100644 --- a/resources/js/wysiwyg/utils/table-map.ts +++ b/resources/js/wysiwyg/utils/table-map.ts @@ -1,6 +1,11 @@ -import {CustomTableNode} from "../nodes/custom-table"; -import {$isCustomTableCellNode, CustomTableCellNode} from "../nodes/custom-table-cell"; -import {$isTableRowNode} from "@lexical/table"; +import {$isTableCellNode, $isTableRowNode, TableCellNode, TableNode} from "@lexical/table"; + +export type CellRange = { + fromX: number; + fromY: number; + toX: number; + toY: number; +} export class TableMap { @@ -9,15 +14,15 @@ export class TableMap { // Represents an array (rows*columns in length) of cell nodes from top-left to // bottom right. Cells may repeat where merged and covering multiple spaces. - cells: CustomTableCellNode[] = []; + cells: TableCellNode[] = []; - constructor(table: CustomTableNode) { + constructor(table: TableNode) { this.buildCellMap(table); } - protected buildCellMap(table: CustomTableNode) { - const rowsAndCells: CustomTableCellNode[][] = []; - const setCell = (x: number, y: number, cell: CustomTableCellNode) => { + protected buildCellMap(table: TableNode) { + const rowsAndCells: TableCellNode[][] = []; + const setCell = (x: number, y: number, cell: TableCellNode) => { if (typeof rowsAndCells[y] === 'undefined') { rowsAndCells[y] = []; } @@ -29,7 +34,7 @@ export class TableMap { const rowNodes = table.getChildren().filter(r => $isTableRowNode(r)); for (let rowIndex = 0; rowIndex < rowNodes.length; rowIndex++) { const rowNode = rowNodes[rowIndex]; - const cellNodes = rowNode.getChildren().filter(c => $isCustomTableCellNode(c)); + const cellNodes = rowNode.getChildren().filter(c => $isTableCellNode(c)); let targetColIndex: number = 0; for (let cellIndex = 0; cellIndex < cellNodes.length; cellIndex++) { const cellNode = cellNodes[cellIndex]; @@ -53,7 +58,7 @@ export class TableMap { this.columnCount = Math.max(...rowsAndCells.map(r => r.length)); const cells = []; - let lastCell: CustomTableCellNode = rowsAndCells[0][0]; + let lastCell: TableCellNode = rowsAndCells[0][0]; for (let y = 0; y < this.rowCount; y++) { for (let x = 0; x < this.columnCount; x++) { if (!rowsAndCells[y] || !rowsAndCells[y][x]) { @@ -68,7 +73,7 @@ export class TableMap { this.cells = cells; } - public getCellAtPosition(x: number, y: number): CustomTableCellNode { + public getCellAtPosition(x: number, y: number): TableCellNode { const position = (y * this.columnCount) + x; if (position >= this.cells.length) { throw new Error(`TableMap Error: Attempted to get cell ${position+1} of ${this.cells.length}`); @@ -77,13 +82,13 @@ export class TableMap { return this.cells[position]; } - public getCellsInRange(fromX: number, fromY: number, toX: number, toY: number): CustomTableCellNode[] { - const minX = Math.max(Math.min(fromX, toX), 0); - const maxX = Math.min(Math.max(fromX, toX), this.columnCount - 1); - const minY = Math.max(Math.min(fromY, toY), 0); - const maxY = Math.min(Math.max(fromY, toY), this.rowCount - 1); + public getCellsInRange(range: CellRange): TableCellNode[] { + const minX = Math.max(Math.min(range.fromX, range.toX), 0); + const maxX = Math.min(Math.max(range.fromX, range.toX), this.columnCount - 1); + const minY = Math.max(Math.min(range.fromY, range.toY), 0); + const maxY = Math.min(Math.max(range.fromY, range.toY), this.rowCount - 1); - const cells = new Set(); + const cells = new Set(); for (let y = minY; y <= maxY; y++) { for (let x = minX; x <= maxX; x++) { @@ -93,4 +98,37 @@ export class TableMap { return [...cells.values()]; } -} + + public getCellsInColumn(columnIndex: number): TableCellNode[] { + return this.getCellsInRange({ + fromX: columnIndex, + toX: columnIndex, + fromY: 0, + toY: this.rowCount - 1, + }); + } + + public getRangeForCell(cell: TableCellNode): CellRange|null { + let range: CellRange|null = null; + const cellKey = cell.getKey(); + + for (let y = 0; y < this.rowCount; y++) { + for (let x = 0; x < this.columnCount; x++) { + const index = (y * this.columnCount) + x; + const lCell = this.cells[index]; + if (lCell.getKey() === cellKey) { + if (range === null) { + range = {fromX: x, toX: x, fromY: y, toY: y}; + } else { + range.fromX = Math.min(range.fromX, x); + range.toX = Math.max(range.toX, x); + range.fromY = Math.min(range.fromY, y); + range.toY = Math.max(range.toY, y); + } + } + } + } + + return range; + } +} \ No newline at end of file