SD-3386 - fix: deletion handling across paragraph boundaries#3664
SD-3386 - fix: deletion handling across paragraph boundaries#3664chittolinag wants to merge 2 commits into
Conversation
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
…e-selection-inserts-spurious
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 737a2ae4be
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| const isStructuralShellDelete = | ||
| step.from !== step.to && step.slice.content.size > 0 && !sliceHasInlineLeafContent(step.slice); |
There was a problem hiding this comment.
Preserve block-only replacement content
When a non-empty selection is replaced with a block-only slice that has no inline descendants (for example DOCX paste/import content containing a mathBlock, passthroughBlock, or an empty block SDT), this predicate classifies the step as a structural-shell delete and routes it through makeTextDeleteIntent, so the selected text is marked deleted but the inserted block is silently dropped. The special case should be limited to ProseMirror's paragraph re-join shell (or explicitly exclude block leaf/atom content), otherwise suggesting mode loses valid replacement content instead of inserting or failing closed.
Useful? React with 👍 / 👎.
Issue
In suggesting mode, deleting a selection that spans two paragraphs pushed the remainder of the second paragraph onto a new line, as if Enter was pressed. On the real Backspace/Delete keymap path the tracked interception could crash position mapping (
RangeError: Position NaN), and the dispatch fallback then deleted the text untracked. Accepting or rejecting the change failed silently, leaving the inline decoration painted, and the hover bubble reported "Accepted" even after a reject.Proposed solution
replaceStep.jsnow compiles slices without inline leaf content as plain tracked deletions, skips the invert/mirror mapping pairing for that mark-only compile (the source of the NaN), and emits an explicit caret hint at the deletion's left edge.