CSS class precedence issue with hljs

So my project uses PM as its wysiwyg editor and uses prosemirror-highlightjs to highlight code inside of the pm editor.

An issue that I’ve been having is that some code is highlighted incorrectly inside of the prosemirror editor. Here’s an example:

The left side is how it should look, the right side is how it looks inside of prosemirror. And the issues get worse with other languages like C# that have more tokens


My first thought was the fact that prosemirror flattens the styles on nodes, so a

<span class="hljs-meta">
    <span class="hljs-meta-string">iostream</span>
</span>

would be converted to

<span class="hljs-meta-string hljs-meta">iostream</span>

and I checked the HTML and (at first) saw that it was placing the parent class after the child class, and thought this was the reason it was highlighting incorrectly.

Then I realized it was only doing that about half the time and I figured out that that wasn’t the issue.


So I looked at the css styles that were applying in chrome devtools some more, and I noticed that it doesn’t matter what order the classes in the style tag are in.

I found out on Stack Overflow that if there are multiple classes in the style tag, CSS picks the style that’s physically farther down in the .css file.

The highlight.js stylesheet files (119 of them in version 10) are all structured very differently so I think it would be impractical to try to edit all of the stylesheets to match like a hljs-meta hljs-meta-string selector.

So does anyone have some advice on how I could fix this issue? My first thought would be to just not flatten the text nodes inside codeblocks but I don’t know if that’s even possible

Hierarchical DOM structure of inline content isn’t something ProseMirror support, so you’ll have to look in a different direction (possibly only applying the innermost style).

Looking into this, here’s what the plugin is doing in my example on the #include <iostream> line:

It’s creating a Decoration for the entire line with the class hljs-meta. Then it makes a hljs-meta-keyword decoration for #include and a hljs-meta-string decoration for the <iostream> part

So it’s creating a decoration for each of those keywords in the line, and then another decoration that covers both of those.

How would I go about forcing it to only apply the innermost style?