@pierre/diffs 1.1.12 → 1.1.13

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.
@@ -62,220 +62,10 @@ function attachResolvedThemes(themes, highlighter$1) {
62
62
  }
63
63
  }
64
64
 
65
- //#endregion
66
- //#region src/utils/cleanLastNewline.ts
67
- function cleanLastNewline(contents) {
68
- return contents.replace(/\n$|\r\n$/, "");
69
- }
70
-
71
- //#endregion
72
- //#region src/utils/hast_utils.ts
73
- function createTextNodeElement(value) {
74
- return {
75
- type: "text",
76
- value
77
- };
78
- }
79
- function createHastElement({ tagName, children = [], properties = {} }) {
80
- return {
81
- type: "element",
82
- tagName,
83
- properties,
84
- children
85
- };
86
- }
87
- function findCodeElement(nodes) {
88
- let firstChild = nodes.children[0];
89
- while (firstChild != null) {
90
- if (firstChild.type === "element" && firstChild.tagName === "code") return firstChild;
91
- if ("children" in firstChild) firstChild = firstChild.children[0];
92
- else firstChild = null;
93
- }
94
- }
95
-
96
- //#endregion
97
- //#region src/utils/processLine.ts
98
- function processLine(node, line, state) {
99
- const lineInfo = typeof state.lineInfo === "function" ? state.lineInfo(line) : state.lineInfo[line - 1];
100
- if (lineInfo == null) {
101
- const errorMessage = `processLine: line ${line}, contains no state.lineInfo`;
102
- console.error(errorMessage, {
103
- node,
104
- line,
105
- state
106
- });
107
- throw new Error(errorMessage);
108
- }
109
- node.tagName = "div";
110
- node.properties["data-line"] = lineInfo.lineNumber;
111
- node.properties["data-alt-line"] = lineInfo.altLineNumber;
112
- node.properties["data-line-type"] = lineInfo.type;
113
- node.properties["data-line-index"] = lineInfo.lineIndex;
114
- if (node.children.length === 0) node.children.push(createTextNodeElement("\n"));
115
- return node;
116
- }
117
-
118
- //#endregion
119
- //#region src/utils/wrapTokenFragments.ts
120
- const NO_TOKEN = Symbol("no-token");
121
- const MULTIPLE_TOKENS = Symbol("multiple-tokens");
122
- function wrapTokenFragments(container) {
123
- const ownTokenChar = getTokenChar(container);
124
- if (ownTokenChar != null) return ownTokenChar;
125
- let containerTokenState = NO_TOKEN;
126
- const wrappedChildren = [];
127
- let currentTokenChildren = [];
128
- let currentTokenChar;
129
- const flushTokenChildren = () => {
130
- if (currentTokenChildren.length === 0 || currentTokenChar == null) {
131
- currentTokenChildren = [];
132
- currentTokenChar = void 0;
133
- return;
134
- }
135
- if (currentTokenChildren.length === 1) {
136
- const child = currentTokenChildren[0];
137
- if (child?.type === "element") {
138
- setTokenChar(child, currentTokenChar);
139
- for (const grandChild of child.children) stripTokenChar(grandChild);
140
- } else stripTokenChar(child);
141
- wrappedChildren.push(child);
142
- currentTokenChildren = [];
143
- currentTokenChar = void 0;
144
- return;
145
- }
146
- for (const child of currentTokenChildren) stripTokenChar(child);
147
- wrappedChildren.push(createHastElement({
148
- tagName: "span",
149
- properties: { "data-char": currentTokenChar },
150
- children: currentTokenChildren
151
- }));
152
- currentTokenChildren = [];
153
- currentTokenChar = void 0;
154
- };
155
- const mergeContainerTokenState = (childTokenState) => {
156
- if (childTokenState === NO_TOKEN) return;
157
- if (childTokenState === MULTIPLE_TOKENS) {
158
- containerTokenState = MULTIPLE_TOKENS;
159
- return;
160
- }
161
- if (containerTokenState === NO_TOKEN) {
162
- containerTokenState = childTokenState;
163
- return;
164
- }
165
- if (containerTokenState !== childTokenState) containerTokenState = MULTIPLE_TOKENS;
166
- };
167
- for (const child of container.children) {
168
- const childTokenState = child.type === "element" ? wrapTokenFragments(child) : NO_TOKEN;
169
- mergeContainerTokenState(childTokenState);
170
- if (typeof childTokenState !== "number") {
171
- flushTokenChildren();
172
- wrappedChildren.push(child);
173
- continue;
174
- }
175
- if (currentTokenChar != null && currentTokenChar !== childTokenState) flushTokenChildren();
176
- currentTokenChar ??= childTokenState;
177
- currentTokenChildren.push(child);
178
- }
179
- flushTokenChildren();
180
- container.children = wrappedChildren;
181
- return containerTokenState;
182
- }
183
- function getTokenChar(node) {
184
- const value = node.properties["data-char"];
185
- if (typeof value === "number") return value;
186
- }
187
- function stripTokenChar(node) {
188
- if (node.type !== "element") return;
189
- node.properties["data-char"] = void 0;
190
- for (const child of node.children) stripTokenChar(child);
191
- }
192
- function setTokenChar(node, char) {
193
- node.properties["data-char"] = char;
194
- }
195
-
196
- //#endregion
197
- //#region src/utils/createTransformerWithState.ts
198
- function createTransformerWithState(useTokenTransformer = false, useCSSClasses = false) {
199
- const state = { lineInfo: [] };
200
- const transformers = [{
201
- line(node) {
202
- delete node.properties.class;
203
- return node;
204
- },
205
- pre(pre) {
206
- const code = findCodeElement(pre);
207
- const children = [];
208
- if (code != null) {
209
- let index = 1;
210
- for (const node of code.children) {
211
- if (node.type !== "element") continue;
212
- if (useTokenTransformer) wrapTokenFragments(node);
213
- children.push(processLine(node, index, state));
214
- index++;
215
- }
216
- code.children = children;
217
- }
218
- return pre;
219
- },
220
- ...useTokenTransformer ? {
221
- tokens(lines) {
222
- for (const line of lines) {
223
- let col = 0;
224
- for (const token of line) {
225
- const tokenWithOriginalRange = token;
226
- tokenWithOriginalRange.__lineChar ??= col;
227
- col += token.content.length;
228
- }
229
- }
230
- },
231
- preprocess(_code, options) {
232
- options.mergeWhitespaces = "never";
233
- },
234
- span(hast, _line, _char, _lineElement, token) {
235
- if (token?.offset != null && token.content != null) {
236
- const tokenChar = token.__lineChar;
237
- if (tokenChar != null) hast.properties["data-char"] = tokenChar;
238
- return hast;
239
- }
240
- return hast;
241
- }
242
- } : null
243
- }];
244
- if (useCSSClasses) transformers.push(tokenStyleNormalizer, toClass);
245
- return {
246
- state,
247
- transformers,
248
- toClass
249
- };
250
- }
251
- const toClass = transformerStyleToClass({ classPrefix: "hl-" });
252
- const tokenStyleNormalizer = {
253
- name: "token-style-normalizer",
254
- tokens(lines) {
255
- for (const line of lines) for (const token of line) {
256
- if (token.htmlStyle != null) continue;
257
- const style = {};
258
- if (token.color != null) style.color = token.color;
259
- if (token.bgColor != null) style["background-color"] = token.bgColor;
260
- if (token.fontStyle != null && token.fontStyle !== 0) {
261
- if ((token.fontStyle & 1) !== 0) style["font-style"] = "italic";
262
- if ((token.fontStyle & 2) !== 0) style["font-weight"] = "bold";
263
- if ((token.fontStyle & 4) !== 0) style["text-decoration"] = "underline";
264
- }
265
- if (Object.keys(style).length > 0) token.htmlStyle = style;
266
- }
267
- }
268
- };
269
-
270
- //#endregion
271
- //#region src/utils/formatCSSVariablePrefix.ts
272
- function formatCSSVariablePrefix(type) {
273
- return `--${type === "token" ? "diffs-token" : "diffs"}-`;
274
- }
275
-
276
65
  //#endregion
277
66
  //#region src/utils/getFiletypeFromFileName.ts
278
67
  const CUSTOM_EXTENSION_TO_FILE_FORMAT = /* @__PURE__ */ new Map();
68
+ let customExtensionsVersion = 0;
279
69
  const EXTENSION_TO_FILE_FORMAT = {
280
70
  "1c": "1c",
281
71
  abap: "abap",
@@ -617,6 +407,227 @@ function getFiletypeFromFileName(fileName) {
617
407
  if (CUSTOM_EXTENSION_TO_FILE_FORMAT.has(simpleMatch)) return CUSTOM_EXTENSION_TO_FILE_FORMAT.get(simpleMatch) ?? "text";
618
408
  return EXTENSION_TO_FILE_FORMAT[simpleMatch] ?? "text";
619
409
  }
410
+ function replaceCustomExtensions(version, map) {
411
+ if (version <= customExtensionsVersion) return false;
412
+ CUSTOM_EXTENSION_TO_FILE_FORMAT.clear();
413
+ for (const key in map) {
414
+ const lang = map[key];
415
+ if (lang != null) CUSTOM_EXTENSION_TO_FILE_FORMAT.set(key, lang);
416
+ }
417
+ customExtensionsVersion = version;
418
+ return true;
419
+ }
420
+
421
+ //#endregion
422
+ //#region src/utils/cleanLastNewline.ts
423
+ function cleanLastNewline(contents) {
424
+ return contents.replace(/\n$|\r\n$/, "");
425
+ }
426
+
427
+ //#endregion
428
+ //#region src/utils/hast_utils.ts
429
+ function createTextNodeElement(value) {
430
+ return {
431
+ type: "text",
432
+ value
433
+ };
434
+ }
435
+ function createHastElement({ tagName, children = [], properties = {} }) {
436
+ return {
437
+ type: "element",
438
+ tagName,
439
+ properties,
440
+ children
441
+ };
442
+ }
443
+ function findCodeElement(nodes) {
444
+ let firstChild = nodes.children[0];
445
+ while (firstChild != null) {
446
+ if (firstChild.type === "element" && firstChild.tagName === "code") return firstChild;
447
+ if ("children" in firstChild) firstChild = firstChild.children[0];
448
+ else firstChild = null;
449
+ }
450
+ }
451
+
452
+ //#endregion
453
+ //#region src/utils/processLine.ts
454
+ function processLine(node, line, state) {
455
+ const lineInfo = typeof state.lineInfo === "function" ? state.lineInfo(line) : state.lineInfo[line - 1];
456
+ if (lineInfo == null) {
457
+ const errorMessage = `processLine: line ${line}, contains no state.lineInfo`;
458
+ console.error(errorMessage, {
459
+ node,
460
+ line,
461
+ state
462
+ });
463
+ throw new Error(errorMessage);
464
+ }
465
+ node.tagName = "div";
466
+ node.properties["data-line"] = lineInfo.lineNumber;
467
+ node.properties["data-alt-line"] = lineInfo.altLineNumber;
468
+ node.properties["data-line-type"] = lineInfo.type;
469
+ node.properties["data-line-index"] = lineInfo.lineIndex;
470
+ if (node.children.length === 0) node.children.push(createTextNodeElement("\n"));
471
+ return node;
472
+ }
473
+
474
+ //#endregion
475
+ //#region src/utils/wrapTokenFragments.ts
476
+ const NO_TOKEN = Symbol("no-token");
477
+ const MULTIPLE_TOKENS = Symbol("multiple-tokens");
478
+ function wrapTokenFragments(container) {
479
+ const ownTokenChar = getTokenChar(container);
480
+ if (ownTokenChar != null) return ownTokenChar;
481
+ let containerTokenState = NO_TOKEN;
482
+ const wrappedChildren = [];
483
+ let currentTokenChildren = [];
484
+ let currentTokenChar;
485
+ const flushTokenChildren = () => {
486
+ if (currentTokenChildren.length === 0 || currentTokenChar == null) {
487
+ currentTokenChildren = [];
488
+ currentTokenChar = void 0;
489
+ return;
490
+ }
491
+ if (currentTokenChildren.length === 1) {
492
+ const child = currentTokenChildren[0];
493
+ if (child?.type === "element") {
494
+ setTokenChar(child, currentTokenChar);
495
+ for (const grandChild of child.children) stripTokenChar(grandChild);
496
+ } else stripTokenChar(child);
497
+ wrappedChildren.push(child);
498
+ currentTokenChildren = [];
499
+ currentTokenChar = void 0;
500
+ return;
501
+ }
502
+ for (const child of currentTokenChildren) stripTokenChar(child);
503
+ wrappedChildren.push(createHastElement({
504
+ tagName: "span",
505
+ properties: { "data-char": currentTokenChar },
506
+ children: currentTokenChildren
507
+ }));
508
+ currentTokenChildren = [];
509
+ currentTokenChar = void 0;
510
+ };
511
+ const mergeContainerTokenState = (childTokenState) => {
512
+ if (childTokenState === NO_TOKEN) return;
513
+ if (childTokenState === MULTIPLE_TOKENS) {
514
+ containerTokenState = MULTIPLE_TOKENS;
515
+ return;
516
+ }
517
+ if (containerTokenState === NO_TOKEN) {
518
+ containerTokenState = childTokenState;
519
+ return;
520
+ }
521
+ if (containerTokenState !== childTokenState) containerTokenState = MULTIPLE_TOKENS;
522
+ };
523
+ for (const child of container.children) {
524
+ const childTokenState = child.type === "element" ? wrapTokenFragments(child) : NO_TOKEN;
525
+ mergeContainerTokenState(childTokenState);
526
+ if (typeof childTokenState !== "number") {
527
+ flushTokenChildren();
528
+ wrappedChildren.push(child);
529
+ continue;
530
+ }
531
+ if (currentTokenChar != null && currentTokenChar !== childTokenState) flushTokenChildren();
532
+ currentTokenChar ??= childTokenState;
533
+ currentTokenChildren.push(child);
534
+ }
535
+ flushTokenChildren();
536
+ container.children = wrappedChildren;
537
+ return containerTokenState;
538
+ }
539
+ function getTokenChar(node) {
540
+ const value = node.properties["data-char"];
541
+ if (typeof value === "number") return value;
542
+ }
543
+ function stripTokenChar(node) {
544
+ if (node.type !== "element") return;
545
+ node.properties["data-char"] = void 0;
546
+ for (const child of node.children) stripTokenChar(child);
547
+ }
548
+ function setTokenChar(node, char) {
549
+ node.properties["data-char"] = char;
550
+ }
551
+
552
+ //#endregion
553
+ //#region src/utils/createTransformerWithState.ts
554
+ function createTransformerWithState(useTokenTransformer = false, useCSSClasses = false) {
555
+ const state = { lineInfo: [] };
556
+ const transformers = [{
557
+ line(node) {
558
+ delete node.properties.class;
559
+ return node;
560
+ },
561
+ pre(pre) {
562
+ const code = findCodeElement(pre);
563
+ const children = [];
564
+ if (code != null) {
565
+ let index = 1;
566
+ for (const node of code.children) {
567
+ if (node.type !== "element") continue;
568
+ if (useTokenTransformer) wrapTokenFragments(node);
569
+ children.push(processLine(node, index, state));
570
+ index++;
571
+ }
572
+ code.children = children;
573
+ }
574
+ return pre;
575
+ },
576
+ ...useTokenTransformer ? {
577
+ tokens(lines) {
578
+ for (const line of lines) {
579
+ let col = 0;
580
+ for (const token of line) {
581
+ const tokenWithOriginalRange = token;
582
+ tokenWithOriginalRange.__lineChar ??= col;
583
+ col += token.content.length;
584
+ }
585
+ }
586
+ },
587
+ preprocess(_code, options) {
588
+ options.mergeWhitespaces = "never";
589
+ },
590
+ span(hast, _line, _char, _lineElement, token) {
591
+ if (token?.offset != null && token.content != null) {
592
+ const tokenChar = token.__lineChar;
593
+ if (tokenChar != null) hast.properties["data-char"] = tokenChar;
594
+ return hast;
595
+ }
596
+ return hast;
597
+ }
598
+ } : null
599
+ }];
600
+ if (useCSSClasses) transformers.push(tokenStyleNormalizer, toClass);
601
+ return {
602
+ state,
603
+ transformers,
604
+ toClass
605
+ };
606
+ }
607
+ const toClass = transformerStyleToClass({ classPrefix: "hl-" });
608
+ const tokenStyleNormalizer = {
609
+ name: "token-style-normalizer",
610
+ tokens(lines) {
611
+ for (const line of lines) for (const token of line) {
612
+ if (token.htmlStyle != null) continue;
613
+ const style = {};
614
+ if (token.color != null) style.color = token.color;
615
+ if (token.bgColor != null) style["background-color"] = token.bgColor;
616
+ if (token.fontStyle != null && token.fontStyle !== 0) {
617
+ if ((token.fontStyle & 1) !== 0) style["font-style"] = "italic";
618
+ if ((token.fontStyle & 2) !== 0) style["font-weight"] = "bold";
619
+ if ((token.fontStyle & 4) !== 0) style["text-decoration"] = "underline";
620
+ }
621
+ if (Object.keys(style).length > 0) token.htmlStyle = style;
622
+ }
623
+ }
624
+ };
625
+
626
+ //#endregion
627
+ //#region src/utils/formatCSSVariablePrefix.ts
628
+ function formatCSSVariablePrefix(type) {
629
+ return `--${type === "token" ? "diffs-token" : "diffs"}-`;
630
+ }
620
631
 
621
632
  //#endregion
622
633
  //#region src/utils/getHighlighterThemeStyles.ts
@@ -1501,9 +1512,13 @@ async function handleMessage(request) {
1501
1512
  sendError(request.id, error);
1502
1513
  }
1503
1514
  }
1504
- async function handleInitialize({ id, renderOptions: options, preferredHighlighter, resolvedThemes, resolvedLanguages }) {
1515
+ async function handleInitialize({ id, renderOptions: options, preferredHighlighter, resolvedThemes, resolvedLanguages, customExtensionsVersion: customExtensionsVersion$1, customExtensionMap }) {
1505
1516
  let highlighter$1 = getHighlighter(preferredHighlighter);
1506
1517
  if ("then" in highlighter$1) highlighter$1 = await highlighter$1;
1518
+ syncCustomExtensionsFromRequest({
1519
+ customExtensionsVersion: customExtensionsVersion$1,
1520
+ customExtensionMap
1521
+ });
1507
1522
  attachResolvedThemes(resolvedThemes, highlighter$1);
1508
1523
  if (resolvedLanguages != null) attachResolvedLanguages(resolvedLanguages, highlighter$1);
1509
1524
  renderOptions = options;
@@ -1526,9 +1541,13 @@ async function handleSetRenderOptions({ id, renderOptions: options, resolvedThem
1526
1541
  sentAt: Date.now()
1527
1542
  });
1528
1543
  }
1529
- async function handleRenderFile({ id, file, resolvedLanguages }) {
1544
+ async function handleRenderFile({ id, file, resolvedLanguages, customExtensionsVersion: customExtensionsVersion$1, customExtensionMap }) {
1530
1545
  let highlighter$1 = getHighlighter();
1531
1546
  if ("then" in highlighter$1) highlighter$1 = await highlighter$1;
1547
+ syncCustomExtensionsFromRequest({
1548
+ customExtensionsVersion: customExtensionsVersion$1,
1549
+ customExtensionMap
1550
+ });
1532
1551
  if (resolvedLanguages != null) attachResolvedLanguages(resolvedLanguages, highlighter$1);
1533
1552
  const fileOptions = {
1534
1553
  theme: renderOptions.theme,
@@ -1537,9 +1556,13 @@ async function handleRenderFile({ id, file, resolvedLanguages }) {
1537
1556
  };
1538
1557
  sendFileSuccess(id, renderFileWithHighlighter(file, highlighter$1, fileOptions), fileOptions);
1539
1558
  }
1540
- async function handleRenderDiff({ id, diff, resolvedLanguages }) {
1559
+ async function handleRenderDiff({ id, diff, resolvedLanguages, customExtensionsVersion: customExtensionsVersion$1, customExtensionMap }) {
1541
1560
  let highlighter$1 = getHighlighter();
1542
1561
  if ("then" in highlighter$1) highlighter$1 = await highlighter$1;
1562
+ syncCustomExtensionsFromRequest({
1563
+ customExtensionsVersion: customExtensionsVersion$1,
1564
+ customExtensionMap
1565
+ });
1543
1566
  if (resolvedLanguages != null) attachResolvedLanguages(resolvedLanguages, highlighter$1);
1544
1567
  sendDiffSuccess(id, renderDiffWithHighlighter(diff, highlighter$1, renderOptions), renderOptions);
1545
1568
  }
@@ -1551,6 +1574,11 @@ function getHighlighter(preferredHighlighter = "shiki-js") {
1551
1574
  });
1552
1575
  return highlighter;
1553
1576
  }
1577
+ function syncCustomExtensionsFromRequest({ customExtensionsVersion: customExtensionsVersion$1, customExtensionMap }) {
1578
+ if (customExtensionsVersion$1 == null && customExtensionMap == null) return;
1579
+ if (customExtensionsVersion$1 == null || customExtensionMap == null) throw new Error("Worker request must include both customExtensionsVersion and customExtensionMap");
1580
+ replaceCustomExtensions(customExtensionsVersion$1, customExtensionMap);
1581
+ }
1554
1582
  function sendFileSuccess(id, result, options) {
1555
1583
  postMessage({
1556
1584
  type: "success",