Skip to content

Conversation

@tupizz
Copy link
Contributor

@tupizz tupizz commented Feb 7, 2026

Demo

CleanShot.2026-02-09.at.21.13.12.mp4

Summary

Fixes SD-1810 — Backspace doesn't delete empty paragraph in suggesting mode.

MVP blocker for Ontra (Feb 17 release).

Problem

When a user creates a new paragraph (Enter) in suggesting mode and immediately presses Backspace, nothing happens — the empty paragraph stays.

Root cause

The track changes system intercepts every transaction in suggesting mode via trackedTransactionreplaceStep()markDeletion(). The flow:

  1. Backspace on an empty paragraph creates a ReplaceStep(from, to, Slice.empty) to remove it
  2. replaceStep() inverts the original step and tries to re-apply it as a tracked change
  3. markDeletion() iterates nodesBetween(from, to) looking for inline nodes to mark as deleted
  4. An empty paragraph has no inline content — the loop finds nothing
  5. The deletion is silently swallowed as a no-op

Fix

Added an early return guard at the top of replaceStep(). Before entering the full tracked-change flow, it checks:

  1. Is this a pure deletion?step.slice.content.size === 0 (no replacement content)
  2. Is the range empty of inline content?nodesBetween finds no inline nodes

When both are true, the step is applied directly since there's nothing to track as a change. This matches Word behavior — deleting an empty paragraph has no visible "tracked change" to show.

For all other cases (non-empty paragraphs, text content, etc.), the existing tracked-change flow runs unchanged.

Changes

  • replaceStep.js — 6-line guard clause at function entry (lines 24–42)
  • replaceStep.test.js — new test: creates <p>Hello</p><p></p>, simulates Backspace on empty paragraph, asserts it's removed

Test plan

  • New unit test passes: deletes empty paragraph on Backspace in suggesting mode
  • All 5,499 existing tests pass (622 test files, 0 failures)
  • Manual browser verification: Enter → Backspace cycle works correctly in suggesting mode
  • Test with multi-paragraph documents (empty paragraph between content paragraphs)
  • Test that non-empty paragraph deletion still gets tracked normally
  • Test undo (Ctrl+Z) after deleting empty paragraph

Copilot AI review requested due to automatic review settings February 7, 2026 16:38
@linear
Copy link

linear bot commented Feb 7, 2026

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9916d6484e

ℹ️ 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".

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes a track-changes edge case in the super editor where pressing Backspace on a newly created empty paragraph in suggesting mode results in a no-op, by allowing certain “pure deletion” ReplaceSteps to apply directly (untracked) when there’s no inline content to mark as deleted.

Changes:

  • Add an early guard in replaceStep() to directly apply pure-deletion steps when the deleted range contains no inline nodes.
  • Add a unit test covering Backspace-like deletion of an empty paragraph in suggesting mode.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
packages/super-editor/src/extensions/track-changes/trackChangesHelpers/replaceStep.js Adds a guard to bypass tracked-change logic for deletions with no inline content, allowing empty paragraph removal.
packages/super-editor/src/extensions/track-changes/trackChangesHelpers/replaceStep.test.js Adds a regression test asserting an empty paragraph is removed when “Backspace deletion” occurs in suggesting mode.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@tupizz tupizz self-assigned this Feb 8, 2026
Copy link
Collaborator

@harbournick harbournick left a comment

Choose a reason for hiding this comment

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

I think there's a bug with: When a user presses Backspace at the start of a non-empty paragraph, the paragraphs are joined, but the delete is applied directly and no deletion mark is created. That makes the edit invisible (not reviewable/rejectable) in Suggesting mode. The direct-delete fast path should only apply to removing a truly empty block node.

see 7ebce03 (I added a test that fails here for this case)

tupizz and others added 5 commits February 10, 2026 15:55
- Introduced a new test suite for keymap history grouping, validating the behavior of the Enter and space keys in creating undo boundaries.
- Enhanced the handleEnter and handleBackspace functions to dispatch closeHistory, ensuring proper history management during text input.
- Added tests to confirm that undo operations correctly restore text and manage undo group boundaries in various scenarios.
…mode

The replaceStep guard now applies any pure deletion with no inline
content directly, covering both empty paragraph removal and paragraph
joins. markDeletion cannot represent structural changes (block boundary
tokens) as inline marks, so these steps were silently swallowed.

Fixes the Enter→Enter→Backspace→Backspace flow in suggesting mode
where the second Backspace (paragraph join) did nothing.
@tupizz tupizz force-pushed the tadeu/sd-1810-backspace-doesnt-delete-empty-paragraph-in-suggesting-mode branch from db51225 to 3d37af6 Compare February 10, 2026 18:55
@tupizz
Copy link
Contributor Author

tupizz commented Feb 10, 2026

I think there's a bug with: When a user presses Backspace at the start of a non-empty paragraph, the paragraphs are joined, but the delete is applied directly and no deletion mark is created. That makes the edit invisible (not reviewable/rejectable) in Suggesting mode. The direct-delete fast path should only apply to removing a truly empty block node.

see 7ebce03 (I added a test that fails here for this case)

We have an existing bug that we don't track new line breaks inside a paragraph, or enters in a document, or backspace in paragraphs. its a separate issue altogether. In that case let's leave it alone in 1966 we can proceed without it.

Copy link
Contributor

@caio-pizzol caio-pizzol left a comment

Choose a reason for hiding this comment

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

looking good @tupizz

since it involves browser interactions, let's also write a "interaction story" in @devtools/visual-testing
p.s. there's already a comments-tcs/ category with tracked change stories

- Fix editor?.view?.dispatch inconsistency in handleDelete (use view?.dispatch)
- Add comments explaining closeHistory no-op edge case in keymap handlers
- Add tests for handleBackspace/handleDelete closeHistory behavior
- Extract ensureUniqueSdBlockId() helper to deduplicate seenIds logic in block-node
- Add comment explaining TrackDelete-only paragraph edge case in replaceStep
- Add visual testing story for SD-1810 backspace empty paragraph in suggesting mode
@tupizz tupizz requested a review from caio-pizzol February 11, 2026 19:12
@caio-pizzol caio-pizzol requested review from caio-pizzol and luccas-harbour and removed request for caio-pizzol February 11, 2026 19:15
Copy link
Contributor

@caio-pizzol caio-pizzol left a comment

Choose a reason for hiding this comment

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

lgtm - let's make sure to add interaction story for this scenario before merging

@tupizz
Copy link
Contributor Author

tupizz commented Feb 11, 2026

thanks @caio-pizzol
I added visual interaction tests already 🙏🏻

Copy link
Collaborator

@harbournick harbournick left a comment

Choose a reason for hiding this comment

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

LGTM

@harbournick harbournick merged commit 820c73c into main Feb 12, 2026
2 checks passed
@harbournick harbournick deleted the tadeu/sd-1810-backspace-doesnt-delete-empty-paragraph-in-suggesting-mode branch February 12, 2026 00:48
@superdoc-bot
Copy link

superdoc-bot bot commented Feb 12, 2026

🎉 This PR is included in superdoc v1.12.0-next.15

The release is available on GitHub release

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.

3 participants