diff --git a/modules/syntax.js b/modules/syntax.js
index bf7ff4cc72..356a9b4628 100644
--- a/modules/syntax.js
+++ b/modules/syntax.js
@@ -10,6 +10,7 @@ import TextBlot, { escapeText } from '../blots/text';
import CodeBlock, { CodeBlockContainer } from '../formats/code';
import { traverse } from './clipboard';
import hasWindow from '../utils/has_window';
+import isVersionNotLessThan from '../utils/is_version_not_less_than';
const TokenAttributor = new ClassAttributor('code-token', 'hljs', {
scope: Scope.INLINE,
@@ -256,7 +257,15 @@ class Syntax extends Module {
}
const container = this.quill.root.ownerDocument.createElement('div');
container.classList.add(CodeBlock.className);
- container.innerHTML = this.options.hljs.highlight(language, text).value;
+
+ const highlightJsVersion = this.options.hljs.versionString;
+ if (isVersionNotLessThan(highlightJsVersion, '10.7')) {
+ // NOTE: https://github.com/highlightjs/highlight.js/issues/2277;
+ container.innerHTML = this.options.hljs.highlight(text, { language }).value;
+ } else {
+ container.innerHTML = this.options.hljs.highlight(language, text).value;
+ }
+
return traverse(
this.quill.scroll,
container,
diff --git a/test/unit/modules/syntax.js b/test/unit/modules/syntax.js
index 9b0db6032a..63673018bd 100644
--- a/test/unit/modules/syntax.js
+++ b/test/unit/modules/syntax.js
@@ -17,10 +17,16 @@ describe('Syntax', function () {
];
});
- beforeEach(function () {
+ afterAll(function () {
+ Quill.register(CodeBlock, true);
+ Quill.register(CodeBlockContainer, true);
+ });
+
+ function initializeQuill(codeBlockText) {
+ const codeBlockMarkup = codeBlockText ?? 'var test = 1;
var bugz = 0;
';
const container = this.initialize(
HTMLElement,
- `
var test = 1;
var bugz = 0;
+ `${codeBlockMarkup}
`,
);
this.quill = new Quill(container, {
@@ -31,14 +37,64 @@ describe('Syntax', function () {
},
},
});
- });
+ }
- afterAll(function () {
- Quill.register(CodeBlock, true);
- Quill.register(CodeBlockContainer, true);
+ describe('highlightjs api', function () {
+ it('logs no deprecation warning after code-block is applied (T1247520)', function (done) {
+ const consoleSpy = spyOn(console, 'log');
+
+ initializeQuill.call(this);
+
+ setTimeout(() => {
+ const logArgs = consoleSpy.calls.allArgs();
+ expect(consoleSpy)
+ .withContext(`console.log was called with "${logArgs}"`)
+ .not.toHaveBeenCalled();
+ consoleSpy.calls.reset();
+ done();
+ }, HIGHLIGHT_INTERVAL + 1);
+ });
+
+ it('works with no errors if old version of highlightjs is used', function (done) {
+ const { versionString } = hljs;
+ const initialCodeBlockText = 'my text\n';
+
+ hljs.versionString = '10.1.4';
+ const highlightSpy = spyOn(hljs, 'highlight');
+
+ initializeQuill.call(this, initialCodeBlockText);
+
+ setTimeout(() => {
+ expect(highlightSpy).toHaveBeenCalledWith('javascript', initialCodeBlockText);
+ hljs.versionString = versionString;
+ highlightSpy.calls.reset();
+ done();
+ }, HIGHLIGHT_INTERVAL + 1);
+ });
+
+ it('uses modern api for new versions', function (done) {
+ const { versionString } = hljs;
+ const initialCodeBlockText = 'my text\n';
+
+ hljs.versionString = '12.1.1';
+ const highlightSpy = spyOn(hljs, 'highlight');
+
+ initializeQuill.call(this, initialCodeBlockText);
+
+ setTimeout(() => {
+ expect(highlightSpy).toHaveBeenCalledWith(initialCodeBlockText, { language: 'javascript' });
+ hljs.versionString = versionString;
+ highlightSpy.calls.reset();
+ done();
+ }, HIGHLIGHT_INTERVAL + 1);
+ });
});
describe('highlighting', function () {
+ beforeEach(function () {
+ initializeQuill.call(this);
+ });
+
it('initialize', function () {
expect(this.quill.root).toEqualHTML(
`
@@ -225,6 +281,12 @@ describe('Syntax', function () {
}, HIGHLIGHT_INTERVAL + 1);
});
+ it('code language', function () {
+ expect(this.quill.getSemanticHTML()).toContain(
+ 'data-language="javascript"',
+ );
+ });
+
describe('allowedChildren', function () {
beforeAll(function () {
SyntaxCodeBlock.allowedChildren.push(BoldBlot);
@@ -295,12 +357,4 @@ describe('Syntax', function () {
});
});
});
-
- describe('html', function () {
- it('code language', function () {
- expect(this.quill.getSemanticHTML()).toContain(
- 'data-language="javascript"',
- );
- });
- });
});
diff --git a/utils/is_version_not_less_than.js b/utils/is_version_not_less_than.js
new file mode 100644
index 0000000000..7a1f58c84f
--- /dev/null
+++ b/utils/is_version_not_less_than.js
@@ -0,0 +1,17 @@
+export default function isVersionNotLessThan(version, versionToCompare) {
+ const aVersionArray = version.split('.').map(Number);
+ const bVersionArray = versionToCompare.split('.').map(Number);
+
+ const maxVersionLength = Math.max(aVersionArray.length, bVersionArray.length);
+
+ for (let i = 0; i < maxVersionLength; i += 1) {
+ const a = aVersionArray[i] ?? 0;
+ const b = bVersionArray[i] ?? 0;
+
+ if (a !== b) {
+ return a > b;
+ }
+ }
+
+ return true;
+}