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; +}