Converting editor selection into absolute position for yjs doc?

So I am using yjs for the document however I am having a problem being able to take the selected text and relate that to the absolute positions in the yjs doc. I can get the select however the selection is related to the editor so when this is map to the yjs doc, it is incorrect as the yjs document includes the html element when reference postion.

How can I convert the editor selection positions to the correct positions in the yjs doc?

Personally, I don’t understand what you are working on and what you want to achieve. Yjs is being used in a wide area of applications. Please try to be more specific…

@dmonad Well I tried to present the simple form of my problem to avoid unneeded extra complexity but ok.

I have a text editor using TipTap (which uses prosemirror under the hood) and I want to add collaboration support. To do this, I am using yjs with TipTap’s TiptapCollabProvider to connect the yjs doc, our custom backend, and the TipTap’s editor. We are also using TipTap’s Collaboration and CollaborationCursor extension to get the real-time mouse position of people in the document. This all is working but something else we want to add is commenting include adding comments to a specific block of text.

Now best I can tell is in order to do that is to reference comments to a starting and ending relative position of the yjs doc itself (that way if the selected text for the comment has content add to or remove from, those relatively position will keep the correct start and end of where the selected text of the comment should be). This is where my issue is. While I can get the text select range from the TipTap editor, those values are based on the TipTap editor and not the underlying yjs doc format so those values are always lower than they should be (since the yjs doc seems to include the html content that the TipTap editor dealing with), or at least this is my best guess.

I have tried a number of manual combinations using Y.createRelativePositionFromTypeIndex() but they seem to always return null values where they should not (which from my understanding is expected as the format of the yjs doc that comes from TipTap is Y.XmlFragment and not a Y.Text). There is also a y-prosemirror library (which is the underlying library the TipTap uses) and I have tried combinations of absolutePositionToRelativePosition, relativePositionToAbsolutePosition, and getRelativeSelection and while they do give position back, they are always smaller then they should be (when I use them to get the text with doc.get('default', Y.XmlFragment).toString().substring(startIndex, endIndex), it always returns text previous to what is should be) so either I am doing 2 things wrong:

  • I am not getting the correct relative positions (and since I am using officially libraries now, I would think this is correct)
  • I am using those relative position wrong in trying to get the content they represent (which I would assume is the case but I can’t find any references on how to do this properly).

In Yjs, positions are always relative to a parent-type.

Y.createRelativePositionFromAbsolutePosition(rootYXmlFragment, 5000) will not work, because it is not traversing the children.

Since Prosemirror traverses children, I built this helper library that traverses children: y-prosemirror/src/lib.js at master · yjs/y-prosemirror · GitHub

Maybe check the source code for usage examples.

The documentation for the underlying technology can be found here: Y.RelativePosition | Yjs Docs

Like I said, I am using that library and that method but I can’t see to find a way to use absolutePositionToRelativePosition() and relativePositionToAbsolutePosition() to selected the text it should be referencing in the yjs doc