syntax.js 2.1 KB

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