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