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

[Breaking Change][lexical][lexical-playground] Bug Fix: Improve character deletion around shadow roots and decorators #7155

Merged
merged 13 commits into from
Feb 18, 2025

Conversation

etrepum
Copy link
Collaborator

@etrepum etrepum commented Feb 9, 2025

Breaking Change

The heuristic used in RangeSelection.deleteCharacter to handle merging blocks and deleting decorators from a collapsed selection has been refactored for consistency. It now traverses the node tree directly instead of attempting to use browser selection APIs.

This generally has much more predictable results, aligned with how this method is expected to behave, but it is not "bug for bug" compatible with how it worked previously. Notably, it will no longer pierce shadow roots when merging blocks. For example, performing a forward deletion from the end of a block before a CollapsibleContainerNode would pierce the shadow root of its CollapsibleTitleNode and merge its first block child (e.g. the preceding paragraph and the title's paragraph would be merged). Since there was a test that expected this strange behavior, this functionality was moved to the CollapsiblePlugin's DELETE_CHARACTER_COMMAND command listener.

Description

Allowing the native platform to control deletion only really makes sense when the content to be deleted includes a TextNode, otherwise we are better off handling it ourselves. There's also some "interesting" edge cases around nested elements (with or without shadow roots) and decorators that need to be addressed by this sort of manual navigation.

Other fixes:

Closes #7082
Closes #7090
Closes #5686
Closes #7173
Closes #6763
Closes #7184

Test plan

Before

  • Using character deletion from inside of a TextNode at the beginning of a block, when that block has a TableNode or block decorator previous sibling, would affect the TextNode (Bug: Backspace after a table causes unexpected deletion #7090)
  • Removing a TableNode that was the only child of the RootNode would leave the RootNode with no children
  • Various issues with $setBlocksType (see below)
  • RangeSelection.insertNodes (used by paste) could leave existing content under certain conditions

After

  • All existing unit and e2e tests pass unchanged
  • Removing a TableNode that was the only child of the RootNode now creates a ParagraphNode in its place
  • Pressing delete at the block after a TableNode or DecoratorNode behaves predictably
  • $setBlocksType works for table selections
  • $setBlocksType works for normal
  • $setBlocksType for code nodes in the playground works for partially selected blocks
  • insertNodes removes the select text before adding anything

Copy link

vercel bot commented Feb 9, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
lexical ✅ Ready (Inspect) Visit Preview 💬 Add feedback Feb 17, 2025 4:40am
lexical-playground ✅ Ready (Inspect) Visit Preview 💬 Add feedback Feb 17, 2025 4:40am

@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Feb 9, 2025
@etrepum etrepum changed the title [WIP][lexical] Bug Fix: Improve character deletion around shadow roots and decorators [lexical] Bug Fix: Improve character deletion around shadow roots and decorators Feb 10, 2025
@etrepum etrepum changed the title [lexical] Bug Fix: Improve character deletion around shadow roots and decorators [Breaking Change][lexical] Bug Fix: Improve character deletion around shadow roots and decorators Feb 10, 2025
@etrepum etrepum changed the title [Breaking Change][lexical] Bug Fix: Improve character deletion around shadow roots and decorators [Breaking Change][lexical][lexical-playground] Bug Fix: Improve character deletion around shadow roots and decorators Feb 10, 2025
return false;
}
if (!isBackward) {
// inherit strange forward delete behavior per e2e election test
Copy link
Collaborator

Choose a reason for hiding this comment

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

If you want to change the behaviour that forward deletion should not delete the collapsible section, I'm with you.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I don't have strong opinions about it, it's in a playground plug-in after all. I figured that breaking zero tests would maybe speed up review but it's been a week 🤷

Copy link
Collaborator

Choose a reason for hiding this comment

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

Let's make it better. I'll do my part on the reviewing side this evening.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I created a follow-up #7203 to address this separately

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

PR in #7204

Comment on lines +263 to +267
if (target) {
if ($isLineBreakNode(possibleLineBreak)) {
possibleLineBreak.remove();
}
target.select().insertRawText(textContent);
Copy link
Member

Choose a reason for hiding this comment

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

How come this toolbar logic has now become so manual? Is this the final shape? It used to be pretty straightforward to replicate once it was backed by insertNodes

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It's because insertNodes is buggy and I didn't want to also fix that in the scope of this PR

https://github.com/facebook/lexical/pull/7155/files#diff-c0aa95ba19e1cabb9a918e474930a02f54f63df8f1cd43f2eb96354b681e8071R240-R242

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. extended-tests Run extended e2e tests on a PR
Projects
None yet
4 participants