Skip to content

Fix decorator input selection#3491

Merged
trueadm merged 3 commits into
mainfrom
fix-input-sel
Dec 5, 2022
Merged

Fix decorator input selection#3491
trueadm merged 3 commits into
mainfrom
fix-input-sel

Conversation

@trueadm

@trueadm trueadm commented Dec 5, 2022

Copy link
Copy Markdown
Collaborator

Turns out we had a strange bug in isSelectionCapturedInDecoratorInput. Fixes #3488.

@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 Dec 5, 2022
@vercel

vercel Bot commented Dec 5, 2022

Copy link
Copy Markdown

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

Name Status Preview Updated
lexical ✅ Ready (Inspect) Visit Preview Dec 5, 2022 at 2:10PM (UTC)
lexical-playground ✅ Ready (Inspect) Visit Preview Dec 5, 2022 at 2:10PM (UTC)

Comment thread packages/lexical-playground/src/nodes/PollComponent.tsx Outdated
},
() => {
target.selectionStart = selectionStart;
target.selectionEnd = selectionEnd;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

It's a bit weird pattern to follow as it might be hard to add selection restoration in more complex embeds. I thought lexical would avoid handling input completely when selection is within decorator input.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I guess you could avoid doing this if you marked the update as discrete too. However, I've had to do this in React before, it's because the setState for React is async from the change event AFAIK.

@trueadm
trueadm merged commit 2af4559 into main Dec 5, 2022
@trueadm
trueadm deleted the fix-input-sel branch December 5, 2022 14:48
@trueadm trueadm mentioned this pull request Dec 5, 2022
etrepum pushed a commit to etrepum/lexical that referenced this pull request Jun 11, 2026
…ew findings, add tests and docs

Addresses the issues identified in review of the SelectBlockExtension PR:

- Bail out of the SELECT_ALL_COMMAND listener for commands bubbled from
  nested editors when cascadeSelection is off (the default), so a stale
  parent selection can no longer hijack select all from a nested editor
- Expand a selection that already spans multiple blocks directly to the
  whole document instead of shrinking it to the anchor's block
- Store a clone() snapshot of the selectAll selection; the live selection
  object can be mutated in place by later updates, aliasing
  prevSelectionAll and swallowing the next select all
- Select all even when the selection is anchored directly on the root
  (previously a no-op when prevSelectionAll was set)
- Guard against an empty NodeSelection instead of throwing
- Keep the PreventSelectAllExtension dependency's disabled state in sync
  with SelectBlockExtension so disabling the feature disables all of it
- Import PreventSelectAllExtension directly instead of via the package
  barrel (circular import), and drop redundant $setSelection() wrappers
  around ElementNode.select()
- Rename extensions to the majority '@lexical/extension/*' name convention
- Restore the PollComponent input caret workaround from facebook#3491 that was
  removed without explanation or test coverage

Tests:
- New unit suite for $isBlockFullySelected, block/document select all
  progression, multi-block expansion, root-anchored selections, node
  selections, disabled config and PreventSelectAll coupling, nested
  editor handling with cascadeSelection on and off, and the
  PreventSelectAll input/textarea behavior (4 of these fail against the
  previous implementation)
- New e2e test for multi-block selection expansion

Docs:
- Add SelectBlockExtension and PreventSelectAllExtension to
  included-extensions.md and fill in the other missing entries
  (@lexical/clipboard, @lexical/html, and the rest of @lexical/extension),
  omitting deprecated extensions

https://claude.ai/code/session_013LyjzFTiTDhbaNe3Tadiqo
etrepum pushed a commit to etrepum/lexical that referenced this pull request Jun 11, 2026
…kExtension review findings, add tests and docs

Addresses the issues identified in review of the SelectBlockExtension PR:

- Promote $isBlockFullySelected to @lexical/utils using the caret-based
  containment implementation from facebook#8666 (simplified with
  $getCaretRangeInDirection), which handles ancestor element points and
  empty blocks consistently; it accepts a RangeSelection or CaretRange so
  the clearFormatting use case in facebook#8666 can adopt it as well
- Bail out of the SELECT_ALL_COMMAND listener for commands bubbled from
  nested editors when cascadeSelection is off (the default), so a stale
  parent selection can no longer hijack select all from a nested editor
- Expand a selection that already spans multiple blocks directly to the
  whole document instead of shrinking it to the anchor's block
- Store a clone() snapshot of the selectAll selection; the live selection
  object can be mutated in place by later updates, aliasing
  prevSelectionAll and swallowing the next select all
- Select all even when the selection is anchored directly on the root
  (previously a no-op when prevSelectionAll was set)
- Guard against an empty NodeSelection instead of throwing
- Keep the PreventSelectAllExtension dependency's disabled state in sync
  with SelectBlockExtension so disabling the feature disables all of it
- Import PreventSelectAllExtension directly instead of via the package
  barrel (circular import), and drop redundant $setSelection() wrappers
  around ElementNode.select()
- Rename extensions to the majority '@lexical/extension/*' name convention
- Restore the PollComponent input caret workaround from facebook#3491 that was
  removed without explanation or test coverage

Tests:
- New @lexical/utils unit suite for $isBlockFullySelected covering
  containment semantics, ancestor element points, backward selections,
  CaretRange input, trailing decorators, empty and nested blocks
- New unit suite for SelectBlockExtension: block/document select all
  progression, multi-block expansion, root-anchored selections, node
  selections, disabled config and PreventSelectAll coupling, nested
  editor handling with cascadeSelection on and off (including an empty
  nested editor), and the PreventSelectAll input/textarea behavior
- New e2e test for multi-block selection expansion

Docs:
- Add SelectBlockExtension and PreventSelectAllExtension to
  included-extensions.md and fill in the other missing entries
  (@lexical/clipboard, @lexical/html, and the rest of @lexical/extension),
  omitting deprecated extensions

https://claude.ai/code/session_013LyjzFTiTDhbaNe3Tadiqo
etrepum pushed a commit to etrepum/lexical that referenced this pull request Jun 11, 2026
…kExtension review findings, add tests and docs

Addresses the issues identified in review of the SelectBlockExtension PR:

- Promote $isBlockFullySelected to @lexical/utils using the caret-based
  containment implementation from facebook#8666 (simplified with
  $getCaretRangeInDirection), which handles ancestor element points and
  empty blocks consistently; it accepts a RangeSelection or CaretRange so
  the clearFormatting use case in facebook#8666 can adopt it as well
- Remove the prevSelectionAll snapshot in favor of a stateless
  $isBlockFullySelected($getRoot(), selection) check. The stored
  selection could go stale and swallow select all (e.g. a collaborator
  appending a paragraph while the document was fully selected), and the
  live selection object could be mutated in place by later updates,
  aliasing the snapshot
- Bail out of the SELECT_ALL_COMMAND listener for commands bubbled from
  nested editors when cascadeSelection is off (the default), so a stale
  parent selection can no longer hijack select all from a nested editor
- Expand a selection that already spans multiple blocks directly to the
  whole document instead of shrinking it to the anchor's block
- Select all even when the selection is anchored directly on the root
- Guard against an empty NodeSelection instead of throwing
- Keep the PreventSelectAllExtension dependency's disabled state in sync
  with SelectBlockExtension so disabling the feature disables all of it
- Import PreventSelectAllExtension directly instead of via the package
  barrel (circular import), and drop redundant $setSelection() wrappers
  around ElementNode.select()
- Rename extensions to the majority '@lexical/extension/*' name convention
- Restore the PollComponent input caret workaround from facebook#3491 that was
  removed without explanation or test coverage

Tests:
- New @lexical/utils unit suite for $isBlockFullySelected covering
  containment semantics, ancestor element points, backward selections,
  CaretRange input, trailing decorators, empty and nested blocks
- New unit suite for SelectBlockExtension: block/document select all
  progression, multi-block expansion, root-anchored selections, select
  all after concurrent document changes, node selections, disabled config
  and PreventSelectAll coupling, nested editor handling with
  cascadeSelection on and off (including an empty nested editor), and the
  PreventSelectAll input/textarea behavior
- New e2e test for multi-block selection expansion

Docs:
- Add SelectBlockExtension and PreventSelectAllExtension to
  included-extensions.md and fill in the other missing entries
  (@lexical/clipboard, @lexical/html, and the rest of @lexical/extension),
  omitting deprecated extensions

https://claude.ai/code/session_013LyjzFTiTDhbaNe3Tadiqo
etrepum pushed a commit to etrepum/lexical that referenced this pull request Jun 11, 2026
…kExtension review findings, add tests and docs

Addresses the issues identified in review of the SelectBlockExtension PR:

- Promote $isBlockFullySelected to @lexical/utils using the caret-based
  containment implementation from facebook#8666 (simplified with
  $getCaretRangeInDirection), which handles ancestor element points and
  empty blocks consistently; it accepts a RangeSelection or CaretRange so
  the clearFormatting use case in facebook#8666 can adopt it as well
- Remove the prevSelectionAll snapshot in favor of a stateless
  $isBlockFullySelected($getRoot(), selection) check. The stored
  selection could go stale and swallow select all (e.g. a collaborator
  appending a paragraph while the document was fully selected), and the
  live selection object could be mutated in place by later updates,
  aliasing the snapshot
- Bail out of the SELECT_ALL_COMMAND listener for commands bubbled from
  nested editors when cascadeSelection is off (the default), so a stale
  parent selection can no longer hijack select all from a nested editor
- Expand a selection that already spans multiple blocks directly to the
  whole document instead of shrinking it to the anchor's block
- Select all even when the selection is anchored directly on the root
- Guard against an empty NodeSelection instead of throwing
- Keep the PreventSelectAllExtension dependency's disabled state in sync
  with SelectBlockExtension so disabling the feature disables all of it
- Import PreventSelectAllExtension directly instead of via the package
  barrel (circular import), and drop redundant $setSelection() wrappers
  around ElementNode.select()
- Rename extensions to the majority '@lexical/extension/*' name convention
- Restore the PollComponent input caret workaround from facebook#3491 that was
  removed without explanation or test coverage

Tests:
- New @lexical/utils unit suite for $isBlockFullySelected covering
  containment semantics, ancestor element points, backward selections,
  CaretRange input, trailing decorators, empty and nested blocks
- New unit suite for SelectBlockExtension: block/document select all
  progression (including single-block documents), multi-block expansion,
  root-anchored selections, select all after concurrent document changes,
  preservation of manually created full selections, node selections,
  disabled config and PreventSelectAll coupling, nested editor handling
  with cascadeSelection on and off (including an empty nested editor),
  and the PreventSelectAll input/textarea behavior
- New e2e test for multi-block selection expansion

Docs:
- Add SelectBlockExtension and PreventSelectAllExtension to
  included-extensions.md and fill in the other missing entries
  (@lexical/clipboard, @lexical/html, and the rest of @lexical/extension),
  omitting deprecated extensions

https://claude.ai/code/session_013LyjzFTiTDhbaNe3Tadiqo
etrepum pushed a commit to levensta/lexical that referenced this pull request Jun 11, 2026
…kExtension review findings, add tests and docs

Addresses the issues identified in review of the SelectBlockExtension PR:

- Promote $isBlockFullySelected to @lexical/utils using the caret-based
  containment implementation from facebook#8666 (simplified with
  $getCaretRangeInDirection), which handles ancestor element points and
  empty blocks consistently; it accepts a RangeSelection or CaretRange so
  the clearFormatting use case in facebook#8666 can adopt it as well
- Remove the prevSelectionAll snapshot in favor of a stateless
  $isBlockFullySelected($getRoot(), selection) check. The stored
  selection could go stale and swallow select all (e.g. a collaborator
  appending a paragraph while the document was fully selected), and the
  live selection object could be mutated in place by later updates,
  aliasing the snapshot
- Bail out of the SELECT_ALL_COMMAND listener for commands bubbled from
  nested editors when cascadeSelection is off (the default), so a stale
  parent selection can no longer hijack select all from a nested editor
- Expand a selection that already spans multiple blocks directly to the
  whole document instead of shrinking it to the anchor's block
- Select all even when the selection is anchored directly on the root
- Guard against an empty NodeSelection instead of throwing
- Keep the PreventSelectAllExtension dependency's disabled state in sync
  with SelectBlockExtension so disabling the feature disables all of it
- Import PreventSelectAllExtension directly instead of via the package
  barrel (circular import), and drop redundant $setSelection() wrappers
  around ElementNode.select()
- Rename extensions to the majority '@lexical/extension/*' name convention
- Restore the PollComponent input caret workaround from facebook#3491 that was
  removed without explanation or test coverage

Tests:
- New @lexical/utils unit suite for $isBlockFullySelected covering
  containment semantics, ancestor element points, backward selections,
  CaretRange input, trailing decorators, empty and nested blocks
- New unit suite for SelectBlockExtension: block/document select all
  progression (including single-block documents), multi-block expansion,
  root-anchored selections, select all after concurrent document changes,
  preservation of manually created full selections, node selections,
  disabled config and PreventSelectAll coupling, nested editor handling
  with cascadeSelection on and off (including an empty nested editor),
  and the PreventSelectAll input/textarea behavior
- New e2e test for multi-block selection expansion

Docs:
- Add SelectBlockExtension and PreventSelectAllExtension to
  included-extensions.md and fill in the other missing entries
  (@lexical/clipboard, @lexical/html, and the rest of @lexical/extension),
  omitting deprecated extensions

https://claude.ai/code/session_013LyjzFTiTDhbaNe3Tadiqo
etrepum pushed a commit to etrepum/lexical that referenced this pull request Jun 11, 2026
…kExtension review findings, add tests and docs

Addresses the issues identified in review of the SelectBlockExtension PR:

- Promote $isBlockFullySelected to @lexical/utils using the caret-based
  containment implementation from facebook#8666 (simplified with
  $getCaretRangeInDirection), which handles ancestor element points and
  empty blocks consistently; it accepts a RangeSelection or CaretRange so
  the clearFormatting use case in facebook#8666 can adopt it as well
- Remove the prevSelectionAll snapshot in favor of a stateless
  $isBlockFullySelected($getRoot(), selection) check. The stored
  selection could go stale and swallow select all (e.g. a collaborator
  appending a paragraph while the document was fully selected), and the
  live selection object could be mutated in place by later updates,
  aliasing the snapshot
- Bail out of the SELECT_ALL_COMMAND listener for commands bubbled from
  nested editors when cascadeSelection is off (the default), so a stale
  parent selection can no longer hijack select all from a nested editor
- Expand a selection that already spans multiple blocks directly to the
  whole document instead of shrinking it to the anchor's block
- Select all even when the selection is anchored directly on the root
- Guard against an empty NodeSelection instead of throwing
- Keep the PreventSelectAllExtension dependency's disabled state in sync
  with SelectBlockExtension so disabling the feature disables all of it
- Import PreventSelectAllExtension directly instead of via the package
  barrel (circular import), and drop redundant $setSelection() wrappers
  around ElementNode.select()
- Rename extensions to the majority '@lexical/extension/*' name convention
- Restore the PollComponent input caret workaround from facebook#3491 that was
  removed without explanation or test coverage

Tests:
- New @lexical/utils unit suite for $isBlockFullySelected covering
  containment semantics, ancestor element points, backward selections,
  CaretRange input, trailing decorators, empty and nested blocks
- New unit suite for SelectBlockExtension: block/document select all
  progression (including single-block documents), multi-block expansion,
  root-anchored selections, select all after concurrent document changes,
  preservation of manually created full selections, node selections,
  disabled config and PreventSelectAll coupling, nested editor handling
  with cascadeSelection on and off (including an empty nested editor),
  and the PreventSelectAll input/textarea behavior
- New e2e test for multi-block selection expansion

Docs:
- Add SelectBlockExtension and PreventSelectAllExtension to
  included-extensions.md and fill in the other missing entries
  (@lexical/clipboard, @lexical/html, and the rest of @lexical/extension),
  omitting deprecated extensions

https://claude.ai/code/session_013LyjzFTiTDhbaNe3Tadiqo
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.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: Weird Backspace key behavior in nodes containing inputs

3 participants