I’d like to be able to create overlapping text annotations (as in the image above). I have tried using the Decoration.mark from Codemirror 6, but on account of all the overlapping decorations ending up as classes on the same dom elements, I can’t create separate and overlapping styles (like the underlines and highlights above). Is what I’m looking for possible with Replace Decorations or Widget Decorations? Or some other way? I would like the text to still be editable and would like to retain the ability for the annotation to span multiple lines.
I’m happy to use Codemirror 5 or 6 to implement the extension/addon necessary. But I could use some direction on what the primitives to start with.
CSS doesn’t have a way to do this automatically. So you’d have to compute the appropriate height of the underlines on each bit of the code yourself, and then use something like SVG backgrounds to display the proper lines at each span.
@marijn Could this be implemented as an extension or would it need to be part of the core in order to function? I’d be interested in getting this to work. It seems like it could open up a lot of power for Decorations if feasible.
If you’re talking about arbitrarily nested inline nodes, I’m strongly leaning towards that being out of scope. (And I doubt it would help a lot with what you’re trying to accomplish here.)
If you mean the underline thing, you could do that as an extension—do your own splitting into spans and computing of underline heights, and then generate decorations that assign the right style to each of the ranges.
Thanks for the quick reply. To clarify, I don’t want arbitrarily nested inline nodes necessarily.
This example:
<span class="1">
te
<span class="1 overlay"></span>
</span>
<span class="1 2">
x
<span class="1 overlay"></span>
<span class="2 overlay"></span>
</span>
<span class="2">
t
<span class="2 overlay"></span>
</span>
…could be achieved with an option on the mark decoration to inject a single overlay dom element. That way, the injected overlay elements could be styled individually without conflict. Or, at least, that is naively how I am thinking of it. That’s more or less the approach I used to create the editor in the image above.
The span simply gets the :before for annotation-3, with the other annotations not being rendered to the view.
Whereas if each annotation can inject it’s own overlay element, each of those elements can be styled differently without overwriting other annotations.
Ah, right, that’s true. But no, though you can insert elements with decorations, you can’t insert them inside text spans. If you have low maximum number of underlines, you could just generate classws with background images for the 2**n possibilities of each line being present and absent, but I’m not sure if that works for your case.
That doesn’t feel like quite the right solution to me as I’d like to solve for the general case and not just underlines, but any kind of overlapping styling that could ostensibly not override others. Underlines of various colors based on some kind of taxonomy, highlights of similarly varying colors, etc. Perhaps highlights that change color on hover while still overlapping other highlights and underlines.
Could this functionality be added as an external library or would it need to be added as part of the core to function correctly? And if it would need to be added to the core in order to function, would you be open to me potentially pulling together a pull request to add an injection option to the MarkDecorationSpec with the necessary accompanying changes to internals?
That would have to be implemented in the core, and my instinct is to resist that, since this seems a very specific use case and I’d have to keep supporting that forever without knowing if anyone is still going to use it.
I can imagine adding support for multiple tagNames to create additional wrapper nodes for a given piece of content. Though in order to have that we’d need to be able to define a stable ordering for overlapping decorations, which doesn’t currently exist.