From 34c3b603800d7912c4994fa2e2535073a2320d04 Mon Sep 17 00:00:00 2001 From: tylerjbainbridge Date: Thu, 22 Sep 2022 13:22:00 -0400 Subject: [PATCH 1/2] Improve table selection handling when there are no siblings --- .../src/LexicalTableSelectionHelpers.ts | 45 +++++++++++++++++-- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/packages/lexical-table/src/LexicalTableSelectionHelpers.ts b/packages/lexical-table/src/LexicalTableSelectionHelpers.ts index 7991138ad38..a3f5db26313 100644 --- a/packages/lexical-table/src/LexicalTableSelectionHelpers.ts +++ b/packages/lexical-table/src/LexicalTableSelectionHelpers.ts @@ -36,6 +36,7 @@ import { DELETE_CHARACTER_COMMAND, DELETE_LINE_COMMAND, DELETE_WORD_COMMAND, + DEPRECATED_$createGridSelection, DEPRECATED_$isGridSelection, FOCUS_COMMAND, FORMAT_TEXT_COMMAND, @@ -629,11 +630,11 @@ export function applyTableHandlers( const isAnchorInside = tableNode.isParentOf(anchorNode); const isFocusInside = tableNode.isParentOf(focusNode); - const containsPartialTable = + const selectionContainsPartialTable = (isAnchorInside && !isFocusInside) || (isFocusInside && !isAnchorInside); - if (containsPartialTable) { + if (selectionContainsPartialTable) { tableSelection.clearText(); return true; } @@ -890,11 +891,14 @@ export function applyTableHandlers( const isAnchorInside = tableNode.isParentOf(anchorNode); const isFocusInside = tableNode.isParentOf(focusNode); - const containsPartialTable = + const selectionContainsPartialTable = (isAnchorInside && !isFocusInside) || (isFocusInside && !isAnchorInside); - if (containsPartialTable) { + const selectionIsInsideTable = + isAnchorInside && isFocusInside && !tableNode.isSelected(); + + if (selectionContainsPartialTable) { const isBackward = selection.isBackward(); const modifiedSelection = $createRangeSelection(); const tableKey = tableNode.getKey(); @@ -916,6 +920,39 @@ export function applyTableHandlers( $addHighlightStyleToTable(tableSelection); return true; + } else if (selectionIsInsideTable) { + const {grid} = tableSelection; + + if ( + selection.getNodes().filter($isTableCellNode).length === + grid.rows * grid.columns + ) { + const gridSelection = DEPRECATED_$createGridSelection(); + const tableKey = tableNode.getKey(); + const tableFirstDescendant = tableNode.getFirstDescendant(); + const tableLastDescendant = tableNode.getLastDescendant(); + + const firstCell = + tableFirstDescendant && + $findMatchingParent(tableFirstDescendant, $isTableCellNode); + + const lastCell = + tableLastDescendant && + $findMatchingParent(tableLastDescendant, $isTableCellNode); + + if (firstCell != null && lastCell != null) { + gridSelection.set( + tableKey, + firstCell.getKey(), + lastCell.getKey(), + ); + + $setSelection(gridSelection); + tableSelection.updateTableGridSelection(gridSelection); + + return true; + } + } } } From f442c5e81f83825449d510e6ee3457792352aee5 Mon Sep 17 00:00:00 2001 From: tylerjbainbridge Date: Thu, 22 Sep 2022 15:41:31 -0400 Subject: [PATCH 2/2] Refine solution --- .../src/LexicalTableSelectionHelpers.ts | 12 ++++-------- packages/lexical/flow/Lexical.js.flow | 1 + packages/lexical/src/nodes/LexicalElementNode.ts | 7 +++++++ 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/packages/lexical-table/src/LexicalTableSelectionHelpers.ts b/packages/lexical-table/src/LexicalTableSelectionHelpers.ts index a3f5db26313..a1ad0dc5be3 100644 --- a/packages/lexical-table/src/LexicalTableSelectionHelpers.ts +++ b/packages/lexical-table/src/LexicalTableSelectionHelpers.ts @@ -929,16 +929,12 @@ export function applyTableHandlers( ) { const gridSelection = DEPRECATED_$createGridSelection(); const tableKey = tableNode.getKey(); - const tableFirstDescendant = tableNode.getFirstDescendant(); - const tableLastDescendant = tableNode.getLastDescendant(); - const firstCell = - tableFirstDescendant && - $findMatchingParent(tableFirstDescendant, $isTableCellNode); + const firstCell = tableNode + .getFirstChildOrThrow() + .getFirstChild(); - const lastCell = - tableLastDescendant && - $findMatchingParent(tableLastDescendant, $isTableCellNode); + const lastCell = tableNode.getLastChildOrThrow().getLastChild(); if (firstCell != null && lastCell != null) { gridSelection.set( diff --git a/packages/lexical/flow/Lexical.js.flow b/packages/lexical/flow/Lexical.js.flow index 801a118ca54..9a21826f70e 100644 --- a/packages/lexical/flow/Lexical.js.flow +++ b/packages/lexical/flow/Lexical.js.flow @@ -681,6 +681,7 @@ declare export class ElementNode extends LexicalNode { getFirstChild(): null | T; getFirstChildOrThrow(): T; getLastChild(): null | T; + getLastChildOrThrow(): T; getChildAtIndex(index: number): null | T; getTextContent(): string; getDirection(): 'ltr' | 'rtl' | null; diff --git a/packages/lexical/src/nodes/LexicalElementNode.ts b/packages/lexical/src/nodes/LexicalElementNode.ts index 63d0a1f2bfe..c1edc598d7e 100644 --- a/packages/lexical/src/nodes/LexicalElementNode.ts +++ b/packages/lexical/src/nodes/LexicalElementNode.ts @@ -201,6 +201,13 @@ export class ElementNode extends LexicalNode { } return $getNodeByKey(children[childrenLength - 1]); } + getLastChildOrThrow(): T { + const lastChild = this.getLastChild(); + if (lastChild === null) { + invariant(false, 'Expected node %s to have a last child.', this.__key); + } + return lastChild; + } getChildAtIndex(index: number): null | T { const self = this.getLatest(); const children = self.__children;