@lexical/table 0.8.1 → 0.9.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.
@@ -22,18 +22,20 @@ const TableCellHeaderStates = {
22
22
  NO_STATUS: 0,
23
23
  ROW: 1
24
24
  };
25
+
25
26
  /** @noInheritDoc */
26
27
  class TableCellNode extends lexical.DEPRECATED_GridCellNode {
27
28
  /** @internal */
28
29
 
29
30
  /** @internal */
30
-
31
31
  static getType() {
32
32
  return 'tablecell';
33
33
  }
34
+
34
35
  static clone(node) {
35
36
  return new TableCellNode(node.__headerState, node.__colSpan, node.__width, node.__key);
36
37
  }
38
+
37
39
  static importDOM() {
38
40
  return {
39
41
  td: node => ({
@@ -46,99 +48,142 @@ class TableCellNode extends lexical.DEPRECATED_GridCellNode {
46
48
  })
47
49
  };
48
50
  }
51
+
49
52
  static importJSON(serializedNode) {
50
53
  return $createTableCellNode(serializedNode.headerState, serializedNode.colSpan, serializedNode.width || undefined);
51
54
  }
55
+
52
56
  constructor(headerState = TableCellHeaderStates.NO_STATUS, colSpan = 1, width, key) {
53
57
  super(colSpan, key);
54
58
  this.__headerState = headerState;
55
59
  this.__width = width;
56
60
  }
61
+
57
62
  createDOM(config) {
58
63
  const element = document.createElement(this.getTag());
64
+
59
65
  if (this.__width) {
60
66
  element.style.width = `${this.__width}px`;
61
67
  }
68
+
69
+ if (this.__colSpan !== 1) {
70
+ element.colSpan = this.__colSpan;
71
+ }
72
+
73
+ if (this.__rowSpan !== 1) {
74
+ element.rowSpan = this.__rowSpan;
75
+ }
76
+
62
77
  utils.addClassNamesToElement(element, config.theme.tableCell, this.hasHeader() && config.theme.tableCellHeader);
63
78
  return element;
64
79
  }
80
+
65
81
  exportDOM(editor) {
66
82
  const {
67
83
  element
68
84
  } = super.exportDOM(editor);
85
+
69
86
  if (element) {
87
+ const element_ = element;
70
88
  const maxWidth = 700;
71
89
  const colCount = this.getParentOrThrow().getChildrenSize();
72
- element.style.border = '1px solid black';
73
- element.style.width = `${this.getWidth() || Math.max(90, maxWidth / colCount)}px`;
74
- element.style.verticalAlign = 'top';
75
- element.style.textAlign = 'start';
90
+ element_.style.border = '1px solid black';
91
+
92
+ if (this.__colSpan !== 1) {
93
+ element_.colSpan = this.__colSpan;
94
+ }
95
+
96
+ if (this.__rowSpan !== 1) {
97
+ element_.rowSpan = this.__rowSpan;
98
+ }
99
+
100
+ element_.style.width = `${this.getWidth() || Math.max(90, maxWidth / colCount)}px`;
101
+ element_.style.verticalAlign = 'top';
102
+ element_.style.textAlign = 'start';
103
+
76
104
  if (this.hasHeader()) {
77
- element.style.backgroundColor = '#f2f3f5';
105
+ element_.style.backgroundColor = '#f2f3f5';
78
106
  }
79
107
  }
108
+
80
109
  return {
81
110
  element
82
111
  };
83
112
  }
113
+
84
114
  exportJSON() {
85
- return {
86
- ...super.exportJSON(),
115
+ return { ...super.exportJSON(),
87
116
  colSpan: super.__colSpan,
88
117
  headerState: this.__headerState,
89
118
  type: 'tablecell',
90
119
  width: this.getWidth()
91
120
  };
92
121
  }
122
+
93
123
  getTag() {
94
124
  return this.hasHeader() ? 'th' : 'td';
95
125
  }
126
+
96
127
  setHeaderStyles(headerState) {
97
128
  const self = this.getWritable();
98
129
  self.__headerState = headerState;
99
130
  return this.__headerState;
100
131
  }
132
+
101
133
  getHeaderStyles() {
102
134
  return this.getLatest().__headerState;
103
135
  }
136
+
104
137
  setWidth(width) {
105
138
  const self = this.getWritable();
106
139
  self.__width = width;
107
140
  return this.__width;
108
141
  }
142
+
109
143
  getWidth() {
110
144
  return this.getLatest().__width;
111
145
  }
146
+
112
147
  toggleHeaderStyle(headerStateToToggle) {
113
148
  const self = this.getWritable();
149
+
114
150
  if ((self.__headerState & headerStateToToggle) === headerStateToToggle) {
115
151
  self.__headerState -= headerStateToToggle;
116
152
  } else {
117
153
  self.__headerState += headerStateToToggle;
118
154
  }
155
+
119
156
  return self;
120
157
  }
158
+
121
159
  hasHeaderState(headerState) {
122
160
  return (this.getHeaderStyles() & headerState) === headerState;
123
161
  }
162
+
124
163
  hasHeader() {
125
164
  return this.getLatest().__headerState !== TableCellHeaderStates.NO_STATUS;
126
165
  }
166
+
127
167
  updateDOM(prevNode) {
128
- return prevNode.__headerState !== this.__headerState || prevNode.__width !== this.__width;
168
+ return prevNode.__headerState !== this.__headerState || prevNode.__width !== this.__width || prevNode.__colSpan !== this.__colSpan || prevNode.__rowSpan !== this.__rowSpan;
129
169
  }
170
+
130
171
  isShadowRoot() {
131
172
  return true;
132
173
  }
174
+
133
175
  collapseAtStart() {
134
176
  return true;
135
177
  }
178
+
136
179
  canBeEmpty() {
137
180
  return false;
138
181
  }
182
+
139
183
  canIndent() {
140
184
  return false;
141
185
  }
186
+
142
187
  }
143
188
  function convertTableCellNodeElement(domNode) {
144
189
  const nodeName = domNode.nodeName.toLowerCase();
@@ -147,12 +192,15 @@ function convertTableCellNodeElement(domNode) {
147
192
  forChild: (lexicalNode, parentLexicalNode) => {
148
193
  if ($isTableCellNode(parentLexicalNode) && !lexical.$isElementNode(lexicalNode)) {
149
194
  const paragraphNode = lexical.$createParagraphNode();
195
+
150
196
  if (lexical.$isLineBreakNode(lexicalNode) && lexicalNode.getTextContent() === '\n') {
151
197
  return null;
152
198
  }
199
+
153
200
  paragraphNode.append(lexicalNode);
154
201
  return paragraphNode;
155
202
  }
203
+
156
204
  return lexicalNode;
157
205
  },
158
206
  node: tableCellNode
@@ -172,16 +220,18 @@ function $isTableCellNode(node) {
172
220
  * LICENSE file in the root directory of this source tree.
173
221
  *
174
222
  */
223
+
175
224
  /** @noInheritDoc */
176
225
  class TableRowNode extends lexical.DEPRECATED_GridRowNode {
177
226
  /** @internal */
178
-
179
227
  static getType() {
180
228
  return 'tablerow';
181
229
  }
230
+
182
231
  static clone(node) {
183
232
  return new TableRowNode(node.__height, node.__key);
184
233
  }
234
+
185
235
  static importDOM() {
186
236
  return {
187
237
  tr: node => ({
@@ -190,48 +240,60 @@ class TableRowNode extends lexical.DEPRECATED_GridRowNode {
190
240
  })
191
241
  };
192
242
  }
243
+
193
244
  static importJSON(serializedNode) {
194
245
  return $createTableRowNode(serializedNode.height);
195
246
  }
247
+
196
248
  constructor(height, key) {
197
249
  super(key);
198
250
  this.__height = height;
199
251
  }
252
+
200
253
  exportJSON() {
201
- return {
202
- ...super.exportJSON(),
254
+ return { ...super.exportJSON(),
203
255
  type: 'tablerow',
204
256
  version: 1
205
257
  };
206
258
  }
259
+
207
260
  createDOM(config) {
208
261
  const element = document.createElement('tr');
262
+
209
263
  if (this.__height) {
210
264
  element.style.height = `${this.__height}px`;
211
265
  }
266
+
212
267
  utils.addClassNamesToElement(element, config.theme.tableRow);
213
268
  return element;
214
269
  }
270
+
215
271
  isShadowRoot() {
216
272
  return true;
217
273
  }
274
+
218
275
  setHeight(height) {
219
276
  const self = this.getWritable();
220
277
  self.__height = height;
221
278
  return this.__height;
222
279
  }
280
+
223
281
  getHeight() {
224
282
  return this.getLatest().__height;
225
283
  }
284
+
226
285
  updateDOM(prevNode) {
227
286
  return prevNode.__height !== this.__height;
228
287
  }
288
+
229
289
  canBeEmpty() {
230
290
  return false;
231
291
  }
292
+
232
293
  canIndent() {
233
294
  return false;
234
295
  }
296
+
235
297
  }
236
298
  function convertTableRowElement(domNode) {
237
299
  return {
@@ -252,7 +314,6 @@ function $isTableRowNode(node) {
252
314
  * LICENSE file in the root directory of this source tree.
253
315
  *
254
316
  */
255
-
256
317
  const CAN_USE_DOM = typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined';
257
318
 
258
319
  /**
@@ -262,7 +323,9 @@ const CAN_USE_DOM = typeof window !== 'undefined' && typeof window.document !==
262
323
  * LICENSE file in the root directory of this source tree.
263
324
  *
264
325
  */
326
+
265
327
  const getDOMSelection = targetWindow => CAN_USE_DOM ? (targetWindow || window).getSelection() : null;
328
+
266
329
  class TableSelection {
267
330
  constructor(editor, tableNodeKey) {
268
331
  this.isHighlightingCells = false;
@@ -286,40 +349,51 @@ class TableSelection {
286
349
  this.hasHijackedSelectionStyles = false;
287
350
  this.trackTableGrid();
288
351
  }
352
+
289
353
  getGrid() {
290
354
  return this.grid;
291
355
  }
356
+
292
357
  removeListeners() {
293
358
  Array.from(this.listenersToRemove).forEach(removeListener => removeListener());
294
359
  }
360
+
295
361
  trackTableGrid() {
296
362
  const observer = new MutationObserver(records => {
297
363
  this.editor.update(() => {
298
364
  let gridNeedsRedraw = false;
365
+
299
366
  for (let i = 0; i < records.length; i++) {
300
367
  const record = records[i];
301
368
  const target = record.target;
302
369
  const nodeName = target.nodeName;
370
+
303
371
  if (nodeName === 'TABLE' || nodeName === 'TR') {
304
372
  gridNeedsRedraw = true;
305
373
  break;
306
374
  }
307
375
  }
376
+
308
377
  if (!gridNeedsRedraw) {
309
378
  return;
310
379
  }
380
+
311
381
  const tableElement = this.editor.getElementByKey(this.tableNodeKey);
382
+
312
383
  if (!tableElement) {
313
384
  throw new Error('Expected to find TableElement in DOM');
314
385
  }
386
+
315
387
  this.grid = getTableGrid(tableElement);
316
388
  });
317
389
  });
318
390
  this.editor.update(() => {
319
391
  const tableElement = this.editor.getElementByKey(this.tableNodeKey);
392
+
320
393
  if (!tableElement) {
321
394
  throw new Error('Expected to find TableElement in DOM');
322
395
  }
396
+
323
397
  this.grid = getTableGrid(tableElement);
324
398
  observer.observe(tableElement, {
325
399
  childList: true,
@@ -327,6 +401,7 @@ class TableSelection {
327
401
  });
328
402
  });
329
403
  }
404
+
330
405
  clearHighlight() {
331
406
  this.isHighlightingCells = false;
332
407
  this.anchorX = -1;
@@ -342,39 +417,50 @@ class TableSelection {
342
417
  this.enableHighlightStyle();
343
418
  this.editor.update(() => {
344
419
  const tableNode = lexical.$getNodeByKey(this.tableNodeKey);
420
+
345
421
  if (!$isTableNode(tableNode)) {
346
422
  throw new Error('Expected TableNode.');
347
423
  }
424
+
348
425
  const tableElement = this.editor.getElementByKey(this.tableNodeKey);
426
+
349
427
  if (!tableElement) {
350
428
  throw new Error('Expected to find TableElement in DOM');
351
429
  }
430
+
352
431
  const grid = getTableGrid(tableElement);
353
432
  $updateDOMForSelection(grid, null);
354
433
  lexical.$setSelection(null);
355
434
  this.editor.dispatchCommand(lexical.SELECTION_CHANGE_COMMAND, undefined);
356
435
  });
357
436
  }
437
+
358
438
  enableHighlightStyle() {
359
439
  this.editor.update(() => {
360
440
  const tableElement = this.editor.getElementByKey(this.tableNodeKey);
441
+
361
442
  if (!tableElement) {
362
443
  throw new Error('Expected to find TableElement in DOM');
363
444
  }
445
+
364
446
  tableElement.classList.remove('disable-selection');
365
447
  this.hasHijackedSelectionStyles = false;
366
448
  });
367
449
  }
450
+
368
451
  disableHighlightStyle() {
369
452
  this.editor.update(() => {
370
453
  const tableElement = this.editor.getElementByKey(this.tableNodeKey);
454
+
371
455
  if (!tableElement) {
372
456
  throw new Error('Expected to find TableElement in DOM');
373
457
  }
458
+
374
459
  tableElement.classList.add('disable-selection');
375
460
  this.hasHijackedSelectionStyles = true;
376
461
  });
377
462
  }
463
+
378
464
  updateTableGridSelection(selection) {
379
465
  if (selection != null && selection.gridKey === this.tableNodeKey) {
380
466
  this.gridSelection = selection;
@@ -385,36 +471,46 @@ class TableSelection {
385
471
  this.clearHighlight();
386
472
  }
387
473
  }
474
+
388
475
  setFocusCellForSelection(cell, ignoreStart = false) {
389
476
  this.editor.update(() => {
390
477
  const tableNode = lexical.$getNodeByKey(this.tableNodeKey);
478
+
391
479
  if (!$isTableNode(tableNode)) {
392
480
  throw new Error('Expected TableNode.');
393
481
  }
482
+
394
483
  const tableElement = this.editor.getElementByKey(this.tableNodeKey);
484
+
395
485
  if (!tableElement) {
396
486
  throw new Error('Expected to find TableElement in DOM');
397
487
  }
488
+
398
489
  const cellX = cell.x;
399
490
  const cellY = cell.y;
400
491
  this.focusCell = cell;
492
+
401
493
  if (this.anchorCell !== null) {
402
- const domSelection = getDOMSelection(this.editor._window);
403
- // Collapse the selection
494
+ const domSelection = getDOMSelection(this.editor._window); // Collapse the selection
495
+
404
496
  if (domSelection) {
405
497
  domSelection.setBaseAndExtent(this.anchorCell.elem, 0, this.focusCell.elem, 0);
406
498
  }
407
499
  }
500
+
408
501
  if (!this.isHighlightingCells && (this.anchorX !== cellX || this.anchorY !== cellY || ignoreStart)) {
409
502
  this.isHighlightingCells = true;
410
503
  this.disableHighlightStyle();
411
504
  } else if (cellX === this.focusX && cellY === this.focusY) {
412
505
  return;
413
506
  }
507
+
414
508
  this.focusX = cellX;
415
509
  this.focusY = cellY;
510
+
416
511
  if (this.isHighlightingCells) {
417
512
  const focusTableCellNode = lexical.$getNearestNodeFromDOMNode(cell.elem);
513
+
418
514
  if (this.gridSelection != null && this.anchorCellNodeKey != null && $isTableCellNode(focusTableCellNode)) {
419
515
  const focusNodeKey = focusTableCellNode.getKey();
420
516
  this.gridSelection = this.gridSelection.clone() || lexical.DEPRECATED_$createGridSelection();
@@ -427,6 +523,7 @@ class TableSelection {
427
523
  }
428
524
  });
429
525
  }
526
+
430
527
  setAnchorCellForSelection(cell) {
431
528
  this.isHighlightingCells = false;
432
529
  this.anchorCell = cell;
@@ -434,6 +531,7 @@ class TableSelection {
434
531
  this.anchorY = cell.y;
435
532
  this.editor.update(() => {
436
533
  const anchorTableCellNode = lexical.$getNearestNodeFromDOMNode(cell.elem);
534
+
437
535
  if ($isTableCellNode(anchorTableCellNode)) {
438
536
  const anchorNodeKey = anchorTableCellNode.getKey();
439
537
  this.gridSelection = lexical.DEPRECATED_$createGridSelection();
@@ -441,14 +539,17 @@ class TableSelection {
441
539
  }
442
540
  });
443
541
  }
542
+
444
543
  formatCells(type) {
445
544
  this.editor.update(() => {
446
545
  const selection = lexical.$getSelection();
546
+
447
547
  if (!lexical.DEPRECATED_$isGridSelection(selection)) {
448
548
  {
449
549
  throw Error(`Expected grid selection`);
450
550
  }
451
551
  }
552
+
452
553
  const formatSelection = lexical.$createRangeSelection();
453
554
  const anchor = formatSelection.anchor;
454
555
  const focus = formatSelection.focus;
@@ -463,27 +564,34 @@ class TableSelection {
463
564
  this.editor.dispatchCommand(lexical.SELECTION_CHANGE_COMMAND, undefined);
464
565
  });
465
566
  }
567
+
466
568
  clearText() {
467
569
  this.editor.update(() => {
468
570
  const tableNode = lexical.$getNodeByKey(this.tableNodeKey);
571
+
469
572
  if (!$isTableNode(tableNode)) {
470
573
  throw new Error('Expected TableNode.');
471
574
  }
575
+
472
576
  const selection = lexical.$getSelection();
577
+
473
578
  if (!lexical.DEPRECATED_$isGridSelection(selection)) {
474
579
  {
475
580
  throw Error(`Expected grid selection`);
476
581
  }
477
582
  }
583
+
478
584
  const selectedNodes = selection.getNodes().filter($isTableCellNode);
585
+
479
586
  if (selectedNodes.length === this.grid.columns * this.grid.rows) {
480
- tableNode.selectPrevious();
481
- // Delete entire table
587
+ tableNode.selectPrevious(); // Delete entire table
588
+
482
589
  tableNode.remove();
483
590
  const rootNode = lexical.$getRoot();
484
591
  rootNode.selectStart();
485
592
  return;
486
593
  }
594
+
487
595
  selectedNodes.forEach(cellNode => {
488
596
  if (lexical.$isElementNode(cellNode)) {
489
597
  const paragraphNode = lexical.$createParagraphNode();
@@ -502,6 +610,7 @@ class TableSelection {
502
610
  this.editor.dispatchCommand(lexical.SELECTION_CHANGE_COMMAND, undefined);
503
611
  });
504
612
  }
613
+
505
614
  }
506
615
 
507
616
  /**
@@ -514,15 +623,18 @@ class TableSelection {
514
623
  const LEXICAL_ELEMENT_KEY = '__lexicalTableSelection';
515
624
  function applyTableHandlers(tableNode, tableElement, editor) {
516
625
  const rootElement = editor.getRootElement();
626
+
517
627
  if (rootElement === null) {
518
628
  throw new Error('No root element.');
519
629
  }
630
+
520
631
  const tableSelection = new TableSelection(editor, tableNode.getKey());
521
632
  attachTableSelectionToTableElement(tableElement, tableSelection);
522
633
  let isMouseDown = false;
523
634
  let isRangeSelectionHijacked = false;
524
635
  tableElement.addEventListener('dblclick', event => {
525
636
  const cell = getCellFromTarget(event.target);
637
+
526
638
  if (cell !== null) {
527
639
  event.preventDefault();
528
640
  event.stopImmediatePropagation();
@@ -531,15 +643,16 @@ function applyTableHandlers(tableNode, tableElement, editor) {
531
643
  tableSelection.setFocusCellForSelection(cell, true);
532
644
  isMouseDown = false;
533
645
  }
534
- });
646
+ }); // This is the anchor of the selection.
535
647
 
536
- // This is the anchor of the selection.
537
648
  tableElement.addEventListener('mousedown', event => {
538
649
  setTimeout(() => {
539
650
  if (event.button !== 0) {
540
651
  return;
541
652
  }
653
+
542
654
  const cell = getCellFromTarget(event.target);
655
+
543
656
  if (cell !== null) {
544
657
  event.preventDefault();
545
658
  event.stopPropagation();
@@ -547,268 +660,327 @@ function applyTableHandlers(tableNode, tableElement, editor) {
547
660
  tableSelection.setAnchorCellForSelection(cell);
548
661
  }
549
662
  }, 0);
550
- });
663
+ }); // This is adjusting the focus of the selection.
551
664
 
552
- // This is adjusting the focus of the selection.
553
665
  tableElement.addEventListener('mousemove', event => {
554
666
  if (isRangeSelectionHijacked) {
555
667
  event.preventDefault();
556
668
  event.stopPropagation();
557
669
  event.stopImmediatePropagation();
558
670
  }
671
+
559
672
  if (isMouseDown) {
560
673
  const cell = getCellFromTarget(event.target);
674
+
561
675
  if (cell !== null) {
562
676
  const cellX = cell.x;
563
677
  const cellY = cell.y;
678
+
564
679
  if (isMouseDown && (tableSelection.anchorX !== cellX || tableSelection.anchorY !== cellY || tableSelection.isHighlightingCells)) {
565
680
  event.preventDefault();
566
681
  tableSelection.setFocusCellForSelection(cell);
567
682
  }
568
683
  }
569
684
  }
570
- });
685
+ }); // Select entire table at this point, when grid selection is ready.
571
686
 
572
- // Select entire table at this point, when grid selection is ready.
573
687
  tableElement.addEventListener('mouseleave', () => {
574
688
  if (isMouseDown) {
575
689
  return;
576
690
  }
577
- });
691
+ }); // Clear selection when clicking outside of dom.
578
692
 
579
- // Clear selection when clicking outside of dom.
580
693
  const mouseDownCallback = event => {
581
694
  isMouseDown = true;
695
+
582
696
  if (event.button !== 0) {
583
697
  return;
584
698
  }
699
+
585
700
  editor.update(() => {
586
701
  const selection = lexical.$getSelection();
702
+
587
703
  if (lexical.DEPRECATED_$isGridSelection(selection) && selection.gridKey === tableSelection.tableNodeKey && rootElement.contains(event.target)) {
588
704
  return tableSelection.clearHighlight();
589
705
  }
590
706
  });
591
707
  };
708
+
592
709
  window.addEventListener('mousedown', mouseDownCallback);
593
710
  tableSelection.listenersToRemove.add(() => window.removeEventListener('mousedown', mouseDownCallback));
711
+
594
712
  const mouseUpCallback = event => {
595
713
  if (isMouseDown) {
596
714
  event.preventDefault();
597
715
  event.stopPropagation();
598
716
  }
717
+
599
718
  isMouseDown = false;
600
719
  };
720
+
601
721
  window.addEventListener('mouseup', mouseUpCallback);
602
722
  tableSelection.listenersToRemove.add(() => window.removeEventListener('mouseup', mouseUpCallback));
603
723
  tableSelection.listenersToRemove.add(() => tableElement.addEventListener('mouseup', mouseUpCallback));
604
724
  tableSelection.listenersToRemove.add(() => tableElement.removeEventListener('mouseup', mouseUpCallback));
605
725
  tableSelection.listenersToRemove.add(editor.registerCommand(lexical.KEY_ARROW_DOWN_COMMAND, event => {
606
726
  const selection = lexical.$getSelection();
727
+
607
728
  if (!$isSelectionInTable(selection, tableNode)) {
608
729
  return false;
609
730
  }
731
+
610
732
  const direction = 'down';
733
+
611
734
  if (lexical.$isRangeSelection(selection)) {
612
735
  if (selection.isCollapsed()) {
613
736
  const tableCellNode = utils.$findMatchingParent(selection.anchor.getNode(), n => $isTableCellNode(n));
737
+
614
738
  if (!$isTableCellNode(tableCellNode)) {
615
739
  return false;
616
740
  }
741
+
617
742
  const currentCords = tableNode.getCordsFromCellNode(tableCellNode, tableSelection.grid);
618
743
  const elementParentNode = utils.$findMatchingParent(selection.anchor.getNode(), n => lexical.$isElementNode(n));
744
+
619
745
  if (elementParentNode == null) {
620
746
  throw new Error('Expected BlockNode Parent');
621
747
  }
748
+
622
749
  const lastChild = tableCellNode.getLastChild();
623
750
  const isSelectionInLastBlock = lastChild && elementParentNode.isParentOf(lastChild) || elementParentNode === lastChild;
751
+
624
752
  if (isSelectionInLastBlock || event.shiftKey) {
625
753
  event.preventDefault();
626
754
  event.stopImmediatePropagation();
627
- event.stopPropagation();
755
+ event.stopPropagation(); // Start Selection
628
756
 
629
- // Start Selection
630
757
  if (event.shiftKey) {
631
758
  tableSelection.setAnchorCellForSelection(tableNode.getCellFromCordsOrThrow(currentCords.x, currentCords.y, tableSelection.grid));
632
759
  return adjustFocusNodeInDirection(tableSelection, tableNode, currentCords.x, currentCords.y, direction);
633
760
  }
761
+
634
762
  return selectGridNodeInDirection(tableSelection, tableNode, currentCords.x, currentCords.y, direction);
635
763
  }
636
764
  }
637
765
  } else if (lexical.DEPRECATED_$isGridSelection(selection) && event.shiftKey) {
638
766
  const tableCellNode = selection.focus.getNode();
767
+
639
768
  if (!$isTableCellNode(tableCellNode)) {
640
769
  return false;
641
770
  }
771
+
642
772
  const currentCords = tableNode.getCordsFromCellNode(tableCellNode, tableSelection.grid);
643
773
  event.preventDefault();
644
774
  event.stopImmediatePropagation();
645
775
  event.stopPropagation();
646
776
  return adjustFocusNodeInDirection(tableSelection, tableNode, currentCords.x, currentCords.y, direction);
647
777
  }
778
+
648
779
  return false;
649
780
  }, lexical.COMMAND_PRIORITY_HIGH));
650
781
  tableSelection.listenersToRemove.add(editor.registerCommand(lexical.KEY_ARROW_UP_COMMAND, event => {
651
782
  const selection = lexical.$getSelection();
783
+
652
784
  if (!$isSelectionInTable(selection, tableNode)) {
653
785
  return false;
654
786
  }
787
+
655
788
  const direction = 'up';
789
+
656
790
  if (lexical.$isRangeSelection(selection)) {
657
791
  if (selection.isCollapsed()) {
658
792
  const tableCellNode = utils.$findMatchingParent(selection.anchor.getNode(), n => $isTableCellNode(n));
793
+
659
794
  if (!$isTableCellNode(tableCellNode)) {
660
795
  return false;
661
796
  }
797
+
662
798
  const currentCords = tableNode.getCordsFromCellNode(tableCellNode, tableSelection.grid);
663
799
  const elementParentNode = utils.$findMatchingParent(selection.anchor.getNode(), n => lexical.$isElementNode(n));
800
+
664
801
  if (elementParentNode == null) {
665
802
  throw new Error('Expected BlockNode Parent');
666
803
  }
804
+
667
805
  const lastChild = tableCellNode.getLastChild();
668
806
  const isSelectionInLastBlock = lastChild && elementParentNode.isParentOf(lastChild) || elementParentNode === lastChild;
807
+
669
808
  if (isSelectionInLastBlock || event.shiftKey) {
670
809
  event.preventDefault();
671
810
  event.stopImmediatePropagation();
672
- event.stopPropagation();
811
+ event.stopPropagation(); // Start Selection
673
812
 
674
- // Start Selection
675
813
  if (event.shiftKey) {
676
814
  tableSelection.setAnchorCellForSelection(tableNode.getCellFromCordsOrThrow(currentCords.x, currentCords.y, tableSelection.grid));
677
815
  return adjustFocusNodeInDirection(tableSelection, tableNode, currentCords.x, currentCords.y, direction);
678
816
  }
817
+
679
818
  return selectGridNodeInDirection(tableSelection, tableNode, currentCords.x, currentCords.y, direction);
680
819
  }
681
820
  }
682
821
  } else if (lexical.DEPRECATED_$isGridSelection(selection) && event.shiftKey) {
683
822
  const tableCellNode = selection.focus.getNode();
823
+
684
824
  if (!$isTableCellNode(tableCellNode)) {
685
825
  return false;
686
826
  }
827
+
687
828
  const currentCords = tableNode.getCordsFromCellNode(tableCellNode, tableSelection.grid);
688
829
  event.preventDefault();
689
830
  event.stopImmediatePropagation();
690
831
  event.stopPropagation();
691
832
  return adjustFocusNodeInDirection(tableSelection, tableNode, currentCords.x, currentCords.y, direction);
692
833
  }
834
+
693
835
  return false;
694
836
  }, lexical.COMMAND_PRIORITY_HIGH));
695
837
  tableSelection.listenersToRemove.add(editor.registerCommand(lexical.KEY_ARROW_LEFT_COMMAND, event => {
696
838
  const selection = lexical.$getSelection();
839
+
697
840
  if (!$isSelectionInTable(selection, tableNode)) {
698
841
  return false;
699
842
  }
843
+
700
844
  const direction = 'backward';
845
+
701
846
  if (lexical.$isRangeSelection(selection)) {
702
847
  if (selection.isCollapsed()) {
703
848
  const tableCellNode = utils.$findMatchingParent(selection.anchor.getNode(), n => $isTableCellNode(n));
849
+
704
850
  if (!$isTableCellNode(tableCellNode)) {
705
851
  return false;
706
852
  }
853
+
707
854
  const currentCords = tableNode.getCordsFromCellNode(tableCellNode, tableSelection.grid);
708
855
  const elementParentNode = utils.$findMatchingParent(selection.anchor.getNode(), n => lexical.$isElementNode(n));
856
+
709
857
  if (elementParentNode == null) {
710
858
  throw new Error('Expected BlockNode Parent');
711
859
  }
860
+
712
861
  if (selection.anchor.offset === 0 || event.shiftKey) {
713
862
  event.preventDefault();
714
863
  event.stopImmediatePropagation();
715
- event.stopPropagation();
864
+ event.stopPropagation(); // Start Selection
716
865
 
717
- // Start Selection
718
866
  if (event.shiftKey) {
719
867
  tableSelection.setAnchorCellForSelection(tableNode.getCellFromCordsOrThrow(currentCords.x, currentCords.y, tableSelection.grid));
720
868
  return adjustFocusNodeInDirection(tableSelection, tableNode, currentCords.x, currentCords.y, direction);
721
869
  }
870
+
722
871
  return selectGridNodeInDirection(tableSelection, tableNode, currentCords.x, currentCords.y, direction);
723
872
  }
724
873
  }
725
874
  } else if (lexical.DEPRECATED_$isGridSelection(selection) && event.shiftKey) {
726
875
  const tableCellNode = selection.focus.getNode();
876
+
727
877
  if (!$isTableCellNode(tableCellNode)) {
728
878
  return false;
729
879
  }
880
+
730
881
  const currentCords = tableNode.getCordsFromCellNode(tableCellNode, tableSelection.grid);
731
882
  event.preventDefault();
732
883
  event.stopImmediatePropagation();
733
884
  event.stopPropagation();
734
885
  return adjustFocusNodeInDirection(tableSelection, tableNode, currentCords.x, currentCords.y, direction);
735
886
  }
887
+
736
888
  return false;
737
889
  }, lexical.COMMAND_PRIORITY_HIGH));
738
890
  tableSelection.listenersToRemove.add(editor.registerCommand(lexical.KEY_ARROW_RIGHT_COMMAND, event => {
739
891
  const selection = lexical.$getSelection();
892
+
740
893
  if (!$isSelectionInTable(selection, tableNode)) {
741
894
  return false;
742
895
  }
896
+
743
897
  const direction = 'forward';
898
+
744
899
  if (lexical.$isRangeSelection(selection)) {
745
900
  if (selection.isCollapsed()) {
746
901
  const tableCellNode = utils.$findMatchingParent(selection.anchor.getNode(), n => $isTableCellNode(n));
902
+
747
903
  if (!$isTableCellNode(tableCellNode)) {
748
904
  return false;
749
905
  }
906
+
750
907
  const currentCords = tableNode.getCordsFromCellNode(tableCellNode, tableSelection.grid);
751
908
  const elementParentNode = utils.$findMatchingParent(selection.anchor.getNode(), n => lexical.$isElementNode(n));
909
+
752
910
  if (elementParentNode == null) {
753
911
  throw new Error('Expected BlockNode Parent');
754
912
  }
913
+
755
914
  if (selection.anchor.offset === selection.anchor.getNode().getTextContentSize() || event.shiftKey) {
756
915
  event.preventDefault();
757
916
  event.stopImmediatePropagation();
758
- event.stopPropagation();
917
+ event.stopPropagation(); // Start Selection
759
918
 
760
- // Start Selection
761
919
  if (event.shiftKey) {
762
920
  tableSelection.setAnchorCellForSelection(tableNode.getCellFromCordsOrThrow(currentCords.x, currentCords.y, tableSelection.grid));
763
921
  return adjustFocusNodeInDirection(tableSelection, tableNode, currentCords.x, currentCords.y, direction);
764
922
  }
923
+
765
924
  return selectGridNodeInDirection(tableSelection, tableNode, currentCords.x, currentCords.y, direction);
766
925
  }
767
926
  }
768
927
  } else if (lexical.DEPRECATED_$isGridSelection(selection) && event.shiftKey) {
769
928
  const tableCellNode = selection.focus.getNode();
929
+
770
930
  if (!$isTableCellNode(tableCellNode)) {
771
931
  return false;
772
932
  }
933
+
773
934
  const currentCords = tableNode.getCordsFromCellNode(tableCellNode, tableSelection.grid);
774
935
  event.preventDefault();
775
936
  event.stopImmediatePropagation();
776
937
  event.stopPropagation();
777
938
  return adjustFocusNodeInDirection(tableSelection, tableNode, currentCords.x, currentCords.y, direction);
778
939
  }
940
+
779
941
  return false;
780
942
  }, lexical.COMMAND_PRIORITY_HIGH));
943
+
781
944
  const deleteTextHandler = command => () => {
782
945
  const selection = lexical.$getSelection();
946
+
783
947
  if (!$isSelectionInTable(selection, tableNode)) {
784
948
  return false;
785
949
  }
950
+
786
951
  if (lexical.DEPRECATED_$isGridSelection(selection)) {
787
952
  tableSelection.clearText();
788
953
  return true;
789
954
  } else if (lexical.$isRangeSelection(selection)) {
790
955
  const tableCellNode = utils.$findMatchingParent(selection.anchor.getNode(), n => $isTableCellNode(n));
956
+
791
957
  if (!$isTableCellNode(tableCellNode)) {
792
958
  return false;
793
959
  }
960
+
794
961
  const anchorNode = selection.anchor.getNode();
795
962
  const focusNode = selection.focus.getNode();
796
963
  const isAnchorInside = tableNode.isParentOf(anchorNode);
797
964
  const isFocusInside = tableNode.isParentOf(focusNode);
798
965
  const selectionContainsPartialTable = isAnchorInside && !isFocusInside || isFocusInside && !isAnchorInside;
966
+
799
967
  if (selectionContainsPartialTable) {
800
968
  tableSelection.clearText();
801
969
  return true;
802
970
  }
971
+
803
972
  const nearestElementNode = utils.$findMatchingParent(selection.anchor.getNode(), n => lexical.$isElementNode(n));
804
973
  const topLevelCellElementNode = nearestElementNode && utils.$findMatchingParent(nearestElementNode, n => lexical.$isElementNode(n) && $isTableCellNode(n.getParent()));
974
+
805
975
  if (!lexical.$isElementNode(topLevelCellElementNode) || !lexical.$isElementNode(nearestElementNode)) {
806
976
  return false;
807
977
  }
978
+
808
979
  if (command === lexical.DELETE_LINE_COMMAND && topLevelCellElementNode.getPreviousSibling() === null) {
809
980
  // TODO: Fix Delete Line in Table Cells.
810
981
  return true;
811
982
  }
983
+
812
984
  if (command === lexical.DELETE_CHARACTER_COMMAND || command === lexical.DELETE_WORD_COMMAND) {
813
985
  if (selection.isCollapsed() && selection.anchor.offset === 0) {
814
986
  if (nearestElementNode !== topLevelCellElementNode) {
@@ -822,16 +994,21 @@ function applyTableHandlers(tableNode, tableElement, editor) {
822
994
  }
823
995
  }
824
996
  }
997
+
825
998
  return false;
826
999
  };
1000
+
827
1001
  [lexical.DELETE_WORD_COMMAND, lexical.DELETE_LINE_COMMAND, lexical.DELETE_CHARACTER_COMMAND].forEach(command => {
828
1002
  tableSelection.listenersToRemove.add(editor.registerCommand(command, deleteTextHandler(command), lexical.COMMAND_PRIORITY_CRITICAL));
829
1003
  });
1004
+
830
1005
  const deleteCellHandler = event => {
831
1006
  const selection = lexical.$getSelection();
1007
+
832
1008
  if (!$isSelectionInTable(selection, tableNode)) {
833
1009
  return false;
834
1010
  }
1011
+
835
1012
  if (lexical.DEPRECATED_$isGridSelection(selection)) {
836
1013
  event.preventDefault();
837
1014
  event.stopPropagation();
@@ -839,56 +1016,71 @@ function applyTableHandlers(tableNode, tableElement, editor) {
839
1016
  return true;
840
1017
  } else if (lexical.$isRangeSelection(selection)) {
841
1018
  const tableCellNode = utils.$findMatchingParent(selection.anchor.getNode(), n => $isTableCellNode(n));
1019
+
842
1020
  if (!$isTableCellNode(tableCellNode)) {
843
1021
  return false;
844
1022
  }
845
1023
  }
1024
+
846
1025
  return false;
847
1026
  };
1027
+
848
1028
  tableSelection.listenersToRemove.add(editor.registerCommand(lexical.KEY_BACKSPACE_COMMAND, deleteCellHandler, lexical.COMMAND_PRIORITY_CRITICAL));
849
1029
  tableSelection.listenersToRemove.add(editor.registerCommand(lexical.KEY_DELETE_COMMAND, deleteCellHandler, lexical.COMMAND_PRIORITY_CRITICAL));
850
1030
  tableSelection.listenersToRemove.add(editor.registerCommand(lexical.FORMAT_TEXT_COMMAND, payload => {
851
1031
  const selection = lexical.$getSelection();
1032
+
852
1033
  if (!$isSelectionInTable(selection, tableNode)) {
853
1034
  return false;
854
1035
  }
1036
+
855
1037
  if (lexical.DEPRECATED_$isGridSelection(selection)) {
856
1038
  tableSelection.formatCells(payload);
857
1039
  return true;
858
1040
  } else if (lexical.$isRangeSelection(selection)) {
859
1041
  const tableCellNode = utils.$findMatchingParent(selection.anchor.getNode(), n => $isTableCellNode(n));
1042
+
860
1043
  if (!$isTableCellNode(tableCellNode)) {
861
1044
  return false;
862
1045
  }
863
1046
  }
1047
+
864
1048
  return false;
865
1049
  }, lexical.COMMAND_PRIORITY_CRITICAL));
866
1050
  tableSelection.listenersToRemove.add(editor.registerCommand(lexical.CONTROLLED_TEXT_INSERTION_COMMAND, payload => {
867
1051
  const selection = lexical.$getSelection();
1052
+
868
1053
  if (!$isSelectionInTable(selection, tableNode)) {
869
1054
  return false;
870
1055
  }
1056
+
871
1057
  if (lexical.DEPRECATED_$isGridSelection(selection)) {
872
1058
  tableSelection.clearHighlight();
873
1059
  return false;
874
1060
  } else if (lexical.$isRangeSelection(selection)) {
875
1061
  const tableCellNode = utils.$findMatchingParent(selection.anchor.getNode(), n => $isTableCellNode(n));
1062
+
876
1063
  if (!$isTableCellNode(tableCellNode)) {
877
1064
  return false;
878
1065
  }
879
1066
  }
1067
+
880
1068
  return false;
881
1069
  }, lexical.COMMAND_PRIORITY_CRITICAL));
882
1070
  tableSelection.listenersToRemove.add(editor.registerCommand(lexical.KEY_TAB_COMMAND, event => {
883
1071
  const selection = lexical.$getSelection();
1072
+
884
1073
  if (!$isSelectionInTable(selection, tableNode)) {
885
1074
  return false;
886
1075
  }
1076
+
887
1077
  if (lexical.$isRangeSelection(selection)) {
888
1078
  const tableCellNode = utils.$findMatchingParent(selection.anchor.getNode(), n => $isTableCellNode(n));
1079
+
889
1080
  if (!$isTableCellNode(tableCellNode)) {
890
1081
  return false;
891
1082
  }
1083
+
892
1084
  if (selection.isCollapsed()) {
893
1085
  const currentCords = tableNode.getCordsFromCellNode(tableCellNode, tableSelection.grid);
894
1086
  event.preventDefault();
@@ -896,6 +1088,7 @@ function applyTableHandlers(tableNode, tableElement, editor) {
896
1088
  return true;
897
1089
  }
898
1090
  }
1091
+
899
1092
  return false;
900
1093
  }, lexical.COMMAND_PRIORITY_HIGH));
901
1094
  tableSelection.listenersToRemove.add(editor.registerCommand(lexical.FOCUS_COMMAND, payload => {
@@ -904,6 +1097,7 @@ function applyTableHandlers(tableNode, tableElement, editor) {
904
1097
  tableSelection.listenersToRemove.add(editor.registerCommand(lexical.SELECTION_CHANGE_COMMAND, payload => {
905
1098
  const selection = lexical.$getSelection();
906
1099
  const prevSelection = lexical.$getPreviousSelection();
1100
+
907
1101
  if (selection && lexical.$isRangeSelection(selection) && !selection.isCollapsed()) {
908
1102
  const anchorNode = selection.anchor.getNode();
909
1103
  const focusNode = selection.focus.getNode();
@@ -911,6 +1105,7 @@ function applyTableHandlers(tableNode, tableElement, editor) {
911
1105
  const isFocusInside = tableNode.isParentOf(focusNode);
912
1106
  const selectionContainsPartialTable = isAnchorInside && !isFocusInside || isFocusInside && !isAnchorInside;
913
1107
  const selectionIsInsideTable = isAnchorInside && isFocusInside && !tableNode.isSelected();
1108
+
914
1109
  if (selectionContainsPartialTable) {
915
1110
  const isBackward = selection.isBackward();
916
1111
  const modifiedSelection = lexical.$createRangeSelection();
@@ -925,11 +1120,13 @@ function applyTableHandlers(tableNode, tableElement, editor) {
925
1120
  const {
926
1121
  grid
927
1122
  } = tableSelection;
1123
+
928
1124
  if (selection.getNodes().filter($isTableCellNode).length === grid.rows * grid.columns) {
929
1125
  const gridSelection = lexical.DEPRECATED_$createGridSelection();
930
1126
  const tableKey = tableNode.getKey();
931
1127
  const firstCell = tableNode.getFirstChildOrThrow().getFirstChild();
932
1128
  const lastCell = tableNode.getLastChildOrThrow().getLastChild();
1129
+
933
1130
  if (firstCell != null && lastCell != null) {
934
1131
  gridSelection.set(tableKey, firstCell.getKey(), lastCell.getKey());
935
1132
  lexical.$setSelection(gridSelection);
@@ -939,20 +1136,24 @@ function applyTableHandlers(tableNode, tableElement, editor) {
939
1136
  }
940
1137
  }
941
1138
  }
1139
+
942
1140
  if (selection && !selection.is(prevSelection) && (lexical.DEPRECATED_$isGridSelection(selection) || lexical.DEPRECATED_$isGridSelection(prevSelection)) && tableSelection.gridSelection && !tableSelection.gridSelection.is(prevSelection)) {
943
1141
  if (lexical.DEPRECATED_$isGridSelection(selection) && selection.gridKey === tableSelection.tableNodeKey) {
944
1142
  tableSelection.updateTableGridSelection(selection);
945
1143
  } else if (!lexical.DEPRECATED_$isGridSelection(selection) && lexical.DEPRECATED_$isGridSelection(prevSelection) && prevSelection.gridKey === tableSelection.tableNodeKey) {
946
1144
  tableSelection.updateTableGridSelection(null);
947
1145
  }
1146
+
948
1147
  return false;
949
1148
  }
1149
+
950
1150
  if (tableSelection.hasHijackedSelectionStyles && !tableNode.isSelected()) {
951
1151
  $removeHighlightStyleToTable(tableSelection);
952
1152
  isRangeSelectionHijacked = false;
953
1153
  } else if (!tableSelection.hasHijackedSelectionStyles && tableNode.isSelected()) {
954
1154
  $addHighlightStyleToTable(tableSelection);
955
1155
  }
1156
+
956
1157
  return false;
957
1158
  }, lexical.COMMAND_PRIORITY_CRITICAL));
958
1159
  return tableSelection;
@@ -965,18 +1166,24 @@ function getTableSelectionFromTableElement(tableElement) {
965
1166
  }
966
1167
  function getCellFromTarget(node) {
967
1168
  let currentNode = node;
1169
+
968
1170
  while (currentNode != null) {
969
1171
  const nodeName = currentNode.nodeName;
1172
+
970
1173
  if (nodeName === 'TD' || nodeName === 'TH') {
971
1174
  // @ts-expect-error: internal field
972
1175
  const cell = currentNode._cell;
1176
+
973
1177
  if (cell === undefined) {
974
1178
  return null;
975
1179
  }
1180
+
976
1181
  return cell;
977
1182
  }
1183
+
978
1184
  currentNode = currentNode.parentNode;
979
1185
  }
1186
+
980
1187
  return null;
981
1188
  }
982
1189
  function getTableGrid(tableElement) {
@@ -990,8 +1197,10 @@ function getTableGrid(tableElement) {
990
1197
  let x = 0;
991
1198
  let y = 0;
992
1199
  cells.length = 0;
1200
+
993
1201
  while (currentNode != null) {
994
1202
  const nodeMame = currentNode.nodeName;
1203
+
995
1204
  if (nodeMame === 'TD' || nodeMame === 'TH') {
996
1205
  const elem = currentNode;
997
1206
  const cell = {
@@ -999,38 +1208,47 @@ function getTableGrid(tableElement) {
999
1208
  highlighted: false,
1000
1209
  x,
1001
1210
  y
1002
- };
1211
+ }; // @ts-expect-error: internal field
1003
1212
 
1004
- // @ts-expect-error: internal field
1005
1213
  currentNode._cell = cell;
1214
+
1006
1215
  if (cells[y] === undefined) {
1007
1216
  cells[y] = [];
1008
1217
  }
1218
+
1009
1219
  cells[y][x] = cell;
1010
1220
  } else {
1011
1221
  const child = currentNode.firstChild;
1222
+
1012
1223
  if (child != null) {
1013
1224
  currentNode = child;
1014
1225
  continue;
1015
1226
  }
1016
1227
  }
1228
+
1017
1229
  const sibling = currentNode.nextSibling;
1230
+
1018
1231
  if (sibling != null) {
1019
1232
  x++;
1020
1233
  currentNode = sibling;
1021
1234
  continue;
1022
1235
  }
1236
+
1023
1237
  const parent = currentNode.parentNode;
1238
+
1024
1239
  if (parent != null) {
1025
1240
  const parentSibling = parent.nextSibling;
1241
+
1026
1242
  if (parentSibling == null) {
1027
1243
  break;
1028
1244
  }
1245
+
1029
1246
  y++;
1030
1247
  x = 0;
1031
1248
  currentNode = parentSibling;
1032
1249
  }
1033
1250
  }
1251
+
1034
1252
  grid.columns = x + 1;
1035
1253
  grid.rows = y + 1;
1036
1254
  return grid;
@@ -1040,6 +1258,7 @@ function $updateDOMForSelection(grid, selection) {
1040
1258
  const selectedCellNodes = new Set(selection ? selection.getNodes() : []);
1041
1259
  $forEachGridCell(grid, (cell, lexicalNode) => {
1042
1260
  const elem = cell.elem;
1261
+
1043
1262
  if (selectedCellNodes.has(lexicalNode)) {
1044
1263
  cell.highlighted = true;
1045
1264
  elem.style.setProperty('background-color', 'rgb(172, 206, 247)');
@@ -1049,6 +1268,7 @@ function $updateDOMForSelection(grid, selection) {
1049
1268
  cell.highlighted = false;
1050
1269
  elem.style.removeProperty('background-color');
1051
1270
  elem.style.removeProperty('caret-color');
1271
+
1052
1272
  if (!elem.getAttribute('style')) {
1053
1273
  elem.removeAttribute('style');
1054
1274
  }
@@ -1060,11 +1280,14 @@ function $forEachGridCell(grid, cb) {
1060
1280
  const {
1061
1281
  cells
1062
1282
  } = grid;
1283
+
1063
1284
  for (let y = 0; y < cells.length; y++) {
1064
1285
  const row = cells[y];
1286
+
1065
1287
  for (let x = 0; x < row.length; x++) {
1066
1288
  const cell = row[x];
1067
1289
  const lexicalNode = lexical.$getNearestNodeFromDOMNode(cell.elem);
1290
+
1068
1291
  if (lexicalNode !== null) {
1069
1292
  cb(cell, lexicalNode, {
1070
1293
  x,
@@ -1090,13 +1313,16 @@ function $removeHighlightStyleToTable(tableSelection) {
1090
1313
  cell.highlighted = false;
1091
1314
  elem.style.removeProperty('background-color');
1092
1315
  elem.style.removeProperty('caret-color');
1316
+
1093
1317
  if (!elem.getAttribute('style')) {
1094
1318
  elem.removeAttribute('style');
1095
1319
  }
1096
1320
  });
1097
1321
  }
1322
+
1098
1323
  const selectGridNodeInDirection = (tableSelection, tableNode, x, y, direction) => {
1099
1324
  const isForward = direction === 'forward';
1325
+
1100
1326
  switch (direction) {
1101
1327
  case 'backward':
1102
1328
  case 'forward':
@@ -1111,34 +1337,44 @@ const selectGridNodeInDirection = (tableSelection, tableNode, x, y, direction) =
1111
1337
  tableNode.selectNext();
1112
1338
  }
1113
1339
  }
1340
+
1114
1341
  return true;
1342
+
1115
1343
  case 'up':
1116
1344
  if (y !== 0) {
1117
1345
  selectTableCellNode(tableNode.getCellNodeFromCordsOrThrow(x, y - 1, tableSelection.grid));
1118
1346
  } else {
1119
1347
  tableNode.selectPrevious();
1120
1348
  }
1349
+
1121
1350
  return true;
1351
+
1122
1352
  case 'down':
1123
1353
  if (y !== tableSelection.grid.rows - 1) {
1124
1354
  selectTableCellNode(tableNode.getCellNodeFromCordsOrThrow(x, y + 1, tableSelection.grid));
1125
1355
  } else {
1126
1356
  tableNode.selectNext();
1127
1357
  }
1358
+
1128
1359
  return true;
1360
+
1129
1361
  default:
1130
1362
  return false;
1131
1363
  }
1132
1364
  };
1365
+
1133
1366
  const adjustFocusNodeInDirection = (tableSelection, tableNode, x, y, direction) => {
1134
1367
  const isForward = direction === 'forward';
1368
+
1135
1369
  switch (direction) {
1136
1370
  case 'backward':
1137
1371
  case 'forward':
1138
1372
  if (x !== (isForward ? tableSelection.grid.columns - 1 : 0)) {
1139
1373
  tableSelection.setFocusCellForSelection(tableNode.getCellFromCordsOrThrow(x + (isForward ? 1 : -1), y, tableSelection.grid));
1140
1374
  }
1375
+
1141
1376
  return true;
1377
+
1142
1378
  case 'up':
1143
1379
  if (y !== 0) {
1144
1380
  tableSelection.setFocusCellForSelection(tableNode.getCellFromCordsOrThrow(x, y - 1, tableSelection.grid));
@@ -1146,6 +1382,7 @@ const adjustFocusNodeInDirection = (tableSelection, tableNode, x, y, direction)
1146
1382
  } else {
1147
1383
  return false;
1148
1384
  }
1385
+
1149
1386
  case 'down':
1150
1387
  if (y !== tableSelection.grid.rows - 1) {
1151
1388
  tableSelection.setFocusCellForSelection(tableNode.getCellFromCordsOrThrow(x, y + 1, tableSelection.grid));
@@ -1153,20 +1390,25 @@ const adjustFocusNodeInDirection = (tableSelection, tableNode, x, y, direction)
1153
1390
  } else {
1154
1391
  return false;
1155
1392
  }
1393
+
1156
1394
  default:
1157
1395
  return false;
1158
1396
  }
1159
1397
  };
1398
+
1160
1399
  function $isSelectionInTable(selection, tableNode) {
1161
1400
  if (lexical.$isRangeSelection(selection) || lexical.DEPRECATED_$isGridSelection(selection)) {
1162
1401
  const isAnchorInside = tableNode.isParentOf(selection.anchor.getNode());
1163
1402
  const isFocusInside = tableNode.isParentOf(selection.focus.getNode());
1164
1403
  return isAnchorInside && isFocusInside;
1165
1404
  }
1405
+
1166
1406
  return false;
1167
1407
  }
1408
+
1168
1409
  function selectTableCellNode(tableCell) {
1169
1410
  const possibleParagraph = tableCell.getChildren().find(n => lexical.$isParagraphNode(n));
1411
+
1170
1412
  if (lexical.$isParagraphNode(possibleParagraph)) {
1171
1413
  possibleParagraph.selectEnd();
1172
1414
  } else {
@@ -1181,16 +1423,18 @@ function selectTableCellNode(tableCell) {
1181
1423
  * LICENSE file in the root directory of this source tree.
1182
1424
  *
1183
1425
  */
1426
+
1184
1427
  /** @noInheritDoc */
1185
1428
  class TableNode extends lexical.DEPRECATED_GridNode {
1186
1429
  /** @internal */
1187
-
1188
1430
  static getType() {
1189
1431
  return 'table';
1190
1432
  }
1433
+
1191
1434
  static clone(node) {
1192
1435
  return new TableNode(node.__key);
1193
1436
  }
1437
+
1194
1438
  static importDOM() {
1195
1439
  return {
1196
1440
  table: _node => ({
@@ -1199,30 +1443,34 @@ class TableNode extends lexical.DEPRECATED_GridNode {
1199
1443
  })
1200
1444
  };
1201
1445
  }
1446
+
1202
1447
  static importJSON(_serializedNode) {
1203
1448
  return $createTableNode();
1204
1449
  }
1450
+
1205
1451
  constructor(key) {
1206
1452
  super(key);
1207
1453
  }
1454
+
1208
1455
  exportJSON() {
1209
- return {
1210
- ...super.exportJSON(),
1456
+ return { ...super.exportJSON(),
1211
1457
  type: 'table',
1212
1458
  version: 1
1213
1459
  };
1214
1460
  }
1461
+
1215
1462
  createDOM(config, editor) {
1216
1463
  const tableElement = document.createElement('table');
1217
1464
  utils.addClassNamesToElement(tableElement, config.theme.table);
1218
1465
  return tableElement;
1219
1466
  }
1467
+
1220
1468
  updateDOM() {
1221
1469
  return false;
1222
1470
  }
1471
+
1223
1472
  exportDOM(editor) {
1224
- return {
1225
- ...super.exportDOM(editor),
1473
+ return { ...super.exportDOM(editor),
1226
1474
  after: tableElement => {
1227
1475
  if (tableElement) {
1228
1476
  const newElement = tableElement.cloneNode();
@@ -1230,45 +1478,57 @@ class TableNode extends lexical.DEPRECATED_GridNode {
1230
1478
  const tBody = document.createElement('tbody');
1231
1479
  tBody.append(...tableElement.children);
1232
1480
  const firstRow = this.getFirstChildOrThrow();
1481
+
1233
1482
  if (!$isTableRowNode(firstRow)) {
1234
1483
  throw new Error('Expected to find row node.');
1235
1484
  }
1485
+
1236
1486
  const colCount = firstRow.getChildrenSize();
1487
+
1237
1488
  for (let i = 0; i < colCount; i++) {
1238
1489
  const col = document.createElement('col');
1239
1490
  colGroup.append(col);
1240
1491
  }
1492
+
1241
1493
  newElement.replaceChildren(colGroup, tBody);
1242
1494
  return newElement;
1243
1495
  }
1244
1496
  }
1245
1497
  };
1246
1498
  }
1499
+
1247
1500
  canExtractContents() {
1248
1501
  return false;
1249
1502
  }
1503
+
1250
1504
  canBeEmpty() {
1251
1505
  return false;
1252
1506
  }
1507
+
1253
1508
  isShadowRoot() {
1254
1509
  return true;
1255
1510
  }
1511
+
1256
1512
  getCordsFromCellNode(tableCellNode, grid) {
1257
1513
  const {
1258
1514
  rows,
1259
1515
  cells
1260
1516
  } = grid;
1517
+
1261
1518
  for (let y = 0; y < rows; y++) {
1262
1519
  const row = cells[y];
1520
+
1263
1521
  if (row == null) {
1264
1522
  throw new Error(`Row not found at y:${y}`);
1265
1523
  }
1524
+
1266
1525
  const x = row.findIndex(({
1267
1526
  elem
1268
1527
  }) => {
1269
1528
  const cellNode = lexical.$getNearestNodeFromDOMNode(elem);
1270
1529
  return cellNode === tableCellNode;
1271
1530
  });
1531
+
1272
1532
  if (x !== -1) {
1273
1533
  return {
1274
1534
  x,
@@ -1276,59 +1536,81 @@ class TableNode extends lexical.DEPRECATED_GridNode {
1276
1536
  };
1277
1537
  }
1278
1538
  }
1539
+
1279
1540
  throw new Error('Cell not found in table.');
1280
1541
  }
1542
+
1281
1543
  getCellFromCords(x, y, grid) {
1282
1544
  const {
1283
1545
  cells
1284
1546
  } = grid;
1285
1547
  const row = cells[y];
1548
+
1286
1549
  if (row == null) {
1287
1550
  return null;
1288
1551
  }
1552
+
1289
1553
  const cell = row[x];
1554
+
1290
1555
  if (cell == null) {
1291
1556
  return null;
1292
1557
  }
1558
+
1293
1559
  return cell;
1294
1560
  }
1561
+
1295
1562
  getCellFromCordsOrThrow(x, y, grid) {
1296
1563
  const cell = this.getCellFromCords(x, y, grid);
1564
+
1297
1565
  if (!cell) {
1298
1566
  throw new Error('Cell not found at cords.');
1299
1567
  }
1568
+
1300
1569
  return cell;
1301
1570
  }
1571
+
1302
1572
  getCellNodeFromCords(x, y, grid) {
1303
1573
  const cell = this.getCellFromCords(x, y, grid);
1574
+
1304
1575
  if (cell == null) {
1305
1576
  return null;
1306
1577
  }
1578
+
1307
1579
  const node = lexical.$getNearestNodeFromDOMNode(cell.elem);
1580
+
1308
1581
  if ($isTableCellNode(node)) {
1309
1582
  return node;
1310
1583
  }
1584
+
1311
1585
  return null;
1312
1586
  }
1587
+
1313
1588
  getCellNodeFromCordsOrThrow(x, y, grid) {
1314
1589
  const node = this.getCellNodeFromCords(x, y, grid);
1590
+
1315
1591
  if (!node) {
1316
1592
  throw new Error('Node at cords not TableCellNode.');
1317
1593
  }
1594
+
1318
1595
  return node;
1319
1596
  }
1597
+
1320
1598
  canSelectBefore() {
1321
1599
  return true;
1322
1600
  }
1601
+
1323
1602
  canIndent() {
1324
1603
  return false;
1325
1604
  }
1605
+
1326
1606
  }
1327
1607
  function $getElementGridForTableNode(editor, tableNode) {
1328
1608
  const tableElement = editor.getElementByKey(tableNode.getKey());
1609
+
1329
1610
  if (tableElement == null) {
1330
1611
  throw new Error('Table Element Not Found');
1331
1612
  }
1613
+
1332
1614
  return getTableGrid(tableElement);
1333
1615
  }
1334
1616
  function convertTableElement(_domNode) {
@@ -1352,10 +1634,13 @@ function $isTableNode(node) {
1352
1634
  */
1353
1635
  function $createTableNodeWithDimensions(rowCount, columnCount, includeHeaders = true) {
1354
1636
  const tableNode = $createTableNode();
1637
+
1355
1638
  for (let iRow = 0; iRow < rowCount; iRow++) {
1356
1639
  const tableRowNode = $createTableRowNode();
1640
+
1357
1641
  for (let iColumn = 0; iColumn < columnCount; iColumn++) {
1358
1642
  let headerState = TableCellHeaderStates.NO_STATUS;
1643
+
1359
1644
  if (typeof includeHeaders === 'object') {
1360
1645
  if (iRow === 0 && includeHeaders.rows) headerState |= TableCellHeaderStates.ROW;
1361
1646
  if (iColumn === 0 && includeHeaders.columns) headerState |= TableCellHeaderStates.COLUMN;
@@ -1363,35 +1648,44 @@ function $createTableNodeWithDimensions(rowCount, columnCount, includeHeaders =
1363
1648
  if (iRow === 0) headerState |= TableCellHeaderStates.ROW;
1364
1649
  if (iColumn === 0) headerState |= TableCellHeaderStates.COLUMN;
1365
1650
  }
1651
+
1366
1652
  const tableCellNode = $createTableCellNode(headerState);
1367
1653
  const paragraphNode = lexical.$createParagraphNode();
1368
1654
  paragraphNode.append(lexical.$createTextNode());
1369
1655
  tableCellNode.append(paragraphNode);
1370
1656
  tableRowNode.append(tableCellNode);
1371
1657
  }
1658
+
1372
1659
  tableNode.append(tableRowNode);
1373
1660
  }
1661
+
1374
1662
  return tableNode;
1375
1663
  }
1376
1664
  function $getTableCellNodeFromLexicalNode(startingNode) {
1377
1665
  const node = utils.$findMatchingParent(startingNode, n => $isTableCellNode(n));
1666
+
1378
1667
  if ($isTableCellNode(node)) {
1379
1668
  return node;
1380
1669
  }
1670
+
1381
1671
  return null;
1382
1672
  }
1383
1673
  function $getTableRowNodeFromTableCellNodeOrThrow(startingNode) {
1384
1674
  const node = utils.$findMatchingParent(startingNode, n => $isTableRowNode(n));
1675
+
1385
1676
  if ($isTableRowNode(node)) {
1386
1677
  return node;
1387
1678
  }
1679
+
1388
1680
  throw new Error('Expected table cell to be inside of table row.');
1389
1681
  }
1390
1682
  function $getTableNodeFromLexicalNodeOrThrow(startingNode) {
1391
1683
  const node = utils.$findMatchingParent(startingNode, n => $isTableNode(n));
1684
+
1392
1685
  if ($isTableNode(node)) {
1393
1686
  return node;
1394
1687
  }
1688
+
1395
1689
  throw new Error('Expected table cell to be inside of table.');
1396
1690
  }
1397
1691
  function $getTableRowIndexFromTableCellNode(tableCellNode) {
@@ -1418,42 +1712,53 @@ function $getTableCellSiblingsFromTableCellNode(tableCellNode, grid) {
1418
1712
  }
1419
1713
  function $removeTableRowAtIndex(tableNode, indexToDelete) {
1420
1714
  const tableRows = tableNode.getChildren();
1715
+
1421
1716
  if (indexToDelete >= tableRows.length || indexToDelete < 0) {
1422
1717
  throw new Error('Expected table cell to be inside of table row.');
1423
1718
  }
1719
+
1424
1720
  const targetRowNode = tableRows[indexToDelete];
1425
1721
  targetRowNode.remove();
1426
1722
  return tableNode;
1427
1723
  }
1428
1724
  function $insertTableRow(tableNode, targetIndex, shouldInsertAfter = true, rowCount, grid) {
1429
1725
  const tableRows = tableNode.getChildren();
1726
+
1430
1727
  if (targetIndex >= tableRows.length || targetIndex < 0) {
1431
1728
  throw new Error('Table row target index out of range');
1432
1729
  }
1730
+
1433
1731
  const targetRowNode = tableRows[targetIndex];
1732
+
1434
1733
  if ($isTableRowNode(targetRowNode)) {
1435
1734
  for (let r = 0; r < rowCount; r++) {
1436
1735
  const tableRowCells = targetRowNode.getChildren();
1437
1736
  const tableColumnCount = tableRowCells.length;
1438
1737
  const newTableRowNode = $createTableRowNode();
1738
+
1439
1739
  for (let c = 0; c < tableColumnCount; c++) {
1440
1740
  const tableCellFromTargetRow = tableRowCells[c];
1741
+
1441
1742
  if (!$isTableCellNode(tableCellFromTargetRow)) {
1442
1743
  throw Error(`Expected table cell`);
1443
1744
  }
1745
+
1444
1746
  const {
1445
1747
  above,
1446
1748
  below
1447
1749
  } = $getTableCellSiblingsFromTableCellNode(tableCellFromTargetRow, grid);
1448
1750
  let headerState = TableCellHeaderStates.NO_STATUS;
1449
1751
  const width = above && above.getWidth() || below && below.getWidth() || undefined;
1752
+
1450
1753
  if (above && above.hasHeaderState(TableCellHeaderStates.COLUMN) || below && below.hasHeaderState(TableCellHeaderStates.COLUMN)) {
1451
1754
  headerState |= TableCellHeaderStates.COLUMN;
1452
1755
  }
1756
+
1453
1757
  const tableCellNode = $createTableCellNode(headerState, 1, width);
1454
1758
  tableCellNode.append(lexical.$createParagraphNode());
1455
1759
  newTableRowNode.append(tableCellNode);
1456
1760
  }
1761
+
1457
1762
  if (shouldInsertAfter) {
1458
1763
  targetRowNode.insertAfter(newTableRowNode);
1459
1764
  } else {
@@ -1463,32 +1768,42 @@ function $insertTableRow(tableNode, targetIndex, shouldInsertAfter = true, rowCo
1463
1768
  } else {
1464
1769
  throw new Error('Row before insertion index does not exist.');
1465
1770
  }
1771
+
1466
1772
  return tableNode;
1467
1773
  }
1468
1774
  function $insertTableColumn(tableNode, targetIndex, shouldInsertAfter = true, columnCount, grid) {
1469
1775
  const tableRows = tableNode.getChildren();
1776
+
1470
1777
  for (let r = 0; r < tableRows.length; r++) {
1471
1778
  const currentTableRowNode = tableRows[r];
1779
+
1472
1780
  if ($isTableRowNode(currentTableRowNode)) {
1473
1781
  for (let c = 0; c < columnCount; c++) {
1474
1782
  const tableRowChildren = currentTableRowNode.getChildren();
1783
+
1475
1784
  if (targetIndex >= tableRowChildren.length || targetIndex < 0) {
1476
1785
  throw new Error('Table column target index out of range');
1477
1786
  }
1787
+
1478
1788
  const targetCell = tableRowChildren[targetIndex];
1789
+
1479
1790
  if (!$isTableCellNode(targetCell)) {
1480
1791
  throw Error(`Expected table cell`);
1481
1792
  }
1793
+
1482
1794
  const {
1483
1795
  left,
1484
1796
  right
1485
1797
  } = $getTableCellSiblingsFromTableCellNode(targetCell, grid);
1486
1798
  let headerState = TableCellHeaderStates.NO_STATUS;
1799
+
1487
1800
  if (left && left.hasHeaderState(TableCellHeaderStates.ROW) || right && right.hasHeaderState(TableCellHeaderStates.ROW)) {
1488
1801
  headerState |= TableCellHeaderStates.ROW;
1489
1802
  }
1803
+
1490
1804
  const newTableCell = $createTableCellNode(headerState);
1491
1805
  newTableCell.append(lexical.$createParagraphNode());
1806
+
1492
1807
  if (shouldInsertAfter) {
1493
1808
  targetCell.insertAfter(newTableCell);
1494
1809
  } else {
@@ -1497,20 +1812,26 @@ function $insertTableColumn(tableNode, targetIndex, shouldInsertAfter = true, co
1497
1812
  }
1498
1813
  }
1499
1814
  }
1815
+
1500
1816
  return tableNode;
1501
1817
  }
1502
1818
  function $deleteTableColumn(tableNode, targetIndex) {
1503
1819
  const tableRows = tableNode.getChildren();
1820
+
1504
1821
  for (let i = 0; i < tableRows.length; i++) {
1505
1822
  const currentTableRowNode = tableRows[i];
1823
+
1506
1824
  if ($isTableRowNode(currentTableRowNode)) {
1507
1825
  const tableRowChildren = currentTableRowNode.getChildren();
1826
+
1508
1827
  if (targetIndex >= tableRowChildren.length || targetIndex < 0) {
1509
1828
  throw new Error('Table column target index out of range');
1510
1829
  }
1830
+
1511
1831
  tableRowChildren[targetIndex].remove();
1512
1832
  }
1513
1833
  }
1834
+
1514
1835
  return tableNode;
1515
1836
  }
1516
1837