yjs / y-prosemirror

ProseMirror editor binding for Yjs

Home Page:https://demos.yjs.dev/prosemirror/prosemirror.html

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

prosemirrorJSONToYXmlFragment doesn't work if no given YXmlFragment

NathanLauth opened this issue · comments

Describe the bug
In order to initially create and populate my Y.Doc in my server (Before sharing it with my frontend) I want to use y-prosemirror utility fonctions.
The final goal is to have my Tiptap Wysiwyg nicely displayed with the already existing data in my DataBase (HTML stored as String).
I already have my Y.Doc, and I only want to create a new Y.XmlFragment populated with my existing HTML.

So the utility function prosemirrorJSONToYXmlFragment(schema, state) looks perfect for my usage.
But it seems that the method cannot return a populated Y.XmlFragment, without giving an existing one already linked to an existing Y.Doc

To Reproduce
I think the best thing I can do is to provide a real exemple of what I am trying to do :

import * as Y from "yjs";
import { generateJSON } from "@tiptap/html";
import { prosemirrorJSONToYXmlFragment } from "y-prosemirror";
import { getSchema } from "@tiptap/core";

const htmlFromDataBase = "<p>Hello !</p>";
const yDoc = new Y.Doc();

// import from tiptap are omitted (but theses are only tiptap extensions).
const tiptapExtensions = [Document, Paragraph, Text, Link, BulletList, ListItem, OrderedList, Bold, Italic, Underline, Strike];

const schema = getSchema(tiptapExtensions);

const state = generateJSON(htmlFromDataBase, tiptapExtensions);

const xmlFragment = yDoc.getXmlFragment('myFragment');
// Here xmlFragment and yFragment are correctly populated with my given HTML. Working exemple !
const yFragment = prosemirrorJSONToYXmlFragment(schema, state, xmlFragment);

// If I would have done that, newFragment would have been empty (without Y.XmlElements) 
const newFragment = prosemirrorJSONToYXmlFragment(schema, state);

// Same I gave and existing fragment ! updateFragment is witout any elements.
const updateFragment = prosemirrorJSONToYXmlFragment(schema, state, new Y.XmlFragment());

// So i guess it only work if the given Y.XmlFragment is already linked to and existing Y.Doc !

Expected behavior
I expect that if i use the method prosemirrorJSONToYXmlFragment(schema, state) with valid schema and json, it should create me a populated Y.XmlFragment

Environment Information

  • NodeJs : V20.2.0
  • Yjs : 13.6.0
  • y-prosemirror : 1.2.1
  • tiptap : 2.0.3 (with given packages : html, core, extensions cf code*)

I have stumbled upon this issue as well.

This makes it very difficult to restore a XmlFragment from the output of XmlFragment.toJSON(). Especially, because the XmlFragment cannot be properly cloned to be inserted in another yDoc.

You can see a reproduction of the above and the problem with the clone here: https://codesandbox.io/p/sandbox/agitated-night-7fgj8d

You just have to open the console from the served page to the right.

I think you can create the XmlFragment with prosemirrorJSONToYXmlFragment(schema, state), but you can only get its contents after linking to a Y.Doc. See https://github.com/yjs/yjs/blob/main/src/types/YXmlFragment.js#L306.