Add class to mark using decoration

Is it possible change HTML attributes on a mark using decorations? I see one can add a class to a node using Decoration.node, and there’s Decoration.inline but this nests a span within the mark. I want to modify the mark’s class so I can adjust its styling.

Here’s the use case: Users can add comments to the document which are tracked using marks. When a user clicks on a comment (outside of the editor) I want to highlight the comment in the editor by darkening the background color. I tried manually adding highlight class to the DOM but have noticed some issues and, from my understanding, we’re not supposed to edit the DOM directly.

I could add a highlight attribute to the mark but this would be synced with collaborators and persisted in the document. I want highlighting to be a visual indicator for the one user.

Any ideas how to achieve this?

1 Like

Edit: I wrote up a reply but I think I missed this - “I want highlighting to be a visual indicator for the one user.”

This is an interesting problem. Its possible that Mark Views may work here. But even with decorations, you should be able to programatically apply a class if you can get access in toDOM of your mark schema. It’s not entirely clear what went wrong here or if you tried this as I am expecting.

As for the undesired inner nesting, its possible that you may need to adjust the decoration position - 1 (and target via inheritance)? Or maybe there is either an existing priority flag or a new one to be thought of that might resolve it. Library author would know off-hand.

No, inline decorations are drawn inside the wrapper elements added for marks, you can’t directly add attributes to those.

I recently stumbled upon something similar - and am not sure if this has been solved in the time since (sorry for the necro, this was asked over a year ago after all).

But wouldn’t a CSS-based solution work here as a workaround?

  1. have the mark have an ID attribute like <mark data-comment-id="12312321">
  2. When the user clicks on the mark, add an attribute to the editor element (or parent, probably doesn’t need to be the prosemirror instance itself), like data-active-comment-id
  3. have a bit of javascript that live-updates a <style> tag that basically has the following:
    [data-active-comment-id="123"] mark[data-comment-id="123"] {
      background-color: yellow;
    }
    

Unless I got something wrong, that way, you’re not touching any ProseMirror stuff (not even for editor/plugin state).

I assume it would require a major rework, or maybe not even be possible, to apply decorations directly to marks, but it would increase the use cases and (potentially dramatically) decrease the number of DOM elements, and thus performance.

I’m finding this to be a pain point right now and it seems our only workaround might be to end up adding these classNames directly to the mark’s spec, but this is very lackluster.