@tiptap/extension-code-block-lowlight 2.5.0-beta.4 → 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.cjs CHANGED
@@ -11,37 +11,41 @@ function getDefaultExportFromCjs (x) {
11
11
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
12
12
  }
13
13
 
14
- var deepFreezeEs6 = {exports: {}};
14
+ /* eslint-disable no-multi-assign */
15
15
 
16
16
  function deepFreeze(obj) {
17
- if (obj instanceof Map) {
18
- obj.clear = obj.delete = obj.set = function () {
19
- throw new Error('map is read-only');
17
+ if (obj instanceof Map) {
18
+ obj.clear =
19
+ obj.delete =
20
+ obj.set =
21
+ function () {
22
+ throw new Error('map is read-only');
20
23
  };
21
- } else if (obj instanceof Set) {
22
- obj.add = obj.clear = obj.delete = function () {
23
- throw new Error('set is read-only');
24
+ } else if (obj instanceof Set) {
25
+ obj.add =
26
+ obj.clear =
27
+ obj.delete =
28
+ function () {
29
+ throw new Error('set is read-only');
24
30
  };
25
- }
31
+ }
26
32
 
27
- // Freeze self
28
- Object.freeze(obj);
33
+ // Freeze self
34
+ Object.freeze(obj);
29
35
 
30
- Object.getOwnPropertyNames(obj).forEach(function (name) {
31
- var prop = obj[name];
36
+ Object.getOwnPropertyNames(obj).forEach((name) => {
37
+ const prop = obj[name];
38
+ const type = typeof prop;
32
39
 
33
- // Freeze prop if it is an object
34
- if (typeof prop == 'object' && !Object.isFrozen(prop)) {
35
- deepFreeze(prop);
36
- }
37
- });
40
+ // Freeze prop if it is an object or function and also not already frozen
41
+ if ((type === 'object' || type === 'function') && !Object.isFrozen(prop)) {
42
+ deepFreeze(prop);
43
+ }
44
+ });
38
45
 
39
- return obj;
46
+ return obj;
40
47
  }
41
48
 
42
- deepFreezeEs6.exports = deepFreeze;
43
- deepFreezeEs6.exports.default = deepFreeze;
44
-
45
49
  /** @typedef {import('highlight.js').CallbackResponse} CallbackResponse */
46
50
  /** @typedef {import('highlight.js').CompiledMode} CompiledMode */
47
51
  /** @implements CallbackResponse */
@@ -120,7 +124,7 @@ const SPAN_CLOSE = '</span>';
120
124
  const emitsWrappingTags = (node) => {
121
125
  // rarely we can have a sublanguage where language is undefined
122
126
  // TODO: track down why
123
- return !!node.scope || (node.sublanguage && node.language);
127
+ return !!node.scope;
124
128
  };
125
129
 
126
130
  /**
@@ -129,6 +133,11 @@ const emitsWrappingTags = (node) => {
129
133
  * @param {{prefix:string}} options
130
134
  */
131
135
  const scopeToCSSClass = (name, { prefix }) => {
136
+ // sub-language
137
+ if (name.startsWith("language:")) {
138
+ return name.replace("language:", "language-");
139
+ }
140
+ // tiered scope: comment.line
132
141
  if (name.includes(".")) {
133
142
  const pieces = name.split(".");
134
143
  return [
@@ -136,6 +145,7 @@ const scopeToCSSClass = (name, { prefix }) => {
136
145
  ...(pieces.map((x, i) => `${x}${"_".repeat(i + 1)}`))
137
146
  ].join(" ");
138
147
  }
148
+ // simple scope
139
149
  return `${prefix}${name}`;
140
150
  };
141
151
 
@@ -168,12 +178,8 @@ class HTMLRenderer {
168
178
  openNode(node) {
169
179
  if (!emitsWrappingTags(node)) return;
170
180
 
171
- let className = "";
172
- if (node.sublanguage) {
173
- className = `language-${node.language}`;
174
- } else {
175
- className = scopeToCSSClass(node.scope, { prefix: this.classPrefix });
176
- }
181
+ const className = scopeToCSSClass(node.scope,
182
+ { prefix: this.classPrefix });
177
183
  this.span(className);
178
184
  }
179
185
 
@@ -205,8 +211,8 @@ class HTMLRenderer {
205
211
  }
206
212
  }
207
213
 
208
- /** @typedef {{scope?: string, language?: string, sublanguage?: boolean, children: Node[]} | string} Node */
209
- /** @typedef {{scope?: string, language?: string, sublanguage?: boolean, children: Node[]} } DataNode */
214
+ /** @typedef {{scope?: string, language?: string, children: Node[]} | string} Node */
215
+ /** @typedef {{scope?: string, language?: string, children: Node[]} } DataNode */
210
216
  /** @typedef {import('highlight.js').Emitter} Emitter */
211
217
  /** */
212
218
 
@@ -311,13 +317,11 @@ class TokenTree {
311
317
 
312
318
  Minimal interface:
313
319
 
314
- - addKeyword(text, scope)
315
320
  - addText(text)
316
- - addSublanguage(emitter, subLanguageName)
321
+ - __addSublanguage(emitter, subLanguageName)
322
+ - startScope(scope)
323
+ - endScope()
317
324
  - finalize()
318
- - openNode(scope)
319
- - closeNode()
320
- - closeAllNodes()
321
325
  - toHTML()
322
326
 
323
327
  */
@@ -336,34 +340,31 @@ class TokenTreeEmitter extends TokenTree {
336
340
 
337
341
  /**
338
342
  * @param {string} text
339
- * @param {string} scope
340
343
  */
341
- addKeyword(text, scope) {
344
+ addText(text) {
342
345
  if (text === "") { return; }
343
346
 
344
- this.openNode(scope);
345
- this.addText(text);
346
- this.closeNode();
347
+ this.add(text);
347
348
  }
348
349
 
349
- /**
350
- * @param {string} text
351
- */
352
- addText(text) {
353
- if (text === "") { return; }
350
+ /** @param {string} scope */
351
+ startScope(scope) {
352
+ this.openNode(scope);
353
+ }
354
354
 
355
- this.add(text);
355
+ endScope() {
356
+ this.closeNode();
356
357
  }
357
358
 
358
359
  /**
359
360
  * @param {Emitter & {root: DataNode}} emitter
360
361
  * @param {string} name
361
362
  */
362
- addSublanguage(emitter, name) {
363
+ __addSublanguage(emitter, name) {
363
364
  /** @type DataNode */
364
365
  const node = emitter.root;
365
- node.sublanguage = true;
366
- node.language = name;
366
+ if (name) node.scope = `language:${name}`;
367
+
367
368
  this.add(node);
368
369
  }
369
370
 
@@ -373,6 +374,7 @@ class TokenTreeEmitter extends TokenTree {
373
374
  }
374
375
 
375
376
  finalize() {
377
+ this.closeAllNodes();
376
378
  return true;
377
379
  }
378
380
  }
@@ -677,28 +679,18 @@ const BINARY_NUMBER_MODE = {
677
679
  relevance: 0
678
680
  };
679
681
  const REGEXP_MODE = {
680
- // this outer rule makes sure we actually have a WHOLE regex and not simply
681
- // an expression such as:
682
- //
683
- // 3 / something
684
- //
685
- // (which will then blow up when regex's `illegal` sees the newline)
686
- begin: /(?=\/[^/\n]*\/)/,
687
- contains: [{
688
- scope: 'regexp',
689
- begin: /\//,
690
- end: /\/[gimuy]*/,
691
- illegal: /\n/,
692
- contains: [
693
- BACKSLASH_ESCAPE,
694
- {
695
- begin: /\[/,
696
- end: /\]/,
697
- relevance: 0,
698
- contains: [BACKSLASH_ESCAPE]
699
- }
700
- ]
701
- }]
682
+ scope: "regexp",
683
+ begin: /\/(?=[^/\n]*\/)/,
684
+ end: /\/[gimuy]*/,
685
+ contains: [
686
+ BACKSLASH_ESCAPE,
687
+ {
688
+ begin: /\[/,
689
+ end: /\]/,
690
+ relevance: 0,
691
+ contains: [BACKSLASH_ESCAPE]
692
+ }
693
+ ]
702
694
  };
703
695
  const TITLE_MODE = {
704
696
  scope: 'title',
@@ -734,31 +726,31 @@ const END_SAME_AS_BEGIN = function(mode) {
734
726
  };
735
727
 
736
728
  var MODES = /*#__PURE__*/Object.freeze({
737
- __proto__: null,
738
- MATCH_NOTHING_RE: MATCH_NOTHING_RE,
739
- IDENT_RE: IDENT_RE,
740
- UNDERSCORE_IDENT_RE: UNDERSCORE_IDENT_RE,
741
- NUMBER_RE: NUMBER_RE,
742
- C_NUMBER_RE: C_NUMBER_RE,
743
- BINARY_NUMBER_RE: BINARY_NUMBER_RE,
744
- RE_STARTERS_RE: RE_STARTERS_RE,
745
- SHEBANG: SHEBANG,
746
- BACKSLASH_ESCAPE: BACKSLASH_ESCAPE,
747
- APOS_STRING_MODE: APOS_STRING_MODE,
748
- QUOTE_STRING_MODE: QUOTE_STRING_MODE,
749
- PHRASAL_WORDS_MODE: PHRASAL_WORDS_MODE,
750
- COMMENT: COMMENT,
751
- C_LINE_COMMENT_MODE: C_LINE_COMMENT_MODE,
752
- C_BLOCK_COMMENT_MODE: C_BLOCK_COMMENT_MODE,
753
- HASH_COMMENT_MODE: HASH_COMMENT_MODE,
754
- NUMBER_MODE: NUMBER_MODE,
755
- C_NUMBER_MODE: C_NUMBER_MODE,
756
- BINARY_NUMBER_MODE: BINARY_NUMBER_MODE,
757
- REGEXP_MODE: REGEXP_MODE,
758
- TITLE_MODE: TITLE_MODE,
759
- UNDERSCORE_TITLE_MODE: UNDERSCORE_TITLE_MODE,
760
- METHOD_GUARD: METHOD_GUARD,
761
- END_SAME_AS_BEGIN: END_SAME_AS_BEGIN
729
+ __proto__: null,
730
+ APOS_STRING_MODE: APOS_STRING_MODE,
731
+ BACKSLASH_ESCAPE: BACKSLASH_ESCAPE,
732
+ BINARY_NUMBER_MODE: BINARY_NUMBER_MODE,
733
+ BINARY_NUMBER_RE: BINARY_NUMBER_RE,
734
+ COMMENT: COMMENT,
735
+ C_BLOCK_COMMENT_MODE: C_BLOCK_COMMENT_MODE,
736
+ C_LINE_COMMENT_MODE: C_LINE_COMMENT_MODE,
737
+ C_NUMBER_MODE: C_NUMBER_MODE,
738
+ C_NUMBER_RE: C_NUMBER_RE,
739
+ END_SAME_AS_BEGIN: END_SAME_AS_BEGIN,
740
+ HASH_COMMENT_MODE: HASH_COMMENT_MODE,
741
+ IDENT_RE: IDENT_RE,
742
+ MATCH_NOTHING_RE: MATCH_NOTHING_RE,
743
+ METHOD_GUARD: METHOD_GUARD,
744
+ NUMBER_MODE: NUMBER_MODE,
745
+ NUMBER_RE: NUMBER_RE,
746
+ PHRASAL_WORDS_MODE: PHRASAL_WORDS_MODE,
747
+ QUOTE_STRING_MODE: QUOTE_STRING_MODE,
748
+ REGEXP_MODE: REGEXP_MODE,
749
+ RE_STARTERS_RE: RE_STARTERS_RE,
750
+ SHEBANG: SHEBANG,
751
+ TITLE_MODE: TITLE_MODE,
752
+ UNDERSCORE_IDENT_RE: UNDERSCORE_IDENT_RE,
753
+ UNDERSCORE_TITLE_MODE: UNDERSCORE_TITLE_MODE
762
754
  });
763
755
 
764
756
  /**
@@ -912,7 +904,7 @@ const DEFAULT_KEYWORD_SCOPE = "keyword";
912
904
  * @param {boolean} caseInsensitive
913
905
  */
914
906
  function compileKeywords(rawKeywords, caseInsensitive, scopeName = DEFAULT_KEYWORD_SCOPE) {
915
- /** @type KeywordDict */
907
+ /** @type {import("highlight.js/private").KeywordDict} */
916
908
  const compiledKeywords = Object.create(null);
917
909
 
918
910
  // input can be a string of keywords, an array of keywords, or a object with
@@ -1571,7 +1563,7 @@ function expandOrCloneMode(mode) {
1571
1563
  return mode;
1572
1564
  }
1573
1565
 
1574
- var version = "11.6.0";
1566
+ var version = "11.9.0";
1575
1567
 
1576
1568
  class HTMLInjectionError extends Error {
1577
1569
  constructor(reason, html) {
@@ -1586,6 +1578,8 @@ Syntax highlighting with language autodetection.
1586
1578
  https://highlightjs.org/
1587
1579
  */
1588
1580
 
1581
+
1582
+
1589
1583
  /**
1590
1584
  @typedef {import('highlight.js').Mode} Mode
1591
1585
  @typedef {import('highlight.js').CompiledMode} CompiledMode
@@ -1795,7 +1789,7 @@ const HLJS = function(hljs) {
1795
1789
  buf += match[0];
1796
1790
  } else {
1797
1791
  const cssClass = language.classNameAliases[kind] || kind;
1798
- emitter.addKeyword(match[0], cssClass);
1792
+ emitKeyword(match[0], cssClass);
1799
1793
  }
1800
1794
  } else {
1801
1795
  buf += match[0];
@@ -1830,7 +1824,7 @@ const HLJS = function(hljs) {
1830
1824
  if (top.relevance > 0) {
1831
1825
  relevance += result.relevance;
1832
1826
  }
1833
- emitter.addSublanguage(result._emitter, result.language);
1827
+ emitter.__addSublanguage(result._emitter, result.language);
1834
1828
  }
1835
1829
 
1836
1830
  function processBuffer() {
@@ -1842,6 +1836,18 @@ const HLJS = function(hljs) {
1842
1836
  modeBuffer = '';
1843
1837
  }
1844
1838
 
1839
+ /**
1840
+ * @param {string} text
1841
+ * @param {string} scope
1842
+ */
1843
+ function emitKeyword(keyword, scope) {
1844
+ if (keyword === "") return;
1845
+
1846
+ emitter.startScope(scope);
1847
+ emitter.addText(keyword);
1848
+ emitter.endScope();
1849
+ }
1850
+
1845
1851
  /**
1846
1852
  * @param {CompiledScope} scope
1847
1853
  * @param {RegExpMatchArray} match
@@ -1854,7 +1860,7 @@ const HLJS = function(hljs) {
1854
1860
  const klass = language.classNameAliases[scope[i]] || scope[i];
1855
1861
  const text = match[i];
1856
1862
  if (klass) {
1857
- emitter.addKeyword(text, klass);
1863
+ emitKeyword(text, klass);
1858
1864
  } else {
1859
1865
  modeBuffer = text;
1860
1866
  processKeywords();
@@ -1875,7 +1881,7 @@ const HLJS = function(hljs) {
1875
1881
  if (mode.beginScope) {
1876
1882
  // beginScope just wraps the begin match itself in a scope
1877
1883
  if (mode.beginScope._wrap) {
1878
- emitter.addKeyword(modeBuffer, language.classNameAliases[mode.beginScope._wrap] || mode.beginScope._wrap);
1884
+ emitKeyword(modeBuffer, language.classNameAliases[mode.beginScope._wrap] || mode.beginScope._wrap);
1879
1885
  modeBuffer = "";
1880
1886
  } else if (mode.beginScope._multi) {
1881
1887
  // at this point modeBuffer should just be the match
@@ -1986,7 +1992,7 @@ const HLJS = function(hljs) {
1986
1992
  const origin = top;
1987
1993
  if (top.endScope && top.endScope._wrap) {
1988
1994
  processBuffer();
1989
- emitter.addKeyword(lexeme, top.endScope._wrap);
1995
+ emitKeyword(lexeme, top.endScope._wrap);
1990
1996
  } else if (top.endScope && top.endScope._multi) {
1991
1997
  processBuffer();
1992
1998
  emitMultiClass(top.endScope, match);
@@ -2129,37 +2135,41 @@ const HLJS = function(hljs) {
2129
2135
  let resumeScanAtSamePosition = false;
2130
2136
 
2131
2137
  try {
2132
- top.matcher.considerAll();
2133
-
2134
- for (;;) {
2135
- iterations++;
2136
- if (resumeScanAtSamePosition) {
2137
- // only regexes not matched previously will now be
2138
- // considered for a potential match
2139
- resumeScanAtSamePosition = false;
2140
- } else {
2141
- top.matcher.considerAll();
2142
- }
2143
- top.matcher.lastIndex = index;
2138
+ if (!language.__emitTokens) {
2139
+ top.matcher.considerAll();
2140
+
2141
+ for (;;) {
2142
+ iterations++;
2143
+ if (resumeScanAtSamePosition) {
2144
+ // only regexes not matched previously will now be
2145
+ // considered for a potential match
2146
+ resumeScanAtSamePosition = false;
2147
+ } else {
2148
+ top.matcher.considerAll();
2149
+ }
2150
+ top.matcher.lastIndex = index;
2144
2151
 
2145
- const match = top.matcher.exec(codeToHighlight);
2146
- // console.log("match", match[0], match.rule && match.rule.begin)
2152
+ const match = top.matcher.exec(codeToHighlight);
2153
+ // console.log("match", match[0], match.rule && match.rule.begin)
2147
2154
 
2148
- if (!match) break;
2155
+ if (!match) break;
2149
2156
 
2150
- const beforeMatch = codeToHighlight.substring(index, match.index);
2151
- const processedCount = processLexeme(beforeMatch, match);
2152
- index = match.index + processedCount;
2157
+ const beforeMatch = codeToHighlight.substring(index, match.index);
2158
+ const processedCount = processLexeme(beforeMatch, match);
2159
+ index = match.index + processedCount;
2160
+ }
2161
+ processLexeme(codeToHighlight.substring(index));
2162
+ } else {
2163
+ language.__emitTokens(codeToHighlight, emitter);
2153
2164
  }
2154
- processLexeme(codeToHighlight.substring(index));
2155
- emitter.closeAllNodes();
2165
+
2156
2166
  emitter.finalize();
2157
2167
  result = emitter.toHTML();
2158
2168
 
2159
2169
  return {
2160
2170
  language: languageName,
2161
2171
  value: result,
2162
- relevance: relevance,
2172
+ relevance,
2163
2173
  illegal: false,
2164
2174
  _emitter: emitter,
2165
2175
  _top: top
@@ -2173,7 +2183,7 @@ const HLJS = function(hljs) {
2173
2183
  relevance: 0,
2174
2184
  _illegalBy: {
2175
2185
  message: err.message,
2176
- index: index,
2186
+ index,
2177
2187
  context: codeToHighlight.slice(index - 100, index + 100),
2178
2188
  mode: err.mode,
2179
2189
  resultSoFar: result
@@ -2295,7 +2305,12 @@ const HLJS = function(hljs) {
2295
2305
  if (shouldNotHighlight(language)) return;
2296
2306
 
2297
2307
  fire("before:highlightElement",
2298
- { el: element, language: language });
2308
+ { el: element, language });
2309
+
2310
+ if (element.dataset.highlighted) {
2311
+ console.log("Element previously highlighted. To highlight again, first unset `dataset.highlighted`.", element);
2312
+ return;
2313
+ }
2299
2314
 
2300
2315
  // we should be all text, no child nodes (unescaped HTML) - this is possibly
2301
2316
  // an HTML injection attack - it's likely too late if this is already in
@@ -2323,6 +2338,7 @@ const HLJS = function(hljs) {
2323
2338
  const result = language ? highlight(text, { language, ignoreIllegals: true }) : highlightAuto(text);
2324
2339
 
2325
2340
  element.innerHTML = result.value;
2341
+ element.dataset.highlighted = "yes";
2326
2342
  updateClassName(element, language, result.language);
2327
2343
  element.result = {
2328
2344
  language: result.language,
@@ -2499,6 +2515,16 @@ const HLJS = function(hljs) {
2499
2515
  plugins.push(plugin);
2500
2516
  }
2501
2517
 
2518
+ /**
2519
+ * @param {HLJSPlugin} plugin
2520
+ */
2521
+ function removePlugin(plugin) {
2522
+ const index = plugins.indexOf(plugin);
2523
+ if (index !== -1) {
2524
+ plugins.splice(index, 1);
2525
+ }
2526
+ }
2527
+
2502
2528
  /**
2503
2529
  *
2504
2530
  * @param {PluginEvent} event
@@ -2542,7 +2568,8 @@ const HLJS = function(hljs) {
2542
2568
  registerAliases,
2543
2569
  autoDetection,
2544
2570
  inherit,
2545
- addPlugin
2571
+ addPlugin,
2572
+ removePlugin
2546
2573
  });
2547
2574
 
2548
2575
  hljs.debugMode = function() { SAFE_MODE = false; };
@@ -2561,7 +2588,7 @@ const HLJS = function(hljs) {
2561
2588
  // @ts-ignore
2562
2589
  if (typeof MODES[key] === "object") {
2563
2590
  // @ts-ignore
2564
- deepFreezeEs6.exports(MODES[key]);
2591
+ deepFreeze(MODES[key]);
2565
2592
  }
2566
2593
  }
2567
2594
 
@@ -2571,8 +2598,12 @@ const HLJS = function(hljs) {
2571
2598
  return hljs;
2572
2599
  };
2573
2600
 
2574
- // export an "instance" of the highlighter
2575
- var highlight = HLJS({});
2601
+ // Other names for the variable may break build script
2602
+ const highlight = HLJS({});
2603
+
2604
+ // returns a new instance of the highlighter to be used for extensions
2605
+ // check https://github.com/wooorm/lowlight/issues/47
2606
+ highlight.newInstance = () => HLJS({});
2576
2607
 
2577
2608
  var core = highlight;
2578
2609
  highlight.HighlightJS = highlight;