SyntaxHighlight throw error on shadow DOM

I try to use the CodeMirror with custom language in a Vaadin Dialog, but I ran into errors.

import {EditorView, lineNumbers} from "@codemirror/view";
import {EditorState} from "@codemirror/state";
import {HighlightStyle, StreamLanguage, syntaxHighlighting} from "@codemirror/language";
import {tags} from "@lezer/highlight"

...

  const dialog = document.createElement('vaadin-dialog', {});
  document.body.appendChild(dialog);

  dialog.renderer = (root, dialog) => {
    const editorContainer = document.createElement('div');
    root.appendChild(editorContainer);

    const customLanguage = StreamLanguage.define({...});
    const myHighlightStyle = HighlightStyle.define([ { tag: tags.keyword, color: "#E06C75" }, ...]);

    const editorState = EditorState.create({
      doc: "The custom language content",
      extensions: [
        lineNumbers(),
        customLanguage,
        syntaxHighlighting(myHighlightStyle)
     ],
  });

  const editorView = new EditorView({
    state: editorState,
    parent: editorContainer,
    // give the shadow root context
    root: root.getRootNode()
  });

If I add the syntax highlighting to the extensions, then I get the following error:

CodeMirror plugin crashed: TypeError: e is not iterable
    at zy.style (index.js:261:29)
    at index.js:278:33
    at iy.highlightRange (index.js:365:22)
    at ty (index.js:306:13)
    at Wy.buildDeco (index.js:1784:13)
    at new Wy (index.js:1762:33)
    at wf.create (index.js:2502:49)
    at xf.update (index.js:2522:51)
    at new vg (index.js:7557:20)
    at t.renderer [as _oldRenderer]

Any idea?

I use the following versions:

"@codemirror/language": "^6.11.2",
    "@codemirror/state": "^6.5.2",
    "@codemirror/view": "^6.38.1",
    "@lezer/highlight": "^1.2.1",
    "@vaadin/vaadin-core": "^16.0.1",

Can you reproduce this without @vaadin/vaadin-core? If so, could you set up a minimal, self-contained script that produces the error, and tell me which browser(s) you’re seeing it in?

Yes. Can easily reproduce it without Vaadin. Just put the editor into the Shadow DOM.

Here is a short example. I tested it with Chrome.

<!DOCTYPE html>
<html>
<head>
<title>CodeMirror 6 Custom Syntax Highlighting</title>
<style>
  body { font-family: sans-serif; margin: 20px; }
  .cm-editor {
    border: 1px solid #ccc;
    height: auto;
  }
  .cm-keyword { color: #007bff; font-weight: bold; } /* Kék a PROGRAM-hoz */
  .cm-keyword-jelszo { color: #dc3545; font-weight: bold; }  /* Piros a JELSZÓ-hoz */
</style>
</head>
<body>

<h1>CodeMirror 6 Custom Syntax Highlighting with shadow DOM</h1>

<script type="module">
  import { EditorView } from 'https://esm.sh/@codemirror/view';
  import { EditorState } from 'https://esm.sh/@codemirror/state';
  import { HighlightStyle, StreamLanguage, syntaxHighlighting } from 'https://esm.sh/@codemirror/language';
  import {tags} from "https://esm.sh/@lezer/highlight"
  
	const root = document.createElement("div");
	document.body.append(root);
	const editor = document.createElement("div");
	
	//TODO use this to use without shadow DOM
	//root.append(editor);
	
	//TODO comment this two line out to not use the shadow DOM
	const shadow = root.attachShadow({ mode: "open" });
	shadow.append(editor);

  const myLanguage = StreamLanguage.define({
	name: "Signalterv",
	startState: () => ({}),
	token: (stream) => {
	
		const commands = ["JELSZO", "VEGE", "PROGRAM"];

		for (let cmd of commands) {
			if (stream.match(new RegExp(`^${cmd} `, ''))) {
				return "keyword";
			}
		}		

		if (stream.match(/^[a-zA-Z0-9,\-_|#]+/)) { 
			return "string"; 
		}

		stream.next();
        return null;
	}
  });

  const doc = `PROGRAM MyAwesomeProgram
  This is some code.
  JELSZO SecretPassword123
  Another code line.
VEGE `;



	const myHighlightStyle = HighlightStyle.define([
		{ tag: tags.keyword, class: 'cm-keyword' },
	]);

  new EditorView({
    state: EditorState.create({
      doc: doc,
      extensions: [
        myLanguage, 
		syntaxHighlighting(myHighlightStyle, {fallback: true})
      ]
    }),
    parent: editor,
    // TODO comment it out to not use the shadow DOM
	root: shadow
  });
</script>

</body>
</html>

I get no errors thrown when I run this (see for example here) in Chrome.

Yes you are right. I did not noticed that no error thrown with this example, but as you can see, no highlighting either in the editor.

So probably the exception is cached somewhere.

If you follow the TODO comments, you will see, that without the ShadowDOM the code will be highlighted, but if pasted into the shadowDOM, the syntaxHighlighting() doesn’t work.

The class names are there in the editor content. The reason they don’t have a color is that you defined their styles in the outer document, and they won’t take effect inside the shadow DOM.

ok. I will check it tomorrow at work and then try to give you an small vaadin example with the exception then.

Well, seems that was a code bug on my side. I replaced the old stream/highlight code with the one from the example, and it worked in the Vaadin dialog as well.

So I am very thankful for your help!