Using decorations for comments - yes or no?

Hey community!

I’m currently working on a commenting / threads feature and resorted into using marks and nodes for adding comments into the content as we want those to be included in the history + need to keep track of their positions in a yjs document.

Now I’m running into a few issues where the Prosemirror schema I setup is getting restrictive and prevents comments to be wrapped for example around list items. Since my implementation is not a specific one for me but a generic solution for others I don’t want users to forcefully adjust their schemas to allow my comment marks and nodes in each of their elements.

Before going for nodes and marks I tried to solve this via decorations but ran into several issues as for example:

  • Decorations not working with the history / y-prosemirror history
  • Storing said decoration from and to positions and keeping those positions updated whenever changes occur (specifically remote changes from other yjs clients)
  • Ran into a few issues while copy pasting / moving content around but that could also be an issue of my implementation

I wanted to store each comment inside the yjs document including their from and to positions but those would need to be kept in sync with the actual positions when the document change.

I’d like to get back to this because I think using decorations would be benefitial as it doesn’t change the documents content structure & can be used while respecting the Prosemirror schema. My questions now would be:

  • Is this actually a good idea? Are there any drawbacks I didn’t include when using decorations for that?
  • What would be a good solution to keep comment positions in sync between yjs and the editor (specifically with multiple clients?)
  • Are there any solutions that are similar to what I’m looking for? I found some but all of them suffer from the same issues I described
  • Can I somehow trick the history to keep information about changes on decorations so I can revert them on undo?
1 Like

I think generally,

  • keeping comments positions in a separate data store but also having to keep them in sync with changes in the document and mapping them through all transactions,
  • and not being supported by native undo-redo, or by yjs (which means you would have to implement a custom history plugin)

have been reasons why comments have for the most part been modeled as marks, instead of decorations.

Lot more details in Prosemirror: Highlights & Comments | by Ronny Roeller | NEXT Engineering | Medium.

Yep that’s also why we ran back to marks after fiddleing around with DecorationSets before. I’ll check out the linked article. Do you have any insights when it comes to restrictive schemas? Should I just let my users know that they have to customize the schema to allow comments everywhere?

Not particularly? Could you elaborate with a code example to illustrate the difficulties a developer could have integrating your comments mark into their schema?

No exact code example but two specific cases.

As I said we have two types of content types first we have a inlineThread mark that we use for everything that relates to inline selections inside a text node.

As soon as your selection is wrapping one or multiple block nodes / non-text nodes though, we wrap said nodes with a blockThread node which works almost the same as a mark but is of type node so we are able to for example wrap it around images for example.

This both works as long as it works for the schema.

  <li><p>Item A</p></li>
  <li><p>Item B</p></li>
  <li><p>Item C</p></li>

Lets say I want to select Item A and B and add a comment to those now I’m currently trying to wrap both list items with a blockThread node which does not work as our unorderedList node isn’t expecting / allowing any other nodes then listItem nodes.

Maybe there’s a better solution for those cases but even then we also have a few limitations for our mark. For example our default inline code mark won’t allow any other marks inside (since we don’t want to parse any other html markup inside as it’s inline code which shouldn’t be parsed anyway) so users would be required to update their schema to allow inlineMarks there.

Maybe I’m heavily overthinking or thinking into a wrong direction with my solution but that were the problems I struggled with while implementing marks/nodes for threads right now.

You can do block-level marks but you would need the image parent to allow for the thread mark. So maybe you can keep comments as marks strictly.