1 | import Parchment from 'parchment';
|
2 | import Quill from '../core/quill';
|
3 | import Module from '../core/module';
|
4 | import CodeBlock from '../formats/code';
|
5 |
|
6 |
|
7 | class SyntaxCodeBlock extends CodeBlock {
|
8 | replaceWith(block) {
|
9 | this.domNode.textContent = this.domNode.textContent;
|
10 | this.attach();
|
11 | super.replaceWith(block);
|
12 | }
|
13 |
|
14 | highlight(highlight) {
|
15 | let text = this.domNode.textContent;
|
16 | if (this.cachedText !== text) {
|
17 | if (text.trim().length > 0 || this.cachedText == null) {
|
18 | this.domNode.innerHTML = highlight(text);
|
19 | this.domNode.normalize();
|
20 | this.attach();
|
21 | }
|
22 | this.cachedText = text;
|
23 | }
|
24 | }
|
25 | }
|
26 | SyntaxCodeBlock.className = 'ql-syntax';
|
27 |
|
28 |
|
29 | let CodeToken = new Parchment.Attributor.Class('token', 'hljs', {
|
30 | scope: Parchment.Scope.INLINE
|
31 | });
|
32 |
|
33 |
|
34 | class Syntax extends Module {
|
35 | static register() {
|
36 | Quill.register(CodeToken, true);
|
37 | Quill.register(SyntaxCodeBlock, true);
|
38 | }
|
39 |
|
40 | constructor(quill, options) {
|
41 | super(quill, options);
|
42 | if (typeof this.options.highlight !== 'function') {
|
43 | throw new Error('Syntax module requires highlight.js. Please include the library on the page before Quill.');
|
44 | }
|
45 | let timer = null;
|
46 | this.quill.on(Quill.events.SCROLL_OPTIMIZE, () => {
|
47 | clearTimeout(timer);
|
48 | timer = setTimeout(() => {
|
49 | this.highlight();
|
50 | timer = null;
|
51 | }, this.options.interval);
|
52 | });
|
53 | this.highlight();
|
54 | }
|
55 |
|
56 | highlight() {
|
57 | if (this.quill.selection.composing) return;
|
58 | this.quill.update(Quill.sources.USER);
|
59 | let range = this.quill.getSelection();
|
60 | this.quill.scroll.descendants(SyntaxCodeBlock).forEach((code) => {
|
61 | code.highlight(this.options.highlight);
|
62 | });
|
63 | this.quill.update(Quill.sources.SILENT);
|
64 | if (range != null) {
|
65 | this.quill.setSelection(range, Quill.sources.SILENT);
|
66 | }
|
67 | }
|
68 | }
|
69 | Syntax.DEFAULTS = {
|
70 | highlight: (function() {
|
71 | if (window.hljs == null) return null;
|
72 | return function(text) {
|
73 | let result = window.hljs.highlightAuto(text);
|
74 | return result.value;
|
75 | };
|
76 | })(),
|
77 | interval: 1000
|
78 | };
|
79 |
|
80 |
|
81 | export { SyntaxCodeBlock as CodeBlock, CodeToken, Syntax as default};
|