Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions packages/lexical-website/docs/collaboration/y.md
Original file line number Diff line number Diff line change
Expand Up @@ -810,6 +810,21 @@ not merge as a user might expect:
that outdents an item of such a list is a delete in the nested list's
container and an insert in the list's: text a collaborator types in those
items at the same time is lost (only lists stored in that older shape).
- **Text nodes made again with other text.** Where an update replaces a

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

IIRC the text merge transform is going to splice TextNode back together at least in a left-biased way if the other matching conditions are met before the update is committed and then relayed to collab, so a split-then-join should be indistinguishable from a setTextContent splice unless there's something blocking the merge altogether or the changed content isn't a prefix. We could add a different bias in $mergeTextNodes to prefer preserving an existing node on merge even if it is on the right.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

And if the problem is that it doesn't call TextNode.spliceText (after the bias heuristic is changed), we could probably have TextNode.mergeWithSibling call it?

line's text nodes with new ones and the line's text changed (an AI rewrite
that makes a block's text nodes again with one word changed, or removes a
block's children and appends one new text node), a replaced node whose
text is not all there unchanged is written again whole: its characters are
deleted, and the new text is inserted. What a collaborator types into that
Comment on lines +816 to +818

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Optional, non-blocking: a remade node whose text did not change keeps its characters only where it lines up from the start or the end of the replaced text. With aa · bb · cc remade as aX · bb · cY, the whole line aa bb cc is deleted and aX bb cY inserted, and a z a collaborator types inside the unchanged bb at the same time lands in front of the line; with only the last word changed, only cc is rewritten. So an update that changes two words of a block rewrites everything between them. Possible wording: “…every replaced node from the first whose text changed to the last, also one whose text did not change, is written again whole…”.

text at the same time, which the update's author has not seen, stays where
it was, so it lands outside the new text, before it (a letter typed at the
end of a word ends up in front of the rewritten text, out of its word),
Comment on lines +819 to +821

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Optional, non-blocking: a letter typed at the very end of the replaced text can land after the new text instead: z typed after t15 (the end of the line) gives t63 t72 t13 t81 t15z when the author has the lower client id, and zt63 t72 t13 t81 t15 otherwise. Possible wording: “outside the new text: before it, or after it where it was typed at the very end of the replaced text (by the order Yjs gives the two inserts)”.

and the collaborator's formatting of that text at the same time is not
kept. The concurrent typed text is kept, and every client shows the same
Comment on lines +822 to +823

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Optional, non-blocking: formatting that reaches the end of the replaced text is not dropped but can cover all of the new text. With t63 t71 t13 t81 t15 made again as one node with t72, a collaborator bolding t15 at the same time leaves the whole rewritten line bold on every client when the author has the lower client id; in head · t63 t71 · t13 tail remade from JSON, bolding t71 makes all of the new t63 t72 bold in either id order. Formatting that ends inside the text (bolding t63) is dropped, as written. Possible wording: “…is not kept where it was; formatting that reaches the end of the replaced text can cover all of the new text instead.” The “Other races” bullet already describes a related case, text typed at the start of a range a collaborator formats at the same time.

result. Edit the changed
words in place instead (`TextNode#spliceText`, the selection's
`insertText`; see [Edits made by code](#edits-made-by-code-agents-tools)):
only the changed characters are written.
- **Delete wins.** Text typed into a container that a collaborator deletes at
the same time is deleted with it, and so is a block moved into it.
- **Last writer wins** for the fields of one link (URL and target change
Expand Down
Loading