@pierre/diffs 1.5.1 → 1.6.0-beta.1
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/README.md +4 -3
- package/dist/components/CodeView.d.ts +2 -1
- package/dist/components/CodeView.d.ts.map +1 -1
- package/dist/components/CodeView.js +27 -16
- package/dist/components/CodeView.js.map +1 -1
- package/dist/components/File.d.ts.map +1 -1
- package/dist/components/File.js +14 -7
- package/dist/components/File.js.map +1 -1
- package/dist/components/FileDiff.d.ts +7 -4
- package/dist/components/FileDiff.d.ts.map +1 -1
- package/dist/components/FileDiff.js +16 -9
- package/dist/components/FileDiff.js.map +1 -1
- package/dist/components/FileStream.d.ts +6 -4
- package/dist/components/FileStream.d.ts.map +1 -1
- package/dist/components/FileStream.js +49 -36
- package/dist/components/FileStream.js.map +1 -1
- package/dist/components/VirtualizedFile.d.ts.map +1 -1
- package/dist/components/VirtualizedFile.js +10 -5
- package/dist/components/VirtualizedFile.js.map +1 -1
- package/dist/components/VirtualizedFileDiff.d.ts.map +1 -1
- package/dist/components/VirtualizedFileDiff.js +3 -4
- package/dist/components/VirtualizedFileDiff.js.map +1 -1
- package/dist/constants.d.ts +3 -2
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +2 -1
- package/dist/constants.js.map +1 -1
- package/dist/editor/editor.d.ts +2 -1
- package/dist/editor/editor.d.ts.map +1 -1
- package/dist/editor/editor.js +10 -3
- package/dist/editor/editor.js.map +1 -1
- package/dist/editor/getChangedDocumentLines.d.ts +6 -0
- package/dist/editor/getChangedDocumentLines.d.ts.map +1 -0
- package/dist/editor/getChangedDocumentLines.js +35 -0
- package/dist/editor/getChangedDocumentLines.js.map +1 -0
- package/dist/editor/tokenizer.d.ts +6 -4
- package/dist/editor/tokenizer.d.ts.map +1 -1
- package/dist/editor/tokenizer.js +25 -470
- package/dist/editor/tokenizer.js.map +1 -1
- package/dist/highlighter/DiffsEditorTokenizer.d.ts +16 -0
- package/dist/highlighter/DiffsEditorTokenizer.d.ts.map +1 -0
- package/dist/highlighter/DiffsEditorTokenizer.js +0 -0
- package/dist/highlighter/DiffsHighlighter.d.ts +41 -0
- package/dist/highlighter/DiffsHighlighter.d.ts.map +1 -0
- package/dist/highlighter/DiffsHighlighter.js +39 -0
- package/dist/highlighter/DiffsHighlighter.js.map +1 -0
- package/dist/highlighter/backends/highlights.d.ts +26 -0
- package/dist/highlighter/backends/highlights.d.ts.map +1 -0
- package/dist/highlighter/backends/highlights.js +71 -0
- package/dist/highlighter/backends/highlights.js.map +1 -0
- package/dist/highlighter/backends/shiki.d.ts +27 -0
- package/dist/highlighter/backends/shiki.d.ts.map +1 -0
- package/dist/highlighter/backends/shiki.js +107 -0
- package/dist/highlighter/backends/shiki.js.map +1 -0
- package/dist/highlighter/highlighterType.d.ts +13 -0
- package/dist/highlighter/highlighterType.d.ts.map +1 -0
- package/dist/highlighter/highlighterType.js +32 -0
- package/dist/highlighter/highlighterType.js.map +1 -0
- package/dist/highlighter/highlights-editor.d.ts +24 -0
- package/dist/highlighter/highlights-editor.d.ts.map +1 -0
- package/dist/highlighter/highlights-editor.js +166 -0
- package/dist/highlighter/highlights-editor.js.map +1 -0
- package/dist/highlighter/highlights-stream.d.ts +20 -0
- package/dist/highlighter/highlights-stream.d.ts.map +1 -0
- package/dist/highlighter/highlights-stream.js +93 -0
- package/dist/highlighter/highlights-stream.js.map +1 -0
- package/dist/highlighter/languages/areLanguagesAttached.d.ts +2 -1
- package/dist/highlighter/languages/areLanguagesAttached.d.ts.map +1 -1
- package/dist/highlighter/languages/areLanguagesAttached.js +4 -6
- package/dist/highlighter/languages/areLanguagesAttached.js.map +1 -1
- package/dist/highlighter/languages/attachResolvedLanguages.d.ts +6 -1
- package/dist/highlighter/languages/attachResolvedLanguages.d.ts.map +1 -1
- package/dist/highlighter/languages/attachResolvedLanguages.js +6 -11
- package/dist/highlighter/languages/attachResolvedLanguages.js.map +1 -1
- package/dist/highlighter/languages/constants.d.ts +1 -1
- package/dist/highlighter/languages/getResolvedLanguages.d.ts +1 -1
- package/dist/highlighter/languages/getResolvedOrResolveLanguage.d.ts +1 -1
- package/dist/highlighter/languages/resolveLanguage.d.ts +1 -1
- package/dist/highlighter/languages/resolveLanguage.d.ts.map +1 -1
- package/dist/highlighter/languages/resolveLanguage.js +19 -16
- package/dist/highlighter/languages/resolveLanguage.js.map +1 -1
- package/dist/highlighter/languages/resolveLanguages.d.ts +1 -1
- package/dist/highlighter/shared_highlighter.d.ts +23 -9
- package/dist/highlighter/shared_highlighter.d.ts.map +1 -1
- package/dist/highlighter/shared_highlighter.js +59 -47
- package/dist/highlighter/shared_highlighter.js.map +1 -1
- package/dist/highlighter/shiki-editor.d.ts +25 -0
- package/dist/highlighter/shiki-editor.d.ts.map +1 -0
- package/dist/highlighter/shiki-editor.js +483 -0
- package/dist/highlighter/shiki-editor.js.map +1 -0
- package/dist/highlighter/shiki-stream.d.ts +20 -0
- package/dist/highlighter/shiki-stream.d.ts.map +1 -0
- package/dist/highlighter/shiki-stream.js +60 -0
- package/dist/highlighter/shiki-stream.js.map +1 -0
- package/dist/highlighter/stream-tokenizer.d.ts +40 -0
- package/dist/highlighter/stream-tokenizer.d.ts.map +1 -0
- package/dist/highlighter/stream-tokenizer.js +70 -0
- package/dist/highlighter/stream-tokenizer.js.map +1 -0
- package/dist/highlighter/themes/areThemesAttached.d.ts +3 -2
- package/dist/highlighter/themes/areThemesAttached.d.ts.map +1 -1
- package/dist/highlighter/themes/areThemesAttached.js +5 -4
- package/dist/highlighter/themes/areThemesAttached.js.map +1 -1
- package/dist/highlighter/themes/attachResolvedThemes.d.ts +5 -2
- package/dist/highlighter/themes/attachResolvedThemes.d.ts.map +1 -1
- package/dist/highlighter/themes/attachResolvedThemes.js +4 -16
- package/dist/highlighter/themes/attachResolvedThemes.js.map +1 -1
- package/dist/highlighter/themes/cleanUpResolvedThemes.d.ts +3 -1
- package/dist/highlighter/themes/cleanUpResolvedThemes.d.ts.map +1 -1
- package/dist/highlighter/themes/cleanUpResolvedThemes.js +8 -5
- package/dist/highlighter/themes/cleanUpResolvedThemes.js.map +1 -1
- package/dist/highlighter/themes/createCSSVariablesTheme.d.ts +7 -0
- package/dist/highlighter/themes/createCSSVariablesTheme.d.ts.map +1 -0
- package/dist/highlighter/themes/createCSSVariablesTheme.js +89 -0
- package/dist/highlighter/themes/createCSSVariablesTheme.js.map +1 -0
- package/dist/highlighter/themes/createCachedLoader.d.ts +5 -0
- package/dist/highlighter/themes/createCachedLoader.d.ts.map +1 -0
- package/dist/highlighter/themes/createCachedLoader.js +15 -0
- package/dist/highlighter/themes/createCachedLoader.js.map +1 -0
- package/dist/highlighter/themes/getResolvedOrResolveTheme.d.ts +3 -2
- package/dist/highlighter/themes/getResolvedOrResolveTheme.d.ts.map +1 -1
- package/dist/highlighter/themes/getResolvedOrResolveTheme.js +4 -4
- package/dist/highlighter/themes/getResolvedOrResolveTheme.js.map +1 -1
- package/dist/highlighter/themes/getResolvedThemes.d.ts +3 -2
- package/dist/highlighter/themes/getResolvedThemes.d.ts.map +1 -1
- package/dist/highlighter/themes/getResolvedThemes.js +4 -3
- package/dist/highlighter/themes/getResolvedThemes.js.map +1 -1
- package/dist/highlighter/themes/hasResolvedThemes.d.ts +2 -2
- package/dist/highlighter/themes/hasResolvedThemes.d.ts.map +1 -1
- package/dist/highlighter/themes/hasResolvedThemes.js +4 -3
- package/dist/highlighter/themes/hasResolvedThemes.js.map +1 -1
- package/dist/highlighter/themes/registerCustomCSSVariableTheme.d.ts.map +1 -1
- package/dist/highlighter/themes/registerCustomCSSVariableTheme.js +3 -3
- package/dist/highlighter/themes/registerCustomCSSVariableTheme.js.map +1 -1
- package/dist/highlighter/themes/registerCustomTheme.d.ts +9 -4
- package/dist/highlighter/themes/registerCustomTheme.d.ts.map +1 -1
- package/dist/highlighter/themes/registerCustomTheme.js +8 -16
- package/dist/highlighter/themes/registerCustomTheme.js.map +1 -1
- package/dist/highlighter/themes/resolveTheme.d.ts +3 -2
- package/dist/highlighter/themes/resolveTheme.d.ts.map +1 -1
- package/dist/highlighter/themes/resolveTheme.js +4 -7
- package/dist/highlighter/themes/resolveTheme.js.map +1 -1
- package/dist/highlighter/themes/resolveThemes.d.ts +3 -2
- package/dist/highlighter/themes/resolveThemes.d.ts.map +1 -1
- package/dist/highlighter/themes/resolveThemes.js +4 -7
- package/dist/highlighter/themes/resolveThemes.js.map +1 -1
- package/dist/highlighter/themes/themeResolver.d.ts +10 -4
- package/dist/highlighter/themes/themeResolver.d.ts.map +1 -1
- package/dist/highlighter/themes/themeResolver.js +141 -2
- package/dist/highlighter/themes/themeResolver.js.map +1 -1
- package/dist/highlighter/themes/types.d.ts +23 -0
- package/dist/highlighter/themes/types.d.ts.map +1 -0
- package/dist/highlighter/themes/types.js +0 -0
- package/dist/highlighter/tokenizer-types.d.ts +35 -0
- package/dist/highlighter/tokenizer-types.d.ts.map +1 -0
- package/dist/highlighter/tokenizer-types.js +0 -0
- package/dist/highlighter/types.d.ts +55 -0
- package/dist/highlighter/types.d.ts.map +1 -0
- package/dist/highlighter/types.js +0 -0
- package/dist/index.d.ts +14 -10
- package/dist/index.js +16 -18
- package/dist/managers/InteractionManager.d.ts.map +1 -1
- package/dist/managers/InteractionManager.js +2 -2
- package/dist/managers/InteractionManager.js.map +1 -1
- package/dist/node_modules/.pnpm/@types_hast@3.0.4/node_modules/@types/hast/index.d.ts +9 -1
- package/dist/node_modules/.pnpm/@types_hast@3.0.4/node_modules/@types/hast/index.d.ts.map +1 -1
- package/dist/react/CodeView.js +1 -1
- package/dist/react/index.d.ts +8 -3
- package/dist/renderers/DiffHunksRenderer.d.ts +3 -2
- package/dist/renderers/DiffHunksRenderer.d.ts.map +1 -1
- package/dist/renderers/DiffHunksRenderer.js +50 -24
- package/dist/renderers/DiffHunksRenderer.js.map +1 -1
- package/dist/renderers/FileRenderer.d.ts +2 -1
- package/dist/renderers/FileRenderer.d.ts.map +1 -1
- package/dist/renderers/FileRenderer.js +33 -24
- package/dist/renderers/FileRenderer.js.map +1 -1
- package/dist/shiki-stream/index.d.ts +3 -3
- package/dist/shiki-stream/index.js +1 -2
- package/dist/shiki-stream/stream.d.ts +4 -4
- package/dist/shiki-stream/stream.d.ts.map +1 -1
- package/dist/shiki-stream/stream.js +20 -9
- package/dist/shiki-stream/stream.js.map +1 -1
- package/dist/shiki-stream/types.d.ts +7 -38
- package/dist/shiki-stream/types.d.ts.map +1 -1
- package/dist/ssr/FileDiffReact.js +1 -1
- package/dist/ssr/index.d.ts +7 -2
- package/dist/ssr/renderHTML.js +2 -2
- package/dist/ssr/renderHTML.js.map +1 -1
- package/dist/style.js +1 -1
- package/dist/style.js.map +1 -1
- package/dist/types.d.ts +13 -13
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/computeVirtualFileMetrics.d.ts +2 -1
- package/dist/utils/computeVirtualFileMetrics.d.ts.map +1 -1
- package/dist/utils/computeVirtualFileMetrics.js +5 -3
- package/dist/utils/computeVirtualFileMetrics.js.map +1 -1
- package/dist/utils/createSpanNodeFromToken.d.ts +3 -2
- package/dist/utils/createSpanNodeFromToken.d.ts.map +1 -1
- package/dist/utils/createSpanNodeFromToken.js +4 -5
- package/dist/utils/createSpanNodeFromToken.js.map +1 -1
- package/dist/utils/cssWrappers.d.ts.map +1 -1
- package/dist/utils/cssWrappers.js +12 -0
- package/dist/utils/cssWrappers.js.map +1 -1
- package/dist/utils/getDiffHunksRendererOptions.js +1 -0
- package/dist/utils/getDiffHunksRendererOptions.js.map +1 -1
- package/dist/utils/getFiletypeFromFileName.d.ts.map +1 -1
- package/dist/utils/getFiletypeFromFileName.js +21 -3
- package/dist/utils/getFiletypeFromFileName.js.map +1 -1
- package/dist/utils/getHighlighterOptions.d.ts.map +1 -1
- package/dist/utils/getHighlighterOptions.js +3 -2
- package/dist/utils/getHighlighterOptions.js.map +1 -1
- package/dist/utils/getHighlighterThemeStyles.d.ts +2 -1
- package/dist/utils/getHighlighterThemeStyles.d.ts.map +1 -1
- package/dist/utils/getHighlighterThemeStyles.js +13 -3
- package/dist/utils/getHighlighterThemeStyles.js.map +1 -1
- package/dist/utils/getTokenOptions.d.ts +7 -0
- package/dist/utils/getTokenOptions.d.ts.map +1 -0
- package/dist/utils/getTokenOptions.js +16 -0
- package/dist/utils/getTokenOptions.js.map +1 -0
- package/dist/utils/hastToHtml.d.ts +10 -0
- package/dist/utils/hastToHtml.d.ts.map +1 -0
- package/dist/utils/hastToHtml.js +125 -0
- package/dist/utils/hastToHtml.js.map +1 -0
- package/dist/utils/parseDiffDecorations.d.ts +2 -1
- package/dist/utils/parseDiffDecorations.d.ts.map +1 -1
- package/dist/utils/platform.d.ts +2 -1
- package/dist/utils/platform.d.ts.map +1 -1
- package/dist/utils/platform.js +6 -1
- package/dist/utils/platform.js.map +1 -1
- package/dist/utils/renderDiffWithHighlighter.d.ts +3 -2
- package/dist/utils/renderDiffWithHighlighter.d.ts.map +1 -1
- package/dist/utils/renderDiffWithHighlighter.js +33 -48
- package/dist/utils/renderDiffWithHighlighter.js.map +1 -1
- package/dist/utils/renderFileWithHighlighter.d.ts +3 -2
- package/dist/utils/renderFileWithHighlighter.d.ts.map +1 -1
- package/dist/utils/renderFileWithHighlighter.js +10 -26
- package/dist/utils/renderFileWithHighlighter.js.map +1 -1
- package/dist/utils/renderTokenLines.d.ts +17 -0
- package/dist/utils/renderTokenLines.d.ts.map +1 -0
- package/dist/utils/renderTokenLines.js +246 -0
- package/dist/utils/renderTokenLines.js.map +1 -0
- package/dist/utils/resolvePreferredHighlighter.d.ts +13 -0
- package/dist/utils/resolvePreferredHighlighter.d.ts.map +1 -0
- package/dist/utils/resolvePreferredHighlighter.js +11 -0
- package/dist/utils/resolvePreferredHighlighter.js.map +1 -0
- package/dist/utils/setDeferredArrayItem.d.ts +5 -0
- package/dist/utils/setDeferredArrayItem.d.ts.map +1 -0
- package/dist/utils/setDeferredArrayItem.js +39 -0
- package/dist/utils/setDeferredArrayItem.js.map +1 -0
- package/dist/utils/tokenStyle.d.ts +7 -0
- package/dist/utils/tokenStyle.d.ts.map +1 -0
- package/dist/utils/tokenStyle.js +28 -0
- package/dist/utils/tokenStyle.js.map +1 -0
- package/dist/utils/tokensToHtml.d.ts +8 -0
- package/dist/utils/tokensToHtml.d.ts.map +1 -0
- package/dist/utils/tokensToHtml.js +45 -0
- package/dist/utils/tokensToHtml.js.map +1 -0
- package/dist/utils/wrapTokenFragments.js.map +1 -1
- package/dist/worker/WorkerPoolManager.d.ts +10 -2
- package/dist/worker/WorkerPoolManager.d.ts.map +1 -1
- package/dist/worker/WorkerPoolManager.js +85 -60
- package/dist/worker/WorkerPoolManager.js.map +1 -1
- package/dist/worker/errors.d.ts +35 -0
- package/dist/worker/errors.d.ts.map +1 -0
- package/dist/worker/errors.js +52 -0
- package/dist/worker/errors.js.map +1 -0
- package/dist/worker/hastLinesTransport.d.ts +14 -0
- package/dist/worker/hastLinesTransport.d.ts.map +1 -0
- package/dist/worker/hastLinesTransport.js +156 -0
- package/dist/worker/hastLinesTransport.js.map +1 -0
- package/dist/worker/highlights-sAHlxqlf.js +317 -0
- package/dist/worker/highlights-sAHlxqlf.js.map +1 -0
- package/dist/worker/index.d.ts +2 -1
- package/dist/worker/index.js +2 -1
- package/dist/worker/shiki-Bx2JpdqZ.js +697 -0
- package/dist/worker/shiki-Bx2JpdqZ.js.map +1 -0
- package/dist/worker/stream-tokenizer-YZ6M1qSx.js +424 -0
- package/dist/worker/stream-tokenizer-YZ6M1qSx.js.map +1 -0
- package/dist/worker/types.d.ts +18 -3
- package/dist/worker/types.d.ts.map +1 -1
- package/dist/worker/worker-portable.js +41 -13319
- package/dist/worker/worker-portable.js.map +1 -1
- package/dist/worker/worker.js +693 -352
- package/dist/worker/worker.js.map +1 -1
- package/dist/worker/workerMessage.d.ts +24 -0
- package/dist/worker/workerMessage.d.ts.map +1 -0
- package/dist/worker/workerMessage.js +0 -0
- package/package.json +33 -29
- package/dist/highlighter/themes/constants.d.ts +0 -5
- package/dist/highlighter/themes/constants.d.ts.map +0 -1
- package/dist/highlighter/themes/constants.js +0 -6
- package/dist/highlighter/themes/constants.js.map +0 -1
- package/dist/highlighter/themes/themeResolution.d.ts +0 -7
- package/dist/highlighter/themes/themeResolution.d.ts.map +0 -1
- package/dist/highlighter/themes/themeResolution.js +0 -21
- package/dist/highlighter/themes/themeResolution.js.map +0 -1
- package/dist/shiki-stream/tokenizer.d.ts +0 -23
- package/dist/shiki-stream/tokenizer.d.ts.map +0 -1
- package/dist/shiki-stream/tokenizer.js +0 -72
- package/dist/shiki-stream/tokenizer.js.map +0 -1
- package/dist/utils/createTransformerWithState.d.ts +0 -12
- package/dist/utils/createTransformerWithState.d.ts.map +0 -1
- package/dist/utils/createTransformerWithState.js +0 -89
- package/dist/utils/createTransformerWithState.js.map +0 -1
- package/dist/worker/wasm-B9ZqxnKj.js +0 -8
- package/dist/worker/wasm-B9ZqxnKj.js.map +0 -1
package/dist/utils/platform.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
let _isMacLike = void 0;
|
|
3
3
|
let _isLinux = void 0;
|
|
4
4
|
let _isSafari = void 0;
|
|
5
|
+
let _isFirefox = void 0;
|
|
5
6
|
/**
|
|
6
7
|
* Clears the cached platform/browser detection. Detection is memoized on first
|
|
7
8
|
* call, so a test process that swaps `navigator` (e.g. to exercise Linux or
|
|
@@ -12,6 +13,7 @@ function resetPlatformDetection() {
|
|
|
12
13
|
_isMacLike = void 0;
|
|
13
14
|
_isLinux = void 0;
|
|
14
15
|
_isSafari = void 0;
|
|
16
|
+
_isFirefox = void 0;
|
|
15
17
|
}
|
|
16
18
|
function isMacLike() {
|
|
17
19
|
return _isMacLike ??= /macOS|MacIntel|iPhone|iPad|iPod/i.test(getPlatform());
|
|
@@ -22,11 +24,14 @@ function isLinux() {
|
|
|
22
24
|
function isSafari() {
|
|
23
25
|
return _isSafari ??= "safari" in window && "pushNotification" in window.safari || /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
|
|
24
26
|
}
|
|
27
|
+
function isFirefox() {
|
|
28
|
+
return _isFirefox ??= /\bFirefox\//.test(navigator.userAgent);
|
|
29
|
+
}
|
|
25
30
|
function getPlatform() {
|
|
26
31
|
const navigator = globalThis.navigator;
|
|
27
32
|
return navigator?.platform ?? navigator?.userAgentData?.platform ?? "unknown";
|
|
28
33
|
}
|
|
29
34
|
//#endregion
|
|
30
|
-
export { isLinux, isMacLike, isSafari, resetPlatformDetection };
|
|
35
|
+
export { isFirefox, isLinux, isMacLike, isSafari, resetPlatformDetection };
|
|
31
36
|
|
|
32
37
|
//# sourceMappingURL=platform.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform.js","names":[],"sources":["../../src/utils/platform.ts"],"sourcesContent":["let _isMacLike: boolean | undefined = undefined;\nlet _isLinux: boolean | undefined = undefined;\nlet _isSafari: boolean | undefined = undefined;\n\n/**\n * Clears the cached platform/browser detection. Detection is memoized on first\n * call, so a test process that swaps `navigator` (e.g. to exercise Linux or\n * Safari behavior) must reset it; otherwise the value cached by an earlier test\n * leaks across tests and no longer matches the active navigator.\n */\nexport function resetPlatformDetection(): void {\n _isMacLike = undefined;\n _isLinux = undefined;\n _isSafari = undefined;\n}\n\nexport function isMacLike(): boolean {\n return (_isMacLike ??= /macOS|MacIntel|iPhone|iPad|iPod/i.test(\n getPlatform()\n ));\n}\n\nexport function isLinux(): boolean {\n return (_isLinux ??= /Linux/i.test(getPlatform()));\n}\n\nexport function isSafari(): boolean {\n return (_isSafari ??=\n // oxlint-disable-next-line typescript/no-explicit-any\n ('safari' in window && 'pushNotification' in (window as any).safari) ||\n /^((?!chrome|android).)*safari/i.test(navigator.userAgent));\n}\n\nfunction getPlatform(): string {\n const navigator = globalThis.navigator as Navigator & {\n userAgentData?: { platform?: string };\n };\n return navigator?.platform ?? navigator?.userAgentData?.platform ?? 'unknown';\n}\n"],"mappings":";AAAA,IAAI,aAAkC,KAAA;AACtC,IAAI,WAAgC,KAAA;AACpC,IAAI,YAAiC,KAAA;;;;;;;
|
|
1
|
+
{"version":3,"file":"platform.js","names":[],"sources":["../../src/utils/platform.ts"],"sourcesContent":["let _isMacLike: boolean | undefined = undefined;\nlet _isLinux: boolean | undefined = undefined;\nlet _isSafari: boolean | undefined = undefined;\nlet _isFirefox: boolean | undefined = undefined;\n\n/**\n * Clears the cached platform/browser detection. Detection is memoized on first\n * call, so a test process that swaps `navigator` (e.g. to exercise Linux or\n * Safari behavior) must reset it; otherwise the value cached by an earlier test\n * leaks across tests and no longer matches the active navigator.\n */\nexport function resetPlatformDetection(): void {\n _isMacLike = undefined;\n _isLinux = undefined;\n _isSafari = undefined;\n _isFirefox = undefined;\n}\n\nexport function isMacLike(): boolean {\n return (_isMacLike ??= /macOS|MacIntel|iPhone|iPad|iPod/i.test(\n getPlatform()\n ));\n}\n\nexport function isLinux(): boolean {\n return (_isLinux ??= /Linux/i.test(getPlatform()));\n}\n\nexport function isSafari(): boolean {\n return (_isSafari ??=\n // oxlint-disable-next-line typescript/no-explicit-any\n ('safari' in window && 'pushNotification' in (window as any).safari) ||\n /^((?!chrome|android).)*safari/i.test(navigator.userAgent));\n}\n\n// Gecko-based Firefox builds (desktop and Android). Firefox on iOS (FxiOS)\n// renders with WebKit and is intentionally excluded.\nexport function isFirefox(): boolean {\n return (_isFirefox ??= /\\bFirefox\\//.test(navigator.userAgent));\n}\n\nfunction getPlatform(): string {\n const navigator = globalThis.navigator as Navigator & {\n userAgentData?: { platform?: string };\n };\n return navigator?.platform ?? navigator?.userAgentData?.platform ?? 'unknown';\n}\n"],"mappings":";AAAA,IAAI,aAAkC,KAAA;AACtC,IAAI,WAAgC,KAAA;AACpC,IAAI,YAAiC,KAAA;AACrC,IAAI,aAAkC,KAAA;;;;;;;AAQtC,SAAgB,yBAA+B;CAC7C,aAAa,KAAA;CACb,WAAW,KAAA;CACX,YAAY,KAAA;CACZ,aAAa,KAAA;AACf;AAEA,SAAgB,YAAqB;CACnC,OAAQ,eAAe,mCAAmC,KACxD,YAAY,CACd;AACF;AAEA,SAAgB,UAAmB;CACjC,OAAQ,aAAa,SAAS,KAAK,YAAY,CAAC;AAClD;AAEA,SAAgB,WAAoB;CAClC,OAAQ,cAEL,YAAY,UAAU,sBAAuB,OAAe,UAC7D,iCAAiC,KAAK,UAAU,SAAS;AAC7D;AAIA,SAAgB,YAAqB;CACnC,OAAQ,eAAe,cAAc,KAAK,UAAU,SAAS;AAC/D;AAEA,SAAS,cAAsB;CAC7B,MAAM,YAAY,WAAW;CAG7B,OAAO,WAAW,YAAY,WAAW,eAAe,YAAY;AACtE"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { DiffsHighlighter
|
|
1
|
+
import { DiffsHighlighter } from "../highlighter/DiffsHighlighter.js";
|
|
2
|
+
import { FileDiffMetadata, ForceDiffPlainTextOptions, RenderDiffOptions, ThemedDiffResult } from "../types.js";
|
|
2
3
|
//#region src/utils/renderDiffWithHighlighter.d.ts
|
|
3
|
-
declare function renderDiffWithHighlighter(diff: FileDiffMetadata, highlighter: DiffsHighlighter, options: RenderDiffOptions, { forcePlainText, startingLine, totalLines, expandedHunks, collapsedContextThreshold }?: ForceDiffPlainTextOptions): ThemedDiffResult;
|
|
4
|
+
declare function renderDiffWithHighlighter(diff: FileDiffMetadata, highlighter: DiffsHighlighter, options: RenderDiffOptions, { forcePlainText, lazyLineAST, startingLine, totalLines, expandedHunks, collapsedContextThreshold }?: ForceDiffPlainTextOptions): ThemedDiffResult;
|
|
4
5
|
//#endregion
|
|
5
6
|
export { renderDiffWithHighlighter };
|
|
6
7
|
//# sourceMappingURL=renderDiffWithHighlighter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderDiffWithHighlighter.d.ts","names":[],"sources":["../../src/utils/renderDiffWithHighlighter.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"renderDiffWithHighlighter.d.ts","names":[],"sources":["../../src/utils/renderDiffWithHighlighter.ts"],"mappings":";;;iBAiCgB,0BACd,MAAM,kBACN,aAAa,kBACb,SAAS,qBAEP,gBACA,aACA,cACA,YACA,eACA,8BACC,4BACF"}
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import "../constants.js";
|
|
2
2
|
import { getFiletypeFromFileName } from "./getFiletypeFromFileName.js";
|
|
3
3
|
import { appendItems } from "./appendItems.js";
|
|
4
|
-
import { createTransformerWithState } from "./createTransformerWithState.js";
|
|
5
|
-
import { formatCSSVariablePrefix } from "./formatCSSVariablePrefix.js";
|
|
6
4
|
import { getHighlighterThemeStyles } from "./getHighlighterThemeStyles.js";
|
|
7
|
-
import {
|
|
5
|
+
import { getTokenOptions } from "./getTokenOptions.js";
|
|
6
|
+
import { setDeferredArrayItem } from "./setDeferredArrayItem.js";
|
|
7
|
+
import { renderTokenLines } from "./renderTokenLines.js";
|
|
8
8
|
import { iterateOverDiff } from "./iterateOverDiff.js";
|
|
9
9
|
import { cleanLastNewline } from "./cleanLastNewline.js";
|
|
10
10
|
import { createDiffSpanDecoration, pushOrJoinSpan } from "./parseDiffDecorations.js";
|
|
11
11
|
import { diffChars, diffWordsWithSpace } from "diff";
|
|
12
12
|
//#region src/utils/renderDiffWithHighlighter.ts
|
|
13
13
|
const DEFAULT_PLAIN_TEXT_OPTIONS = { forcePlainText: false };
|
|
14
|
-
function renderDiffWithHighlighter(diff, highlighter, options, { forcePlainText, startingLine, totalLines, expandedHunks, collapsedContextThreshold = 1 } = DEFAULT_PLAIN_TEXT_OPTIONS) {
|
|
14
|
+
function renderDiffWithHighlighter(diff, highlighter, options, { forcePlainText, lazyLineAST = false, startingLine, totalLines, expandedHunks, collapsedContextThreshold = 1 } = DEFAULT_PLAIN_TEXT_OPTIONS) {
|
|
15
15
|
if (forcePlainText) {
|
|
16
16
|
startingLine ??= 0;
|
|
17
17
|
totalLines ??= Infinity;
|
|
@@ -20,6 +20,7 @@ function renderDiffWithHighlighter(diff, highlighter, options, { forcePlainText,
|
|
|
20
20
|
totalLines = Infinity;
|
|
21
21
|
}
|
|
22
22
|
const isWindowedHighlight = startingLine > 0 || totalLines < Infinity;
|
|
23
|
+
lazyLineAST &&= !forcePlainText && !options.useTokenTransformer;
|
|
23
24
|
const baseThemeType = typeof options.theme === "string" ? highlighter.getTheme(options.theme).type : void 0;
|
|
24
25
|
const themeStyles = getHighlighterThemeStyles({
|
|
25
26
|
theme: options.theme,
|
|
@@ -114,17 +115,27 @@ function renderDiffWithHighlighter(diff, highlighter, options, { forcePlainText,
|
|
|
114
115
|
additionDecorations: bucket.additionDecorations,
|
|
115
116
|
highlighter,
|
|
116
117
|
options,
|
|
117
|
-
languageOverride: forcePlainText ? "text" : diff.lang
|
|
118
|
+
languageOverride: forcePlainText ? "text" : diff.lang,
|
|
119
|
+
lazyLineAST
|
|
118
120
|
});
|
|
119
121
|
if (shouldGroupAll) {
|
|
120
122
|
code.deletionLines = deletionLines;
|
|
121
123
|
code.additionLines = additionLines;
|
|
122
124
|
continue;
|
|
123
125
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
126
|
+
for (const [target, lines, segments] of [[
|
|
127
|
+
code.deletionLines,
|
|
128
|
+
deletionLines,
|
|
129
|
+
bucket.deletionSegments
|
|
130
|
+
], [
|
|
131
|
+
code.additionLines,
|
|
132
|
+
additionLines,
|
|
133
|
+
bucket.additionSegments
|
|
134
|
+
]]) if (segments.length > 0) for (const segment of segments) for (let index = 0; index < segment.count; index++) target[segment.targetIndex + index] = lines[segment.originalOffset + index];
|
|
135
|
+
else if (lazyLineAST) {
|
|
136
|
+
const offset = target.length;
|
|
137
|
+
for (let index = 0; index < lines.length; index++) setDeferredArrayItem(target, offset + index, () => lines[index]);
|
|
138
|
+
} else appendItems(target, lines);
|
|
128
139
|
}
|
|
129
140
|
return {
|
|
130
141
|
code,
|
|
@@ -256,46 +267,20 @@ function createBucket() {
|
|
|
256
267
|
additionSegments: []
|
|
257
268
|
};
|
|
258
269
|
}
|
|
259
|
-
function renderTwoFiles({ deletionFile, additionFile, deletionInfo, additionInfo, highlighter, deletionDecorations, additionDecorations, languageOverride, options: { theme
|
|
260
|
-
const
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
defaultColor: false,
|
|
271
|
-
cssVariablePrefix: formatCSSVariablePrefix("token"),
|
|
272
|
-
tokenizeTimeLimit: 0
|
|
273
|
-
} : {
|
|
274
|
-
...options,
|
|
275
|
-
lang: "text",
|
|
276
|
-
themes: themeOrThemes,
|
|
277
|
-
transformers,
|
|
278
|
-
decorations: void 0,
|
|
279
|
-
defaultColor: false,
|
|
280
|
-
cssVariablePrefix: formatCSSVariablePrefix("token"),
|
|
281
|
-
tokenizeTimeLimit: 0
|
|
282
|
-
};
|
|
283
|
-
})();
|
|
270
|
+
function renderTwoFiles({ lazyLineAST, deletionFile, additionFile, deletionInfo, additionInfo, highlighter, deletionDecorations, additionDecorations, languageOverride, options: { theme, useTokenTransformer, tokenizeMaxLineLength } }) {
|
|
271
|
+
const renderFile = (file, lineInfo, decorations) => {
|
|
272
|
+
if (file.contents === "") return [];
|
|
273
|
+
return renderTokenLines(highlighter.codeToTokens(cleanLastNewline(file.contents), getTokenOptions(languageOverride ?? getFiletypeFromFileName(file.name), theme, tokenizeMaxLineLength)).tokens, {
|
|
274
|
+
state: { lineInfo },
|
|
275
|
+
useTokenTransformer,
|
|
276
|
+
decorations,
|
|
277
|
+
lazyLineAST,
|
|
278
|
+
cacheHtmlStyles: highlighter.name === "highlights"
|
|
279
|
+
});
|
|
280
|
+
};
|
|
284
281
|
return {
|
|
285
|
-
deletionLines: (
|
|
286
|
-
|
|
287
|
-
hastConfig.lang = deletionLang;
|
|
288
|
-
state.lineInfo = deletionInfo;
|
|
289
|
-
hastConfig.decorations = deletionDecorations;
|
|
290
|
-
return getLineNodes(highlighter.codeToHast(cleanLastNewline(deletionFile.contents), hastConfig));
|
|
291
|
-
})(),
|
|
292
|
-
additionLines: (() => {
|
|
293
|
-
if (additionFile.contents === "") return [];
|
|
294
|
-
hastConfig.lang = additionLang;
|
|
295
|
-
hastConfig.decorations = additionDecorations;
|
|
296
|
-
state.lineInfo = additionInfo;
|
|
297
|
-
return getLineNodes(highlighter.codeToHast(cleanLastNewline(additionFile.contents), hastConfig));
|
|
298
|
-
})()
|
|
282
|
+
deletionLines: renderFile(deletionFile, deletionInfo, deletionDecorations),
|
|
283
|
+
additionLines: renderFile(additionFile, additionInfo, additionDecorations)
|
|
299
284
|
};
|
|
300
285
|
}
|
|
301
286
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderDiffWithHighlighter.js","names":[],"sources":["../../src/utils/renderDiffWithHighlighter.ts"],"sourcesContent":["import { type ChangeObject, diffChars, diffWordsWithSpace } from 'diff';\n\nimport { DEFAULT_COLLAPSED_CONTEXT_THRESHOLD } from '../constants';\nimport type {\n CodeToHastOptions,\n DecorationItem,\n DiffsHighlighter,\n DiffsThemeNames,\n FileContents,\n FileDiffMetadata,\n ForceDiffPlainTextOptions,\n LineDiffTypes,\n LineInfo,\n RenderDiffFilesResult,\n RenderDiffOptions,\n SupportedLanguages,\n ThemedDiffResult,\n} from '../types';\nimport { appendItems } from './appendItems';\nimport { cleanLastNewline } from './cleanLastNewline';\nimport { createTransformerWithState } from './createTransformerWithState';\nimport { formatCSSVariablePrefix } from './formatCSSVariablePrefix';\nimport { getFiletypeFromFileName } from './getFiletypeFromFileName';\nimport { getHighlighterThemeStyles } from './getHighlighterThemeStyles';\nimport { getLineNodes } from './getLineNodes';\nimport { iterateOverDiff } from './iterateOverDiff';\nimport {\n createDiffSpanDecoration,\n pushOrJoinSpan,\n} from './parseDiffDecorations';\n\nconst DEFAULT_PLAIN_TEXT_OPTIONS: ForceDiffPlainTextOptions = {\n forcePlainText: false,\n};\n\nexport function renderDiffWithHighlighter(\n diff: FileDiffMetadata,\n highlighter: DiffsHighlighter,\n options: RenderDiffOptions,\n {\n forcePlainText,\n startingLine,\n totalLines,\n expandedHunks,\n collapsedContextThreshold = DEFAULT_COLLAPSED_CONTEXT_THRESHOLD,\n }: ForceDiffPlainTextOptions = DEFAULT_PLAIN_TEXT_OPTIONS\n): ThemedDiffResult {\n if (forcePlainText) {\n startingLine ??= 0;\n totalLines ??= Infinity;\n } else {\n // If we aren't forcing plain text, then we intentionally do not support\n // ranges for highlighting as that could break the syntax highlighting, we\n // we override any values that may have been passed in. Maybe one day we\n // warn about this?\n startingLine = 0;\n totalLines = Infinity;\n }\n const isWindowedHighlight = startingLine > 0 || totalLines < Infinity;\n const baseThemeType =\n typeof options.theme === 'string'\n ? highlighter.getTheme(options.theme).type\n : undefined;\n const themeStyles = getHighlighterThemeStyles({\n theme: options.theme,\n highlighter,\n });\n\n // If we have a large file and we are rendering the WHOLE plain diff ast,\n // then we should remove the lineDiffType to make sure things render quickly.\n // For highlighted ASTs or windowed highlights, we should just inherit the\n // setting\n const lineDiffType =\n forcePlainText &&\n !isWindowedHighlight &&\n (diff.unifiedLineCount > 1000 || diff.splitLineCount > 1000)\n ? 'none'\n : options.lineDiffType;\n\n const code: RenderDiffFilesResult = {\n deletionLines: [],\n additionLines: [],\n };\n\n const { maxLineDiffLength } = options;\n const shouldGroupAll = !forcePlainText && !diff.isPartial;\n const expandedHunksForIteration = forcePlainText ? expandedHunks : undefined;\n const buckets = new Map<number, RenderBucket>();\n function getBucketForHunk(hunkIndex: number) {\n const index = shouldGroupAll ? 0 : hunkIndex;\n const bucket = buckets.get(index) ?? createBucket();\n buckets.set(index, bucket);\n return bucket;\n }\n\n function appendContent(\n lineContent: string,\n lineIndex: number,\n segments: HighlightSegment[],\n contentWrapper: FakeArrayType\n ) {\n if (isWindowedHighlight) {\n let segment = segments.at(-1);\n if (\n segment == null ||\n segment.targetIndex + segment.count !== lineIndex\n ) {\n segment = {\n targetIndex: lineIndex,\n originalOffset: contentWrapper.length,\n count: 0,\n };\n segments.push(segment);\n }\n segment.count++;\n }\n contentWrapper.push(lineContent);\n }\n\n iterateOverDiff({\n diff,\n diffStyle: 'both',\n startingLine,\n totalLines,\n expandedHunks: isWindowedHighlight ? expandedHunksForIteration : true,\n collapsedContextThreshold,\n callback: ({ hunkIndex, additionLine, deletionLine, type }) => {\n const bucket = getBucketForHunk(hunkIndex);\n const splitLineIndex =\n additionLine != null\n ? additionLine.splitLineIndex\n : deletionLine.splitLineIndex;\n\n if (type === 'change' && additionLine != null && deletionLine != null) {\n computeLineDiffDecorations({\n additionLine: diff.additionLines[additionLine.lineIndex],\n deletionLine: diff.deletionLines[deletionLine.lineIndex],\n deletionLineIndex: bucket.deletionContent.length,\n additionLineIndex: bucket.additionContent.length,\n deletionDecorations: bucket.deletionDecorations,\n additionDecorations: bucket.additionDecorations,\n lineDiffType,\n maxLineDiffLength,\n });\n }\n\n if (deletionLine != null) {\n appendContent(\n diff.deletionLines[deletionLine.lineIndex],\n deletionLine.lineIndex,\n bucket.deletionSegments,\n bucket.deletionContent\n );\n bucket.deletionInfo.push({\n type: type === 'change' ? 'change-deletion' : type,\n lineNumber: deletionLine.lineNumber,\n altLineNumber:\n type === 'change'\n ? undefined\n : (additionLine.lineNumber ?? undefined),\n lineIndex: `${deletionLine.unifiedLineIndex},${splitLineIndex}`,\n });\n }\n\n if (additionLine != null) {\n appendContent(\n diff.additionLines[additionLine.lineIndex],\n additionLine.lineIndex,\n bucket.additionSegments,\n bucket.additionContent\n );\n bucket.additionInfo.push({\n type: type === 'change' ? 'change-addition' : type,\n lineNumber: additionLine.lineNumber,\n altLineNumber:\n type === 'change'\n ? undefined\n : (deletionLine.lineNumber ?? undefined),\n lineIndex: `${additionLine.unifiedLineIndex},${splitLineIndex}`,\n });\n }\n },\n });\n\n for (const bucket of buckets.values()) {\n if (\n bucket.deletionContent.length === 0 &&\n bucket.additionContent.length === 0\n ) {\n continue;\n }\n\n const deletionFile = {\n name: diff.prevName ?? diff.name,\n contents: bucket.deletionContent.value,\n };\n const additionFile = {\n name: diff.name,\n contents: bucket.additionContent.value,\n };\n const { deletionLines, additionLines } = renderTwoFiles({\n deletionFile,\n deletionInfo: bucket.deletionInfo,\n deletionDecorations: bucket.deletionDecorations,\n\n additionFile,\n additionInfo: bucket.additionInfo,\n additionDecorations: bucket.additionDecorations,\n\n highlighter,\n options,\n languageOverride: forcePlainText ? 'text' : diff.lang,\n });\n\n if (shouldGroupAll) {\n code.deletionLines = deletionLines;\n code.additionLines = additionLines;\n continue;\n }\n\n if (bucket.deletionSegments.length > 0) {\n for (const seg of bucket.deletionSegments) {\n for (let i = 0; i < seg.count; i++) {\n code.deletionLines[seg.targetIndex + i] =\n deletionLines[seg.originalOffset + i];\n }\n }\n } else {\n appendItems(code.deletionLines, deletionLines);\n }\n if (bucket.additionSegments.length > 0) {\n for (const seg of bucket.additionSegments) {\n for (let i = 0; i < seg.count; i++) {\n code.additionLines[seg.targetIndex + i] =\n additionLines[seg.originalOffset + i];\n }\n }\n } else {\n appendItems(code.additionLines, additionLines);\n }\n }\n\n return { code, themeStyles, baseThemeType };\n}\n\n// The line indexes and decoration arrays a line diff writes its highlights to\ninterface LineDiffDecorationTargets {\n deletionLineIndex: number;\n additionLineIndex: number;\n deletionDecorations: DecorationItem[];\n additionDecorations: DecorationItem[];\n}\n\ninterface ProcessLineDiffProps extends LineDiffDecorationTargets {\n deletionLine: string | undefined;\n additionLine: string | undefined;\n lineDiffType: LineDiffTypes;\n maxLineDiffLength: number;\n}\n\n// Push one decoration per side covering the first through last changed\n// token, so each line only has one highlight. Offsets come straight from the\n// diff items, skipping the span arrays the other word modes build.\nfunction pushWordLineDecorations(\n lineDiff: ChangeObject<string>[],\n {\n deletionLineIndex,\n additionLineIndex,\n deletionDecorations,\n additionDecorations,\n }: LineDiffDecorationTargets\n): void {\n let deletionOffset = 0;\n let additionOffset = 0;\n let deletionStart = -1;\n let deletionEnd = 0;\n let additionStart = -1;\n let additionEnd = 0;\n for (const { value, added, removed } of lineDiff) {\n if (removed) {\n if (deletionStart === -1) deletionStart = deletionOffset;\n deletionOffset += value.length;\n deletionEnd = deletionOffset;\n } else if (added) {\n if (additionStart === -1) additionStart = additionOffset;\n additionOffset += value.length;\n additionEnd = additionOffset;\n } else {\n deletionOffset += value.length;\n additionOffset += value.length;\n }\n }\n if (deletionStart !== -1) {\n deletionDecorations.push(\n createDiffSpanDecoration({\n line: deletionLineIndex,\n spanStart: deletionStart,\n spanLength: deletionEnd - deletionStart,\n })\n );\n }\n if (additionStart !== -1) {\n additionDecorations.push(\n createDiffSpanDecoration({\n line: additionLineIndex,\n spanStart: additionStart,\n spanLength: additionEnd - additionStart,\n })\n );\n }\n}\n\nfunction computeLineDiffDecorations({\n deletionLine,\n additionLine,\n deletionLineIndex,\n additionLineIndex,\n deletionDecorations,\n additionDecorations,\n lineDiffType,\n maxLineDiffLength,\n}: ProcessLineDiffProps) {\n if (deletionLine == null || additionLine == null || lineDiffType === 'none') {\n return;\n }\n deletionLine = cleanLastNewline(deletionLine);\n additionLine = cleanLastNewline(additionLine);\n // If we have really long lines, we probably shouldn't compute diffs on them.\n if (\n deletionLine.length > maxLineDiffLength ||\n additionLine.length > maxLineDiffLength\n ) {\n return;\n }\n // NOTE(amadeus): Because we visually trim trailing newlines when rendering,\n // we also gotta make sure the diff parsing doesn't include the newline\n // character that could be there...\n const lineDiff =\n lineDiffType === 'char'\n ? diffChars(deletionLine, additionLine)\n : diffWordsWithSpace(deletionLine, additionLine);\n if (lineDiffType === 'word-line') {\n pushWordLineDecorations(lineDiff, {\n deletionLineIndex,\n additionLineIndex,\n deletionDecorations,\n additionDecorations,\n });\n return;\n }\n const deletionSpans: [0 | 1, string][] = [];\n const additionSpans: [0 | 1, string][] = [];\n const enableJoin = lineDiffType === 'word-alt';\n const lastItem = lineDiff.at(-1);\n for (const item of lineDiff) {\n const isLastItem = item === lastItem;\n if (!item.added && !item.removed) {\n pushOrJoinSpan({\n item,\n arr: deletionSpans,\n enableJoin,\n isNeutral: true,\n isLastItem,\n });\n pushOrJoinSpan({\n item,\n arr: additionSpans,\n enableJoin,\n isNeutral: true,\n isLastItem,\n });\n } else if (item.removed) {\n pushOrJoinSpan({ item, arr: deletionSpans, enableJoin, isLastItem });\n } else {\n pushOrJoinSpan({ item, arr: additionSpans, enableJoin, isLastItem });\n }\n }\n let spanIndex = 0;\n for (const span of deletionSpans) {\n if (span[0] === 1) {\n deletionDecorations.push(\n createDiffSpanDecoration({\n line: deletionLineIndex,\n spanStart: spanIndex,\n spanLength: span[1].length,\n })\n );\n }\n spanIndex += span[1].length;\n }\n spanIndex = 0;\n for (const span of additionSpans) {\n if (span[0] === 1) {\n additionDecorations.push(\n createDiffSpanDecoration({\n line: additionLineIndex,\n spanStart: spanIndex,\n spanLength: span[1].length,\n })\n );\n }\n spanIndex += span[1].length;\n }\n}\n\ninterface HighlightSegment {\n // The where the highlighted region starts\n originalOffset: number;\n // Where to place the highlighted line in RenderDiffFilesResult\n targetIndex: number;\n // Number of highlighted lines\n count: number;\n}\n\ninterface FakeArrayType {\n push(value: string): void;\n value: string;\n length: number;\n}\n\ninterface RenderBucket {\n deletionContent: FakeArrayType;\n additionContent: FakeArrayType;\n deletionInfo: (LineInfo | undefined)[];\n additionInfo: (LineInfo | undefined)[];\n deletionDecorations: DecorationItem[];\n additionDecorations: DecorationItem[];\n deletionSegments: HighlightSegment[];\n additionSegments: HighlightSegment[];\n}\n\nfunction createBucket(): RenderBucket {\n return {\n deletionContent: {\n push(value: string) {\n this.value += value;\n this.length++;\n },\n value: '',\n length: 0,\n },\n additionContent: {\n push(value: string) {\n this.value += value;\n this.length++;\n },\n value: '',\n length: 0,\n },\n deletionInfo: [],\n additionInfo: [],\n deletionDecorations: [],\n additionDecorations: [],\n deletionSegments: [],\n additionSegments: [],\n };\n}\n\ninterface RenderTwoFilesProps {\n deletionFile: FileContents;\n additionFile: FileContents;\n deletionInfo: (LineInfo | undefined)[];\n additionInfo: (LineInfo | undefined)[];\n deletionDecorations: DecorationItem[];\n additionDecorations: DecorationItem[];\n options: RenderDiffOptions;\n highlighter: DiffsHighlighter;\n languageOverride: SupportedLanguages | undefined;\n}\n\nfunction renderTwoFiles({\n deletionFile,\n additionFile,\n deletionInfo,\n additionInfo,\n highlighter,\n deletionDecorations,\n additionDecorations,\n languageOverride,\n options: { theme: themeOrThemes, ...options },\n}: RenderTwoFilesProps): RenderDiffFilesResult {\n const deletionLang =\n languageOverride ?? getFiletypeFromFileName(deletionFile.name);\n const additionLang =\n languageOverride ?? getFiletypeFromFileName(additionFile.name);\n const { state, transformers } = createTransformerWithState(\n options.useTokenTransformer\n );\n // tokenizeTimeLimit: 0 — never trade silently-wrong token colors for\n // latency; see renderFileWithHighlighter for the full rationale.\n const hastConfig: CodeToHastOptions<DiffsThemeNames> = (() => {\n return typeof themeOrThemes === 'string'\n ? {\n ...options,\n // language will be overwritten for each highlight\n lang: 'text',\n theme: themeOrThemes,\n transformers,\n decorations: undefined,\n defaultColor: false,\n cssVariablePrefix: formatCSSVariablePrefix('token'),\n tokenizeTimeLimit: 0,\n }\n : {\n ...options,\n // language will be overwritten for each highlight\n lang: 'text',\n themes: themeOrThemes,\n transformers,\n decorations: undefined,\n defaultColor: false,\n cssVariablePrefix: formatCSSVariablePrefix('token'),\n tokenizeTimeLimit: 0,\n };\n })();\n\n const deletionLines = (() => {\n if (deletionFile.contents === '') {\n return [];\n }\n hastConfig.lang = deletionLang;\n state.lineInfo = deletionInfo;\n hastConfig.decorations = deletionDecorations;\n return getLineNodes(\n highlighter.codeToHast(\n cleanLastNewline(deletionFile.contents),\n hastConfig\n )\n );\n })();\n const additionLines = (() => {\n if (additionFile.contents === '') {\n return [];\n }\n hastConfig.lang = additionLang;\n hastConfig.decorations = additionDecorations;\n state.lineInfo = additionInfo;\n return getLineNodes(\n highlighter.codeToHast(\n cleanLastNewline(additionFile.contents),\n hastConfig\n )\n );\n })();\n\n return { deletionLines, additionLines };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"renderDiffWithHighlighter.js","names":[],"sources":["../../src/utils/renderDiffWithHighlighter.ts"],"sourcesContent":["import { type ChangeObject, diffChars, diffWordsWithSpace } from 'diff';\n\nimport { DEFAULT_COLLAPSED_CONTEXT_THRESHOLD } from '../constants';\nimport type {\n DecorationItem,\n DiffsHighlighter,\n FileContents,\n FileDiffMetadata,\n ForceDiffPlainTextOptions,\n LineDiffTypes,\n LineInfo,\n RenderDiffFilesResult,\n RenderDiffOptions,\n SupportedLanguages,\n ThemedDiffResult,\n} from '../types';\nimport { appendItems } from './appendItems';\nimport { cleanLastNewline } from './cleanLastNewline';\nimport { getFiletypeFromFileName } from './getFiletypeFromFileName';\nimport { getHighlighterThemeStyles } from './getHighlighterThemeStyles';\nimport { getTokenOptions } from './getTokenOptions';\nimport { iterateOverDiff } from './iterateOverDiff';\nimport {\n createDiffSpanDecoration,\n pushOrJoinSpan,\n} from './parseDiffDecorations';\nimport { renderTokenLines } from './renderTokenLines';\nimport { setDeferredArrayItem } from './setDeferredArrayItem';\n\nconst DEFAULT_PLAIN_TEXT_OPTIONS: ForceDiffPlainTextOptions = {\n forcePlainText: false,\n};\n\nexport function renderDiffWithHighlighter(\n diff: FileDiffMetadata,\n highlighter: DiffsHighlighter,\n options: RenderDiffOptions,\n {\n forcePlainText,\n lazyLineAST = false,\n startingLine,\n totalLines,\n expandedHunks,\n collapsedContextThreshold = DEFAULT_COLLAPSED_CONTEXT_THRESHOLD,\n }: ForceDiffPlainTextOptions = DEFAULT_PLAIN_TEXT_OPTIONS\n): ThemedDiffResult {\n if (forcePlainText) {\n startingLine ??= 0;\n totalLines ??= Infinity;\n } else {\n // Tokenization must include preceding lines to preserve lexical state.\n startingLine = 0;\n totalLines = Infinity;\n }\n const isWindowedHighlight = startingLine > 0 || totalLines < Infinity;\n lazyLineAST &&= !forcePlainText && !options.useTokenTransformer;\n const baseThemeType =\n typeof options.theme === 'string'\n ? highlighter.getTheme(options.theme).type\n : undefined;\n const themeStyles = getHighlighterThemeStyles({\n theme: options.theme,\n highlighter,\n });\n\n // If we have a large file and we are rendering the WHOLE plain diff ast,\n // then we should remove the lineDiffType to make sure things render quickly.\n // For highlighted ASTs or windowed highlights, we should just inherit the\n // setting\n const lineDiffType =\n forcePlainText &&\n !isWindowedHighlight &&\n (diff.unifiedLineCount > 1000 || diff.splitLineCount > 1000)\n ? 'none'\n : options.lineDiffType;\n\n const code: RenderDiffFilesResult = {\n deletionLines: [],\n additionLines: [],\n };\n\n const { maxLineDiffLength } = options;\n const shouldGroupAll = !forcePlainText && !diff.isPartial;\n const expandedHunksForIteration = forcePlainText ? expandedHunks : undefined;\n const buckets = new Map<number, RenderBucket>();\n function getBucketForHunk(hunkIndex: number) {\n const index = shouldGroupAll ? 0 : hunkIndex;\n const bucket = buckets.get(index) ?? createBucket();\n buckets.set(index, bucket);\n return bucket;\n }\n\n function appendContent(\n lineContent: string,\n lineIndex: number,\n segments: HighlightSegment[],\n contentWrapper: FakeArrayType\n ) {\n if (isWindowedHighlight) {\n let segment = segments.at(-1);\n if (\n segment == null ||\n segment.targetIndex + segment.count !== lineIndex\n ) {\n segment = {\n targetIndex: lineIndex,\n originalOffset: contentWrapper.length,\n count: 0,\n };\n segments.push(segment);\n }\n segment.count++;\n }\n contentWrapper.push(lineContent);\n }\n\n iterateOverDiff({\n diff,\n diffStyle: 'both',\n startingLine,\n totalLines,\n expandedHunks: isWindowedHighlight ? expandedHunksForIteration : true,\n collapsedContextThreshold,\n callback: ({ hunkIndex, additionLine, deletionLine, type }) => {\n const bucket = getBucketForHunk(hunkIndex);\n const splitLineIndex =\n additionLine != null\n ? additionLine.splitLineIndex\n : deletionLine.splitLineIndex;\n\n if (type === 'change' && additionLine != null && deletionLine != null) {\n computeLineDiffDecorations({\n additionLine: diff.additionLines[additionLine.lineIndex],\n deletionLine: diff.deletionLines[deletionLine.lineIndex],\n deletionLineIndex: bucket.deletionContent.length,\n additionLineIndex: bucket.additionContent.length,\n deletionDecorations: bucket.deletionDecorations,\n additionDecorations: bucket.additionDecorations,\n lineDiffType,\n maxLineDiffLength,\n });\n }\n\n if (deletionLine != null) {\n appendContent(\n diff.deletionLines[deletionLine.lineIndex],\n deletionLine.lineIndex,\n bucket.deletionSegments,\n bucket.deletionContent\n );\n bucket.deletionInfo.push({\n type: type === 'change' ? 'change-deletion' : type,\n lineNumber: deletionLine.lineNumber,\n altLineNumber:\n type === 'change'\n ? undefined\n : (additionLine.lineNumber ?? undefined),\n lineIndex: `${deletionLine.unifiedLineIndex},${splitLineIndex}`,\n });\n }\n\n if (additionLine != null) {\n appendContent(\n diff.additionLines[additionLine.lineIndex],\n additionLine.lineIndex,\n bucket.additionSegments,\n bucket.additionContent\n );\n bucket.additionInfo.push({\n type: type === 'change' ? 'change-addition' : type,\n lineNumber: additionLine.lineNumber,\n altLineNumber:\n type === 'change'\n ? undefined\n : (deletionLine.lineNumber ?? undefined),\n lineIndex: `${additionLine.unifiedLineIndex},${splitLineIndex}`,\n });\n }\n },\n });\n\n for (const bucket of buckets.values()) {\n if (\n bucket.deletionContent.length === 0 &&\n bucket.additionContent.length === 0\n ) {\n continue;\n }\n\n const deletionFile = {\n name: diff.prevName ?? diff.name,\n contents: bucket.deletionContent.value,\n };\n const additionFile = {\n name: diff.name,\n contents: bucket.additionContent.value,\n };\n const { deletionLines, additionLines } = renderTwoFiles({\n deletionFile,\n deletionInfo: bucket.deletionInfo,\n deletionDecorations: bucket.deletionDecorations,\n\n additionFile,\n additionInfo: bucket.additionInfo,\n additionDecorations: bucket.additionDecorations,\n\n highlighter,\n options,\n languageOverride: forcePlainText ? 'text' : diff.lang,\n lazyLineAST,\n });\n\n if (shouldGroupAll) {\n code.deletionLines = deletionLines;\n code.additionLines = additionLines;\n continue;\n }\n\n for (const [target, lines, segments] of [\n [code.deletionLines, deletionLines, bucket.deletionSegments],\n [code.additionLines, additionLines, bucket.additionSegments],\n ] as const) {\n if (segments.length > 0) {\n for (const segment of segments) {\n for (let index = 0; index < segment.count; index++) {\n target[segment.targetIndex + index] =\n lines[segment.originalOffset + index];\n }\n }\n } else if (lazyLineAST) {\n const offset = target.length;\n for (let index = 0; index < lines.length; index++) {\n setDeferredArrayItem(target, offset + index, () => lines[index]);\n }\n } else {\n appendItems(target, lines);\n }\n }\n }\n\n return { code, themeStyles, baseThemeType };\n}\n\n// The line indexes and decoration arrays a line diff writes its highlights to\ninterface LineDiffDecorationTargets {\n deletionLineIndex: number;\n additionLineIndex: number;\n deletionDecorations: DecorationItem[];\n additionDecorations: DecorationItem[];\n}\n\ninterface ProcessLineDiffProps extends LineDiffDecorationTargets {\n deletionLine: string | undefined;\n additionLine: string | undefined;\n lineDiffType: LineDiffTypes;\n maxLineDiffLength: number;\n}\n\n// Push one decoration per side covering the first through last changed\n// token, so each line only has one highlight. Offsets come straight from the\n// diff items, skipping the span arrays the other word modes build.\nfunction pushWordLineDecorations(\n lineDiff: ChangeObject<string>[],\n {\n deletionLineIndex,\n additionLineIndex,\n deletionDecorations,\n additionDecorations,\n }: LineDiffDecorationTargets\n): void {\n let deletionOffset = 0;\n let additionOffset = 0;\n let deletionStart = -1;\n let deletionEnd = 0;\n let additionStart = -1;\n let additionEnd = 0;\n for (const { value, added, removed } of lineDiff) {\n if (removed) {\n if (deletionStart === -1) deletionStart = deletionOffset;\n deletionOffset += value.length;\n deletionEnd = deletionOffset;\n } else if (added) {\n if (additionStart === -1) additionStart = additionOffset;\n additionOffset += value.length;\n additionEnd = additionOffset;\n } else {\n deletionOffset += value.length;\n additionOffset += value.length;\n }\n }\n if (deletionStart !== -1) {\n deletionDecorations.push(\n createDiffSpanDecoration({\n line: deletionLineIndex,\n spanStart: deletionStart,\n spanLength: deletionEnd - deletionStart,\n })\n );\n }\n if (additionStart !== -1) {\n additionDecorations.push(\n createDiffSpanDecoration({\n line: additionLineIndex,\n spanStart: additionStart,\n spanLength: additionEnd - additionStart,\n })\n );\n }\n}\n\nfunction computeLineDiffDecorations({\n deletionLine,\n additionLine,\n deletionLineIndex,\n additionLineIndex,\n deletionDecorations,\n additionDecorations,\n lineDiffType,\n maxLineDiffLength,\n}: ProcessLineDiffProps) {\n if (deletionLine == null || additionLine == null || lineDiffType === 'none') {\n return;\n }\n deletionLine = cleanLastNewline(deletionLine);\n additionLine = cleanLastNewline(additionLine);\n // If we have really long lines, we probably shouldn't compute diffs on them.\n if (\n deletionLine.length > maxLineDiffLength ||\n additionLine.length > maxLineDiffLength\n ) {\n return;\n }\n // NOTE(amadeus): Because we visually trim trailing newlines when rendering,\n // we also gotta make sure the diff parsing doesn't include the newline\n // character that could be there...\n const lineDiff =\n lineDiffType === 'char'\n ? diffChars(deletionLine, additionLine)\n : diffWordsWithSpace(deletionLine, additionLine);\n if (lineDiffType === 'word-line') {\n pushWordLineDecorations(lineDiff, {\n deletionLineIndex,\n additionLineIndex,\n deletionDecorations,\n additionDecorations,\n });\n return;\n }\n const deletionSpans: [0 | 1, string][] = [];\n const additionSpans: [0 | 1, string][] = [];\n const enableJoin = lineDiffType === 'word-alt';\n const lastItem = lineDiff.at(-1);\n for (const item of lineDiff) {\n const isLastItem = item === lastItem;\n if (!item.added && !item.removed) {\n pushOrJoinSpan({\n item,\n arr: deletionSpans,\n enableJoin,\n isNeutral: true,\n isLastItem,\n });\n pushOrJoinSpan({\n item,\n arr: additionSpans,\n enableJoin,\n isNeutral: true,\n isLastItem,\n });\n } else if (item.removed) {\n pushOrJoinSpan({ item, arr: deletionSpans, enableJoin, isLastItem });\n } else {\n pushOrJoinSpan({ item, arr: additionSpans, enableJoin, isLastItem });\n }\n }\n let spanIndex = 0;\n for (const span of deletionSpans) {\n if (span[0] === 1) {\n deletionDecorations.push(\n createDiffSpanDecoration({\n line: deletionLineIndex,\n spanStart: spanIndex,\n spanLength: span[1].length,\n })\n );\n }\n spanIndex += span[1].length;\n }\n spanIndex = 0;\n for (const span of additionSpans) {\n if (span[0] === 1) {\n additionDecorations.push(\n createDiffSpanDecoration({\n line: additionLineIndex,\n spanStart: spanIndex,\n spanLength: span[1].length,\n })\n );\n }\n spanIndex += span[1].length;\n }\n}\n\ninterface HighlightSegment {\n // The where the highlighted region starts\n originalOffset: number;\n // Where to place the highlighted line in RenderDiffFilesResult\n targetIndex: number;\n // Number of highlighted lines\n count: number;\n}\n\ninterface FakeArrayType {\n push(value: string): void;\n value: string;\n length: number;\n}\n\ninterface RenderBucket {\n deletionContent: FakeArrayType;\n additionContent: FakeArrayType;\n deletionInfo: (LineInfo | undefined)[];\n additionInfo: (LineInfo | undefined)[];\n deletionDecorations: DecorationItem[];\n additionDecorations: DecorationItem[];\n deletionSegments: HighlightSegment[];\n additionSegments: HighlightSegment[];\n}\n\nfunction createBucket(): RenderBucket {\n return {\n deletionContent: {\n push(value: string) {\n this.value += value;\n this.length++;\n },\n value: '',\n length: 0,\n },\n additionContent: {\n push(value: string) {\n this.value += value;\n this.length++;\n },\n value: '',\n length: 0,\n },\n deletionInfo: [],\n additionInfo: [],\n deletionDecorations: [],\n additionDecorations: [],\n deletionSegments: [],\n additionSegments: [],\n };\n}\n\ninterface RenderTwoFilesProps {\n lazyLineAST: boolean;\n deletionFile: FileContents;\n additionFile: FileContents;\n deletionInfo: (LineInfo | undefined)[];\n additionInfo: (LineInfo | undefined)[];\n deletionDecorations: DecorationItem[];\n additionDecorations: DecorationItem[];\n options: RenderDiffOptions;\n highlighter: DiffsHighlighter;\n languageOverride: SupportedLanguages | undefined;\n}\n\nfunction renderTwoFiles({\n lazyLineAST,\n deletionFile,\n additionFile,\n deletionInfo,\n additionInfo,\n highlighter,\n deletionDecorations,\n additionDecorations,\n languageOverride,\n options: { theme, useTokenTransformer, tokenizeMaxLineLength },\n}: RenderTwoFilesProps): RenderDiffFilesResult {\n const renderFile = (\n file: FileContents,\n lineInfo: (LineInfo | undefined)[],\n decorations: DecorationItem[]\n ): RenderDiffFilesResult['additionLines'] => {\n if (file.contents === '') return [];\n return renderTokenLines(\n highlighter.codeToTokens(\n cleanLastNewline(file.contents),\n getTokenOptions(\n languageOverride ?? getFiletypeFromFileName(file.name),\n theme,\n tokenizeMaxLineLength\n )\n ).tokens,\n {\n state: { lineInfo },\n useTokenTransformer,\n decorations,\n lazyLineAST,\n cacheHtmlStyles: highlighter.name === 'highlights',\n }\n );\n };\n\n return {\n deletionLines: renderFile(deletionFile, deletionInfo, deletionDecorations),\n additionLines: renderFile(additionFile, additionInfo, additionDecorations),\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { DiffsHighlighter
|
|
1
|
+
import { DiffsHighlighter } from "../highlighter/DiffsHighlighter.js";
|
|
2
|
+
import { FileContents, ForceFilePlainTextOptions, RenderFileOptions, ThemedFileResult } from "../types.js";
|
|
2
3
|
//#region src/utils/renderFileWithHighlighter.d.ts
|
|
3
|
-
declare function renderFileWithHighlighter(file: FileContents, highlighter: DiffsHighlighter, { theme, tokenizeMaxLineLength, useTokenTransformer }: RenderFileOptions, { forcePlainText, startingLine, totalLines, lines }?: ForceFilePlainTextOptions): ThemedFileResult;
|
|
4
|
+
declare function renderFileWithHighlighter(file: FileContents, highlighter: DiffsHighlighter, { theme, tokenizeMaxLineLength, useTokenTransformer }: RenderFileOptions, { forcePlainText, lazyLineAST, startingLine, totalLines, lines }?: ForceFilePlainTextOptions): ThemedFileResult;
|
|
4
5
|
//#endregion
|
|
5
6
|
export { renderFileWithHighlighter };
|
|
6
7
|
//# sourceMappingURL=renderFileWithHighlighter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderFileWithHighlighter.d.ts","names":[],"sources":["../../src/utils/renderFileWithHighlighter.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"renderFileWithHighlighter.d.ts","names":[],"sources":["../../src/utils/renderFileWithHighlighter.ts"],"mappings":";;;iBAmBgB,0BACd,MAAM,cACN,aAAa,oBACX,OAAO,uBAAuB,uBAAuB,qBAErD,gBACA,aACA,cACA,YACA,UACC,4BACF"}
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { linesFromFileContents } from "./computeFileOffsets.js";
|
|
2
2
|
import { getFiletypeFromFileName } from "./getFiletypeFromFileName.js";
|
|
3
3
|
import { appendItems } from "./appendItems.js";
|
|
4
|
-
import { createTransformerWithState } from "./createTransformerWithState.js";
|
|
5
|
-
import { formatCSSVariablePrefix } from "./formatCSSVariablePrefix.js";
|
|
6
4
|
import { getHighlighterThemeStyles } from "./getHighlighterThemeStyles.js";
|
|
7
|
-
import {
|
|
5
|
+
import { getTokenOptions } from "./getTokenOptions.js";
|
|
6
|
+
import { renderTokenLines } from "./renderTokenLines.js";
|
|
8
7
|
//#region src/utils/renderFileWithHighlighter.ts
|
|
9
8
|
const DEFAULT_PLAIN_TEXT_OPTIONS = { forcePlainText: false };
|
|
10
|
-
function renderFileWithHighlighter(file, highlighter, { theme, tokenizeMaxLineLength, useTokenTransformer }, { forcePlainText, startingLine, totalLines, lines } = DEFAULT_PLAIN_TEXT_OPTIONS) {
|
|
9
|
+
function renderFileWithHighlighter(file, highlighter, { theme, tokenizeMaxLineLength, useTokenTransformer }, { forcePlainText, lazyLineAST = false, startingLine, totalLines, lines } = DEFAULT_PLAIN_TEXT_OPTIONS) {
|
|
11
10
|
if (forcePlainText) {
|
|
12
11
|
startingLine ??= 0;
|
|
13
12
|
totalLines ??= Infinity;
|
|
@@ -16,7 +15,7 @@ function renderFileWithHighlighter(file, highlighter, { theme, tokenizeMaxLineLe
|
|
|
16
15
|
totalLines = Infinity;
|
|
17
16
|
}
|
|
18
17
|
const isWindowedHighlight = startingLine > 0 || totalLines < Infinity;
|
|
19
|
-
const {
|
|
18
|
+
const state = { lineInfo: [] };
|
|
20
19
|
const lang = forcePlainText ? "text" : file.lang ?? getFiletypeFromFileName(file.name);
|
|
21
20
|
const baseThemeType = typeof theme === "string" ? highlighter.getTheme(theme).type : void 0;
|
|
22
21
|
const themeStyles = getHighlighterThemeStyles({
|
|
@@ -28,27 +27,12 @@ function renderFileWithHighlighter(file, highlighter, { theme, tokenizeMaxLineLe
|
|
|
28
27
|
lineIndex: shikiLineNumber - 1 + startingLine,
|
|
29
28
|
lineNumber: shikiLineNumber + startingLine
|
|
30
29
|
});
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
cssVariablePrefix: formatCSSVariablePrefix("token"),
|
|
38
|
-
tokenizeMaxLineLength,
|
|
39
|
-
tokenizeTimeLimit: 0
|
|
40
|
-
};
|
|
41
|
-
return {
|
|
42
|
-
lang,
|
|
43
|
-
themes: theme,
|
|
44
|
-
transformers,
|
|
45
|
-
defaultColor: false,
|
|
46
|
-
cssVariablePrefix: formatCSSVariablePrefix("token"),
|
|
47
|
-
tokenizeMaxLineLength,
|
|
48
|
-
tokenizeTimeLimit: 0
|
|
49
|
-
};
|
|
50
|
-
})();
|
|
51
|
-
const highlightedLines = getLineNodes(highlighter.codeToHast(normalizeHighlightLineEndings(isWindowedHighlight ? extractWindowedFileContent(lines ?? linesFromFileContents(file.contents), startingLine, totalLines) : file.contents), hastConfig));
|
|
30
|
+
const highlightedLines = renderTokenLines(highlighter.codeToTokens(normalizeHighlightLineEndings(isWindowedHighlight ? extractWindowedFileContent(lines ?? linesFromFileContents(file.contents), startingLine, totalLines) : file.contents), getTokenOptions(lang, theme, tokenizeMaxLineLength)).tokens, {
|
|
31
|
+
state,
|
|
32
|
+
useTokenTransformer,
|
|
33
|
+
lazyLineAST: lazyLineAST && !forcePlainText && !useTokenTransformer,
|
|
34
|
+
cacheHtmlStyles: highlighter.name === "highlights"
|
|
35
|
+
});
|
|
52
36
|
const code = isWindowedHighlight ? new Array(startingLine) : highlightedLines;
|
|
53
37
|
if (isWindowedHighlight) appendItems(code, highlightedLines);
|
|
54
38
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderFileWithHighlighter.js","names":[],"sources":["../../src/utils/renderFileWithHighlighter.ts"],"sourcesContent":["import type {\n
|
|
1
|
+
{"version":3,"file":"renderFileWithHighlighter.js","names":[],"sources":["../../src/utils/renderFileWithHighlighter.ts"],"sourcesContent":["import type {\n DiffsHighlighter,\n FileContents,\n ForceFilePlainTextOptions,\n RenderFileOptions,\n SharedRenderState,\n ThemedFileResult,\n} from '../types';\nimport { appendItems } from './appendItems';\nimport { linesFromFileContents } from './computeFileOffsets';\nimport { getFiletypeFromFileName } from './getFiletypeFromFileName';\nimport { getHighlighterThemeStyles } from './getHighlighterThemeStyles';\nimport { getTokenOptions } from './getTokenOptions';\nimport { renderTokenLines } from './renderTokenLines';\n\nconst DEFAULT_PLAIN_TEXT_OPTIONS: ForceFilePlainTextOptions = {\n forcePlainText: false,\n};\n\nexport function renderFileWithHighlighter(\n file: FileContents,\n highlighter: DiffsHighlighter,\n { theme, tokenizeMaxLineLength, useTokenTransformer }: RenderFileOptions,\n {\n forcePlainText,\n lazyLineAST = false,\n startingLine,\n totalLines,\n lines,\n }: ForceFilePlainTextOptions = DEFAULT_PLAIN_TEXT_OPTIONS\n): ThemedFileResult {\n if (forcePlainText) {\n startingLine ??= 0;\n totalLines ??= Infinity;\n } else {\n // Tokenization must include preceding lines to preserve lexical state.\n startingLine = 0;\n totalLines = Infinity;\n }\n const isWindowedHighlight = startingLine > 0 || totalLines < Infinity;\n const state: SharedRenderState = { lineInfo: [] };\n const lang = forcePlainText\n ? 'text'\n : (file.lang ?? getFiletypeFromFileName(file.name));\n const baseThemeType =\n typeof theme === 'string' ? highlighter.getTheme(theme).type : undefined;\n const themeStyles = getHighlighterThemeStyles({\n theme,\n highlighter,\n });\n state.lineInfo = (shikiLineNumber: number) => ({\n type: 'context',\n lineIndex: shikiLineNumber - 1 + startingLine,\n lineNumber: shikiLineNumber + startingLine,\n });\n const highlightedLines = renderTokenLines(\n highlighter.codeToTokens(\n normalizeHighlightLineEndings(\n isWindowedHighlight\n ? extractWindowedFileContent(\n lines ?? linesFromFileContents(file.contents),\n startingLine,\n totalLines\n )\n : file.contents\n ),\n getTokenOptions(lang, theme, tokenizeMaxLineLength)\n ).tokens,\n {\n state,\n useTokenTransformer,\n lazyLineAST: lazyLineAST && !forcePlainText && !useTokenTransformer,\n cacheHtmlStyles: highlighter.name === 'highlights',\n }\n );\n\n // Create sparse array for windowed rendering\n const code = isWindowedHighlight ? new Array(startingLine) : highlightedLines;\n if (isWindowedHighlight) {\n appendItems(code, highlightedLines);\n }\n\n return { code, themeStyles, baseThemeType };\n}\n\n// Shiki does not treat a lone carriage return as a line break. Normalize only\n// the text sent to the highlighter so its output stays aligned with the file\n// model while the original document retains its line endings.\nfunction normalizeHighlightLineEndings(contents: string): string {\n return contents.replace(/\\r(?!\\n)/g, '\\n');\n}\n\nfunction extractWindowedFileContent(\n lines: string[],\n startingLine: number,\n totalLines: number\n): string {\n if (lines.length === 0) {\n return '';\n }\n const endLine = Math.min(startingLine + totalLines, lines.length);\n return lines.slice(startingLine, endLine).join('');\n}\n"],"mappings":";;;;;;;AAeA,MAAM,6BAAwD,EAC5D,gBAAgB,MAClB;AAEA,SAAgB,0BACd,MACA,aACA,EAAE,OAAO,uBAAuB,uBAChC,EACE,gBACA,cAAc,OACd,cACA,YACA,UAC6B,4BACb;CAClB,IAAI,gBAAgB;EAClB,iBAAiB;EACjB,eAAe;CACjB,OAAO;EAEL,eAAe;EACf,aAAa;CACf;CACA,MAAM,sBAAsB,eAAe,KAAK,aAAa;CAC7D,MAAM,QAA2B,EAAE,UAAU,CAAC,EAAE;CAChD,MAAM,OAAO,iBACT,SACC,KAAK,QAAQ,wBAAwB,KAAK,IAAI;CACnD,MAAM,gBACJ,OAAO,UAAU,WAAW,YAAY,SAAS,KAAK,CAAC,CAAC,OAAO,KAAA;CACjE,MAAM,cAAc,0BAA0B;EAC5C;EACA;CACF,CAAC;CACD,MAAM,YAAY,qBAA6B;EAC7C,MAAM;EACN,WAAW,kBAAkB,IAAI;EACjC,YAAY,kBAAkB;CAChC;CACA,MAAM,mBAAmB,iBACvB,YAAY,aACV,8BACE,sBACI,2BACE,SAAS,sBAAsB,KAAK,QAAQ,GAC5C,cACA,UACF,IACA,KAAK,QACX,GACA,gBAAgB,MAAM,OAAO,qBAAqB,CACpD,CAAC,CAAC,QACF;EACE;EACA;EACA,aAAa,eAAe,CAAC,kBAAkB,CAAC;EAChD,iBAAiB,YAAY,SAAS;CACxC,CACF;CAGA,MAAM,OAAO,sBAAsB,IAAI,MAAM,YAAY,IAAI;CAC7D,IAAI,qBACF,YAAY,MAAM,gBAAgB;CAGpC,OAAO;EAAE;EAAM;EAAa;CAAc;AAC5C;AAKA,SAAS,8BAA8B,UAA0B;CAC/D,OAAO,SAAS,QAAQ,aAAa,IAAI;AAC3C;AAEA,SAAS,2BACP,OACA,cACA,YACQ;CACR,IAAI,MAAM,WAAW,GACnB,OAAO;CAET,MAAM,UAAU,KAAK,IAAI,eAAe,YAAY,MAAM,MAAM;CAChE,OAAO,MAAM,MAAM,cAAc,OAAO,CAAC,CAAC,KAAK,EAAE;AACnD"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ElementContent } from "../node_modules/.pnpm/@types_hast@3.0.4/node_modules/@types/hast/index.js";
|
|
2
|
+
import { DecorationItem, ThemedToken } from "../highlighter/types.js";
|
|
3
|
+
import { SharedRenderState } from "../types.js";
|
|
4
|
+
//#region src/utils/renderTokenLines.d.ts
|
|
5
|
+
interface RenderTokenLinesOptions {
|
|
6
|
+
lazyLineAST?: boolean;
|
|
7
|
+
cacheHtmlStyles?: boolean;
|
|
8
|
+
state?: SharedRenderState;
|
|
9
|
+
useTokenTransformer?: boolean;
|
|
10
|
+
mergeWhitespaces?: 'never' | 'always';
|
|
11
|
+
decorations?: DecorationItem[];
|
|
12
|
+
lineOffsets?: number[];
|
|
13
|
+
}
|
|
14
|
+
declare function renderTokenLines(lines: ThemedToken[][], { state, lazyLineAST, cacheHtmlStyles, useTokenTransformer, mergeWhitespaces, decorations, lineOffsets }: RenderTokenLinesOptions): ElementContent[];
|
|
15
|
+
//#endregion
|
|
16
|
+
export { renderTokenLines };
|
|
17
|
+
//# sourceMappingURL=renderTokenLines.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderTokenLines.d.ts","names":[],"sources":["../../src/utils/renderTokenLines.ts"],"mappings":";;;;UAQU;EACR;EACA;EACA,QAAQ;EACR;EACA;EACA,cAAc;EACd;;iBAsBc,iBACd,OAAO,mBAEL,OACA,aACA,iBACA,qBACA,kBACA,aACA,eACC,0BACF"}
|