Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix code block syntax highlighting not updating when changing its language #2267

Merged
merged 15 commits into from Apr 15, 2023
Merged
15 changes: 13 additions & 2 deletions packages/editor/src/extensions/code-block/highlighter.ts
Expand Up @@ -125,9 +125,14 @@ export function HighlighterPlugin({

const changedBlocks: Set<string> = new Set();
for (const blockKey in pluginState.languages) {
Abdulrehman-Jafer marked this conversation as resolved.
Show resolved Hide resolved
if (HIGHLIGHTED_BLOCKS.has(blockKey)) continue;

const language = pluginState.languages[blockKey];
if (
HIGHLIGHTED_BLOCKS.has(blockKey) &&
refractor.registered(language)
) {
continue;
}

const languageDefinition = Languages.find(
(l) =>
l.filename === language || l.alias?.some((a) => a === language)
Expand Down Expand Up @@ -198,6 +203,12 @@ export function HighlighterPlugin({
updated.add(block.pos);

const { id, language } = block.node.attrs;

if (language && !refractor.registered(language)) {
languages[id] = language;
return { decorations, languages };
}

if (languages[id]) {
const newDecorations = getDecorations({
block,
Expand Down
15 changes: 15 additions & 0 deletions packages/editor/src/extensions/code-block/tests/code-block.test.ts
Expand Up @@ -22,6 +22,7 @@ import { expect, test, vi } from "vitest";
import { CodeBlock, inferLanguage } from "../code-block";
import { HighlighterPlugin } from "../highlighter";
import { getChangedNodes } from "../../../utils/prosemirror";
import { refractor } from "refractor/lib/core";

const CODEBLOCKS_HTML = h("div", [
h("pre", [h("code", ["function hello() { }"])], {
Expand Down Expand Up @@ -191,3 +192,17 @@ test("editing code in a highlighted code block should not be too slow", async ()
expect(timings.reduce((a, b) => a + b) / timings.length).toBeLessThan(16);
expect(editorElement.outerHTML).toMatchSnapshot();
});

test("Switching codeblock language should register the new language", async () => {
thecodrr marked this conversation as resolved.
Show resolved Hide resolved
const editorElement = h("div");
const { editor } = createEditor({
element: editorElement,
initialContent: CODEBLOCKS_HTML,
extensions: {
codeblock: CodeBlock
}
});
editor.commands.updateAttributes(CodeBlock.name, { language: "java" });
await new Promise((resolve) => setTimeout(resolve, 100));
expect(refractor.registered("java")).toBe(true);
});