Skip to content

[lexical-y] Undo can restore a text attribute's opener without its closer, spreading it to the end of the document #9716

Open

Description

@zurfyx

Summary

With @lexical/y, a collaborator's undo can restore the opening marker of a text attribute (comment ids stored on a text node) without its closing marker. The attribute then covers every following text node, to the end of the document, on every peer.

Repro (two peers, A and B)

  1. A, all in one undo step: adds comment ids to parts of a text entity (a keyword), types inside it, adds another comment id (c3) over it, then types so that the entity becomes another entity type that keeps the comment ids (keyword two becomes hashtag #ttwox). With [lexical][lexical-text] Bug Fix: Text entities keep their NodeState when they become text #9712/[lexical-text][lexical-playground] Bug Fix: Text entity transforms settle between text nodes of other formats (re-land of #9686) #9713 the comment ids stay on the entity through that change; on main they reach the same shape another way (below).
  2. Sync. B removes c3. A undoes. Sync. B undoes.
  3. c3 is now on every text node of every block, on both peers (gc on and off).

What happens in the Y document

  • The binding stores that one text node as several runs, each in its own typed box with its own c3 open/close pair.
  • B's removal deletes the openers but leaves A's last closer and writes its own null markers, so the pair has two owners.
  • A's undo deletes that closer (A's item).
  • B's undo restores the opener (B deleted it), but not the closer (A deleted it), and writes no end, so c3 runs to the end of the document.

main reaches it too: the pinned test (hashtag and keyword transforms, two peers) leaves the comment on the later blocks on main as well, through main's own entity path. #9712/#9713 reach it more often, because entities keep their comment ids. Same opener-without-closer undo class as #9689.

Test

#9713 pins the repro as a test.fails in packages/lexical-y, named after this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions