Open emsurezhang opened 4 days ago
In LexicalSelection.ts removeText() function, I simply remove the node.remove line, it workes fine.
/**
* Removes the text in the Selection, adjusting the EditorState accordingly.
*/
removeText(): void {
if (this.isCollapsed()) {
return;
}
const {anchor, focus} = this;
const selectedNodes = this.getNodes();
const firstPoint = this.isBackward() ? focus : anchor;
const lastPoint = this.isBackward() ? anchor : focus;
let firstNode = firstPoint.getNode();
let lastNode = lastPoint.getNode();
const firstBlock = $getAncestor(firstNode, INTERNAL_$isBlock);
const lastBlock = $getAncestor(lastNode, INTERNAL_$isBlock);
// If a token is partially selected then move the selection to cover the whole selection
if (
$isTextNode(firstNode) &&
firstNode.isToken() &&
firstPoint.offset < firstNode.getTextContentSize()
) {
firstPoint.offset = 0;
}
if (lastPoint.offset > 0 && $isTextNode(lastNode) && lastNode.isToken()) {
lastPoint.offset = lastNode.getTextContentSize();
}
selectedNodes.forEach((node) => {
if (
!$hasAncestor(firstNode, node) &&
!$hasAncestor(lastNode, node) &&
node.getKey() !== firstNode.getKey() &&
node.getKey() !== lastNode.getKey()
) {
console.log("remove node", node.getKey())
**// node.remove();**
}
});
const fixText = (node: TextNode, del: number) => {
if (node.getTextContent() === '') {
node.remove();
} else if (del !== 0 && $isTokenOrSegmented(node)) {
const textNode = $createTextNode(node.getTextContent());
textNode.setFormat(node.getFormat());
textNode.setStyle(node.getStyle());
return node.replace(textNode);
}
};
if (firstNode === lastNode && $isTextNode(firstNode)) {
const del = Math.abs(focus.offset - anchor.offset);
firstNode.spliceText(firstPoint.offset, del, '', true);
fixText(firstNode, del);
return;
}
if ($isTextNode(firstNode)) {
const del = firstNode.getTextContentSize() - firstPoint.offset;
firstNode.spliceText(firstPoint.offset, del, '');
firstNode = fixText(firstNode, del) || firstNode;
}
if ($isTextNode(lastNode)) {
lastNode.spliceText(0, lastPoint.offset, '');
lastNode = fixText(lastNode, lastPoint.offset) || lastNode;
}
if (firstNode.isAttached() && $isTextNode(firstNode)) {
firstNode.selectEnd();
} else if (lastNode.isAttached() && $isTextNode(lastNode)) {
lastNode.selectStart();
}
// Merge blocks
const bothElem = $isElementNode(firstBlock) && $isElementNode(lastBlock);
if (bothElem && firstBlock !== lastBlock) {
firstBlock.append(...lastBlock.getChildren());
lastBlock.remove();
lastPoint.set(firstPoint.key, firstPoint.offset, firstPoint.type);
}
}
is there any suggestion to fix it ?
I think the real reason is after delete ParagraphNode the selection should be collapsed, so in the remove.text function
if (this.isCollapsed()) {
return;
}
will be return, the node.remove() will not run.
update: in LexicalSelection.ts file, change the native selection move mode from "extend" to "move", cause isCollapsed is true. at line 1781: this.modify('extend', isBackward, 'character'); => this.modify('move', isBackward, 'character');
In the playground, I insert an ImageNode and press enter to start a new ParagraphNode. The cursor is at ParagraphNode which key is 4. Now I press backward and expect only the ParagraphNode key 4 is deleted. But the result is the ImageNode is deleted too.