@lexical/table 0.26.0 → 0.27.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.
@@ -91,6 +91,7 @@ class TableCellNode extends lexical.ElementNode {
91
91
  this.__headerState = headerState;
92
92
  this.__width = width;
93
93
  this.__backgroundColor = null;
94
+ this.__verticalAlign = undefined;
94
95
  }
95
96
  createDOM(config) {
96
97
  const element = document.createElement(this.getTag());
@@ -306,6 +307,20 @@ function $isTableCellNode(node) {
306
307
 
307
308
  const INSERT_TABLE_COMMAND = lexical.createCommand('INSERT_TABLE_COMMAND');
308
309
 
310
+ /**
311
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
312
+ *
313
+ * This source code is licensed under the MIT license found in the
314
+ * LICENSE file in the root directory of this source tree.
315
+ *
316
+ */
317
+
318
+ // Do not require this module directly! Use normal `invariant` calls.
319
+
320
+ function formatDevErrorMessage(message) {
321
+ throw new Error(message);
322
+ }
323
+
309
324
  /**
310
325
  * Copyright (c) Meta Platforms, Inc. and affiliates.
311
326
  *
@@ -423,14 +438,6 @@ const documentMode = CAN_USE_DOM && 'documentMode' in document ? document.docume
423
438
  const IS_FIREFOX = CAN_USE_DOM && /^(?!.*Seamonkey)(?=.*Firefox).*/i.test(navigator.userAgent);
424
439
  CAN_USE_DOM && 'InputEvent' in window && !documentMode ? 'getTargetRanges' in new window.InputEvent('input') : false;
425
440
 
426
- /**
427
- * Copyright (c) Meta Platforms, Inc. and affiliates.
428
- *
429
- * This source code is licensed under the MIT license found in the
430
- * LICENSE file in the root directory of this source tree.
431
- *
432
- */
433
-
434
441
  function $createTableNodeWithDimensions(rowCount, columnCount, includeHeaders = true) {
435
442
  const tableNode = $createTableNode();
436
443
  for (let iRow = 0; iRow < rowCount; iRow++) {
@@ -528,7 +535,7 @@ function $insertTableRow(tableNode, targetIndex, shouldInsertAfter = true, rowCo
528
535
  for (let c = 0; c < tableColumnCount; c++) {
529
536
  const tableCellFromTargetRow = tableRowCells[c];
530
537
  if (!$isTableCellNode(tableCellFromTargetRow)) {
531
- throw Error(`Expected table cell`);
538
+ formatDevErrorMessage(`Expected table cell`);
532
539
  }
533
540
  const {
534
541
  above,
@@ -569,7 +576,7 @@ const getHeaderState = (currentState, possibleState) => {
569
576
  function $insertTableRow__EXPERIMENTAL(insertAfter = true) {
570
577
  const selection = lexical.$getSelection();
571
578
  if (!(lexical.$isRangeSelection(selection) || $isTableSelection(selection))) {
572
- throw Error(`Expected a RangeSelection or TableSelection`);
579
+ formatDevErrorMessage(`Expected a RangeSelection or TableSelection`);
573
580
  }
574
581
  const anchor = selection.anchor.getNode();
575
582
  const focus = selection.focus.getNode();
@@ -604,7 +611,7 @@ function $insertTableRow__EXPERIMENTAL(insertAfter = true) {
604
611
  }
605
612
  const insertAfterEndRowNode = grid.getChildAtIndex(insertAfterEndRow);
606
613
  if (!$isTableRowNode(insertAfterEndRowNode)) {
607
- throw Error(`insertAfterEndRow is not a TableRowNode`);
614
+ formatDevErrorMessage(`insertAfterEndRow is not a TableRowNode`);
608
615
  }
609
616
  insertAfterEndRowNode.insertAfter(newRow);
610
617
  insertedRow = newRow;
@@ -628,7 +635,7 @@ function $insertTableRow__EXPERIMENTAL(insertAfter = true) {
628
635
  }
629
636
  const insertBeforeStartRowNode = grid.getChildAtIndex(insertBeforeStartRow);
630
637
  if (!$isTableRowNode(insertBeforeStartRowNode)) {
631
- throw Error(`insertBeforeStartRow is not a TableRowNode`);
638
+ formatDevErrorMessage(`insertBeforeStartRow is not a TableRowNode`);
632
639
  }
633
640
  insertBeforeStartRowNode.insertBefore(newRow);
634
641
  insertedRow = newRow;
@@ -648,7 +655,7 @@ function $insertTableColumn(tableNode, targetIndex, shouldInsertAfter = true, co
648
655
  }
649
656
  const targetCell = tableRowChildren[targetIndex];
650
657
  if (!$isTableCellNode(targetCell)) {
651
- throw Error(`Expected table cell`);
658
+ formatDevErrorMessage(`Expected table cell`);
652
659
  }
653
660
  const {
654
661
  left,
@@ -688,7 +695,7 @@ function $insertTableColumn(tableNode, targetIndex, shouldInsertAfter = true, co
688
695
  function $insertTableColumn__EXPERIMENTAL(insertAfter = true) {
689
696
  const selection = lexical.$getSelection();
690
697
  if (!(lexical.$isRangeSelection(selection) || $isTableSelection(selection))) {
691
- throw Error(`Expected a RangeSelection or TableSelection`);
698
+ formatDevErrorMessage(`Expected a RangeSelection or TableSelection`);
692
699
  }
693
700
  const anchor = selection.anchor.getNode();
694
701
  const focus = selection.focus.getNode();
@@ -700,7 +707,7 @@ function $insertTableColumn__EXPERIMENTAL(insertAfter = true) {
700
707
  const insertAfterColumn = insertAfter ? startColumn + focusCell.__colSpan - 1 : startColumn - 1;
701
708
  const gridFirstChild = grid.getFirstChild();
702
709
  if (!$isTableRowNode(gridFirstChild)) {
703
- throw Error(`Expected firstTable child to be a row`);
710
+ formatDevErrorMessage(`Expected firstTable child to be a row`);
704
711
  }
705
712
  let firstInsertedCell = null;
706
713
  function $createTableCellNodeForInsertTableColumn(headerState = TableCellHeaderStates.NO_STATUS) {
@@ -715,7 +722,7 @@ function $insertTableColumn__EXPERIMENTAL(insertAfter = true) {
715
722
  if (i !== 0) {
716
723
  const currentRow = loopRow.getNextSibling();
717
724
  if (!$isTableRowNode(currentRow)) {
718
- throw Error(`Expected row nextSibling to be a row`);
725
+ formatDevErrorMessage(`Expected row nextSibling to be a row`);
719
726
  }
720
727
  loopRow = currentRow;
721
728
  }
@@ -784,7 +791,7 @@ function $deleteTableColumn(tableNode, targetIndex) {
784
791
  function $deleteTableRow__EXPERIMENTAL() {
785
792
  const selection = lexical.$getSelection();
786
793
  if (!(lexical.$isRangeSelection(selection) || $isTableSelection(selection))) {
787
- throw Error(`Expected a RangeSelection or TableSelection`);
794
+ formatDevErrorMessage(`Expected a RangeSelection or TableSelection`);
788
795
  }
789
796
  const [anchor, focus] = selection.isBackward() ? [selection.focus.getNode(), selection.anchor.getNode()] : [selection.anchor.getNode(), selection.focus.getNode()];
790
797
  const [anchorCell,, grid] = $getNodeTriplet(anchor);
@@ -826,7 +833,7 @@ function $deleteTableRow__EXPERIMENTAL() {
826
833
  if (cellStartRow >= anchorStartRow && cellStartRow + cell.__rowSpan - 1 > focusEndRow) {
827
834
  cell.setRowSpan(cell.__rowSpan - (focusEndRow - cellStartRow + 1));
828
835
  if (!(nextRowNode !== null)) {
829
- throw Error(`Expected nextRowNode not to be null`);
836
+ formatDevErrorMessage(`Expected nextRowNode not to be null`);
830
837
  }
831
838
  let insertAfterCell = null;
832
839
  for (let columnIndex = 0; columnIndex < column; columnIndex++) {
@@ -849,7 +856,7 @@ function $deleteTableRow__EXPERIMENTAL() {
849
856
  }
850
857
  const rowNode = grid.getChildAtIndex(row);
851
858
  if (!$isTableRowNode(rowNode)) {
852
- throw Error(`Expected TableNode childAtIndex(${String(row)}) to be RowNode`);
859
+ formatDevErrorMessage(`Expected TableNode childAtIndex(${String(row)}) to be RowNode`);
853
860
  }
854
861
  rowNode.remove();
855
862
  }
@@ -869,7 +876,7 @@ function $deleteTableRow__EXPERIMENTAL() {
869
876
  function $deleteTableColumn__EXPERIMENTAL() {
870
877
  const selection = lexical.$getSelection();
871
878
  if (!(lexical.$isRangeSelection(selection) || $isTableSelection(selection))) {
872
- throw Error(`Expected a RangeSelection or TableSelection`);
879
+ formatDevErrorMessage(`Expected a RangeSelection or TableSelection`);
873
880
  }
874
881
  const anchor = selection.anchor.getNode();
875
882
  const focus = selection.focus.getNode();
@@ -959,7 +966,7 @@ function $insertFirst(parent, node) {
959
966
  function $unmergeCell() {
960
967
  const selection = lexical.$getSelection();
961
968
  if (!(lexical.$isRangeSelection(selection) || $isTableSelection(selection))) {
962
- throw Error(`Expected a RangeSelection or TableSelection`);
969
+ formatDevErrorMessage(`Expected a RangeSelection or TableSelection`);
963
970
  }
964
971
  const anchor = selection.anchor.getNode();
965
972
  const [cell, row, grid] = $getNodeTriplet(anchor);
@@ -1009,7 +1016,7 @@ function $unmergeCell() {
1009
1016
  const currentRowMap = map[currentRow];
1010
1017
  currentRowNode = (currentRowNode || row).getNextSibling();
1011
1018
  if (!$isTableRowNode(currentRowNode)) {
1012
- throw Error(`Expected row next sibling to be a row`);
1019
+ formatDevErrorMessage(`Expected row next sibling to be a row`);
1013
1020
  }
1014
1021
  let insertAfterCell = null;
1015
1022
  for (let column = 0; column < startColumn; column++) {
@@ -1038,10 +1045,10 @@ function $unmergeCell() {
1038
1045
  function $computeTableMap(tableNode, cellA, cellB) {
1039
1046
  const [tableMap, cellAValue, cellBValue] = $computeTableMapSkipCellCheck(tableNode, cellA, cellB);
1040
1047
  if (!(cellAValue !== null)) {
1041
- throw Error(`Anchor not found in Table`);
1048
+ formatDevErrorMessage(`Anchor not found in Table`);
1042
1049
  }
1043
1050
  if (!(cellBValue !== null)) {
1044
- throw Error(`Focus not found in Table`);
1051
+ formatDevErrorMessage(`Focus not found in Table`);
1045
1052
  }
1046
1053
  return [tableMap, cellAValue, cellBValue];
1047
1054
  }
@@ -1060,12 +1067,12 @@ function $computeTableMapSkipCellCheck(tableNode, cellA, cellB) {
1060
1067
  for (let rowIdx = 0; rowIdx < gridChildren.length; rowIdx++) {
1061
1068
  const row = gridChildren[rowIdx];
1062
1069
  if (!$isTableRowNode(row)) {
1063
- throw Error(`Expected TableNode children to be TableRowNode`);
1070
+ formatDevErrorMessage(`Expected TableNode children to be TableRowNode`);
1064
1071
  }
1065
1072
  const startMapRow = getMapRow(rowIdx);
1066
1073
  for (let cell = row.getFirstChild(), colIdx = 0; cell != null; cell = cell.getNextSibling()) {
1067
1074
  if (!$isTableCellNode(cell)) {
1068
- throw Error(`Expected TableRowNode children to be TableCellNode`);
1075
+ formatDevErrorMessage(`Expected TableRowNode children to be TableCellNode`);
1069
1076
  } // Skip past any columns that were merged from a higher row
1070
1077
  while (startMapRow[colIdx] !== undefined) {
1071
1078
  colIdx++;
@@ -1112,23 +1119,23 @@ function $getNodeTriplet(source) {
1112
1119
  } else if ('__type' in source) {
1113
1120
  const cell_ = utils.$findMatchingParent(source, $isTableCellNode);
1114
1121
  if (!$isTableCellNode(cell_)) {
1115
- throw Error(`Expected to find a parent TableCellNode`);
1122
+ formatDevErrorMessage(`Expected to find a parent TableCellNode`);
1116
1123
  }
1117
1124
  cell = cell_;
1118
1125
  } else {
1119
1126
  const cell_ = utils.$findMatchingParent(source.getNode(), $isTableCellNode);
1120
1127
  if (!$isTableCellNode(cell_)) {
1121
- throw Error(`Expected to find a parent TableCellNode`);
1128
+ formatDevErrorMessage(`Expected to find a parent TableCellNode`);
1122
1129
  }
1123
1130
  cell = cell_;
1124
1131
  }
1125
1132
  const row = cell.getParent();
1126
1133
  if (!$isTableRowNode(row)) {
1127
- throw Error(`Expected TableCellNode to have a parent TableRowNode`);
1134
+ formatDevErrorMessage(`Expected TableCellNode to have a parent TableRowNode`);
1128
1135
  }
1129
1136
  const grid = row.getParent();
1130
1137
  if (!$isTableNode(grid)) {
1131
- throw Error(`Expected TableRowNode to have a parent TableNode`);
1138
+ formatDevErrorMessage(`Expected TableRowNode to have a parent TableNode`);
1132
1139
  }
1133
1140
  return [cell, row, grid];
1134
1141
  }
@@ -1259,34 +1266,26 @@ function $getTableCellNodeRect(tableCellNode) {
1259
1266
  return null;
1260
1267
  }
1261
1268
 
1262
- /**
1263
- * Copyright (c) Meta Platforms, Inc. and affiliates.
1264
- *
1265
- * This source code is licensed under the MIT license found in the
1266
- * LICENSE file in the root directory of this source tree.
1267
- *
1268
- */
1269
-
1270
1269
  function $getCellNodes(tableSelection) {
1271
1270
  const [[anchorNode, anchorCell, anchorRow, anchorTable], [focusNode, focusCell, focusRow, focusTable]] = ['anchor', 'focus'].map(k => {
1272
1271
  const node = tableSelection[k].getNode();
1273
1272
  const cellNode = utils.$findMatchingParent(node, $isTableCellNode);
1274
1273
  if (!$isTableCellNode(cellNode)) {
1275
- throw Error(`Expected TableSelection ${k} to be (or a child of) TableCellNode, got key ${node.getKey()} of type ${node.getType()}`);
1274
+ formatDevErrorMessage(`Expected TableSelection ${k} to be (or a child of) TableCellNode, got key ${node.getKey()} of type ${node.getType()}`);
1276
1275
  }
1277
1276
  const rowNode = cellNode.getParent();
1278
1277
  if (!$isTableRowNode(rowNode)) {
1279
- throw Error(`Expected TableSelection ${k} cell parent to be a TableRowNode`);
1278
+ formatDevErrorMessage(`Expected TableSelection ${k} cell parent to be a TableRowNode`);
1280
1279
  }
1281
1280
  const tableNode = rowNode.getParent();
1282
1281
  if (!$isTableNode(tableNode)) {
1283
- throw Error(`Expected TableSelection ${k} row parent to be a TableNode`);
1282
+ formatDevErrorMessage(`Expected TableSelection ${k} row parent to be a TableNode`);
1284
1283
  }
1285
1284
  return [node, cellNode, rowNode, tableNode];
1286
1285
  });
1287
1286
  // TODO: nested tables may violate this
1288
1287
  if (!anchorTable.is(focusTable)) {
1289
- throw Error(`Expected TableSelection anchor and focus to be in the same table`);
1288
+ formatDevErrorMessage(`Expected TableSelection anchor and focus to be in the same table`);
1290
1289
  }
1291
1290
  return {
1292
1291
  anchorCell,
@@ -1387,7 +1386,7 @@ class TableSelection {
1387
1386
  insertNodes(nodes) {
1388
1387
  const focusNode = this.focus.getNode();
1389
1388
  if (!lexical.$isElementNode(focusNode)) {
1390
- throw Error(`Expected TableSelection focus to be an ElementNode`);
1389
+ formatDevErrorMessage(`Expected TableSelection focus to be an ElementNode`);
1391
1390
  }
1392
1391
  const selection = lexical.$normalizeSelection__EXPERIMENTAL(focusNode.select(0, focusNode.getChildrenSize()));
1393
1392
  selection.insertNodes(nodes);
@@ -1401,11 +1400,11 @@ class TableSelection {
1401
1400
  } = $getCellNodes(this);
1402
1401
  const anchorCellNodeRect = $getTableCellNodeRect(anchorCell);
1403
1402
  if (!(anchorCellNodeRect !== null)) {
1404
- throw Error(`getCellRect: expected to find AnchorNode`);
1403
+ formatDevErrorMessage(`getCellRect: expected to find AnchorNode`);
1405
1404
  }
1406
1405
  const focusCellNodeRect = $getTableCellNodeRect(focusCell);
1407
1406
  if (!(focusCellNodeRect !== null)) {
1408
- throw Error(`getCellRect: expected to find focusCellNode`);
1407
+ formatDevErrorMessage(`getCellRect: expected to find focusCellNode`);
1409
1408
  }
1410
1409
  const startX = Math.min(anchorCellNodeRect.columnIndex, focusCellNodeRect.columnIndex);
1411
1410
  const stopX = Math.max(anchorCellNodeRect.columnIndex + anchorCellNodeRect.colSpan - 1, focusCellNodeRect.columnIndex + focusCellNodeRect.colSpan - 1);
@@ -1437,14 +1436,14 @@ class TableSelection {
1437
1436
  // focus is on higher Grid level than anchor
1438
1437
  const gridParent = tableNode.getParent();
1439
1438
  if (!(gridParent != null)) {
1440
- throw Error(`Expected gridParent to have a parent`);
1439
+ formatDevErrorMessage(`Expected gridParent to have a parent`);
1441
1440
  }
1442
1441
  this.set(this.tableKey, gridParent.getKey(), focusCell.getKey());
1443
1442
  } else {
1444
1443
  // anchor is on higher Grid level than focus
1445
1444
  const focusCellParent = focusCellGrid.getParent();
1446
1445
  if (!(focusCellParent != null)) {
1447
- throw Error(`Expected focusCellParent to have a parent`);
1446
+ formatDevErrorMessage(`Expected focusCellParent to have a parent`);
1448
1447
  }
1449
1448
  this.set(this.tableKey, focusCell.getKey(), focusCellParent.getKey());
1450
1449
  }
@@ -1474,7 +1473,7 @@ class TableSelection {
1474
1473
  } = map[i][j];
1475
1474
  const currentRow = cell.getParent();
1476
1475
  if (!$isTableRowNode(currentRow)) {
1477
- throw Error(`Expected TableCellNode parent to be a TableRowNode`);
1476
+ formatDevErrorMessage(`Expected TableCellNode parent to be a TableRowNode`);
1478
1477
  }
1479
1478
  if (currentRow !== lastRow) {
1480
1479
  nodeMap.set(currentRow.getKey(), currentRow);
@@ -1524,13 +1523,13 @@ function $createTableSelectionFrom(tableNode, anchorCell, focusCell) {
1524
1523
  const focusCellKey = focusCell.getKey();
1525
1524
  {
1526
1525
  if (!tableNode.isAttached()) {
1527
- throw Error(`$createTableSelectionFrom: tableNode ${tableNodeKey} is not attached`);
1526
+ formatDevErrorMessage(`$createTableSelectionFrom: tableNode ${tableNodeKey} is not attached`);
1528
1527
  }
1529
1528
  if (!tableNode.is($findTableNode(anchorCell))) {
1530
- throw Error(`$createTableSelectionFrom: anchorCell ${anchorCellKey} is not in table ${tableNodeKey}`);
1529
+ formatDevErrorMessage(`$createTableSelectionFrom: anchorCell ${anchorCellKey} is not in table ${tableNodeKey}`);
1531
1530
  }
1532
1531
  if (!tableNode.is($findTableNode(focusCell))) {
1533
- throw Error(`$createTableSelectionFrom: focusCell ${focusCellKey} is not in table ${tableNodeKey}`);
1532
+ formatDevErrorMessage(`$createTableSelectionFrom: focusCell ${focusCellKey} is not in table ${tableNodeKey}`);
1534
1533
  } // TODO: Check for rectangular grid
1535
1534
  }
1536
1535
  const prevSelection = lexical.$getSelection();
@@ -1556,22 +1555,14 @@ function $visitRecursively(node, $visit) {
1556
1555
  }
1557
1556
  }
1558
1557
 
1559
- /**
1560
- * Copyright (c) Meta Platforms, Inc. and affiliates.
1561
- *
1562
- * This source code is licensed under the MIT license found in the
1563
- * LICENSE file in the root directory of this source tree.
1564
- *
1565
- */
1566
-
1567
1558
  function $getTableAndElementByKey(tableNodeKey, editor = lexical.$getEditor()) {
1568
1559
  const tableNode = lexical.$getNodeByKey(tableNodeKey);
1569
1560
  if (!$isTableNode(tableNode)) {
1570
- throw Error(`TableObserver: Expected tableNodeKey ${tableNodeKey} to be a TableNode`);
1561
+ formatDevErrorMessage(`TableObserver: Expected tableNodeKey ${tableNodeKey} to be a TableNode`);
1571
1562
  }
1572
1563
  const tableElement = getTableElement(tableNode, editor.getElementByKey(tableNodeKey));
1573
1564
  if (!(tableElement !== null)) {
1574
- throw Error(`TableObserver: Expected to find TableElement in DOM for key ${tableNodeKey}`);
1565
+ formatDevErrorMessage(`TableObserver: Expected to find TableElement in DOM for key ${tableNodeKey}`);
1575
1566
  }
1576
1567
  return {
1577
1568
  tableElement,
@@ -1703,7 +1694,7 @@ class TableObserver {
1703
1694
  $updateTableTableSelection(selection) {
1704
1695
  if (selection !== null) {
1705
1696
  if (!(selection.tableKey === this.tableNodeKey)) {
1706
- throw Error(`TableObserver.$updateTableTableSelection: selection.tableKey !== this.tableNodeKey ('${selection.tableKey}' !== '${this.tableNodeKey}')`);
1697
+ formatDevErrorMessage(`TableObserver.$updateTableTableSelection: selection.tableKey !== this.tableNodeKey ('${selection.tableKey}' !== '${this.tableNodeKey}')`);
1707
1698
  }
1708
1699
  const editor = this.editor;
1709
1700
  this.tableSelection = selection;
@@ -1810,7 +1801,7 @@ class TableObserver {
1810
1801
  $getAnchorTableCellOrThrow() {
1811
1802
  const anchorTableCell = this.$getAnchorTableCell();
1812
1803
  if (!(anchorTableCell !== null)) {
1813
- throw Error(`TableObserver anchorTableCell is null`);
1804
+ formatDevErrorMessage(`TableObserver anchorTableCell is null`);
1814
1805
  }
1815
1806
  return anchorTableCell;
1816
1807
  }
@@ -1820,7 +1811,7 @@ class TableObserver {
1820
1811
  $getFocusTableCellOrThrow() {
1821
1812
  const focusTableCell = this.$getFocusTableCell();
1822
1813
  if (!(focusTableCell !== null)) {
1823
- throw Error(`TableObserver focusTableCell is null`);
1814
+ formatDevErrorMessage(`TableObserver focusTableCell is null`);
1824
1815
  }
1825
1816
  return focusTableCell;
1826
1817
  }
@@ -1842,14 +1833,14 @@ class TableObserver {
1842
1833
  $formatCells(type) {
1843
1834
  const selection = lexical.$getSelection();
1844
1835
  if (!$isTableSelection(selection)) {
1845
- throw Error(`Expected Table selection`);
1836
+ formatDevErrorMessage(`Expected Table selection`);
1846
1837
  }
1847
1838
  const formatSelection = lexical.$createRangeSelection();
1848
1839
  const anchor = formatSelection.anchor;
1849
1840
  const focus = formatSelection.focus;
1850
1841
  const cellNodes = selection.getNodes().filter($isTableCellNode);
1851
1842
  if (!(cellNodes.length > 0)) {
1852
- throw Error(`No table cells present`);
1843
+ formatDevErrorMessage(`No table cells present`);
1853
1844
  }
1854
1845
  const paragraph = cellNodes[0].getFirstChild();
1855
1846
  const alignFormatWith = lexical.$isParagraphNode(paragraph) ? paragraph.getFormatFlags(type, null) : null;
@@ -1871,7 +1862,7 @@ class TableObserver {
1871
1862
  }
1872
1863
  const selection = lexical.$getSelection();
1873
1864
  if (!$isTableSelection(selection)) {
1874
- throw Error(`Expected TableSelection`);
1865
+ formatDevErrorMessage(`Expected TableSelection`);
1875
1866
  }
1876
1867
  const selectedNodes = selection.getNodes().filter($isTableCellNode);
1877
1868
  if (selectedNodes.length === this.table.columns * this.table.rows) {
@@ -1904,14 +1895,6 @@ class TableObserver {
1904
1895
  }
1905
1896
  }
1906
1897
 
1907
- /**
1908
- * Copyright (c) Meta Platforms, Inc. and affiliates.
1909
- *
1910
- * This source code is licensed under the MIT license found in the
1911
- * LICENSE file in the root directory of this source tree.
1912
- *
1913
- */
1914
-
1915
1898
  const LEXICAL_ELEMENT_KEY = '__lexicalTableSelection';
1916
1899
  const isMouseDownOnEvent = event => {
1917
1900
  return (event.buttons & 1) === 1;
@@ -1922,7 +1905,7 @@ function getTableElement(tableNode, dom) {
1922
1905
  }
1923
1906
  const element = dom.nodeName === 'TABLE' ? dom : tableNode.getDOMSlot(dom).element;
1924
1907
  if (!(element.nodeName === 'TABLE')) {
1925
- throw Error(`getTableElement: Expecting table in as DOM node for TableNode, not ${dom.nodeName}`);
1908
+ formatDevErrorMessage(`getTableElement: Expecting table in as DOM node for TableNode, not ${dom.nodeName}`);
1926
1909
  }
1927
1910
  return element;
1928
1911
  }
@@ -1946,7 +1929,7 @@ function applyTableHandlers(tableNode, element, editor, hasTabHandler) {
1946
1929
  const rootElement = editor.getRootElement();
1947
1930
  const editorWindow = getEditorWindow(editor);
1948
1931
  if (!(rootElement !== null && editorWindow !== null)) {
1949
- throw Error(`applyTableHandlers: editor has no root element set`);
1932
+ formatDevErrorMessage(`applyTableHandlers: editor has no root element set`);
1950
1933
  }
1951
1934
  const tableObserver = new TableObserver(editor, tableNode.getKey());
1952
1935
  const tableElement = getTableElement(tableNode, element);
@@ -2478,7 +2461,7 @@ function detatchTableObserverFromTableElement(tableElement, tableObserver) {
2478
2461
  }
2479
2462
  function attachTableObserverToTableElement(tableElement, tableObserver) {
2480
2463
  if (!(getTableObserverFromTableElement(tableElement) === null)) {
2481
- throw Error(`tableElement already has an attached TableObserver`);
2464
+ formatDevErrorMessage(`tableElement already has an attached TableObserver`);
2482
2465
  }
2483
2466
  tableElement[LEXICAL_ELEMENT_KEY] = tableObserver;
2484
2467
  }
@@ -2627,7 +2610,7 @@ function $selectAdjacentCell(tableCellNode, direction) {
2627
2610
  }
2628
2611
  const parentRow = utils.$findMatchingParent(tableCellNode, $isTableRowNode);
2629
2612
  if (!(parentRow !== null)) {
2630
- throw Error(`selectAdjacentCell: Cell not in table row`);
2613
+ formatDevErrorMessage(`selectAdjacentCell: Cell not in table row`);
2631
2614
  }
2632
2615
  for (let nextRow = parentRow[siblingMethod](); $isTableRowNode(nextRow); nextRow = nextRow[siblingMethod]()) {
2633
2616
  const child = nextRow[childMethod]();
@@ -2637,7 +2620,7 @@ function $selectAdjacentCell(tableCellNode, direction) {
2637
2620
  }
2638
2621
  const parentTable = utils.$findMatchingParent(parentRow, $isTableNode);
2639
2622
  if (!(parentTable !== null)) {
2640
- throw Error(`selectAdjacentCell: Row not in table`);
2623
+ formatDevErrorMessage(`selectAdjacentCell: Row not in table`);
2641
2624
  }
2642
2625
  return direction === 'next' ? parentTable.selectNext() : parentTable.selectPrevious();
2643
2626
  }
@@ -2698,7 +2681,7 @@ function getCorner(rect, cellValue) {
2698
2681
  function getCornerOrThrow(rect, cellValue) {
2699
2682
  const corner = getCorner(rect, cellValue);
2700
2683
  if (!(corner !== null)) {
2701
- throw Error(`getCornerOrThrow: cell ${cellValue.cell.getKey()} is not at a corner of rect`);
2684
+ formatDevErrorMessage(`getCornerOrThrow: cell ${cellValue.cell.getKey()} is not at a corner of rect`);
2702
2685
  }
2703
2686
  return corner;
2704
2687
  }
@@ -2709,12 +2692,12 @@ function cellAtCornerOrThrow(tableMap, rect, [colName, rowName]) {
2709
2692
  const rowNum = rect[rowName];
2710
2693
  const rowMap = tableMap[rowNum];
2711
2694
  if (!(rowMap !== undefined)) {
2712
- throw Error(`cellAtCornerOrThrow: ${rowName} = ${String(rowNum)} missing in tableMap`);
2695
+ formatDevErrorMessage(`cellAtCornerOrThrow: ${rowName} = ${String(rowNum)} missing in tableMap`);
2713
2696
  }
2714
2697
  const colNum = rect[colName];
2715
2698
  const cell = rowMap[colNum];
2716
2699
  if (!(cell !== undefined)) {
2717
- throw Error(`cellAtCornerOrThrow: ${colName} = ${String(colNum)} missing in tableMap`);
2700
+ formatDevErrorMessage(`cellAtCornerOrThrow: ${colName} = ${String(colNum)} missing in tableMap`);
2718
2701
  }
2719
2702
  return cell;
2720
2703
  }
@@ -2777,6 +2760,9 @@ function $adjustFocusInDirection(tableObserver, tableMap, anchorCellValue, focus
2777
2760
  }
2778
2761
  function $isSelectionInTable(selection, tableNode) {
2779
2762
  if (lexical.$isRangeSelection(selection) || $isTableSelection(selection)) {
2763
+ // TODO this should probably return false if there's an unrelated
2764
+ // shadow root between the node and the table (e.g. another table,
2765
+ // collapsible, etc.)
2780
2766
  const isAnchorInside = tableNode.isParentOf(selection.anchor.getNode());
2781
2767
  const isFocusInside = tableNode.isParentOf(selection.focus.getNode());
2782
2768
  return isAnchorInside && isFocusInside;
@@ -2806,7 +2792,7 @@ function $addHighlightToDOM(editor, cell) {
2806
2792
  const editorThemeClasses = editor._config.theme;
2807
2793
  const node = lexical.$getNearestNodeFromDOMNode(element);
2808
2794
  if (!$isTableCellNode(node)) {
2809
- throw Error(`Expected to find LexicalNode from Table Cell DOMNode`);
2795
+ formatDevErrorMessage(`Expected to find LexicalNode from Table Cell DOMNode`);
2810
2796
  }
2811
2797
  utils.addClassNamesToElement(element, editorThemeClasses.tableCellSelected);
2812
2798
  }
@@ -2814,7 +2800,7 @@ function $removeHighlightFromDOM(editor, cell) {
2814
2800
  const element = cell.elem;
2815
2801
  const node = lexical.$getNearestNodeFromDOMNode(element);
2816
2802
  if (!$isTableCellNode(node)) {
2817
- throw Error(`Expected to find LexicalNode from Table Cell DOMNode`);
2803
+ formatDevErrorMessage(`Expected to find LexicalNode from Table Cell DOMNode`);
2818
2804
  }
2819
2805
  const editorThemeClasses = editor._config.theme;
2820
2806
  utils.removeClassNamesFromElement(element, editorThemeClasses.tableCellSelected);
@@ -2840,6 +2826,85 @@ function $getBlockParentIfFirstNode(node) {
2840
2826
  }
2841
2827
  return null;
2842
2828
  }
2829
+ function $handleHorizontalArrowKeyRangeSelection(editor, event, selection, alter, isBackward, tableNode, tableObserver) {
2830
+ const initialFocus = lexical.$caretFromPoint(selection.focus, isBackward ? 'previous' : 'next');
2831
+ if (lexical.$isExtendableTextPointCaret(initialFocus)) {
2832
+ return false;
2833
+ }
2834
+ let lastCaret = initialFocus;
2835
+ // TableCellNode is the only shadow root we are interested in piercing so
2836
+ // we find the last internal caret and then check its parent
2837
+ for (const nextCaret of lexical.$extendCaretToRange(initialFocus).iterNodeCarets('shadowRoot')) {
2838
+ if (!(lexical.$isSiblingCaret(nextCaret) && lexical.$isElementNode(nextCaret.origin))) {
2839
+ return false;
2840
+ }
2841
+ lastCaret = nextCaret;
2842
+ }
2843
+ const lastCaretParent = lastCaret.getParentAtCaret();
2844
+ if (!$isTableCellNode(lastCaretParent)) {
2845
+ return false;
2846
+ }
2847
+ const anchorCell = lastCaretParent;
2848
+ const focusCaret = $findNextTableCell(lexical.$getSiblingCaret(anchorCell, lastCaret.direction));
2849
+ const anchorCellTable = utils.$findMatchingParent(anchorCell, $isTableNode);
2850
+ if (!(anchorCellTable && anchorCellTable.is(tableNode))) {
2851
+ return false;
2852
+ }
2853
+ const anchorCellDOM = editor.getElementByKey(anchorCell.getKey());
2854
+ const anchorDOMCell = getDOMCellFromTarget(anchorCellDOM);
2855
+ if (!anchorCellDOM || !anchorDOMCell) {
2856
+ return false;
2857
+ }
2858
+ const anchorCellTableElement = $getElementForTableNode(editor, anchorCellTable);
2859
+ tableObserver.table = anchorCellTableElement;
2860
+ if (!focusCaret) {
2861
+ if (alter === 'extend') {
2862
+ // extend the selection from a range inside the cell to a table selection of the cell
2863
+ tableObserver.$setAnchorCellForSelection(anchorDOMCell);
2864
+ tableObserver.$setFocusCellForSelection(anchorDOMCell, true);
2865
+ } else {
2866
+ // exit the table
2867
+ const outerFocusCaret = $getTableExitCaret(lexical.$getSiblingCaret(anchorCellTable, initialFocus.direction));
2868
+ lexical.$setPointFromCaret(selection.anchor, outerFocusCaret);
2869
+ lexical.$setPointFromCaret(selection.focus, outerFocusCaret);
2870
+ }
2871
+ } else if (alter === 'extend') {
2872
+ const focusDOMCell = getDOMCellFromTarget(editor.getElementByKey(focusCaret.origin.getKey()));
2873
+ if (!focusDOMCell) {
2874
+ return false;
2875
+ }
2876
+ tableObserver.$setAnchorCellForSelection(anchorDOMCell);
2877
+ tableObserver.$setFocusCellForSelection(focusDOMCell, true);
2878
+ } else {
2879
+ // alter === 'move'
2880
+ const innerFocusCaret = lexical.$normalizeCaret(focusCaret);
2881
+ lexical.$setPointFromCaret(selection.anchor, innerFocusCaret);
2882
+ lexical.$setPointFromCaret(selection.focus, innerFocusCaret);
2883
+ }
2884
+ stopEvent(event);
2885
+ return true;
2886
+ }
2887
+ function $getTableExitCaret(initialCaret) {
2888
+ const adjacent = lexical.$getAdjacentChildCaret(initialCaret);
2889
+ return lexical.$isChildCaret(adjacent) ? lexical.$normalizeCaret(adjacent) : initialCaret;
2890
+ }
2891
+ function $findNextTableCell(initialCaret) {
2892
+ for (const nextCaret of lexical.$extendCaretToRange(initialCaret).iterNodeCarets('root')) {
2893
+ const {
2894
+ origin
2895
+ } = nextCaret;
2896
+ if ($isTableCellNode(origin)) {
2897
+ // not sure why ts isn't narrowing here (even if the guard is on nextCaret.origin)
2898
+ // but returning a new caret is fine
2899
+ if (lexical.$isChildCaret(nextCaret)) {
2900
+ return lexical.$getChildCaret(origin, initialCaret.direction);
2901
+ }
2902
+ } else if (!$isTableRowNode(origin)) {
2903
+ break;
2904
+ }
2905
+ }
2906
+ return null;
2907
+ }
2843
2908
  function $handleArrowKey(editor, event, direction, tableNode, tableObserver) {
2844
2909
  if ((direction === 'up' || direction === 'down') && isTypeaheadMenuInView(editor)) {
2845
2910
  return false;
@@ -2957,77 +3022,67 @@ function $handleArrowKey(editor, event, direction, tableNode, tableObserver) {
2957
3022
  }
2958
3023
  return false;
2959
3024
  }
2960
- if (lexical.$isRangeSelection(selection) && selection.isCollapsed()) {
2961
- const {
2962
- anchor,
2963
- focus
2964
- } = selection;
2965
- const anchorCellNode = utils.$findMatchingParent(anchor.getNode(), $isTableCellNode);
2966
- const focusCellNode = utils.$findMatchingParent(focus.getNode(), $isTableCellNode);
2967
- if (!$isTableCellNode(anchorCellNode) || !anchorCellNode.is(focusCellNode)) {
2968
- return false;
2969
- }
2970
- const anchorCellTable = $findTableNode(anchorCellNode);
2971
- if (anchorCellTable !== tableNode && anchorCellTable != null) {
2972
- const anchorCellTableElement = getTableElement(anchorCellTable, editor.getElementByKey(anchorCellTable.getKey()));
2973
- if (anchorCellTableElement != null) {
2974
- tableObserver.table = getTable(anchorCellTable, anchorCellTableElement);
2975
- return $handleArrowKey(editor, event, direction, anchorCellTable, tableObserver);
2976
- }
2977
- }
3025
+ if (lexical.$isRangeSelection(selection)) {
2978
3026
  if (direction === 'backward' || direction === 'forward') {
2979
- const anchorType = anchor.type;
2980
- const anchorOffset = anchor.offset;
2981
- const anchorNode = anchor.getNode();
2982
- if (!anchorNode) {
3027
+ const alter = event.shiftKey ? 'extend' : 'move';
3028
+ return $handleHorizontalArrowKeyRangeSelection(editor, event, selection, alter, direction === 'backward', tableNode, tableObserver);
3029
+ }
3030
+ if (selection.isCollapsed()) {
3031
+ const {
3032
+ anchor,
3033
+ focus
3034
+ } = selection;
3035
+ const anchorCellNode = utils.$findMatchingParent(anchor.getNode(), $isTableCellNode);
3036
+ const focusCellNode = utils.$findMatchingParent(focus.getNode(), $isTableCellNode);
3037
+ if (!$isTableCellNode(anchorCellNode) || !anchorCellNode.is(focusCellNode)) {
2983
3038
  return false;
2984
3039
  }
2985
- const selectedNodes = selection.getNodes();
2986
- if (selectedNodes.length === 1 && lexical.$isDecoratorNode(selectedNodes[0])) {
3040
+ const anchorCellTable = $findTableNode(anchorCellNode);
3041
+ if (anchorCellTable !== tableNode && anchorCellTable != null) {
3042
+ const anchorCellTableElement = getTableElement(anchorCellTable, editor.getElementByKey(anchorCellTable.getKey()));
3043
+ if (anchorCellTableElement != null) {
3044
+ tableObserver.table = getTable(anchorCellTable, anchorCellTableElement);
3045
+ return $handleArrowKey(editor, event, direction, anchorCellTable, tableObserver);
3046
+ }
3047
+ }
3048
+ const anchorCellDom = editor.getElementByKey(anchorCellNode.__key);
3049
+ const anchorDOM = editor.getElementByKey(anchor.key);
3050
+ if (anchorDOM == null || anchorCellDom == null) {
2987
3051
  return false;
2988
3052
  }
2989
- if (isExitingTableAnchor(anchorType, anchorOffset, anchorNode, direction)) {
2990
- return $handleTableExit(event, anchorNode, anchorCellNode, tableNode, direction);
3053
+ let edgeSelectionRect;
3054
+ if (anchor.type === 'element') {
3055
+ edgeSelectionRect = anchorDOM.getBoundingClientRect();
3056
+ } else {
3057
+ const domSelection = lexical.getDOMSelection(getEditorWindow(editor));
3058
+ if (domSelection === null || domSelection.rangeCount === 0) {
3059
+ return false;
3060
+ }
3061
+ const range = domSelection.getRangeAt(0);
3062
+ edgeSelectionRect = range.getBoundingClientRect();
2991
3063
  }
2992
- return false;
2993
- }
2994
- const anchorCellDom = editor.getElementByKey(anchorCellNode.__key);
2995
- const anchorDOM = editor.getElementByKey(anchor.key);
2996
- if (anchorDOM == null || anchorCellDom == null) {
2997
- return false;
2998
- }
2999
- let edgeSelectionRect;
3000
- if (anchor.type === 'element') {
3001
- edgeSelectionRect = anchorDOM.getBoundingClientRect();
3002
- } else {
3003
- const domSelection = lexical.getDOMSelection(getEditorWindow(editor));
3004
- if (domSelection === null || domSelection.rangeCount === 0) {
3064
+ const edgeChild = direction === 'up' ? anchorCellNode.getFirstChild() : anchorCellNode.getLastChild();
3065
+ if (edgeChild == null) {
3005
3066
  return false;
3006
3067
  }
3007
- const range = domSelection.getRangeAt(0);
3008
- edgeSelectionRect = range.getBoundingClientRect();
3009
- }
3010
- const edgeChild = direction === 'up' ? anchorCellNode.getFirstChild() : anchorCellNode.getLastChild();
3011
- if (edgeChild == null) {
3012
- return false;
3013
- }
3014
- const edgeChildDOM = editor.getElementByKey(edgeChild.__key);
3015
- if (edgeChildDOM == null) {
3016
- return false;
3017
- }
3018
- const edgeRect = edgeChildDOM.getBoundingClientRect();
3019
- const isExiting = direction === 'up' ? edgeRect.top > edgeSelectionRect.top - edgeSelectionRect.height : edgeSelectionRect.bottom + edgeSelectionRect.height > edgeRect.bottom;
3020
- if (isExiting) {
3021
- stopEvent(event);
3022
- const cords = tableNode.getCordsFromCellNode(anchorCellNode, tableObserver.table);
3023
- if (event.shiftKey) {
3024
- const cell = tableNode.getDOMCellFromCordsOrThrow(cords.x, cords.y, tableObserver.table);
3025
- tableObserver.$setAnchorCellForSelection(cell);
3026
- tableObserver.$setFocusCellForSelection(cell, true);
3027
- } else {
3028
- return selectTableNodeInDirection(tableObserver, tableNode, cords.x, cords.y, direction);
3068
+ const edgeChildDOM = editor.getElementByKey(edgeChild.__key);
3069
+ if (edgeChildDOM == null) {
3070
+ return false;
3071
+ }
3072
+ const edgeRect = edgeChildDOM.getBoundingClientRect();
3073
+ const isExiting = direction === 'up' ? edgeRect.top > edgeSelectionRect.top - edgeSelectionRect.height : edgeSelectionRect.bottom + edgeSelectionRect.height > edgeRect.bottom;
3074
+ if (isExiting) {
3075
+ stopEvent(event);
3076
+ const cords = tableNode.getCordsFromCellNode(anchorCellNode, tableObserver.table);
3077
+ if (event.shiftKey) {
3078
+ const cell = tableNode.getDOMCellFromCordsOrThrow(cords.x, cords.y, tableObserver.table);
3079
+ tableObserver.$setAnchorCellForSelection(cell);
3080
+ tableObserver.$setFocusCellForSelection(cell, true);
3081
+ } else {
3082
+ return selectTableNodeInDirection(tableObserver, tableNode, cords.x, cords.y, direction);
3083
+ }
3084
+ return true;
3029
3085
  }
3030
- return true;
3031
3086
  }
3032
3087
  } else if ($isTableSelection(selection)) {
3033
3088
  const {
@@ -3038,7 +3093,7 @@ function $handleArrowKey(editor, event, direction, tableNode, tableObserver) {
3038
3093
  const focusCellNode = utils.$findMatchingParent(focus.getNode(), $isTableCellNode);
3039
3094
  const [tableNodeFromSelection] = selection.getNodes();
3040
3095
  if (!$isTableNode(tableNodeFromSelection)) {
3041
- throw Error(`$handleArrowKey: TableSelection.getNodes()[0] expected to be TableNode`);
3096
+ formatDevErrorMessage(`$handleArrowKey: TableSelection.getNodes()[0] expected to be TableNode`);
3042
3097
  }
3043
3098
  const tableElement = getTableElement(tableNodeFromSelection, editor.getElementByKey(tableNodeFromSelection.getKey()));
3044
3099
  if (!$isTableCellNode(anchorCellNode) || !$isTableCellNode(focusCellNode) || !$isTableNode(tableNodeFromSelection) || tableElement == null) {
@@ -3074,54 +3129,6 @@ function isTypeaheadMenuInView(editor) {
3074
3129
  }
3075
3130
  return root.hasAttribute('aria-controls') && root.getAttribute('aria-controls') === 'typeahead-menu';
3076
3131
  }
3077
- function isExitingTableAnchor(type, offset, anchorNode, direction) {
3078
- return isExitingTableElementAnchor(type, anchorNode, direction) || $isExitingTableTextAnchor(type, offset, anchorNode, direction);
3079
- }
3080
- function isExitingTableElementAnchor(type, anchorNode, direction) {
3081
- return type === 'element' && (direction === 'backward' ? anchorNode.getPreviousSibling() === null : anchorNode.getNextSibling() === null);
3082
- }
3083
- function $isExitingTableTextAnchor(type, offset, anchorNode, direction) {
3084
- const parentNode = utils.$findMatchingParent(anchorNode, n => lexical.$isElementNode(n) && !n.isInline());
3085
- if (!parentNode) {
3086
- return false;
3087
- }
3088
- const hasValidOffset = direction === 'backward' ? offset === 0 : offset === anchorNode.getTextContentSize();
3089
- return type === 'text' && hasValidOffset && (direction === 'backward' ? parentNode.getPreviousSibling() === null : parentNode.getNextSibling() === null);
3090
- }
3091
- function $handleTableExit(event, anchorNode, anchorCellNode, tableNode, direction) {
3092
- const [tableMap, cellValue] = $computeTableMap(tableNode, anchorCellNode, anchorCellNode);
3093
- if (!isExitingCell(tableMap, cellValue, direction)) {
3094
- return false;
3095
- }
3096
- const toNode = $getExitingToNode(anchorNode, direction, tableNode);
3097
- if (!toNode || $isTableNode(toNode)) {
3098
- return false;
3099
- }
3100
- stopEvent(event);
3101
- if (direction === 'backward') {
3102
- toNode.selectEnd();
3103
- } else {
3104
- toNode.selectStart();
3105
- }
3106
- return true;
3107
- }
3108
- function isExitingCell(tableMap, cellValue, direction) {
3109
- const firstCell = tableMap[0][0];
3110
- const lastCell = tableMap[tableMap.length - 1][tableMap[0].length - 1];
3111
- const {
3112
- startColumn,
3113
- startRow
3114
- } = cellValue;
3115
- return direction === 'backward' ? startColumn === firstCell.startColumn && startRow === firstCell.startRow : startColumn === lastCell.startColumn && startRow === lastCell.startRow;
3116
- }
3117
- function $getExitingToNode(anchorNode, direction, tableNode) {
3118
- const parentNode = utils.$findMatchingParent(anchorNode, n => lexical.$isElementNode(n) && !n.isInline());
3119
- if (!parentNode) {
3120
- return undefined;
3121
- }
3122
- const anchorSibling = direction === 'backward' ? parentNode.getPreviousSibling() : parentNode.getNextSibling();
3123
- return anchorSibling && $isTableNode(anchorSibling) ? anchorSibling : direction === 'backward' ? tableNode.getPreviousSibling() : tableNode.getNextSibling();
3124
- }
3125
3132
  function $insertParagraphAtTableEdge(edgePosition, tableNode, children) {
3126
3133
  const paragraphNode = lexical.$createParagraphNode();
3127
3134
  if (edgePosition === 'first') {
@@ -3190,14 +3197,6 @@ function $getNearestTableCellInTableFromDOMNode(tableNode, startingDOM, editorSt
3190
3197
  return $findParentTableCellNodeInTable(tableNode, lexical.$getNearestNodeFromDOMNode(startingDOM, editorState));
3191
3198
  }
3192
3199
 
3193
- /**
3194
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3195
- *
3196
- * This source code is licensed under the MIT license found in the
3197
- * LICENSE file in the root directory of this source tree.
3198
- *
3199
- */
3200
-
3201
3200
  function updateColgroup(dom, config, colCount, colWidths) {
3202
3201
  const colGroup = dom.querySelector('colgroup');
3203
3202
  if (!colGroup) {
@@ -3334,7 +3333,7 @@ class TableNode extends lexical.ElementNode {
3334
3333
  getDOMSlot(element) {
3335
3334
  const tableElement = element.nodeName !== 'TABLE' && element.querySelector('table') || element;
3336
3335
  if (!(tableElement.nodeName === 'TABLE')) {
3337
- throw Error(`TableNode.getDOMSlot: createDOM() did not return a table`);
3336
+ formatDevErrorMessage(`TableNode.getDOMSlot: createDOM() did not return a table`);
3338
3337
  }
3339
3338
  return super.getDOMSlot(tableElement).withAfter(tableElement.querySelector('colgroup'));
3340
3339
  }
@@ -3584,7 +3583,7 @@ class TableNode extends lexical.ElementNode {
3584
3583
  function $getElementForTableNode(editor, tableNode) {
3585
3584
  const tableElement = editor.getElementByKey(tableNode.getKey());
3586
3585
  if (!(tableElement !== null)) {
3587
- throw Error(`$getElementForTableNode: Table Element Not Found`);
3586
+ formatDevErrorMessage(`$getElementForTableNode: Table Element Not Found`);
3588
3587
  }
3589
3588
  return getTable(tableNode, tableElement);
3590
3589
  }
@@ -3624,14 +3623,6 @@ function $isTableNode(node) {
3624
3623
  return node instanceof TableNode;
3625
3624
  }
3626
3625
 
3627
- /**
3628
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3629
- *
3630
- * This source code is licensed under the MIT license found in the
3631
- * LICENSE file in the root directory of this source tree.
3632
- *
3633
- */
3634
-
3635
3626
  function $insertTableCommandListener({
3636
3627
  rows,
3637
3628
  columns,
@@ -3687,7 +3678,7 @@ function $tableTransform(node) {
3687
3678
  continue;
3688
3679
  }
3689
3680
  if (!$isTableRowNode(rowNode)) {
3690
- throw Error(`TablePlugin: Expecting all children of TableNode to be TableRowNode, found ${rowNode.constructor.name} (type ${rowNode.getType()})`);
3681
+ formatDevErrorMessage(`TablePlugin: Expecting all children of TableNode to be TableRowNode, found ${rowNode.constructor.name} (type ${rowNode.getType()})`);
3691
3682
  }
3692
3683
  const rowLength = gridMap[i].reduce((acc, cell) => cell ? 1 + acc : acc, 0);
3693
3684
  if (rowLength === maxRowLength) {
@@ -3740,14 +3731,14 @@ function registerTableCellUnmergeTransform(editor) {
3740
3731
  const columnsCount = gridMap[0].length;
3741
3732
  let row = gridNode.getFirstChild();
3742
3733
  if (!$isTableRowNode(row)) {
3743
- throw Error(`Expected TableNode first child to be a RowNode`);
3734
+ formatDevErrorMessage(`Expected TableNode first child to be a RowNode`);
3744
3735
  }
3745
3736
  const unmerged = [];
3746
3737
  for (let i = 0; i < rowsCount; i++) {
3747
3738
  if (i !== 0) {
3748
3739
  row = row.getNextSibling();
3749
3740
  if (!$isTableRowNode(row)) {
3750
- throw Error(`Expected TableNode first child to be a RowNode`);
3741
+ formatDevErrorMessage(`Expected TableNode first child to be a RowNode`);
3751
3742
  }
3752
3743
  }
3753
3744
  let lastRowCell = null;
@@ -3759,7 +3750,7 @@ function registerTableCellUnmergeTransform(editor) {
3759
3750
  unmerged.push(cell);
3760
3751
  } else if (cell.getColSpan() > 1 || cell.getRowSpan() > 1) {
3761
3752
  if (!$isTableCellNode(cell)) {
3762
- throw Error(`Expected TableNode cell to be a TableCellNode`);
3753
+ formatDevErrorMessage(`Expected TableNode cell to be a TableCellNode`);
3763
3754
  }
3764
3755
  const newCell = $createTableCellNode(cell.__headerState);
3765
3756
  if (lastRowCell !== null) {
@@ -3835,7 +3826,7 @@ function registerTableSelectionObserver(editor, hasTabHandler = true) {
3835
3826
  function registerTablePlugin(editor) {
3836
3827
  if (!editor.hasNodes([TableNode])) {
3837
3828
  {
3838
- throw Error(`TablePlugin: TableNode is not registered on editor`);
3829
+ formatDevErrorMessage(`TablePlugin: TableNode is not registered on editor`);
3839
3830
  }
3840
3831
  }
3841
3832
  return utils.mergeRegister(editor.registerCommand(INSERT_TABLE_COMMAND, $insertTableCommandListener, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.SELECTION_INSERT_CLIPBOARD_NODES_COMMAND, ({