Skip to content

Fix cross-block text selection delete across nested blocks#78771

Draft
ellatrix wants to merge 1 commit into
trunkfrom
fix/list-multiselect-backspace
Draft

Fix cross-block text selection delete across nested blocks#78771
ellatrix wants to merge 1 commit into
trunkfrom
fix/list-multiselect-backspace

Conversation

@ellatrix

@ellatrix ellatrix commented May 28, 2026

Copy link
Copy Markdown
Member

What?

Closes #76233.

Backspace or Delete on a text selection that spans a nested list item (e.g. from the middle of an outer item to the middle of its own nested item) now deletes the selected range and merges the remaining content, instead of silently doing nothing.

Why?

The selection observer promoted ancestor/descendant selections to a block-level multi-selection, and the store's merge/delete paths bailed on any selection that did not start and end in the same block list.

How?

  1. use-selection-observer.js: detect when one selection endpoint is an ancestor of the other and dispatch a rich-text selectionChange instead of promoting to multiSelect.
  2. __unstableIsSelectionMergeable: drop the same-parent gate; determine document order via parent-chain comparison.
  3. __unstableDeleteSelection: support ancestor/descendant endpoints; the merged content always lands in the ancestor (also for forward Delete, which previously targeted the descendant).

Notes

  • Rebased onto trunk as a single commit (pre-rebase history preserved locally). Preserve nested list when deleting a selection across sibling list items #78776 landed the sibling-item half of this; the merged block now keeps the selection-end block's inner blocks, matching that PR's behavior, so the descendant's own children survive the merge.
  • Known remaining gap (follow-up): unselected following siblings of the selection-end block inside intermediate containers are still dropped (e.g. in ab[ul[cd, xy]], selecting from mid-"ab" to mid-"cd" also removes "xy").
  • A conservative alternative for the WP 7.1 cycle (fall back to selecting the ancestor block instead of partially merging) is proposed separately; this PR remains the full cross-level merge.

Testing Instructions

  1. Create a list item "ab" with a nested item "cd".
  2. Select from the middle of "ab" to the middle of "cd".
  3. Press Backspace (or Delete).
  4. Expect a single list item "ad" with the caret at the merge boundary.

Covered by three e2e tests in list.spec.js (2-level Backspace, 3-level Backspace, 2-level Delete).

Use of AI Tools

Authored with Claude Code under direction and review.

@github-actions github-actions Bot added the [Package] Block editor /packages/block-editor label May 28, 2026
Backspace or Delete on a text selection running from an outer block
into its own nested descendant previously did nothing: the selection
observer promoted such selections to a block-level multi-selection,
and the store's merge and delete paths bailed on any selection that
did not start and end in the same block list.

- use-selection-observer: when one endpoint is an ancestor of the
  other, dispatch a rich-text selectionChange instead of promoting
  to multiSelect.
- __unstableIsSelectionMergeable: allow cross-parent selections with
  a determinable document order via an isClientIdBefore helper.
- __unstableDeleteSelection: order endpoints through the parent
  chain; merged content always lands in the ancestor, also for
  forward Delete; the end block's inner blocks survive onto the
  merged block, matching the sibling-selection behavior.

Adds e2e coverage for the two-level Backspace and Delete cases and
a three-level Backspace case.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ellatrix
ellatrix force-pushed the fix/list-multiselect-backspace branch from b5ae898 to 2528519 Compare July 18, 2026 05:23
@github-actions

Copy link
Copy Markdown

Size Change: +176 B (0%)

Total Size: 7.73 MB

📦 View Changed
Filename Size Change
build/scripts/block-editor/index.min.js 422 kB +176 B (+0.04%)

compressed-size-action

@ellatrix ellatrix changed the title Fix cross-block text selection delete across nested blocks Writing flow: fall back to selecting the ancestor when a text selection crosses a nesting boundary Jul 18, 2026
@ellatrix ellatrix changed the title Writing flow: fall back to selecting the ancestor when a text selection crosses a nesting boundary Fix cross-block text selection delete across nested blocks Jul 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Package] Block editor /packages/block-editor

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Writing flow: Can't delete list items with backspace

1 participant