diff --git a/packages/lexical-yjs/src/CollabElementNode.ts b/packages/lexical-yjs/src/CollabElementNode.ts index 2b9ec581c..8d102d628 100644 --- a/packages/lexical-yjs/src/CollabElementNode.ts +++ b/packages/lexical-yjs/src/CollabElementNode.ts @@ -17,6 +17,7 @@ import { $isDecoratorNode, $isElementNode, $isTextNode, + removeFromParent, } from 'lexical'; import invariant from 'shared/invariant'; @@ -29,7 +30,6 @@ import { $syncPropertiesFromYjs, createLexicalNodeFromCollabNode, getPositionFromElementAndOffset, - removeFromParent, spliceString, syncPropertiesFromLexical, } from './Utils'; diff --git a/packages/lexical-yjs/src/Utils.ts b/packages/lexical-yjs/src/Utils.ts index 6c1560ca6..87a35d5f2 100644 --- a/packages/lexical-yjs/src/Utils.ts +++ b/packages/lexical-yjs/src/Utils.ts @@ -559,57 +559,6 @@ export function syncWithTransaction(binding: Binding, fn: () => void): void { binding.doc.transact(fn, binding); } -export function removeFromParent(node: LexicalNode): void { - const oldParent = node.getParent(); - if (oldParent !== null) { - const writableNode = node.getWritable(); - const writableParent = oldParent.getWritable(); - const prevSibling = node.getPreviousSibling(); - const nextSibling = node.getNextSibling(); - // TODO: this function duplicates a bunch of operations, can be simplified. - if (prevSibling === null) { - if (nextSibling !== null) { - const writableNextSibling = nextSibling.getWritable(); - writableParent.__first = nextSibling.__key; - writableNextSibling.__prev = null; - } else { - writableParent.__first = null; - } - } else { - const writablePrevSibling = prevSibling.getWritable(); - if (nextSibling !== null) { - const writableNextSibling = nextSibling.getWritable(); - writableNextSibling.__prev = writablePrevSibling.__key; - writablePrevSibling.__next = writableNextSibling.__key; - } else { - writablePrevSibling.__next = null; - } - writableNode.__prev = null; - } - if (nextSibling === null) { - if (prevSibling !== null) { - const writablePrevSibling = prevSibling.getWritable(); - writableParent.__last = prevSibling.__key; - writablePrevSibling.__next = null; - } else { - writableParent.__last = null; - } - } else { - const writableNextSibling = nextSibling.getWritable(); - if (prevSibling !== null) { - const writablePrevSibling = prevSibling.getWritable(); - writablePrevSibling.__next = writableNextSibling.__key; - writableNextSibling.__prev = writablePrevSibling.__key; - } else { - writableNextSibling.__prev = null; - } - writableNode.__next = null; - } - writableParent.__size--; - writableNode.__parent = null; - } -} - export function $moveSelectionToPreviousNode( anchorNodeKey: string, currentEditorState: EditorState, diff --git a/packages/lexical/src/LexicalUtils.ts b/packages/lexical/src/LexicalUtils.ts index 45e5c56ea..11787b869 100644 --- a/packages/lexical/src/LexicalUtils.ts +++ b/packages/lexical/src/LexicalUtils.ts @@ -339,6 +339,13 @@ function internalMarkParentElementsAsDirty( } // TODO #6031 this function or their callers have to adjust selection (i.e. insertBefore) +/** + * Removes a node from its parent, updating all necessary pointers and links. + * @internal + * + * This function is for internal use of the library. + * Please do not use it as it may change in the future. + */ export function removeFromParent(node: LexicalNode): void { const oldParent = node.getParent(); if (oldParent !== null) { @@ -346,47 +353,40 @@ export function removeFromParent(node: LexicalNode): void { const writableParent = oldParent.getWritable(); const prevSibling = node.getPreviousSibling(); const nextSibling = node.getNextSibling(); - // TODO: this function duplicates a bunch of operations, can be simplified. + + // Store sibling keys + const nextSiblingKey = nextSibling !== null ? nextSibling.__key : null; + const prevSiblingKey = prevSibling !== null ? prevSibling.__key : null; + + // Get writable siblings once + const writablePrevSibling = + prevSibling !== null ? prevSibling.getWritable() : null; + const writableNextSibling = + nextSibling !== null ? nextSibling.getWritable() : null; + + // Update parent's first/last pointers if (prevSibling === null) { - if (nextSibling !== null) { - const writableNextSibling = nextSibling.getWritable(); - writableParent.__first = nextSibling.__key; - writableNextSibling.__prev = null; - } else { - writableParent.__first = null; - } - } else { - const writablePrevSibling = prevSibling.getWritable(); - if (nextSibling !== null) { - const writableNextSibling = nextSibling.getWritable(); - writableNextSibling.__prev = writablePrevSibling.__key; - writablePrevSibling.__next = writableNextSibling.__key; - } else { - writablePrevSibling.__next = null; - } - writableNode.__prev = null; + writableParent.__first = nextSiblingKey; } if (nextSibling === null) { - if (prevSibling !== null) { - const writablePrevSibling = prevSibling.getWritable(); - writableParent.__last = prevSibling.__key; - writablePrevSibling.__next = null; - } else { - writableParent.__last = null; - } - } else { - const writableNextSibling = nextSibling.getWritable(); - if (prevSibling !== null) { - const writablePrevSibling = prevSibling.getWritable(); - writablePrevSibling.__next = writableNextSibling.__key; - writableNextSibling.__prev = writablePrevSibling.__key; - } else { - writableNextSibling.__prev = null; - } - writableNode.__next = null; + writableParent.__last = prevSiblingKey; } - writableParent.__size--; + + // Update sibling links + if (writablePrevSibling !== null) { + writablePrevSibling.__next = nextSiblingKey; + } + if (writableNextSibling !== null) { + writableNextSibling.__prev = prevSiblingKey; + } + + // Clear node's links + writableNode.__prev = null; + writableNode.__next = null; writableNode.__parent = null; + + // Update parent size + writableParent.__size--; } } diff --git a/packages/lexical/src/index.ts b/packages/lexical/src/index.ts index 3ee9494f7..1b0bab383 100644 --- a/packages/lexical/src/index.ts +++ b/packages/lexical/src/index.ts @@ -262,6 +262,7 @@ export { isLexicalEditor, isSelectionCapturedInDecoratorInput, isSelectionWithinEditor, + removeFromParent, resetRandomKey, setDOMUnmanaged, setNodeIndentFromDOM,