Skip to content

fix(super-editor): select inline SDT on backspace before run start (SD-3165)#3388

Open
luccas-harbour wants to merge 3 commits into
mainfrom
luccas/sd-3165-bug-unable-to-delete-a-contentlocked-inline-sdt-when-text-is
Open

fix(super-editor): select inline SDT on backspace before run start (SD-3165)#3388
luccas-harbour wants to merge 3 commits into
mainfrom
luccas/sd-3165-bug-unable-to-delete-a-contentlocked-inline-sdt-when-text-is

Conversation

@luccas-harbour
Copy link
Copy Markdown
Contributor

Summary

Fixes SD-3165: a content-locked inline SDT could not be deleted with Backspace when the cursor was placed at the start of the run immediately following it. The run-aware Backspace chain scanned into the SDT's content, so the locked wrapper never became the deletion target.

A new command, selectInlineSdtBeforeRunStart, runs early in the Backspace chain. When the cursor is at offset 0 of a run whose previous sibling is a structuredContent node, it promotes the selection to a NodeSelection over that wrapper (unless lockMode is sdtLocked/sdtContentLocked, in which case it consumes the keystroke to block deletion). A subsequent Backspace then deletes the now-selected SDT as a unit.

The command tags its transaction with a SELECT_INLINE_SDT_BEFORE_RUN_START_META meta so the existing inline-SDT auto-select plugin (structured-content-select-plugin) does not clobber the new NodeSelection back into a TextSelection.

Changes

  • Add selectInlineSdtBeforeRunStart command and register it in the core command map, index, and types.
  • Insert the new command into the handleBackspace keymap chain between deleteBlockSdtAtTextBlockStart and backspaceEmptyRunParagraph.
  • Teach structured-content-select-plugin to skip its normalization when the new meta is present on the dispatched transaction.

Tests

  • Unit tests for selectInlineSdtBeforeRunStart covering: unlocked / contentLocked (selects wrapper), sdtLocked / sdtContentLocked (consumes without selecting), cursor not at run start, and previous sibling not an inline SDT.
  • core-command-map declaration test asserts the new entry in CoreCommandNames.
  • keymap-backspace-chain test pins the new command's position in the Backspace chain.
  • Integration test in structured-content-lock-plugin.test.js for the full two-step flow (Backspace selects, second Backspace deletes) on a contentLocked inline SDT.
  • structured-content-select-plugin test verifies the meta escape keeps the Backspace-created NodeSelection intact.

…ng run (SD-3165)

Adds a new selectInlineSdtBeforeRunStart command in the Backspace chain.
When the caret is at the start of a run whose previous sibling is an
inline structuredContent wrapper, Backspace now selects the wrapper as
a NodeSelection (for unlocked / contentLocked modes) so a subsequent
Backspace deletes it. For sdtLocked / sdtContentLocked wrappers the
command consumes the keystroke without changing the selection. The
structured-content select plugin ignores selections produced via the
new meta flag so it does not collapse the NodeSelection back to a
TextSelection.
@luccas-harbour luccas-harbour requested a review from a team as a code owner May 19, 2026 16:46
@linear-code
Copy link
Copy Markdown

linear-code Bot commented May 19, 2026

SD-3165

@codecov-commenter
Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@harbournick harbournick requested a review from VladaHarbour May 19, 2026 19:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants