From 732f3dda2ecc6052c3d78329a564594eb45b38c2 Mon Sep 17 00:00:00 2001 From: Bob Ippolito Date: Fri, 4 Oct 2024 16:08:19 -0700 Subject: [PATCH] Fix #6701 insertion into inline ElementNode --- packages/lexical/src/LexicalSelection.ts | 19 +++++++++++++------ packages/lexical/src/LexicalUtils.ts | 2 +- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/packages/lexical/src/LexicalSelection.ts b/packages/lexical/src/LexicalSelection.ts index 8f851d4cfa4..fc06fd21865 100644 --- a/packages/lexical/src/LexicalSelection.ts +++ b/packages/lexical/src/LexicalSelection.ts @@ -1334,7 +1334,7 @@ export class RangeSelection implements BaseSelection { /** * Attempts to "intelligently" insert an arbitrary list of Lexical nodes into the EditorState at the * current Selection according to a set of heuristics that determine how surrounding nodes - * should be changed, replaced, or moved to accomodate the incoming ones. + * should be changed, replaced, or moved to accommodate the incoming ones. * * @param nodes - the nodes to insert */ @@ -1353,12 +1353,13 @@ export class RangeSelection implements BaseSelection { } const firstPoint = this.isBackward() ? this.focus : this.anchor; - const firstBlock = $getAncestor(firstPoint.getNode(), INTERNAL_$isBlock)!; + const firstNode = firstPoint.getNode(); + const firstBlock = $getAncestor(firstNode, INTERNAL_$isBlock); const last = nodes[nodes.length - 1]!; // CASE 1: insert inside a code block - if ('__language' in firstBlock && $isElementNode(firstBlock)) { + if ($isElementNode(firstBlock) && '__language' in firstBlock) { if ('__language' in nodes[0]) { this.insertText(nodes[0].getTextContent()); } else { @@ -1397,8 +1398,8 @@ export class RangeSelection implements BaseSelection { const shouldInsert = !$isElementNode(firstBlock) || !firstBlock.isEmpty(); const insertedParagraph = shouldInsert ? this.insertParagraph() : null; - const lastToInsert = blocks[blocks.length - 1]; - let firstToInsert = blocks[0]; + const lastToInsert: LexicalNode | undefined = blocks[blocks.length - 1]; + let firstToInsert: LexicalNode | undefined = blocks[0]; if (isMergeable(firstToInsert)) { invariant( $isElementNode(firstBlock), @@ -1408,9 +1409,15 @@ export class RangeSelection implements BaseSelection { firstToInsert = blocks[1]; } if (firstToInsert) { + invariant( + firstBlock !== null, + 'Expected node %s of type %s to have a block ElementNode ancestor', + firstNode.constructor.name, + firstNode.getType(), + ); insertRangeAfter(firstBlock, firstToInsert); } - const lastInsertedBlock = $getAncestor(nodeToSelect, INTERNAL_$isBlock)!; + const lastInsertedBlock = $getAncestor(nodeToSelect, INTERNAL_$isBlock); if ( insertedParagraph && diff --git a/packages/lexical/src/LexicalUtils.ts b/packages/lexical/src/LexicalUtils.ts index bf7904d3b90..472703d63d5 100644 --- a/packages/lexical/src/LexicalUtils.ts +++ b/packages/lexical/src/LexicalUtils.ts @@ -1732,7 +1732,7 @@ export function INTERNAL_$isBlock( export function $getAncestor( node: LexicalNode, predicate: (ancestor: LexicalNode) => ancestor is NodeType, -) { +): NodeType | null { let parent = node; while (parent !== null && parent.getParent() !== null && !predicate(parent)) { parent = parent.getParentOrThrow();