@lexical/table 0.29.1-nightly.20250401.0 → 0.29.1-nightly.20250403.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LexicalTable.dev.js +296 -56
- package/LexicalTable.dev.mjs +293 -58
- package/LexicalTable.js.flow +30 -0
- package/LexicalTable.mjs +5 -0
- package/LexicalTable.node.mjs +5 -0
- package/LexicalTable.prod.js +1 -1
- package/LexicalTable.prod.mjs +1 -1
- package/LexicalTableUtils.d.ts +43 -4
- package/index.d.ts +1 -1
- package/package.json +4 -4
package/LexicalTable.dev.js
CHANGED
@@ -535,6 +535,10 @@ function $removeTableRowAtIndex(tableNode, indexToDelete) {
|
|
535
535
|
targetRowNode.remove();
|
536
536
|
return tableNode;
|
537
537
|
}
|
538
|
+
|
539
|
+
/**
|
540
|
+
* @deprecated This function does not support merged cells. Use {@link $insertTableRowAtSelection} or {@link $insertTableRowAtNode} instead.
|
541
|
+
*/
|
538
542
|
function $insertTableRow(tableNode, targetIndex, shouldInsertAfter = true, rowCount, table) {
|
539
543
|
const tableRows = tableNode.getChildren();
|
540
544
|
if (targetIndex >= tableRows.length || targetIndex < 0) {
|
@@ -587,7 +591,7 @@ const getHeaderState = (currentState, possibleState) => {
|
|
587
591
|
* taking into account any spans. If successful, returns the
|
588
592
|
* inserted table row node.
|
589
593
|
*/
|
590
|
-
function $
|
594
|
+
function $insertTableRowAtSelection(insertAfter = true) {
|
591
595
|
const selection = lexical.$getSelection();
|
592
596
|
if (!(lexical.$isRangeSelection(selection) || $isTableSelection(selection))) {
|
593
597
|
formatDevErrorMessage(`Expected a RangeSelection or TableSelection`);
|
@@ -596,17 +600,40 @@ function $insertTableRow__EXPERIMENTAL(insertAfter = true) {
|
|
596
600
|
const focus = selection.focus.getNode();
|
597
601
|
const [anchorCell] = $getNodeTriplet(anchor);
|
598
602
|
const [focusCell,, grid] = $getNodeTriplet(focus);
|
599
|
-
const [
|
600
|
-
const columnCount = gridMap[0].length;
|
603
|
+
const [, focusCellMap, anchorCellMap] = $computeTableMap(grid, focusCell, anchorCell);
|
601
604
|
const {
|
602
605
|
startRow: anchorStartRow
|
603
606
|
} = anchorCellMap;
|
604
607
|
const {
|
605
608
|
startRow: focusStartRow
|
606
609
|
} = focusCellMap;
|
610
|
+
if (insertAfter) {
|
611
|
+
return $insertTableRowAtNode(anchorStartRow + anchorCell.__rowSpan > focusStartRow + focusCell.__rowSpan ? anchorCell : focusCell, true);
|
612
|
+
} else {
|
613
|
+
return $insertTableRowAtNode(focusStartRow < anchorStartRow ? focusCell : anchorCell, false);
|
614
|
+
}
|
615
|
+
}
|
616
|
+
|
617
|
+
/**
|
618
|
+
* @deprecated renamed to {@link $insertTableRowAtSelection}
|
619
|
+
*/
|
620
|
+
const $insertTableRow__EXPERIMENTAL = $insertTableRowAtSelection;
|
621
|
+
|
622
|
+
/**
|
623
|
+
* Inserts a table row before or after the given cell node,
|
624
|
+
* taking into account any spans. If successful, returns the
|
625
|
+
* inserted table row node.
|
626
|
+
*/
|
627
|
+
function $insertTableRowAtNode(cellNode, insertAfter = true) {
|
628
|
+
const [,, grid] = $getNodeTriplet(cellNode);
|
629
|
+
const [gridMap, cellMap] = $computeTableMap(grid, cellNode, cellNode);
|
630
|
+
const columnCount = gridMap[0].length;
|
631
|
+
const {
|
632
|
+
startRow: cellStartRow
|
633
|
+
} = cellMap;
|
607
634
|
let insertedRow = null;
|
608
635
|
if (insertAfter) {
|
609
|
-
const insertAfterEndRow =
|
636
|
+
const insertAfterEndRow = cellStartRow + cellNode.__rowSpan - 1;
|
610
637
|
const insertAfterEndRowMap = gridMap[insertAfterEndRow];
|
611
638
|
const newRow = $createTableRowNode();
|
612
639
|
for (let i = 0; i < columnCount; i++) {
|
@@ -630,7 +657,7 @@ function $insertTableRow__EXPERIMENTAL(insertAfter = true) {
|
|
630
657
|
insertAfterEndRowNode.insertAfter(newRow);
|
631
658
|
insertedRow = newRow;
|
632
659
|
} else {
|
633
|
-
const insertBeforeStartRow =
|
660
|
+
const insertBeforeStartRow = cellStartRow;
|
634
661
|
const insertBeforeStartRowMap = gridMap[insertBeforeStartRow];
|
635
662
|
const newRow = $createTableRowNode();
|
636
663
|
for (let i = 0; i < columnCount; i++) {
|
@@ -656,6 +683,10 @@ function $insertTableRow__EXPERIMENTAL(insertAfter = true) {
|
|
656
683
|
}
|
657
684
|
return insertedRow;
|
658
685
|
}
|
686
|
+
|
687
|
+
/**
|
688
|
+
* @deprecated This function does not support merged cells. Use {@link $insertTableColumnAtSelection} or {@link $insertTableColumnAtNode} instead.
|
689
|
+
*/
|
659
690
|
function $insertTableColumn(tableNode, targetIndex, shouldInsertAfter = true, columnCount, table) {
|
660
691
|
const tableRows = tableNode.getChildren();
|
661
692
|
const tableCellsToBeInserted = [];
|
@@ -706,7 +737,7 @@ function $insertTableColumn(tableNode, targetIndex, shouldInsertAfter = true, co
|
|
706
737
|
* taking into account any spans. If successful, returns the
|
707
738
|
* first inserted cell node.
|
708
739
|
*/
|
709
|
-
function $
|
740
|
+
function $insertTableColumnAtSelection(insertAfter = true) {
|
710
741
|
const selection = lexical.$getSelection();
|
711
742
|
if (!(lexical.$isRangeSelection(selection) || $isTableSelection(selection))) {
|
712
743
|
formatDevErrorMessage(`Expected a RangeSelection or TableSelection`);
|
@@ -715,10 +746,38 @@ function $insertTableColumn__EXPERIMENTAL(insertAfter = true) {
|
|
715
746
|
const focus = selection.focus.getNode();
|
716
747
|
const [anchorCell] = $getNodeTriplet(anchor);
|
717
748
|
const [focusCell,, grid] = $getNodeTriplet(focus);
|
718
|
-
const [
|
749
|
+
const [, focusCellMap, anchorCellMap] = $computeTableMap(grid, focusCell, anchorCell);
|
750
|
+
const {
|
751
|
+
startColumn: anchorStartColumn
|
752
|
+
} = anchorCellMap;
|
753
|
+
const {
|
754
|
+
startColumn: focusStartColumn
|
755
|
+
} = focusCellMap;
|
756
|
+
if (insertAfter) {
|
757
|
+
return $insertTableColumnAtNode(anchorStartColumn + anchorCell.__colSpan > focusStartColumn + focusCell.__colSpan ? anchorCell : focusCell, true);
|
758
|
+
} else {
|
759
|
+
return $insertTableColumnAtNode(focusStartColumn < anchorStartColumn ? focusCell : anchorCell, false);
|
760
|
+
}
|
761
|
+
}
|
762
|
+
|
763
|
+
/**
|
764
|
+
* @deprecated renamed to {@link $insertTableColumnAtSelection}
|
765
|
+
*/
|
766
|
+
const $insertTableColumn__EXPERIMENTAL = $insertTableColumnAtSelection;
|
767
|
+
|
768
|
+
/**
|
769
|
+
* Inserts a column before or after the given cell node,
|
770
|
+
* taking into account any spans. If successful, returns the
|
771
|
+
* first inserted cell node.
|
772
|
+
*/
|
773
|
+
function $insertTableColumnAtNode(cellNode, insertAfter = true, shouldSetSelection = true) {
|
774
|
+
const [,, grid] = $getNodeTriplet(cellNode);
|
775
|
+
const [gridMap, cellMap] = $computeTableMap(grid, cellNode, cellNode);
|
719
776
|
const rowCount = gridMap.length;
|
720
|
-
const
|
721
|
-
|
777
|
+
const {
|
778
|
+
startColumn
|
779
|
+
} = cellMap;
|
780
|
+
const insertAfterColumn = insertAfter ? startColumn + cellNode.__colSpan - 1 : startColumn - 1;
|
722
781
|
const gridFirstChild = grid.getFirstChild();
|
723
782
|
if (!$isTableRowNode(gridFirstChild)) {
|
724
783
|
formatDevErrorMessage(`Expected firstTable child to be a row`);
|
@@ -775,7 +834,7 @@ function $insertTableColumn__EXPERIMENTAL(insertAfter = true) {
|
|
775
834
|
currentCell.setColSpan(currentCell.__colSpan + 1);
|
776
835
|
}
|
777
836
|
}
|
778
|
-
if (firstInsertedCell !== null) {
|
837
|
+
if (firstInsertedCell !== null && shouldSetSelection) {
|
779
838
|
$moveSelectionToCell(firstInsertedCell);
|
780
839
|
}
|
781
840
|
const colWidths = grid.getColWidths();
|
@@ -788,6 +847,10 @@ function $insertTableColumn__EXPERIMENTAL(insertAfter = true) {
|
|
788
847
|
}
|
789
848
|
return firstInsertedCell;
|
790
849
|
}
|
850
|
+
|
851
|
+
/**
|
852
|
+
* @deprecated This function does not support merged cells. Use {@link $deleteTableColumnAtSelection} instead.
|
853
|
+
*/
|
791
854
|
function $deleteTableColumn(tableNode, targetIndex) {
|
792
855
|
const tableRows = tableNode.getChildren();
|
793
856
|
for (let i = 0; i < tableRows.length; i++) {
|
@@ -802,7 +865,7 @@ function $deleteTableColumn(tableNode, targetIndex) {
|
|
802
865
|
}
|
803
866
|
return tableNode;
|
804
867
|
}
|
805
|
-
function $
|
868
|
+
function $deleteTableRowAtSelection() {
|
806
869
|
const selection = lexical.$getSelection();
|
807
870
|
if (!(lexical.$isRangeSelection(selection) || $isTableSelection(selection))) {
|
808
871
|
formatDevErrorMessage(`Expected a RangeSelection or TableSelection`);
|
@@ -887,7 +950,12 @@ function $deleteTableRow__EXPERIMENTAL() {
|
|
887
950
|
$moveSelectionToCell(cell);
|
888
951
|
}
|
889
952
|
}
|
890
|
-
|
953
|
+
|
954
|
+
/**
|
955
|
+
* @deprecated renamed to {@link $deleteTableRowAtSelection}
|
956
|
+
*/
|
957
|
+
const $deleteTableRow__EXPERIMENTAL = $deleteTableRowAtSelection;
|
958
|
+
function $deleteTableColumnAtSelection() {
|
891
959
|
const selection = lexical.$getSelection();
|
892
960
|
if (!(lexical.$isRangeSelection(selection) || $isTableSelection(selection))) {
|
893
961
|
formatDevErrorMessage(`Expected a RangeSelection or TableSelection`);
|
@@ -961,6 +1029,11 @@ function $deleteTableColumn__EXPERIMENTAL() {
|
|
961
1029
|
grid.setColWidths(newColWidths);
|
962
1030
|
}
|
963
1031
|
}
|
1032
|
+
|
1033
|
+
/**
|
1034
|
+
* @deprecated renamed to {@link $deleteTableColumnAtSelection}
|
1035
|
+
*/
|
1036
|
+
const $deleteTableColumn__EXPERIMENTAL = $deleteTableColumnAtSelection;
|
964
1037
|
function $moveSelectionToCell(cell) {
|
965
1038
|
const firstDescendant = cell.getFirstDescendant();
|
966
1039
|
if (firstDescendant == null) {
|
@@ -977,13 +1050,122 @@ function $insertFirst(parent, node) {
|
|
977
1050
|
parent.append(node);
|
978
1051
|
}
|
979
1052
|
}
|
1053
|
+
function $mergeCells(cellNodes) {
|
1054
|
+
if (cellNodes.length === 0) {
|
1055
|
+
return null;
|
1056
|
+
}
|
1057
|
+
|
1058
|
+
// Find the table node
|
1059
|
+
const tableNode = $getTableNodeFromLexicalNodeOrThrow(cellNodes[0]);
|
1060
|
+
const [gridMap] = $computeTableMapSkipCellCheck(tableNode, null, null);
|
1061
|
+
|
1062
|
+
// Find the boundaries of the selection including merged cells
|
1063
|
+
let minRow = Infinity;
|
1064
|
+
let maxRow = -Infinity;
|
1065
|
+
let minCol = Infinity;
|
1066
|
+
let maxCol = -Infinity;
|
1067
|
+
|
1068
|
+
// First pass: find the actual boundaries considering merged cells
|
1069
|
+
const processedCells = new Set();
|
1070
|
+
for (const row of gridMap) {
|
1071
|
+
for (const mapCell of row) {
|
1072
|
+
if (!mapCell || !mapCell.cell) {
|
1073
|
+
continue;
|
1074
|
+
}
|
1075
|
+
const cellKey = mapCell.cell.getKey();
|
1076
|
+
if (processedCells.has(cellKey)) {
|
1077
|
+
continue;
|
1078
|
+
}
|
1079
|
+
if (cellNodes.some(cell => cell.is(mapCell.cell))) {
|
1080
|
+
processedCells.add(cellKey);
|
1081
|
+
// Get the actual position of this cell in the grid
|
1082
|
+
const cellStartRow = mapCell.startRow;
|
1083
|
+
const cellStartCol = mapCell.startColumn;
|
1084
|
+
const cellRowSpan = mapCell.cell.__rowSpan || 1;
|
1085
|
+
const cellColSpan = mapCell.cell.__colSpan || 1;
|
1086
|
+
|
1087
|
+
// Update boundaries considering the cell's actual position and span
|
1088
|
+
minRow = Math.min(minRow, cellStartRow);
|
1089
|
+
maxRow = Math.max(maxRow, cellStartRow + cellRowSpan - 1);
|
1090
|
+
minCol = Math.min(minCol, cellStartCol);
|
1091
|
+
maxCol = Math.max(maxCol, cellStartCol + cellColSpan - 1);
|
1092
|
+
}
|
1093
|
+
}
|
1094
|
+
}
|
1095
|
+
|
1096
|
+
// Validate boundaries
|
1097
|
+
if (minRow === Infinity || minCol === Infinity) {
|
1098
|
+
return null;
|
1099
|
+
}
|
1100
|
+
|
1101
|
+
// The total span of the merged cell
|
1102
|
+
const totalRowSpan = maxRow - minRow + 1;
|
1103
|
+
const totalColSpan = maxCol - minCol + 1;
|
1104
|
+
|
1105
|
+
// Use the top-left cell as the target cell
|
1106
|
+
const targetCellMap = gridMap[minRow][minCol];
|
1107
|
+
if (!targetCellMap.cell) {
|
1108
|
+
return null;
|
1109
|
+
}
|
1110
|
+
const targetCell = targetCellMap.cell;
|
1111
|
+
|
1112
|
+
// Set the spans for the target cell
|
1113
|
+
targetCell.setColSpan(totalColSpan);
|
1114
|
+
targetCell.setRowSpan(totalRowSpan);
|
1115
|
+
|
1116
|
+
// Move content from other cells to the target cell
|
1117
|
+
const seenCells = new Set([targetCell.getKey()]);
|
1118
|
+
|
1119
|
+
// Second pass: merge content and remove other cells
|
1120
|
+
for (let row = minRow; row <= maxRow; row++) {
|
1121
|
+
for (let col = minCol; col <= maxCol; col++) {
|
1122
|
+
const mapCell = gridMap[row][col];
|
1123
|
+
if (!mapCell.cell) {
|
1124
|
+
continue;
|
1125
|
+
}
|
1126
|
+
const currentCell = mapCell.cell;
|
1127
|
+
const key = currentCell.getKey();
|
1128
|
+
if (!seenCells.has(key)) {
|
1129
|
+
seenCells.add(key);
|
1130
|
+
const isEmpty = $cellContainsEmptyParagraph(currentCell);
|
1131
|
+
if (!isEmpty) {
|
1132
|
+
targetCell.append(...currentCell.getChildren());
|
1133
|
+
}
|
1134
|
+
currentCell.remove();
|
1135
|
+
}
|
1136
|
+
}
|
1137
|
+
}
|
1138
|
+
|
1139
|
+
// Ensure target cell has content
|
1140
|
+
if (targetCell.getChildrenSize() === 0) {
|
1141
|
+
targetCell.append(lexical.$createParagraphNode());
|
1142
|
+
}
|
1143
|
+
return targetCell;
|
1144
|
+
}
|
1145
|
+
function $cellContainsEmptyParagraph(cell) {
|
1146
|
+
if (cell.getChildrenSize() !== 1) {
|
1147
|
+
return false;
|
1148
|
+
}
|
1149
|
+
const firstChild = cell.getFirstChildOrThrow();
|
1150
|
+
if (!lexical.$isParagraphNode(firstChild) || !firstChild.isEmpty()) {
|
1151
|
+
return false;
|
1152
|
+
}
|
1153
|
+
return true;
|
1154
|
+
}
|
980
1155
|
function $unmergeCell() {
|
981
1156
|
const selection = lexical.$getSelection();
|
982
1157
|
if (!(lexical.$isRangeSelection(selection) || $isTableSelection(selection))) {
|
983
1158
|
formatDevErrorMessage(`Expected a RangeSelection or TableSelection`);
|
984
1159
|
}
|
985
1160
|
const anchor = selection.anchor.getNode();
|
986
|
-
const
|
1161
|
+
const cellNode = utils.$findMatchingParent(anchor, $isTableCellNode);
|
1162
|
+
if (!$isTableCellNode(cellNode)) {
|
1163
|
+
formatDevErrorMessage(`Expected to find a parent TableCellNode`);
|
1164
|
+
}
|
1165
|
+
return $unmergeCellNode(cellNode);
|
1166
|
+
}
|
1167
|
+
function $unmergeCellNode(cellNode) {
|
1168
|
+
const [cell, row, grid] = $getNodeTriplet(cellNode);
|
987
1169
|
const colSpan = cell.__colSpan;
|
988
1170
|
const rowSpan = cell.__rowSpan;
|
989
1171
|
if (colSpan === 1 && rowSpan === 1) {
|
@@ -2285,62 +2467,115 @@ function applyTableHandlers(tableNode, element, editor, hasTabHandler) {
|
|
2285
2467
|
if (nodes.length !== 1 || !$isTableNode(nodes[0]) || !isSelectionInsideOfGrid || anchorAndFocus === null) {
|
2286
2468
|
return false;
|
2287
2469
|
}
|
2288
|
-
const [anchor] = anchorAndFocus;
|
2289
|
-
const
|
2290
|
-
const
|
2291
|
-
|
2292
|
-
const newRowCount = newGrid.getChildrenSize();
|
2293
|
-
const gridCellNode = utils.$findMatchingParent(anchor.getNode(), n => $isTableCellNode(n));
|
2294
|
-
const gridRowNode = gridCellNode && utils.$findMatchingParent(gridCellNode, n => $isTableRowNode(n));
|
2295
|
-
const gridNode = gridRowNode && utils.$findMatchingParent(gridRowNode, n => $isTableNode(n));
|
2296
|
-
if (!$isTableCellNode(gridCellNode) || !$isTableRowNode(gridRowNode) || !$isTableNode(gridNode)) {
|
2470
|
+
const [anchor, focus] = anchorAndFocus;
|
2471
|
+
const [anchorCellNode, anchorRowNode, gridNode] = $getNodeTriplet(anchor);
|
2472
|
+
const focusCellNode = utils.$findMatchingParent(focus.getNode(), n => $isTableCellNode(n));
|
2473
|
+
if (!$isTableCellNode(anchorCellNode) || !$isTableCellNode(focusCellNode) || !$isTableRowNode(anchorRowNode) || !$isTableNode(gridNode)) {
|
2297
2474
|
return false;
|
2298
2475
|
}
|
2299
|
-
const
|
2300
|
-
const
|
2301
|
-
const
|
2302
|
-
const
|
2303
|
-
const
|
2304
|
-
|
2305
|
-
|
2306
|
-
|
2307
|
-
|
2308
|
-
let
|
2309
|
-
|
2310
|
-
|
2311
|
-
|
2312
|
-
|
2313
|
-
|
2314
|
-
const
|
2315
|
-
|
2316
|
-
|
2476
|
+
const templateGrid = nodes[0];
|
2477
|
+
const [initialGridMap, anchorCellMap, focusCellMap] = $computeTableMap(gridNode, anchorCellNode, focusCellNode);
|
2478
|
+
const [templateGridMap] = $computeTableMapSkipCellCheck(templateGrid, null, null);
|
2479
|
+
const initialRowCount = initialGridMap.length;
|
2480
|
+
const initialColCount = initialRowCount > 0 ? initialGridMap[0].length : 0;
|
2481
|
+
|
2482
|
+
// If we have a range selection, we'll fit the template grid into the
|
2483
|
+
// table, growing the table if necessary.
|
2484
|
+
let startRow = anchorCellMap.startRow;
|
2485
|
+
let startCol = anchorCellMap.startColumn;
|
2486
|
+
let affectedRowCount = templateGridMap.length;
|
2487
|
+
let affectedColCount = affectedRowCount > 0 ? templateGridMap[0].length : 0;
|
2488
|
+
if (isTableSelection) {
|
2489
|
+
// If we have a table selection, we'll only modify the cells within
|
2490
|
+
// the selection boundary.
|
2491
|
+
const selectionBoundary = $computeTableCellRectBoundary(initialGridMap, anchorCellMap, focusCellMap);
|
2492
|
+
const selectionRowCount = selectionBoundary.maxRow - selectionBoundary.minRow + 1;
|
2493
|
+
const selectionColCount = selectionBoundary.maxColumn - selectionBoundary.minColumn + 1;
|
2494
|
+
startRow = selectionBoundary.minRow;
|
2495
|
+
startCol = selectionBoundary.minColumn;
|
2496
|
+
affectedRowCount = Math.min(affectedRowCount, selectionRowCount);
|
2497
|
+
affectedColCount = Math.min(affectedColCount, selectionColCount);
|
2498
|
+
}
|
2499
|
+
|
2500
|
+
// Step 1: Unmerge all merged cells within the affected area
|
2501
|
+
let didPerformMergeOperations = false;
|
2502
|
+
const lastRowForUnmerge = Math.min(initialRowCount, startRow + affectedRowCount) - 1;
|
2503
|
+
const lastColForUnmerge = Math.min(initialColCount, startCol + affectedColCount) - 1;
|
2504
|
+
const unmergedKeys = new Set();
|
2505
|
+
for (let row = startRow; row <= lastRowForUnmerge; row++) {
|
2506
|
+
for (let col = startCol; col <= lastColForUnmerge; col++) {
|
2507
|
+
const cellMap = initialGridMap[row][col];
|
2508
|
+
if (unmergedKeys.has(cellMap.cell.getKey())) {
|
2509
|
+
continue; // cell was a merged cell that was already handled
|
2510
|
+
}
|
2511
|
+
if (cellMap.cell.__rowSpan === 1 && cellMap.cell.__colSpan === 1) {
|
2512
|
+
continue; // cell is not a merged cell
|
2513
|
+
}
|
2514
|
+
$unmergeCellNode(cellMap.cell);
|
2515
|
+
unmergedKeys.add(cellMap.cell.getKey());
|
2516
|
+
didPerformMergeOperations = true;
|
2317
2517
|
}
|
2318
|
-
|
2319
|
-
|
2320
|
-
|
2321
|
-
|
2322
|
-
|
2323
|
-
|
2324
|
-
|
2518
|
+
}
|
2519
|
+
let [interimGridMap] = $computeTableMapSkipCellCheck(gridNode.getWritable(), null, null);
|
2520
|
+
|
2521
|
+
// Step 2: Expand current table (if needed)
|
2522
|
+
const rowsToInsert = affectedRowCount - initialRowCount + startRow;
|
2523
|
+
for (let i = 0; i < rowsToInsert; i++) {
|
2524
|
+
const cellMap = interimGridMap[initialRowCount - 1][0];
|
2525
|
+
$insertTableRowAtNode(cellMap.cell);
|
2526
|
+
}
|
2527
|
+
const colsToInsert = affectedColCount - initialColCount + startCol;
|
2528
|
+
for (let i = 0; i < colsToInsert; i++) {
|
2529
|
+
const cellMap = interimGridMap[0][initialColCount - 1];
|
2530
|
+
$insertTableColumnAtNode(cellMap.cell, true, false);
|
2531
|
+
}
|
2532
|
+
[interimGridMap] = $computeTableMapSkipCellCheck(gridNode.getWritable(), null, null);
|
2533
|
+
|
2534
|
+
// Step 3: Merge cells and set cell content, to match template grid
|
2535
|
+
for (let row = startRow; row < startRow + affectedRowCount; row++) {
|
2536
|
+
for (let col = startCol; col < startCol + affectedColCount; col++) {
|
2537
|
+
const templateRow = row - startRow;
|
2538
|
+
const templateCol = col - startCol;
|
2539
|
+
const templateCellMap = templateGridMap[templateRow][templateCol];
|
2540
|
+
if (templateCellMap.startRow !== templateRow || templateCellMap.startColumn !== templateCol) {
|
2541
|
+
continue; // cell is a merged cell that was already handled
|
2325
2542
|
}
|
2326
|
-
const
|
2327
|
-
if (
|
2328
|
-
|
2543
|
+
const templateCell = templateCellMap.cell;
|
2544
|
+
if (templateCell.__rowSpan !== 1 || templateCell.__colSpan !== 1) {
|
2545
|
+
const cellsToMerge = [];
|
2546
|
+
const lastRowForMerge = Math.min(row + templateCell.__rowSpan, startRow + affectedRowCount) - 1;
|
2547
|
+
const lastColForMerge = Math.min(col + templateCell.__colSpan, startCol + affectedColCount) - 1;
|
2548
|
+
for (let r = row; r <= lastRowForMerge; r++) {
|
2549
|
+
for (let c = col; c <= lastColForMerge; c++) {
|
2550
|
+
const cellMap = interimGridMap[r][c];
|
2551
|
+
cellsToMerge.push(cellMap.cell);
|
2552
|
+
}
|
2553
|
+
}
|
2554
|
+
$mergeCells(cellsToMerge);
|
2555
|
+
didPerformMergeOperations = true;
|
2329
2556
|
}
|
2330
|
-
const
|
2331
|
-
|
2557
|
+
const {
|
2558
|
+
cell
|
2559
|
+
} = interimGridMap[row][col];
|
2560
|
+
const originalChildren = cell.getChildren();
|
2561
|
+
templateCell.getChildren().forEach(child => {
|
2332
2562
|
if (lexical.$isTextNode(child)) {
|
2333
2563
|
const paragraphNode = lexical.$createParagraphNode();
|
2334
2564
|
paragraphNode.append(child);
|
2335
|
-
|
2565
|
+
cell.append(child);
|
2336
2566
|
} else {
|
2337
|
-
|
2567
|
+
cell.append(child);
|
2338
2568
|
}
|
2339
2569
|
});
|
2340
2570
|
originalChildren.forEach(n => n.remove());
|
2341
|
-
newColumnIdx++;
|
2342
2571
|
}
|
2343
|
-
|
2572
|
+
}
|
2573
|
+
if (isTableSelection && didPerformMergeOperations) {
|
2574
|
+
// reset the table selection in case the anchor or focus cell was
|
2575
|
+
// removed via merge operations
|
2576
|
+
const [finalGridMap] = $computeTableMapSkipCellCheck(gridNode.getWritable(), null, null);
|
2577
|
+
const newAnchorCellMap = finalGridMap[anchorCellMap.startRow][anchorCellMap.startColumn];
|
2578
|
+
newAnchorCellMap.cell.selectEnd();
|
2344
2579
|
}
|
2345
2580
|
return true;
|
2346
2581
|
}, lexical.COMMAND_PRIORITY_CRITICAL));
|
@@ -3900,7 +4135,9 @@ exports.$createTableRowNode = $createTableRowNode;
|
|
3900
4135
|
exports.$createTableSelection = $createTableSelection;
|
3901
4136
|
exports.$createTableSelectionFrom = $createTableSelectionFrom;
|
3902
4137
|
exports.$deleteTableColumn = $deleteTableColumn;
|
4138
|
+
exports.$deleteTableColumnAtSelection = $deleteTableColumnAtSelection;
|
3903
4139
|
exports.$deleteTableColumn__EXPERIMENTAL = $deleteTableColumn__EXPERIMENTAL;
|
4140
|
+
exports.$deleteTableRowAtSelection = $deleteTableRowAtSelection;
|
3904
4141
|
exports.$deleteTableRow__EXPERIMENTAL = $deleteTableRow__EXPERIMENTAL;
|
3905
4142
|
exports.$findCellNode = $findCellNode;
|
3906
4143
|
exports.$findTableNode = $findTableNode;
|
@@ -3914,14 +4151,17 @@ exports.$getTableNodeFromLexicalNodeOrThrow = $getTableNodeFromLexicalNodeOrThro
|
|
3914
4151
|
exports.$getTableRowIndexFromTableCellNode = $getTableRowIndexFromTableCellNode;
|
3915
4152
|
exports.$getTableRowNodeFromTableCellNodeOrThrow = $getTableRowNodeFromTableCellNodeOrThrow;
|
3916
4153
|
exports.$insertTableColumn = $insertTableColumn;
|
4154
|
+
exports.$insertTableColumnAtSelection = $insertTableColumnAtSelection;
|
3917
4155
|
exports.$insertTableColumn__EXPERIMENTAL = $insertTableColumn__EXPERIMENTAL;
|
3918
4156
|
exports.$insertTableRow = $insertTableRow;
|
4157
|
+
exports.$insertTableRowAtSelection = $insertTableRowAtSelection;
|
3919
4158
|
exports.$insertTableRow__EXPERIMENTAL = $insertTableRow__EXPERIMENTAL;
|
3920
4159
|
exports.$isScrollableTablesActive = $isScrollableTablesActive;
|
3921
4160
|
exports.$isTableCellNode = $isTableCellNode;
|
3922
4161
|
exports.$isTableNode = $isTableNode;
|
3923
4162
|
exports.$isTableRowNode = $isTableRowNode;
|
3924
4163
|
exports.$isTableSelection = $isTableSelection;
|
4164
|
+
exports.$mergeCells = $mergeCells;
|
3925
4165
|
exports.$removeTableRowAtIndex = $removeTableRowAtIndex;
|
3926
4166
|
exports.$unmergeCell = $unmergeCell;
|
3927
4167
|
exports.INSERT_TABLE_COMMAND = INSERT_TABLE_COMMAND;
|