From 0238ea29a21082a35eb45103c1f8d19e73926184 Mon Sep 17 00:00:00 2001 From: GermanJablo <43938777+GermanJablo@users.noreply.github.com> Date: Fri, 1 Dec 2023 16:16:33 -0300 Subject: [PATCH] selectEnd/start as a method of LexicalNode instead of ElementNode (#5205) Co-authored-by: EgonBolton <43938777+EgonBolton@users.noreply.github.com> --- .../docs/concepts/selection.md | 2 +- packages/lexical/src/LexicalNode.ts | 8 ++++++++ packages/lexical/src/LexicalSelection.ts | 19 ++++--------------- .../lexical/src/nodes/LexicalElementNode.ts | 18 ++---------------- packages/lexical/src/nodes/LexicalTextNode.ts | 9 +++++++++ 5 files changed, 24 insertions(+), 32 deletions(-) diff --git a/packages/lexical-website/docs/concepts/selection.md b/packages/lexical-website/docs/concepts/selection.md index 8a54f1a562f..19dd4062156 100644 --- a/packages/lexical-website/docs/concepts/selection.md +++ b/packages/lexical-website/docs/concepts/selection.md @@ -101,7 +101,7 @@ editor.update(() => { someNode.selectPrevious(); someNode.selectNext(); - // On element nodes, you can use these. + // You can use this on any node. someNode.selectStart(); someNode.selectEnd(); diff --git a/packages/lexical/src/LexicalNode.ts b/packages/lexical/src/LexicalNode.ts index 9eb7915d88f..2d721cf1d8a 100644 --- a/packages/lexical/src/LexicalNode.ts +++ b/packages/lexical/src/LexicalNode.ts @@ -1024,6 +1024,14 @@ export class LexicalNode { return $createParagraphNode(); } + selectStart(): RangeSelection { + return this.selectPrevious(); + } + + selectEnd(): RangeSelection { + return this.selectNext(0, 0); + } + /** * Moves selection to the previous sibling of this node, at the specified offsets. * diff --git a/packages/lexical/src/LexicalSelection.ts b/packages/lexical/src/LexicalSelection.ts index bc086f1e183..3ba10f136a8 100644 --- a/packages/lexical/src/LexicalSelection.ts +++ b/packages/lexical/src/LexicalSelection.ts @@ -1556,6 +1556,7 @@ export class RangeSelection implements BaseSelection { return selection.insertNodes(nodes); } const firstBlock = $getAncestor(this.anchor.getNode(), INTERNAL_$isBlock)!; + const last = nodes[nodes.length - 1]!; // CASE 1: insert inside a code block if ('__language' in firstBlock) { @@ -1564,10 +1565,7 @@ export class RangeSelection implements BaseSelection { } else { const index = removeTextAndSplitBlock(this); firstBlock.splice(index, 0, nodes); - const last = nodes[nodes.length - 1]!; - if (last.select) { - last.select(); - } else last.selectNext(0, 0); + last.selectEnd(); } return; } @@ -1576,22 +1574,13 @@ export class RangeSelection implements BaseSelection { const notInline = (node: LexicalNode) => ($isElementNode(node) || $isDecoratorNode(node)) && !node.isInline(); - const last = nodes[nodes.length - 1]!; const nodeToSelect = $isElementNode(last) ? last.getLastDescendant() || last : last; - const nodeToSelectSize = nodeToSelect.getTextContentSize(); - function restoreSelection() { - if (nodeToSelect.select) { - nodeToSelect.select(nodeToSelectSize, nodeToSelectSize); - } else { - nodeToSelect.selectNext(0, 0); - } - } if (!nodes.some(notInline)) { const index = removeTextAndSplitBlock(this); firstBlock.splice(index, 0, nodes); - restoreSelection(); + nodeToSelect.selectEnd(); return; } @@ -1631,7 +1620,7 @@ export class RangeSelection implements BaseSelection { firstBlock.remove(); } - restoreSelection(); + nodeToSelect.selectEnd(); // To understand this take a look at the test "can wrap post-linebreak nodes into new element" const lastChild = $isElementNode(firstBlock) diff --git a/packages/lexical/src/nodes/LexicalElementNode.ts b/packages/lexical/src/nodes/LexicalElementNode.ts index 9e2a6e5d22d..a768f089fa3 100644 --- a/packages/lexical/src/nodes/LexicalElementNode.ts +++ b/packages/lexical/src/nodes/LexicalElementNode.ts @@ -339,25 +339,11 @@ export class ElementNode extends LexicalNode { } selectStart(): RangeSelection { const firstNode = this.getFirstDescendant(); - if ($isElementNode(firstNode) || $isTextNode(firstNode)) { - return firstNode.select(0, 0); - } - // Decorator or LineBreak - if (firstNode !== null) { - return firstNode.selectPrevious(); - } - return this.select(0, 0); + return firstNode ? firstNode.selectStart() : this.select(); } selectEnd(): RangeSelection { const lastNode = this.getLastDescendant(); - if ($isElementNode(lastNode) || $isTextNode(lastNode)) { - return lastNode.select(); - } - // Decorator or LineBreak - if (lastNode !== null) { - return lastNode.selectNext(); - } - return this.select(); + return lastNode ? lastNode.selectEnd() : this.select(); } clear(): this { const writableSelf = this.getWritable(); diff --git a/packages/lexical/src/nodes/LexicalTextNode.ts b/packages/lexical/src/nodes/LexicalTextNode.ts index de9585477aa..a25628b8249 100644 --- a/packages/lexical/src/nodes/LexicalTextNode.ts +++ b/packages/lexical/src/nodes/LexicalTextNode.ts @@ -807,6 +807,15 @@ export class TextNode extends LexicalNode { return selection; } + selectStart(): RangeSelection { + return this.select(0, 0); + } + + selectEnd(): RangeSelection { + const size = this.getTextContentSize(); + return this.select(size, size); + } + /** * Inserts the provided text into this TextNode at the provided offset, deleting the number of characters * specified. Can optionally calculate a new selection after the operation is complete.