Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inconsistent Y.XmlText.format behavior #606

Closed
gblaketx opened this issue Jan 19, 2024 — with Huly GitHub · 1 comment
Closed

Inconsistent Y.XmlText.format behavior #606

gblaketx opened this issue Jan 19, 2024 — with Huly GitHub · 1 comment
Assignees
Labels

Comments

Copy link

gblaketx commented Jan 19, 2024

Describe the bug Y.XmlText.format can strip attributes outside the range provided to the function. This behavior seems to happen specifically when the YDoc is initialized via applyUpdate from an encoded update.

To Reproduce This jest test reproduces the issue.

import * as Y from "yjs";

describe("inconsistentFormatBug", () => {
  it("1. Passes on fresh YDoc", () => {
    const yDoc = initializeYDoc();
    testYjsMerge(yDoc);
  });

  it("2. Fails on YDoc initialized via an encoded update", () => {
    const initialYDoc = initializeYDoc();
    const yDoc = new Y.Doc({ gc: false });
    Y.applyUpdate(yDoc, Y.encodeStateAsUpdate(initialYDoc));
    testYjsMerge(yDoc);
  });
});

function testYjsMerge(yDoc: Y.Doc) {
  const content = yDoc.get("text", Y.XmlText) as Y.XmlText;
  content.format(0, 6, { bold: null });
  content.format(6, 4, { type: "text" });

  expect(content.toDelta()).toEqual([
    {
      attributes: { type: "text" },
      insert: "Merge Test",
    },
    {
      attributes: { type: "text", italic: true },
      insert: " After",
    },
  ]);
}

function initializeYDoc(): Y.Doc {
  const yDoc = new Y.Doc({ gc: false });

  const content = yDoc.get("text", Y.XmlText) as Y.XmlText;
  content.insert(0, " After", { type: "text", italic: true });
  content.insert(0, "Test", { type: "text" });
  content.insert(0, "Merge ", { type: "text", bold: true });

  return yDoc;
}

The only difference between the setup for cases (1) and (2) is how the document is initialized, but they produce different results. In case (1), the format call is applied correctly. In case (2), it strips type attribute from the " After" text, even though it is outside of the provided range.

    {
      attributes: { type: "text" },
      insert: "Merge ",
    },
    {
      attributes: { type: "text" },
      insert: "Test",
    },
    {
      attributes: { italic: true },
      insert: " After",
    },

Expected behavior I would expect case (2) to behave like case (1) and not strip out the "type" attribute.

Environment Information

  • node.js v16.19.1
  • yjs v13.6.10

Additional context We are using yjs with slate-yjs and found this behavior was triggered by Slate merge_node operations on a newly loaded editor.

We found the issue in yjs v13.5.45 but have been able to repro it in v13.6.10 as well.

Huly®: YJS-408

@dmonad
Copy link
Member

dmonad commented Jan 21, 2024

Thanks for the report and the code for reproducing it!

This will be fixed in the next release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants