@pierre/diffs 1.3.0-beta.6 → 1.3.0-beta.7
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 +4 -1
- package/dist/components/CodeView.d.ts.map +1 -1
- package/dist/components/CodeView.js +45 -6
- package/dist/components/CodeView.js.map +1 -1
- package/dist/components/File.d.ts.map +1 -1
- package/dist/components/File.js +5 -2
- package/dist/components/File.js.map +1 -1
- package/dist/components/FileDiff.d.ts +36 -23
- package/dist/components/FileDiff.d.ts.map +1 -1
- package/dist/components/FileDiff.js +126 -58
- package/dist/components/FileDiff.js.map +1 -1
- package/dist/components/UnresolvedFile.d.ts +3 -2
- package/dist/components/UnresolvedFile.d.ts.map +1 -1
- package/dist/components/UnresolvedFile.js +4 -2
- package/dist/components/UnresolvedFile.js.map +1 -1
- package/dist/components/VirtualizedFile.d.ts.map +1 -1
- package/dist/components/VirtualizedFile.js +3 -7
- package/dist/components/VirtualizedFile.js.map +1 -1
- package/dist/components/VirtualizedFileDiff.d.ts +10 -4
- package/dist/components/VirtualizedFileDiff.d.ts.map +1 -1
- package/dist/components/VirtualizedFileDiff.js +178 -49
- package/dist/components/VirtualizedFileDiff.js.map +1 -1
- package/dist/editor/editor.d.ts +2 -2
- package/dist/editor/editor.d.ts.map +1 -1
- package/dist/editor/editor.js +163 -106
- package/dist/editor/editor.js.map +1 -1
- package/dist/editor/editor2.js +1 -1
- package/dist/editor/selection.d.ts +1 -1
- package/dist/editor/selection.d.ts.map +1 -1
- package/dist/editor/selection.js +87 -37
- package/dist/editor/selection.js.map +1 -1
- package/dist/editor/textMeasure.d.ts.map +1 -1
- package/dist/editor/textMeasure.js +25 -7
- package/dist/editor/textMeasure.js.map +1 -1
- package/dist/editor/tokenzier.d.ts +2 -0
- package/dist/editor/tokenzier.d.ts.map +1 -1
- package/dist/editor/tokenzier.js +11 -3
- package/dist/editor/tokenzier.js.map +1 -1
- package/dist/editor/utils.d.ts +3 -1
- package/dist/editor/utils.d.ts.map +1 -1
- package/dist/editor/utils.js +14 -1
- package/dist/editor/utils.js.map +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.js +3 -1
- package/dist/managers/InteractionManager.d.ts.map +1 -1
- package/dist/managers/InteractionManager.js +0 -1
- package/dist/managers/InteractionManager.js.map +1 -1
- package/dist/react/EditorContext.js.map +1 -1
- package/dist/react/MultiFileDiff.d.ts +3 -4
- package/dist/react/MultiFileDiff.d.ts.map +1 -1
- package/dist/react/MultiFileDiff.js.map +1 -1
- package/dist/react/index.d.ts +2 -2
- package/dist/react/utils/useFileDiffInstance.js +14 -15
- package/dist/react/utils/useFileDiffInstance.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 +29 -16
- package/dist/renderers/DiffHunksRenderer.js.map +1 -1
- package/dist/renderers/FileRenderer.js.map +1 -1
- package/dist/ssr/index.d.ts +2 -2
- package/dist/ssr/preloadDiffs.d.ts +11 -10
- package/dist/ssr/preloadDiffs.d.ts.map +1 -1
- package/dist/ssr/preloadDiffs.js +14 -6
- package/dist/ssr/preloadDiffs.js.map +1 -1
- package/dist/types.d.ts +59 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/areHunkDataEqual.js +1 -1
- package/dist/utils/areHunkDataEqual.js.map +1 -1
- package/dist/utils/awaitWithTimeout.d.ts +5 -0
- package/dist/utils/awaitWithTimeout.d.ts.map +1 -0
- package/dist/utils/awaitWithTimeout.js +15 -0
- package/dist/utils/awaitWithTimeout.js.map +1 -0
- package/dist/utils/cloneFileDiffMetadata.d.ts +7 -0
- package/dist/utils/cloneFileDiffMetadata.d.ts.map +1 -0
- package/dist/utils/cloneFileDiffMetadata.js +16 -0
- package/dist/utils/cloneFileDiffMetadata.js.map +1 -0
- package/dist/utils/computeEstimatedDiffHeights.d.ts +3 -1
- package/dist/utils/computeEstimatedDiffHeights.d.ts.map +1 -1
- package/dist/utils/computeEstimatedDiffHeights.js +8 -1
- package/dist/utils/computeEstimatedDiffHeights.js.map +1 -1
- package/dist/utils/createPreElement.js +0 -1
- package/dist/utils/createPreElement.js.map +1 -1
- package/dist/utils/getDiffFileInput.d.ts +14 -0
- package/dist/utils/getDiffFileInput.d.ts.map +1 -0
- package/dist/utils/getDiffFileInput.js +24 -0
- package/dist/utils/getDiffFileInput.js.map +1 -0
- package/dist/utils/getDiffHunksRendererOptions.js +1 -0
- package/dist/utils/getDiffHunksRendererOptions.js.map +1 -1
- package/dist/utils/getFiletypeFromFileName.d.ts.map +1 -1
- package/dist/utils/getFiletypeFromFileName.js +2 -0
- package/dist/utils/getFiletypeFromFileName.js.map +1 -1
- package/dist/utils/hydratePartialDiff.d.ts +10 -0
- package/dist/utils/hydratePartialDiff.d.ts.map +1 -0
- package/dist/utils/hydratePartialDiff.js +140 -0
- package/dist/utils/hydratePartialDiff.js.map +1 -0
- package/dist/utils/iterateOverDiff.js +3 -3
- package/dist/utils/iterateOverDiff.js.map +1 -1
- package/dist/utils/parseDiffFromFile.d.ts +1 -1
- package/dist/utils/parseDiffFromFile.d.ts.map +1 -1
- package/dist/utils/parseDiffFromFile.js +26 -5
- package/dist/utils/parseDiffFromFile.js.map +1 -1
- package/dist/utils/setWrapperNodeProps.js +0 -1
- package/dist/utils/setWrapperNodeProps.js.map +1 -1
- package/dist/utils/updateDiffHunks.d.ts +5 -1
- package/dist/utils/updateDiffHunks.d.ts.map +1 -1
- package/dist/utils/updateDiffHunks.js +26 -4
- package/dist/utils/updateDiffHunks.js.map +1 -1
- package/dist/worker/WorkerPoolManager.d.ts +7 -2
- package/dist/worker/WorkerPoolManager.d.ts.map +1 -1
- package/dist/worker/WorkerPoolManager.js +78 -15
- package/dist/worker/WorkerPoolManager.js.map +1 -1
- package/dist/worker/index.d.ts +2 -2
- package/dist/worker/types.d.ts +7 -1
- package/dist/worker/types.d.ts.map +1 -1
- package/dist/worker/worker-portable.js +5 -3
- package/dist/worker/worker-portable.js.map +1 -1
- package/dist/worker/worker.js +5 -3
- package/dist/worker/worker.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DiffHunksRenderer.js","names":["createDefaultAnnotationElement"],"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 DiffsTextDocument,\n ExpansionDirections,\n FileDiffMetadata,\n FileHeaderRenderMode,\n HighlightedToken,\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 { cleanLastNewline } from '../utils/cleanLastNewline';\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 {\n FILE_ANNOTATION_HUNK_INDEX,\n FILE_ANNOTATION_LINE_INDEX,\n getFileAnnotations,\n shouldRenderFileAnnotations,\n} from '../utils/includesFileAnnotations';\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 { splitFileContents } from '../utils/splitFileContents';\nimport {\n recomputeDiffHunks,\n recomputeEmptyDocumentDiff,\n updateDiffHunks,\n} from '../utils/updateDiffHunks';\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 getRenderDiff(): FileDiffMetadata | undefined {\n return this.renderCache?.diff ?? this.diff;\n }\n\n public clearRenderCache(): void {\n const renderCache = this.renderCache;\n this.renderCache = undefined;\n if (\n renderCache != null &&\n renderCache.isDirty === true &&\n renderCache.diff.cacheKey != null\n ) {\n // The render cache has been updated by the editor, let's purge it\n // from the worker manager cache.\n this.workerManager?.evictDiffFromCache(renderCache.diff.cacheKey);\n }\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 public updateRenderCache(\n dirtyLines: Map<number, Array<HighlightedToken>>,\n themeType: 'dark' | 'light',\n // When a line-count change is being applied in the same edit pass,\n // `applyDocumentChange` recomputes hunk metadata from the full document\n // text immediately after this call, so recomputing here is wasted work\n // (and runs against a mid-update line array). Skip it but keep syncing the\n // per-line token/text content below, which `applyDocumentChange` preserves.\n skipDiffRecompute = false\n ): void {\n if (this.renderCache == null) {\n return;\n }\n const { result, diff } = this.renderCache;\n if (result == null) {\n return;\n }\n if (diff.isPartial) {\n throw new Error('Could not update render cache for partial diff');\n }\n\n const hastLines = result.code.additionLines;\n const changedAdditionLines: number[] = [];\n for (const [line, tokens] of dirtyLines) {\n const prev = hastLines[line] as HASTElement | undefined;\n const prevProps = prev?.properties ?? {};\n const lineText = tokens.map((a) => a[2]).join('');\n const canSyncDiffLine = line < diff.additionLines.length;\n const prevLine = canSyncDiffLine ? (diff.additionLines[line] ?? '') : '';\n const prevText = cleanLastNewline(prevLine);\n // The editor text document can expose one extra trailing empty line when\n // the file ends with a newline. Deferred tokenization must not grow\n // additionLines from that mismatch or hunk trailing context desyncs.\n if (canSyncDiffLine) {\n diff.additionLines[line] = applyLineTextWithNewline(prevLine, lineText);\n if (prevText !== lineText) {\n changedAdditionLines.push(line);\n }\n }\n hastLines[line] = {\n type: 'element',\n tagName: 'div',\n properties: {\n 'data-line': prevProps['data-line'] ?? line + 1,\n 'data-line-index': prevProps['data-line-index'] ?? line,\n 'data-line-type': prevProps['data-line-type'] ?? 'context',\n },\n children: tokens.map(([char, fg, text]) => {\n if (char === 0 && fg === '') {\n if (text === '') {\n return {\n type: 'element',\n tagName: 'br',\n properties: {},\n children: [],\n };\n }\n return { type: 'text', value: text };\n }\n return {\n type: 'element',\n tagName: 'span',\n properties: {\n 'data-char': char,\n style: `--diffs-token-${themeType}:${fg};`,\n },\n children: [{ type: 'text', value: text }],\n };\n }),\n };\n }\n\n if (!skipDiffRecompute && changedAdditionLines.length > 0) {\n Object.assign(\n diff,\n updateDiffHunks(\n diff,\n changedAdditionLines,\n this.options.parseDiffOptions\n )\n );\n }\n\n result.baseThemeType = themeType;\n this.renderCache.isDirty = true;\n }\n\n // Normally triggered by the editor when the document line count changes.\n public applyDocumentChange(textDocument: DiffsTextDocument): void {\n if (this.renderCache == null) {\n return;\n }\n const { diff, result } = this.renderCache;\n if (result == null) {\n return;\n }\n\n // updateRenderCache may already have extended diff.additionLines for the\n // same edit pass, so never bail out purely on matching lengths here.\n diff.additionLines = splitFileContents(textDocument.getText());\n const newLength = diff.additionLines.length;\n\n const additionHastLines = result.code.additionLines;\n const prevLen = additionHastLines.length;\n if (newLength < prevLen) {\n additionHastLines.length = newLength;\n }\n for (let i = prevLen; i < newLength; i++) {\n additionHastLines[i] ??= createPlainAdditionLineElement(i, textDocument);\n }\n if (!diff.isPartial) {\n // An empty document splits into zero addition lines, which would recompute\n // to a diff with no editable rows and leave the attached editor with no\n // line element to host its caret (the additions column vanishes in split;\n // unified shows only deletions). Keep one empty editable line instead.\n if (newLength === 0) {\n Object.assign(\n diff,\n recomputeEmptyDocumentDiff(diff, this.options.parseDiffOptions)\n );\n additionHastLines[0] = createPlainAdditionLineElement(0, textDocument);\n } else {\n Object.assign(\n diff,\n recomputeDiffHunks(diff, this.options.parseDiffOptions)\n );\n }\n }\n\n this.renderCache.isDirty = true;\n }\n\n protected getUnifiedLineDecoration({\n lineType,\n }: UnifiedLineDecorationProps): LineDecoration {\n return {\n gutterLineType: lineType,\n contentProperties: {\n 'data-line-type': lineType,\n },\n };\n }\n\n protected getSplitLineDecoration({\n side,\n type,\n }: SplitLineDecorationProps): LineDecoration {\n const lineType: LineTypes =\n type === 'change'\n ? side === 'deletions'\n ? 'change-deletion'\n : 'change-addition'\n : type;\n return {\n gutterLineType: lineType,\n contentProperties: {\n 'data-line-type': lineType,\n },\n };\n }\n\n private 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 const isRenderCacheDirty = this.renderCache?.isDirty ?? false;\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 this.pushFileLevelAnnotations(fileDiff, diffStyle, renderRange, context);\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 isRenderCacheDirty && additionLine != null\n ? {\n 'data-line': additionLine.lineNumber,\n 'data-line-index': `${unifiedLineIndex},${splitLineIndex}`,\n }\n : undefined\n );\n } else if (deletionLineContent != null) {\n deletionLineContent = withContentProperties(\n deletionLineContent,\n lineDecoration.contentProperties,\n isRenderCacheDirty && deletionLine != null\n ? {\n 'data-line': deletionLine.lineNumber,\n 'data-line-index': `${unifiedLineIndex},${splitLineIndex}`,\n }\n : undefined\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 isRenderCacheDirty\n ? {\n 'data-line': deletionLine.lineNumber,\n 'data-line-index': `${deletionLine.unifiedLineIndex},${splitLineIndex}`,\n }\n : undefined\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 isRenderCacheDirty\n ? {\n 'data-line': additionLine.lineNumber,\n 'data-line-index': `${additionLine.unifiedLineIndex},${splitLineIndex}`,\n }\n : undefined\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 pushFileLevelAnnotations(\n fileDiff: FileDiffMetadata,\n diffStyle: 'unified' | 'split',\n renderRange: RenderRange,\n context: ProcessContext\n ): void {\n if (!shouldRenderFileAnnotations(renderRange)) {\n return;\n }\n\n const deletionAnnotationNames =\n fileDiff.type !== 'new'\n ? getAnnotationNames(getFileAnnotations(this.deletionAnnotations))\n : [];\n const additionAnnotationNames =\n fileDiff.type !== 'deleted'\n ? getAnnotationNames(getFileAnnotations(this.additionAnnotations))\n : [];\n if (\n deletionAnnotationNames.length === 0 &&\n additionAnnotationNames.length === 0\n ) {\n return;\n }\n\n const hunkIndex = FILE_ANNOTATION_HUNK_INDEX;\n const lineIndex = FILE_ANNOTATION_LINE_INDEX;\n const { createAnnotationElement } = this;\n\n if (diffStyle === 'unified') {\n pushLineWithAnnotation({\n diffStyle,\n type: 'context',\n unifiedSpan: {\n type: 'annotation',\n hunkIndex,\n lineIndex,\n annotations: deletionAnnotationNames.concat(additionAnnotationNames),\n },\n createAnnotationElement,\n context,\n });\n return;\n }\n\n pushLineWithAnnotation({\n diffStyle,\n type: 'context',\n deletionSpan: {\n type: 'annotation',\n hunkIndex,\n lineIndex,\n annotations: deletionAnnotationNames,\n },\n additionSpan: {\n type: 'annotation',\n hunkIndex,\n lineIndex,\n annotations: additionAnnotationNames,\n },\n createAnnotationElement,\n context,\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 getAnnotationNames<LAnnotation>(\n annotations: DiffLineAnnotation<LAnnotation>[] | undefined\n): string[] {\n return (\n annotations?.map((annotation) => getLineAnnotationName(annotation)) ?? []\n );\n}\n\n// Use the platform's English plural rules to pick \"line\" vs \"lines\" so a\n// count of 0 reads as \"0 unmodified lines\". en-US returns \"one\" only for 1.\nconst EN_PLURAL_RULES = new Intl.PluralRules('en-US');\n\nfunction getModifiedLinesString(lines: number) {\n const suffix = EN_PLURAL_RULES.select(lines) === 'one' ? '' : 's';\n return `${lines} unmodified line${suffix}`;\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,\n extendProperties?: Properties\n): ElementContent | undefined {\n if (\n lineNode == null ||\n lineNode.type !== 'element' ||\n (contentProperties == null && extendProperties == null)\n ) {\n return lineNode;\n }\n return {\n ...lineNode,\n properties: {\n ...lineNode.properties,\n ...contentProperties,\n ...extendProperties,\n },\n };\n}\n\nfunction createPlainAdditionLineElement(\n lineIndex: number,\n textDocument: DiffsTextDocument\n): HASTElement {\n return {\n type: 'element',\n tagName: 'div',\n properties: {\n 'data-line': lineIndex + 1,\n 'data-line-index': `${lineIndex},${lineIndex}`,\n 'data-line-type': 'context',\n },\n children: [\n {\n type: 'element',\n tagName: 'span',\n properties: {\n 'data-char': 0,\n },\n children: [\n {\n type: 'text',\n value: textDocument.getLineText(lineIndex),\n },\n ],\n },\n ],\n };\n}\n\n// Editor line text omits line endings; diff line arrays keep the suffix from parsing.\nfunction applyLineTextWithNewline(line: string, lineText: string): string {\n if (line.endsWith('\\r\\n')) {\n return lineText + '\\r\\n';\n }\n if (line.endsWith('\\r')) {\n return lineText + '\\r';\n }\n if (line.endsWith('\\n')) {\n return lineText + '\\n';\n }\n return lineText;\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":["createDefaultAnnotationElement"],"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 DiffsTextDocument,\n ExpansionDirections,\n FileDiffMetadata,\n FileHeaderRenderMode,\n HighlightedToken,\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 { cleanLastNewline } from '../utils/cleanLastNewline';\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 {\n FILE_ANNOTATION_HUNK_INDEX,\n FILE_ANNOTATION_LINE_INDEX,\n getFileAnnotations,\n shouldRenderFileAnnotations,\n} from '../utils/includesFileAnnotations';\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 { splitFileContents } from '../utils/splitFileContents';\nimport {\n recomputeDiffHunksForEdit,\n recomputeEmptyDocumentDiff,\n updateDiffHunks,\n} from '../utils/updateDiffHunks';\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 | 'unknown';\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 getDiffCache(): FileDiffMetadata | undefined {\n return this.renderCache?.diff ?? this.diff;\n }\n\n public clearRenderCache(): void {\n const renderCache = this.renderCache;\n this.renderCache = undefined;\n if (\n renderCache != null &&\n renderCache.isDirty === true &&\n renderCache.diff.cacheKey != null\n ) {\n // The render cache has been updated by the host, let's purge it\n // from the worker manager cache.\n this.workerManager?.evictDiffFromCache(renderCache.diff.cacheKey);\n }\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 public updateRenderCache(\n dirtyLines: Map<number, Array<HighlightedToken>>,\n themeType: 'dark' | 'light'\n ): void {\n if (this.renderCache == null) {\n return;\n }\n const { result, diff } = this.renderCache;\n if (result == null) {\n return;\n }\n if (diff.isPartial) {\n throw new Error('Could not update render cache for partial diff');\n }\n\n const hastLines = result.code.additionLines;\n const changedAdditionLines: number[] = [];\n for (const [line, tokens] of dirtyLines) {\n const prev = hastLines[line] as HASTElement | undefined;\n const prevProps = prev?.properties ?? {};\n const lineText = tokens.map((a) => a[2]).join('');\n const canSyncDiffLine = line < diff.additionLines.length;\n const prevLine = canSyncDiffLine ? (diff.additionLines[line] ?? '') : '';\n const prevText = cleanLastNewline(prevLine);\n // The host text document can expose one extra trailing empty line when\n // the file ends with a newline. Deferred tokenization must not grow\n // additionLines from that mismatch or hunk trailing context desyncs.\n if (canSyncDiffLine) {\n diff.additionLines[line] = applyLineTextWithNewline(prevLine, lineText);\n if (prevText !== lineText) {\n changedAdditionLines.push(line);\n }\n }\n hastLines[line] = {\n type: 'element',\n tagName: 'div',\n properties: {\n 'data-line': prevProps['data-line'] ?? line + 1,\n 'data-line-index': prevProps['data-line-index'] ?? line,\n 'data-line-type': prevProps['data-line-type'] ?? 'context',\n },\n children: tokens.map(([char, fg, text]) => {\n if (char === 0 && fg === '') {\n if (text === '') {\n return {\n type: 'element',\n tagName: 'br',\n properties: {},\n children: [],\n };\n }\n return { type: 'text', value: text };\n }\n return {\n type: 'element',\n tagName: 'span',\n properties: {\n 'data-char': char,\n style: `--diffs-token-${themeType}:${fg};`,\n },\n children: [{ type: 'text', value: text }],\n };\n }),\n };\n }\n\n if (changedAdditionLines.length > 0) {\n Object.assign(\n diff,\n updateDiffHunks(\n diff,\n changedAdditionLines,\n this.options.parseDiffOptions\n )\n );\n }\n\n result.baseThemeType = themeType;\n this.renderCache.isDirty = true;\n }\n\n // Normally triggered by the host when the document line count changes.\n public applyDocumentChange(textDocument: DiffsTextDocument): void {\n if (this.renderCache == null) {\n return;\n }\n const { diff, result } = this.renderCache;\n if (result == null) {\n return;\n }\n\n // updateRenderCache may already have extended diff.additionLines for the\n // same edit pass, so never bail out purely on matching lengths here.\n const documentText = textDocument.getText();\n if (documentText.trim().length === 0) {\n // Blank documents need the editor's logical line count: `\"\\n\"` is two\n // editable rows even though the diff parser sees one newline token.\n const lines: string[] = [];\n for (let line = 0; line < textDocument.lineCount; line++) {\n lines.push(textDocument.getLineText(line, true));\n }\n diff.additionLines = lines;\n } else {\n diff.additionLines = splitFileContents(documentText);\n }\n\n const newLength = diff.additionLines.length;\n const additionHastLines = result.code.additionLines;\n const prevLen = additionHastLines.length;\n if (newLength < prevLen) {\n additionHastLines.length = newLength;\n }\n for (let i = prevLen; i < newLength; i++) {\n additionHastLines[i] ??= createPlainAdditionLineElement(i, textDocument);\n }\n if (!diff.isPartial) {\n // An empty document splits into zero addition lines, which would recompute\n // to a diff with no editable rows and leave the attached host with no\n // line element for its caret (the additions column vanishes in split;\n // unified shows only deletions). Keep one empty editable line instead.\n if (\n diff.additionLines.length <= 1 &&\n diff.additionLines.join('') === ''\n ) {\n Object.assign(\n diff,\n recomputeEmptyDocumentDiff(diff, this.options.parseDiffOptions)\n );\n additionHastLines[0] = createPlainAdditionLineElement(0, textDocument);\n } else {\n Object.assign(\n diff,\n recomputeDiffHunksForEdit(diff, this.options.parseDiffOptions)\n );\n }\n }\n\n this.renderCache.isDirty = true;\n }\n\n protected getUnifiedLineDecoration({\n lineType,\n }: UnifiedLineDecorationProps): LineDecoration {\n return {\n gutterLineType: lineType,\n contentProperties: {\n 'data-line-type': lineType,\n },\n };\n }\n\n protected getSplitLineDecoration({\n side,\n type,\n }: SplitLineDecorationProps): LineDecoration {\n const lineType: LineTypes =\n type === 'change'\n ? side === 'deletions'\n ? 'change-deletion'\n : 'change-addition'\n : type;\n return {\n gutterLineType: lineType,\n contentProperties: {\n 'data-line-type': lineType,\n },\n };\n }\n\n private 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 const isRenderCacheDirty = this.renderCache?.isDirty ?? false;\n\n this.diff = fileDiff;\n const unified = diffStyle === 'unified';\n const canHydrateContext = canHydrateCollapsedContext(\n fileDiff,\n this.options.loadDiffFiles != null\n );\n const isExpandableDiff = !fileDiff.isPartial || canHydrateContext;\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 this.pushFileLevelAnnotations(fileDiff, diffStyle, renderRange, context);\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: isExpandableDiff,\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 isRenderCacheDirty && additionLine != null\n ? {\n 'data-line': additionLine.lineNumber,\n 'data-line-index': `${unifiedLineIndex},${splitLineIndex}`,\n }\n : undefined\n );\n } else if (deletionLineContent != null) {\n deletionLineContent = withContentProperties(\n deletionLineContent,\n lineDecoration.contentProperties,\n isRenderCacheDirty && deletionLine != null\n ? {\n 'data-line': deletionLine.lineNumber,\n 'data-line-index': `${unifiedLineIndex},${splitLineIndex}`,\n }\n : undefined\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 isRenderCacheDirty\n ? {\n 'data-line': deletionLine.lineNumber,\n 'data-line-index': `${deletionLine.unifiedLineIndex},${splitLineIndex}`,\n }\n : undefined\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 isRenderCacheDirty\n ? {\n 'data-line': additionLine.lineNumber,\n 'data-line-index': `${additionLine.unifiedLineIndex},${splitLineIndex}`,\n }\n : undefined\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 isFinalHunkRow =\n hunkIndex === fileDiff.hunks.length - 1 &&\n hunk != null &&\n (diffStyle === 'split'\n ? splitLineIndex === hunk.splitLineStart + hunk.splitLineCount - 1\n : unifiedLineIndex ===\n hunk.unifiedLineStart + hunk.unifiedLineCount - 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 (\n hunkSeparators !== 'simple' &&\n hunkSeparators !== 'metadata' &&\n (collapsedAfter > 0 || (isFinalHunkRow && canHydrateContext))\n ) {\n pushSeparators({\n hunkIndex: type === 'context-expanded' ? hunkIndex : hunkIndex + 1,\n collapsedLines:\n isFinalHunkRow && canHydrateContext ? 'unknown' : collapsedAfter,\n rangeSize: trailingRangeSize,\n hunkSpecs: undefined,\n isFirstHunk: false,\n isLastHunk: true,\n isExpandable: isExpandableDiff,\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 pushFileLevelAnnotations(\n fileDiff: FileDiffMetadata,\n diffStyle: 'unified' | 'split',\n renderRange: RenderRange,\n context: ProcessContext\n ): void {\n if (!shouldRenderFileAnnotations(renderRange)) {\n return;\n }\n\n const deletionAnnotationNames =\n fileDiff.type !== 'new'\n ? getAnnotationNames(getFileAnnotations(this.deletionAnnotations))\n : [];\n const additionAnnotationNames =\n fileDiff.type !== 'deleted'\n ? getAnnotationNames(getFileAnnotations(this.additionAnnotations))\n : [];\n if (\n deletionAnnotationNames.length === 0 &&\n additionAnnotationNames.length === 0\n ) {\n return;\n }\n\n const hunkIndex = FILE_ANNOTATION_HUNK_INDEX;\n const lineIndex = FILE_ANNOTATION_LINE_INDEX;\n const { createAnnotationElement } = this;\n\n if (diffStyle === 'unified') {\n pushLineWithAnnotation({\n diffStyle,\n type: 'context',\n unifiedSpan: {\n type: 'annotation',\n hunkIndex,\n lineIndex,\n annotations: deletionAnnotationNames.concat(additionAnnotationNames),\n },\n createAnnotationElement,\n context,\n });\n return;\n }\n\n pushLineWithAnnotation({\n diffStyle,\n type: 'context',\n deletionSpan: {\n type: 'annotation',\n hunkIndex,\n lineIndex,\n annotations: deletionAnnotationNames,\n },\n additionSpan: {\n type: 'annotation',\n hunkIndex,\n lineIndex,\n annotations: additionAnnotationNames,\n },\n createAnnotationElement,\n context,\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 getAnnotationNames<LAnnotation>(\n annotations: DiffLineAnnotation<LAnnotation>[] | undefined\n): string[] {\n return (\n annotations?.map((annotation) => getLineAnnotationName(annotation)) ?? []\n );\n}\n\n// Use the platform's English plural rules to pick \"line\" vs \"lines\" so a\n// count of 0 reads as \"0 unmodified lines\". en-US returns \"one\" only for 1.\nconst EN_PLURAL_RULES = new Intl.PluralRules('en-US');\n\nfunction getModifiedLinesString(lines: number) {\n const suffix = EN_PLURAL_RULES.select(lines) === 'one' ? '' : 's';\n return `${lines} unmodified line${suffix}`;\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 (typeof collapsedLines === 'number' && 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 const content =\n typeof collapsedLines === 'number'\n ? getModifiedLinesString(collapsedLines)\n : 'More unchanged context may be available';\n context.pushToGutter(\n type,\n createSeparator({\n type: context.hunkSeparators,\n content,\n expandIndex,\n chunked,\n slotName,\n isFirstHunk,\n isLastHunk,\n })\n );\n linesAST.push(\n createSeparator({\n type: context.hunkSeparators,\n content,\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: typeof collapsedLines === 'number' ? collapsedLines : 0,\n lineCountKnown: typeof collapsedLines === 'number',\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,\n extendProperties?: Properties\n): ElementContent | undefined {\n if (\n lineNode == null ||\n lineNode.type !== 'element' ||\n (contentProperties == null && extendProperties == null)\n ) {\n return lineNode;\n }\n return {\n ...lineNode,\n properties: {\n ...lineNode.properties,\n ...contentProperties,\n ...extendProperties,\n },\n };\n}\n\nfunction createPlainAdditionLineElement(\n lineIndex: number,\n textDocument: DiffsTextDocument\n): HASTElement {\n return {\n type: 'element',\n tagName: 'div',\n properties: {\n 'data-line': lineIndex + 1,\n 'data-line-index': `${lineIndex},${lineIndex}`,\n 'data-line-type': 'context',\n },\n children: [\n {\n type: 'element',\n tagName: 'span',\n properties: {\n 'data-char': 0,\n },\n children: [\n {\n type: 'text',\n value: textDocument.getLineText(lineIndex),\n },\n ],\n },\n ],\n };\n}\n\n// Host line text omits line endings; diff line arrays keep the suffix from parsing.\nfunction applyLineTextWithNewline(line: string, lineText: string): string {\n if (line.endsWith('\\r\\n')) {\n return lineText + '\\r\\n';\n }\n if (line.endsWith('\\r')) {\n return lineText + '\\r';\n }\n if (line.endsWith('\\n')) {\n return lineText + '\\n';\n }\n return lineText;\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 canHydrateCollapsedContext(\n fileDiff: FileDiffMetadata,\n hasFileLoader: boolean\n): boolean {\n return (\n fileDiff.isPartial &&\n hasFileLoader &&\n (fileDiff.type === 'change' || fileDiff.type === 'rename-changed')\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileRenderer.js","names":[],"sources":["../../src/renderers/FileRenderer.ts"],"sourcesContent":["import type { ElementContent, Element as HASTElement } from 'hast';\nimport { toHtml } from 'hast-util-to-html';\n\nimport {\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 { hasResolvedThemes } from '../highlighter/themes/hasResolvedThemes';\nimport type {\n BaseCodeOptions,\n DiffsHighlighter,\n DiffsTextDocument,\n FileContents,\n FileHeaderRenderMode,\n HighlightedToken,\n LineAnnotation,\n RenderedFileASTCache,\n RenderFileOptions,\n RenderFileResult,\n RenderRange,\n SupportedLanguages,\n ThemedFileResult,\n} from '../types';\nimport { areFileRenderOptionsEqual } from '../utils/areFileRenderOptionsEqual';\nimport { areFilesEqual } from '../utils/areFilesEqual';\nimport { areRenderRangesEqual } from '../utils/areRenderRangesEqual';\nimport { linesFromFileContents } from '../utils/computeFileOffsets';\nimport { createAnnotationElement } from '../utils/createAnnotationElement';\nimport { createContentColumn } from '../utils/createContentColumn';\nimport { createFileHeaderElement } from '../utils/createFileHeaderElement';\nimport { createPreElement } from '../utils/createPreElement';\nimport { getFiletypeFromFileName } from '../utils/getFiletypeFromFileName';\nimport { getHighlighterOptions } from '../utils/getHighlighterOptions';\nimport { getLineAnnotationName } from '../utils/getLineAnnotationName';\nimport { getThemes } from '../utils/getThemes';\nimport {\n createGutterGap,\n createGutterItem,\n createGutterWrapper,\n createHastElement,\n} from '../utils/hast_utils';\nimport {\n FILE_ANNOTATION_HUNK_INDEX,\n FILE_ANNOTATION_LINE_INDEX,\n getFileAnnotations,\n shouldRenderFileAnnotations,\n} from '../utils/includesFileAnnotations';\nimport { isFilePlainText } from '../utils/isFilePlainText';\nimport { renderFileWithHighlighter } from '../utils/renderFileWithHighlighter';\nimport { shouldUseTokenTransformer } from '../utils/shouldUseTokenTransformer';\nimport type { WorkerPoolManager } from '../worker';\n\ntype AnnotationLineMap<LAnnotation> = Record<\n number,\n LineAnnotation<LAnnotation>[] | undefined\n>;\n\ninterface GetRenderOptionsReturn {\n options: RenderFileOptions;\n forceHighlight: boolean;\n}\n\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}\n\ninterface LineCache {\n cacheKey: string | undefined;\n lines: string[];\n}\n\nexport interface FileRendererOptions extends BaseCodeOptions {\n headerRenderMode?: FileHeaderRenderMode;\n}\n\nlet instanceId = -1;\n\nexport class FileRenderer<LAnnotation = undefined> {\n readonly __id: string = `file-renderer:${++instanceId}`;\n\n private highlighter: DiffsHighlighter | undefined;\n private renderCache: RenderedFileASTCache | undefined;\n private computedLang: SupportedLanguages = 'text';\n private lineAnnotations: AnnotationLineMap<LAnnotation> = {};\n private lineCache: LineCache | undefined;\n private textDoucmentCache = new WeakMap<FileContents, DiffsTextDocument>();\n\n constructor(\n public options: FileRendererOptions = { 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 setOptions(options: FileRendererOptions): void {\n this.options = options;\n }\n\n public mergeOptions(options: Partial<FileRendererOptions>): void {\n this.options = { ...this.options, ...options };\n }\n\n public setLineAnnotations(\n lineAnnotations: LineAnnotation<LAnnotation>[]\n ): void {\n this.lineAnnotations = {};\n for (const annotation of lineAnnotations) {\n const arr = this.lineAnnotations[annotation.lineNumber] ?? [];\n this.lineAnnotations[annotation.lineNumber] = arr;\n arr.push(annotation);\n }\n }\n\n public cleanUp(): void {\n this.recycle();\n this.workerManager = undefined;\n this.onRenderUpdate = undefined;\n }\n\n public recycle(): void {\n this.clearRenderCache();\n this.highlighter = undefined;\n this.workerManager?.cleanUpTasks(this);\n this.lineCache = undefined;\n }\n\n public clearRenderCache(): void {\n const renderCache = this.renderCache;\n this.renderCache = undefined;\n if (\n renderCache != null &&\n renderCache.isDirty === true &&\n renderCache.file.cacheKey != null\n ) {\n // The render cache has been updated by the editor, let's purge it\n // from the worker manager cache.\n this.workerManager?.evictFileFromCache(renderCache.file.cacheKey);\n }\n }\n\n public hydrate(file: FileContents): void {\n const { options } = this.getRenderOptions(file);\n const lines = this.getOrCreateLineCache(file);\n const massiveFile = isFileMassive(\n lines.length,\n this.getTokenizeMaxLength()\n );\n let cache = this.workerManager?.getFileResultCache(file);\n if (cache != null && !areFileRenderOptionsEqual(options, cache.options)) {\n cache = undefined;\n }\n this.renderCache ??= {\n file,\n options,\n highlighted: !massiveFile && !isFilePlainText(file),\n result: massiveFile ? undefined : cache?.result,\n // FIXME(amadeus): Add support for renderRanges\n renderRange: undefined,\n };\n if (this.workerManager?.isWorkingPool() === true) {\n if (this.renderCache.result == null && !massiveFile) {\n // We should only kick off a preload of the AST if we have a WorkerPool\n this.workerManager.highlightFileAST(this, file);\n }\n }\n // Lets attempt to get the highlighter/languages ready immediately\n else if (this.highlighter == null) {\n this.computedLang = file.lang ?? getFiletypeFromFileName(file.name);\n void this.initializeHighlighter();\n }\n }\n\n private getRenderOptions(file: FileContents): GetRenderOptionsReturn {\n const options: RenderFileOptions = (() => {\n if (this.workerManager?.isWorkingPool() === true) {\n return this.workerManager.getFileRenderOptions();\n }\n const { theme = DEFAULT_THEMES, tokenizeMaxLineLength = 1000 } =\n this.options;\n return {\n theme,\n useTokenTransformer: shouldUseTokenTransformer(this.options),\n tokenizeMaxLineLength,\n };\n })();\n const { renderCache } = this;\n if (renderCache?.result == null) {\n return { options, forceHighlight: true };\n }\n if (\n !areFilesEqual(file, renderCache.file) ||\n !areFileRenderOptionsEqual(options, renderCache.options)\n ) {\n return { options, forceHighlight: true };\n }\n return { options, forceHighlight: false };\n }\n\n public getOrCreateLineCache(file: FileContents): string[] {\n // Uncached files will get split every time, not the greatest experience\n // tbh... but something people should try to optimize away\n if (file.cacheKey == null) {\n this.lineCache = undefined;\n return linesFromFileContents(file.contents);\n }\n\n let { lineCache } = this;\n if (lineCache == null || lineCache.cacheKey !== file.cacheKey) {\n lineCache = {\n cacheKey: file.cacheKey,\n lines: linesFromFileContents(file.contents),\n };\n }\n this.lineCache = lineCache;\n return lineCache.lines;\n }\n\n // when a emitLineCountChange is called,\n // calculate the line count using the cached text document\n public getLineCount(file: FileContents): number {\n return (\n this.textDoucmentCache.get(file)?.lineCount ??\n this.getOrCreateLineCache(file).length\n );\n }\n\n public updateRenderCache(\n dirtyLines: Map<number, Array<HighlightedToken>>,\n themeType: 'dark' | 'light'\n ): void {\n if (this.renderCache == null) {\n return;\n }\n const { result } = this.renderCache;\n if (result == null) {\n return;\n }\n for (const [line, tokens] of dirtyLines) {\n result.code[line] = {\n type: 'element',\n tagName: 'div',\n properties: {\n 'data-line': line + 1,\n 'data-line-type': 'context',\n 'data-line-index': line,\n },\n children: tokens.map(([char, fg, text]) => {\n if (char === 0 && fg === '') {\n if (text === '') {\n return {\n type: 'element',\n tagName: 'br',\n properties: {},\n children: [],\n };\n }\n return { type: 'text', value: text };\n }\n return {\n type: 'element',\n tagName: 'span',\n properties: {\n 'data-char': char,\n style: `--diffs-token-${themeType}:${fg};`,\n },\n children: [{ type: 'text', value: text }],\n };\n }),\n };\n }\n\n result.baseThemeType = themeType;\n this.renderCache.isDirty = true;\n }\n\n // normally triggered by the editor when the document line count changes\n public applyDocumentChange(textDocument: DiffsTextDocument): void {\n if (this.renderCache == null) {\n return undefined;\n }\n const { file, result } = this.renderCache;\n if (result != null && result.code.length !== textDocument.lineCount) {\n result.code.length = Math.min(result.code.length, textDocument.lineCount);\n for (let i = result.code.length; i < textDocument.lineCount; i++) {\n // prefill lines with plain text content\n result.code.push({\n type: 'element',\n tagName: 'div',\n properties: {\n 'data-line': i + 1,\n 'data-line-type': 'context',\n 'data-line-index': i,\n },\n children: [\n {\n type: 'element',\n tagName: 'span',\n properties: {\n 'data-char': 0,\n },\n children: [\n {\n type: 'text',\n value: textDocument.getLineText(i),\n },\n ],\n },\n ],\n });\n }\n this.renderCache.isDirty = true;\n }\n this.textDoucmentCache.set(file, textDocument);\n }\n\n public renderFile(\n file: FileContents | undefined = this.renderCache?.file,\n renderRange: RenderRange = DEFAULT_RENDER_RANGE\n ): FileRenderResult | undefined {\n if (file == null) {\n return undefined;\n }\n let { options, forceHighlight } = this.getRenderOptions(file);\n const cache = this.getMatchingWorkerResultCache(file, options);\n if (cache != null && !this.hasHighlightedRenderCache(file, options)) {\n this.renderCache = {\n file,\n highlighted: true,\n renderRange: undefined,\n ...cache,\n };\n forceHighlight = false;\n }\n this.renderCache ??= {\n file,\n highlighted: false,\n options,\n result: undefined,\n renderRange: undefined,\n };\n const lines = this.getOrCreateLineCache(file);\n const hasContent = file.contents.length > 0;\n const forcePlainText =\n !hasContent ||\n isFilePlainText(file) ||\n isFileMassive(lines.length, this.getTokenizeMaxLength());\n const newContent = !areFilesEqual(file, this.renderCache.file);\n const newRenderRange = !areRenderRangesEqual(\n this.renderCache.renderRange,\n renderRange\n );\n if (this.workerManager?.isWorkingPool() === true) {\n // Cache invalidation based on renderRange comparison\n if (\n forcePlainText ||\n this.renderCache.result == null ||\n (!this.renderCache.highlighted && (newContent || newRenderRange))\n ) {\n this.renderCache.file = file;\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.getPlainFileAST(\n file,\n renderRange.startingLine,\n renderRange.totalLines,\n lines\n );\n }\n this.renderCache.renderRange = renderRange;\n }\n\n if (\n !forcePlainText &&\n hasContent &&\n (!this.renderCache.highlighted || forceHighlight)\n ) {\n this.workerManager.highlightFileAST(this, file);\n }\n } else {\n this.computedLang = file.lang ?? getFiletypeFromFileName(file.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.renderFileWithHighlighter(\n file,\n this.highlighter,\n forcePlainText || !hasLangs\n );\n this.renderCache = {\n file,\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(file).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(file, result, options, !forcePlainText);\n });\n }\n }\n\n return this.renderCache.result != null\n ? this.processFileResult(\n this.renderCache.file,\n renderRange,\n this.renderCache.result\n )\n : undefined;\n }\n\n async asyncRender(\n file: FileContents,\n renderRange: RenderRange = DEFAULT_RENDER_RANGE\n ): Promise<FileRenderResult> {\n const { result } = await this.asyncHighlight(file);\n return this.processFileResult(file, renderRange, result);\n }\n\n private async asyncHighlight(file: FileContents): Promise<RenderFileResult> {\n const lines = this.getOrCreateLineCache(file);\n const forcePlainText = isFileMassive(\n lines.length,\n this.getTokenizeMaxLength()\n );\n this.computedLang = forcePlainText\n ? 'text'\n : (file.lang ?? getFiletypeFromFileName(file.name));\n const hasThemes =\n this.highlighter != null &&\n hasResolvedThemes(getThemes(this.options.theme));\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.renderFileWithHighlighter(\n file,\n this.highlighter,\n forcePlainText\n );\n }\n\n private renderFileWithHighlighter(\n file: FileContents,\n highlighter: DiffsHighlighter,\n forcePlainText = false\n ): RenderFileResult {\n const { options } = this.getRenderOptions(file);\n const result = renderFileWithHighlighter(file, highlighter, options, {\n forcePlainText,\n });\n return { result, options };\n }\n\n private processFileResult(\n file: FileContents,\n renderRange: RenderRange,\n { code, themeStyles, baseThemeType }: ThemedFileResult\n ): FileRenderResult {\n const totalLines = this.getLineCount(file);\n const { disableFileHeader = false } = this.options;\n const contentArray: ElementContent[] = [];\n const gutter = createGutterWrapper();\n const endLine = Math.min(\n renderRange.startingLine + renderRange.totalLines,\n totalLines\n );\n let rowCount = 0;\n\n const fileLevelAnnotations = shouldRenderFileAnnotations(renderRange)\n ? getFileAnnotations(this.lineAnnotations)\n : undefined;\n if (fileLevelAnnotations != null) {\n gutter.children.push(createGutterGap('context', 'annotation', 1));\n contentArray.push(\n createAnnotationElement({\n type: 'annotation',\n hunkIndex: FILE_ANNOTATION_HUNK_INDEX,\n lineIndex: FILE_ANNOTATION_LINE_INDEX,\n annotations: fileLevelAnnotations.map((annotation) =>\n getLineAnnotationName(annotation)\n ),\n })\n );\n rowCount++;\n }\n\n for (\n let lineIndex = renderRange.startingLine;\n lineIndex < endLine;\n lineIndex++\n ) {\n const lineNumber = lineIndex + 1;\n\n // Sparse array - directly indexed by lineIndex\n const line = code[lineIndex];\n if (line == null) {\n const message = 'FileRenderer.processFileResult: Line doesnt exist';\n console.error(message, {\n name: file.name,\n lineIndex,\n lineNumber,\n });\n throw new Error(message);\n }\n\n // Add gutter line number\n gutter.children.push(\n createGutterItem('context', lineNumber, `${lineIndex}`)\n );\n contentArray.push(line);\n rowCount++;\n\n // Check annotations using ACTUAL line number from file\n const annotations = this.lineAnnotations[lineNumber];\n if (annotations != null) {\n gutter.children.push(createGutterGap('context', 'annotation', 1));\n contentArray.push(\n createAnnotationElement({\n type: 'annotation',\n hunkIndex: 0,\n lineIndex: lineNumber,\n annotations: annotations.map((annotation) =>\n getLineAnnotationName(annotation)\n ),\n })\n );\n rowCount++;\n }\n }\n\n // Finalize: wrap gutter and content\n gutter.properties.style = `grid-row: span ${rowCount}`;\n return {\n gutterAST: gutter.children ?? [],\n contentAST: contentArray,\n preAST: this.createPreElement(totalLines),\n headerAST: !disableFileHeader ? this.renderHeader(file) : undefined,\n totalLines: totalLines,\n rowCount,\n themeStyles: themeStyles,\n baseThemeType,\n bufferBefore: renderRange.bufferBefore,\n bufferAfter: renderRange.bufferAfter,\n css: '',\n };\n }\n\n private renderHeader(file: FileContents) {\n const { headerRenderMode = 'default', stickyHeader = false } = this.options;\n return createFileHeaderElement({\n fileOrDiff: file,\n mode: headerRenderMode,\n stickyHeader,\n });\n }\n\n public renderFullHTML(result: FileRenderResult): string {\n return toHtml(this.renderFullAST(result));\n }\n\n public renderFullAST(\n result: FileRenderResult,\n children: ElementContent[] = []\n ): HASTElement {\n children.push(\n createHastElement({\n tagName: 'code',\n children: this.renderCodeAST(result),\n properties: { 'data-code': '' },\n })\n );\n return { ...result.preAST, children };\n }\n\n public renderCodeAST(result: FileRenderResult): ElementContent[] {\n const gutter = createGutterWrapper();\n gutter.children = result.gutterAST;\n gutter.properties.style = `grid-row: span ${result.rowCount}`;\n const contentColumn = createContentColumn(\n result.contentAST,\n result.rowCount\n );\n return [gutter, contentColumn];\n }\n\n public renderPartialHTML(\n children: ElementContent[],\n includeCodeNode: boolean = false\n ): string {\n if (!includeCodeNode) {\n return toHtml(children);\n }\n return toHtml(\n createHastElement({\n tagName: 'code',\n children,\n properties: { 'data-code': '' },\n })\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 onHighlightSuccess(\n file: FileContents,\n result: ThemedFileResult,\n options: RenderFileOptions,\n highlighted = true\n ): void {\n if (this.renderCache == null) {\n return;\n }\n const triggerRenderUpdate =\n !areFilesEqual(file, this.renderCache.file) ||\n !this.renderCache.highlighted ||\n !areFileRenderOptionsEqual(options, this.renderCache.options);\n\n this.renderCache = {\n file,\n options,\n highlighted,\n result,\n renderRange: undefined,\n };\n\n if (triggerRenderUpdate) {\n this.onRenderUpdate?.();\n }\n }\n\n private getMatchingWorkerResultCache(\n file: FileContents,\n options: RenderFileOptions\n ): RenderFileResult | undefined {\n const cache = this.workerManager?.getFileResultCache(file);\n if (cache == null || !areFileRenderOptionsEqual(options, cache.options)) {\n return undefined;\n }\n return cache;\n }\n\n private hasHighlightedRenderCache(\n file: FileContents,\n options: RenderFileOptions\n ): boolean {\n const { renderCache } = this;\n return (\n renderCache?.result != null &&\n renderCache.highlighted &&\n areFilesEqual(file, renderCache.file) &&\n areFileRenderOptionsEqual(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 createPreElement(totalLines: number): HASTElement {\n const { disableLineNumbers = false, overflow = 'scroll' } = this.options;\n return createPreElement({\n type: 'file',\n diffIndicators: 'none',\n disableBackground: true,\n disableLineNumbers,\n overflow,\n split: false,\n totalLines,\n });\n }\n}\n\nfunction isFileMassive(lineCount: number, tokenizeMaxLength: number): boolean {\n return lineCount > tokenizeMaxLength;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"FileRenderer.js","names":[],"sources":["../../src/renderers/FileRenderer.ts"],"sourcesContent":["import type { ElementContent, Element as HASTElement } from 'hast';\nimport { toHtml } from 'hast-util-to-html';\n\nimport {\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 { hasResolvedThemes } from '../highlighter/themes/hasResolvedThemes';\nimport type {\n BaseCodeOptions,\n DiffsHighlighter,\n DiffsTextDocument,\n FileContents,\n FileHeaderRenderMode,\n HighlightedToken,\n LineAnnotation,\n RenderedFileASTCache,\n RenderFileOptions,\n RenderFileResult,\n RenderRange,\n SupportedLanguages,\n ThemedFileResult,\n} from '../types';\nimport { areFileRenderOptionsEqual } from '../utils/areFileRenderOptionsEqual';\nimport { areFilesEqual } from '../utils/areFilesEqual';\nimport { areRenderRangesEqual } from '../utils/areRenderRangesEqual';\nimport { linesFromFileContents } from '../utils/computeFileOffsets';\nimport { createAnnotationElement } from '../utils/createAnnotationElement';\nimport { createContentColumn } from '../utils/createContentColumn';\nimport { createFileHeaderElement } from '../utils/createFileHeaderElement';\nimport { createPreElement } from '../utils/createPreElement';\nimport { getFiletypeFromFileName } from '../utils/getFiletypeFromFileName';\nimport { getHighlighterOptions } from '../utils/getHighlighterOptions';\nimport { getLineAnnotationName } from '../utils/getLineAnnotationName';\nimport { getThemes } from '../utils/getThemes';\nimport {\n createGutterGap,\n createGutterItem,\n createGutterWrapper,\n createHastElement,\n} from '../utils/hast_utils';\nimport {\n FILE_ANNOTATION_HUNK_INDEX,\n FILE_ANNOTATION_LINE_INDEX,\n getFileAnnotations,\n shouldRenderFileAnnotations,\n} from '../utils/includesFileAnnotations';\nimport { isFilePlainText } from '../utils/isFilePlainText';\nimport { renderFileWithHighlighter } from '../utils/renderFileWithHighlighter';\nimport { shouldUseTokenTransformer } from '../utils/shouldUseTokenTransformer';\nimport type { WorkerPoolManager } from '../worker';\n\ntype AnnotationLineMap<LAnnotation> = Record<\n number,\n LineAnnotation<LAnnotation>[] | undefined\n>;\n\ninterface GetRenderOptionsReturn {\n options: RenderFileOptions;\n forceHighlight: boolean;\n}\n\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}\n\ninterface LineCache {\n cacheKey: string | undefined;\n lines: string[];\n}\n\nexport interface FileRendererOptions extends BaseCodeOptions {\n headerRenderMode?: FileHeaderRenderMode;\n}\n\nlet instanceId = -1;\n\nexport class FileRenderer<LAnnotation = undefined> {\n readonly __id: string = `file-renderer:${++instanceId}`;\n\n private highlighter: DiffsHighlighter | undefined;\n private renderCache: RenderedFileASTCache | undefined;\n private computedLang: SupportedLanguages = 'text';\n private lineAnnotations: AnnotationLineMap<LAnnotation> = {};\n private lineCache: LineCache | undefined;\n private textDoucmentCache = new WeakMap<FileContents, DiffsTextDocument>();\n\n constructor(\n public options: FileRendererOptions = { 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 setOptions(options: FileRendererOptions): void {\n this.options = options;\n }\n\n public mergeOptions(options: Partial<FileRendererOptions>): void {\n this.options = { ...this.options, ...options };\n }\n\n public setLineAnnotations(\n lineAnnotations: LineAnnotation<LAnnotation>[]\n ): void {\n this.lineAnnotations = {};\n for (const annotation of lineAnnotations) {\n const arr = this.lineAnnotations[annotation.lineNumber] ?? [];\n this.lineAnnotations[annotation.lineNumber] = arr;\n arr.push(annotation);\n }\n }\n\n public cleanUp(): void {\n this.recycle();\n this.workerManager = undefined;\n this.onRenderUpdate = undefined;\n }\n\n public recycle(): void {\n this.clearRenderCache();\n this.highlighter = undefined;\n this.workerManager?.cleanUpTasks(this);\n this.lineCache = undefined;\n }\n\n public clearRenderCache(): void {\n const renderCache = this.renderCache;\n this.renderCache = undefined;\n if (\n renderCache != null &&\n renderCache.isDirty === true &&\n renderCache.file.cacheKey != null\n ) {\n // The render cache has been updated by the host, let's purge it\n // from the worker manager cache.\n this.workerManager?.evictFileFromCache(renderCache.file.cacheKey);\n }\n }\n\n public hydrate(file: FileContents): void {\n const { options } = this.getRenderOptions(file);\n const lines = this.getOrCreateLineCache(file);\n const massiveFile = isFileMassive(\n lines.length,\n this.getTokenizeMaxLength()\n );\n let cache = this.workerManager?.getFileResultCache(file);\n if (cache != null && !areFileRenderOptionsEqual(options, cache.options)) {\n cache = undefined;\n }\n this.renderCache ??= {\n file,\n options,\n highlighted: !massiveFile && !isFilePlainText(file),\n result: massiveFile ? undefined : cache?.result,\n // FIXME(amadeus): Add support for renderRanges\n renderRange: undefined,\n };\n if (this.workerManager?.isWorkingPool() === true) {\n if (this.renderCache.result == null && !massiveFile) {\n // We should only kick off a preload of the AST if we have a WorkerPool\n this.workerManager.highlightFileAST(this, file);\n }\n }\n // Lets attempt to get the highlighter/languages ready immediately\n else if (this.highlighter == null) {\n this.computedLang = file.lang ?? getFiletypeFromFileName(file.name);\n void this.initializeHighlighter();\n }\n }\n\n private getRenderOptions(file: FileContents): GetRenderOptionsReturn {\n const options: RenderFileOptions = (() => {\n if (this.workerManager?.isWorkingPool() === true) {\n return this.workerManager.getFileRenderOptions();\n }\n const { theme = DEFAULT_THEMES, tokenizeMaxLineLength = 1000 } =\n this.options;\n return {\n theme,\n useTokenTransformer: shouldUseTokenTransformer(this.options),\n tokenizeMaxLineLength,\n };\n })();\n const { renderCache } = this;\n if (renderCache?.result == null) {\n return { options, forceHighlight: true };\n }\n if (\n !areFilesEqual(file, renderCache.file) ||\n !areFileRenderOptionsEqual(options, renderCache.options)\n ) {\n return { options, forceHighlight: true };\n }\n return { options, forceHighlight: false };\n }\n\n public getOrCreateLineCache(file: FileContents): string[] {\n // Uncached files will get split every time, not the greatest experience\n // tbh... but something people should try to optimize away\n if (file.cacheKey == null) {\n this.lineCache = undefined;\n return linesFromFileContents(file.contents);\n }\n\n let { lineCache } = this;\n if (lineCache == null || lineCache.cacheKey !== file.cacheKey) {\n lineCache = {\n cacheKey: file.cacheKey,\n lines: linesFromFileContents(file.contents),\n };\n }\n this.lineCache = lineCache;\n return lineCache.lines;\n }\n\n // when a emitLineCountChange is called,\n // calculate the line count using the cached text document\n public getLineCount(file: FileContents): number {\n return (\n this.textDoucmentCache.get(file)?.lineCount ??\n this.getOrCreateLineCache(file).length\n );\n }\n\n public updateRenderCache(\n dirtyLines: Map<number, Array<HighlightedToken>>,\n themeType: 'dark' | 'light'\n ): void {\n if (this.renderCache == null) {\n return;\n }\n const { result } = this.renderCache;\n if (result == null) {\n return;\n }\n for (const [line, tokens] of dirtyLines) {\n result.code[line] = {\n type: 'element',\n tagName: 'div',\n properties: {\n 'data-line': line + 1,\n 'data-line-type': 'context',\n 'data-line-index': line,\n },\n children: tokens.map(([char, fg, text]) => {\n if (char === 0 && fg === '') {\n if (text === '') {\n return {\n type: 'element',\n tagName: 'br',\n properties: {},\n children: [],\n };\n }\n return { type: 'text', value: text };\n }\n return {\n type: 'element',\n tagName: 'span',\n properties: {\n 'data-char': char,\n style: `--diffs-token-${themeType}:${fg};`,\n },\n children: [{ type: 'text', value: text }],\n };\n }),\n };\n }\n\n result.baseThemeType = themeType;\n this.renderCache.isDirty = true;\n }\n\n // normally triggered by the host when the document line count changes\n public applyDocumentChange(textDocument: DiffsTextDocument): void {\n if (this.renderCache == null) {\n return undefined;\n }\n const { file, result } = this.renderCache;\n if (result != null && result.code.length !== textDocument.lineCount) {\n result.code.length = Math.min(result.code.length, textDocument.lineCount);\n for (let i = result.code.length; i < textDocument.lineCount; i++) {\n // prefill lines with plain text content\n result.code.push({\n type: 'element',\n tagName: 'div',\n properties: {\n 'data-line': i + 1,\n 'data-line-type': 'context',\n 'data-line-index': i,\n },\n children: [\n {\n type: 'element',\n tagName: 'span',\n properties: {\n 'data-char': 0,\n },\n children: [\n {\n type: 'text',\n value: textDocument.getLineText(i),\n },\n ],\n },\n ],\n });\n }\n this.renderCache.isDirty = true;\n }\n this.textDoucmentCache.set(file, textDocument);\n }\n\n public renderFile(\n file: FileContents | undefined = this.renderCache?.file,\n renderRange: RenderRange = DEFAULT_RENDER_RANGE\n ): FileRenderResult | undefined {\n if (file == null) {\n return undefined;\n }\n let { options, forceHighlight } = this.getRenderOptions(file);\n const cache = this.getMatchingWorkerResultCache(file, options);\n if (cache != null && !this.hasHighlightedRenderCache(file, options)) {\n this.renderCache = {\n file,\n highlighted: true,\n renderRange: undefined,\n ...cache,\n };\n forceHighlight = false;\n }\n this.renderCache ??= {\n file,\n highlighted: false,\n options,\n result: undefined,\n renderRange: undefined,\n };\n const lines = this.getOrCreateLineCache(file);\n const hasContent = file.contents.length > 0;\n const forcePlainText =\n !hasContent ||\n isFilePlainText(file) ||\n isFileMassive(lines.length, this.getTokenizeMaxLength());\n const newContent = !areFilesEqual(file, this.renderCache.file);\n const newRenderRange = !areRenderRangesEqual(\n this.renderCache.renderRange,\n renderRange\n );\n if (this.workerManager?.isWorkingPool() === true) {\n // Cache invalidation based on renderRange comparison\n if (\n forcePlainText ||\n this.renderCache.result == null ||\n (!this.renderCache.highlighted && (newContent || newRenderRange))\n ) {\n this.renderCache.file = file;\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.getPlainFileAST(\n file,\n renderRange.startingLine,\n renderRange.totalLines,\n lines\n );\n }\n this.renderCache.renderRange = renderRange;\n }\n\n if (\n !forcePlainText &&\n hasContent &&\n (!this.renderCache.highlighted || forceHighlight)\n ) {\n this.workerManager.highlightFileAST(this, file);\n }\n } else {\n this.computedLang = file.lang ?? getFiletypeFromFileName(file.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.renderFileWithHighlighter(\n file,\n this.highlighter,\n forcePlainText || !hasLangs\n );\n this.renderCache = {\n file,\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(file).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(file, result, options, !forcePlainText);\n });\n }\n }\n\n return this.renderCache.result != null\n ? this.processFileResult(\n this.renderCache.file,\n renderRange,\n this.renderCache.result\n )\n : undefined;\n }\n\n async asyncRender(\n file: FileContents,\n renderRange: RenderRange = DEFAULT_RENDER_RANGE\n ): Promise<FileRenderResult> {\n const { result } = await this.asyncHighlight(file);\n return this.processFileResult(file, renderRange, result);\n }\n\n private async asyncHighlight(file: FileContents): Promise<RenderFileResult> {\n const lines = this.getOrCreateLineCache(file);\n const forcePlainText = isFileMassive(\n lines.length,\n this.getTokenizeMaxLength()\n );\n this.computedLang = forcePlainText\n ? 'text'\n : (file.lang ?? getFiletypeFromFileName(file.name));\n const hasThemes =\n this.highlighter != null &&\n hasResolvedThemes(getThemes(this.options.theme));\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.renderFileWithHighlighter(\n file,\n this.highlighter,\n forcePlainText\n );\n }\n\n private renderFileWithHighlighter(\n file: FileContents,\n highlighter: DiffsHighlighter,\n forcePlainText = false\n ): RenderFileResult {\n const { options } = this.getRenderOptions(file);\n const result = renderFileWithHighlighter(file, highlighter, options, {\n forcePlainText,\n });\n return { result, options };\n }\n\n private processFileResult(\n file: FileContents,\n renderRange: RenderRange,\n { code, themeStyles, baseThemeType }: ThemedFileResult\n ): FileRenderResult {\n const totalLines = this.getLineCount(file);\n const { disableFileHeader = false } = this.options;\n const contentArray: ElementContent[] = [];\n const gutter = createGutterWrapper();\n const endLine = Math.min(\n renderRange.startingLine + renderRange.totalLines,\n totalLines\n );\n let rowCount = 0;\n\n const fileLevelAnnotations = shouldRenderFileAnnotations(renderRange)\n ? getFileAnnotations(this.lineAnnotations)\n : undefined;\n if (fileLevelAnnotations != null) {\n gutter.children.push(createGutterGap('context', 'annotation', 1));\n contentArray.push(\n createAnnotationElement({\n type: 'annotation',\n hunkIndex: FILE_ANNOTATION_HUNK_INDEX,\n lineIndex: FILE_ANNOTATION_LINE_INDEX,\n annotations: fileLevelAnnotations.map((annotation) =>\n getLineAnnotationName(annotation)\n ),\n })\n );\n rowCount++;\n }\n\n for (\n let lineIndex = renderRange.startingLine;\n lineIndex < endLine;\n lineIndex++\n ) {\n const lineNumber = lineIndex + 1;\n\n // Sparse array - directly indexed by lineIndex\n const line = code[lineIndex];\n if (line == null) {\n const message = 'FileRenderer.processFileResult: Line doesnt exist';\n console.error(message, {\n name: file.name,\n lineIndex,\n lineNumber,\n });\n throw new Error(message);\n }\n\n // Add gutter line number\n gutter.children.push(\n createGutterItem('context', lineNumber, `${lineIndex}`)\n );\n contentArray.push(line);\n rowCount++;\n\n // Check annotations using ACTUAL line number from file\n const annotations = this.lineAnnotations[lineNumber];\n if (annotations != null) {\n gutter.children.push(createGutterGap('context', 'annotation', 1));\n contentArray.push(\n createAnnotationElement({\n type: 'annotation',\n hunkIndex: 0,\n lineIndex: lineNumber,\n annotations: annotations.map((annotation) =>\n getLineAnnotationName(annotation)\n ),\n })\n );\n rowCount++;\n }\n }\n\n // Finalize: wrap gutter and content\n gutter.properties.style = `grid-row: span ${rowCount}`;\n return {\n gutterAST: gutter.children ?? [],\n contentAST: contentArray,\n preAST: this.createPreElement(totalLines),\n headerAST: !disableFileHeader ? this.renderHeader(file) : undefined,\n totalLines: totalLines,\n rowCount,\n themeStyles: themeStyles,\n baseThemeType,\n bufferBefore: renderRange.bufferBefore,\n bufferAfter: renderRange.bufferAfter,\n css: '',\n };\n }\n\n private renderHeader(file: FileContents) {\n const { headerRenderMode = 'default', stickyHeader = false } = this.options;\n return createFileHeaderElement({\n fileOrDiff: file,\n mode: headerRenderMode,\n stickyHeader,\n });\n }\n\n public renderFullHTML(result: FileRenderResult): string {\n return toHtml(this.renderFullAST(result));\n }\n\n public renderFullAST(\n result: FileRenderResult,\n children: ElementContent[] = []\n ): HASTElement {\n children.push(\n createHastElement({\n tagName: 'code',\n children: this.renderCodeAST(result),\n properties: { 'data-code': '' },\n })\n );\n return { ...result.preAST, children };\n }\n\n public renderCodeAST(result: FileRenderResult): ElementContent[] {\n const gutter = createGutterWrapper();\n gutter.children = result.gutterAST;\n gutter.properties.style = `grid-row: span ${result.rowCount}`;\n const contentColumn = createContentColumn(\n result.contentAST,\n result.rowCount\n );\n return [gutter, contentColumn];\n }\n\n public renderPartialHTML(\n children: ElementContent[],\n includeCodeNode: boolean = false\n ): string {\n if (!includeCodeNode) {\n return toHtml(children);\n }\n return toHtml(\n createHastElement({\n tagName: 'code',\n children,\n properties: { 'data-code': '' },\n })\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 onHighlightSuccess(\n file: FileContents,\n result: ThemedFileResult,\n options: RenderFileOptions,\n highlighted = true\n ): void {\n if (this.renderCache == null) {\n return;\n }\n const triggerRenderUpdate =\n !areFilesEqual(file, this.renderCache.file) ||\n !this.renderCache.highlighted ||\n !areFileRenderOptionsEqual(options, this.renderCache.options);\n\n this.renderCache = {\n file,\n options,\n highlighted,\n result,\n renderRange: undefined,\n };\n\n if (triggerRenderUpdate) {\n this.onRenderUpdate?.();\n }\n }\n\n private getMatchingWorkerResultCache(\n file: FileContents,\n options: RenderFileOptions\n ): RenderFileResult | undefined {\n const cache = this.workerManager?.getFileResultCache(file);\n if (cache == null || !areFileRenderOptionsEqual(options, cache.options)) {\n return undefined;\n }\n return cache;\n }\n\n private hasHighlightedRenderCache(\n file: FileContents,\n options: RenderFileOptions\n ): boolean {\n const { renderCache } = this;\n return (\n renderCache?.result != null &&\n renderCache.highlighted &&\n areFilesEqual(file, renderCache.file) &&\n areFileRenderOptionsEqual(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 createPreElement(totalLines: number): HASTElement {\n const { disableLineNumbers = false, overflow = 'scroll' } = this.options;\n return createPreElement({\n type: 'file',\n diffIndicators: 'none',\n disableBackground: true,\n disableLineNumbers,\n overflow,\n split: false,\n totalLines,\n });\n }\n}\n\nfunction isFileMassive(lineCount: number, tokenizeMaxLength: number): boolean {\n return lineCount > tokenizeMaxLength;\n}\n"],"mappings":"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"}
|