Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: RangeSelection.modify() at the beginning of a paragraph incorrectly selects the inlineDecorator of the previous block #7165

Closed
GermanJablo opened this issue Feb 11, 2025 · 2 comments

Comments

@GermanJablo
Copy link
Contributor

The original report is here, where you can see that an inline-block is incorrectly removed if it is at the end of a block and backspace is pressed at the beginning of the next one.

I was able to trace the problem back to RangeSelection.modify().

Lexical version: 0.21.0

Steps To Reproduce

  1. Create a paragraph with an inlineDecorator at the end.
  2. In the next empty paragraph, press backspace, or alternatively click the following plugin button:
function MyPlugin() {
  const [editor] = useLexicalComposerContext()

  return <button onClick={() => {
    editor.update(() => {
      const selection = $getSelection()
      if ($isRangeSelection(selection)) {
        selection.modify('extend', true, 'character')
      }
    })
    }}
  >
    Extend selection one character backward
  </button>
}

I was trying to make the following test to make it easier to resolve the bug, but then I realized that RangeSelection.modify is using the window object and won't work in unit tests that are configured with Node, so I gave up:

    test('RangeSelection.modify() at the beginning of a paragraph. The previous block ends with inlineDecorator', () => {
      const editor = createEditor({
        nodes: [TestDecoratorNode],
      });
      editor.update(() => {
        const firstParagraph = $createParagraphNode().append(
          $createTextNode('hello world'),
          $createTestDecoratorNode(),
        );
        const secondParagraph = $createParagraphNode();
        $getRoot().clear().append(firstParagraph, secondParagraph);
        secondParagraph.select().modify('extend', true, 'character');
        const {anchor, focus} = $getSelection() as RangeSelection;
        // TODO: expects...
      });
    });

The current behavior

The final selection covers the inline decorator if you use my plugin, or removes the decorator if you press backspace.

The expected behavior

The final selection does not cover the inline decorator if you use my plugin, and it does not remove the decorator if you press backspace

@etrepum
Copy link
Collaborator

etrepum commented Feb 11, 2025

I can't reproduce this in the playground, for example this doc has an equation at the end which is an inline decorator. The DELETE_CHARACTER_COMMAND has workarounds for this before the selection is modified. I suspect that #7155 would fix this if you did have a case where it doesn't work, although it also leaves the workaround in that command rather than fixing the RangeSelection behavior directly.

@GermanJablo
Copy link
Contributor Author

Thanks, I just checked and this doesn't work in 0.21.0, but it does in 0.24.0, so it must have been fixed somewhere in the middle.
We'll have to upgrade!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants