Skip to content

[Bug] Text typed in reverse order in Suggesting Mode when all content is track-deletedΒ #1827

@kapil-LH

Description

@kapil-LH

Description

When using SuperDoc in Suggesting Mode (track changes), typing new text after deleting ALL content in a text node results in characters appearing in reverse order.

For example:

  • Original text: TEST
  • Delete all 4 characters (backspace Γ— 4)
  • Type: ABCD
  • Expected result: ABCD
  • Actual result: DCBA

Reproduction Steps

  1. Open SuperDoc with collaboration enabled and in suggesting/track changes mode (documentMode: 'suggesting')
  2. Have some text in the document (e.g., "TEST")
  3. Delete ALL the text using backspace (all characters get trackDelete marks)
  4. Start typing new characters (e.g., "ABCD")
  5. Observe that characters appear in reverse order

Important Finding

The bug only occurs when ALL content is deleted:

Scenario Result
Delete 3 of 4 chars, then type ABCD βœ… Works correctly: ABCD
Delete ALL 4 chars, then type ABCD ❌ Reversed: DCBA

This does NOT happen in editing mode - only in suggesting mode with track changes.

Root Cause Analysis

Through debugging with Y.Doc observers, we identified the issue in the Yjs delta operations:

// Expected: retain should increment (1, 2, 3, 4...) as cursor advances
// Actual: retain stays at 1 for every insert

// First keystroke "A":
[XmlFragment Change - TEXT DELTA] {
  delta: [
    { retain: 1 },  // Position 1
    { insert: "A", attributes: { trackInsert: {...} } }
  ]
}

// Second keystroke "B":
[XmlFragment Change - TEXT DELTA] {
  delta: [
    { retain: 1 },  // ← Still 1, should be 2!
    { insert: "B", attributes: { trackInsert: {...} } }
  ]
}

// Third keystroke "C":
[XmlFragment Change - TEXT DELTA] {
  delta: [
    { retain: 1 },  // ← Still 1, should be 3!
    { insert: "C", attributes: { trackInsert: {...} } }
  ]
}

The cursor position (relative position in CRDT) is not advancing after each insert when the text node is "visually empty" (all content has trackDelete marks but still exists in the document).

Additional Observation

We also noticed a large docx-update event (~23KB) being triggered after EVERY keystroke:

[Y.Doc Update] {
  origin: { event: 'docx-update', user: {...} },
  updateSize: 23799  // Full document sync on every keystroke
}

This full document re-sync via updateYdocDocxData() storing the entire DOCX in the Y.Doc meta map after each keystroke may be interfering with cursor position tracking. At minimum, this is a significant performance concern for collaborative editing at scale (thousands of concurrent users).

Environment

  • SuperDoc version: 1.8.3 (also reproduced on 1.7.0)
  • Browser: Chrome
  • Collaboration: Using HocuspocusProvider with Yjs
  • y-prosemirror: 1.3.7
  • yjs: 13.6.19
  • Mode: Suggesting (track changes enabled)

Demo Comparison

We tested on the official SuperDoc demo which uses version 0.20.0-next.13 and could NOT reproduce the issue there. This suggests:

  1. The bug may have been introduced in a later version, OR
  2. The demo has different configuration that avoids the issue

Expected Behavior

Characters should appear in the order they are typed, regardless of whether the preceding content was track-deleted.

Suggested Fix Area

The issue is likely in how the track changes extension calculates insert positions relative to track-deleted content. When all visible content is deleted (but still exists with trackDelete marks), the cursor anchor point for new trackInsert content appears to be miscalculated, causing every insert to go to position 1 instead of incrementing.

The docx-update full sync after each keystroke may also be resetting some state that affects cursor positioning.

Screencast.from.2026-01-24.18-07-05.webm

SuperDoc version (if relevant)

1.7.0

Additional context

Please try and confirm if issue exists with the superdoc's latest version. Thanks.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions