@tiptap/extension-code-block-lowlight 2.5.0-beta.5 → 2.5.0-beta.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.umd.js CHANGED
@@ -8,37 +8,41 @@
8
8
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
9
9
  }
10
10
 
11
- var deepFreezeEs6 = {exports: {}};
11
+ /* eslint-disable no-multi-assign */
12
12
 
13
13
  function deepFreeze(obj) {
14
- if (obj instanceof Map) {
15
- obj.clear = obj.delete = obj.set = function () {
16
- throw new Error('map is read-only');
14
+ if (obj instanceof Map) {
15
+ obj.clear =
16
+ obj.delete =
17
+ obj.set =
18
+ function () {
19
+ throw new Error('map is read-only');
17
20
  };
18
- } else if (obj instanceof Set) {
19
- obj.add = obj.clear = obj.delete = function () {
20
- throw new Error('set is read-only');
21
+ } else if (obj instanceof Set) {
22
+ obj.add =
23
+ obj.clear =
24
+ obj.delete =
25
+ function () {
26
+ throw new Error('set is read-only');
21
27
  };
22
- }
28
+ }
23
29
 
24
- // Freeze self
25
- Object.freeze(obj);
30
+ // Freeze self
31
+ Object.freeze(obj);
26
32
 
27
- Object.getOwnPropertyNames(obj).forEach(function (name) {
28
- var prop = obj[name];
33
+ Object.getOwnPropertyNames(obj).forEach((name) => {
34
+ const prop = obj[name];
35
+ const type = typeof prop;
29
36
 
30
- // Freeze prop if it is an object
31
- if (typeof prop == 'object' && !Object.isFrozen(prop)) {
32
- deepFreeze(prop);
33
- }
34
- });
37
+ // Freeze prop if it is an object or function and also not already frozen
38
+ if ((type === 'object' || type === 'function') && !Object.isFrozen(prop)) {
39
+ deepFreeze(prop);
40
+ }
41
+ });
35
42
 
36
- return obj;
43
+ return obj;
37
44
  }
38
45
 
39
- deepFreezeEs6.exports = deepFreeze;
40
- deepFreezeEs6.exports.default = deepFreeze;
41
-
42
46
  /** @typedef {import('highlight.js').CallbackResponse} CallbackResponse */
43
47
  /** @typedef {import('highlight.js').CompiledMode} CompiledMode */
44
48
  /** @implements CallbackResponse */
@@ -117,7 +121,7 @@
117
121
  const emitsWrappingTags = (node) => {
118
122
  // rarely we can have a sublanguage where language is undefined
119
123
  // TODO: track down why
120
- return !!node.scope || (node.sublanguage && node.language);
124
+ return !!node.scope;
121
125
  };
122
126
 
123
127
  /**
@@ -126,6 +130,11 @@
126
130
  * @param {{prefix:string}} options
127
131
  */
128
132
  const scopeToCSSClass = (name, { prefix }) => {
133
+ // sub-language
134
+ if (name.startsWith("language:")) {
135
+ return name.replace("language:", "language-");
136
+ }
137
+ // tiered scope: comment.line
129
138
  if (name.includes(".")) {
130
139
  const pieces = name.split(".");
131
140
  return [
@@ -133,6 +142,7 @@
133
142
  ...(pieces.map((x, i) => `${x}${"_".repeat(i + 1)}`))
134
143
  ].join(" ");
135
144
  }
145
+ // simple scope
136
146
  return `${prefix}${name}`;
137
147
  };
138
148
 
@@ -165,12 +175,8 @@
165
175
  openNode(node) {
166
176
  if (!emitsWrappingTags(node)) return;
167
177
 
168
- let className = "";
169
- if (node.sublanguage) {
170
- className = `language-${node.language}`;
171
- } else {
172
- className = scopeToCSSClass(node.scope, { prefix: this.classPrefix });
173
- }
178
+ const className = scopeToCSSClass(node.scope,
179
+ { prefix: this.classPrefix });
174
180
  this.span(className);
175
181
  }
176
182
 
@@ -202,8 +208,8 @@
202
208
  }
203
209
  }
204
210
 
205
- /** @typedef {{scope?: string, language?: string, sublanguage?: boolean, children: Node[]} | string} Node */
206
- /** @typedef {{scope?: string, language?: string, sublanguage?: boolean, children: Node[]} } DataNode */
211
+ /** @typedef {{scope?: string, language?: string, children: Node[]} | string} Node */
212
+ /** @typedef {{scope?: string, language?: string, children: Node[]} } DataNode */
207
213
  /** @typedef {import('highlight.js').Emitter} Emitter */
208
214
  /** */
209
215
 
@@ -308,13 +314,11 @@
308
314
 
309
315
  Minimal interface:
310
316
 
311
- - addKeyword(text, scope)
312
317
  - addText(text)
313
- - addSublanguage(emitter, subLanguageName)
318
+ - __addSublanguage(emitter, subLanguageName)
319
+ - startScope(scope)
320
+ - endScope()
314
321
  - finalize()
315
- - openNode(scope)
316
- - closeNode()
317
- - closeAllNodes()
318
322
  - toHTML()
319
323
 
320
324
  */
@@ -333,34 +337,31 @@
333
337
 
334
338
  /**
335
339
  * @param {string} text
336
- * @param {string} scope
337
340
  */
338
- addKeyword(text, scope) {
341
+ addText(text) {
339
342
  if (text === "") { return; }
340
343
 
341
- this.openNode(scope);
342
- this.addText(text);
343
- this.closeNode();
344
+ this.add(text);
344
345
  }
345
346
 
346
- /**
347
- * @param {string} text
348
- */
349
- addText(text) {
350
- if (text === "") { return; }
347
+ /** @param {string} scope */
348
+ startScope(scope) {
349
+ this.openNode(scope);
350
+ }
351
351
 
352
- this.add(text);
352
+ endScope() {
353
+ this.closeNode();
353
354
  }
354
355
 
355
356
  /**
356
357
  * @param {Emitter & {root: DataNode}} emitter
357
358
  * @param {string} name
358
359
  */
359
- addSublanguage(emitter, name) {
360
+ __addSublanguage(emitter, name) {
360
361
  /** @type DataNode */
361
362
  const node = emitter.root;
362
- node.sublanguage = true;
363
- node.language = name;
363
+ if (name) node.scope = `language:${name}`;
364
+
364
365
  this.add(node);
365
366
  }
366
367
 
@@ -370,6 +371,7 @@
370
371
  }
371
372
 
372
373
  finalize() {
374
+ this.closeAllNodes();
373
375
  return true;
374
376
  }
375
377
  }
@@ -674,28 +676,18 @@
674
676
  relevance: 0
675
677
  };
676
678
  const REGEXP_MODE = {
677
- // this outer rule makes sure we actually have a WHOLE regex and not simply
678
- // an expression such as:
679
- //
680
- // 3 / something
681
- //
682
- // (which will then blow up when regex's `illegal` sees the newline)
683
- begin: /(?=\/[^/\n]*\/)/,
684
- contains: [{
685
- scope: 'regexp',
686
- begin: /\//,
687
- end: /\/[gimuy]*/,
688
- illegal: /\n/,
689
- contains: [
690
- BACKSLASH_ESCAPE,
691
- {
692
- begin: /\[/,
693
- end: /\]/,
694
- relevance: 0,
695
- contains: [BACKSLASH_ESCAPE]
696
- }
697
- ]
698
- }]
679
+ scope: "regexp",
680
+ begin: /\/(?=[^/\n]*\/)/,
681
+ end: /\/[gimuy]*/,
682
+ contains: [
683
+ BACKSLASH_ESCAPE,
684
+ {
685
+ begin: /\[/,
686
+ end: /\]/,
687
+ relevance: 0,
688
+ contains: [BACKSLASH_ESCAPE]
689
+ }
690
+ ]
699
691
  };
700
692
  const TITLE_MODE = {
701
693
  scope: 'title',
@@ -731,31 +723,31 @@
731
723
  };
732
724
 
733
725
  var MODES = /*#__PURE__*/Object.freeze({
734
- __proto__: null,
735
- MATCH_NOTHING_RE: MATCH_NOTHING_RE,
736
- IDENT_RE: IDENT_RE,
737
- UNDERSCORE_IDENT_RE: UNDERSCORE_IDENT_RE,
738
- NUMBER_RE: NUMBER_RE,
739
- C_NUMBER_RE: C_NUMBER_RE,
740
- BINARY_NUMBER_RE: BINARY_NUMBER_RE,
741
- RE_STARTERS_RE: RE_STARTERS_RE,
742
- SHEBANG: SHEBANG,
743
- BACKSLASH_ESCAPE: BACKSLASH_ESCAPE,
744
- APOS_STRING_MODE: APOS_STRING_MODE,
745
- QUOTE_STRING_MODE: QUOTE_STRING_MODE,
746
- PHRASAL_WORDS_MODE: PHRASAL_WORDS_MODE,
747
- COMMENT: COMMENT,
748
- C_LINE_COMMENT_MODE: C_LINE_COMMENT_MODE,
749
- C_BLOCK_COMMENT_MODE: C_BLOCK_COMMENT_MODE,
750
- HASH_COMMENT_MODE: HASH_COMMENT_MODE,
751
- NUMBER_MODE: NUMBER_MODE,
752
- C_NUMBER_MODE: C_NUMBER_MODE,
753
- BINARY_NUMBER_MODE: BINARY_NUMBER_MODE,
754
- REGEXP_MODE: REGEXP_MODE,
755
- TITLE_MODE: TITLE_MODE,
756
- UNDERSCORE_TITLE_MODE: UNDERSCORE_TITLE_MODE,
757
- METHOD_GUARD: METHOD_GUARD,
758
- END_SAME_AS_BEGIN: END_SAME_AS_BEGIN
726
+ __proto__: null,
727
+ APOS_STRING_MODE: APOS_STRING_MODE,
728
+ BACKSLASH_ESCAPE: BACKSLASH_ESCAPE,
729
+ BINARY_NUMBER_MODE: BINARY_NUMBER_MODE,
730
+ BINARY_NUMBER_RE: BINARY_NUMBER_RE,
731
+ COMMENT: COMMENT,
732
+ C_BLOCK_COMMENT_MODE: C_BLOCK_COMMENT_MODE,
733
+ C_LINE_COMMENT_MODE: C_LINE_COMMENT_MODE,
734
+ C_NUMBER_MODE: C_NUMBER_MODE,
735
+ C_NUMBER_RE: C_NUMBER_RE,
736
+ END_SAME_AS_BEGIN: END_SAME_AS_BEGIN,
737
+ HASH_COMMENT_MODE: HASH_COMMENT_MODE,
738
+ IDENT_RE: IDENT_RE,
739
+ MATCH_NOTHING_RE: MATCH_NOTHING_RE,
740
+ METHOD_GUARD: METHOD_GUARD,
741
+ NUMBER_MODE: NUMBER_MODE,
742
+ NUMBER_RE: NUMBER_RE,
743
+ PHRASAL_WORDS_MODE: PHRASAL_WORDS_MODE,
744
+ QUOTE_STRING_MODE: QUOTE_STRING_MODE,
745
+ REGEXP_MODE: REGEXP_MODE,
746
+ RE_STARTERS_RE: RE_STARTERS_RE,
747
+ SHEBANG: SHEBANG,
748
+ TITLE_MODE: TITLE_MODE,
749
+ UNDERSCORE_IDENT_RE: UNDERSCORE_IDENT_RE,
750
+ UNDERSCORE_TITLE_MODE: UNDERSCORE_TITLE_MODE
759
751
  });
760
752
 
761
753
  /**
@@ -909,7 +901,7 @@
909
901
  * @param {boolean} caseInsensitive
910
902
  */
911
903
  function compileKeywords(rawKeywords, caseInsensitive, scopeName = DEFAULT_KEYWORD_SCOPE) {
912
- /** @type KeywordDict */
904
+ /** @type {import("highlight.js/private").KeywordDict} */
913
905
  const compiledKeywords = Object.create(null);
914
906
 
915
907
  // input can be a string of keywords, an array of keywords, or a object with
@@ -1568,7 +1560,7 @@
1568
1560
  return mode;
1569
1561
  }
1570
1562
 
1571
- var version = "11.6.0";
1563
+ var version = "11.9.0";
1572
1564
 
1573
1565
  class HTMLInjectionError extends Error {
1574
1566
  constructor(reason, html) {
@@ -1583,6 +1575,8 @@
1583
1575
  https://highlightjs.org/
1584
1576
  */
1585
1577
 
1578
+
1579
+
1586
1580
  /**
1587
1581
  @typedef {import('highlight.js').Mode} Mode
1588
1582
  @typedef {import('highlight.js').CompiledMode} CompiledMode
@@ -1792,7 +1786,7 @@
1792
1786
  buf += match[0];
1793
1787
  } else {
1794
1788
  const cssClass = language.classNameAliases[kind] || kind;
1795
- emitter.addKeyword(match[0], cssClass);
1789
+ emitKeyword(match[0], cssClass);
1796
1790
  }
1797
1791
  } else {
1798
1792
  buf += match[0];
@@ -1827,7 +1821,7 @@
1827
1821
  if (top.relevance > 0) {
1828
1822
  relevance += result.relevance;
1829
1823
  }
1830
- emitter.addSublanguage(result._emitter, result.language);
1824
+ emitter.__addSublanguage(result._emitter, result.language);
1831
1825
  }
1832
1826
 
1833
1827
  function processBuffer() {
@@ -1839,6 +1833,18 @@
1839
1833
  modeBuffer = '';
1840
1834
  }
1841
1835
 
1836
+ /**
1837
+ * @param {string} text
1838
+ * @param {string} scope
1839
+ */
1840
+ function emitKeyword(keyword, scope) {
1841
+ if (keyword === "") return;
1842
+
1843
+ emitter.startScope(scope);
1844
+ emitter.addText(keyword);
1845
+ emitter.endScope();
1846
+ }
1847
+
1842
1848
  /**
1843
1849
  * @param {CompiledScope} scope
1844
1850
  * @param {RegExpMatchArray} match
@@ -1851,7 +1857,7 @@
1851
1857
  const klass = language.classNameAliases[scope[i]] || scope[i];
1852
1858
  const text = match[i];
1853
1859
  if (klass) {
1854
- emitter.addKeyword(text, klass);
1860
+ emitKeyword(text, klass);
1855
1861
  } else {
1856
1862
  modeBuffer = text;
1857
1863
  processKeywords();
@@ -1872,7 +1878,7 @@
1872
1878
  if (mode.beginScope) {
1873
1879
  // beginScope just wraps the begin match itself in a scope
1874
1880
  if (mode.beginScope._wrap) {
1875
- emitter.addKeyword(modeBuffer, language.classNameAliases[mode.beginScope._wrap] || mode.beginScope._wrap);
1881
+ emitKeyword(modeBuffer, language.classNameAliases[mode.beginScope._wrap] || mode.beginScope._wrap);
1876
1882
  modeBuffer = "";
1877
1883
  } else if (mode.beginScope._multi) {
1878
1884
  // at this point modeBuffer should just be the match
@@ -1983,7 +1989,7 @@
1983
1989
  const origin = top;
1984
1990
  if (top.endScope && top.endScope._wrap) {
1985
1991
  processBuffer();
1986
- emitter.addKeyword(lexeme, top.endScope._wrap);
1992
+ emitKeyword(lexeme, top.endScope._wrap);
1987
1993
  } else if (top.endScope && top.endScope._multi) {
1988
1994
  processBuffer();
1989
1995
  emitMultiClass(top.endScope, match);
@@ -2126,37 +2132,41 @@
2126
2132
  let resumeScanAtSamePosition = false;
2127
2133
 
2128
2134
  try {
2129
- top.matcher.considerAll();
2130
-
2131
- for (;;) {
2132
- iterations++;
2133
- if (resumeScanAtSamePosition) {
2134
- // only regexes not matched previously will now be
2135
- // considered for a potential match
2136
- resumeScanAtSamePosition = false;
2137
- } else {
2138
- top.matcher.considerAll();
2139
- }
2140
- top.matcher.lastIndex = index;
2135
+ if (!language.__emitTokens) {
2136
+ top.matcher.considerAll();
2137
+
2138
+ for (;;) {
2139
+ iterations++;
2140
+ if (resumeScanAtSamePosition) {
2141
+ // only regexes not matched previously will now be
2142
+ // considered for a potential match
2143
+ resumeScanAtSamePosition = false;
2144
+ } else {
2145
+ top.matcher.considerAll();
2146
+ }
2147
+ top.matcher.lastIndex = index;
2141
2148
 
2142
- const match = top.matcher.exec(codeToHighlight);
2143
- // console.log("match", match[0], match.rule && match.rule.begin)
2149
+ const match = top.matcher.exec(codeToHighlight);
2150
+ // console.log("match", match[0], match.rule && match.rule.begin)
2144
2151
 
2145
- if (!match) break;
2152
+ if (!match) break;
2146
2153
 
2147
- const beforeMatch = codeToHighlight.substring(index, match.index);
2148
- const processedCount = processLexeme(beforeMatch, match);
2149
- index = match.index + processedCount;
2154
+ const beforeMatch = codeToHighlight.substring(index, match.index);
2155
+ const processedCount = processLexeme(beforeMatch, match);
2156
+ index = match.index + processedCount;
2157
+ }
2158
+ processLexeme(codeToHighlight.substring(index));
2159
+ } else {
2160
+ language.__emitTokens(codeToHighlight, emitter);
2150
2161
  }
2151
- processLexeme(codeToHighlight.substring(index));
2152
- emitter.closeAllNodes();
2162
+
2153
2163
  emitter.finalize();
2154
2164
  result = emitter.toHTML();
2155
2165
 
2156
2166
  return {
2157
2167
  language: languageName,
2158
2168
  value: result,
2159
- relevance: relevance,
2169
+ relevance,
2160
2170
  illegal: false,
2161
2171
  _emitter: emitter,
2162
2172
  _top: top
@@ -2170,7 +2180,7 @@
2170
2180
  relevance: 0,
2171
2181
  _illegalBy: {
2172
2182
  message: err.message,
2173
- index: index,
2183
+ index,
2174
2184
  context: codeToHighlight.slice(index - 100, index + 100),
2175
2185
  mode: err.mode,
2176
2186
  resultSoFar: result
@@ -2292,7 +2302,12 @@
2292
2302
  if (shouldNotHighlight(language)) return;
2293
2303
 
2294
2304
  fire("before:highlightElement",
2295
- { el: element, language: language });
2305
+ { el: element, language });
2306
+
2307
+ if (element.dataset.highlighted) {
2308
+ console.log("Element previously highlighted. To highlight again, first unset `dataset.highlighted`.", element);
2309
+ return;
2310
+ }
2296
2311
 
2297
2312
  // we should be all text, no child nodes (unescaped HTML) - this is possibly
2298
2313
  // an HTML injection attack - it's likely too late if this is already in
@@ -2320,6 +2335,7 @@
2320
2335
  const result = language ? highlight(text, { language, ignoreIllegals: true }) : highlightAuto(text);
2321
2336
 
2322
2337
  element.innerHTML = result.value;
2338
+ element.dataset.highlighted = "yes";
2323
2339
  updateClassName(element, language, result.language);
2324
2340
  element.result = {
2325
2341
  language: result.language,
@@ -2496,6 +2512,16 @@
2496
2512
  plugins.push(plugin);
2497
2513
  }
2498
2514
 
2515
+ /**
2516
+ * @param {HLJSPlugin} plugin
2517
+ */
2518
+ function removePlugin(plugin) {
2519
+ const index = plugins.indexOf(plugin);
2520
+ if (index !== -1) {
2521
+ plugins.splice(index, 1);
2522
+ }
2523
+ }
2524
+
2499
2525
  /**
2500
2526
  *
2501
2527
  * @param {PluginEvent} event
@@ -2539,7 +2565,8 @@
2539
2565
  registerAliases,
2540
2566
  autoDetection,
2541
2567
  inherit,
2542
- addPlugin
2568
+ addPlugin,
2569
+ removePlugin
2543
2570
  });
2544
2571
 
2545
2572
  hljs.debugMode = function() { SAFE_MODE = false; };
@@ -2558,7 +2585,7 @@
2558
2585
  // @ts-ignore
2559
2586
  if (typeof MODES[key] === "object") {
2560
2587
  // @ts-ignore
2561
- deepFreezeEs6.exports(MODES[key]);
2588
+ deepFreeze(MODES[key]);
2562
2589
  }
2563
2590
  }
2564
2591
 
@@ -2568,8 +2595,12 @@
2568
2595
  return hljs;
2569
2596
  };
2570
2597
 
2571
- // export an "instance" of the highlighter
2572
- var highlight = HLJS({});
2598
+ // Other names for the variable may break build script
2599
+ const highlight = HLJS({});
2600
+
2601
+ // returns a new instance of the highlighter to be used for extensions
2602
+ // check https://github.com/wooorm/lowlight/issues/47
2603
+ highlight.newInstance = () => HLJS({});
2573
2604
 
2574
2605
  var core = highlight;
2575
2606
  highlight.HighlightJS = highlight;