@pierre/diffs 1.2.6 → 1.3.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/dist/components/CodeView.d.ts +0 -1
- package/dist/components/CodeView.d.ts.map +1 -1
- package/dist/components/CodeView.js +0 -23
- package/dist/components/CodeView.js.map +1 -1
- package/dist/components/File.d.ts +7 -2
- package/dist/components/File.d.ts.map +1 -1
- package/dist/components/File.js +36 -2
- package/dist/components/File.js.map +1 -1
- package/dist/components/FileDiff.d.ts +8 -2
- package/dist/components/FileDiff.d.ts.map +1 -1
- package/dist/components/FileDiff.js +73 -1
- package/dist/components/FileDiff.js.map +1 -1
- package/dist/components/UnresolvedFile.d.ts.map +1 -1
- package/dist/components/UnresolvedFile.js +2 -2
- package/dist/components/VirtualizedFile.d.ts +2 -1
- package/dist/components/VirtualizedFile.d.ts.map +1 -1
- package/dist/components/VirtualizedFile.js +48 -48
- package/dist/components/VirtualizedFile.js.map +1 -1
- package/dist/components/VirtualizedFileDiff.js +42 -22
- package/dist/components/VirtualizedFileDiff.js.map +1 -1
- package/dist/components/Virtualizer.d.ts +1 -1
- package/dist/components/Virtualizer.d.ts.map +1 -1
- package/dist/components/Virtualizer.js +3 -5
- package/dist/components/Virtualizer.js.map +1 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/editor/command.d.ts +6 -0
- package/dist/editor/command.d.ts.map +1 -0
- package/dist/editor/command.js +31 -0
- package/dist/editor/command.js.map +1 -0
- package/dist/editor/css.d.ts +6 -0
- package/dist/editor/css.d.ts.map +1 -0
- package/dist/editor/css.js +218 -0
- package/dist/editor/css.js.map +1 -0
- package/dist/editor/editStack.d.ts +66 -0
- package/dist/editor/editStack.d.ts.map +1 -0
- package/dist/editor/editStack.js +218 -0
- package/dist/editor/editStack.js.map +1 -0
- package/dist/editor/editor.d.ts +22 -0
- package/dist/editor/editor.d.ts.map +1 -0
- package/dist/editor/editor.js +1323 -0
- package/dist/editor/editor.js.map +1 -0
- package/dist/editor/index.d.ts +3 -0
- package/dist/editor/index.js +4 -0
- package/dist/editor/lineAnnotations.d.ts +8 -0
- package/dist/editor/lineAnnotations.d.ts.map +1 -0
- package/dist/editor/lineAnnotations.js +32 -0
- package/dist/editor/lineAnnotations.js.map +1 -0
- package/dist/editor/pieceTable.d.ts +33 -0
- package/dist/editor/pieceTable.d.ts.map +1 -0
- package/dist/editor/pieceTable.js +590 -0
- package/dist/editor/pieceTable.js.map +1 -0
- package/dist/editor/platform.d.ts +12 -0
- package/dist/editor/platform.d.ts.map +1 -0
- package/dist/editor/platform.js +44 -0
- package/dist/editor/platform.js.map +1 -0
- package/dist/editor/quickEdit.d.ts +29 -0
- package/dist/editor/quickEdit.d.ts.map +1 -0
- package/dist/editor/quickEdit.js +81 -0
- package/dist/editor/quickEdit.js.map +1 -0
- package/dist/editor/searchPanel.d.ts +30 -0
- package/dist/editor/searchPanel.d.ts.map +1 -0
- package/dist/editor/searchPanel.js +219 -0
- package/dist/editor/searchPanel.js.map +1 -0
- package/dist/editor/selection.d.ts +126 -0
- package/dist/editor/selection.d.ts.map +1 -0
- package/dist/editor/selection.js +900 -0
- package/dist/editor/selection.js.map +1 -0
- package/dist/editor/textDocument.d.ts +139 -0
- package/dist/editor/textDocument.d.ts.map +1 -0
- package/dist/editor/textDocument.js +202 -0
- package/dist/editor/textDocument.js.map +1 -0
- package/dist/editor/textMeasure.d.ts +32 -0
- package/dist/editor/textMeasure.d.ts.map +1 -0
- package/dist/editor/textMeasure.js +108 -0
- package/dist/editor/textMeasure.js.map +1 -0
- package/dist/editor/tokenzier.d.ts +37 -0
- package/dist/editor/tokenzier.d.ts.map +1 -0
- package/dist/editor/tokenzier.js +348 -0
- package/dist/editor/tokenzier.js.map +1 -0
- package/dist/editor/utils.d.ts +16 -0
- package/dist/editor/utils.d.ts.map +1 -0
- package/dist/editor/utils.js +37 -0
- package/dist/editor/utils.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/react/EditorContext.d.ts +16 -0
- package/dist/react/EditorContext.d.ts.map +1 -0
- package/dist/react/EditorContext.js +26 -0
- package/dist/react/EditorContext.js.map +1 -0
- package/dist/react/File.d.ts +2 -1
- package/dist/react/File.d.ts.map +1 -1
- package/dist/react/File.js +3 -2
- package/dist/react/File.js.map +1 -1
- package/dist/react/FileDiff.d.ts +3 -1
- package/dist/react/FileDiff.d.ts.map +1 -1
- package/dist/react/FileDiff.js +3 -2
- package/dist/react/FileDiff.js.map +1 -1
- package/dist/react/MultiFileDiff.d.ts +3 -1
- package/dist/react/MultiFileDiff.d.ts.map +1 -1
- package/dist/react/MultiFileDiff.js +3 -2
- package/dist/react/MultiFileDiff.js.map +1 -1
- package/dist/react/PatchDiff.d.ts +3 -1
- package/dist/react/PatchDiff.d.ts.map +1 -1
- package/dist/react/PatchDiff.js +3 -2
- package/dist/react/PatchDiff.js.map +1 -1
- package/dist/react/index.d.ts +3 -2
- package/dist/react/index.js +2 -1
- package/dist/react/jsx.d.ts +0 -1
- package/dist/react/jsx.d.ts.map +1 -1
- package/dist/react/types.d.ts +1 -0
- package/dist/react/types.d.ts.map +1 -1
- package/dist/react/types.js +0 -1
- package/dist/react/utils/useFileDiffInstance.d.ts +3 -1
- package/dist/react/utils/useFileDiffInstance.d.ts.map +1 -1
- package/dist/react/utils/useFileDiffInstance.js +31 -5
- package/dist/react/utils/useFileDiffInstance.js.map +1 -1
- package/dist/react/utils/useFileInstance.d.ts +4 -1
- package/dist/react/utils/useFileInstance.d.ts.map +1 -1
- package/dist/react/utils/useFileInstance.js +30 -5
- package/dist/react/utils/useFileInstance.js.map +1 -1
- package/dist/renderers/DiffHunksRenderer.d.ts +2 -2
- package/dist/renderers/DiffHunksRenderer.d.ts.map +1 -1
- package/dist/renderers/DiffHunksRenderer.js +9 -5
- package/dist/renderers/DiffHunksRenderer.js.map +1 -1
- package/dist/renderers/FileRenderer.d.ts +5 -1
- package/dist/renderers/FileRenderer.d.ts.map +1 -1
- package/dist/renderers/FileRenderer.js +108 -41
- package/dist/renderers/FileRenderer.js.map +1 -1
- package/dist/ssr/index.d.ts +2 -2
- package/dist/style.js +1 -1
- package/dist/style.js.map +1 -1
- package/dist/types.d.ts +45 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/cleanLastNewline.js +6 -1
- package/dist/utils/cleanLastNewline.js.map +1 -1
- package/dist/utils/computeEstimatedDiffHeights.js +20 -9
- package/dist/utils/computeEstimatedDiffHeights.js.map +1 -1
- package/dist/utils/computeFileOffsets.d.ts +13 -0
- package/dist/utils/computeFileOffsets.d.ts.map +1 -0
- package/dist/utils/computeFileOffsets.js +33 -0
- package/dist/utils/computeFileOffsets.js.map +1 -0
- package/dist/utils/createTransformerWithState.js +9 -0
- package/dist/utils/createTransformerWithState.js.map +1 -1
- package/dist/utils/iterateOverDiff.js +182 -147
- package/dist/utils/iterateOverDiff.js.map +1 -1
- package/dist/utils/renderDiffWithHighlighter.js +1 -1
- package/dist/utils/renderFileWithHighlighter.js +5 -14
- package/dist/utils/renderFileWithHighlighter.js.map +1 -1
- package/dist/utils/virtualDiffLayout.d.ts +2 -23
- package/dist/utils/virtualDiffLayout.d.ts.map +1 -1
- package/dist/utils/virtualDiffLayout.js +1 -41
- package/dist/utils/virtualDiffLayout.js.map +1 -1
- package/dist/worker/WorkerPoolManager.js +1 -1
- package/dist/worker/{wasm-BaDzIkIn.js → wasm-D4DU5jgR.js} +2 -2
- package/dist/worker/wasm-D4DU5jgR.js.map +1 -0
- package/dist/worker/worker-portable.js +349 -363
- package/dist/worker/worker-portable.js.map +1 -1
- package/dist/worker/worker.js +222 -243
- package/dist/worker/worker.js.map +1 -1
- package/package.json +9 -1
- package/dist/utils/iterateOverFile.d.ts +0 -50
- package/dist/utils/iterateOverFile.d.ts.map +0 -1
- package/dist/utils/iterateOverFile.js +0 -49
- package/dist/utils/iterateOverFile.js.map +0 -1
- package/dist/worker/wasm-BaDzIkIn.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DiffHunksRenderer.js","names":["options: DiffHunksRendererOptions","onRenderUpdate?: () => unknown","workerManager?: WorkerPoolManager | undefined","createDefaultAnnotationElement","options: RenderDiffOptions","options","additionsContentAST: ElementContent[] | undefined","deletionsContentAST: ElementContent[] | undefined","unifiedContentAST: ElementContent[] | undefined","hunkData: HunkData[]","context: ProcessContext","pendingSplitContext: PendingSplitContext","renderedLineContext: RenderedLineContext","deletionSpan: AnnotationSpan","additionSpan: AnnotationSpan","createAnnotationElement"],"sources":["../../src/renderers/DiffHunksRenderer.ts"],"sourcesContent":["import type { ElementContent, Element as HASTElement, Properties } from 'hast';\nimport { toHtml } from 'hast-util-to-html';\n\nimport {\n DEFAULT_COLLAPSED_CONTEXT_THRESHOLD,\n DEFAULT_EXPANDED_REGION,\n DEFAULT_RENDER_RANGE,\n DEFAULT_THEMES,\n DEFAULT_TOKENIZE_MAX_LENGTH,\n} from '../constants';\nimport { areLanguagesAttached } from '../highlighter/languages/areLanguagesAttached';\nimport {\n getHighlighterIfLoaded,\n getSharedHighlighter,\n} from '../highlighter/shared_highlighter';\nimport { areThemesAttached } from '../highlighter/themes/areThemesAttached';\nimport type {\n AnnotationLineMap,\n AnnotationSpan,\n BaseDiffOptions,\n BaseDiffOptionsWithDefaults,\n CodeColumnType,\n CustomPreProperties,\n DiffLineAnnotation,\n DiffsHighlighter,\n ExpansionDirections,\n FileDiffMetadata,\n FileHeaderRenderMode,\n HunkData,\n HunkExpansionRegion,\n HunkSeparators,\n LineTypes,\n RenderDiffOptions,\n RenderDiffResult,\n RenderedDiffASTCache,\n RenderRange,\n SupportedLanguages,\n ThemedDiffResult,\n} from '../types';\nimport { areDiffRenderOptionsEqual } from '../utils/areDiffRenderOptionsEqual';\nimport { areDiffTargetsEqual } from '../utils/areDiffTargetsEqual';\nimport { areRenderRangesEqual } from '../utils/areRenderRangesEqual';\nimport { createAnnotationElement as createDefaultAnnotationElement } from '../utils/createAnnotationElement';\nimport { createContentColumn } from '../utils/createContentColumn';\nimport { createEmptyRowBuffer } from '../utils/createEmptyRowBuffer';\nimport { createFileHeaderElement } from '../utils/createFileHeaderElement';\nimport { createNoNewlineElement } from '../utils/createNoNewlineElement';\nimport { createPreElement } from '../utils/createPreElement';\nimport { createSeparator } from '../utils/createSeparator';\nimport { getFiletypeFromFileName } from '../utils/getFiletypeFromFileName';\nimport { getHighlighterOptions } from '../utils/getHighlighterOptions';\nimport { getHunkSeparatorSlotName } from '../utils/getHunkSeparatorSlotName';\nimport { getLineAnnotationName } from '../utils/getLineAnnotationName';\nimport { getTotalLineCountFromHunks } from '../utils/getTotalLineCountFromHunks';\nimport {\n createGutterGap,\n createGutterItem,\n createGutterWrapper,\n createHastElement,\n} from '../utils/hast_utils';\nimport { isDefaultRenderRange } from '../utils/isDefaultRenderRange';\nimport { isDiffPlainText } from '../utils/isDiffPlainText';\nimport type { DiffLineMetadata } from '../utils/iterateOverDiff';\nimport { iterateOverDiff } from '../utils/iterateOverDiff';\nimport { renderDiffWithHighlighter } from '../utils/renderDiffWithHighlighter';\nimport { shouldUseTokenTransformer } from '../utils/shouldUseTokenTransformer';\nimport { getTrailingContextRangeSize } from '../utils/virtualDiffLayout';\nimport type { WorkerPoolManager } from '../worker';\n\ninterface PushLineWithAnnotation {\n diffStyle: 'unified' | 'split';\n type: 'context' | 'context-expanded' | 'change';\n\n deletionLine?: ElementContent;\n additionLine?: ElementContent;\n\n unifiedSpan?: AnnotationSpan;\n deletionSpan?: AnnotationSpan;\n additionSpan?: AnnotationSpan;\n\n createAnnotationElement(span: AnnotationSpan): HASTElement;\n context: ProcessContext;\n}\n\ninterface GetRenderOptionsReturn {\n options: RenderDiffOptions;\n forceHighlight: boolean;\n}\n\ninterface PushSeparatorProps {\n hunkIndex: number;\n collapsedLines: number;\n rangeSize: number;\n hunkSpecs: string | undefined;\n isFirstHunk: boolean;\n isLastHunk: boolean;\n isExpandable: boolean;\n}\n\ninterface ProcessContext {\n rowCount: number;\n expansionLineCount: number;\n hunkSeparators: HunkSeparators;\n unifiedContentAST: ElementContent[];\n deletionsContentAST: ElementContent[];\n additionsContentAST: ElementContent[];\n unifiedGutterAST: HASTElement;\n deletionsGutterAST: HASTElement;\n additionsGutterAST: HASTElement;\n hunkData: HunkData[];\n pushToGutter(type: CodeColumnType, element: HASTElement): void;\n incrementRowCount(count?: number): void;\n}\n\nexport interface DiffHunksRendererOptions extends BaseDiffOptions {\n headerRenderMode?: FileHeaderRenderMode;\n}\n\nexport interface DiffHunksRendererOptionsWithDefaults extends Omit<\n BaseDiffOptionsWithDefaults,\n 'themeType'\n> {\n headerRenderMode: FileHeaderRenderMode;\n}\n\nexport interface UnifiedLineDecorationProps {\n type: 'context' | 'context-expanded' | 'change';\n lineType: LineTypes;\n additionLineIndex: number | undefined;\n deletionLineIndex: number | undefined;\n}\n\nexport interface SplitLineDecorationProps {\n side: 'deletions' | 'additions';\n type: 'context' | 'context-expanded' | 'change';\n lineIndex: number | undefined;\n}\n\nexport interface LineDecoration {\n gutterLineType: LineTypes;\n gutterProperties?: Properties;\n contentProperties?: Properties;\n}\n\ninterface PendingSplitContext {\n size: number;\n side: 'additions' | 'deletions' | undefined;\n increment(): void;\n flush(): void;\n}\n\nexport interface RenderedLineContext {\n type: 'context' | 'context-expanded' | 'change';\n hunkIndex: number;\n lineIndex: number;\n unifiedLineIndex: number;\n splitLineIndex: number;\n deletionLine?: DiffLineMetadata;\n additionLine?: DiffLineMetadata;\n}\n\nexport interface InjectedRow {\n content: HASTElement;\n gutter: HASTElement;\n}\n\nexport interface SplitInjectedRow {\n deletion: InjectedRow | undefined;\n addition: InjectedRow | undefined;\n}\n\nexport interface UnifiedInjectedRowPlacement {\n before?: InjectedRow[];\n after?: InjectedRow[];\n}\n\nexport interface SplitInjectedRowPlacement {\n before?: SplitInjectedRow[];\n after?: SplitInjectedRow[];\n}\n\nexport interface HunksRenderResult {\n unifiedGutterAST: ElementContent[] | undefined;\n unifiedContentAST: ElementContent[] | undefined;\n deletionsGutterAST: ElementContent[] | undefined;\n deletionsContentAST: ElementContent[] | undefined;\n additionsGutterAST: ElementContent[] | undefined;\n additionsContentAST: ElementContent[] | undefined;\n hunkData: HunkData[];\n css: string;\n preNode: HASTElement;\n headerElement: HASTElement | undefined;\n totalLines: number;\n themeStyles: string;\n baseThemeType: 'light' | 'dark' | undefined;\n rowCount: number;\n bufferBefore: number;\n bufferAfter: number;\n}\n\nlet instanceId = -1;\n\nexport class DiffHunksRenderer<LAnnotation = undefined> {\n readonly __id: string = `diff-hunks-renderer:${++instanceId}`;\n\n private highlighter: DiffsHighlighter | undefined;\n private diff: FileDiffMetadata | undefined;\n\n private expandedHunks = new Map<number, HunkExpansionRegion>();\n\n private deletionAnnotations: AnnotationLineMap<LAnnotation> = {};\n private additionAnnotations: AnnotationLineMap<LAnnotation> = {};\n\n private computedLang: SupportedLanguages = 'text';\n private renderCache: RenderedDiffASTCache | undefined;\n\n constructor(\n public options: DiffHunksRendererOptions = { theme: DEFAULT_THEMES },\n private onRenderUpdate?: () => unknown,\n private workerManager?: WorkerPoolManager | undefined\n ) {\n if (workerManager?.isWorkingPool() !== true) {\n this.highlighter = areThemesAttached(options.theme ?? DEFAULT_THEMES)\n ? getHighlighterIfLoaded()\n : undefined;\n }\n }\n\n public cleanUp(): void {\n this.recycle();\n this.expandedHunks.clear();\n this.workerManager = undefined;\n this.onRenderUpdate = undefined;\n }\n\n public recycle(): void {\n this.highlighter = undefined;\n this.diff = undefined;\n this.clearRenderCache();\n this.additionAnnotations = {};\n this.deletionAnnotations = {};\n this.workerManager?.cleanUpTasks(this);\n }\n\n public clearRenderCache(): void {\n this.renderCache = undefined;\n }\n\n public setOptions(options: DiffHunksRendererOptions): void {\n this.options = options;\n }\n\n public mergeOptions(options: Partial<DiffHunksRendererOptions>): void {\n this.options = { ...this.options, ...options };\n }\n\n public expandHunk(\n index: number,\n direction: ExpansionDirections,\n expansionLineCount: number = this.getOptionsWithDefaults()\n .expansionLineCount\n ): void {\n const region = {\n ...(this.expandedHunks.get(index) ?? {\n fromStart: 0,\n fromEnd: 0,\n }),\n };\n if (direction === 'up' || direction === 'both') {\n region.fromStart += expansionLineCount;\n }\n if (direction === 'down' || direction === 'both') {\n region.fromEnd += expansionLineCount;\n }\n // NOTE(amadeus): If our render cache is not highlighted, we need to clear\n // it, otherwise we won't have the correct AST lines\n if (this.renderCache?.highlighted !== true) {\n this.clearRenderCache();\n }\n this.expandedHunks.set(index, region);\n }\n\n public getExpandedHunk(hunkIndex: number): HunkExpansionRegion {\n return this.expandedHunks.get(hunkIndex) ?? DEFAULT_EXPANDED_REGION;\n }\n\n public getExpandedHunksMap(): Map<number, HunkExpansionRegion> {\n return this.expandedHunks;\n }\n\n public setLineAnnotations(\n lineAnnotations: DiffLineAnnotation<LAnnotation>[]\n ): void {\n this.additionAnnotations = {};\n this.deletionAnnotations = {};\n for (const annotation of lineAnnotations) {\n const map = ((): AnnotationLineMap<LAnnotation> => {\n switch (annotation.side) {\n case 'deletions':\n return this.deletionAnnotations;\n case 'additions':\n return this.additionAnnotations;\n }\n })();\n const arr = map[annotation.lineNumber] ?? [];\n map[annotation.lineNumber] = arr;\n arr.push(annotation);\n }\n }\n\n protected getUnifiedLineDecoration({\n lineType,\n }: UnifiedLineDecorationProps): LineDecoration {\n return { gutterLineType: lineType };\n }\n\n protected getSplitLineDecoration({\n side,\n type,\n }: SplitLineDecorationProps): LineDecoration {\n if (type !== 'change') {\n return { gutterLineType: type };\n }\n return {\n gutterLineType:\n side === 'deletions' ? 'change-deletion' : 'change-addition',\n };\n }\n\n protected createAnnotationElement(span: AnnotationSpan): HASTElement {\n return createDefaultAnnotationElement(span);\n }\n\n // Unified hook returns extra rows that render before/after the current line.\n declare protected getUnifiedInjectedRowsForLine?: (\n ctx: RenderedLineContext\n ) => UnifiedInjectedRowPlacement | undefined;\n\n // Split hook returns extra rows per side before/after the current line.\n declare protected getSplitInjectedRowsForLine?: (\n ctx: RenderedLineContext\n ) => SplitInjectedRowPlacement | undefined;\n\n protected getOptionsWithDefaults(): DiffHunksRendererOptionsWithDefaults {\n const {\n diffIndicators = 'bars',\n diffStyle = 'split',\n disableBackground = false,\n disableFileHeader = false,\n disableLineNumbers = false,\n disableVirtualizationBuffers = false,\n collapsed = false,\n expandUnchanged = false,\n collapsedContextThreshold = DEFAULT_COLLAPSED_CONTEXT_THRESHOLD,\n expansionLineCount = 100,\n hunkSeparators = 'line-info',\n lineDiffType = 'word-alt',\n maxLineDiffLength = 1000,\n overflow = 'scroll',\n stickyHeader = false,\n theme = DEFAULT_THEMES,\n headerRenderMode = 'default',\n tokenizeMaxLineLength = 1000,\n tokenizeMaxLength = DEFAULT_TOKENIZE_MAX_LENGTH,\n useTokenTransformer = false,\n useCSSClasses = false,\n } = this.options;\n return {\n diffIndicators,\n diffStyle,\n disableBackground,\n disableFileHeader,\n disableLineNumbers,\n disableVirtualizationBuffers,\n collapsed,\n expandUnchanged,\n collapsedContextThreshold,\n expansionLineCount,\n hunkSeparators,\n lineDiffType,\n maxLineDiffLength,\n overflow,\n stickyHeader,\n theme: this.workerManager?.getDiffRenderOptions().theme ?? theme,\n headerRenderMode,\n tokenizeMaxLineLength,\n tokenizeMaxLength,\n useTokenTransformer,\n useCSSClasses,\n };\n }\n\n private async initializeHighlighter(): Promise<DiffsHighlighter> {\n this.highlighter = await getSharedHighlighter(\n getHighlighterOptions(this.computedLang, this.options)\n );\n return this.highlighter;\n }\n\n public hydrate(diff: FileDiffMetadata | undefined): void {\n if (diff == null) {\n return;\n }\n this.diff = diff;\n const { options } = this.getRenderOptions(diff);\n const massiveDiff = isDiffMassive(diff, this.getTokenizeMaxLength());\n let cache = this.workerManager?.getDiffResultCache(diff);\n if (cache != null && !areDiffRenderOptionsEqual(options, cache.options)) {\n cache = undefined;\n }\n this.renderCache ??= {\n diff,\n highlighted: !massiveDiff && !isDiffPlainText(diff),\n options,\n result: massiveDiff ? undefined : cache?.result,\n renderRange: undefined,\n };\n if (this.workerManager?.isWorkingPool() === true) {\n if (this.renderCache.result == null && !massiveDiff) {\n // We should only kick off a preload of the AST if we have a WorkerPool\n this.workerManager.highlightDiffAST(this, this.diff);\n }\n }\n // Lets attempt to get the highlighter/languages ready immediately\n else if (this.highlighter == null) {\n this.computedLang = diff.lang ?? getFiletypeFromFileName(diff.name);\n void this.initializeHighlighter();\n }\n }\n\n private getRenderOptions(diff: FileDiffMetadata): GetRenderOptionsReturn {\n const options: RenderDiffOptions = (() => {\n if (this.workerManager?.isWorkingPool() === true) {\n return this.workerManager.getDiffRenderOptions();\n }\n const { theme, tokenizeMaxLineLength, lineDiffType, maxLineDiffLength } =\n this.getOptionsWithDefaults();\n return {\n theme,\n useTokenTransformer: shouldUseTokenTransformer(this.options),\n tokenizeMaxLineLength,\n lineDiffType,\n maxLineDiffLength,\n };\n })();\n this.getOptionsWithDefaults();\n const { renderCache } = this;\n if (renderCache?.result == null) {\n return { options, forceHighlight: true };\n }\n if (\n !areDiffTargetsEqual(diff, renderCache.diff) ||\n !areDiffRenderOptionsEqual(options, renderCache.options)\n ) {\n return { options, forceHighlight: true };\n }\n return { options, forceHighlight: false };\n }\n\n public renderDiff(\n diff: FileDiffMetadata | undefined = this.renderCache?.diff,\n renderRange: RenderRange = DEFAULT_RENDER_RANGE\n ): HunksRenderResult | undefined {\n if (diff == null) {\n return undefined;\n }\n const { expandUnchanged = false, collapsedContextThreshold } =\n this.getOptionsWithDefaults();\n let { options, forceHighlight } = this.getRenderOptions(diff);\n const cache = this.getMatchingWorkerResultCache(diff, options);\n if (cache != null && !this.hasHighlightedRenderCache(diff, options)) {\n this.renderCache = {\n diff,\n highlighted: true,\n renderRange: undefined,\n ...cache,\n };\n forceHighlight = false;\n }\n this.renderCache ??= {\n diff,\n highlighted: false,\n options,\n result: undefined,\n renderRange: undefined,\n };\n const hasContent =\n diff.additionLines.length > 0 || diff.deletionLines.length > 0;\n const forcePlainText =\n !hasContent ||\n isDiffPlainText(diff) ||\n isDiffMassive(diff, this.getTokenizeMaxLength());\n const newContent = !areDiffTargetsEqual(diff, this.renderCache.diff);\n const newRenderRange = !areRenderRangesEqual(\n this.renderCache.renderRange,\n renderRange\n );\n if (this.workerManager?.isWorkingPool() === true) {\n if (\n forcePlainText ||\n this.renderCache.result == null ||\n (!this.renderCache.highlighted && (newContent || newRenderRange))\n ) {\n this.renderCache.diff = diff;\n this.renderCache.options = options;\n this.renderCache.highlighted = false;\n if (\n this.renderCache.result == null ||\n newContent ||\n newRenderRange ||\n forceHighlight\n ) {\n this.renderCache.result = this.workerManager.getPlainDiffAST(\n diff,\n renderRange.startingLine,\n renderRange.totalLines,\n // If we aren't using a windowed render, then we need to render\n // everything\n isDefaultRenderRange(renderRange)\n ? true\n : expandUnchanged\n ? true\n : this.expandedHunks,\n collapsedContextThreshold\n );\n }\n this.renderCache.renderRange = renderRange;\n }\n\n // Should we kick off an async highlight process\n if (\n !forcePlainText &&\n hasContent &&\n (!this.renderCache.highlighted || forceHighlight)\n ) {\n this.workerManager.highlightDiffAST(this, diff);\n }\n } else {\n this.computedLang = diff.lang ?? getFiletypeFromFileName(diff.name);\n const hasThemes =\n this.highlighter != null && areThemesAttached(options.theme);\n const hasLangs =\n this.highlighter != null && areLanguagesAttached(this.computedLang);\n const canHighlight = !forcePlainText && hasLangs;\n\n // If we have any semblance of a highlighter with the correct theme(s)\n // attached, we can kick off some form of rendering. If we don't have\n // the correct language, then we can render plain text and after kick off\n // an async job to get the highlighted AST\n if (\n this.highlighter != null &&\n hasThemes &&\n (forceHighlight ||\n forcePlainText ||\n (!this.renderCache.highlighted && canHighlight) ||\n this.renderCache.result == null)\n ) {\n const { result, options } = this.renderDiffWithHighlighter(\n diff,\n this.highlighter,\n forcePlainText || !hasLangs\n );\n this.renderCache = {\n diff,\n options,\n highlighted: canHighlight,\n result,\n renderRange: undefined,\n };\n }\n\n // If we get in here it means we'll have to kick off an async highlight\n // process which will involve initializing the highlighter with new themes\n // and languages\n if (!hasThemes || (!forcePlainText && !hasLangs)) {\n void this.asyncHighlight(diff).then(({ result, options }) => {\n // In this case we need to force a re-render, so we can do that by\n // reaching into renderCache\n if (this.renderCache != null) {\n this.renderCache.highlighted = false;\n }\n this.onHighlightSuccess(diff, result, options, !forcePlainText);\n });\n }\n }\n return this.renderCache.result != null\n ? this.processDiffResult(\n this.renderCache.diff,\n renderRange,\n this.renderCache.result\n )\n : undefined;\n }\n\n public async asyncRender(\n diff: FileDiffMetadata,\n renderRange: RenderRange = DEFAULT_RENDER_RANGE\n ): Promise<HunksRenderResult> {\n const { result } = await this.asyncHighlight(diff);\n return this.processDiffResult(diff, renderRange, result);\n }\n\n protected createPreElement(\n split: boolean,\n totalLines: number,\n customProperties?: CustomPreProperties\n ): HASTElement {\n const { diffIndicators, disableBackground, disableLineNumbers, overflow } =\n this.getOptionsWithDefaults();\n return createPreElement({\n type: 'diff',\n diffIndicators,\n disableBackground,\n disableLineNumbers,\n overflow,\n split,\n totalLines,\n customProperties,\n });\n }\n\n private async asyncHighlight(\n diff: FileDiffMetadata\n ): Promise<RenderDiffResult> {\n const forcePlainText = isDiffMassive(diff, this.getTokenizeMaxLength());\n this.computedLang = forcePlainText\n ? 'text'\n : (diff.lang ?? getFiletypeFromFileName(diff.name));\n const hasThemes =\n this.highlighter != null &&\n areThemesAttached(this.options.theme ?? DEFAULT_THEMES);\n const hasLangs =\n forcePlainText ||\n (this.highlighter != null && areLanguagesAttached(this.computedLang));\n // If we don't have the required langs or themes, then we need to\n // initialize the highlighter to load the appropriate languages and themes\n if (this.highlighter == null || !hasThemes || !hasLangs) {\n this.highlighter = await this.initializeHighlighter();\n }\n return this.renderDiffWithHighlighter(\n diff,\n this.highlighter,\n forcePlainText\n );\n }\n\n private renderDiffWithHighlighter(\n diff: FileDiffMetadata,\n highlighter: DiffsHighlighter,\n forcePlainText = false\n ): RenderDiffResult {\n const { options } = this.getRenderOptions(diff);\n const { collapsedContextThreshold } = this.getOptionsWithDefaults();\n const result = renderDiffWithHighlighter(diff, highlighter, options, {\n forcePlainText,\n expandedHunks: forcePlainText ? true : undefined,\n collapsedContextThreshold,\n });\n return { result, options };\n }\n\n public onHighlightSuccess(\n diff: FileDiffMetadata,\n result: ThemedDiffResult,\n options: RenderDiffOptions,\n highlighted = true\n ): void {\n // NOTE(amadeus): This is a bad assumption, and I should figure out\n // something better... If renderCache was blown away, we can assume we've\n // run cleanUp()\n if (this.renderCache == null) {\n return;\n }\n\n const triggerRenderUpdate =\n !this.renderCache.highlighted ||\n !areDiffRenderOptionsEqual(this.renderCache.options, options) ||\n !areDiffTargetsEqual(this.renderCache.diff, diff);\n\n this.renderCache = {\n diff,\n options,\n highlighted,\n result,\n renderRange: undefined,\n };\n if (triggerRenderUpdate) {\n this.onRenderUpdate?.();\n }\n }\n\n private getMatchingWorkerResultCache(\n diff: FileDiffMetadata,\n options: RenderDiffOptions\n ): RenderDiffResult | undefined {\n const cache = this.workerManager?.getDiffResultCache(diff);\n if (cache == null || !areDiffRenderOptionsEqual(options, cache.options)) {\n return undefined;\n }\n return cache;\n }\n\n private hasHighlightedRenderCache(\n diff: FileDiffMetadata,\n options: RenderDiffOptions\n ): boolean {\n const { renderCache } = this;\n return (\n renderCache?.result != null &&\n renderCache.highlighted &&\n areDiffTargetsEqual(diff, renderCache.diff) &&\n areDiffRenderOptionsEqual(options, renderCache.options)\n );\n }\n\n public onHighlightError(error: unknown): void {\n console.error(error);\n }\n\n private getTokenizeMaxLength(): number {\n return this.options.tokenizeMaxLength ?? DEFAULT_TOKENIZE_MAX_LENGTH;\n }\n\n private processDiffResult(\n fileDiff: FileDiffMetadata,\n renderRange: RenderRange,\n { code, themeStyles, baseThemeType }: ThemedDiffResult\n ): HunksRenderResult {\n const {\n diffStyle,\n disableFileHeader,\n expandUnchanged,\n expansionLineCount,\n collapsedContextThreshold,\n hunkSeparators,\n } = this.getOptionsWithDefaults();\n\n this.diff = fileDiff;\n const unified = diffStyle === 'unified';\n\n let additionsContentAST: ElementContent[] | undefined = [];\n let deletionsContentAST: ElementContent[] | undefined = [];\n let unifiedContentAST: ElementContent[] | undefined = [];\n\n const hunkData: HunkData[] = [];\n const { additionLines, deletionLines } = code;\n const context: ProcessContext = {\n rowCount: 0,\n hunkSeparators,\n additionsContentAST,\n deletionsContentAST,\n unifiedContentAST,\n unifiedGutterAST: createGutterWrapper(),\n deletionsGutterAST: createGutterWrapper(),\n additionsGutterAST: createGutterWrapper(),\n expansionLineCount,\n hunkData,\n incrementRowCount(count = 1) {\n context.rowCount += count;\n },\n pushToGutter(type: CodeColumnType, element: HASTElement) {\n switch (type) {\n case 'unified': {\n context.unifiedGutterAST.children.push(element);\n break;\n }\n case 'deletions': {\n context.deletionsGutterAST.children.push(element);\n break;\n }\n case 'additions': {\n context.additionsGutterAST.children.push(element);\n break;\n }\n }\n },\n };\n const trailingRangeSize = getTrailingContextRangeSize({\n fileDiff,\n errorPrefix: 'DiffHunksRenderer.processDiffResult',\n });\n const pendingSplitContext: PendingSplitContext = {\n size: 0,\n side: undefined,\n increment() {\n this.size += 1;\n },\n flush() {\n if (diffStyle === 'unified') {\n return;\n }\n if (this.size <= 0 || this.side == null) {\n this.side = undefined;\n this.size = 0;\n return;\n }\n if (this.side === 'additions') {\n context.pushToGutter(\n 'additions',\n createGutterGap(undefined, 'buffer', this.size)\n );\n additionsContentAST?.push(createEmptyRowBuffer(this.size));\n } else {\n context.pushToGutter(\n 'deletions',\n createGutterGap(undefined, 'buffer', this.size)\n );\n deletionsContentAST?.push(createEmptyRowBuffer(this.size));\n }\n this.size = 0;\n this.side = undefined;\n },\n };\n\n const pushGutterLineNumber = (\n type: CodeColumnType,\n lineType: LineTypes | 'buffer' | 'separator' | 'annotation',\n lineNumber: number,\n lineIndex: string,\n gutterProperties: Properties | undefined\n ) => {\n context.pushToGutter(\n type,\n createGutterItem(lineType, lineNumber, lineIndex, gutterProperties)\n );\n };\n\n function pushSeparators(props: PushSeparatorProps) {\n pendingSplitContext.flush();\n if (diffStyle === 'unified') {\n pushSeparator('unified', props, context);\n } else {\n pushSeparator('deletions', props, context);\n pushSeparator('additions', props, context);\n }\n }\n\n iterateOverDiff({\n diff: fileDiff,\n diffStyle,\n startingLine: renderRange.startingLine,\n totalLines: renderRange.totalLines,\n expandedHunks: expandUnchanged ? true : this.expandedHunks,\n collapsedContextThreshold,\n callback: ({\n hunkIndex,\n hunk,\n collapsedBefore,\n collapsedAfter,\n additionLine,\n deletionLine,\n type,\n }) => {\n const splitLineIndex =\n deletionLine != null\n ? deletionLine.splitLineIndex\n : additionLine.splitLineIndex;\n const unifiedLineIndex =\n additionLine != null\n ? additionLine.unifiedLineIndex\n : deletionLine.unifiedLineIndex;\n\n if (diffStyle === 'split' && type !== 'change') {\n pendingSplitContext.flush();\n }\n\n if (collapsedBefore > 0) {\n pushSeparators({\n hunkIndex,\n collapsedLines: collapsedBefore,\n rangeSize: Math.max(hunk?.collapsedBefore ?? 0, 0),\n hunkSpecs: hunk?.hunkSpecs,\n isFirstHunk: hunkIndex === 0,\n isLastHunk: false,\n isExpandable: !fileDiff.isPartial,\n });\n }\n\n const lineIndex =\n diffStyle === 'unified' ? unifiedLineIndex : splitLineIndex;\n const renderedLineContext: RenderedLineContext = {\n type,\n hunkIndex,\n lineIndex,\n unifiedLineIndex,\n splitLineIndex,\n deletionLine,\n additionLine,\n };\n\n if (diffStyle === 'unified') {\n const injectedRows =\n this.getUnifiedInjectedRowsForLine?.(renderedLineContext);\n if (injectedRows?.before != null) {\n pushUnifiedInjectedRows(injectedRows.before, context);\n }\n let deletionLineContent =\n deletionLine != null\n ? deletionLines[deletionLine.lineIndex]\n : undefined;\n let additionLineContent =\n additionLine != null\n ? additionLines[additionLine.lineIndex]\n : undefined;\n if (deletionLineContent == null && additionLineContent == null) {\n const errorMessage =\n 'DiffHunksRenderer.processDiffResult: deletionLine and additionLine are null, something is wrong';\n console.error(errorMessage, { file: fileDiff.name });\n throw new Error(errorMessage);\n }\n const lineType =\n type === 'change'\n ? additionLine != null\n ? 'change-addition'\n : 'change-deletion'\n : type;\n const lineDecoration = this.getUnifiedLineDecoration({\n // NOTE: This function gets extended so don't remove\n // these extra props\n type,\n lineType,\n additionLineIndex: additionLine?.lineIndex,\n deletionLineIndex: deletionLine?.lineIndex,\n });\n pushGutterLineNumber(\n 'unified',\n lineDecoration.gutterLineType,\n additionLine != null\n ? additionLine.lineNumber\n : deletionLine.lineNumber,\n `${unifiedLineIndex},${splitLineIndex}`,\n lineDecoration.gutterProperties\n );\n if (additionLineContent != null) {\n additionLineContent = withContentProperties(\n additionLineContent,\n lineDecoration.contentProperties\n );\n } else if (deletionLineContent != null) {\n deletionLineContent = withContentProperties(\n deletionLineContent,\n lineDecoration.contentProperties\n );\n }\n pushLineWithAnnotation({\n diffStyle: 'unified',\n type: type,\n deletionLine: deletionLineContent,\n additionLine: additionLineContent,\n unifiedSpan: this.getAnnotations(\n 'unified',\n deletionLine?.lineNumber,\n additionLine?.lineNumber,\n hunkIndex,\n lineIndex\n ),\n createAnnotationElement: (span) =>\n this.createAnnotationElement(span),\n context,\n });\n if (injectedRows?.after != null) {\n pushUnifiedInjectedRows(injectedRows.after, context);\n }\n } else {\n const injectedRows =\n this.getSplitInjectedRowsForLine?.(renderedLineContext);\n if (injectedRows?.before != null) {\n pushSplitInjectedRows(\n injectedRows.before,\n context,\n pendingSplitContext\n );\n }\n\n let deletionLineContent =\n deletionLine != null\n ? deletionLines[deletionLine.lineIndex]\n : undefined;\n let additionLineContent =\n additionLine != null\n ? additionLines[additionLine.lineIndex]\n : undefined;\n const deletionLineDecoration = this.getSplitLineDecoration({\n side: 'deletions',\n type,\n lineIndex: deletionLine?.lineIndex,\n });\n const additionLineDecoration = this.getSplitLineDecoration({\n side: 'additions',\n type,\n lineIndex: additionLine?.lineIndex,\n });\n\n if (deletionLineContent == null && additionLineContent == null) {\n const errorMessage =\n 'DiffHunksRenderer.processDiffResult: deletionLine and additionLine are null, something is wrong';\n console.error(errorMessage, { file: fileDiff.name });\n throw new Error(errorMessage);\n }\n\n const missingSide = (() => {\n if (type === 'change') {\n if (additionLineContent == null) {\n return 'additions';\n } else if (deletionLineContent == null) {\n return 'deletions';\n }\n }\n return undefined;\n })();\n if (missingSide != null) {\n if (\n pendingSplitContext.side != null &&\n pendingSplitContext.side !== missingSide\n ) {\n // NOTE(amadeus): If we see this error, we might need to bring back: flushSplitSpan();\n throw new Error(\n 'DiffHunksRenderer.processDiffResult: iterateOverDiff, invalid pending splits'\n );\n }\n pendingSplitContext.side = missingSide;\n pendingSplitContext.increment();\n }\n\n const annotationSpans = this.getAnnotations(\n 'split',\n deletionLine?.lineNumber,\n additionLine?.lineNumber,\n hunkIndex,\n lineIndex\n );\n if (annotationSpans != null && pendingSplitContext.size > 0) {\n pendingSplitContext.flush();\n }\n\n if (deletionLine != null) {\n const deletionLineDecorated = withContentProperties(\n deletionLineContent,\n deletionLineDecoration.contentProperties\n );\n pushGutterLineNumber(\n 'deletions',\n deletionLineDecoration.gutterLineType,\n deletionLine.lineNumber,\n `${deletionLine.unifiedLineIndex},${splitLineIndex}`,\n deletionLineDecoration.gutterProperties\n );\n if (deletionLineDecorated != null) {\n deletionLineContent = deletionLineDecorated;\n }\n }\n if (additionLine != null) {\n const additionLineDecorated = withContentProperties(\n additionLineContent,\n additionLineDecoration.contentProperties\n );\n pushGutterLineNumber(\n 'additions',\n additionLineDecoration.gutterLineType,\n additionLine.lineNumber,\n `${additionLine.unifiedLineIndex},${splitLineIndex}`,\n additionLineDecoration.gutterProperties\n );\n if (additionLineDecorated != null) {\n additionLineContent = additionLineDecorated;\n }\n }\n pushLineWithAnnotation({\n diffStyle: 'split',\n type: type,\n additionLine: additionLineContent,\n deletionLine: deletionLineContent,\n ...annotationSpans,\n createAnnotationElement: (span) =>\n this.createAnnotationElement(span),\n context,\n });\n if (injectedRows?.after != null) {\n pushSplitInjectedRows(\n injectedRows.after,\n context,\n pendingSplitContext\n );\n }\n }\n\n const isFinalSplitHunkRow =\n diffStyle === 'split' &&\n hunk != null &&\n splitLineIndex === hunk.splitLineStart + hunk.splitLineCount - 1;\n const splitNoEOFCRDeletion = isFinalSplitHunkRow\n ? hunk.noEOFCRDeletions\n : false;\n const splitNoEOFCRAddition = isFinalSplitHunkRow\n ? hunk.noEOFCRAdditions\n : false;\n const noEOFCRDeletion =\n (deletionLine?.noEOFCR ?? false) || splitNoEOFCRDeletion;\n const noEOFCRAddition =\n (additionLine?.noEOFCR ?? false) || splitNoEOFCRAddition;\n if (noEOFCRAddition || noEOFCRDeletion) {\n if (diffStyle === 'split') {\n pendingSplitContext.flush();\n }\n if (noEOFCRDeletion) {\n const noEOFType =\n type === 'context' || type === 'context-expanded'\n ? type\n : 'change-deletion';\n if (diffStyle === 'unified') {\n context.unifiedContentAST.push(createNoNewlineElement(noEOFType));\n context.pushToGutter(\n 'unified',\n createGutterGap(noEOFType, 'metadata', 1)\n );\n } else {\n context.deletionsContentAST.push(\n createNoNewlineElement(noEOFType)\n );\n context.pushToGutter(\n 'deletions',\n createGutterGap(noEOFType, 'metadata', 1)\n );\n if (!noEOFCRAddition) {\n context.pushToGutter(\n 'additions',\n createGutterGap(undefined, 'buffer', 1)\n );\n context.additionsContentAST.push(createEmptyRowBuffer(1));\n }\n }\n }\n if (noEOFCRAddition) {\n const noEOFType =\n type === 'context' || type === 'context-expanded'\n ? type\n : 'change-addition';\n if (diffStyle === 'unified') {\n context.unifiedContentAST.push(createNoNewlineElement(noEOFType));\n context.pushToGutter(\n 'unified',\n createGutterGap(noEOFType, 'metadata', 1)\n );\n } else {\n context.additionsContentAST.push(\n createNoNewlineElement(noEOFType)\n );\n context.pushToGutter(\n 'additions',\n createGutterGap(noEOFType, 'metadata', 1)\n );\n if (!noEOFCRDeletion) {\n context.pushToGutter(\n 'deletions',\n createGutterGap(undefined, 'buffer', 1)\n );\n context.deletionsContentAST.push(createEmptyRowBuffer(1));\n }\n }\n }\n context.incrementRowCount(1);\n }\n\n if (collapsedAfter > 0 && hunkSeparators !== 'simple') {\n pushSeparators({\n hunkIndex: type === 'context-expanded' ? hunkIndex : hunkIndex + 1,\n collapsedLines: collapsedAfter,\n rangeSize: trailingRangeSize,\n hunkSpecs: undefined,\n isFirstHunk: false,\n isLastHunk: true,\n isExpandable: !fileDiff.isPartial,\n });\n }\n context.incrementRowCount(1);\n },\n });\n\n if (diffStyle === 'split') {\n pendingSplitContext.flush();\n }\n\n const totalLines = Math.max(\n getTotalLineCountFromHunks(fileDiff.hunks),\n fileDiff.additionLines.length ?? 0,\n fileDiff.deletionLines.length ?? 0\n );\n\n const hasBuffer =\n renderRange.bufferBefore > 0 || renderRange.bufferAfter > 0;\n // Determine which ASTs to include based on diff style and file type\n const shouldIncludeAdditions = !unified && fileDiff.type !== 'deleted';\n const shouldIncludeDeletions = !unified && fileDiff.type !== 'new';\n const hasContent = context.rowCount > 0 || hasBuffer;\n\n additionsContentAST =\n shouldIncludeAdditions && hasContent ? additionsContentAST : undefined;\n deletionsContentAST =\n shouldIncludeDeletions && hasContent ? deletionsContentAST : undefined;\n unifiedContentAST = unified && hasContent ? unifiedContentAST : undefined;\n\n const preNode = this.createPreElement(\n deletionsContentAST != null && additionsContentAST != null,\n totalLines\n );\n\n return {\n unifiedGutterAST:\n unified && hasContent ? context.unifiedGutterAST.children : undefined,\n unifiedContentAST,\n deletionsGutterAST:\n shouldIncludeDeletions && hasContent\n ? context.deletionsGutterAST.children\n : undefined,\n deletionsContentAST,\n additionsGutterAST:\n shouldIncludeAdditions && hasContent\n ? context.additionsGutterAST.children\n : undefined,\n additionsContentAST,\n hunkData,\n preNode,\n themeStyles,\n baseThemeType,\n headerElement: !disableFileHeader\n ? this.renderHeader(this.diff)\n : undefined,\n totalLines,\n rowCount: context.rowCount,\n bufferBefore: renderRange.bufferBefore,\n bufferAfter: renderRange.bufferAfter,\n // FIXME\n css: '',\n };\n }\n\n public renderCodeAST(\n type: 'unified' | 'deletions' | 'additions',\n result: HunksRenderResult\n ): ElementContent[] | undefined {\n const gutterAST =\n type === 'unified'\n ? result.unifiedGutterAST\n : type === 'deletions'\n ? result.deletionsGutterAST\n : result.additionsGutterAST;\n\n const contentAST =\n type === 'unified'\n ? result.unifiedContentAST\n : type === 'deletions'\n ? result.deletionsContentAST\n : result.additionsContentAST;\n\n if (gutterAST == null || contentAST == null) {\n return undefined;\n }\n\n const gutter = createGutterWrapper(gutterAST);\n gutter.properties.style = `grid-row: span ${result.rowCount}`;\n const contentColumn = createContentColumn(contentAST, result.rowCount);\n return [gutter, contentColumn];\n }\n\n public renderFullAST(\n result: HunksRenderResult,\n children: ElementContent[] = []\n ): HASTElement {\n const containerSize =\n this.getOptionsWithDefaults().hunkSeparators === 'line-info';\n const unifiedAST = this.renderCodeAST('unified', result);\n if (unifiedAST != null) {\n children.push(\n createHastElement({\n tagName: 'code',\n children: unifiedAST,\n properties: {\n 'data-code': '',\n 'data-container-size': containerSize ? '' : undefined,\n 'data-unified': '',\n },\n })\n );\n return { ...result.preNode, children };\n }\n\n const deletionsAST = this.renderCodeAST('deletions', result);\n if (deletionsAST != null) {\n children.push(\n createHastElement({\n tagName: 'code',\n children: deletionsAST,\n properties: {\n 'data-code': '',\n 'data-container-size': containerSize ? '' : undefined,\n 'data-deletions': '',\n },\n })\n );\n }\n const additionsAST = this.renderCodeAST('additions', result);\n if (additionsAST != null) {\n children.push(\n createHastElement({\n tagName: 'code',\n children: additionsAST,\n properties: {\n 'data-code': '',\n 'data-container-size': containerSize ? '' : undefined,\n 'data-additions': '',\n },\n })\n );\n }\n return { ...result.preNode, children };\n }\n\n public renderFullHTML(\n result: HunksRenderResult,\n tempChildren: ElementContent[] = []\n ): string {\n return toHtml(this.renderFullAST(result, tempChildren));\n }\n\n public renderPartialHTML(\n children: ElementContent[],\n columnType?: 'unified' | 'deletions' | 'additions'\n ): string {\n if (columnType == null) {\n return toHtml(children);\n }\n return toHtml(\n createHastElement({\n tagName: 'code',\n children,\n properties: {\n 'data-code': '',\n 'data-container-size':\n this.getOptionsWithDefaults().hunkSeparators === 'line-info'\n ? ''\n : undefined,\n [`data-${columnType}`]: '',\n },\n })\n );\n }\n\n private getAnnotations(\n type: 'unified',\n deletionLineNumber: number | undefined,\n additionLineNumber: number | undefined,\n hunkIndex: number,\n lineIndex: number\n ): AnnotationSpan | undefined;\n private getAnnotations(\n type: 'split',\n deletionLineNumber: number | undefined,\n additionLineNumber: number | undefined,\n hunkIndex: number,\n lineIndex: number\n ): { deletionSpan: AnnotationSpan; additionSpan: AnnotationSpan } | undefined;\n private getAnnotations(\n type: 'unified' | 'split',\n deletionLineNumber: number | undefined,\n additionLineNumber: number | undefined,\n hunkIndex: number,\n lineIndex: number\n ):\n | AnnotationSpan\n | { deletionSpan: AnnotationSpan; additionSpan: AnnotationSpan }\n | undefined {\n const deletionSpan: AnnotationSpan = {\n type: 'annotation',\n hunkIndex,\n lineIndex,\n annotations: [],\n };\n if (deletionLineNumber != null) {\n for (const anno of this.deletionAnnotations[deletionLineNumber] ?? []) {\n deletionSpan.annotations.push(getLineAnnotationName(anno));\n }\n }\n const additionSpan: AnnotationSpan = {\n type: 'annotation',\n hunkIndex,\n lineIndex,\n annotations: [],\n };\n if (additionLineNumber != null) {\n for (const anno of this.additionAnnotations[additionLineNumber] ?? []) {\n (type === 'unified' ? deletionSpan : additionSpan).annotations.push(\n getLineAnnotationName(anno)\n );\n }\n }\n if (type === 'unified') {\n if (deletionSpan.annotations.length > 0) {\n return deletionSpan;\n }\n return undefined;\n }\n if (\n additionSpan.annotations.length === 0 &&\n deletionSpan.annotations.length === 0\n ) {\n return undefined;\n }\n return { deletionSpan, additionSpan };\n }\n\n private renderHeader(diff: FileDiffMetadata): HASTElement {\n const { headerRenderMode, stickyHeader } = this.getOptionsWithDefaults();\n return createFileHeaderElement({\n fileOrDiff: diff,\n mode: headerRenderMode,\n stickyHeader,\n });\n }\n}\n\nfunction getModifiedLinesString(lines: number) {\n return `${lines} unmodified line${lines > 1 ? 's' : ''}`;\n}\n\nfunction pushUnifiedInjectedRows(\n rows: InjectedRow[],\n context: ProcessContext\n): void {\n for (const row of rows) {\n context.unifiedContentAST.push(row.content);\n context.pushToGutter('unified', row.gutter);\n context.incrementRowCount(1);\n }\n}\n\nfunction pushSplitInjectedRows(\n rows: SplitInjectedRow[],\n context: ProcessContext,\n pendingSplitContext: PendingSplitContext\n): void {\n for (const { deletion, addition } of rows) {\n if (deletion == null && addition == null) {\n continue;\n }\n const missingSide =\n deletion != null && addition != null\n ? undefined\n : deletion == null\n ? 'deletions'\n : 'additions';\n\n if (missingSide == null || pendingSplitContext.side !== missingSide) {\n pendingSplitContext.flush();\n }\n\n if (deletion != null) {\n context.deletionsContentAST.push(deletion.content);\n context.pushToGutter('deletions', deletion.gutter);\n }\n\n if (addition != null) {\n context.additionsContentAST.push(addition.content);\n context.pushToGutter('additions', addition.gutter);\n }\n\n if (missingSide != null) {\n pendingSplitContext.side = missingSide;\n pendingSplitContext.increment();\n }\n\n context.incrementRowCount(1);\n }\n}\n\nfunction pushLineWithAnnotation({\n diffStyle,\n type,\n deletionLine,\n additionLine,\n unifiedSpan,\n deletionSpan,\n additionSpan,\n createAnnotationElement,\n context,\n}: PushLineWithAnnotation) {\n let hasAnnotationRow = false;\n if (diffStyle === 'unified') {\n if (additionLine != null) {\n context.unifiedContentAST.push(additionLine);\n } else if (deletionLine != null) {\n context.unifiedContentAST.push(deletionLine);\n }\n if (unifiedSpan != null) {\n const lineType =\n type === 'change'\n ? deletionLine != null\n ? 'change-deletion'\n : 'change-addition'\n : type;\n context.unifiedContentAST.push(createAnnotationElement(unifiedSpan));\n context.pushToGutter(\n 'unified',\n createGutterGap(lineType, 'annotation', 1)\n );\n hasAnnotationRow = true;\n }\n } else if (diffStyle === 'split') {\n if (deletionLine != null) {\n context.deletionsContentAST.push(deletionLine);\n }\n if (additionLine != null) {\n context.additionsContentAST.push(additionLine);\n }\n if (deletionSpan != null) {\n const lineType =\n type === 'change'\n ? deletionLine != null\n ? 'change-deletion'\n : 'context'\n : type;\n context.deletionsContentAST.push(createAnnotationElement(deletionSpan));\n context.pushToGutter(\n 'deletions',\n createGutterGap(lineType, 'annotation', 1)\n );\n hasAnnotationRow = true;\n }\n if (additionSpan != null) {\n const lineType =\n type === 'change'\n ? additionLine != null\n ? 'change-addition'\n : 'context'\n : type;\n context.additionsContentAST.push(createAnnotationElement(additionSpan));\n context.pushToGutter(\n 'additions',\n createGutterGap(lineType, 'annotation', 1)\n );\n hasAnnotationRow = true;\n }\n }\n if (hasAnnotationRow) {\n context.incrementRowCount(1);\n }\n}\n\nfunction pushSeparator(\n type: 'additions' | 'deletions' | 'unified',\n {\n hunkIndex,\n collapsedLines,\n rangeSize,\n hunkSpecs,\n isFirstHunk,\n isLastHunk,\n isExpandable,\n }: PushSeparatorProps,\n context: ProcessContext\n) {\n if (collapsedLines <= 0) {\n return;\n }\n const linesAST =\n type === 'unified'\n ? context.unifiedContentAST\n : type === 'deletions'\n ? context.deletionsContentAST\n : context.additionsContentAST;\n\n if (context.hunkSeparators === 'metadata') {\n if (hunkSpecs != null) {\n context.pushToGutter(\n type,\n createSeparator({\n type: 'metadata',\n content: hunkSpecs,\n isFirstHunk,\n isLastHunk,\n })\n );\n linesAST.push(\n createSeparator({\n type: 'metadata',\n content: hunkSpecs,\n isFirstHunk,\n isLastHunk,\n })\n );\n if (type !== 'additions') {\n context.incrementRowCount(1);\n }\n }\n return;\n }\n if (context.hunkSeparators === 'simple') {\n if (hunkIndex > 0) {\n context.pushToGutter(\n type,\n createSeparator({ type: 'simple', isFirstHunk, isLastHunk: false })\n );\n linesAST.push(\n createSeparator({ type: 'simple', isFirstHunk, isLastHunk: false })\n );\n if (type !== 'additions') {\n context.incrementRowCount(1);\n }\n }\n return;\n }\n const slotName = getHunkSeparatorSlotName(type, hunkIndex);\n const chunked = rangeSize > context.expansionLineCount;\n const expandIndex = isExpandable ? hunkIndex : undefined;\n context.pushToGutter(\n type,\n createSeparator({\n type: context.hunkSeparators,\n content: getModifiedLinesString(collapsedLines),\n expandIndex,\n chunked,\n slotName,\n isFirstHunk,\n isLastHunk,\n })\n );\n linesAST.push(\n createSeparator({\n type: context.hunkSeparators,\n content: getModifiedLinesString(collapsedLines),\n expandIndex,\n chunked,\n slotName,\n isFirstHunk,\n isLastHunk,\n })\n );\n if (type !== 'additions') {\n context.incrementRowCount(1);\n }\n context.hunkData.push({\n slotName,\n hunkIndex,\n lines: collapsedLines,\n type,\n expandable: isExpandable\n ? { up: !isFirstHunk, down: !isLastHunk, chunked }\n : undefined,\n });\n}\n\nfunction withContentProperties(\n lineNode: ElementContent | undefined,\n contentProperties: Properties | undefined\n): ElementContent | undefined {\n if (\n lineNode == null ||\n lineNode.type !== 'element' ||\n contentProperties == null\n ) {\n return lineNode;\n }\n return {\n ...lineNode,\n properties: {\n ...lineNode.properties,\n ...contentProperties,\n },\n };\n}\n\nfunction isDiffMassive(\n diff: FileDiffMetadata,\n tokenizeMaxLength: number\n): boolean {\n return (\n Math.max(diff.additionLines.length, diff.deletionLines.length) >\n tokenizeMaxLength\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DiffHunksRenderer.js","names":["options: DiffHunksRendererOptions","onRenderUpdate?: () => unknown","workerManager?: WorkerPoolManager | undefined","createDefaultAnnotationElement","options: RenderDiffOptions","options","additionsContentAST: ElementContent[] | undefined","deletionsContentAST: ElementContent[] | undefined","unifiedContentAST: ElementContent[] | undefined","hunkData: HunkData[]","context: ProcessContext","pendingSplitContext: PendingSplitContext","renderedLineContext: RenderedLineContext","deletionSpan: AnnotationSpan","additionSpan: AnnotationSpan","createAnnotationElement"],"sources":["../../src/renderers/DiffHunksRenderer.ts"],"sourcesContent":["import type { ElementContent, Element as HASTElement, Properties } from 'hast';\nimport { toHtml } from 'hast-util-to-html';\n\nimport {\n DEFAULT_COLLAPSED_CONTEXT_THRESHOLD,\n DEFAULT_EXPANDED_REGION,\n DEFAULT_RENDER_RANGE,\n DEFAULT_THEMES,\n DEFAULT_TOKENIZE_MAX_LENGTH,\n} from '../constants';\nimport { areLanguagesAttached } from '../highlighter/languages/areLanguagesAttached';\nimport {\n getHighlighterIfLoaded,\n getSharedHighlighter,\n} from '../highlighter/shared_highlighter';\nimport { areThemesAttached } from '../highlighter/themes/areThemesAttached';\nimport type {\n AnnotationLineMap,\n AnnotationSpan,\n BaseDiffOptions,\n BaseDiffOptionsWithDefaults,\n CodeColumnType,\n CustomPreProperties,\n DiffLineAnnotation,\n DiffsHighlighter,\n ExpansionDirections,\n FileDiffMetadata,\n FileHeaderRenderMode,\n HunkData,\n HunkExpansionRegion,\n HunkSeparators,\n LineTypes,\n RenderDiffOptions,\n RenderDiffResult,\n RenderedDiffASTCache,\n RenderRange,\n SupportedLanguages,\n ThemedDiffResult,\n} from '../types';\nimport { areDiffRenderOptionsEqual } from '../utils/areDiffRenderOptionsEqual';\nimport { areDiffTargetsEqual } from '../utils/areDiffTargetsEqual';\nimport { areRenderRangesEqual } from '../utils/areRenderRangesEqual';\nimport { createAnnotationElement as createDefaultAnnotationElement } from '../utils/createAnnotationElement';\nimport { createContentColumn } from '../utils/createContentColumn';\nimport { createEmptyRowBuffer } from '../utils/createEmptyRowBuffer';\nimport { createFileHeaderElement } from '../utils/createFileHeaderElement';\nimport { createNoNewlineElement } from '../utils/createNoNewlineElement';\nimport { createPreElement } from '../utils/createPreElement';\nimport { createSeparator } from '../utils/createSeparator';\nimport { getFiletypeFromFileName } from '../utils/getFiletypeFromFileName';\nimport { getHighlighterOptions } from '../utils/getHighlighterOptions';\nimport { getHunkSeparatorSlotName } from '../utils/getHunkSeparatorSlotName';\nimport { getLineAnnotationName } from '../utils/getLineAnnotationName';\nimport { getTotalLineCountFromHunks } from '../utils/getTotalLineCountFromHunks';\nimport {\n createGutterGap,\n createGutterItem,\n createGutterWrapper,\n createHastElement,\n} from '../utils/hast_utils';\nimport { isDefaultRenderRange } from '../utils/isDefaultRenderRange';\nimport { isDiffPlainText } from '../utils/isDiffPlainText';\nimport type { DiffLineMetadata } from '../utils/iterateOverDiff';\nimport { iterateOverDiff } from '../utils/iterateOverDiff';\nimport { renderDiffWithHighlighter } from '../utils/renderDiffWithHighlighter';\nimport { shouldUseTokenTransformer } from '../utils/shouldUseTokenTransformer';\nimport type { WorkerPoolManager } from '../worker';\n\ninterface PushLineWithAnnotation {\n diffStyle: 'unified' | 'split';\n type: 'context' | 'context-expanded' | 'change';\n\n deletionLine?: ElementContent;\n additionLine?: ElementContent;\n\n unifiedSpan?: AnnotationSpan;\n deletionSpan?: AnnotationSpan;\n additionSpan?: AnnotationSpan;\n\n createAnnotationElement(span: AnnotationSpan): HASTElement;\n context: ProcessContext;\n}\n\ninterface GetRenderOptionsReturn {\n options: RenderDiffOptions;\n forceHighlight: boolean;\n}\n\ninterface PushSeparatorProps {\n hunkIndex: number;\n collapsedLines: number;\n rangeSize: number;\n hunkSpecs: string | undefined;\n isFirstHunk: boolean;\n isLastHunk: boolean;\n isExpandable: boolean;\n}\n\ninterface ProcessContext {\n rowCount: number;\n expansionLineCount: number;\n hunkSeparators: HunkSeparators;\n unifiedContentAST: ElementContent[];\n deletionsContentAST: ElementContent[];\n additionsContentAST: ElementContent[];\n unifiedGutterAST: HASTElement;\n deletionsGutterAST: HASTElement;\n additionsGutterAST: HASTElement;\n hunkData: HunkData[];\n pushToGutter(type: CodeColumnType, element: HASTElement): void;\n incrementRowCount(count?: number): void;\n}\n\nexport interface DiffHunksRendererOptions extends BaseDiffOptions {\n headerRenderMode?: FileHeaderRenderMode;\n}\n\nexport interface DiffHunksRendererOptionsWithDefaults extends Omit<\n BaseDiffOptionsWithDefaults,\n 'themeType'\n> {\n headerRenderMode: FileHeaderRenderMode;\n}\n\nexport interface UnifiedLineDecorationProps {\n type: 'context' | 'context-expanded' | 'change';\n lineType: LineTypes;\n additionLineIndex: number | undefined;\n deletionLineIndex: number | undefined;\n}\n\nexport interface SplitLineDecorationProps {\n side: 'deletions' | 'additions';\n type: 'context' | 'context-expanded' | 'change';\n lineIndex: number | undefined;\n}\n\nexport interface LineDecoration {\n gutterLineType: LineTypes;\n gutterProperties?: Properties;\n contentProperties?: Properties;\n}\n\ninterface PendingSplitContext {\n size: number;\n side: 'additions' | 'deletions' | undefined;\n increment(): void;\n flush(): void;\n}\n\nexport interface RenderedLineContext {\n type: 'context' | 'context-expanded' | 'change';\n hunkIndex: number;\n lineIndex: number;\n unifiedLineIndex: number;\n splitLineIndex: number;\n deletionLine?: DiffLineMetadata;\n additionLine?: DiffLineMetadata;\n}\n\nexport interface InjectedRow {\n content: HASTElement;\n gutter: HASTElement;\n}\n\nexport interface SplitInjectedRow {\n deletion: InjectedRow | undefined;\n addition: InjectedRow | undefined;\n}\n\nexport interface UnifiedInjectedRowPlacement {\n before?: InjectedRow[];\n after?: InjectedRow[];\n}\n\nexport interface SplitInjectedRowPlacement {\n before?: SplitInjectedRow[];\n after?: SplitInjectedRow[];\n}\n\nexport interface HunksRenderResult {\n unifiedGutterAST: ElementContent[] | undefined;\n unifiedContentAST: ElementContent[] | undefined;\n deletionsGutterAST: ElementContent[] | undefined;\n deletionsContentAST: ElementContent[] | undefined;\n additionsGutterAST: ElementContent[] | undefined;\n additionsContentAST: ElementContent[] | undefined;\n hunkData: HunkData[];\n css: string;\n preNode: HASTElement;\n headerElement: HASTElement | undefined;\n totalLines: number;\n themeStyles: string;\n baseThemeType: 'light' | 'dark' | undefined;\n rowCount: number;\n bufferBefore: number;\n bufferAfter: number;\n}\n\nlet instanceId = -1;\n\nexport class DiffHunksRenderer<LAnnotation = undefined> {\n readonly __id: string = `diff-hunks-renderer:${++instanceId}`;\n\n private highlighter: DiffsHighlighter | undefined;\n private diff: FileDiffMetadata | undefined;\n\n private expandedHunks = new Map<number, HunkExpansionRegion>();\n\n private deletionAnnotations: AnnotationLineMap<LAnnotation> = {};\n private additionAnnotations: AnnotationLineMap<LAnnotation> = {};\n\n private computedLang: SupportedLanguages = 'text';\n private renderCache: RenderedDiffASTCache | undefined;\n\n constructor(\n public options: DiffHunksRendererOptions = { theme: DEFAULT_THEMES },\n private onRenderUpdate?: () => unknown,\n private workerManager?: WorkerPoolManager | undefined\n ) {\n if (workerManager?.isWorkingPool() !== true) {\n this.highlighter = areThemesAttached(options.theme ?? DEFAULT_THEMES)\n ? getHighlighterIfLoaded()\n : undefined;\n }\n }\n\n public cleanUp(): void {\n this.recycle();\n this.expandedHunks.clear();\n this.workerManager = undefined;\n this.onRenderUpdate = undefined;\n }\n\n public recycle(): void {\n this.highlighter = undefined;\n this.diff = undefined;\n this.clearRenderCache();\n this.additionAnnotations = {};\n this.deletionAnnotations = {};\n this.workerManager?.cleanUpTasks(this);\n }\n\n public clearRenderCache(): void {\n this.renderCache = undefined;\n }\n\n public setOptions(options: DiffHunksRendererOptions): void {\n this.options = options;\n }\n\n public mergeOptions(options: Partial<DiffHunksRendererOptions>): void {\n this.options = { ...this.options, ...options };\n }\n\n public expandHunk(\n index: number,\n direction: ExpansionDirections,\n expansionLineCount: number = this.getOptionsWithDefaults()\n .expansionLineCount\n ): void {\n const region = {\n ...(this.expandedHunks.get(index) ?? {\n fromStart: 0,\n fromEnd: 0,\n }),\n };\n if (direction === 'up' || direction === 'both') {\n region.fromStart += expansionLineCount;\n }\n if (direction === 'down' || direction === 'both') {\n region.fromEnd += expansionLineCount;\n }\n // NOTE(amadeus): If our render cache is not highlighted, we need to clear\n // it, otherwise we won't have the correct AST lines\n if (this.renderCache?.highlighted !== true) {\n this.clearRenderCache();\n }\n this.expandedHunks.set(index, region);\n }\n\n public getExpandedHunk(hunkIndex: number): HunkExpansionRegion {\n return this.expandedHunks.get(hunkIndex) ?? DEFAULT_EXPANDED_REGION;\n }\n\n public getExpandedHunksMap(): Map<number, HunkExpansionRegion> {\n return this.expandedHunks;\n }\n\n public setLineAnnotations(\n lineAnnotations: DiffLineAnnotation<LAnnotation>[]\n ): void {\n this.additionAnnotations = {};\n this.deletionAnnotations = {};\n for (const annotation of lineAnnotations) {\n const map = ((): AnnotationLineMap<LAnnotation> => {\n switch (annotation.side) {\n case 'deletions':\n return this.deletionAnnotations;\n case 'additions':\n return this.additionAnnotations;\n }\n })();\n const arr = map[annotation.lineNumber] ?? [];\n map[annotation.lineNumber] = arr;\n arr.push(annotation);\n }\n }\n\n protected getUnifiedLineDecoration({\n lineType,\n }: UnifiedLineDecorationProps): LineDecoration {\n return { gutterLineType: lineType };\n }\n\n protected getSplitLineDecoration({\n side,\n type,\n }: SplitLineDecorationProps): LineDecoration {\n if (type !== 'change') {\n return { gutterLineType: type };\n }\n return {\n gutterLineType:\n side === 'deletions' ? 'change-deletion' : 'change-addition',\n };\n }\n\n protected createAnnotationElement(span: AnnotationSpan): HASTElement {\n return createDefaultAnnotationElement(span);\n }\n\n // Unified hook returns extra rows that render before/after the current line.\n declare protected getUnifiedInjectedRowsForLine?: (\n ctx: RenderedLineContext\n ) => UnifiedInjectedRowPlacement | undefined;\n\n // Split hook returns extra rows per side before/after the current line.\n declare protected getSplitInjectedRowsForLine?: (\n ctx: RenderedLineContext\n ) => SplitInjectedRowPlacement | undefined;\n\n protected getOptionsWithDefaults(): DiffHunksRendererOptionsWithDefaults {\n const {\n diffIndicators = 'bars',\n diffStyle = 'split',\n disableBackground = false,\n disableFileHeader = false,\n disableLineNumbers = false,\n disableVirtualizationBuffers = false,\n collapsed = false,\n expandUnchanged = false,\n collapsedContextThreshold = DEFAULT_COLLAPSED_CONTEXT_THRESHOLD,\n expansionLineCount = 100,\n hunkSeparators = 'line-info',\n lineDiffType = 'word-alt',\n maxLineDiffLength = 1000,\n overflow = 'scroll',\n stickyHeader = false,\n theme = DEFAULT_THEMES,\n headerRenderMode = 'default',\n tokenizeMaxLineLength = 1000,\n tokenizeMaxLength = DEFAULT_TOKENIZE_MAX_LENGTH,\n useTokenTransformer = false,\n useCSSClasses = false,\n } = this.options;\n return {\n diffIndicators,\n diffStyle,\n disableBackground,\n disableFileHeader,\n disableLineNumbers,\n disableVirtualizationBuffers,\n collapsed,\n expandUnchanged,\n collapsedContextThreshold,\n expansionLineCount,\n hunkSeparators,\n lineDiffType,\n maxLineDiffLength,\n overflow,\n stickyHeader,\n theme: this.workerManager?.getDiffRenderOptions().theme ?? theme,\n headerRenderMode,\n tokenizeMaxLineLength,\n tokenizeMaxLength,\n useTokenTransformer,\n useCSSClasses,\n };\n }\n\n public async initializeHighlighter(): Promise<DiffsHighlighter> {\n this.highlighter = await getSharedHighlighter(\n getHighlighterOptions(this.computedLang, this.options)\n );\n return this.highlighter;\n }\n\n public hydrate(diff: FileDiffMetadata | undefined): void {\n if (diff == null) {\n return;\n }\n this.diff = diff;\n const { options } = this.getRenderOptions(diff);\n const massiveDiff = isDiffMassive(diff, this.getTokenizeMaxLength());\n let cache = this.workerManager?.getDiffResultCache(diff);\n if (cache != null && !areDiffRenderOptionsEqual(options, cache.options)) {\n cache = undefined;\n }\n this.renderCache ??= {\n diff,\n highlighted: !massiveDiff && !isDiffPlainText(diff),\n options,\n result: massiveDiff ? undefined : cache?.result,\n renderRange: undefined,\n };\n if (this.workerManager?.isWorkingPool() === true) {\n if (this.renderCache.result == null && !massiveDiff) {\n // We should only kick off a preload of the AST if we have a WorkerPool\n this.workerManager.highlightDiffAST(this, this.diff);\n }\n }\n // Lets attempt to get the highlighter/languages ready immediately\n else if (this.highlighter == null) {\n this.computedLang = diff.lang ?? getFiletypeFromFileName(diff.name);\n void this.initializeHighlighter();\n }\n }\n\n private getRenderOptions(diff: FileDiffMetadata): GetRenderOptionsReturn {\n const options: RenderDiffOptions = (() => {\n if (this.workerManager?.isWorkingPool() === true) {\n return this.workerManager.getDiffRenderOptions();\n }\n const { theme, tokenizeMaxLineLength, lineDiffType, maxLineDiffLength } =\n this.getOptionsWithDefaults();\n return {\n theme,\n useTokenTransformer: shouldUseTokenTransformer(this.options),\n tokenizeMaxLineLength,\n lineDiffType,\n maxLineDiffLength,\n };\n })();\n this.getOptionsWithDefaults();\n const { renderCache } = this;\n if (renderCache?.result == null) {\n return { options, forceHighlight: true };\n }\n if (\n !areDiffTargetsEqual(diff, renderCache.diff) ||\n !areDiffRenderOptionsEqual(options, renderCache.options)\n ) {\n return { options, forceHighlight: true };\n }\n return { options, forceHighlight: false };\n }\n\n public renderDiff(\n diff: FileDiffMetadata | undefined = this.renderCache?.diff,\n renderRange: RenderRange = DEFAULT_RENDER_RANGE\n ): HunksRenderResult | undefined {\n if (diff == null) {\n return undefined;\n }\n const { expandUnchanged = false, collapsedContextThreshold } =\n this.getOptionsWithDefaults();\n let { options, forceHighlight } = this.getRenderOptions(diff);\n const cache = this.getMatchingWorkerResultCache(diff, options);\n if (cache != null && !this.hasHighlightedRenderCache(diff, options)) {\n this.renderCache = {\n diff,\n highlighted: true,\n renderRange: undefined,\n ...cache,\n };\n forceHighlight = false;\n }\n this.renderCache ??= {\n diff,\n highlighted: false,\n options,\n result: undefined,\n renderRange: undefined,\n };\n const hasContent =\n diff.additionLines.length > 0 || diff.deletionLines.length > 0;\n const forcePlainText =\n !hasContent ||\n isDiffPlainText(diff) ||\n isDiffMassive(diff, this.getTokenizeMaxLength());\n const newContent = !areDiffTargetsEqual(diff, this.renderCache.diff);\n const newRenderRange = !areRenderRangesEqual(\n this.renderCache.renderRange,\n renderRange\n );\n if (this.workerManager?.isWorkingPool() === true) {\n if (\n forcePlainText ||\n this.renderCache.result == null ||\n (!this.renderCache.highlighted && (newContent || newRenderRange))\n ) {\n this.renderCache.diff = diff;\n this.renderCache.options = options;\n this.renderCache.highlighted = false;\n if (\n this.renderCache.result == null ||\n newContent ||\n newRenderRange ||\n forceHighlight\n ) {\n this.renderCache.result = this.workerManager.getPlainDiffAST(\n diff,\n renderRange.startingLine,\n renderRange.totalLines,\n // If we aren't using a windowed render, then we need to render\n // everything\n isDefaultRenderRange(renderRange)\n ? true\n : expandUnchanged\n ? true\n : this.expandedHunks,\n collapsedContextThreshold\n );\n }\n this.renderCache.renderRange = renderRange;\n }\n\n // Should we kick off an async highlight process\n if (\n !forcePlainText &&\n hasContent &&\n (!this.renderCache.highlighted || forceHighlight)\n ) {\n this.workerManager.highlightDiffAST(this, diff);\n }\n } else {\n this.computedLang = diff.lang ?? getFiletypeFromFileName(diff.name);\n const hasThemes =\n this.highlighter != null && areThemesAttached(options.theme);\n const hasLangs =\n this.highlighter != null && areLanguagesAttached(this.computedLang);\n const canHighlight = !forcePlainText && hasLangs;\n\n // If we have any semblance of a highlighter with the correct theme(s)\n // attached, we can kick off some form of rendering. If we don't have\n // the correct language, then we can render plain text and after kick off\n // an async job to get the highlighted AST\n if (\n this.highlighter != null &&\n hasThemes &&\n (forceHighlight ||\n forcePlainText ||\n (!this.renderCache.highlighted && canHighlight) ||\n this.renderCache.result == null)\n ) {\n const { result, options } = this.renderDiffWithHighlighter(\n diff,\n this.highlighter,\n forcePlainText || !hasLangs\n );\n this.renderCache = {\n diff,\n options,\n highlighted: canHighlight,\n result,\n renderRange: undefined,\n };\n }\n\n // If we get in here it means we'll have to kick off an async highlight\n // process which will involve initializing the highlighter with new themes\n // and languages\n if (!hasThemes || (!forcePlainText && !hasLangs)) {\n void this.asyncHighlight(diff).then(({ result, options }) => {\n // In this case we need to force a re-render, so we can do that by\n // reaching into renderCache\n if (this.renderCache != null) {\n this.renderCache.highlighted = false;\n }\n this.onHighlightSuccess(diff, result, options, !forcePlainText);\n });\n }\n }\n return this.renderCache.result != null\n ? this.processDiffResult(\n this.renderCache.diff,\n renderRange,\n this.renderCache.result\n )\n : undefined;\n }\n\n public async asyncRender(\n diff: FileDiffMetadata,\n renderRange: RenderRange = DEFAULT_RENDER_RANGE\n ): Promise<HunksRenderResult> {\n const { result } = await this.asyncHighlight(diff);\n return this.processDiffResult(diff, renderRange, result);\n }\n\n protected createPreElement(\n split: boolean,\n totalLines: number,\n customProperties?: CustomPreProperties\n ): HASTElement {\n const { diffIndicators, disableBackground, disableLineNumbers, overflow } =\n this.getOptionsWithDefaults();\n return createPreElement({\n type: 'diff',\n diffIndicators,\n disableBackground,\n disableLineNumbers,\n overflow,\n split,\n totalLines,\n customProperties,\n });\n }\n\n private async asyncHighlight(\n diff: FileDiffMetadata\n ): Promise<RenderDiffResult> {\n const forcePlainText = isDiffMassive(diff, this.getTokenizeMaxLength());\n this.computedLang = forcePlainText\n ? 'text'\n : (diff.lang ?? getFiletypeFromFileName(diff.name));\n const hasThemes =\n this.highlighter != null &&\n areThemesAttached(this.options.theme ?? DEFAULT_THEMES);\n const hasLangs =\n forcePlainText ||\n (this.highlighter != null && areLanguagesAttached(this.computedLang));\n // If we don't have the required langs or themes, then we need to\n // initialize the highlighter to load the appropriate languages and themes\n if (this.highlighter == null || !hasThemes || !hasLangs) {\n this.highlighter = await this.initializeHighlighter();\n }\n return this.renderDiffWithHighlighter(\n diff,\n this.highlighter,\n forcePlainText\n );\n }\n\n private renderDiffWithHighlighter(\n diff: FileDiffMetadata,\n highlighter: DiffsHighlighter,\n forcePlainText = false\n ): RenderDiffResult {\n const { options } = this.getRenderOptions(diff);\n const { collapsedContextThreshold } = this.getOptionsWithDefaults();\n const result = renderDiffWithHighlighter(diff, highlighter, options, {\n forcePlainText,\n expandedHunks: forcePlainText ? true : undefined,\n collapsedContextThreshold,\n });\n return { result, options };\n }\n\n public onHighlightSuccess(\n diff: FileDiffMetadata,\n result: ThemedDiffResult,\n options: RenderDiffOptions,\n highlighted = true\n ): void {\n // NOTE(amadeus): This is a bad assumption, and I should figure out\n // something better... If renderCache was blown away, we can assume we've\n // run cleanUp()\n if (this.renderCache == null) {\n return;\n }\n\n const triggerRenderUpdate =\n !this.renderCache.highlighted ||\n !areDiffRenderOptionsEqual(this.renderCache.options, options) ||\n !areDiffTargetsEqual(this.renderCache.diff, diff);\n\n this.renderCache = {\n diff,\n options,\n highlighted,\n result,\n renderRange: undefined,\n };\n if (triggerRenderUpdate) {\n this.onRenderUpdate?.();\n }\n }\n\n private getMatchingWorkerResultCache(\n diff: FileDiffMetadata,\n options: RenderDiffOptions\n ): RenderDiffResult | undefined {\n const cache = this.workerManager?.getDiffResultCache(diff);\n if (cache == null || !areDiffRenderOptionsEqual(options, cache.options)) {\n return undefined;\n }\n return cache;\n }\n\n private hasHighlightedRenderCache(\n diff: FileDiffMetadata,\n options: RenderDiffOptions\n ): boolean {\n const { renderCache } = this;\n return (\n renderCache?.result != null &&\n renderCache.highlighted &&\n areDiffTargetsEqual(diff, renderCache.diff) &&\n areDiffRenderOptionsEqual(options, renderCache.options)\n );\n }\n\n public onHighlightError(error: unknown): void {\n console.error(error);\n }\n\n private getTokenizeMaxLength(): number {\n return this.options.tokenizeMaxLength ?? DEFAULT_TOKENIZE_MAX_LENGTH;\n }\n\n private processDiffResult(\n fileDiff: FileDiffMetadata,\n renderRange: RenderRange,\n { code, themeStyles, baseThemeType }: ThemedDiffResult\n ): HunksRenderResult {\n const {\n diffStyle,\n disableFileHeader,\n expandUnchanged,\n expansionLineCount,\n collapsedContextThreshold,\n hunkSeparators,\n } = this.getOptionsWithDefaults();\n\n this.diff = fileDiff;\n const unified = diffStyle === 'unified';\n\n let additionsContentAST: ElementContent[] | undefined = [];\n let deletionsContentAST: ElementContent[] | undefined = [];\n let unifiedContentAST: ElementContent[] | undefined = [];\n\n const hunkData: HunkData[] = [];\n const { additionLines, deletionLines } = code;\n const context: ProcessContext = {\n rowCount: 0,\n hunkSeparators,\n additionsContentAST,\n deletionsContentAST,\n unifiedContentAST,\n unifiedGutterAST: createGutterWrapper(),\n deletionsGutterAST: createGutterWrapper(),\n additionsGutterAST: createGutterWrapper(),\n expansionLineCount,\n hunkData,\n incrementRowCount(count = 1) {\n context.rowCount += count;\n },\n pushToGutter(type: CodeColumnType, element: HASTElement) {\n switch (type) {\n case 'unified': {\n context.unifiedGutterAST.children.push(element);\n break;\n }\n case 'deletions': {\n context.deletionsGutterAST.children.push(element);\n break;\n }\n case 'additions': {\n context.additionsGutterAST.children.push(element);\n break;\n }\n }\n },\n };\n const trailingRangeSize = calculateTrailingRangeSize(fileDiff);\n const pendingSplitContext: PendingSplitContext = {\n size: 0,\n side: undefined,\n increment() {\n this.size += 1;\n },\n flush() {\n if (diffStyle === 'unified') {\n return;\n }\n if (this.size <= 0 || this.side == null) {\n this.side = undefined;\n this.size = 0;\n return;\n }\n if (this.side === 'additions') {\n context.pushToGutter(\n 'additions',\n createGutterGap(undefined, 'buffer', this.size)\n );\n additionsContentAST?.push(createEmptyRowBuffer(this.size));\n } else {\n context.pushToGutter(\n 'deletions',\n createGutterGap(undefined, 'buffer', this.size)\n );\n deletionsContentAST?.push(createEmptyRowBuffer(this.size));\n }\n this.size = 0;\n this.side = undefined;\n },\n };\n\n const pushGutterLineNumber = (\n type: CodeColumnType,\n lineType: LineTypes | 'buffer' | 'separator' | 'annotation',\n lineNumber: number,\n lineIndex: string,\n gutterProperties: Properties | undefined\n ) => {\n context.pushToGutter(\n type,\n createGutterItem(lineType, lineNumber, lineIndex, gutterProperties)\n );\n };\n\n function pushSeparators(props: PushSeparatorProps) {\n pendingSplitContext.flush();\n if (diffStyle === 'unified') {\n pushSeparator('unified', props, context);\n } else {\n pushSeparator('deletions', props, context);\n pushSeparator('additions', props, context);\n }\n }\n\n iterateOverDiff({\n diff: fileDiff,\n diffStyle,\n startingLine: renderRange.startingLine,\n totalLines: renderRange.totalLines,\n expandedHunks: expandUnchanged ? true : this.expandedHunks,\n collapsedContextThreshold,\n callback: ({\n hunkIndex,\n hunk,\n collapsedBefore,\n collapsedAfter,\n additionLine,\n deletionLine,\n type,\n }) => {\n const splitLineIndex =\n deletionLine != null\n ? deletionLine.splitLineIndex\n : additionLine.splitLineIndex;\n const unifiedLineIndex =\n additionLine != null\n ? additionLine.unifiedLineIndex\n : deletionLine.unifiedLineIndex;\n\n if (diffStyle === 'split' && type !== 'change') {\n pendingSplitContext.flush();\n }\n\n if (collapsedBefore > 0) {\n pushSeparators({\n hunkIndex,\n collapsedLines: collapsedBefore,\n rangeSize: Math.max(hunk?.collapsedBefore ?? 0, 0),\n hunkSpecs: hunk?.hunkSpecs,\n isFirstHunk: hunkIndex === 0,\n isLastHunk: false,\n isExpandable: !fileDiff.isPartial,\n });\n }\n\n const lineIndex =\n diffStyle === 'unified' ? unifiedLineIndex : splitLineIndex;\n const renderedLineContext: RenderedLineContext = {\n type,\n hunkIndex,\n lineIndex,\n unifiedLineIndex,\n splitLineIndex,\n deletionLine,\n additionLine,\n };\n\n if (diffStyle === 'unified') {\n const injectedRows =\n this.getUnifiedInjectedRowsForLine?.(renderedLineContext);\n if (injectedRows?.before != null) {\n pushUnifiedInjectedRows(injectedRows.before, context);\n }\n let deletionLineContent =\n deletionLine != null\n ? deletionLines[deletionLine.lineIndex]\n : undefined;\n let additionLineContent =\n additionLine != null\n ? additionLines[additionLine.lineIndex]\n : undefined;\n if (deletionLineContent == null && additionLineContent == null) {\n const errorMessage =\n 'DiffHunksRenderer.processDiffResult: deletionLine and additionLine are null, something is wrong';\n console.error(errorMessage, { file: fileDiff.name });\n throw new Error(errorMessage);\n }\n const lineType =\n type === 'change'\n ? additionLine != null\n ? 'change-addition'\n : 'change-deletion'\n : type;\n const lineDecoration = this.getUnifiedLineDecoration({\n // NOTE: This function gets extended so don't remove\n // these extra props\n type,\n lineType,\n additionLineIndex: additionLine?.lineIndex,\n deletionLineIndex: deletionLine?.lineIndex,\n });\n pushGutterLineNumber(\n 'unified',\n lineDecoration.gutterLineType,\n additionLine != null\n ? additionLine.lineNumber\n : deletionLine.lineNumber,\n `${unifiedLineIndex},${splitLineIndex}`,\n lineDecoration.gutterProperties\n );\n if (additionLineContent != null) {\n additionLineContent = withContentProperties(\n additionLineContent,\n lineDecoration.contentProperties\n );\n } else if (deletionLineContent != null) {\n deletionLineContent = withContentProperties(\n deletionLineContent,\n lineDecoration.contentProperties\n );\n }\n pushLineWithAnnotation({\n diffStyle: 'unified',\n type: type,\n deletionLine: deletionLineContent,\n additionLine: additionLineContent,\n unifiedSpan: this.getAnnotations(\n 'unified',\n deletionLine?.lineNumber,\n additionLine?.lineNumber,\n hunkIndex,\n lineIndex\n ),\n createAnnotationElement: (span) =>\n this.createAnnotationElement(span),\n context,\n });\n if (injectedRows?.after != null) {\n pushUnifiedInjectedRows(injectedRows.after, context);\n }\n } else {\n const injectedRows =\n this.getSplitInjectedRowsForLine?.(renderedLineContext);\n if (injectedRows?.before != null) {\n pushSplitInjectedRows(\n injectedRows.before,\n context,\n pendingSplitContext\n );\n }\n\n let deletionLineContent =\n deletionLine != null\n ? deletionLines[deletionLine.lineIndex]\n : undefined;\n let additionLineContent =\n additionLine != null\n ? additionLines[additionLine.lineIndex]\n : undefined;\n const deletionLineDecoration = this.getSplitLineDecoration({\n side: 'deletions',\n type,\n lineIndex: deletionLine?.lineIndex,\n });\n const additionLineDecoration = this.getSplitLineDecoration({\n side: 'additions',\n type,\n lineIndex: additionLine?.lineIndex,\n });\n\n if (deletionLineContent == null && additionLineContent == null) {\n const errorMessage =\n 'DiffHunksRenderer.processDiffResult: deletionLine and additionLine are null, something is wrong';\n console.error(errorMessage, { file: fileDiff.name });\n throw new Error(errorMessage);\n }\n\n const missingSide = (() => {\n if (type === 'change') {\n if (additionLineContent == null) {\n return 'additions';\n } else if (deletionLineContent == null) {\n return 'deletions';\n }\n }\n return undefined;\n })();\n if (missingSide != null) {\n if (\n pendingSplitContext.side != null &&\n pendingSplitContext.side !== missingSide\n ) {\n // NOTE(amadeus): If we see this error, we might need to bring back: flushSplitSpan();\n throw new Error(\n 'DiffHunksRenderer.processDiffResult: iterateOverDiff, invalid pending splits'\n );\n }\n pendingSplitContext.side = missingSide;\n pendingSplitContext.increment();\n }\n\n const annotationSpans = this.getAnnotations(\n 'split',\n deletionLine?.lineNumber,\n additionLine?.lineNumber,\n hunkIndex,\n lineIndex\n );\n if (annotationSpans != null && pendingSplitContext.size > 0) {\n pendingSplitContext.flush();\n }\n\n if (deletionLine != null) {\n const deletionLineDecorated = withContentProperties(\n deletionLineContent,\n deletionLineDecoration.contentProperties\n );\n pushGutterLineNumber(\n 'deletions',\n deletionLineDecoration.gutterLineType,\n deletionLine.lineNumber,\n `${deletionLine.unifiedLineIndex},${splitLineIndex}`,\n deletionLineDecoration.gutterProperties\n );\n if (deletionLineDecorated != null) {\n deletionLineContent = deletionLineDecorated;\n }\n }\n if (additionLine != null) {\n const additionLineDecorated = withContentProperties(\n additionLineContent,\n additionLineDecoration.contentProperties\n );\n pushGutterLineNumber(\n 'additions',\n additionLineDecoration.gutterLineType,\n additionLine.lineNumber,\n `${additionLine.unifiedLineIndex},${splitLineIndex}`,\n additionLineDecoration.gutterProperties\n );\n if (additionLineDecorated != null) {\n additionLineContent = additionLineDecorated;\n }\n }\n pushLineWithAnnotation({\n diffStyle: 'split',\n type: type,\n additionLine: additionLineContent,\n deletionLine: deletionLineContent,\n ...annotationSpans,\n createAnnotationElement: (span) =>\n this.createAnnotationElement(span),\n context,\n });\n if (injectedRows?.after != null) {\n pushSplitInjectedRows(\n injectedRows.after,\n context,\n pendingSplitContext\n );\n }\n }\n\n const isFinalSplitHunkRow =\n diffStyle === 'split' &&\n hunk != null &&\n splitLineIndex === hunk.splitLineStart + hunk.splitLineCount - 1;\n const splitNoEOFCRDeletion = isFinalSplitHunkRow\n ? hunk.noEOFCRDeletions\n : false;\n const splitNoEOFCRAddition = isFinalSplitHunkRow\n ? hunk.noEOFCRAdditions\n : false;\n const noEOFCRDeletion =\n (deletionLine?.noEOFCR ?? false) || splitNoEOFCRDeletion;\n const noEOFCRAddition =\n (additionLine?.noEOFCR ?? false) || splitNoEOFCRAddition;\n if (noEOFCRAddition || noEOFCRDeletion) {\n if (diffStyle === 'split') {\n pendingSplitContext.flush();\n }\n if (noEOFCRDeletion) {\n const noEOFType =\n type === 'context' || type === 'context-expanded'\n ? type\n : 'change-deletion';\n if (diffStyle === 'unified') {\n context.unifiedContentAST.push(createNoNewlineElement(noEOFType));\n context.pushToGutter(\n 'unified',\n createGutterGap(noEOFType, 'metadata', 1)\n );\n } else {\n context.deletionsContentAST.push(\n createNoNewlineElement(noEOFType)\n );\n context.pushToGutter(\n 'deletions',\n createGutterGap(noEOFType, 'metadata', 1)\n );\n if (!noEOFCRAddition) {\n context.pushToGutter(\n 'additions',\n createGutterGap(undefined, 'buffer', 1)\n );\n context.additionsContentAST.push(createEmptyRowBuffer(1));\n }\n }\n }\n if (noEOFCRAddition) {\n const noEOFType =\n type === 'context' || type === 'context-expanded'\n ? type\n : 'change-addition';\n if (diffStyle === 'unified') {\n context.unifiedContentAST.push(createNoNewlineElement(noEOFType));\n context.pushToGutter(\n 'unified',\n createGutterGap(noEOFType, 'metadata', 1)\n );\n } else {\n context.additionsContentAST.push(\n createNoNewlineElement(noEOFType)\n );\n context.pushToGutter(\n 'additions',\n createGutterGap(noEOFType, 'metadata', 1)\n );\n if (!noEOFCRDeletion) {\n context.pushToGutter(\n 'deletions',\n createGutterGap(undefined, 'buffer', 1)\n );\n context.deletionsContentAST.push(createEmptyRowBuffer(1));\n }\n }\n }\n context.incrementRowCount(1);\n }\n\n if (collapsedAfter > 0 && hunkSeparators !== 'simple') {\n pushSeparators({\n hunkIndex: type === 'context-expanded' ? hunkIndex : hunkIndex + 1,\n collapsedLines: collapsedAfter,\n rangeSize: trailingRangeSize,\n hunkSpecs: undefined,\n isFirstHunk: false,\n isLastHunk: true,\n isExpandable: !fileDiff.isPartial,\n });\n }\n context.incrementRowCount(1);\n },\n });\n\n if (diffStyle === 'split') {\n pendingSplitContext.flush();\n }\n\n const totalLines = Math.max(\n getTotalLineCountFromHunks(fileDiff.hunks),\n fileDiff.additionLines.length ?? 0,\n fileDiff.deletionLines.length ?? 0\n );\n\n const hasBuffer =\n renderRange.bufferBefore > 0 || renderRange.bufferAfter > 0;\n // Determine which ASTs to include based on diff style and file type\n const shouldIncludeAdditions = !unified && fileDiff.type !== 'deleted';\n const shouldIncludeDeletions = !unified && fileDiff.type !== 'new';\n const hasContent = context.rowCount > 0 || hasBuffer;\n\n additionsContentAST =\n shouldIncludeAdditions && hasContent ? additionsContentAST : undefined;\n deletionsContentAST =\n shouldIncludeDeletions && hasContent ? deletionsContentAST : undefined;\n unifiedContentAST = unified && hasContent ? unifiedContentAST : undefined;\n\n const preNode = this.createPreElement(\n deletionsContentAST != null && additionsContentAST != null,\n totalLines\n );\n\n return {\n unifiedGutterAST:\n unified && hasContent ? context.unifiedGutterAST.children : undefined,\n unifiedContentAST,\n deletionsGutterAST:\n shouldIncludeDeletions && hasContent\n ? context.deletionsGutterAST.children\n : undefined,\n deletionsContentAST,\n additionsGutterAST:\n shouldIncludeAdditions && hasContent\n ? context.additionsGutterAST.children\n : undefined,\n additionsContentAST,\n hunkData,\n preNode,\n themeStyles,\n baseThemeType,\n headerElement: !disableFileHeader\n ? this.renderHeader(this.diff)\n : undefined,\n totalLines,\n rowCount: context.rowCount,\n bufferBefore: renderRange.bufferBefore,\n bufferAfter: renderRange.bufferAfter,\n // FIXME\n css: '',\n };\n }\n\n public renderCodeAST(\n type: 'unified' | 'deletions' | 'additions',\n result: HunksRenderResult\n ): ElementContent[] | undefined {\n const gutterAST =\n type === 'unified'\n ? result.unifiedGutterAST\n : type === 'deletions'\n ? result.deletionsGutterAST\n : result.additionsGutterAST;\n\n const contentAST =\n type === 'unified'\n ? result.unifiedContentAST\n : type === 'deletions'\n ? result.deletionsContentAST\n : result.additionsContentAST;\n\n if (gutterAST == null || contentAST == null) {\n return undefined;\n }\n\n const gutter = createGutterWrapper(gutterAST);\n gutter.properties.style = `grid-row: span ${result.rowCount}`;\n const contentColumn = createContentColumn(contentAST, result.rowCount);\n return [gutter, contentColumn];\n }\n\n public renderFullAST(\n result: HunksRenderResult,\n children: ElementContent[] = []\n ): HASTElement {\n const containerSize =\n this.getOptionsWithDefaults().hunkSeparators === 'line-info';\n const unifiedAST = this.renderCodeAST('unified', result);\n if (unifiedAST != null) {\n children.push(\n createHastElement({\n tagName: 'code',\n children: unifiedAST,\n properties: {\n 'data-code': '',\n 'data-container-size': containerSize ? '' : undefined,\n 'data-unified': '',\n },\n })\n );\n return { ...result.preNode, children };\n }\n\n const deletionsAST = this.renderCodeAST('deletions', result);\n if (deletionsAST != null) {\n children.push(\n createHastElement({\n tagName: 'code',\n children: deletionsAST,\n properties: {\n 'data-code': '',\n 'data-container-size': containerSize ? '' : undefined,\n 'data-deletions': '',\n },\n })\n );\n }\n const additionsAST = this.renderCodeAST('additions', result);\n if (additionsAST != null) {\n children.push(\n createHastElement({\n tagName: 'code',\n children: additionsAST,\n properties: {\n 'data-code': '',\n 'data-container-size': containerSize ? '' : undefined,\n 'data-additions': '',\n },\n })\n );\n }\n return { ...result.preNode, children };\n }\n\n public renderFullHTML(\n result: HunksRenderResult,\n tempChildren: ElementContent[] = []\n ): string {\n return toHtml(this.renderFullAST(result, tempChildren));\n }\n\n public renderPartialHTML(\n children: ElementContent[],\n columnType?: 'unified' | 'deletions' | 'additions'\n ): string {\n if (columnType == null) {\n return toHtml(children);\n }\n return toHtml(\n createHastElement({\n tagName: 'code',\n children,\n properties: {\n 'data-code': '',\n 'data-container-size':\n this.getOptionsWithDefaults().hunkSeparators === 'line-info'\n ? ''\n : undefined,\n [`data-${columnType}`]: '',\n },\n })\n );\n }\n\n private getAnnotations(\n type: 'unified',\n deletionLineNumber: number | undefined,\n additionLineNumber: number | undefined,\n hunkIndex: number,\n lineIndex: number\n ): AnnotationSpan | undefined;\n private getAnnotations(\n type: 'split',\n deletionLineNumber: number | undefined,\n additionLineNumber: number | undefined,\n hunkIndex: number,\n lineIndex: number\n ): { deletionSpan: AnnotationSpan; additionSpan: AnnotationSpan } | undefined;\n private getAnnotations(\n type: 'unified' | 'split',\n deletionLineNumber: number | undefined,\n additionLineNumber: number | undefined,\n hunkIndex: number,\n lineIndex: number\n ):\n | AnnotationSpan\n | { deletionSpan: AnnotationSpan; additionSpan: AnnotationSpan }\n | undefined {\n const deletionSpan: AnnotationSpan = {\n type: 'annotation',\n hunkIndex,\n lineIndex,\n annotations: [],\n };\n if (deletionLineNumber != null) {\n for (const anno of this.deletionAnnotations[deletionLineNumber] ?? []) {\n deletionSpan.annotations.push(getLineAnnotationName(anno));\n }\n }\n const additionSpan: AnnotationSpan = {\n type: 'annotation',\n hunkIndex,\n lineIndex,\n annotations: [],\n };\n if (additionLineNumber != null) {\n for (const anno of this.additionAnnotations[additionLineNumber] ?? []) {\n (type === 'unified' ? deletionSpan : additionSpan).annotations.push(\n getLineAnnotationName(anno)\n );\n }\n }\n if (type === 'unified') {\n if (deletionSpan.annotations.length > 0) {\n return deletionSpan;\n }\n return undefined;\n }\n if (\n additionSpan.annotations.length === 0 &&\n deletionSpan.annotations.length === 0\n ) {\n return undefined;\n }\n return { deletionSpan, additionSpan };\n }\n\n private renderHeader(diff: FileDiffMetadata): HASTElement {\n const { headerRenderMode, stickyHeader } = this.getOptionsWithDefaults();\n return createFileHeaderElement({\n fileOrDiff: diff,\n mode: headerRenderMode,\n stickyHeader,\n });\n }\n}\n\nfunction getModifiedLinesString(lines: number) {\n return `${lines} unmodified line${lines > 1 ? 's' : ''}`;\n}\n\nfunction pushUnifiedInjectedRows(\n rows: InjectedRow[],\n context: ProcessContext\n): void {\n for (const row of rows) {\n context.unifiedContentAST.push(row.content);\n context.pushToGutter('unified', row.gutter);\n context.incrementRowCount(1);\n }\n}\n\nfunction pushSplitInjectedRows(\n rows: SplitInjectedRow[],\n context: ProcessContext,\n pendingSplitContext: PendingSplitContext\n): void {\n for (const { deletion, addition } of rows) {\n if (deletion == null && addition == null) {\n continue;\n }\n const missingSide =\n deletion != null && addition != null\n ? undefined\n : deletion == null\n ? 'deletions'\n : 'additions';\n\n if (missingSide == null || pendingSplitContext.side !== missingSide) {\n pendingSplitContext.flush();\n }\n\n if (deletion != null) {\n context.deletionsContentAST.push(deletion.content);\n context.pushToGutter('deletions', deletion.gutter);\n }\n\n if (addition != null) {\n context.additionsContentAST.push(addition.content);\n context.pushToGutter('additions', addition.gutter);\n }\n\n if (missingSide != null) {\n pendingSplitContext.side = missingSide;\n pendingSplitContext.increment();\n }\n\n context.incrementRowCount(1);\n }\n}\n\nfunction pushLineWithAnnotation({\n diffStyle,\n type,\n deletionLine,\n additionLine,\n unifiedSpan,\n deletionSpan,\n additionSpan,\n createAnnotationElement,\n context,\n}: PushLineWithAnnotation) {\n let hasAnnotationRow = false;\n if (diffStyle === 'unified') {\n if (additionLine != null) {\n context.unifiedContentAST.push(additionLine);\n } else if (deletionLine != null) {\n context.unifiedContentAST.push(deletionLine);\n }\n if (unifiedSpan != null) {\n const lineType =\n type === 'change'\n ? deletionLine != null\n ? 'change-deletion'\n : 'change-addition'\n : type;\n context.unifiedContentAST.push(createAnnotationElement(unifiedSpan));\n context.pushToGutter(\n 'unified',\n createGutterGap(lineType, 'annotation', 1)\n );\n hasAnnotationRow = true;\n }\n } else if (diffStyle === 'split') {\n if (deletionLine != null) {\n context.deletionsContentAST.push(deletionLine);\n }\n if (additionLine != null) {\n context.additionsContentAST.push(additionLine);\n }\n if (deletionSpan != null) {\n const lineType =\n type === 'change'\n ? deletionLine != null\n ? 'change-deletion'\n : 'context'\n : type;\n context.deletionsContentAST.push(createAnnotationElement(deletionSpan));\n context.pushToGutter(\n 'deletions',\n createGutterGap(lineType, 'annotation', 1)\n );\n hasAnnotationRow = true;\n }\n if (additionSpan != null) {\n const lineType =\n type === 'change'\n ? additionLine != null\n ? 'change-addition'\n : 'context'\n : type;\n context.additionsContentAST.push(createAnnotationElement(additionSpan));\n context.pushToGutter(\n 'additions',\n createGutterGap(lineType, 'annotation', 1)\n );\n hasAnnotationRow = true;\n }\n }\n if (hasAnnotationRow) {\n context.incrementRowCount(1);\n }\n}\n\nfunction pushSeparator(\n type: 'additions' | 'deletions' | 'unified',\n {\n hunkIndex,\n collapsedLines,\n rangeSize,\n hunkSpecs,\n isFirstHunk,\n isLastHunk,\n isExpandable,\n }: PushSeparatorProps,\n context: ProcessContext\n) {\n if (collapsedLines <= 0) {\n return;\n }\n const linesAST =\n type === 'unified'\n ? context.unifiedContentAST\n : type === 'deletions'\n ? context.deletionsContentAST\n : context.additionsContentAST;\n\n if (context.hunkSeparators === 'metadata') {\n if (hunkSpecs != null) {\n context.pushToGutter(\n type,\n createSeparator({\n type: 'metadata',\n content: hunkSpecs,\n isFirstHunk,\n isLastHunk,\n })\n );\n linesAST.push(\n createSeparator({\n type: 'metadata',\n content: hunkSpecs,\n isFirstHunk,\n isLastHunk,\n })\n );\n if (type !== 'additions') {\n context.incrementRowCount(1);\n }\n }\n return;\n }\n if (context.hunkSeparators === 'simple') {\n if (hunkIndex > 0) {\n context.pushToGutter(\n type,\n createSeparator({ type: 'simple', isFirstHunk, isLastHunk: false })\n );\n linesAST.push(\n createSeparator({ type: 'simple', isFirstHunk, isLastHunk: false })\n );\n if (type !== 'additions') {\n context.incrementRowCount(1);\n }\n }\n return;\n }\n const slotName = getHunkSeparatorSlotName(type, hunkIndex);\n const chunked = rangeSize > context.expansionLineCount;\n const expandIndex = isExpandable ? hunkIndex : undefined;\n context.pushToGutter(\n type,\n createSeparator({\n type: context.hunkSeparators,\n content: getModifiedLinesString(collapsedLines),\n expandIndex,\n chunked,\n slotName,\n isFirstHunk,\n isLastHunk,\n })\n );\n linesAST.push(\n createSeparator({\n type: context.hunkSeparators,\n content: getModifiedLinesString(collapsedLines),\n expandIndex,\n chunked,\n slotName,\n isFirstHunk,\n isLastHunk,\n })\n );\n if (type !== 'additions') {\n context.incrementRowCount(1);\n }\n context.hunkData.push({\n slotName,\n hunkIndex,\n lines: collapsedLines,\n type,\n expandable: isExpandable\n ? { up: !isFirstHunk, down: !isLastHunk, chunked }\n : undefined,\n });\n}\n\nfunction withContentProperties(\n lineNode: ElementContent | undefined,\n contentProperties: Properties | undefined\n): ElementContent | undefined {\n if (\n lineNode == null ||\n lineNode.type !== 'element' ||\n contentProperties == null\n ) {\n return lineNode;\n }\n return {\n ...lineNode,\n properties: {\n ...lineNode.properties,\n ...contentProperties,\n },\n };\n}\n\nfunction isDiffMassive(\n diff: FileDiffMetadata,\n tokenizeMaxLength: number\n): boolean {\n return (\n Math.max(diff.additionLines.length, diff.deletionLines.length) >\n tokenizeMaxLength\n );\n}\n\nfunction calculateTrailingRangeSize(fileDiff: FileDiffMetadata): number {\n const lastHunk = fileDiff.hunks.at(-1);\n if (\n lastHunk == null ||\n fileDiff.isPartial ||\n fileDiff.additionLines.length === 0 ||\n fileDiff.deletionLines.length === 0\n ) {\n return 0;\n }\n const additionRemaining =\n fileDiff.additionLines.length -\n (lastHunk.additionLineIndex + lastHunk.additionCount);\n const deletionRemaining =\n fileDiff.deletionLines.length -\n (lastHunk.deletionLineIndex + lastHunk.deletionCount);\n if (additionRemaining !== deletionRemaining) {\n throw new Error(\n `DiffHunksRenderer.processDiffResult: trailing context mismatch (additions=${additionRemaining}, deletions=${deletionRemaining}) for ${fileDiff.name}`\n );\n }\n return Math.min(additionRemaining, deletionRemaining);\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BaseCodeOptions, DiffsHighlighter, FileContents, FileHeaderRenderMode, LineAnnotation, RenderFileOptions, RenderRange, ThemedFileResult } from "../types.js";
|
|
1
|
+
import { BaseCodeOptions, DiffsHighlighter, DiffsTextDocument, FileContents, FileHeaderRenderMode, HighlightedToken, LineAnnotation, RenderFileOptions, RenderRange, ThemedFileResult } from "../types.js";
|
|
2
2
|
import { WorkerPoolManager } from "../worker/WorkerPoolManager.js";
|
|
3
3
|
import "../worker/index.js";
|
|
4
4
|
import { Element, ElementContent } from "hast";
|
|
@@ -30,6 +30,7 @@ declare class FileRenderer<LAnnotation = undefined> {
|
|
|
30
30
|
private computedLang;
|
|
31
31
|
private lineAnnotations;
|
|
32
32
|
private lineCache;
|
|
33
|
+
private textDoucmentCache;
|
|
33
34
|
constructor(options?: FileRendererOptions, onRenderUpdate?: (() => unknown) | undefined, workerManager?: WorkerPoolManager | undefined);
|
|
34
35
|
setOptions(options: FileRendererOptions): void;
|
|
35
36
|
mergeOptions(options: Partial<FileRendererOptions>): void;
|
|
@@ -40,6 +41,9 @@ declare class FileRenderer<LAnnotation = undefined> {
|
|
|
40
41
|
hydrate(file: FileContents): void;
|
|
41
42
|
private getRenderOptions;
|
|
42
43
|
getOrCreateLineCache(file: FileContents): string[];
|
|
44
|
+
getLineCount(file: FileContents): number;
|
|
45
|
+
applyDirtyLines(dirtyLines: Map<number, Array<HighlightedToken>>, themeType: 'dark' | 'light'): void;
|
|
46
|
+
applyLayoutChange(textDocument: DiffsTextDocument, newLineAnnotations?: LineAnnotation<LAnnotation>[]): void;
|
|
43
47
|
renderFile(file?: FileContents | undefined, renderRange?: RenderRange): FileRenderResult | undefined;
|
|
44
48
|
asyncRender(file: FileContents, renderRange?: RenderRange): Promise<FileRenderResult>;
|
|
45
49
|
private asyncHighlight;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileRenderer.d.ts","names":["ElementContent","Element","HASTElement","BaseCodeOptions","DiffsHighlighter","FileContents","FileHeaderRenderMode","LineAnnotation","RenderFileOptions","RenderRange","ThemedFileResult","WorkerPoolManager","FileRenderResult","FileRendererOptions","FileRenderer","LAnnotation","Partial","Promise"],"sources":["../../src/renderers/FileRenderer.d.ts"],"sourcesContent":["import type { ElementContent, Element as HASTElement } from 'hast';\nimport type { BaseCodeOptions, DiffsHighlighter, FileContents, FileHeaderRenderMode, LineAnnotation, RenderFileOptions, RenderRange, ThemedFileResult } from '../types';\nimport type { WorkerPoolManager } from '../worker';\nexport interface FileRenderResult {\n gutterAST: ElementContent[];\n contentAST: ElementContent[];\n preAST: HASTElement;\n headerAST: HASTElement | undefined;\n css: string;\n totalLines: number;\n themeStyles: string;\n baseThemeType: 'light' | 'dark' | undefined;\n rowCount: number;\n bufferBefore: number;\n bufferAfter: number;\n}\nexport interface FileRendererOptions extends BaseCodeOptions {\n headerRenderMode?: FileHeaderRenderMode;\n}\nexport declare class FileRenderer<LAnnotation = undefined> {\n options: FileRendererOptions;\n private onRenderUpdate?;\n private workerManager?;\n readonly __id: string;\n private highlighter;\n private renderCache;\n private computedLang;\n private lineAnnotations;\n private lineCache;\n constructor(options?: FileRendererOptions, onRenderUpdate?: (() => unknown) | undefined, workerManager?: WorkerPoolManager | undefined);\n setOptions(options: FileRendererOptions): void;\n mergeOptions(options: Partial<FileRendererOptions>): void;\n setLineAnnotations(lineAnnotations: LineAnnotation<LAnnotation>[]): void;\n cleanUp(): void;\n recycle(): void;\n clearRenderCache(): void;\n hydrate(file: FileContents): void;\n private getRenderOptions;\n getOrCreateLineCache(file: FileContents): string[];\n renderFile(file?: FileContents | undefined, renderRange?: RenderRange): FileRenderResult | undefined;\n asyncRender(file: FileContents, renderRange?: RenderRange): Promise<FileRenderResult>;\n private asyncHighlight;\n private renderFileWithHighlighter;\n private processFileResult;\n private renderHeader;\n renderFullHTML(result: FileRenderResult): string;\n renderFullAST(result: FileRenderResult, children?: ElementContent[]): HASTElement;\n renderCodeAST(result: FileRenderResult): ElementContent[];\n renderPartialHTML(children: ElementContent[], includeCodeNode?: boolean): string;\n initializeHighlighter(): Promise<DiffsHighlighter>;\n onHighlightSuccess(file: FileContents, result: ThemedFileResult, options: RenderFileOptions, highlighted?: boolean): void;\n private getMatchingWorkerResultCache;\n private hasHighlightedRenderCache;\n onHighlightError(error: unknown): void;\n private getTokenizeMaxLength;\n private createPreElement;\n}\n//# sourceMappingURL=FileRenderer.d.ts.map"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"FileRenderer.d.ts","names":["ElementContent","Element","HASTElement","BaseCodeOptions","DiffsHighlighter","DiffsTextDocument","FileContents","FileHeaderRenderMode","HighlightedToken","LineAnnotation","RenderFileOptions","RenderRange","ThemedFileResult","WorkerPoolManager","FileRenderResult","FileRendererOptions","FileRenderer","LAnnotation","Partial","Array","Map","Promise"],"sources":["../../src/renderers/FileRenderer.d.ts"],"sourcesContent":["import type { ElementContent, Element as HASTElement } from 'hast';\nimport type { BaseCodeOptions, DiffsHighlighter, DiffsTextDocument, FileContents, FileHeaderRenderMode, HighlightedToken, LineAnnotation, RenderFileOptions, RenderRange, ThemedFileResult } from '../types';\nimport type { WorkerPoolManager } from '../worker';\nexport interface FileRenderResult {\n gutterAST: ElementContent[];\n contentAST: ElementContent[];\n preAST: HASTElement;\n headerAST: HASTElement | undefined;\n css: string;\n totalLines: number;\n themeStyles: string;\n baseThemeType: 'light' | 'dark' | undefined;\n rowCount: number;\n bufferBefore: number;\n bufferAfter: number;\n}\nexport interface FileRendererOptions extends BaseCodeOptions {\n headerRenderMode?: FileHeaderRenderMode;\n}\nexport declare class FileRenderer<LAnnotation = undefined> {\n options: FileRendererOptions;\n private onRenderUpdate?;\n private workerManager?;\n readonly __id: string;\n private highlighter;\n private renderCache;\n private computedLang;\n private lineAnnotations;\n private lineCache;\n private textDoucmentCache;\n constructor(options?: FileRendererOptions, onRenderUpdate?: (() => unknown) | undefined, workerManager?: WorkerPoolManager | undefined);\n setOptions(options: FileRendererOptions): void;\n mergeOptions(options: Partial<FileRendererOptions>): void;\n setLineAnnotations(lineAnnotations: LineAnnotation<LAnnotation>[]): void;\n cleanUp(): void;\n recycle(): void;\n clearRenderCache(): void;\n hydrate(file: FileContents): void;\n private getRenderOptions;\n getOrCreateLineCache(file: FileContents): string[];\n getLineCount(file: FileContents): number;\n applyDirtyLines(dirtyLines: Map<number, Array<HighlightedToken>>, themeType: 'dark' | 'light'): void;\n applyLayoutChange(textDocument: DiffsTextDocument, newLineAnnotations?: LineAnnotation<LAnnotation>[]): void;\n renderFile(file?: FileContents | undefined, renderRange?: RenderRange): FileRenderResult | undefined;\n asyncRender(file: FileContents, renderRange?: RenderRange): Promise<FileRenderResult>;\n private asyncHighlight;\n private renderFileWithHighlighter;\n private processFileResult;\n private renderHeader;\n renderFullHTML(result: FileRenderResult): string;\n renderFullAST(result: FileRenderResult, children?: ElementContent[]): HASTElement;\n renderCodeAST(result: FileRenderResult): ElementContent[];\n renderPartialHTML(children: ElementContent[], includeCodeNode?: boolean): string;\n initializeHighlighter(): Promise<DiffsHighlighter>;\n onHighlightSuccess(file: FileContents, result: ThemedFileResult, options: RenderFileOptions, highlighted?: boolean): void;\n private getMatchingWorkerResultCache;\n private hasHighlightedRenderCache;\n onHighlightError(error: unknown): void;\n private getTokenizeMaxLength;\n private createPreElement;\n}\n//# sourceMappingURL=FileRenderer.d.ts.map"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DEFAULT_RENDER_RANGE, DEFAULT_THEMES, DEFAULT_TOKENIZE_MAX_LENGTH } from "../constants.js";
|
|
2
|
-
import {
|
|
2
|
+
import { areFilesEqual } from "../utils/areFilesEqual.js";
|
|
3
3
|
import { createGutterGap, createGutterItem, createGutterWrapper, createHastElement } from "../utils/hast_utils.js";
|
|
4
4
|
import { areLanguagesAttached } from "../highlighter/languages/areLanguagesAttached.js";
|
|
5
5
|
import { getHighlighterIfLoaded, getSharedHighlighter } from "../highlighter/shared_highlighter.js";
|
|
@@ -7,8 +7,8 @@ import { getThemes } from "../utils/getThemes.js";
|
|
|
7
7
|
import { areThemesAttached } from "../highlighter/themes/areThemesAttached.js";
|
|
8
8
|
import { hasResolvedThemes } from "../highlighter/themes/hasResolvedThemes.js";
|
|
9
9
|
import { areFileRenderOptionsEqual } from "../utils/areFileRenderOptionsEqual.js";
|
|
10
|
-
import { areFilesEqual } from "../utils/areFilesEqual.js";
|
|
11
10
|
import { areRenderRangesEqual } from "../utils/areRenderRangesEqual.js";
|
|
11
|
+
import { linesFromFileContents } from "../utils/computeFileOffsets.js";
|
|
12
12
|
import { createAnnotationElement } from "../utils/createAnnotationElement.js";
|
|
13
13
|
import { createContentColumn } from "../utils/createContentColumn.js";
|
|
14
14
|
import { createFileHeaderElement } from "../utils/createFileHeaderElement.js";
|
|
@@ -17,7 +17,6 @@ import { getFiletypeFromFileName } from "../utils/getFiletypeFromFileName.js";
|
|
|
17
17
|
import { getHighlighterOptions } from "../utils/getHighlighterOptions.js";
|
|
18
18
|
import { getLineAnnotationName } from "../utils/getLineAnnotationName.js";
|
|
19
19
|
import { isFilePlainText } from "../utils/isFilePlainText.js";
|
|
20
|
-
import { splitFileContents } from "../utils/splitFileContents.js";
|
|
21
20
|
import { renderFileWithHighlighter } from "../utils/renderFileWithHighlighter.js";
|
|
22
21
|
import { shouldUseTokenTransformer } from "../utils/shouldUseTokenTransformer.js";
|
|
23
22
|
import { toHtml } from "hast-util-to-html";
|
|
@@ -31,6 +30,7 @@ var FileRenderer = class {
|
|
|
31
30
|
computedLang = "text";
|
|
32
31
|
lineAnnotations = {};
|
|
33
32
|
lineCache;
|
|
33
|
+
textDoucmentCache = /* @__PURE__ */ new WeakMap();
|
|
34
34
|
constructor(options = { theme: DEFAULT_THEMES }, onRenderUpdate, workerManager) {
|
|
35
35
|
this.options = options;
|
|
36
36
|
this.onRenderUpdate = onRenderUpdate;
|
|
@@ -60,9 +60,11 @@ var FileRenderer = class {
|
|
|
60
60
|
this.onRenderUpdate = void 0;
|
|
61
61
|
}
|
|
62
62
|
recycle() {
|
|
63
|
+
const renderCache = this.renderCache;
|
|
63
64
|
this.clearRenderCache();
|
|
64
65
|
this.highlighter = void 0;
|
|
65
66
|
this.workerManager?.cleanUpTasks(this);
|
|
67
|
+
if (renderCache != null && renderCache.isDirty === true && renderCache.file.cacheKey != null) this.workerManager?.evictFileFromCache(renderCache.file.cacheKey);
|
|
66
68
|
this.lineCache = void 0;
|
|
67
69
|
}
|
|
68
70
|
clearRenderCache() {
|
|
@@ -114,16 +116,87 @@ var FileRenderer = class {
|
|
|
114
116
|
getOrCreateLineCache(file) {
|
|
115
117
|
if (file.cacheKey == null) {
|
|
116
118
|
this.lineCache = void 0;
|
|
117
|
-
return
|
|
119
|
+
return linesFromFileContents(file.contents);
|
|
118
120
|
}
|
|
119
121
|
let { lineCache } = this;
|
|
120
122
|
if (lineCache == null || lineCache.cacheKey !== file.cacheKey) lineCache = {
|
|
121
123
|
cacheKey: file.cacheKey,
|
|
122
|
-
lines:
|
|
124
|
+
lines: linesFromFileContents(file.contents)
|
|
123
125
|
};
|
|
124
126
|
this.lineCache = lineCache;
|
|
125
127
|
return lineCache.lines;
|
|
126
128
|
}
|
|
129
|
+
getLineCount(file) {
|
|
130
|
+
return this.textDoucmentCache.get(file)?.lineCount ?? this.getOrCreateLineCache(file).length;
|
|
131
|
+
}
|
|
132
|
+
applyDirtyLines(dirtyLines, themeType) {
|
|
133
|
+
if (this.renderCache == null) return;
|
|
134
|
+
const { result } = this.renderCache;
|
|
135
|
+
if (result == null) return;
|
|
136
|
+
for (const [line, tokens] of dirtyLines) result.code[line] = {
|
|
137
|
+
type: "element",
|
|
138
|
+
tagName: "div",
|
|
139
|
+
properties: {
|
|
140
|
+
"data-line": line + 1,
|
|
141
|
+
"data-line-type": "context",
|
|
142
|
+
"data-line-index": line
|
|
143
|
+
},
|
|
144
|
+
children: tokens.map(([char, fg, text]) => {
|
|
145
|
+
if (char === 0 && fg === "") {
|
|
146
|
+
if (text === "") return {
|
|
147
|
+
type: "element",
|
|
148
|
+
tagName: "br",
|
|
149
|
+
properties: {},
|
|
150
|
+
children: []
|
|
151
|
+
};
|
|
152
|
+
return {
|
|
153
|
+
type: "text",
|
|
154
|
+
value: text
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
return {
|
|
158
|
+
type: "element",
|
|
159
|
+
tagName: "span",
|
|
160
|
+
properties: {
|
|
161
|
+
"data-char": char,
|
|
162
|
+
style: `--diffs-token-${themeType}:${fg};`
|
|
163
|
+
},
|
|
164
|
+
children: [{
|
|
165
|
+
type: "text",
|
|
166
|
+
value: text
|
|
167
|
+
}]
|
|
168
|
+
};
|
|
169
|
+
})
|
|
170
|
+
};
|
|
171
|
+
this.renderCache.isDirty = true;
|
|
172
|
+
}
|
|
173
|
+
applyLayoutChange(textDocument, newLineAnnotations) {
|
|
174
|
+
if (this.renderCache == null) return;
|
|
175
|
+
const { file, result } = this.renderCache;
|
|
176
|
+
if (result != null && result.code.length !== textDocument.lineCount) {
|
|
177
|
+
for (let i = result.code.length; i < textDocument.lineCount; i++) result.code.push({
|
|
178
|
+
type: "element",
|
|
179
|
+
tagName: "div",
|
|
180
|
+
properties: {
|
|
181
|
+
"data-line": i + 1,
|
|
182
|
+
"data-line-type": "context",
|
|
183
|
+
"data-line-index": i
|
|
184
|
+
},
|
|
185
|
+
children: [{
|
|
186
|
+
type: "element",
|
|
187
|
+
tagName: "span",
|
|
188
|
+
properties: { "data-char": 0 },
|
|
189
|
+
children: [{
|
|
190
|
+
type: "text",
|
|
191
|
+
value: textDocument.getLineText(i)
|
|
192
|
+
}]
|
|
193
|
+
}]
|
|
194
|
+
});
|
|
195
|
+
this.renderCache.isDirty = true;
|
|
196
|
+
}
|
|
197
|
+
if (newLineAnnotations != null) this.setLineAnnotations(newLineAnnotations);
|
|
198
|
+
this.textDoucmentCache.set(file, textDocument);
|
|
199
|
+
}
|
|
127
200
|
renderFile(file = this.renderCache?.file, renderRange = DEFAULT_RENDER_RANGE) {
|
|
128
201
|
if (file == null) return;
|
|
129
202
|
let { options, forceHighlight } = this.getRenderOptions(file);
|
|
@@ -200,52 +273,46 @@ var FileRenderer = class {
|
|
|
200
273
|
};
|
|
201
274
|
}
|
|
202
275
|
processFileResult(file, renderRange, { code, themeStyles, baseThemeType }) {
|
|
276
|
+
const totalLines = this.getLineCount(file);
|
|
203
277
|
const { disableFileHeader = false } = this.options;
|
|
204
278
|
const contentArray = [];
|
|
205
279
|
const gutter = createGutterWrapper();
|
|
206
|
-
const
|
|
280
|
+
const endLine = Math.min(renderRange.startingLine + renderRange.totalLines, totalLines);
|
|
207
281
|
let rowCount = 0;
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
lineNumber,
|
|
220
|
-
lines
|
|
221
|
-
});
|
|
222
|
-
throw new Error(message);
|
|
223
|
-
}
|
|
224
|
-
if (line != null) {
|
|
225
|
-
gutter.children.push(createGutterItem("context", lineNumber, `${lineIndex}`));
|
|
226
|
-
contentArray.push(line);
|
|
227
|
-
rowCount++;
|
|
228
|
-
const annotations = this.lineAnnotations[lineNumber];
|
|
229
|
-
if (annotations != null) {
|
|
230
|
-
gutter.children.push(createGutterGap("context", "annotation", 1));
|
|
231
|
-
contentArray.push(createAnnotationElement({
|
|
232
|
-
type: "annotation",
|
|
233
|
-
hunkIndex: 0,
|
|
234
|
-
lineIndex: lineNumber,
|
|
235
|
-
annotations: annotations.map((annotation) => getLineAnnotationName(annotation))
|
|
236
|
-
}));
|
|
237
|
-
rowCount++;
|
|
238
|
-
}
|
|
239
|
-
}
|
|
282
|
+
for (let lineIndex = renderRange.startingLine; lineIndex < endLine; lineIndex++) {
|
|
283
|
+
const lineNumber = lineIndex + 1;
|
|
284
|
+
const line = code[lineIndex];
|
|
285
|
+
if (line == null) {
|
|
286
|
+
const message = "FileRenderer.processFileResult: Line doesnt exist";
|
|
287
|
+
console.error(message, {
|
|
288
|
+
name: file.name,
|
|
289
|
+
lineIndex,
|
|
290
|
+
lineNumber
|
|
291
|
+
});
|
|
292
|
+
throw new Error(message);
|
|
240
293
|
}
|
|
241
|
-
|
|
294
|
+
gutter.children.push(createGutterItem("context", lineNumber, `${lineIndex}`));
|
|
295
|
+
contentArray.push(line);
|
|
296
|
+
rowCount++;
|
|
297
|
+
const annotations = this.lineAnnotations[lineNumber];
|
|
298
|
+
if (annotations != null) {
|
|
299
|
+
gutter.children.push(createGutterGap("context", "annotation", 1));
|
|
300
|
+
contentArray.push(createAnnotationElement({
|
|
301
|
+
type: "annotation",
|
|
302
|
+
hunkIndex: 0,
|
|
303
|
+
lineIndex: lineNumber,
|
|
304
|
+
annotations: annotations.map((annotation) => getLineAnnotationName(annotation))
|
|
305
|
+
}));
|
|
306
|
+
rowCount++;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
242
309
|
gutter.properties.style = `grid-row: span ${rowCount}`;
|
|
243
310
|
return {
|
|
244
311
|
gutterAST: gutter.children ?? [],
|
|
245
312
|
contentAST: contentArray,
|
|
246
|
-
preAST: this.createPreElement(
|
|
313
|
+
preAST: this.createPreElement(totalLines),
|
|
247
314
|
headerAST: !disableFileHeader ? this.renderHeader(file) : void 0,
|
|
248
|
-
totalLines
|
|
315
|
+
totalLines,
|
|
249
316
|
rowCount,
|
|
250
317
|
themeStyles,
|
|
251
318
|
baseThemeType,
|