Skip to content

Commit

Permalink
Fix insertNodes after selection swap (#5175)
Browse files Browse the repository at this point in the history
  • Loading branch information
zurfyx authored Oct 30, 2023
1 parent 68662bf commit 1841b2d
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@ import {
import {
$createLineBreakNode,
$createParagraphNode,
$createRangeSelection,
$createTextNode,
$getNodeByKey,
$getRoot,
$getSelection,
$insertNodes,
$isNodeSelection,
$isRangeSelection,
$setSelection,
RangeSelection,
TextNode,
} from 'lexical';
Expand All @@ -30,6 +32,7 @@ import {
$createTestElementNode,
$createTestShadowRootNode,
createTestEditor,
createTestHeadlessEditor,
TestDecoratorNode,
} from 'lexical/src/__tests__/utils';

Expand Down Expand Up @@ -2669,6 +2672,35 @@ describe('insertNodes', () => {
'<p dir="ltr"><span data-lexical-text="true">Text after</span></p>',
);
});

it('can insert when previous selection was null', async () => {
const editor = createTestHeadlessEditor();
await editor.update(() => {
const selection = $createRangeSelection();
selection.anchor.set('root', 0, 'element');
selection.focus.set('root', 0, 'element');

selection.insertNodes([
$createParagraphNode().append($createTextNode('Text')),
]);

expect($getRoot().getTextContent()).toBe('Text');

$setSelection(null);
});
await editor.update(() => {
const selection = $createRangeSelection();
const text = $getRoot().getLastDescendant();
selection.anchor.set(text.getKey(), 0, 'text');
selection.focus.set(text.getKey(), 0, 'text');

selection.insertNodes([
$createParagraphNode().append($createTextNode('Before ')),
]);

expect($getRoot().getTextContent()).toBe('Before Text');
});
});
});

describe('$patchStyleText', () => {
Expand Down
8 changes: 7 additions & 1 deletion packages/lexical/src/LexicalSelection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1522,12 +1522,18 @@ export class RangeSelection implements BaseSelection {
*
* @param nodes - the nodes to insert
*/
insertNodes(nodes: Array<LexicalNode>) {
insertNodes(nodes: Array<LexicalNode>): void {
if (nodes.length === 0) {
return;
}
if (this.anchor.key === 'root') {
this.insertParagraph();
const selection = $getSelection();
invariant(
$isRangeSelection(selection),
'Expected RangeSelection after insertParagraph',
);
return selection.insertNodes(nodes);
}
const firstBlock = $getAncestor(this.anchor.getNode(), INTERNAL_$isBlock)!;

Expand Down
10 changes: 10 additions & 0 deletions packages/lexical/src/__tests__/utils/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import {CodeHighlightNode, CodeNode} from '@lexical/code';
import {HashtagNode} from '@lexical/hashtag';
import {createHeadlessEditor} from '@lexical/headless';
import {AutoLinkNode, LinkNode} from '@lexical/link';
import {ListItemNode, ListNode} from '@lexical/list';
import {OverflowNode} from '@lexical/overflow';
Expand Down Expand Up @@ -504,6 +505,15 @@ export function createTestEditor(
return editor;
}

export function createTestHeadlessEditor(): LexicalEditor {
return createHeadlessEditor({
namespace: '',
onError: (error) => {
throw error;
},
});
}

export function $assertRangeSelection(selection): RangeSelection {
if (!$isRangeSelection(selection)) {
throw new Error(`Expected RangeSelection, got ${selection}`);
Expand Down

2 comments on commit 1841b2d

@vercel
Copy link

@vercel vercel bot commented on 1841b2d Oct 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

lexical – ./packages/lexical-website

lexical-git-main-fbopensource.vercel.app
lexical.dev
lexical-fbopensource.vercel.app
lexicaljs.com
lexicaljs.org
www.lexical.dev

@vercel
Copy link

@vercel vercel bot commented on 1841b2d Oct 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

lexical-playground – ./packages/lexical-playground

lexical-playground.vercel.app
playground.lexical.dev
lexical-playground-fbopensource.vercel.app
lexical-playground-git-main-fbopensource.vercel.app

Please sign in to comment.