@openclaw/diffs 2026.9.6 → 2026.9.8
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/assets/icon.png +0 -0
- package/dist/.setup/{browser.runtime-VjaO3wrj.mjs → browser.runtime-v15gbeC0.mjs} +1 -1
- package/dist/.setup/{viewer-assets-D3qrnaxI.mjs → viewer-assets-Bg9efLih.mjs} +24 -49
- package/dist/assets/viewer-runtime.js +2 -2
- package/dist/index.js +241 -201
- package/node_modules/@pierre/diffs/dist/components/File.d.ts +1 -0
- package/node_modules/@pierre/diffs/dist/components/File.d.ts.map +1 -1
- package/node_modules/@pierre/diffs/dist/components/File.js +4 -0
- package/node_modules/@pierre/diffs/dist/components/File.js.map +1 -1
- package/node_modules/@pierre/diffs/dist/components/FileDiff.d.ts +1 -0
- package/node_modules/@pierre/diffs/dist/components/FileDiff.d.ts.map +1 -1
- package/node_modules/@pierre/diffs/dist/components/FileDiff.js +4 -0
- package/node_modules/@pierre/diffs/dist/components/FileDiff.js.map +1 -1
- package/node_modules/@pierre/diffs/dist/components/VirtualizedFile.d.ts.map +1 -1
- package/node_modules/@pierre/diffs/dist/components/VirtualizedFile.js +8 -9
- package/node_modules/@pierre/diffs/dist/components/VirtualizedFile.js.map +1 -1
- package/node_modules/@pierre/diffs/dist/components/VirtualizedFileDiff.d.ts.map +1 -1
- package/node_modules/@pierre/diffs/dist/components/VirtualizedFileDiff.js +8 -6
- package/node_modules/@pierre/diffs/dist/components/VirtualizedFileDiff.js.map +1 -1
- package/node_modules/@pierre/diffs/dist/editor/editor.js +3 -5
- package/node_modules/@pierre/diffs/dist/editor/editor.js.map +1 -1
- package/node_modules/@pierre/diffs/dist/editor/textMeasure.d.ts.map +1 -1
- package/node_modules/@pierre/diffs/dist/editor/textMeasure.js +27 -3
- package/node_modules/@pierre/diffs/dist/editor/textMeasure.js.map +1 -1
- package/node_modules/@pierre/diffs/dist/highlighter/languages/attachResolvedLanguages.js +8 -1
- package/node_modules/@pierre/diffs/dist/highlighter/languages/attachResolvedLanguages.js.map +1 -1
- package/node_modules/@pierre/diffs/dist/highlighter/languages/registerCustomLanguage.d.ts +3 -1
- package/node_modules/@pierre/diffs/dist/highlighter/languages/registerCustomLanguage.d.ts.map +1 -1
- package/node_modules/@pierre/diffs/dist/highlighter/languages/registerCustomLanguage.js +3 -1
- package/node_modules/@pierre/diffs/dist/highlighter/languages/registerCustomLanguage.js.map +1 -1
- package/node_modules/@pierre/diffs/dist/worker/WorkerPoolManager.d.ts.map +1 -1
- package/node_modules/@pierre/diffs/dist/worker/WorkerPoolManager.js +40 -38
- package/node_modules/@pierre/diffs/dist/worker/WorkerPoolManager.js.map +1 -1
- package/node_modules/@pierre/diffs/dist/worker/worker-portable.js +8 -1
- package/node_modules/@pierre/diffs/dist/worker/worker-portable.js.map +1 -1
- package/node_modules/@pierre/diffs/dist/worker/worker.js +8 -1
- package/node_modules/@pierre/diffs/dist/worker/worker.js.map +1 -1
- package/node_modules/@pierre/diffs/package.json +1 -1
- package/node_modules/typebox/build/compile/code.mjs +1 -2
- package/node_modules/typebox/build/compile/validator.mjs +5 -1
- package/node_modules/typebox/build/format/iri.mjs +16 -9
- package/node_modules/typebox/build/guard/emit.mjs +2 -2
- package/node_modules/typebox/build/guard/guard.d.mts +7 -5
- package/node_modules/typebox/build/guard/guard.mjs +14 -9
- package/node_modules/typebox/build/guard/index.mjs +6 -0
- package/node_modules/typebox/build/guard/unicode/unicode.d.mts +6 -0
- package/node_modules/typebox/build/guard/unicode/unicode.mjs +35 -0
- package/node_modules/typebox/build/guard/{string.mjs → unicode/unicode_segment.mjs} +16 -19
- package/node_modules/typebox/build/schema/build.mjs +2 -3
- package/node_modules/typebox/build/schema/engine/_pathing.d.mts +1 -0
- package/node_modules/typebox/build/schema/engine/_pathing.mjs +11 -0
- package/node_modules/typebox/build/schema/engine/_refine.mjs +13 -5
- package/node_modules/typebox/build/schema/engine/additionalProperties.mjs +2 -1
- package/node_modules/typebox/build/schema/engine/dependencies.mjs +2 -1
- package/node_modules/typebox/build/schema/engine/dependentSchemas.mjs +2 -1
- package/node_modules/typebox/build/schema/engine/dynamicRef.d.mts +1 -1
- package/node_modules/typebox/build/schema/engine/dynamicRef.mjs +2 -2
- package/node_modules/typebox/build/schema/engine/format.mjs +9 -2
- package/node_modules/typebox/build/schema/engine/patternProperties.mjs +3 -2
- package/node_modules/typebox/build/schema/engine/properties.mjs +3 -2
- package/node_modules/typebox/build/schema/engine/propertyNames.mjs +2 -1
- package/node_modules/typebox/build/schema/engine/recursiveRef.d.mts +1 -1
- package/node_modules/typebox/build/schema/engine/recursiveRef.mjs +2 -2
- package/node_modules/typebox/build/schema/engine/ref.d.mts +1 -1
- package/node_modules/typebox/build/schema/engine/ref.mjs +2 -2
- package/node_modules/typebox/build/schema/engine/schema.mjs +24 -24
- package/node_modules/typebox/build/schema/parse.mjs +3 -0
- package/node_modules/typebox/build/schema/pointer/pointer.d.mts +1 -6
- package/node_modules/typebox/build/schema/pointer/pointer.mjs +47 -64
- package/node_modules/typebox/build/system/settings/internal.d.mts +2 -0
- package/node_modules/typebox/build/system/settings/internal.mjs +20 -0
- package/node_modules/typebox/build/system/settings/settings.d.mts +11 -0
- package/node_modules/typebox/build/system/settings/settings.mjs +14 -0
- package/node_modules/typebox/build/type/extends/inference.d.mts +1 -1
- package/node_modules/typebox/build/type/extends/inference.mjs +15 -2
- package/node_modules/typebox/build/type/extends/tuple.d.mts +2 -1
- package/node_modules/typebox/build/type/extends/tuple.mjs +21 -1
- package/node_modules/typebox/build/value/parse/parse.mjs +10 -4
- package/node_modules/typebox/package.json +1 -1
- package/node_modules/typebox/readme.md +3 -1
- package/package.json +6 -6
- package/dist/api.js +0 -3
- package/dist/runtime-api.js +0 -2
- /package/node_modules/typebox/build/guard/{string.d.mts → unicode/unicode_segment.d.mts} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VirtualizedFileDiff.js","names":[],"sources":["../../src/components/VirtualizedFileDiff.ts"],"sourcesContent":["import { DEFAULT_COLLAPSED_CONTEXT_THRESHOLD } from '../constants';\nimport type { TextDocument } from '../editor/textDocument';\nimport type {\n BaseDiffOptions,\n DiffLineAnnotation,\n ExpansionDirections,\n FileContents,\n FileDiffMetadata,\n Hunk,\n HunkSeparators,\n NumericScrollLineAnchor,\n PendingCodeViewLayoutReset,\n RenderRange,\n RenderWindow,\n SelectionSide,\n StickySpecs,\n ThemeTypes,\n VirtualFileMetrics,\n} from '../types';\nimport { areDiffTargetsEqual } from '../utils/areDiffTargetsEqual';\nimport { areFilesEqual } from '../utils/areFilesEqual';\nimport { areObjectsEqual } from '../utils/areObjectsEqual';\nimport { areOptionsEqual } from '../utils/areOptionsEqual';\nimport { awaitWithTimeout } from '../utils/awaitWithTimeout';\nimport { computeEstimatedDiffHeights } from '../utils/computeEstimatedDiffHeights';\nimport {\n computeVirtualFileMetrics,\n getVirtualFileHeaderRegion,\n getVirtualFilePaddingBottom,\n} from '../utils/computeVirtualFileMetrics';\nimport { getDiffFileInput } from '../utils/getDiffFileInput';\nimport { hydratePartialDiff } from '../utils/hydratePartialDiff';\nimport {\n FILE_ANNOTATION_DOM_KEY,\n FILE_ANNOTATION_LINE_NUMBER,\n includesFileAnnotations,\n shouldRenderFileAnnotations,\n} from '../utils/includesFileAnnotations';\nimport { iterateOverDiff } from '../utils/iterateOverDiff';\nimport { parseDiffFromFile } from '../utils/parseDiffFromFile';\nimport {\n getExpandedRegion,\n getLeadingHunkSeparatorLayout,\n getTrailingExpandedRegion,\n getTrailingHunkSeparatorLayout,\n isAdditionLineRenderable,\n} from '../utils/virtualDiffLayout';\nimport type { WorkerPoolManager } from '../worker';\nimport type { CodeView } from './CodeView';\nimport {\n FileDiff,\n type FileDiffOptions,\n type FileDiffRenderProps,\n} from './FileDiff';\nimport type { Virtualizer } from './Virtualizer';\n\ntype LoadedPartialDiffContents = Awaited<\n ReturnType<NonNullable<BaseDiffOptions['loadDiffFiles']>>\n>;\n\ninterface DiffLayoutCheckpoint {\n renderedLineIndex: number;\n lineIndex: number;\n top: number;\n}\n\ninterface DiffLayoutCache {\n // Sparse map: view-specific line index -> measured height delta from the\n // baseline line height. Only stores lines that differ from the estimate.\n heightDeltas: Map<number, number>;\n // Aggregate delta from estimated height, including source row deltas and the\n // zero-baseline file annotation row height.\n measuredHeightDeltaTotal: number;\n // Baseline estimated heights for the active diff content. These are preserved\n // across style/collapse toggles and cleared only when estimate inputs change.\n estimatedSplitHeight: number | undefined;\n estimatedUnifiedHeight: number | undefined;\n // Sparse measured positions used to resume deep geometry scans near a target\n // diff line, rendered row, or scroll offset instead of replaying layout from\n // the first hunk.\n checkpoints: DiffLayoutCheckpoint[];\n // Total renderable diff rows for the current diff style and expansion state.\n totalLines: number;\n // Measured height for the file annotation row. Starts at 0 so\n // unmeasured annotations behave like all other unmeasured annotations.\n fileAnnotationHeight: number;\n // Ghost text rows folded into `heightDeltas`. `ghostTextRows` is the editor's\n // own map (zero-based new-file line -> rows), replaced rather than mutated, so\n // identity alone says whether anything changed. `ghostTextRowsByIndex` is the\n // same data keyed by this view's row index, which the deltas use.\n ghostTextRows: ReadonlyMap<number, number>;\n ghostTextRowsByIndex: Map<number, number>;\n}\n\ninterface ResetLayoutCacheOptions {\n forceSimpleRecompute?: boolean;\n includeEstimatedHeights?: boolean;\n resetRenderRange?: boolean;\n}\n\ninterface PendingLoadedDiff {\n expectedDiff: FileDiffMetadata;\n nextDiff: FileDiffMetadata;\n files: LoadedPartialDiffContents;\n}\n\ninterface PendingExpansion {\n hunkIndex: number;\n direction: ExpansionDirections;\n expansionLineCountOverride: number | undefined;\n}\n\ninterface PendingRender {\n latestDiff: FileDiffMetadata;\n diff: FileDiffMetadata;\n}\n\nexport const VIRTUALIZED_FILE_DIFF_LAYOUT_CHECKPOINT_INTERVAL = 3_000;\nconst NO_GHOST_TEXT_ROWS: ReadonlyMap<number, number> = new Map();\n\nlet instanceId = -1;\n\nexport class VirtualizedFileDiff<\n LAnnotation = undefined,\n Caret = undefined,\n> extends FileDiff<LAnnotation, Caret> {\n override readonly __id: string = `little-virtualized-file-diff:${++instanceId}`;\n public readonly renderType = 'virtualized';\n\n public top: number | undefined;\n public height: number = 0;\n private metrics: VirtualFileMetrics;\n private cache: DiffLayoutCache = {\n heightDeltas: new Map(),\n measuredHeightDeltaTotal: 0,\n estimatedSplitHeight: undefined,\n estimatedUnifiedHeight: undefined,\n checkpoints: [],\n totalLines: 0,\n fileAnnotationHeight: 0,\n ghostTextRows: NO_GHOST_TEXT_ROWS,\n ghostTextRowsByIndex: new Map(),\n };\n private isVisible: boolean = false;\n private isSetup: boolean = false;\n private virtualizer: Virtualizer | CodeView<LAnnotation, Caret>;\n private layoutDirty = true;\n private forceRenderOverride: true | undefined;\n private currentCollapsed: boolean | undefined;\n private pendingHydratedDiff: PendingLoadedDiff | undefined;\n private pendingExpansions: PendingExpansion[] | undefined;\n // CodeView calculates the next layout before its DOM pass. Keep that\n // selection separate from renderedDiff until render() applies it.\n private pendingRender: PendingRender | undefined;\n\n constructor(\n options: FileDiffOptions<LAnnotation, Caret> | undefined,\n virtualizer: Virtualizer | CodeView<LAnnotation, Caret>,\n metrics?: Partial<VirtualFileMetrics>,\n workerManager?: WorkerPoolManager,\n isContainerManaged = false\n ) {\n super(options, workerManager, isContainerManaged);\n this.virtualizer = virtualizer;\n this.metrics = computeVirtualFileMetrics(metrics);\n }\n\n public setMetrics(\n metrics?: Partial<VirtualFileMetrics>,\n force = false\n ): void {\n const nextMetrics = computeVirtualFileMetrics(metrics);\n if (!force && areObjectsEqual(this.metrics, nextMetrics)) {\n return;\n }\n\n this.metrics = nextMetrics;\n this.resetLayoutCache({ includeEstimatedHeights: true });\n }\n\n override setLineAnnotations(\n lineAnnotations: DiffLineAnnotation<LAnnotation>[]\n ): void {\n if (this.syncLineAnnotations(lineAnnotations)) {\n this.resetLayoutCache({ includeEstimatedHeights: false });\n }\n }\n\n private syncLineAnnotations(\n lineAnnotations: DiffLineAnnotation<LAnnotation>[] | undefined\n ): boolean {\n if (\n lineAnnotations == null ||\n !this.isNewAnnotations(lineAnnotations) ||\n (lineAnnotations.length === 0 && this.getLatestAnnotations().length === 0)\n ) {\n return false;\n }\n super.setLineAnnotations(lineAnnotations);\n return true;\n }\n\n protected override syncEditSessionAnnotationsFromEditor(\n lineAnnotations: DiffLineAnnotation<LAnnotation>[]\n ): boolean {\n if (super.syncEditSessionAnnotationsFromEditor(lineAnnotations)) {\n this.resetLayoutCache({ includeEstimatedHeights: false });\n return true;\n }\n return false;\n }\n\n private setFileAnnotationHeight(nextHeight: number): boolean {\n const previousHeight = this.cache.fileAnnotationHeight;\n if (nextHeight === previousHeight) {\n return false;\n }\n\n this.cache.fileAnnotationHeight = nextHeight;\n this.cache.measuredHeightDeltaTotal += nextHeight - previousHeight;\n return true;\n }\n\n private hasFileAnnotations(fileDiff: FileDiffMetadata): boolean {\n const lineAnnotations = this.getLatestAnnotations();\n if (!includesFileAnnotations(lineAnnotations)) {\n return false;\n }\n return lineAnnotations.some((annotation) => {\n if (annotation.lineNumber !== FILE_ANNOTATION_LINE_NUMBER) {\n return false;\n }\n // Lets ensure for singled sided diffs that the sides match\n if (fileDiff.type === 'new') {\n return annotation.side === 'additions';\n }\n if (fileDiff.type === 'deleted') {\n return annotation.side === 'deletions';\n }\n return true;\n });\n }\n\n // Get the height for a line, using cached value if available.\n // If not cached and hasMetadataLine is true, adds lineHeight for the metadata.\n private getLineHeight(lineIndex: number, hasMetadataLine = false): number {\n return (\n this.getEstimatedLineHeight(hasMetadataLine) +\n (this.cache.heightDeltas.get(lineIndex) ?? 0)\n );\n }\n\n private getEstimatedLineHeight(hasMetadataLine = false): number {\n const multiplier = hasMetadataLine ? 2 : 1;\n return this.metrics.lineHeight * multiplier;\n }\n\n override setOptions(\n options: FileDiffOptions<LAnnotation, Caret> | undefined\n ): void {\n if (this.isAdvancedMode()) {\n throw new Error(\n 'VirtualizedFileDiff.setOptions cannot be used inside CodeView. Update CodeView options instead.'\n );\n }\n\n if (options == null) return;\n const { options: previousOptions } = this;\n const optionsChanged = !areOptionsEqual(previousOptions, options);\n const layoutChanged =\n optionsChanged && hasDiffLayoutOptionChanged(previousOptions, options);\n\n super.setOptions(options);\n\n if (layoutChanged) {\n this.resetLayoutCache({\n forceSimpleRecompute: true,\n includeEstimatedHeights: hasDiffEstimateOptionChanged(\n previousOptions,\n options\n ),\n });\n }\n // Any option can affect rendered DOM; only layout-affecting options clear\n // the measured height cache above.\n if (optionsChanged) {\n this.forceRenderOverride = true;\n }\n if (optionsChanged && this.isSimpleMode()) {\n this.virtualizer.instanceChanged(this, layoutChanged);\n }\n }\n\n override setThemeType(themeType: ThemeTypes): void {\n if (this.isAdvancedMode()) {\n throw new Error(\n 'VirtualizedFileDiff.setThemeType cannot be used inside CodeView. Update CodeView options instead.'\n );\n }\n\n super.setThemeType(themeType);\n }\n\n private resetLayoutCache({\n forceSimpleRecompute = false,\n includeEstimatedHeights = false,\n resetRenderRange = true,\n }: ResetLayoutCacheOptions = {}): void {\n this.layoutDirty = true;\n this.cache.fileAnnotationHeight = 0;\n this.cache.heightDeltas.clear();\n this.cache.measuredHeightDeltaTotal = 0;\n this.cache.ghostTextRows = NO_GHOST_TEXT_ROWS;\n if (this.cache.ghostTextRowsByIndex.size > 0) {\n this.cache.ghostTextRowsByIndex.clear();\n }\n this.invalidateDerivedLayoutCache(\n includeEstimatedHeights,\n resetRenderRange\n );\n // NOTE(amadeus): In CodeView we intentionally batch computes to all happen\n // at the same time, so we shouldn't trigger this there.\n if (forceSimpleRecompute && this.isSimpleMode()) {\n this.computeApproximateSize();\n }\n }\n\n private invalidateDerivedLayoutCache(\n includeEstimatedHeights: boolean,\n resetRenderRange = true\n ): void {\n this.layoutDirty = true;\n if (this.cache.checkpoints.length > 0) {\n this.cache.checkpoints.length = 0;\n }\n if (this.cache.totalLines !== 0) {\n this.cache.totalLines = 0;\n }\n if (includeEstimatedHeights) {\n this.cache.estimatedSplitHeight = undefined;\n this.cache.estimatedUnifiedHeight = undefined;\n }\n if (this.renderRange != null && resetRenderRange) {\n this.renderRange = undefined;\n }\n }\n\n // Fold the ghost text rows the editor is showing below lines into the height\n // deltas. Ghost text sits in a margin below the row, which measuring never\n // includes, so the rows are added here on top of the row's own height, and\n // removed again when the ghost text changes or goes away, even for rows that\n // are not rendered right now. The editor keys by new-file line; the deltas\n // are keyed by this view's row index, so lines are translated the same way\n // getLinePosition does. The editor only reports lines that have a rendered\n // row (it draws a prediction all or nothing); the translation is undefined\n // only for a diff without hunks.\n private applyGhostTextRows(\n fileDiff: FileDiffMetadata,\n ghostTextRows: ReadonlyMap<number, number>\n ): boolean {\n const {\n cache: {\n heightDeltas,\n ghostTextRows: folded,\n ghostTextRowsByIndex: previous,\n },\n metrics: { lineHeight },\n } = this;\n if (folded === ghostTextRows) {\n return false;\n }\n const diffStyle = this.getDiffStyle();\n const next = new Map<number, number>();\n for (const [line, rows] of ghostTextRows) {\n const indexes = this.getLineIndexForDiff(fileDiff, line + 1, 'additions');\n if (indexes == null) {\n continue;\n }\n next.set(diffStyle === 'split' ? indexes[1] : indexes[0], rows);\n }\n let changed = false;\n for (const rowIndex of new Set([...previous.keys(), ...next.keys()])) {\n const delta =\n ((next.get(rowIndex) ?? 0) - (previous.get(rowIndex) ?? 0)) *\n lineHeight;\n if (delta === 0) {\n continue;\n }\n const nextDelta = (heightDeltas.get(rowIndex) ?? 0) + delta;\n if (nextDelta === 0) {\n heightDeltas.delete(rowIndex);\n } else {\n heightDeltas.set(rowIndex, nextDelta);\n }\n this.cache.measuredHeightDeltaTotal += delta;\n changed = true;\n }\n this.cache.ghostTextRows = ghostTextRows;\n this.cache.ghostTextRowsByIndex = next;\n return changed;\n }\n\n // Measure rendered lines and update height cache.\n // Called after render to reconcile estimated vs actual heights.\n // Definitely need to optimize this in cases where there aren't any custom\n // line heights or in cases of extremely large files...\n public reconcileHeights(): boolean {\n let hasHeightChange = false;\n const {\n options: { overflow = 'scroll' },\n cache: { ghostTextRowsByIndex },\n metrics: { lineHeight },\n } = this;\n const fileDiff = this.getRenderedDiff();\n if (this.fileContainer == null || fileDiff == null) {\n if (this.height !== 0) {\n hasHeightChange = true;\n }\n this.height = 0;\n return hasHeightChange;\n }\n this.top = this.getVirtualizedTop();\n hasHeightChange = this.applyGhostTextRows(\n fileDiff,\n this.editor?.__getGhostTextRows() ?? NO_GHOST_TEXT_ROWS\n );\n const lineAnnotations = this.getLatestAnnotations();\n // NOTE(amadeus): We can probably be a lot smarter about this, and we\n // should be thinking about ways to improve this\n // If the file has no annotations and we are using the scroll variant, then\n // we can probably skip everything\n if (\n overflow === 'scroll' &&\n lineAnnotations.length === 0 &&\n !this.isResizeDebuggingEnabled()\n ) {\n if (hasHeightChange) {\n this.computeApproximateSize(true);\n }\n return hasHeightChange;\n }\n const diffStyle = this.getDiffStyle();\n const codeGroups =\n diffStyle === 'split'\n ? [this.codeDeletions, this.codeAdditions]\n : [this.codeUnified];\n\n const hasFileAnnotations = this.hasFileAnnotations(fileDiff);\n if (\n this.renderRange != null &&\n hasFileAnnotations &&\n shouldRenderFileAnnotations(this.renderRange)\n ) {\n const fileAnnotationHeight = measureFileAnnotationHeight(codeGroups);\n const nextFileAnnotationHeight = fileAnnotationHeight ?? 0;\n if (this.setFileAnnotationHeight(nextFileAnnotationHeight)) {\n hasHeightChange = true;\n }\n } else if (!hasFileAnnotations && this.setFileAnnotationHeight(0)) {\n hasHeightChange = true;\n }\n\n for (const codeGroup of codeGroups) {\n if (codeGroup == null) continue;\n const content = codeGroup.children[1];\n if (!(content instanceof HTMLElement)) continue;\n // The ghost prediction margin sits on the additions row. When the two\n // split columns share one grid, the deletions row stretches to that\n // taller track, so measuring it would count the rows twice; the\n // additions row is authoritative for a row pair with ghost text.\n const skipsGhostRows =\n diffStyle === 'split' && codeGroup === this.codeDeletions;\n for (const line of content.children) {\n if (!(line instanceof HTMLElement)) continue;\n\n const lineIndexAttr = line.dataset.lineIndex;\n if (lineIndexAttr == null) continue;\n\n const lineIndex = parseLineIndex(lineIndexAttr, diffStyle);\n const ghostRows = ghostTextRowsByIndex.get(lineIndex) ?? 0;\n if (skipsGhostRows && ghostRows > 0) continue;\n let measuredHeight =\n line.getBoundingClientRect().height + ghostRows * lineHeight;\n let hasMetadata = false;\n // Annotations or noNewline metadata increase the size of the their\n // attached line\n if (\n line.nextElementSibling instanceof HTMLElement &&\n ('lineAnnotation' in line.nextElementSibling.dataset ||\n 'noNewline' in line.nextElementSibling.dataset)\n ) {\n if ('noNewline' in line.nextElementSibling.dataset) {\n hasMetadata = true;\n }\n measuredHeight +=\n line.nextElementSibling.getBoundingClientRect().height;\n }\n const estimatedHeight = this.getEstimatedLineHeight(hasMetadata);\n const previousDelta = this.cache.heightDeltas.get(lineIndex) ?? 0;\n const nextDelta = measuredHeight - estimatedHeight;\n\n if (nextDelta === previousDelta) {\n continue;\n }\n\n hasHeightChange = true;\n this.cache.measuredHeightDeltaTotal += nextDelta - previousDelta;\n if (nextDelta === 0) {\n this.cache.heightDeltas.delete(lineIndex);\n } else {\n this.cache.heightDeltas.set(lineIndex, nextDelta);\n }\n }\n }\n\n if (hasHeightChange || this.isResizeDebuggingEnabled()) {\n this.computeApproximateSize(true);\n }\n return hasHeightChange;\n }\n\n public onRender = (dirty: boolean): boolean => {\n if (this.fileContainer == null) {\n return false;\n }\n if (dirty) {\n this.top = this.getVirtualizedTop();\n }\n return this.render();\n };\n\n // Virtualized renders bypass FileDiff's queued render handler. Apply line\n // state deferred during the refresh once managers target the rebuilt rows.\n public override flushManagers(): void {\n super.flushManagers();\n if (this.lineStateRefreshPending) {\n this.flushDeferredLineState();\n }\n }\n\n // CodeView positions every item before updating the DOM. Recalculate this\n // item's layout whenever its content or position changes.\n public updateCodeViewLayout(\n fileDiff: FileDiffMetadata,\n top: number,\n reset?: PendingCodeViewLayoutReset,\n lineAnnotations?: DiffLineAnnotation<LAnnotation>[]\n ): number {\n let resetLayoutCache = false;\n let resetEstimatedHeights = false;\n const {\n pendingExpansions,\n pendingHydratedDiff,\n options: { collapsed = false },\n } = this;\n\n // Hydrate the `isPartial: true` diff if we have a pending hydration\n if (pendingHydratedDiff != null) {\n this.pendingHydratedDiff = undefined;\n if (pendingHydratedDiff.expectedDiff === fileDiff) {\n // We intentionally keep diff equality referential,\n // and treat it as a mutation\n Object.assign(fileDiff, pendingHydratedDiff.nextDiff);\n this.setHydratedState(pendingHydratedDiff.files);\n this.startHydratedEditSession(fileDiff);\n this.forceRenderOverride = true;\n resetLayoutCache = true;\n resetEstimatedHeights = true;\n }\n }\n\n // Go ahead and apply any queued expansion changes\n if (pendingExpansions != null) {\n this.pendingExpansions = undefined;\n for (const {\n hunkIndex,\n direction,\n expansionLineCountOverride,\n } of pendingExpansions) {\n this.hunksRenderer.expandHunk(\n hunkIndex,\n direction,\n expansionLineCountOverride\n );\n this.forceRenderOverride = true;\n resetEstimatedHeights = true;\n }\n }\n\n const diffChanged = this.updateExternalDiff(fileDiff, lineAnnotations);\n const {\n pendingRenderDiff,\n layoutDiffChanged,\n renderedDiffChanged,\n annotationsChanged,\n } = this.updatePendingRender(fileDiff, lineAnnotations);\n if (\n !this.forceRenderOverride &&\n (diffChanged || renderedDiffChanged || annotationsChanged)\n ) {\n this.forceRenderOverride = true;\n }\n\n if (\n reset?.resetDiffLayoutCache === true ||\n layoutDiffChanged ||\n annotationsChanged\n ) {\n resetLayoutCache = true;\n }\n if (\n layoutDiffChanged ||\n (reset?.resetDiffLayoutCache === true &&\n reset.includeEstimatedDiffHeights)\n ) {\n resetEstimatedHeights = true;\n }\n if (reset?.metrics != null) {\n this.metrics = computeVirtualFileMetrics(reset.metrics);\n resetLayoutCache = true;\n resetEstimatedHeights = true;\n }\n if (this.currentCollapsed !== collapsed) {\n this.currentCollapsed = collapsed;\n resetLayoutCache = true;\n }\n if (resetLayoutCache) {\n this.resetLayoutCache({ includeEstimatedHeights: resetEstimatedHeights });\n } else if (resetEstimatedHeights) {\n this.invalidateDerivedLayoutCache(true);\n }\n\n this.top = top;\n this.computeApproximateSize(false, pendingRenderDiff);\n return this.height;\n }\n\n public getLinePosition(\n lineNumber: number,\n side: SelectionSide = 'additions'\n ): { top: number; height: number } | undefined {\n const fileDiff = this.getLayoutDiff();\n if (fileDiff == null || lineNumber < 1) {\n return undefined;\n }\n\n const targetLineIndexes = this.getLineIndexForDiff(\n fileDiff,\n lineNumber,\n side\n );\n if (targetLineIndexes == null) {\n return undefined;\n }\n\n const {\n disableFileHeader = false,\n expandUnchanged = false,\n collapsed = false,\n collapsedContextThreshold = DEFAULT_COLLAPSED_CONTEXT_THRESHOLD,\n } = this.options;\n const diffStyle = this.getDiffStyle();\n const hunkSeparators = this.getHunkSeparatorType();\n const targetLineIndex =\n diffStyle === 'split' ? targetLineIndexes[1] : targetLineIndexes[0];\n this.approximateLayoutCheckpoints(fileDiff);\n const headerRegion = getVirtualFileHeaderRegion(\n this.metrics,\n disableFileHeader\n );\n const checkpoint = this.getLayoutCheckpointBeforeLineIndex(targetLineIndex);\n let top = checkpoint?.top ?? headerRegion + this.cache.fileAnnotationHeight;\n\n if (collapsed) {\n return { top: headerRegion, height: 0 };\n }\n\n let position: { top: number; height: number } | undefined;\n iterateOverDiff({\n diff: fileDiff,\n diffStyle,\n startingLine: checkpoint?.renderedLineIndex ?? 0,\n expandedHunks: expandUnchanged\n ? true\n : this.hunksRenderer.getExpandedHunksMap(),\n collapsedContextThreshold,\n callback: ({\n hunkIndex,\n hunk,\n collapsedBefore,\n collapsedAfter,\n deletionLine,\n additionLine,\n }) => {\n const lineIndex =\n diffStyle === 'split'\n ? (additionLine?.splitLineIndex ?? deletionLine?.splitLineIndex)\n : (additionLine?.unifiedLineIndex ??\n deletionLine?.unifiedLineIndex);\n if (lineIndex == null) {\n throw new Error(\n 'VirtualizedFileDiff.getLinePosition: missing line index data'\n );\n }\n\n if (collapsedBefore > 0) {\n const separator = getLeadingHunkSeparatorLayout({\n type: hunkSeparators,\n metrics: this.metrics,\n hunkIndex,\n hunkSpecs: hunk?.hunkSpecs,\n });\n if (separator != null) {\n top += separator.gapBefore;\n if (\n targetLineIndex >= lineIndex - collapsedBefore &&\n targetLineIndex < lineIndex\n ) {\n position = {\n top,\n height: separator.height,\n };\n return true;\n }\n top += separator.height + separator.gapAfter;\n }\n }\n\n const lineHeight = this.getLineHeight(\n lineIndex,\n (additionLine?.noEOFCR ?? false) || (deletionLine?.noEOFCR ?? false)\n );\n if (lineIndex === targetLineIndex) {\n position = {\n top,\n height: lineHeight,\n };\n return true;\n }\n top += lineHeight;\n\n if (collapsedAfter > 0) {\n const separator = getTrailingHunkSeparatorLayout({\n type: hunkSeparators,\n metrics: this.metrics,\n });\n if (separator != null) {\n if (\n targetLineIndex > lineIndex &&\n targetLineIndex <= lineIndex + collapsedAfter\n ) {\n position = {\n top: top + separator.gapBefore,\n height: separator.height,\n };\n return true;\n }\n top += separator.totalHeight;\n }\n }\n\n return false;\n },\n });\n\n return position;\n }\n\n public getEditorViewport(): HTMLElement | Document | undefined {\n return this.virtualizer.type === 'simple'\n ? this.virtualizer.getRoot()\n : this.virtualizer.getContainerElement();\n }\n\n public getNumericScrollAnchor(\n localViewportTop: number\n ): NumericScrollLineAnchor | undefined {\n const fileDiff = this.getLayoutDiff();\n if (fileDiff == null) {\n return undefined;\n }\n\n const {\n disableFileHeader = false,\n expandUnchanged = false,\n collapsed = false,\n collapsedContextThreshold = DEFAULT_COLLAPSED_CONTEXT_THRESHOLD,\n } = this.options;\n if (collapsed) {\n return undefined;\n }\n\n const diffStyle = this.getDiffStyle();\n const hunkSeparators = this.getHunkSeparatorType();\n\n this.approximateLayoutCheckpoints(fileDiff);\n const checkpoint = this.getLayoutCheckpointBeforeTop(localViewportTop);\n let top =\n checkpoint?.top ??\n getVirtualFileHeaderRegion(this.metrics, disableFileHeader) +\n this.cache.fileAnnotationHeight;\n let anchor: NumericScrollLineAnchor | undefined;\n\n // This may end up being quite expensive on extremely large files, we may\n // need to figure out how to anchor on different regions, or utilize\n // renderRange to shortcut this for us somehow\n iterateOverDiff({\n diff: fileDiff,\n diffStyle,\n startingLine: checkpoint?.renderedLineIndex ?? 0,\n expandedHunks: expandUnchanged\n ? true\n : this.hunksRenderer.getExpandedHunksMap(),\n collapsedContextThreshold,\n callback: ({\n hunkIndex,\n hunk,\n collapsedBefore,\n collapsedAfter,\n deletionLine,\n additionLine,\n }) => {\n const lineIndex =\n diffStyle === 'split'\n ? (additionLine?.splitLineIndex ?? deletionLine?.splitLineIndex)\n : (additionLine?.unifiedLineIndex ??\n deletionLine?.unifiedLineIndex);\n if (lineIndex == null) {\n throw new Error(\n 'VirtualizedFileDiff.getNumericScrollAnchor: missing line index data'\n );\n }\n\n if (collapsedBefore > 0) {\n const separator = getLeadingHunkSeparatorLayout({\n type: hunkSeparators,\n metrics: this.metrics,\n hunkIndex,\n hunkSpecs: hunk?.hunkSpecs,\n });\n if (separator != null) {\n top += separator.totalHeight;\n }\n }\n\n if (top >= localViewportTop) {\n if (deletionLine != null) {\n anchor = {\n lineNumber: deletionLine.lineNumber,\n side: 'deletions',\n top,\n };\n } else if (additionLine != null) {\n anchor = {\n lineNumber: additionLine.lineNumber,\n side: 'additions',\n top,\n };\n }\n if (anchor != null) {\n return true;\n }\n }\n\n const lineHeight = this.getLineHeight(\n lineIndex,\n (additionLine?.noEOFCR ?? false) || (deletionLine?.noEOFCR ?? false)\n );\n top += lineHeight;\n\n if (collapsedAfter > 0) {\n const separator = getTrailingHunkSeparatorLayout({\n type: hunkSeparators,\n metrics: this.metrics,\n });\n if (separator != null) {\n top += separator.totalHeight;\n }\n }\n\n return false;\n },\n });\n\n return anchor;\n }\n\n public getVirtualizedHeight(): number {\n return this.height;\n }\n\n public getAdvancedStickySpecs(\n windowSpecs?: RenderWindow\n ): StickySpecs | undefined {\n const fileDiff = this.getLayoutDiff();\n if (this.top == null || fileDiff == null) {\n return undefined;\n }\n if (this.options.collapsed === true) {\n return { topOffset: this.top, height: this.height };\n }\n const renderRange =\n windowSpecs != null\n ? this.computeRenderRangeFromWindow(fileDiff, this.top, windowSpecs)\n : this.renderRange;\n if (renderRange == null) {\n return undefined;\n }\n const { bufferBefore, bufferAfter, totalLines } = renderRange;\n // Rendered items flow contiguously in the sticky container with no buffer\n // spacers, so a header-only item (totalLines === 0, none of its rows fall\n // inside the window) must report where its header actually sits in that\n // flow, which depends on which side of the window its content is on:\n // - content ABOVE the window (item starts above window.top): the header\n // sits at the item's bottom so the following item connects, so offset by\n // bufferAfter.\n // - content BELOW the window (item starts at/after window.top, e.g. a\n // trailing header peeking in at the bottom): the header renders at the\n // item's top with nothing after it, so no offset. Always adding\n // bufferAfter here made getStickyBounds over-measure the sticky\n // container for that trailing case.\n let headerOnlyOffset = 0;\n if (totalLines === 0) {\n const activeWindow = windowSpecs ?? this.virtualizer.getWindowSpecs();\n if (this.top < activeWindow.top) {\n headerOnlyOffset = bufferAfter;\n }\n }\n return {\n topOffset: this.top + bufferBefore + headerOnlyOffset,\n height: this.height - (bufferBefore + bufferAfter),\n };\n }\n\n override cleanUp(recycle = false): void {\n const hadGhostTextRows = this.cache.ghostTextRows.size > 0;\n if (hadGhostTextRows) {\n this.layoutDirty = true;\n }\n const shouldRecomputeLayout =\n recycle &&\n this.isAdvancedMode() &&\n this.fileContainer != null &&\n (hadGhostTextRows ||\n !areDiffTargetsEqual(this.getRenderedDiff(), this.getLatestDiff()));\n if (this.fileContainer != null && this.isSimpleMode()) {\n this.getSimpleVirtualizer()?.disconnect(this.fileContainer);\n }\n if (!recycle) {\n this.resetLayoutCache({ includeEstimatedHeights: true });\n this.pendingExpansions = undefined;\n this.pendingHydratedDiff = undefined;\n }\n this.pendingRender = undefined;\n this.isSetup = false;\n super.cleanUp(recycle);\n if (shouldRecomputeLayout) {\n this.virtualizer.instanceChanged(this, true);\n }\n }\n\n override expandHunk = (\n hunkIndex: number,\n direction: ExpansionDirections,\n expansionLineCountOverride?: number\n ): void => {\n if (this.fileDiff == null) {\n return;\n }\n if (this.isAdvancedMode()) {\n this.pendingExpansions ??= [];\n this.pendingExpansions.push({\n hunkIndex,\n direction,\n expansionLineCountOverride,\n });\n } else {\n this.hunksRenderer.expandHunk(\n hunkIndex,\n direction,\n expansionLineCountOverride\n );\n this.resetLayoutCache({ includeEstimatedHeights: true });\n this.computeApproximateSize();\n }\n this.loadFilesIfNecessary();\n this.forceRenderOverride = true;\n this.virtualizer.instanceChanged(this, true);\n };\n\n protected override async handleFilesLoaded(\n expectedDiff: FileDiffMetadata,\n files: LoadedPartialDiffContents\n ): Promise<void> {\n if (this.fileDiff !== expectedDiff || !expectedDiff.isPartial) {\n return;\n }\n // CodeView component requires careful control for anchor\n // fixing on re-renders, and thus we cannot apply the\n // next diff immediately. Instead we clone and stage it for\n // CodeView layout to consume at render time.\n if (this.isAdvancedMode()) {\n const nextDiff = hydratePartialDiff('clone', expectedDiff, files);\n await awaitWithTimeout(() => this.primeHighlightCache(nextDiff));\n if (!this.enabled || this.fileDiff !== expectedDiff) {\n return;\n }\n this.pendingHydratedDiff = {\n expectedDiff,\n nextDiff,\n files,\n };\n } else {\n hydratePartialDiff('merge', expectedDiff, files);\n this.setHydratedState(files);\n if (!this.startHydratedEditSession(expectedDiff)) {\n await awaitWithTimeout(() => this.primeHighlightCache(expectedDiff));\n if (!this.enabled || this.fileDiff !== expectedDiff) {\n return;\n }\n }\n this.resetLayoutCache({ includeEstimatedHeights: true });\n this.computeApproximateSize();\n }\n this.forceRenderOverride = true;\n this.virtualizer.instanceChanged(this, true);\n }\n\n protected override loadFilesIfNecessary(): void {\n if (this.pendingHydratedDiff != null) {\n if (this.pendingHydratedDiff.expectedDiff === this.fileDiff) {\n return;\n }\n this.pendingHydratedDiff = undefined;\n }\n\n super.loadFilesIfNecessary();\n }\n\n // In advanced (CodeView) mode, expansions are staged in pendingExpansions\n // until the next layout consume, so the renderer's expansion map lags a\n // just-requested reveal. Account for the staged expansions so callers (the\n // editor's caret-scroll retry) see the post-consume visibility.\n override isLineRenderable(lineNumber: number): boolean {\n if (super.isLineRenderable(lineNumber)) {\n return true;\n }\n const { pendingExpansions } = this;\n const fileDiff = this.getRenderedDiff();\n if (\n pendingExpansions == null ||\n pendingExpansions.length === 0 ||\n fileDiff == null\n ) {\n return false;\n }\n const {\n expansionLineCount = 100,\n collapsedContextThreshold = DEFAULT_COLLAPSED_CONTEXT_THRESHOLD,\n } = this.options;\n const staged = new Map(this.hunksRenderer.getExpandedHunksMap());\n for (const expansion of pendingExpansions) {\n const region = {\n ...(staged.get(expansion.hunkIndex) ?? { fromStart: 0, fromEnd: 0 }),\n };\n const count = expansion.expansionLineCountOverride ?? expansionLineCount;\n if (expansion.direction === 'up' || expansion.direction === 'both') {\n region.fromStart += count;\n }\n if (expansion.direction === 'down' || expansion.direction === 'both') {\n region.fromEnd += count;\n }\n staged.set(expansion.hunkIndex, region);\n }\n return isAdditionLineRenderable({\n fileDiff,\n lineNumber,\n expandedHunks: staged,\n collapsedContextThreshold,\n });\n }\n\n /**\n * Invalidate layout after an edit session changed the rendered row set\n * without a line-count change (a mid-session region change or the exit\n * recompute): estimated heights bake the hunk shapes in, and nothing else\n * invalidates them now that editing does not flip expandUnchanged. Public\n * so CodeView can run it when reaping a session whose instance was already\n * released.\n */\n public invalidateEditSessionLayout(): void {\n this.getSimpleVirtualizer()?.markDOMDirty();\n this.resetLayoutCache({\n forceSimpleRecompute: this.isSimpleMode(),\n includeEstimatedHeights: true,\n resetRenderRange: false,\n });\n if (!this.isSimpleMode()) {\n this.computeApproximateSize(true);\n }\n this.getSimpleVirtualizer()?.requestHeightReconcile(this);\n }\n\n // Session region changes need the same invalidation a document change\n // gets. The virtualizer is told the layout changed (rendered rows and\n // heights moved) and defers the actual render through its own queue; a\n // released instance stops at the cache invalidation and the host relayout\n // covers it.\n protected override escalateEditSessionRender(): void {\n this.invalidateEditSessionLayout();\n if (!this.enabled || this.fileDiff == null) {\n return;\n }\n this.forceRenderOverride = true;\n this.virtualizer.instanceChanged(this, true);\n }\n\n protected override shouldSelfHealEditSession(): boolean {\n // CodeView sessions retain their editor association while rendering is\n // suspended; CodeView itself runs the exit recompute when it reaps one.\n return !this.isAdvancedMode() && super.shouldSelfHealEditSession();\n }\n\n public setVisibility(visible: boolean): void {\n if (this.isAdvancedMode() || this.fileContainer == null) {\n return;\n }\n this.renderRange = undefined;\n if (visible && !this.isVisible) {\n this.top = this.getVirtualizedTop();\n this.isVisible = true;\n } else if (!visible && this.isVisible) {\n this.isVisible = false;\n this.rerender();\n }\n }\n\n override rerender(): void {\n if (\n !this.enabled ||\n (this.fileDiff == null &&\n this.additionFile == null &&\n this.deletionFile == null)\n ) {\n return;\n }\n const latestDiff = this.getLatestDiff();\n const nextRenderDiff =\n latestDiff == null\n ? undefined\n : this.hunksRenderer.getDiffForNextRender(latestDiff);\n // A completed async highlight can change which diff the next simple\n // virtualizer render will commit. CodeView refreshes this during layout.\n if (this.isSimpleMode()) {\n this.pendingRender = undefined;\n }\n this.forceRenderOverride = true;\n this.virtualizer.instanceChanged(\n this,\n !areDiffTargetsEqual(this.getRenderedDiff(), nextRenderDiff)\n );\n }\n\n // The editor changed the ghost text rows it shows below lines. Ask the\n // virtualizer for a layout pass, which folds them in (see\n // applyGhostTextRows). Layout state only changes inside that pass.\n public syncGhostTextRows(): void {\n const codeView = this.getAdvancedVirtualizer();\n if (codeView != null) {\n codeView.capturePendingLayoutAnchor();\n this.layoutDirty = true;\n codeView.instanceChanged(this, true);\n } else {\n this.getSimpleVirtualizer()?.requestHeightReconcile(this);\n }\n }\n\n // Normally triggered by the host when the document line count changes.\n override applyDocumentChange(\n textDocument: TextDocument<'file-diff', LAnnotation>,\n newLineAnnotations?: DiffLineAnnotation<LAnnotation>[],\n shouldUpdateBuffer = false\n ): void {\n const { renderRange: previousRenderRange } = this;\n // Capture the scroll anchor before the synchronous hunk rebuild and\n // measured-height wipe below; the host's next frame resolves it against\n // the new geometry so on-screen rows do not shift.\n this.getAdvancedVirtualizer()?.capturePendingLayoutAnchor();\n super.applyDocumentChange(textDocument, newLineAnnotations);\n this.getSimpleVirtualizer()?.markDOMDirty();\n this.resetLayoutCache({\n forceSimpleRecompute: this.isSimpleMode(),\n includeEstimatedHeights: true,\n resetRenderRange: false,\n });\n\n const fileDiff = this.getRenderedDiff();\n if (!this.isSimpleMode()) {\n this.computeApproximateSize(true);\n } else if (\n shouldUpdateBuffer &&\n previousRenderRange != null &&\n fileDiff != null\n ) {\n // Update the buffers caused by the line-count change to ensure the host\n // scrolls to the correct position before re-rendering.\n const windowSpecs = this.virtualizer.getWindowSpecs();\n const renderRange = this.computeRenderRangeFromWindow(\n fileDiff,\n this.top ?? 0,\n windowSpecs\n );\n if (renderRange.bufferAfter !== previousRenderRange.bufferAfter) {\n this.updateBuffers(renderRange);\n }\n }\n\n this.forceRenderOverride = true;\n this.virtualizer.instanceChanged(this, true);\n }\n\n // Compute the approximate size from the cached baseline estimate plus any\n // measured height deltas observed in rendered rows.\n // The reason we refer to this as `approximate size` is because heights my\n // dynamically change for a number of reasons so we can never be fully sure\n // if the height is 100% accurate\n private computeApproximateSize(\n force = false,\n fileDiff: FileDiffMetadata | undefined = this.getLayoutDiff()\n ): void {\n const shouldValidateSize = this.isResizeDebuggingEnabled();\n if (!force && !this.layoutDirty && !shouldValidateSize) {\n return;\n }\n\n const isFirstCompute = this.height === 0;\n this.height = 0;\n this.cache.checkpoints = [];\n this.cache.totalLines = 0;\n if (fileDiff == null) {\n this.layoutDirty = false;\n return;\n }\n this.applyGhostTextRows(\n fileDiff,\n this.editor?.__getGhostTextRows() ?? NO_GHOST_TEXT_ROWS\n );\n\n const { disableFileHeader = false, collapsed = false } = this.options;\n const headerRegion = getVirtualFileHeaderRegion(\n this.metrics,\n disableFileHeader\n );\n\n this.height += headerRegion;\n if (collapsed) {\n this.layoutDirty = false;\n return;\n }\n\n this.height =\n this.getActiveEstimatedHeight(fileDiff) +\n this.cache.measuredHeightDeltaTotal;\n\n if (shouldValidateSize && !isFirstCompute) {\n this.validateComputedHeight(fileDiff);\n }\n this.layoutDirty = false;\n }\n\n // CodeView calculates its next layout before updating the DOM. This keeps every\n // layout calculation within that frame tied to the same diff.\n private getLayoutDiff(): FileDiffMetadata | undefined {\n return this.pendingRender?.diff ?? this.getRenderedDiff();\n }\n\n private getActiveEstimatedHeight(\n fileDiff: FileDiffMetadata | undefined = this.getLayoutDiff()\n ): number {\n this.ensureEstimatedDiffHeights(fileDiff);\n const estimatedHeight =\n this.getDiffStyle() === 'split'\n ? this.cache.estimatedSplitHeight\n : this.cache.estimatedUnifiedHeight;\n if (estimatedHeight == null) {\n throw new Error(\n 'VirtualizedFileDiff.getActiveEstimatedHeight: missing estimated height'\n );\n }\n return estimatedHeight;\n }\n\n private ensureEstimatedDiffHeights(\n fileDiff: FileDiffMetadata | undefined = this.getLayoutDiff()\n ): void {\n if (fileDiff == null) {\n this.cache.estimatedSplitHeight = undefined;\n this.cache.estimatedUnifiedHeight = undefined;\n return;\n }\n if (\n this.cache.estimatedSplitHeight != null &&\n this.cache.estimatedUnifiedHeight != null\n ) {\n return;\n }\n\n const {\n disableFileHeader = false,\n expandUnchanged = false,\n collapsedContextThreshold = DEFAULT_COLLAPSED_CONTEXT_THRESHOLD,\n } = this.options;\n const { splitHeight, unifiedHeight } = computeEstimatedDiffHeights({\n fileDiff,\n metrics: this.metrics,\n disableFileHeader,\n hunkSeparators: this.getHunkSeparatorType(),\n expandUnchanged,\n expandedHunks: this.hunksRenderer.getExpandedHunksMap(),\n collapsedContextThreshold,\n canHydratePartialDiff: canHydrateCollapsedContext(\n fileDiff,\n this.options.loadDiffFiles != null\n ),\n });\n this.cache.estimatedSplitHeight = splitHeight;\n this.cache.estimatedUnifiedHeight = unifiedHeight;\n }\n\n private validateComputedHeight(\n fileDiff: FileDiffMetadata | undefined = this.getLayoutDiff()\n ): void {\n if (this.fileContainer == null || fileDiff == null) {\n return;\n }\n\n const rect = this.fileContainer.getBoundingClientRect();\n if (rect.height !== this.height) {\n console.log(\n 'VirtualizedFileDiff.computeApproximateSize: computed height doesnt match',\n {\n name: fileDiff.name,\n elementHeight: rect.height,\n computedHeight: this.height,\n }\n );\n } else {\n console.log(\n 'VirtualizedFileDiff.computeApproximateSize: computed height IS CORRECT'\n );\n }\n }\n\n override render({\n fileContainer,\n fileDiff,\n forceRender = false,\n lineAnnotations,\n ...fileInputProps\n }: FileDiffRenderProps<LAnnotation> = {}): boolean {\n const fileInput = getDiffFileInput(\n fileInputProps,\n 'VirtualizedFileDiff.render'\n );\n const hasFileInput = fileInput != null;\n const oldFile = fileInput?.oldFile;\n const newFile = fileInput?.newFile;\n const filesDidChange =\n hasFileInput &&\n (!areOptionalFilesEqual(oldFile, this.deletionFile) ||\n !areOptionalFilesEqual(newFile, this.additionFile));\n let nextFileDiff = fileDiff ?? this.fileDiff;\n if (\n fileDiff == null &&\n hasFileInput &&\n (filesDidChange || this.fileDiff == null)\n ) {\n nextFileDiff = parseDiffFromFile(\n fileInput.oldFile,\n fileInput.newFile,\n this.options.parseDiffOptions\n );\n }\n const { forceRenderOverride, isSetup } = this;\n this.forceRenderOverride = undefined;\n const targetChanged =\n nextFileDiff != null && !areDiffTargetsEqual(this.fileDiff, nextFileDiff);\n const dataChanged = targetChanged || filesDidChange;\n\n fileContainer = this.getOrCreateFileContainer(fileContainer);\n\n if (nextFileDiff == null) {\n console.error(\n 'VirtualizedFileDiff.render: attempting to virtually render when we dont have the correct data'\n );\n return false;\n }\n if (targetChanged) {\n this.updateExternalDiff(nextFileDiff, lineAnnotations);\n }\n\n const {\n pendingRenderDiff,\n layoutDiffChanged,\n renderedDiffChanged,\n annotationsChanged,\n } = (() => {\n if (\n this.pendingRender != null &&\n this.pendingRender.latestDiff ===\n (this.getLatestDiff(nextFileDiff) ?? nextFileDiff)\n ) {\n return {\n pendingRenderDiff: this.pendingRender.diff,\n layoutDiffChanged: false,\n renderedDiffChanged: false,\n annotationsChanged: false,\n };\n }\n return this.updatePendingRender(nextFileDiff, lineAnnotations);\n })();\n\n if (annotationsChanged || layoutDiffChanged) {\n this.resetLayoutCache({\n includeEstimatedHeights: layoutDiffChanged,\n });\n }\n\n if (!isSetup) {\n this.computeApproximateSize(false, pendingRenderDiff);\n const virtualizer = this.getSimpleVirtualizer();\n this.top ??= this.getVirtualizedTop();\n if (this.isAdvancedMode()) {\n this.isVisible = true;\n } else {\n if (virtualizer == null) {\n throw new Error(\n 'VirtualizedFileDiff.render: simple virtualizer is not available'\n );\n }\n virtualizer.connect(fileContainer, this);\n this.isVisible = virtualizer.isInstanceVisible(\n this.top ?? 0,\n this.height\n );\n }\n this.isSetup = true;\n } else {\n this.top ??= this.getVirtualizedTop();\n if (layoutDiffChanged) {\n this.getSimpleVirtualizer()?.markDOMDirty();\n this.computeApproximateSize(false, pendingRenderDiff);\n }\n }\n\n if (!this.isVisible && this.isSimpleMode() && (!dataChanged || !isSetup)) {\n if (fileInput != null) {\n this.deletionFile = oldFile;\n this.additionFile = newFile;\n }\n if (targetChanged) {\n this.clearReusableHeader();\n }\n this.pendingRender = undefined;\n return this.renderPlaceholder(this.height);\n }\n\n const windowSpecs = this.virtualizer.getWindowSpecs();\n const fileTop = this.top ?? 0;\n const renderRange = this.computeRenderRangeFromWindow(\n pendingRenderDiff,\n fileTop,\n windowSpecs\n );\n return super.render({\n fileDiff: nextFileDiff,\n fileContainer,\n renderRange,\n lineAnnotations,\n forceRender:\n (forceRenderOverride ?? forceRender) ||\n annotationsChanged ||\n renderedDiffChanged ||\n targetChanged,\n ...fileInput,\n ...fileInputProps,\n });\n }\n\n protected override finalizeRender(): void {\n if (this.getRenderedDiff() !== this.pendingRender?.diff) {\n throw new Error(\n 'VirtualizedFileDiff.render: rendered a different diff than its prepared layout'\n );\n }\n this.pendingRender = undefined;\n // Renders can be driven from outside the virtualizer (host/React render\n // calls, async highlight completions), and the virtualizer only\n // auto-reconciles renders it initiated. Queue a measured-height\n // reconciliation for every applied content render so line deltas\n // (wrapped lines, annotation heights) survive layout resets.\n if (this.isSimpleMode()) {\n this.getSimpleVirtualizer()?.requestHeightReconcile(this);\n }\n }\n\n private updatePendingRender(\n nextFileDiff: FileDiffMetadata,\n lineAnnotations: DiffLineAnnotation<LAnnotation>[] | undefined\n ) {\n const latestDiff = this.getLatestDiff(nextFileDiff) ?? nextFileDiff;\n const previousRenderedDiff = this.getRenderedDiff();\n const { pendingRender } = this;\n const previousLayoutDiff = pendingRender?.diff ?? previousRenderedDiff;\n const pendingRenderDiff =\n this.hunksRenderer.getDiffForNextRender(latestDiff);\n\n this.pendingRender = { latestDiff, diff: pendingRenderDiff };\n\n return {\n pendingRenderDiff,\n annotationsChanged: this.syncLineAnnotations(lineAnnotations),\n layoutDiffChanged: !areDiffTargetsEqual(\n previousLayoutDiff,\n pendingRenderDiff\n ),\n renderedDiffChanged: !areDiffTargetsEqual(\n previousRenderedDiff,\n pendingRenderDiff\n ),\n };\n }\n\n public syncVirtualizedTop(): void {\n this.top = this.getVirtualizedTop();\n }\n\n protected override shouldDisableVirtualizationBuffers(): boolean {\n return this.isAdvancedMode() || super.shouldDisableVirtualizationBuffers();\n }\n\n // This WebKit dom manipulation scroll fix is not applicable in virtualized\n // environments, so we avoid the performance hit even on Webkit\n protected override shouldGuardRebuildScroll(): boolean {\n return false;\n }\n\n private isSimpleMode(): boolean {\n return this.virtualizer.type === 'simple';\n }\n\n private isAdvancedMode(): boolean {\n return this.virtualizer.type === 'advanced';\n }\n\n private getVirtualizedTop(): number {\n if (this.virtualizer.type === 'advanced') {\n return this.virtualizer.getLocalTopForInstance(this);\n }\n return this.fileContainer != null\n ? this.virtualizer.getOffsetInScrollContainer(this.fileContainer)\n : 0;\n }\n\n private getSimpleVirtualizer(): Virtualizer | undefined {\n return this.virtualizer.type === 'simple' ? this.virtualizer : undefined;\n }\n\n private getAdvancedVirtualizer(): CodeView<LAnnotation, Caret> | undefined {\n return this.virtualizer.type === 'advanced' ? this.virtualizer : undefined;\n }\n\n private isResizeDebuggingEnabled(): boolean {\n return this.getSimpleVirtualizer()?.config.resizeDebugging ?? false;\n }\n\n private getDiffStyle(): 'split' | 'unified' {\n return this.options.diffStyle ?? 'split';\n }\n\n private getHunkSeparatorType(): HunkSeparators {\n return getOptionHunkSeparatorType(this.options.hunkSeparators);\n }\n\n private approximateLayoutCheckpoints(fileDiff: FileDiffMetadata): void {\n if (\n (!this.layoutDirty && this.cache.checkpoints.length > 0) ||\n fileDiff.hunks.length === 0 ||\n this.options.collapsed === true\n ) {\n return;\n }\n\n const {\n disableFileHeader = false,\n expandUnchanged = false,\n collapsedContextThreshold = DEFAULT_COLLAPSED_CONTEXT_THRESHOLD,\n } = this.options;\n const finalHunkIndex = fileDiff.hunks.length - 1;\n const canHydratePartialDiff = canHydrateCollapsedContext(\n fileDiff,\n this.options.loadDiffFiles != null\n );\n const diffStyle = this.getDiffStyle();\n const hunkSeparators = this.getHunkSeparatorType();\n const expandedHunks = expandUnchanged\n ? true\n : this.hunksRenderer.getExpandedHunksMap();\n const heightDeltaPrefix = createHeightDeltaPrefix(this.cache.heightDeltas);\n let top =\n getVirtualFileHeaderRegion(this.metrics, disableFileHeader) +\n this.cache.fileAnnotationHeight;\n let renderedLineIndex = 0;\n\n const processRows = ({\n rowCount,\n startLineIndex,\n preSeparatorHeight = 0,\n postSeparatorHeight = 0,\n metadataOffsets = [],\n }: {\n rowCount: number;\n startLineIndex: number;\n preSeparatorHeight?: number;\n postSeparatorHeight?: number;\n metadataOffsets?: number[];\n }) => {\n if (rowCount <= 0) {\n return;\n }\n\n const blockStart = renderedLineIndex;\n const blockEnd = renderedLineIndex + rowCount;\n let nextCheckpoint = getNextCheckpointIndex(blockStart);\n while (nextCheckpoint < blockEnd) {\n const offset = nextCheckpoint - blockStart;\n const checkpointTop =\n top +\n (offset > 0 ? preSeparatorHeight : 0) +\n offset * this.metrics.lineHeight +\n countMetadataOffsetsBefore(metadataOffsets, offset) *\n this.metrics.lineHeight +\n sumHeightDeltas(\n heightDeltaPrefix,\n startLineIndex,\n startLineIndex + offset\n );\n this.cache.checkpoints.push({\n renderedLineIndex: nextCheckpoint,\n lineIndex: startLineIndex + offset,\n top: checkpointTop,\n });\n nextCheckpoint += VIRTUALIZED_FILE_DIFF_LAYOUT_CHECKPOINT_INTERVAL;\n }\n\n top +=\n preSeparatorHeight +\n rowCount * this.metrics.lineHeight +\n metadataOffsets.length * this.metrics.lineHeight +\n sumHeightDeltas(\n heightDeltaPrefix,\n startLineIndex,\n startLineIndex + rowCount\n ) +\n postSeparatorHeight;\n renderedLineIndex = blockEnd;\n };\n\n for (let hunkIndex = 0; hunkIndex < fileDiff.hunks.length; hunkIndex++) {\n const hunk = fileDiff.hunks[hunkIndex];\n if (hunk == null) {\n throw new Error(\n 'VirtualizedFileDiff.approximateLayoutCheckpoints: invalid hunk index'\n );\n }\n\n const leadingRegion = getExpandedRegion({\n isPartial: fileDiff.isPartial,\n rangeSize: hunk.collapsedBefore,\n expandedHunks,\n hunkIndex,\n collapsedContextThreshold,\n });\n const leadingSeparatorHeight =\n leadingRegion.collapsedLines > 0\n ? (getLeadingHunkSeparatorLayout({\n type: hunkSeparators,\n metrics: this.metrics,\n hunkIndex,\n hunkSpecs: hunk.hunkSpecs,\n })?.totalHeight ?? 0)\n : 0;\n\n processRows({\n rowCount: leadingRegion.fromStart,\n startLineIndex:\n (diffStyle === 'split'\n ? hunk.splitLineStart\n : hunk.unifiedLineStart) - leadingRegion.rangeSize,\n });\n\n let pendingLeadingSeparatorHeight = leadingSeparatorHeight;\n processRows({\n rowCount: leadingRegion.fromEnd,\n startLineIndex:\n (diffStyle === 'split'\n ? hunk.splitLineStart\n : hunk.unifiedLineStart) - leadingRegion.fromEnd,\n preSeparatorHeight: pendingLeadingSeparatorHeight,\n });\n if (leadingRegion.fromEnd > 0) {\n pendingLeadingSeparatorHeight = 0;\n }\n\n const trailingRegion =\n hunkIndex === finalHunkIndex\n ? getTrailingExpandedRegion({\n fileDiff,\n hunkIndex,\n expandedHunks,\n collapsedContextThreshold,\n errorPrefix: 'VirtualizedFileDiff',\n })\n : undefined;\n const trailingSeparatorHeight =\n trailingRegion != null && trailingRegion.collapsedLines > 0\n ? (getTrailingHunkSeparatorLayout({\n type: hunkSeparators,\n metrics: this.metrics,\n })?.totalHeight ?? 0)\n : hunkIndex === finalHunkIndex && canHydratePartialDiff\n ? (getTrailingHunkSeparatorLayout({\n type: hunkSeparators,\n metrics: this.metrics,\n })?.totalHeight ?? 0)\n : 0;\n const trailingExpandedCount =\n trailingRegion != null\n ? trailingRegion.fromStart + trailingRegion.fromEnd\n : 0;\n\n const hunkBodyRowCount =\n diffStyle === 'split' ? hunk.splitLineCount : hunk.unifiedLineCount;\n const hunkBodyStartLineIndex =\n diffStyle === 'split' ? hunk.splitLineStart : hunk.unifiedLineStart;\n processRows({\n rowCount: hunkBodyRowCount,\n startLineIndex: hunkBodyStartLineIndex,\n preSeparatorHeight: pendingLeadingSeparatorHeight,\n postSeparatorHeight:\n trailingExpandedCount === 0 ? trailingSeparatorHeight : 0,\n metadataOffsets: getHunkMetadataOffsets({\n diffStyle,\n hunk,\n rowCount: hunkBodyRowCount,\n }),\n });\n\n if (trailingRegion != null && trailingExpandedCount > 0) {\n processRows({\n rowCount: trailingExpandedCount,\n startLineIndex: hunkBodyStartLineIndex + hunkBodyRowCount,\n postSeparatorHeight: trailingSeparatorHeight,\n });\n }\n }\n\n this.cache.totalLines = renderedLineIndex;\n }\n\n // Find the nearest sparse layout checkpoint at or before an active\n // diff-style line index. Diff checkpoints also store the dense rendered-row\n // index, so deep line-position lookups can resume iteration from that\n // rendered row and replay only the nearby layout work instead of walking\n // from the first hunk.\n private getLayoutCheckpointBeforeLineIndex(\n lineIndex: number\n ): DiffLayoutCheckpoint | undefined {\n if (lineIndex <= 0 || this.cache.checkpoints.length === 0) {\n return undefined;\n }\n\n let low = 0;\n let high = this.cache.checkpoints.length - 1;\n let result: DiffLayoutCheckpoint | undefined;\n\n while (low <= high) {\n const mid = (low + high) >> 1;\n const checkpoint = this.cache.checkpoints[mid];\n if (checkpoint == null) {\n throw new Error('VirtualizedFileDiff: invalid checkpoint index');\n }\n if (checkpoint.lineIndex <= lineIndex) {\n result = checkpoint;\n low = mid + 1;\n } else {\n high = mid - 1;\n }\n }\n\n return result;\n }\n\n // Find the nearest sparse layout checkpoint at or before a scroll offset.\n // Render-range scans start from this checkpoint so variable-height diffs\n // only replay nearby rows. When `hunkLineCount` is provided, step backward\n // to a rendered hunk boundary so buffer calculations can reuse absolute hunk\n // offsets safely.\n private getLayoutCheckpointBeforeTop(\n top: number,\n hunkLineCount?: number\n ): DiffLayoutCheckpoint | undefined {\n let low = 0;\n let high = this.cache.checkpoints.length - 1;\n let resultIndex = -1;\n\n while (low <= high) {\n const mid = (low + high) >> 1;\n const checkpoint = this.cache.checkpoints[mid];\n if (checkpoint == null) {\n throw new Error('VirtualizedFileDiff: invalid checkpoint index');\n }\n if (checkpoint.top <= top) {\n resultIndex = mid;\n low = mid + 1;\n } else {\n high = mid - 1;\n }\n }\n\n if (hunkLineCount == null) {\n return resultIndex >= 0 ? this.cache.checkpoints[resultIndex] : undefined;\n }\n\n for (let index = resultIndex; index >= 0; index--) {\n const checkpoint = this.cache.checkpoints[index];\n if (checkpoint == null) {\n throw new Error('VirtualizedFileDiff: invalid checkpoint index');\n }\n if (checkpoint.renderedLineIndex % hunkLineCount === 0) {\n return checkpoint;\n }\n }\n\n return undefined;\n }\n\n private getExpandedLineCount(\n fileDiff: FileDiffMetadata,\n diffStyle: 'split' | 'unified'\n ): number {\n let count = 0;\n if (fileDiff.isPartial) {\n for (const hunk of fileDiff.hunks) {\n count +=\n diffStyle === 'split' ? hunk.splitLineCount : hunk.unifiedLineCount;\n }\n return count;\n }\n\n const {\n expandUnchanged = false,\n collapsedContextThreshold = DEFAULT_COLLAPSED_CONTEXT_THRESHOLD,\n } = this.options;\n const expandedHunks = expandUnchanged\n ? true\n : this.hunksRenderer.getExpandedHunksMap();\n\n for (const [hunkIndex, hunk] of fileDiff.hunks.entries()) {\n const hunkCount =\n diffStyle === 'split' ? hunk.splitLineCount : hunk.unifiedLineCount;\n count += hunkCount;\n const collapsedBefore = Math.max(hunk.collapsedBefore, 0);\n const { fromStart, fromEnd, renderAll } = getExpandedRegion({\n isPartial: fileDiff.isPartial,\n rangeSize: collapsedBefore,\n expandedHunks,\n hunkIndex,\n collapsedContextThreshold,\n });\n if (collapsedBefore > 0) {\n count += renderAll ? collapsedBefore : fromStart + fromEnd;\n }\n }\n\n const trailingRegion = getTrailingExpandedRegion({\n fileDiff,\n hunkIndex: fileDiff.hunks.length - 1,\n expandedHunks,\n collapsedContextThreshold,\n errorPrefix: 'VirtualizedFileDiff',\n });\n if (trailingRegion != null) {\n count += trailingRegion.fromStart + trailingRegion.fromEnd;\n }\n\n return count;\n }\n\n // Row total used to clamp render-range scrolling. Sparse layout checkpoints can\n // still hold a smaller pre-edit count until they are rebuilt, so always take\n // the max against the live diff metadata (including additionLines.length).\n private getLayoutLineCount(\n fileDiff: FileDiffMetadata,\n diffStyle: 'split' | 'unified'\n ): number {\n const expandedLineCount = this.getExpandedLineCount(fileDiff, diffStyle);\n const metadataLineCount =\n diffStyle === 'split'\n ? fileDiff.splitLineCount\n : fileDiff.unifiedLineCount;\n return Math.max(\n expandedLineCount,\n metadataLineCount,\n fileDiff.additionLines.length,\n fileDiff.deletionLines.length,\n this.cache.totalLines\n );\n }\n\n private computeRenderRangeFromWindow(\n fileDiff: FileDiffMetadata,\n fileTop: number,\n { top, bottom }: RenderWindow\n ): RenderRange {\n const {\n disableFileHeader = false,\n expandUnchanged = false,\n collapsedContextThreshold = DEFAULT_COLLAPSED_CONTEXT_THRESHOLD,\n } = this.options;\n const { hunkLineCount, lineHeight } = this.metrics;\n const diffStyle = this.getDiffStyle();\n const hunkSeparators = this.getHunkSeparatorType();\n const canHydratePartialDiff = canHydrateCollapsedContext(\n fileDiff,\n this.options.loadDiffFiles != null\n );\n const fileHeight = this.height;\n let lineCount = this.getLayoutLineCount(fileDiff, diffStyle);\n\n const headerRegion = getVirtualFileHeaderRegion(\n this.metrics,\n disableFileHeader\n );\n const paddingBottom =\n fileDiff.hunks.length > 0 ? getVirtualFilePaddingBottom(this.metrics) : 0;\n const { fileAnnotationHeight } = this.cache;\n const codeRegionTop = headerRegion + fileAnnotationHeight;\n const codeHeight = Math.max(\n 0,\n fileHeight - headerRegion - fileAnnotationHeight - paddingBottom\n );\n const hasFileAnnotations = this.hasFileAnnotations(fileDiff);\n const fileAnnotationTop = fileTop + headerRegion;\n const measuredFileAnnotationVisible =\n fileAnnotationHeight > 0 &&\n hasFileAnnotations &&\n fileAnnotationTop < bottom &&\n fileAnnotationTop + fileAnnotationHeight > top;\n\n // File is outside render window\n if (fileTop < top - fileHeight || fileTop > bottom) {\n return {\n startingLine: 0,\n totalLines: 0,\n bufferBefore: 0,\n bufferAfter: fileHeight - headerRegion - paddingBottom,\n };\n }\n\n // Whole file is under hunkLineCount, just render it all\n if (lineCount <= hunkLineCount || fileDiff.hunks.length === 0) {\n return {\n startingLine: 0,\n totalLines: hunkLineCount,\n bufferBefore: 0,\n bufferAfter: 0,\n };\n }\n\n this.approximateLayoutCheckpoints(fileDiff);\n lineCount = this.getLayoutLineCount(fileDiff, diffStyle);\n\n const estimatedTargetLines = Math.ceil(\n Math.max(bottom - top, 0) / lineHeight\n );\n const totalLines =\n Math.ceil(estimatedTargetLines / hunkLineCount) * hunkLineCount +\n hunkLineCount;\n const totalHunks = totalLines / hunkLineCount;\n const overflowHunks = totalHunks;\n const hunkOffsets: number[] = [];\n // Halfway between top & bottom, represented as an absolute position\n const viewportCenter = (top + bottom) / 2;\n // Start the scan before the viewport so we collect hunk offsets that may be\n // needed for bufferBefore. This only chooses the scan origin; the returned\n // render range is still computed from the visible window below.\n const checkpoint = this.getLayoutCheckpointBeforeTop(\n Math.max(0, top - fileTop - totalLines * lineHeight * 2),\n hunkLineCount\n );\n\n let absoluteLineTop = fileTop + (checkpoint?.top ?? codeRegionTop);\n let currentLine = checkpoint?.renderedLineIndex ?? 0;\n let firstVisibleHunk: number | undefined;\n let centerHunk: number | undefined;\n let overflowCounter: number | undefined;\n\n iterateOverDiff({\n diff: fileDiff,\n diffStyle,\n startingLine: checkpoint?.renderedLineIndex ?? 0,\n expandedHunks: expandUnchanged\n ? true\n : this.hunksRenderer.getExpandedHunksMap(),\n collapsedContextThreshold,\n callback: ({\n hunkIndex,\n hunk,\n collapsedBefore,\n collapsedAfter,\n deletionLine,\n additionLine,\n }) => {\n const splitLineIndex =\n additionLine != null\n ? additionLine.splitLineIndex\n : deletionLine.splitLineIndex;\n const unifiedLineIndex =\n additionLine != null\n ? additionLine.unifiedLineIndex\n : deletionLine.unifiedLineIndex;\n const hasMetadata =\n (additionLine?.noEOFCR ?? false) || (deletionLine?.noEOFCR ?? false);\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 leadingSeparator =\n collapsedBefore > 0\n ? getLeadingHunkSeparatorLayout({\n type: hunkSeparators,\n metrics: this.metrics,\n hunkIndex,\n hunkSpecs: hunk?.hunkSpecs,\n })\n : undefined;\n const gapAdjustment = leadingSeparator?.totalHeight ?? 0;\n\n absoluteLineTop += gapAdjustment;\n\n const isAtHunkBoundary = currentLine % hunkLineCount === 0;\n const currentHunk = Math.floor(currentLine / hunkLineCount);\n\n // Track the boundary positional offset at a hunk\n if (isAtHunkBoundary) {\n hunkOffsets[currentHunk] =\n absoluteLineTop - (fileTop + codeRegionTop + gapAdjustment);\n\n // Check if we should bail (overflow complete)\n if (overflowCounter != null) {\n if (overflowCounter <= 0) {\n return true;\n }\n overflowCounter--;\n }\n }\n\n const lineHeight = this.getLineHeight(\n diffStyle === 'split' ? splitLineIndex : unifiedLineIndex,\n hasMetadata\n );\n\n // Track visible region\n if (absoluteLineTop > top - lineHeight && absoluteLineTop < bottom) {\n firstVisibleHunk ??= currentHunk;\n }\n\n // Track which hunk contains the viewport center\n // If viewport center is above this line and we haven't set centerHunk yet,\n // this is the first line at or past the center\n if (\n centerHunk == null &&\n absoluteLineTop + lineHeight > viewportCenter\n ) {\n centerHunk = currentHunk;\n }\n\n // Start overflow when we are out of the viewport at a hunk boundary\n if (\n overflowCounter == null &&\n absoluteLineTop >= bottom &&\n isAtHunkBoundary\n ) {\n overflowCounter = overflowHunks;\n }\n\n currentLine++;\n absoluteLineTop += lineHeight;\n\n if (collapsedAfter > 0 || (isFinalHunkRow && canHydratePartialDiff)) {\n const trailingSeparator = getTrailingHunkSeparatorLayout({\n type: hunkSeparators,\n metrics: this.metrics,\n });\n if (trailingSeparator != null) {\n if (\n absoluteLineTop < bottom &&\n absoluteLineTop + trailingSeparator.totalHeight > top\n ) {\n firstVisibleHunk ??= currentHunk;\n }\n if (\n centerHunk == null &&\n absoluteLineTop + trailingSeparator.totalHeight > viewportCenter\n ) {\n centerHunk = currentHunk;\n }\n absoluteLineTop += trailingSeparator.totalHeight;\n }\n }\n\n return false;\n },\n });\n\n // No visible lines found\n if (firstVisibleHunk == null) {\n if (measuredFileAnnotationVisible) {\n firstVisibleHunk = 0;\n centerHunk = 0;\n } else {\n return {\n startingLine: 0,\n totalLines: 0,\n bufferBefore: 0,\n bufferAfter: fileHeight - headerRegion - paddingBottom,\n };\n }\n }\n\n // Calculate balanced startingLine centered around the viewport center\n // Fall back to firstVisibleHunk if center wasn't found (e.g., center in a gap)\n centerHunk ??= firstVisibleHunk;\n const idealStartHunk = Math.round(centerHunk - totalHunks / 2);\n\n // Clamp startHunk: at the beginning, reduce totalLines; at the end, shift startHunk back\n const maxStartHunk = Math.max(\n 0,\n Math.ceil(lineCount / hunkLineCount) - totalHunks\n );\n const startHunk = Math.max(0, Math.min(idealStartHunk, maxStartHunk));\n const startingLine = startHunk * hunkLineCount;\n\n // If we wanted to start before 0, reduce totalLines by the clamped amount\n const clampedTotalLines =\n idealStartHunk < 0\n ? totalLines + idealStartHunk * hunkLineCount\n : totalLines;\n\n // Use hunkOffsets array for efficient buffer calculations\n const codeBufferBefore = hunkOffsets[startHunk] ?? 0;\n const bufferBefore =\n startingLine === 0 ? 0 : fileAnnotationHeight + codeBufferBefore;\n\n // Calculate bufferAfter using hunkOffset if available, otherwise use cumulative height\n const finalHunkIndex = startHunk + clampedTotalLines / hunkLineCount;\n const bufferAfter =\n finalHunkIndex < hunkOffsets.length\n ? codeHeight - hunkOffsets[finalHunkIndex]\n : // We stopped early, calculate from current position\n codeHeight - (absoluteLineTop - fileTop - codeRegionTop);\n\n return {\n startingLine,\n totalLines: clampedTotalLines,\n bufferBefore,\n bufferAfter: Math.max(0, bufferAfter),\n };\n }\n}\n\nfunction measureFileAnnotationHeight(\n codeGroups: (HTMLElement | undefined)[]\n): number | undefined {\n let height: number | undefined;\n for (const codeGroup of codeGroups) {\n if (codeGroup == null) continue;\n const content = codeGroup.children[1];\n if (!(content instanceof HTMLElement)) continue;\n for (const child of content.children) {\n if (!(child instanceof HTMLElement)) continue;\n if (child.dataset.lineAnnotation !== FILE_ANNOTATION_DOM_KEY) {\n continue;\n }\n height = Math.max(height ?? 0, child.getBoundingClientRect().height);\n }\n }\n return height;\n}\n\ninterface HeightDeltaPrefix {\n lineIndexes: number[];\n prefixTotals: number[];\n}\n\nfunction createHeightDeltaPrefix(\n heightDeltas: Map<number, number>\n): HeightDeltaPrefix {\n const entries = Array.from(heightDeltas).sort((a, b) => a[0] - b[0]);\n const lineIndexes: number[] = [];\n const prefixTotals = [0];\n let total = 0;\n for (const [lineIndex, delta] of entries) {\n lineIndexes.push(lineIndex);\n total += delta;\n prefixTotals.push(total);\n }\n return { lineIndexes, prefixTotals };\n}\n\nfunction sumHeightDeltas(\n { lineIndexes, prefixTotals }: HeightDeltaPrefix,\n startLineIndex: number,\n endLineIndex: number\n): number {\n if (startLineIndex >= endLineIndex || lineIndexes.length === 0) {\n return 0;\n }\n const start = lowerBound(lineIndexes, startLineIndex);\n const end = lowerBound(lineIndexes, endLineIndex);\n return (prefixTotals[end] ?? 0) - (prefixTotals[start] ?? 0);\n}\n\nfunction lowerBound(values: number[], target: number): number {\n let low = 0;\n let high = values.length;\n while (low < high) {\n const mid = (low + high) >> 1;\n const value = values[mid];\n if (value == null) {\n throw new Error('VirtualizedFileDiff: invalid prefix index');\n }\n if (value < target) {\n low = mid + 1;\n } else {\n high = mid;\n }\n }\n return low;\n}\n\nfunction getNextCheckpointIndex(renderedLineIndex: number): number {\n return (\n Math.ceil(\n renderedLineIndex / VIRTUALIZED_FILE_DIFF_LAYOUT_CHECKPOINT_INTERVAL\n ) * VIRTUALIZED_FILE_DIFF_LAYOUT_CHECKPOINT_INTERVAL\n );\n}\n\nfunction countMetadataOffsetsBefore(\n metadataOffsets: number[],\n offset: number\n): number {\n let count = 0;\n for (const metadataOffset of metadataOffsets) {\n if (metadataOffset < offset) {\n count++;\n }\n }\n return count;\n}\n\nfunction getHunkMetadataOffsets({\n diffStyle,\n hunk,\n rowCount,\n}: {\n diffStyle: 'split' | 'unified';\n hunk: Hunk;\n rowCount: number;\n}): number[] {\n if (rowCount <= 0 || (!hunk.noEOFCRAdditions && !hunk.noEOFCRDeletions)) {\n return [];\n }\n\n const lastContent = hunk.hunkContent.at(-1);\n if (lastContent == null) {\n return [];\n }\n\n if (lastContent.type === 'context') {\n return [rowCount - 1];\n }\n\n const splitCount = Math.max(lastContent.deletions, lastContent.additions);\n const unifiedCount = lastContent.deletions + lastContent.additions;\n if (diffStyle === 'split') {\n return splitCount > 0 && (hunk.noEOFCRAdditions || hunk.noEOFCRDeletions)\n ? [rowCount - 1]\n : [];\n }\n\n const offsets: number[] = [];\n const contentStartOffset = rowCount - unifiedCount;\n if (lastContent.deletions > 0 && hunk.noEOFCRDeletions) {\n offsets.push(contentStartOffset + lastContent.deletions - 1);\n }\n if (lastContent.additions > 0 && hunk.noEOFCRAdditions) {\n offsets.push(rowCount - 1);\n }\n return offsets;\n}\n\nfunction hasDiffLayoutOptionChanged<LAnnotation, Caret>(\n previousOptions: FileDiffOptions<LAnnotation, Caret>,\n nextOptions: FileDiffOptions<LAnnotation, Caret>\n): boolean {\n return (\n (previousOptions.diffStyle ?? 'split') !==\n (nextOptions.diffStyle ?? 'split') ||\n (previousOptions.overflow ?? 'scroll') !==\n (nextOptions.overflow ?? 'scroll') ||\n (previousOptions.collapsed ?? false) !== (nextOptions.collapsed ?? false) ||\n (previousOptions.disableLineNumbers ?? false) !==\n (nextOptions.disableLineNumbers ?? false) ||\n (previousOptions.disableFileHeader ?? false) !==\n (nextOptions.disableFileHeader ?? false) ||\n (previousOptions.diffIndicators ?? 'bars') !==\n (nextOptions.diffIndicators ?? 'bars') ||\n (previousOptions.hunkSeparators ?? 'line-info') !==\n (nextOptions.hunkSeparators ?? 'line-info') ||\n Boolean(previousOptions.loadDiffFiles) !==\n Boolean(nextOptions.loadDiffFiles) ||\n (previousOptions.expandUnchanged ?? false) !==\n (nextOptions.expandUnchanged ?? false) ||\n (previousOptions.collapsedContextThreshold ??\n DEFAULT_COLLAPSED_CONTEXT_THRESHOLD) !==\n (nextOptions.collapsedContextThreshold ??\n DEFAULT_COLLAPSED_CONTEXT_THRESHOLD) ||\n previousOptions.unsafeCSS !== nextOptions.unsafeCSS\n );\n}\n\nfunction hasDiffEstimateOptionChanged<LAnnotation, Caret>(\n previousOptions: FileDiffOptions<LAnnotation, Caret>,\n nextOptions: FileDiffOptions<LAnnotation, Caret>\n): boolean {\n return (\n (previousOptions.disableFileHeader ?? false) !==\n (nextOptions.disableFileHeader ?? false) ||\n (previousOptions.hunkSeparators ?? 'line-info') !==\n (nextOptions.hunkSeparators ?? 'line-info') ||\n Boolean(previousOptions.loadDiffFiles) !==\n Boolean(nextOptions.loadDiffFiles) ||\n (previousOptions.expandUnchanged ?? false) !==\n (nextOptions.expandUnchanged ?? false) ||\n (previousOptions.collapsedContextThreshold ??\n DEFAULT_COLLAPSED_CONTEXT_THRESHOLD) !==\n (nextOptions.collapsedContextThreshold ??\n DEFAULT_COLLAPSED_CONTEXT_THRESHOLD)\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\nfunction getOptionHunkSeparatorType<LAnnotation, Caret>(\n hunkSeparators:\n | FileDiffOptions<LAnnotation, Caret>['hunkSeparators']\n | undefined\n): HunkSeparators {\n return typeof hunkSeparators === 'function'\n ? 'custom'\n : (hunkSeparators ?? 'line-info');\n}\n\nfunction areOptionalFilesEqual(\n fileA: FileContents | null | undefined,\n fileB: FileContents | null | undefined\n): boolean {\n if (fileA == null || fileB == null) {\n return fileA == null && fileB == null;\n }\n return areFilesEqual(fileA, fileB);\n}\n\n// Extracts the view-specific line index from the data-line-index attribute.\n// Format is \"unifiedIndex,splitIndex\"\nfunction parseLineIndex(\n lineIndexAttr: string,\n diffStyle: 'split' | 'unified'\n): number {\n const [unifiedIndex, splitIndex] = lineIndexAttr.split(',').map(Number);\n return diffStyle === 'split' ? splitIndex : unifiedIndex;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"VirtualizedFileDiff.js","names":[],"sources":["../../src/components/VirtualizedFileDiff.ts"],"sourcesContent":["import { DEFAULT_COLLAPSED_CONTEXT_THRESHOLD } from '../constants';\nimport type { TextDocument } from '../editor/textDocument';\nimport type {\n BaseDiffOptions,\n DiffLineAnnotation,\n ExpansionDirections,\n FileContents,\n FileDiffMetadata,\n Hunk,\n HunkSeparators,\n NumericScrollLineAnchor,\n PendingCodeViewLayoutReset,\n RenderRange,\n RenderWindow,\n SelectionSide,\n StickySpecs,\n ThemeTypes,\n VirtualFileMetrics,\n} from '../types';\nimport { areDiffTargetsEqual } from '../utils/areDiffTargetsEqual';\nimport { areFilesEqual } from '../utils/areFilesEqual';\nimport { areObjectsEqual } from '../utils/areObjectsEqual';\nimport { areOptionsEqual } from '../utils/areOptionsEqual';\nimport { awaitWithTimeout } from '../utils/awaitWithTimeout';\nimport { computeEstimatedDiffHeights } from '../utils/computeEstimatedDiffHeights';\nimport {\n computeVirtualFileMetrics,\n getVirtualFileHeaderRegion,\n getVirtualFilePaddingBottom,\n} from '../utils/computeVirtualFileMetrics';\nimport { getDiffFileInput } from '../utils/getDiffFileInput';\nimport { hydratePartialDiff } from '../utils/hydratePartialDiff';\nimport {\n FILE_ANNOTATION_DOM_KEY,\n FILE_ANNOTATION_LINE_NUMBER,\n includesFileAnnotations,\n shouldRenderFileAnnotations,\n} from '../utils/includesFileAnnotations';\nimport { iterateOverDiff } from '../utils/iterateOverDiff';\nimport { parseDiffFromFile } from '../utils/parseDiffFromFile';\nimport {\n getExpandedRegion,\n getLeadingHunkSeparatorLayout,\n getTrailingExpandedRegion,\n getTrailingHunkSeparatorLayout,\n isAdditionLineRenderable,\n} from '../utils/virtualDiffLayout';\nimport type { WorkerPoolManager } from '../worker';\nimport type { CodeView } from './CodeView';\nimport {\n FileDiff,\n type FileDiffOptions,\n type FileDiffRenderProps,\n} from './FileDiff';\nimport type { Virtualizer } from './Virtualizer';\n\ntype LoadedPartialDiffContents = Awaited<\n ReturnType<NonNullable<BaseDiffOptions['loadDiffFiles']>>\n>;\n\ninterface DiffLayoutCheckpoint {\n renderedLineIndex: number;\n lineIndex: number;\n top: number;\n}\n\ninterface DiffLayoutCache {\n // Sparse map: view-specific line index -> measured height delta from the\n // baseline line height. Only stores lines that differ from the estimate.\n heightDeltas: Map<number, number>;\n // Aggregate delta from estimated height, including source row deltas and the\n // zero-baseline file annotation row height.\n measuredHeightDeltaTotal: number;\n // Baseline estimated heights for the active diff content. These are preserved\n // across style/collapse toggles and cleared only when estimate inputs change.\n estimatedSplitHeight: number | undefined;\n estimatedUnifiedHeight: number | undefined;\n // Sparse measured positions used to resume deep geometry scans near a target\n // diff line, rendered row, or scroll offset instead of replaying layout from\n // the first hunk.\n checkpoints: DiffLayoutCheckpoint[];\n // Total renderable diff rows for the current diff style and expansion state.\n totalLines: number;\n // Measured height for the file annotation row. Starts at 0 so\n // unmeasured annotations behave like all other unmeasured annotations.\n fileAnnotationHeight: number;\n // Ghost text rows folded into `heightDeltas`. `ghostTextRows` is the editor's\n // own map (zero-based new-file line -> rows), replaced rather than mutated, so\n // identity alone says whether anything changed. `ghostTextRowsByIndex` is the\n // same data keyed by this view's row index, which the deltas use.\n ghostTextRows: ReadonlyMap<number, number>;\n ghostTextRowsByIndex: Map<number, number>;\n}\n\ninterface ResetLayoutCacheOptions {\n forceSimpleRecompute?: boolean;\n includeEstimatedHeights?: boolean;\n resetRenderRange?: boolean;\n}\n\ninterface PendingLoadedDiff {\n expectedDiff: FileDiffMetadata;\n nextDiff: FileDiffMetadata;\n files: LoadedPartialDiffContents;\n}\n\ninterface PendingExpansion {\n hunkIndex: number;\n direction: ExpansionDirections;\n expansionLineCountOverride: number | undefined;\n}\n\ninterface PendingRender {\n latestDiff: FileDiffMetadata;\n diff: FileDiffMetadata;\n}\n\nexport const VIRTUALIZED_FILE_DIFF_LAYOUT_CHECKPOINT_INTERVAL = 3_000;\nconst NO_GHOST_TEXT_ROWS: ReadonlyMap<number, number> = new Map();\n\nlet instanceId = -1;\n\nexport class VirtualizedFileDiff<\n LAnnotation = undefined,\n Caret = undefined,\n> extends FileDiff<LAnnotation, Caret> {\n override readonly __id: string = `little-virtualized-file-diff:${++instanceId}`;\n public readonly renderType = 'virtualized';\n\n public top: number | undefined;\n public height: number = 0;\n private metrics: VirtualFileMetrics;\n private cache: DiffLayoutCache = {\n heightDeltas: new Map(),\n measuredHeightDeltaTotal: 0,\n estimatedSplitHeight: undefined,\n estimatedUnifiedHeight: undefined,\n checkpoints: [],\n totalLines: 0,\n fileAnnotationHeight: 0,\n ghostTextRows: NO_GHOST_TEXT_ROWS,\n ghostTextRowsByIndex: new Map(),\n };\n private isVisible: boolean = false;\n private isSetup: boolean = false;\n private virtualizer: Virtualizer | CodeView<LAnnotation, Caret>;\n private layoutDirty = true;\n private forceRenderOverride: true | undefined;\n private currentCollapsed: boolean | undefined;\n private pendingHydratedDiff: PendingLoadedDiff | undefined;\n private pendingExpansions: PendingExpansion[] | undefined;\n // Remember which diff the layout was calculated from, even when only a\n // placeholder is rendered. Async highlighting clears this through rerender()\n // so layout can use the newly available content. CodeView updates it during\n // its layout pass.\n private pendingRender: PendingRender | undefined;\n\n constructor(\n options: FileDiffOptions<LAnnotation, Caret> | undefined,\n virtualizer: Virtualizer | CodeView<LAnnotation, Caret>,\n metrics?: Partial<VirtualFileMetrics>,\n workerManager?: WorkerPoolManager,\n isContainerManaged = false\n ) {\n super(options, workerManager, isContainerManaged);\n this.virtualizer = virtualizer;\n this.metrics = computeVirtualFileMetrics(metrics);\n }\n\n public setMetrics(\n metrics?: Partial<VirtualFileMetrics>,\n force = false\n ): void {\n const nextMetrics = computeVirtualFileMetrics(metrics);\n if (!force && areObjectsEqual(this.metrics, nextMetrics)) {\n return;\n }\n\n this.metrics = nextMetrics;\n this.resetLayoutCache({ includeEstimatedHeights: true });\n }\n\n override setLineAnnotations(\n lineAnnotations: DiffLineAnnotation<LAnnotation>[]\n ): void {\n if (this.syncLineAnnotations(lineAnnotations)) {\n this.resetLayoutCache({ includeEstimatedHeights: false });\n }\n }\n\n private syncLineAnnotations(\n lineAnnotations: DiffLineAnnotation<LAnnotation>[] | undefined\n ): boolean {\n if (\n lineAnnotations == null ||\n !this.isNewAnnotations(lineAnnotations) ||\n (lineAnnotations.length === 0 && this.getLatestAnnotations().length === 0)\n ) {\n return false;\n }\n super.setLineAnnotations(lineAnnotations);\n return true;\n }\n\n protected override syncEditSessionAnnotationsFromEditor(\n lineAnnotations: DiffLineAnnotation<LAnnotation>[]\n ): boolean {\n if (super.syncEditSessionAnnotationsFromEditor(lineAnnotations)) {\n this.resetLayoutCache({ includeEstimatedHeights: false });\n return true;\n }\n return false;\n }\n\n private setFileAnnotationHeight(nextHeight: number): boolean {\n const previousHeight = this.cache.fileAnnotationHeight;\n if (nextHeight === previousHeight) {\n return false;\n }\n\n this.cache.fileAnnotationHeight = nextHeight;\n this.cache.measuredHeightDeltaTotal += nextHeight - previousHeight;\n return true;\n }\n\n private hasFileAnnotations(fileDiff: FileDiffMetadata): boolean {\n const lineAnnotations = this.getLatestAnnotations();\n if (!includesFileAnnotations(lineAnnotations)) {\n return false;\n }\n return lineAnnotations.some((annotation) => {\n if (annotation.lineNumber !== FILE_ANNOTATION_LINE_NUMBER) {\n return false;\n }\n // Lets ensure for singled sided diffs that the sides match\n if (fileDiff.type === 'new') {\n return annotation.side === 'additions';\n }\n if (fileDiff.type === 'deleted') {\n return annotation.side === 'deletions';\n }\n return true;\n });\n }\n\n // Get the height for a line, using cached value if available.\n // If not cached and hasMetadataLine is true, adds lineHeight for the metadata.\n private getLineHeight(lineIndex: number, hasMetadataLine = false): number {\n return (\n this.getEstimatedLineHeight(hasMetadataLine) +\n (this.cache.heightDeltas.get(lineIndex) ?? 0)\n );\n }\n\n private getEstimatedLineHeight(hasMetadataLine = false): number {\n const multiplier = hasMetadataLine ? 2 : 1;\n return this.metrics.lineHeight * multiplier;\n }\n\n override setOptions(\n options: FileDiffOptions<LAnnotation, Caret> | undefined\n ): void {\n if (this.isAdvancedMode()) {\n throw new Error(\n 'VirtualizedFileDiff.setOptions cannot be used inside CodeView. Update CodeView options instead.'\n );\n }\n\n if (options == null) return;\n const { options: previousOptions } = this;\n const optionsChanged = !areOptionsEqual(previousOptions, options);\n const layoutChanged =\n optionsChanged && hasDiffLayoutOptionChanged(previousOptions, options);\n\n super.setOptions(options);\n\n if (layoutChanged) {\n this.resetLayoutCache({\n forceSimpleRecompute: true,\n includeEstimatedHeights: hasDiffEstimateOptionChanged(\n previousOptions,\n options\n ),\n });\n }\n // Any option can affect rendered DOM; only layout-affecting options clear\n // the measured height cache above.\n if (optionsChanged) {\n this.forceRenderOverride = true;\n }\n if (optionsChanged && this.isSimpleMode()) {\n this.virtualizer.instanceChanged(this, layoutChanged);\n }\n }\n\n override setThemeType(themeType: ThemeTypes): void {\n if (this.isAdvancedMode()) {\n throw new Error(\n 'VirtualizedFileDiff.setThemeType cannot be used inside CodeView. Update CodeView options instead.'\n );\n }\n\n super.setThemeType(themeType);\n }\n\n private resetLayoutCache({\n forceSimpleRecompute = false,\n includeEstimatedHeights = false,\n resetRenderRange = true,\n }: ResetLayoutCacheOptions = {}): void {\n this.layoutDirty = true;\n this.cache.fileAnnotationHeight = 0;\n this.cache.heightDeltas.clear();\n this.cache.measuredHeightDeltaTotal = 0;\n this.cache.ghostTextRows = NO_GHOST_TEXT_ROWS;\n if (this.cache.ghostTextRowsByIndex.size > 0) {\n this.cache.ghostTextRowsByIndex.clear();\n }\n this.invalidateDerivedLayoutCache(\n includeEstimatedHeights,\n resetRenderRange\n );\n // NOTE(amadeus): In CodeView we intentionally batch computes to all happen\n // at the same time, so we shouldn't trigger this there.\n if (forceSimpleRecompute && this.isSimpleMode()) {\n this.computeApproximateSize();\n }\n }\n\n private invalidateDerivedLayoutCache(\n includeEstimatedHeights: boolean,\n resetRenderRange = true\n ): void {\n this.layoutDirty = true;\n if (this.cache.checkpoints.length > 0) {\n this.cache.checkpoints.length = 0;\n }\n if (this.cache.totalLines !== 0) {\n this.cache.totalLines = 0;\n }\n if (includeEstimatedHeights) {\n this.cache.estimatedSplitHeight = undefined;\n this.cache.estimatedUnifiedHeight = undefined;\n }\n if (this.renderRange != null && resetRenderRange) {\n this.renderRange = undefined;\n }\n }\n\n // Fold the ghost text rows the editor is showing below lines into the height\n // deltas. Ghost text sits in a margin below the row, which measuring never\n // includes, so the rows are added here on top of the row's own height, and\n // removed again when the ghost text changes or goes away, even for rows that\n // are not rendered right now. The editor keys by new-file line; the deltas\n // are keyed by this view's row index, so lines are translated the same way\n // getLinePosition does. The editor only reports lines that have a rendered\n // row (it draws a prediction all or nothing); the translation is undefined\n // only for a diff without hunks.\n private applyGhostTextRows(\n fileDiff: FileDiffMetadata,\n ghostTextRows: ReadonlyMap<number, number>\n ): boolean {\n const {\n cache: {\n heightDeltas,\n ghostTextRows: folded,\n ghostTextRowsByIndex: previous,\n },\n metrics: { lineHeight },\n } = this;\n if (folded === ghostTextRows) {\n return false;\n }\n const diffStyle = this.getDiffStyle();\n const next = new Map<number, number>();\n for (const [line, rows] of ghostTextRows) {\n const indexes = this.getLineIndexForDiff(fileDiff, line + 1, 'additions');\n if (indexes == null) {\n continue;\n }\n next.set(diffStyle === 'split' ? indexes[1] : indexes[0], rows);\n }\n let changed = false;\n for (const rowIndex of new Set([...previous.keys(), ...next.keys()])) {\n const delta =\n ((next.get(rowIndex) ?? 0) - (previous.get(rowIndex) ?? 0)) *\n lineHeight;\n if (delta === 0) {\n continue;\n }\n const nextDelta = (heightDeltas.get(rowIndex) ?? 0) + delta;\n if (nextDelta === 0) {\n heightDeltas.delete(rowIndex);\n } else {\n heightDeltas.set(rowIndex, nextDelta);\n }\n this.cache.measuredHeightDeltaTotal += delta;\n changed = true;\n }\n this.cache.ghostTextRows = ghostTextRows;\n this.cache.ghostTextRowsByIndex = next;\n return changed;\n }\n\n // Measure rendered lines and update height cache.\n // Called after render to reconcile estimated vs actual heights.\n // Definitely need to optimize this in cases where there aren't any custom\n // line heights or in cases of extremely large files...\n public reconcileHeights(): boolean {\n let hasHeightChange = false;\n const {\n options: { overflow = 'scroll' },\n cache: { ghostTextRowsByIndex },\n metrics: { lineHeight },\n } = this;\n // A placeholder may have a prepared layout before any content has\n // rendered.\n const fileDiff =\n this.placeHolder != null ? this.getLayoutDiff() : this.getRenderedDiff();\n if (this.fileContainer == null || fileDiff == null) {\n if (this.height !== 0) {\n hasHeightChange = true;\n }\n this.height = 0;\n return hasHeightChange;\n }\n this.top = this.getVirtualizedTop();\n hasHeightChange = this.applyGhostTextRows(\n fileDiff,\n this.editor?.__getGhostTextRows() ?? NO_GHOST_TEXT_ROWS\n );\n const lineAnnotations = this.getLatestAnnotations();\n // Ghost-row changes affect placeholders too, but placeholders have no DOM\n // rows to measure. Unwrapped rows without annotations also need no measurement.\n if (\n this.placeHolder != null ||\n (overflow === 'scroll' &&\n lineAnnotations.length === 0 &&\n !this.isResizeDebuggingEnabled())\n ) {\n if (hasHeightChange) {\n this.computeApproximateSize(true);\n this.setPlaceholderHeight(this.height);\n }\n return hasHeightChange;\n }\n const diffStyle = this.getDiffStyle();\n const codeGroups =\n diffStyle === 'split'\n ? [this.codeDeletions, this.codeAdditions]\n : [this.codeUnified];\n\n const hasFileAnnotations = this.hasFileAnnotations(fileDiff);\n if (\n this.renderRange != null &&\n hasFileAnnotations &&\n shouldRenderFileAnnotations(this.renderRange)\n ) {\n const fileAnnotationHeight = measureFileAnnotationHeight(codeGroups);\n const nextFileAnnotationHeight = fileAnnotationHeight ?? 0;\n if (this.setFileAnnotationHeight(nextFileAnnotationHeight)) {\n hasHeightChange = true;\n }\n } else if (!hasFileAnnotations && this.setFileAnnotationHeight(0)) {\n hasHeightChange = true;\n }\n\n for (const codeGroup of codeGroups) {\n if (codeGroup == null) continue;\n const content = codeGroup.children[1];\n if (!(content instanceof HTMLElement)) continue;\n // The ghost prediction margin sits on the additions row. When the two\n // split columns share one grid, the deletions row stretches to that\n // taller track, so measuring it would count the rows twice; the\n // additions row is authoritative for a row pair with ghost text.\n const skipsGhostRows =\n diffStyle === 'split' && codeGroup === this.codeDeletions;\n for (const line of content.children) {\n if (!(line instanceof HTMLElement)) continue;\n\n const lineIndexAttr = line.dataset.lineIndex;\n if (lineIndexAttr == null) continue;\n\n const lineIndex = parseLineIndex(lineIndexAttr, diffStyle);\n const ghostRows = ghostTextRowsByIndex.get(lineIndex) ?? 0;\n if (skipsGhostRows && ghostRows > 0) continue;\n let measuredHeight =\n line.getBoundingClientRect().height + ghostRows * lineHeight;\n let hasMetadata = false;\n // Annotations or noNewline metadata increase the size of the their\n // attached line\n if (\n line.nextElementSibling instanceof HTMLElement &&\n ('lineAnnotation' in line.nextElementSibling.dataset ||\n 'noNewline' in line.nextElementSibling.dataset)\n ) {\n if ('noNewline' in line.nextElementSibling.dataset) {\n hasMetadata = true;\n }\n measuredHeight +=\n line.nextElementSibling.getBoundingClientRect().height;\n }\n const estimatedHeight = this.getEstimatedLineHeight(hasMetadata);\n const previousDelta = this.cache.heightDeltas.get(lineIndex) ?? 0;\n const nextDelta = measuredHeight - estimatedHeight;\n\n if (nextDelta === previousDelta) {\n continue;\n }\n\n hasHeightChange = true;\n this.cache.measuredHeightDeltaTotal += nextDelta - previousDelta;\n if (nextDelta === 0) {\n this.cache.heightDeltas.delete(lineIndex);\n } else {\n this.cache.heightDeltas.set(lineIndex, nextDelta);\n }\n }\n }\n\n if (hasHeightChange || this.isResizeDebuggingEnabled()) {\n this.computeApproximateSize(true);\n }\n return hasHeightChange;\n }\n\n public onRender = (dirty: boolean): boolean => {\n if (this.fileContainer == null) {\n return false;\n }\n if (dirty) {\n this.top = this.getVirtualizedTop();\n }\n return this.render();\n };\n\n // Virtualized renders bypass FileDiff's queued render handler. Apply line\n // state deferred during the refresh once managers target the rebuilt rows.\n public override flushManagers(): void {\n super.flushManagers();\n if (this.lineStateRefreshPending) {\n this.flushDeferredLineState();\n }\n }\n\n // CodeView positions every item before updating the DOM. Recalculate this\n // item's layout whenever its content or position changes.\n public updateCodeViewLayout(\n fileDiff: FileDiffMetadata,\n top: number,\n reset?: PendingCodeViewLayoutReset,\n lineAnnotations?: DiffLineAnnotation<LAnnotation>[]\n ): number {\n let resetLayoutCache = false;\n let resetEstimatedHeights = false;\n const {\n pendingExpansions,\n pendingHydratedDiff,\n options: { collapsed = false },\n } = this;\n\n // Hydrate the `isPartial: true` diff if we have a pending hydration\n if (pendingHydratedDiff != null) {\n this.pendingHydratedDiff = undefined;\n if (pendingHydratedDiff.expectedDiff === fileDiff) {\n // We intentionally keep diff equality referential,\n // and treat it as a mutation\n Object.assign(fileDiff, pendingHydratedDiff.nextDiff);\n this.setHydratedState(pendingHydratedDiff.files);\n this.startHydratedEditSession(fileDiff);\n this.forceRenderOverride = true;\n resetLayoutCache = true;\n resetEstimatedHeights = true;\n }\n }\n\n // Go ahead and apply any queued expansion changes\n if (pendingExpansions != null) {\n this.pendingExpansions = undefined;\n for (const {\n hunkIndex,\n direction,\n expansionLineCountOverride,\n } of pendingExpansions) {\n this.hunksRenderer.expandHunk(\n hunkIndex,\n direction,\n expansionLineCountOverride\n );\n this.forceRenderOverride = true;\n resetEstimatedHeights = true;\n }\n }\n\n const diffChanged = this.updateExternalDiff(fileDiff, lineAnnotations);\n const {\n pendingRenderDiff,\n layoutDiffChanged,\n renderedDiffChanged,\n annotationsChanged,\n } = this.updatePendingRender(fileDiff, lineAnnotations);\n if (\n !this.forceRenderOverride &&\n (diffChanged || renderedDiffChanged || annotationsChanged)\n ) {\n this.forceRenderOverride = true;\n }\n\n if (\n reset?.resetDiffLayoutCache === true ||\n layoutDiffChanged ||\n annotationsChanged\n ) {\n resetLayoutCache = true;\n }\n if (\n layoutDiffChanged ||\n (reset?.resetDiffLayoutCache === true &&\n reset.includeEstimatedDiffHeights)\n ) {\n resetEstimatedHeights = true;\n }\n if (reset?.metrics != null) {\n this.metrics = computeVirtualFileMetrics(reset.metrics);\n resetLayoutCache = true;\n resetEstimatedHeights = true;\n }\n if (this.currentCollapsed !== collapsed) {\n this.currentCollapsed = collapsed;\n resetLayoutCache = true;\n }\n if (resetLayoutCache) {\n this.resetLayoutCache({ includeEstimatedHeights: resetEstimatedHeights });\n } else if (resetEstimatedHeights) {\n this.invalidateDerivedLayoutCache(true);\n }\n\n this.top = top;\n this.computeApproximateSize(false, pendingRenderDiff);\n return this.height;\n }\n\n public getLinePosition(\n lineNumber: number,\n side: SelectionSide = 'additions'\n ): { top: number; height: number } | undefined {\n const fileDiff = this.getLayoutDiff();\n if (fileDiff == null || lineNumber < 1) {\n return undefined;\n }\n\n const targetLineIndexes = this.getLineIndexForDiff(\n fileDiff,\n lineNumber,\n side\n );\n if (targetLineIndexes == null) {\n return undefined;\n }\n\n const {\n disableFileHeader = false,\n expandUnchanged = false,\n collapsed = false,\n collapsedContextThreshold = DEFAULT_COLLAPSED_CONTEXT_THRESHOLD,\n } = this.options;\n const diffStyle = this.getDiffStyle();\n const hunkSeparators = this.getHunkSeparatorType();\n const targetLineIndex =\n diffStyle === 'split' ? targetLineIndexes[1] : targetLineIndexes[0];\n this.approximateLayoutCheckpoints(fileDiff);\n const headerRegion = getVirtualFileHeaderRegion(\n this.metrics,\n disableFileHeader\n );\n const checkpoint = this.getLayoutCheckpointBeforeLineIndex(targetLineIndex);\n let top = checkpoint?.top ?? headerRegion + this.cache.fileAnnotationHeight;\n\n if (collapsed) {\n return { top: headerRegion, height: 0 };\n }\n\n let position: { top: number; height: number } | undefined;\n iterateOverDiff({\n diff: fileDiff,\n diffStyle,\n startingLine: checkpoint?.renderedLineIndex ?? 0,\n expandedHunks: expandUnchanged\n ? true\n : this.hunksRenderer.getExpandedHunksMap(),\n collapsedContextThreshold,\n callback: ({\n hunkIndex,\n hunk,\n collapsedBefore,\n collapsedAfter,\n deletionLine,\n additionLine,\n }) => {\n const lineIndex =\n diffStyle === 'split'\n ? (additionLine?.splitLineIndex ?? deletionLine?.splitLineIndex)\n : (additionLine?.unifiedLineIndex ??\n deletionLine?.unifiedLineIndex);\n if (lineIndex == null) {\n throw new Error(\n 'VirtualizedFileDiff.getLinePosition: missing line index data'\n );\n }\n\n if (collapsedBefore > 0) {\n const separator = getLeadingHunkSeparatorLayout({\n type: hunkSeparators,\n metrics: this.metrics,\n hunkIndex,\n hunkSpecs: hunk?.hunkSpecs,\n });\n if (separator != null) {\n top += separator.gapBefore;\n if (\n targetLineIndex >= lineIndex - collapsedBefore &&\n targetLineIndex < lineIndex\n ) {\n position = {\n top,\n height: separator.height,\n };\n return true;\n }\n top += separator.height + separator.gapAfter;\n }\n }\n\n const lineHeight = this.getLineHeight(\n lineIndex,\n (additionLine?.noEOFCR ?? false) || (deletionLine?.noEOFCR ?? false)\n );\n if (lineIndex === targetLineIndex) {\n position = {\n top,\n height: lineHeight,\n };\n return true;\n }\n top += lineHeight;\n\n if (collapsedAfter > 0) {\n const separator = getTrailingHunkSeparatorLayout({\n type: hunkSeparators,\n metrics: this.metrics,\n });\n if (separator != null) {\n if (\n targetLineIndex > lineIndex &&\n targetLineIndex <= lineIndex + collapsedAfter\n ) {\n position = {\n top: top + separator.gapBefore,\n height: separator.height,\n };\n return true;\n }\n top += separator.totalHeight;\n }\n }\n\n return false;\n },\n });\n\n return position;\n }\n\n public getEditorViewport(): HTMLElement | Document | undefined {\n return this.virtualizer.type === 'simple'\n ? this.virtualizer.getRoot()\n : this.virtualizer.getContainerElement();\n }\n\n public getNumericScrollAnchor(\n localViewportTop: number\n ): NumericScrollLineAnchor | undefined {\n const fileDiff = this.getLayoutDiff();\n if (fileDiff == null) {\n return undefined;\n }\n\n const {\n disableFileHeader = false,\n expandUnchanged = false,\n collapsed = false,\n collapsedContextThreshold = DEFAULT_COLLAPSED_CONTEXT_THRESHOLD,\n } = this.options;\n if (collapsed) {\n return undefined;\n }\n\n const diffStyle = this.getDiffStyle();\n const hunkSeparators = this.getHunkSeparatorType();\n\n this.approximateLayoutCheckpoints(fileDiff);\n const checkpoint = this.getLayoutCheckpointBeforeTop(localViewportTop);\n let top =\n checkpoint?.top ??\n getVirtualFileHeaderRegion(this.metrics, disableFileHeader) +\n this.cache.fileAnnotationHeight;\n let anchor: NumericScrollLineAnchor | undefined;\n\n // This may end up being quite expensive on extremely large files, we may\n // need to figure out how to anchor on different regions, or utilize\n // renderRange to shortcut this for us somehow\n iterateOverDiff({\n diff: fileDiff,\n diffStyle,\n startingLine: checkpoint?.renderedLineIndex ?? 0,\n expandedHunks: expandUnchanged\n ? true\n : this.hunksRenderer.getExpandedHunksMap(),\n collapsedContextThreshold,\n callback: ({\n hunkIndex,\n hunk,\n collapsedBefore,\n collapsedAfter,\n deletionLine,\n additionLine,\n }) => {\n const lineIndex =\n diffStyle === 'split'\n ? (additionLine?.splitLineIndex ?? deletionLine?.splitLineIndex)\n : (additionLine?.unifiedLineIndex ??\n deletionLine?.unifiedLineIndex);\n if (lineIndex == null) {\n throw new Error(\n 'VirtualizedFileDiff.getNumericScrollAnchor: missing line index data'\n );\n }\n\n if (collapsedBefore > 0) {\n const separator = getLeadingHunkSeparatorLayout({\n type: hunkSeparators,\n metrics: this.metrics,\n hunkIndex,\n hunkSpecs: hunk?.hunkSpecs,\n });\n if (separator != null) {\n top += separator.totalHeight;\n }\n }\n\n if (top >= localViewportTop) {\n if (deletionLine != null) {\n anchor = {\n lineNumber: deletionLine.lineNumber,\n side: 'deletions',\n top,\n };\n } else if (additionLine != null) {\n anchor = {\n lineNumber: additionLine.lineNumber,\n side: 'additions',\n top,\n };\n }\n if (anchor != null) {\n return true;\n }\n }\n\n const lineHeight = this.getLineHeight(\n lineIndex,\n (additionLine?.noEOFCR ?? false) || (deletionLine?.noEOFCR ?? false)\n );\n top += lineHeight;\n\n if (collapsedAfter > 0) {\n const separator = getTrailingHunkSeparatorLayout({\n type: hunkSeparators,\n metrics: this.metrics,\n });\n if (separator != null) {\n top += separator.totalHeight;\n }\n }\n\n return false;\n },\n });\n\n return anchor;\n }\n\n public getVirtualizedHeight(): number {\n return this.height;\n }\n\n public getAdvancedStickySpecs(\n windowSpecs?: RenderWindow\n ): StickySpecs | undefined {\n const fileDiff = this.getLayoutDiff();\n if (this.top == null || fileDiff == null) {\n return undefined;\n }\n if (this.options.collapsed === true) {\n return { topOffset: this.top, height: this.height };\n }\n const renderRange =\n windowSpecs != null\n ? this.computeRenderRangeFromWindow(fileDiff, this.top, windowSpecs)\n : this.renderRange;\n if (renderRange == null) {\n return undefined;\n }\n const { bufferBefore, bufferAfter, totalLines } = renderRange;\n // Rendered items flow contiguously in the sticky container with no buffer\n // spacers, so a header-only item (totalLines === 0, none of its rows fall\n // inside the window) must report where its header actually sits in that\n // flow, which depends on which side of the window its content is on:\n // - content ABOVE the window (item starts above window.top): the header\n // sits at the item's bottom so the following item connects, so offset by\n // bufferAfter.\n // - content BELOW the window (item starts at/after window.top, e.g. a\n // trailing header peeking in at the bottom): the header renders at the\n // item's top with nothing after it, so no offset. Always adding\n // bufferAfter here made getStickyBounds over-measure the sticky\n // container for that trailing case.\n let headerOnlyOffset = 0;\n if (totalLines === 0) {\n const activeWindow = windowSpecs ?? this.virtualizer.getWindowSpecs();\n if (this.top < activeWindow.top) {\n headerOnlyOffset = bufferAfter;\n }\n }\n return {\n topOffset: this.top + bufferBefore + headerOnlyOffset,\n height: this.height - (bufferBefore + bufferAfter),\n };\n }\n\n override cleanUp(recycle = false): void {\n const hadGhostTextRows = this.cache.ghostTextRows.size > 0;\n if (hadGhostTextRows) {\n this.layoutDirty = true;\n }\n const shouldRecomputeLayout =\n recycle &&\n this.isAdvancedMode() &&\n this.fileContainer != null &&\n (hadGhostTextRows ||\n !areDiffTargetsEqual(this.getRenderedDiff(), this.getLatestDiff()));\n if (this.fileContainer != null && this.isSimpleMode()) {\n this.getSimpleVirtualizer()?.disconnect(this.fileContainer);\n }\n if (!recycle) {\n this.resetLayoutCache({ includeEstimatedHeights: true });\n this.pendingExpansions = undefined;\n this.pendingHydratedDiff = undefined;\n }\n this.pendingRender = undefined;\n this.isSetup = false;\n super.cleanUp(recycle);\n if (shouldRecomputeLayout) {\n this.virtualizer.instanceChanged(this, true);\n }\n }\n\n override expandHunk = (\n hunkIndex: number,\n direction: ExpansionDirections,\n expansionLineCountOverride?: number\n ): void => {\n if (this.fileDiff == null) {\n return;\n }\n if (this.isAdvancedMode()) {\n this.pendingExpansions ??= [];\n this.pendingExpansions.push({\n hunkIndex,\n direction,\n expansionLineCountOverride,\n });\n } else {\n this.hunksRenderer.expandHunk(\n hunkIndex,\n direction,\n expansionLineCountOverride\n );\n this.resetLayoutCache({ includeEstimatedHeights: true });\n this.computeApproximateSize();\n }\n this.loadFilesIfNecessary();\n this.forceRenderOverride = true;\n this.virtualizer.instanceChanged(this, true);\n };\n\n protected override async handleFilesLoaded(\n expectedDiff: FileDiffMetadata,\n files: LoadedPartialDiffContents\n ): Promise<void> {\n if (this.fileDiff !== expectedDiff || !expectedDiff.isPartial) {\n return;\n }\n // CodeView component requires careful control for anchor\n // fixing on re-renders, and thus we cannot apply the\n // next diff immediately. Instead we clone and stage it for\n // CodeView layout to consume at render time.\n if (this.isAdvancedMode()) {\n const nextDiff = hydratePartialDiff('clone', expectedDiff, files);\n await awaitWithTimeout(() => this.primeHighlightCache(nextDiff));\n if (!this.enabled || this.fileDiff !== expectedDiff) {\n return;\n }\n this.pendingHydratedDiff = {\n expectedDiff,\n nextDiff,\n files,\n };\n } else {\n hydratePartialDiff('merge', expectedDiff, files);\n this.setHydratedState(files);\n if (!this.startHydratedEditSession(expectedDiff)) {\n await awaitWithTimeout(() => this.primeHighlightCache(expectedDiff));\n if (!this.enabled || this.fileDiff !== expectedDiff) {\n return;\n }\n }\n this.resetLayoutCache({ includeEstimatedHeights: true });\n this.computeApproximateSize();\n }\n this.forceRenderOverride = true;\n this.virtualizer.instanceChanged(this, true);\n }\n\n protected override loadFilesIfNecessary(): void {\n if (this.pendingHydratedDiff != null) {\n if (this.pendingHydratedDiff.expectedDiff === this.fileDiff) {\n return;\n }\n this.pendingHydratedDiff = undefined;\n }\n\n super.loadFilesIfNecessary();\n }\n\n // In advanced (CodeView) mode, expansions are staged in pendingExpansions\n // until the next layout consume, so the renderer's expansion map lags a\n // just-requested reveal. Account for the staged expansions so callers (the\n // editor's caret-scroll retry) see the post-consume visibility.\n override isLineRenderable(lineNumber: number): boolean {\n if (super.isLineRenderable(lineNumber)) {\n return true;\n }\n const { pendingExpansions } = this;\n const fileDiff = this.getRenderedDiff();\n if (\n pendingExpansions == null ||\n pendingExpansions.length === 0 ||\n fileDiff == null\n ) {\n return false;\n }\n const {\n expansionLineCount = 100,\n collapsedContextThreshold = DEFAULT_COLLAPSED_CONTEXT_THRESHOLD,\n } = this.options;\n const staged = new Map(this.hunksRenderer.getExpandedHunksMap());\n for (const expansion of pendingExpansions) {\n const region = {\n ...(staged.get(expansion.hunkIndex) ?? { fromStart: 0, fromEnd: 0 }),\n };\n const count = expansion.expansionLineCountOverride ?? expansionLineCount;\n if (expansion.direction === 'up' || expansion.direction === 'both') {\n region.fromStart += count;\n }\n if (expansion.direction === 'down' || expansion.direction === 'both') {\n region.fromEnd += count;\n }\n staged.set(expansion.hunkIndex, region);\n }\n return isAdditionLineRenderable({\n fileDiff,\n lineNumber,\n expandedHunks: staged,\n collapsedContextThreshold,\n });\n }\n\n /**\n * Invalidate layout after an edit session changed the rendered row set\n * without a line-count change (a mid-session region change or the exit\n * recompute): estimated heights bake the hunk shapes in, and nothing else\n * invalidates them now that editing does not flip expandUnchanged. Public\n * so CodeView can run it when reaping a session whose instance was already\n * released.\n */\n public invalidateEditSessionLayout(): void {\n this.getSimpleVirtualizer()?.markDOMDirty();\n this.resetLayoutCache({\n forceSimpleRecompute: this.isSimpleMode(),\n includeEstimatedHeights: true,\n resetRenderRange: false,\n });\n if (!this.isSimpleMode()) {\n this.computeApproximateSize(true);\n }\n this.getSimpleVirtualizer()?.requestHeightReconcile(this);\n }\n\n // Session region changes need the same invalidation a document change\n // gets. The virtualizer is told the layout changed (rendered rows and\n // heights moved) and defers the actual render through its own queue; a\n // released instance stops at the cache invalidation and the host relayout\n // covers it.\n protected override escalateEditSessionRender(): void {\n this.invalidateEditSessionLayout();\n if (!this.enabled || this.fileDiff == null) {\n return;\n }\n this.forceRenderOverride = true;\n this.virtualizer.instanceChanged(this, true);\n }\n\n protected override shouldSelfHealEditSession(): boolean {\n // CodeView sessions retain their editor association while rendering is\n // suspended; CodeView itself runs the exit recompute when it reaps one.\n return !this.isAdvancedMode() && super.shouldSelfHealEditSession();\n }\n\n public setVisibility(visible: boolean): void {\n if (this.isAdvancedMode() || this.fileContainer == null) {\n return;\n }\n this.renderRange = undefined;\n if (visible && !this.isVisible) {\n this.top = this.getVirtualizedTop();\n this.isVisible = true;\n } else if (!visible && this.isVisible) {\n this.isVisible = false;\n this.rerender();\n }\n }\n\n override rerender(): void {\n if (\n !this.enabled ||\n (this.fileDiff == null &&\n this.additionFile == null &&\n this.deletionFile == null)\n ) {\n return;\n }\n const latestDiff = this.getLatestDiff();\n const nextRenderDiff =\n latestDiff == null\n ? undefined\n : this.hunksRenderer.getDiffForNextRender(latestDiff);\n // A completed async highlight can change which diff the next simple\n // virtualizer render will commit. CodeView refreshes this during layout.\n if (this.isSimpleMode()) {\n this.pendingRender = undefined;\n }\n this.forceRenderOverride = true;\n this.virtualizer.instanceChanged(\n this,\n !areDiffTargetsEqual(this.getRenderedDiff(), nextRenderDiff)\n );\n }\n\n // The editor changed the ghost text rows it shows below lines. Ask the\n // virtualizer for a layout pass, which folds them in (see\n // applyGhostTextRows). Layout state only changes inside that pass.\n public syncGhostTextRows(): void {\n const codeView = this.getAdvancedVirtualizer();\n if (codeView != null) {\n codeView.capturePendingLayoutAnchor();\n this.layoutDirty = true;\n codeView.instanceChanged(this, true);\n } else {\n this.getSimpleVirtualizer()?.requestHeightReconcile(this);\n }\n }\n\n // Normally triggered by the host when the document line count changes.\n override applyDocumentChange(\n textDocument: TextDocument<'file-diff', LAnnotation>,\n newLineAnnotations?: DiffLineAnnotation<LAnnotation>[],\n shouldUpdateBuffer = false\n ): void {\n const { renderRange: previousRenderRange } = this;\n // Capture the scroll anchor before the synchronous hunk rebuild and\n // measured-height wipe below; the host's next frame resolves it against\n // the new geometry so on-screen rows do not shift.\n this.getAdvancedVirtualizer()?.capturePendingLayoutAnchor();\n super.applyDocumentChange(textDocument, newLineAnnotations);\n this.getSimpleVirtualizer()?.markDOMDirty();\n this.resetLayoutCache({\n forceSimpleRecompute: this.isSimpleMode(),\n includeEstimatedHeights: true,\n resetRenderRange: false,\n });\n\n const fileDiff = this.getRenderedDiff();\n if (!this.isSimpleMode()) {\n this.computeApproximateSize(true);\n } else if (\n shouldUpdateBuffer &&\n previousRenderRange != null &&\n fileDiff != null\n ) {\n // Update the buffers caused by the line-count change to ensure the host\n // scrolls to the correct position before re-rendering.\n const windowSpecs = this.virtualizer.getWindowSpecs();\n const renderRange = this.computeRenderRangeFromWindow(\n fileDiff,\n this.top ?? 0,\n windowSpecs\n );\n if (renderRange.bufferAfter !== previousRenderRange.bufferAfter) {\n this.updateBuffers(renderRange);\n }\n }\n\n this.forceRenderOverride = true;\n this.virtualizer.instanceChanged(this, true);\n }\n\n // Compute the approximate size from the cached baseline estimate plus any\n // measured height deltas observed in rendered rows.\n // The reason we refer to this as `approximate size` is because heights my\n // dynamically change for a number of reasons so we can never be fully sure\n // if the height is 100% accurate\n private computeApproximateSize(\n force = false,\n fileDiff: FileDiffMetadata | undefined = this.getLayoutDiff()\n ): void {\n const shouldValidateSize = this.isResizeDebuggingEnabled();\n if (!force && !this.layoutDirty && !shouldValidateSize) {\n return;\n }\n\n const isFirstCompute = this.height === 0;\n this.height = 0;\n this.cache.checkpoints = [];\n this.cache.totalLines = 0;\n if (fileDiff == null) {\n this.layoutDirty = false;\n return;\n }\n this.applyGhostTextRows(\n fileDiff,\n this.editor?.__getGhostTextRows() ?? NO_GHOST_TEXT_ROWS\n );\n\n const { disableFileHeader = false, collapsed = false } = this.options;\n const headerRegion = getVirtualFileHeaderRegion(\n this.metrics,\n disableFileHeader\n );\n\n this.height += headerRegion;\n if (collapsed) {\n this.layoutDirty = false;\n return;\n }\n\n this.height =\n this.getActiveEstimatedHeight(fileDiff) +\n this.cache.measuredHeightDeltaTotal;\n\n if (shouldValidateSize && !isFirstCompute) {\n this.validateComputedHeight(fileDiff);\n }\n this.layoutDirty = false;\n }\n\n // CodeView calculates its next layout before updating the DOM. This keeps every\n // layout calculation within that frame tied to the same diff.\n private getLayoutDiff(): FileDiffMetadata | undefined {\n return this.pendingRender?.diff ?? this.getRenderedDiff();\n }\n\n private getActiveEstimatedHeight(\n fileDiff: FileDiffMetadata | undefined = this.getLayoutDiff()\n ): number {\n this.ensureEstimatedDiffHeights(fileDiff);\n const estimatedHeight =\n this.getDiffStyle() === 'split'\n ? this.cache.estimatedSplitHeight\n : this.cache.estimatedUnifiedHeight;\n if (estimatedHeight == null) {\n throw new Error(\n 'VirtualizedFileDiff.getActiveEstimatedHeight: missing estimated height'\n );\n }\n return estimatedHeight;\n }\n\n private ensureEstimatedDiffHeights(\n fileDiff: FileDiffMetadata | undefined = this.getLayoutDiff()\n ): void {\n if (fileDiff == null) {\n this.cache.estimatedSplitHeight = undefined;\n this.cache.estimatedUnifiedHeight = undefined;\n return;\n }\n if (\n this.cache.estimatedSplitHeight != null &&\n this.cache.estimatedUnifiedHeight != null\n ) {\n return;\n }\n\n const {\n disableFileHeader = false,\n expandUnchanged = false,\n collapsedContextThreshold = DEFAULT_COLLAPSED_CONTEXT_THRESHOLD,\n } = this.options;\n const { splitHeight, unifiedHeight } = computeEstimatedDiffHeights({\n fileDiff,\n metrics: this.metrics,\n disableFileHeader,\n hunkSeparators: this.getHunkSeparatorType(),\n expandUnchanged,\n expandedHunks: this.hunksRenderer.getExpandedHunksMap(),\n collapsedContextThreshold,\n canHydratePartialDiff: canHydrateCollapsedContext(\n fileDiff,\n this.options.loadDiffFiles != null\n ),\n });\n this.cache.estimatedSplitHeight = splitHeight;\n this.cache.estimatedUnifiedHeight = unifiedHeight;\n }\n\n private validateComputedHeight(\n fileDiff: FileDiffMetadata | undefined = this.getLayoutDiff()\n ): void {\n if (this.fileContainer == null || fileDiff == null) {\n return;\n }\n\n const rect = this.fileContainer.getBoundingClientRect();\n if (rect.height !== this.height) {\n console.log(\n 'VirtualizedFileDiff.computeApproximateSize: computed height doesnt match',\n {\n name: fileDiff.name,\n elementHeight: rect.height,\n computedHeight: this.height,\n }\n );\n } else {\n console.log(\n 'VirtualizedFileDiff.computeApproximateSize: computed height IS CORRECT'\n );\n }\n }\n\n override render({\n fileContainer,\n fileDiff,\n forceRender = false,\n lineAnnotations,\n ...fileInputProps\n }: FileDiffRenderProps<LAnnotation> = {}): boolean {\n const fileInput = getDiffFileInput(\n fileInputProps,\n 'VirtualizedFileDiff.render'\n );\n const hasFileInput = fileInput != null;\n const oldFile = fileInput?.oldFile;\n const newFile = fileInput?.newFile;\n const filesDidChange =\n hasFileInput &&\n (!areOptionalFilesEqual(oldFile, this.deletionFile) ||\n !areOptionalFilesEqual(newFile, this.additionFile));\n let nextFileDiff = fileDiff ?? this.fileDiff;\n if (\n fileDiff == null &&\n hasFileInput &&\n (filesDidChange || this.fileDiff == null)\n ) {\n nextFileDiff = parseDiffFromFile(\n fileInput.oldFile,\n fileInput.newFile,\n this.options.parseDiffOptions\n );\n }\n const { forceRenderOverride, isSetup } = this;\n this.forceRenderOverride = undefined;\n const targetChanged =\n nextFileDiff != null && !areDiffTargetsEqual(this.fileDiff, nextFileDiff);\n const dataChanged = targetChanged || filesDidChange;\n\n fileContainer = this.getOrCreateFileContainer(fileContainer);\n\n if (nextFileDiff == null) {\n console.error(\n 'VirtualizedFileDiff.render: attempting to virtually render when we dont have the correct data'\n );\n return false;\n }\n if (targetChanged) {\n this.updateExternalDiff(nextFileDiff, lineAnnotations);\n }\n\n const {\n pendingRenderDiff,\n layoutDiffChanged,\n renderedDiffChanged,\n annotationsChanged,\n } = (() => {\n if (\n this.pendingRender != null &&\n this.pendingRender.latestDiff ===\n (this.getLatestDiff(nextFileDiff) ?? nextFileDiff)\n ) {\n return {\n pendingRenderDiff: this.pendingRender.diff,\n layoutDiffChanged: false,\n renderedDiffChanged: false,\n annotationsChanged: this.syncLineAnnotations(lineAnnotations),\n };\n }\n return this.updatePendingRender(nextFileDiff, lineAnnotations);\n })();\n\n if (annotationsChanged || layoutDiffChanged) {\n this.resetLayoutCache({\n includeEstimatedHeights: layoutDiffChanged,\n });\n }\n\n if (!isSetup) {\n this.computeApproximateSize(false, pendingRenderDiff);\n const virtualizer = this.getSimpleVirtualizer();\n this.top ??= this.getVirtualizedTop();\n if (this.isAdvancedMode()) {\n this.isVisible = true;\n } else {\n if (virtualizer == null) {\n throw new Error(\n 'VirtualizedFileDiff.render: simple virtualizer is not available'\n );\n }\n virtualizer.connect(fileContainer, this);\n this.isVisible = virtualizer.isInstanceVisible(\n this.top ?? 0,\n this.height\n );\n }\n this.isSetup = true;\n } else {\n this.top ??= this.getVirtualizedTop();\n if (this.layoutDirty && this.isSimpleMode()) {\n this.getSimpleVirtualizer()?.markDOMDirty();\n this.computeApproximateSize(false, pendingRenderDiff);\n }\n }\n\n if (!this.isVisible && this.isSimpleMode() && (!dataChanged || !isSetup)) {\n if (fileInput != null) {\n this.deletionFile = oldFile;\n this.additionFile = newFile;\n }\n if (targetChanged) {\n this.clearReusableHeader();\n }\n return this.renderPlaceholder(this.height);\n }\n\n const windowSpecs = this.virtualizer.getWindowSpecs();\n const fileTop = this.top ?? 0;\n const renderRange = this.computeRenderRangeFromWindow(\n pendingRenderDiff,\n fileTop,\n windowSpecs\n );\n return super.render({\n fileDiff: nextFileDiff,\n fileContainer,\n renderRange,\n lineAnnotations,\n forceRender:\n (forceRenderOverride ?? forceRender) ||\n annotationsChanged ||\n renderedDiffChanged ||\n targetChanged,\n ...fileInput,\n ...fileInputProps,\n });\n }\n\n protected override finalizeRender(): void {\n if (this.getRenderedDiff() !== this.pendingRender?.diff) {\n throw new Error(\n 'VirtualizedFileDiff.render: rendered a different diff than its prepared layout'\n );\n }\n this.pendingRender = undefined;\n // Renders can be driven from outside the virtualizer (host/React render\n // calls, async highlight completions), and the virtualizer only\n // auto-reconciles renders it initiated. Queue a measured-height\n // reconciliation for every applied content render so line deltas\n // (wrapped lines, annotation heights) survive layout resets.\n if (this.isSimpleMode()) {\n this.getSimpleVirtualizer()?.requestHeightReconcile(this);\n }\n }\n\n private updatePendingRender(\n nextFileDiff: FileDiffMetadata,\n lineAnnotations: DiffLineAnnotation<LAnnotation>[] | undefined\n ) {\n const latestDiff = this.getLatestDiff(nextFileDiff) ?? nextFileDiff;\n const previousRenderedDiff = this.getRenderedDiff();\n const { pendingRender } = this;\n const previousLayoutDiff = pendingRender?.diff ?? previousRenderedDiff;\n const pendingRenderDiff =\n this.hunksRenderer.getDiffForNextRender(latestDiff);\n\n this.pendingRender = { latestDiff, diff: pendingRenderDiff };\n\n return {\n pendingRenderDiff,\n annotationsChanged: this.syncLineAnnotations(lineAnnotations),\n layoutDiffChanged: !areDiffTargetsEqual(\n previousLayoutDiff,\n pendingRenderDiff\n ),\n renderedDiffChanged: !areDiffTargetsEqual(\n previousRenderedDiff,\n pendingRenderDiff\n ),\n };\n }\n\n public syncVirtualizedTop(): void {\n this.top = this.getVirtualizedTop();\n }\n\n protected override shouldDisableVirtualizationBuffers(): boolean {\n return this.isAdvancedMode() || super.shouldDisableVirtualizationBuffers();\n }\n\n // This WebKit dom manipulation scroll fix is not applicable in virtualized\n // environments, so we avoid the performance hit even on Webkit\n protected override shouldGuardRebuildScroll(): boolean {\n return false;\n }\n\n private isSimpleMode(): boolean {\n return this.virtualizer.type === 'simple';\n }\n\n private isAdvancedMode(): boolean {\n return this.virtualizer.type === 'advanced';\n }\n\n private getVirtualizedTop(): number {\n if (this.virtualizer.type === 'advanced') {\n return this.virtualizer.getLocalTopForInstance(this);\n }\n return this.fileContainer != null\n ? this.virtualizer.getOffsetInScrollContainer(this.fileContainer)\n : 0;\n }\n\n private getSimpleVirtualizer(): Virtualizer | undefined {\n return this.virtualizer.type === 'simple' ? this.virtualizer : undefined;\n }\n\n private getAdvancedVirtualizer(): CodeView<LAnnotation, Caret> | undefined {\n return this.virtualizer.type === 'advanced' ? this.virtualizer : undefined;\n }\n\n private isResizeDebuggingEnabled(): boolean {\n return this.getSimpleVirtualizer()?.config.resizeDebugging ?? false;\n }\n\n private getDiffStyle(): 'split' | 'unified' {\n return this.options.diffStyle ?? 'split';\n }\n\n private getHunkSeparatorType(): HunkSeparators {\n return getOptionHunkSeparatorType(this.options.hunkSeparators);\n }\n\n private approximateLayoutCheckpoints(fileDiff: FileDiffMetadata): void {\n if (\n (!this.layoutDirty && this.cache.checkpoints.length > 0) ||\n fileDiff.hunks.length === 0 ||\n this.options.collapsed === true\n ) {\n return;\n }\n\n const {\n disableFileHeader = false,\n expandUnchanged = false,\n collapsedContextThreshold = DEFAULT_COLLAPSED_CONTEXT_THRESHOLD,\n } = this.options;\n const finalHunkIndex = fileDiff.hunks.length - 1;\n const canHydratePartialDiff = canHydrateCollapsedContext(\n fileDiff,\n this.options.loadDiffFiles != null\n );\n const diffStyle = this.getDiffStyle();\n const hunkSeparators = this.getHunkSeparatorType();\n const expandedHunks = expandUnchanged\n ? true\n : this.hunksRenderer.getExpandedHunksMap();\n const heightDeltaPrefix = createHeightDeltaPrefix(this.cache.heightDeltas);\n let top =\n getVirtualFileHeaderRegion(this.metrics, disableFileHeader) +\n this.cache.fileAnnotationHeight;\n let renderedLineIndex = 0;\n\n const processRows = ({\n rowCount,\n startLineIndex,\n preSeparatorHeight = 0,\n postSeparatorHeight = 0,\n metadataOffsets = [],\n }: {\n rowCount: number;\n startLineIndex: number;\n preSeparatorHeight?: number;\n postSeparatorHeight?: number;\n metadataOffsets?: number[];\n }) => {\n if (rowCount <= 0) {\n return;\n }\n\n const blockStart = renderedLineIndex;\n const blockEnd = renderedLineIndex + rowCount;\n let nextCheckpoint = getNextCheckpointIndex(blockStart);\n while (nextCheckpoint < blockEnd) {\n const offset = nextCheckpoint - blockStart;\n const checkpointTop =\n top +\n (offset > 0 ? preSeparatorHeight : 0) +\n offset * this.metrics.lineHeight +\n countMetadataOffsetsBefore(metadataOffsets, offset) *\n this.metrics.lineHeight +\n sumHeightDeltas(\n heightDeltaPrefix,\n startLineIndex,\n startLineIndex + offset\n );\n this.cache.checkpoints.push({\n renderedLineIndex: nextCheckpoint,\n lineIndex: startLineIndex + offset,\n top: checkpointTop,\n });\n nextCheckpoint += VIRTUALIZED_FILE_DIFF_LAYOUT_CHECKPOINT_INTERVAL;\n }\n\n top +=\n preSeparatorHeight +\n rowCount * this.metrics.lineHeight +\n metadataOffsets.length * this.metrics.lineHeight +\n sumHeightDeltas(\n heightDeltaPrefix,\n startLineIndex,\n startLineIndex + rowCount\n ) +\n postSeparatorHeight;\n renderedLineIndex = blockEnd;\n };\n\n for (let hunkIndex = 0; hunkIndex < fileDiff.hunks.length; hunkIndex++) {\n const hunk = fileDiff.hunks[hunkIndex];\n if (hunk == null) {\n throw new Error(\n 'VirtualizedFileDiff.approximateLayoutCheckpoints: invalid hunk index'\n );\n }\n\n const leadingRegion = getExpandedRegion({\n isPartial: fileDiff.isPartial,\n rangeSize: hunk.collapsedBefore,\n expandedHunks,\n hunkIndex,\n collapsedContextThreshold,\n });\n const leadingSeparatorHeight =\n leadingRegion.collapsedLines > 0\n ? (getLeadingHunkSeparatorLayout({\n type: hunkSeparators,\n metrics: this.metrics,\n hunkIndex,\n hunkSpecs: hunk.hunkSpecs,\n })?.totalHeight ?? 0)\n : 0;\n\n processRows({\n rowCount: leadingRegion.fromStart,\n startLineIndex:\n (diffStyle === 'split'\n ? hunk.splitLineStart\n : hunk.unifiedLineStart) - leadingRegion.rangeSize,\n });\n\n let pendingLeadingSeparatorHeight = leadingSeparatorHeight;\n processRows({\n rowCount: leadingRegion.fromEnd,\n startLineIndex:\n (diffStyle === 'split'\n ? hunk.splitLineStart\n : hunk.unifiedLineStart) - leadingRegion.fromEnd,\n preSeparatorHeight: pendingLeadingSeparatorHeight,\n });\n if (leadingRegion.fromEnd > 0) {\n pendingLeadingSeparatorHeight = 0;\n }\n\n const trailingRegion =\n hunkIndex === finalHunkIndex\n ? getTrailingExpandedRegion({\n fileDiff,\n hunkIndex,\n expandedHunks,\n collapsedContextThreshold,\n errorPrefix: 'VirtualizedFileDiff',\n })\n : undefined;\n const trailingSeparatorHeight =\n trailingRegion != null && trailingRegion.collapsedLines > 0\n ? (getTrailingHunkSeparatorLayout({\n type: hunkSeparators,\n metrics: this.metrics,\n })?.totalHeight ?? 0)\n : hunkIndex === finalHunkIndex && canHydratePartialDiff\n ? (getTrailingHunkSeparatorLayout({\n type: hunkSeparators,\n metrics: this.metrics,\n })?.totalHeight ?? 0)\n : 0;\n const trailingExpandedCount =\n trailingRegion != null\n ? trailingRegion.fromStart + trailingRegion.fromEnd\n : 0;\n\n const hunkBodyRowCount =\n diffStyle === 'split' ? hunk.splitLineCount : hunk.unifiedLineCount;\n const hunkBodyStartLineIndex =\n diffStyle === 'split' ? hunk.splitLineStart : hunk.unifiedLineStart;\n processRows({\n rowCount: hunkBodyRowCount,\n startLineIndex: hunkBodyStartLineIndex,\n preSeparatorHeight: pendingLeadingSeparatorHeight,\n postSeparatorHeight:\n trailingExpandedCount === 0 ? trailingSeparatorHeight : 0,\n metadataOffsets: getHunkMetadataOffsets({\n diffStyle,\n hunk,\n rowCount: hunkBodyRowCount,\n }),\n });\n\n if (trailingRegion != null && trailingExpandedCount > 0) {\n processRows({\n rowCount: trailingExpandedCount,\n startLineIndex: hunkBodyStartLineIndex + hunkBodyRowCount,\n postSeparatorHeight: trailingSeparatorHeight,\n });\n }\n }\n\n this.cache.totalLines = renderedLineIndex;\n }\n\n // Find the nearest sparse layout checkpoint at or before an active\n // diff-style line index. Diff checkpoints also store the dense rendered-row\n // index, so deep line-position lookups can resume iteration from that\n // rendered row and replay only the nearby layout work instead of walking\n // from the first hunk.\n private getLayoutCheckpointBeforeLineIndex(\n lineIndex: number\n ): DiffLayoutCheckpoint | undefined {\n if (lineIndex <= 0 || this.cache.checkpoints.length === 0) {\n return undefined;\n }\n\n let low = 0;\n let high = this.cache.checkpoints.length - 1;\n let result: DiffLayoutCheckpoint | undefined;\n\n while (low <= high) {\n const mid = (low + high) >> 1;\n const checkpoint = this.cache.checkpoints[mid];\n if (checkpoint == null) {\n throw new Error('VirtualizedFileDiff: invalid checkpoint index');\n }\n if (checkpoint.lineIndex <= lineIndex) {\n result = checkpoint;\n low = mid + 1;\n } else {\n high = mid - 1;\n }\n }\n\n return result;\n }\n\n // Find the nearest sparse layout checkpoint at or before a scroll offset.\n // Render-range scans start from this checkpoint so variable-height diffs\n // only replay nearby rows. When `hunkLineCount` is provided, step backward\n // to a rendered hunk boundary so buffer calculations can reuse absolute hunk\n // offsets safely.\n private getLayoutCheckpointBeforeTop(\n top: number,\n hunkLineCount?: number\n ): DiffLayoutCheckpoint | undefined {\n let low = 0;\n let high = this.cache.checkpoints.length - 1;\n let resultIndex = -1;\n\n while (low <= high) {\n const mid = (low + high) >> 1;\n const checkpoint = this.cache.checkpoints[mid];\n if (checkpoint == null) {\n throw new Error('VirtualizedFileDiff: invalid checkpoint index');\n }\n if (checkpoint.top <= top) {\n resultIndex = mid;\n low = mid + 1;\n } else {\n high = mid - 1;\n }\n }\n\n if (hunkLineCount == null) {\n return resultIndex >= 0 ? this.cache.checkpoints[resultIndex] : undefined;\n }\n\n for (let index = resultIndex; index >= 0; index--) {\n const checkpoint = this.cache.checkpoints[index];\n if (checkpoint == null) {\n throw new Error('VirtualizedFileDiff: invalid checkpoint index');\n }\n if (checkpoint.renderedLineIndex % hunkLineCount === 0) {\n return checkpoint;\n }\n }\n\n return undefined;\n }\n\n private getExpandedLineCount(\n fileDiff: FileDiffMetadata,\n diffStyle: 'split' | 'unified'\n ): number {\n let count = 0;\n if (fileDiff.isPartial) {\n for (const hunk of fileDiff.hunks) {\n count +=\n diffStyle === 'split' ? hunk.splitLineCount : hunk.unifiedLineCount;\n }\n return count;\n }\n\n const {\n expandUnchanged = false,\n collapsedContextThreshold = DEFAULT_COLLAPSED_CONTEXT_THRESHOLD,\n } = this.options;\n const expandedHunks = expandUnchanged\n ? true\n : this.hunksRenderer.getExpandedHunksMap();\n\n for (const [hunkIndex, hunk] of fileDiff.hunks.entries()) {\n const hunkCount =\n diffStyle === 'split' ? hunk.splitLineCount : hunk.unifiedLineCount;\n count += hunkCount;\n const collapsedBefore = Math.max(hunk.collapsedBefore, 0);\n const { fromStart, fromEnd, renderAll } = getExpandedRegion({\n isPartial: fileDiff.isPartial,\n rangeSize: collapsedBefore,\n expandedHunks,\n hunkIndex,\n collapsedContextThreshold,\n });\n if (collapsedBefore > 0) {\n count += renderAll ? collapsedBefore : fromStart + fromEnd;\n }\n }\n\n const trailingRegion = getTrailingExpandedRegion({\n fileDiff,\n hunkIndex: fileDiff.hunks.length - 1,\n expandedHunks,\n collapsedContextThreshold,\n errorPrefix: 'VirtualizedFileDiff',\n });\n if (trailingRegion != null) {\n count += trailingRegion.fromStart + trailingRegion.fromEnd;\n }\n\n return count;\n }\n\n // Row total used to clamp render-range scrolling. Sparse layout checkpoints can\n // still hold a smaller pre-edit count until they are rebuilt, so always take\n // the max against the live diff metadata (including additionLines.length).\n private getLayoutLineCount(\n fileDiff: FileDiffMetadata,\n diffStyle: 'split' | 'unified'\n ): number {\n const expandedLineCount = this.getExpandedLineCount(fileDiff, diffStyle);\n const metadataLineCount =\n diffStyle === 'split'\n ? fileDiff.splitLineCount\n : fileDiff.unifiedLineCount;\n return Math.max(\n expandedLineCount,\n metadataLineCount,\n fileDiff.additionLines.length,\n fileDiff.deletionLines.length,\n this.cache.totalLines\n );\n }\n\n private computeRenderRangeFromWindow(\n fileDiff: FileDiffMetadata,\n fileTop: number,\n { top, bottom }: RenderWindow\n ): RenderRange {\n const {\n disableFileHeader = false,\n expandUnchanged = false,\n collapsedContextThreshold = DEFAULT_COLLAPSED_CONTEXT_THRESHOLD,\n } = this.options;\n const { hunkLineCount, lineHeight } = this.metrics;\n const diffStyle = this.getDiffStyle();\n const hunkSeparators = this.getHunkSeparatorType();\n const canHydratePartialDiff = canHydrateCollapsedContext(\n fileDiff,\n this.options.loadDiffFiles != null\n );\n const fileHeight = this.height;\n let lineCount = this.getLayoutLineCount(fileDiff, diffStyle);\n\n const headerRegion = getVirtualFileHeaderRegion(\n this.metrics,\n disableFileHeader\n );\n const paddingBottom =\n fileDiff.hunks.length > 0 ? getVirtualFilePaddingBottom(this.metrics) : 0;\n const { fileAnnotationHeight } = this.cache;\n const codeRegionTop = headerRegion + fileAnnotationHeight;\n const codeHeight = Math.max(\n 0,\n fileHeight - headerRegion - fileAnnotationHeight - paddingBottom\n );\n const hasFileAnnotations = this.hasFileAnnotations(fileDiff);\n const fileAnnotationTop = fileTop + headerRegion;\n const measuredFileAnnotationVisible =\n fileAnnotationHeight > 0 &&\n hasFileAnnotations &&\n fileAnnotationTop < bottom &&\n fileAnnotationTop + fileAnnotationHeight > top;\n\n // File is outside render window\n if (fileTop < top - fileHeight || fileTop > bottom) {\n return {\n startingLine: 0,\n totalLines: 0,\n bufferBefore: 0,\n bufferAfter: fileHeight - headerRegion - paddingBottom,\n };\n }\n\n // Whole file is under hunkLineCount, just render it all\n if (lineCount <= hunkLineCount || fileDiff.hunks.length === 0) {\n return {\n startingLine: 0,\n totalLines: hunkLineCount,\n bufferBefore: 0,\n bufferAfter: 0,\n };\n }\n\n this.approximateLayoutCheckpoints(fileDiff);\n lineCount = this.getLayoutLineCount(fileDiff, diffStyle);\n\n const estimatedTargetLines = Math.ceil(\n Math.max(bottom - top, 0) / lineHeight\n );\n const totalLines =\n Math.ceil(estimatedTargetLines / hunkLineCount) * hunkLineCount +\n hunkLineCount;\n const totalHunks = totalLines / hunkLineCount;\n const overflowHunks = totalHunks;\n const hunkOffsets: number[] = [];\n // Halfway between top & bottom, represented as an absolute position\n const viewportCenter = (top + bottom) / 2;\n // Start the scan before the viewport so we collect hunk offsets that may be\n // needed for bufferBefore. This only chooses the scan origin; the returned\n // render range is still computed from the visible window below.\n const checkpoint = this.getLayoutCheckpointBeforeTop(\n Math.max(0, top - fileTop - totalLines * lineHeight * 2),\n hunkLineCount\n );\n\n let absoluteLineTop = fileTop + (checkpoint?.top ?? codeRegionTop);\n let currentLine = checkpoint?.renderedLineIndex ?? 0;\n let firstVisibleHunk: number | undefined;\n let centerHunk: number | undefined;\n let overflowCounter: number | undefined;\n\n iterateOverDiff({\n diff: fileDiff,\n diffStyle,\n startingLine: checkpoint?.renderedLineIndex ?? 0,\n expandedHunks: expandUnchanged\n ? true\n : this.hunksRenderer.getExpandedHunksMap(),\n collapsedContextThreshold,\n callback: ({\n hunkIndex,\n hunk,\n collapsedBefore,\n collapsedAfter,\n deletionLine,\n additionLine,\n }) => {\n const splitLineIndex =\n additionLine != null\n ? additionLine.splitLineIndex\n : deletionLine.splitLineIndex;\n const unifiedLineIndex =\n additionLine != null\n ? additionLine.unifiedLineIndex\n : deletionLine.unifiedLineIndex;\n const hasMetadata =\n (additionLine?.noEOFCR ?? false) || (deletionLine?.noEOFCR ?? false);\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 leadingSeparator =\n collapsedBefore > 0\n ? getLeadingHunkSeparatorLayout({\n type: hunkSeparators,\n metrics: this.metrics,\n hunkIndex,\n hunkSpecs: hunk?.hunkSpecs,\n })\n : undefined;\n const gapAdjustment = leadingSeparator?.totalHeight ?? 0;\n\n absoluteLineTop += gapAdjustment;\n\n const isAtHunkBoundary = currentLine % hunkLineCount === 0;\n const currentHunk = Math.floor(currentLine / hunkLineCount);\n\n // Track the boundary positional offset at a hunk\n if (isAtHunkBoundary) {\n hunkOffsets[currentHunk] =\n absoluteLineTop - (fileTop + codeRegionTop + gapAdjustment);\n\n // Check if we should bail (overflow complete)\n if (overflowCounter != null) {\n if (overflowCounter <= 0) {\n return true;\n }\n overflowCounter--;\n }\n }\n\n const lineHeight = this.getLineHeight(\n diffStyle === 'split' ? splitLineIndex : unifiedLineIndex,\n hasMetadata\n );\n\n // Track visible region\n if (absoluteLineTop > top - lineHeight && absoluteLineTop < bottom) {\n firstVisibleHunk ??= currentHunk;\n }\n\n // Track which hunk contains the viewport center\n // If viewport center is above this line and we haven't set centerHunk yet,\n // this is the first line at or past the center\n if (\n centerHunk == null &&\n absoluteLineTop + lineHeight > viewportCenter\n ) {\n centerHunk = currentHunk;\n }\n\n // Start overflow when we are out of the viewport at a hunk boundary\n if (\n overflowCounter == null &&\n absoluteLineTop >= bottom &&\n isAtHunkBoundary\n ) {\n overflowCounter = overflowHunks;\n }\n\n currentLine++;\n absoluteLineTop += lineHeight;\n\n if (collapsedAfter > 0 || (isFinalHunkRow && canHydratePartialDiff)) {\n const trailingSeparator = getTrailingHunkSeparatorLayout({\n type: hunkSeparators,\n metrics: this.metrics,\n });\n if (trailingSeparator != null) {\n if (\n absoluteLineTop < bottom &&\n absoluteLineTop + trailingSeparator.totalHeight > top\n ) {\n firstVisibleHunk ??= currentHunk;\n }\n if (\n centerHunk == null &&\n absoluteLineTop + trailingSeparator.totalHeight > viewportCenter\n ) {\n centerHunk = currentHunk;\n }\n absoluteLineTop += trailingSeparator.totalHeight;\n }\n }\n\n return false;\n },\n });\n\n // No visible lines found\n if (firstVisibleHunk == null) {\n if (measuredFileAnnotationVisible) {\n firstVisibleHunk = 0;\n centerHunk = 0;\n } else {\n return {\n startingLine: 0,\n totalLines: 0,\n bufferBefore: 0,\n bufferAfter: fileHeight - headerRegion - paddingBottom,\n };\n }\n }\n\n // Calculate balanced startingLine centered around the viewport center\n // Fall back to firstVisibleHunk if center wasn't found (e.g., center in a gap)\n centerHunk ??= firstVisibleHunk;\n const idealStartHunk = Math.round(centerHunk - totalHunks / 2);\n\n // Clamp startHunk: at the beginning, reduce totalLines; at the end, shift startHunk back\n const maxStartHunk = Math.max(\n 0,\n Math.ceil(lineCount / hunkLineCount) - totalHunks\n );\n const startHunk = Math.max(0, Math.min(idealStartHunk, maxStartHunk));\n const startingLine = startHunk * hunkLineCount;\n\n // If we wanted to start before 0, reduce totalLines by the clamped amount\n const clampedTotalLines =\n idealStartHunk < 0\n ? totalLines + idealStartHunk * hunkLineCount\n : totalLines;\n\n // Use hunkOffsets array for efficient buffer calculations\n const codeBufferBefore = hunkOffsets[startHunk] ?? 0;\n const bufferBefore =\n startingLine === 0 ? 0 : fileAnnotationHeight + codeBufferBefore;\n\n // Calculate bufferAfter using hunkOffset if available, otherwise use cumulative height\n const finalHunkIndex = startHunk + clampedTotalLines / hunkLineCount;\n const bufferAfter =\n finalHunkIndex < hunkOffsets.length\n ? codeHeight - hunkOffsets[finalHunkIndex]\n : // We stopped early, calculate from current position\n codeHeight - (absoluteLineTop - fileTop - codeRegionTop);\n\n return {\n startingLine,\n totalLines: clampedTotalLines,\n bufferBefore,\n bufferAfter: Math.max(0, bufferAfter),\n };\n }\n}\n\nfunction measureFileAnnotationHeight(\n codeGroups: (HTMLElement | undefined)[]\n): number | undefined {\n let height: number | undefined;\n for (const codeGroup of codeGroups) {\n if (codeGroup == null) continue;\n const content = codeGroup.children[1];\n if (!(content instanceof HTMLElement)) continue;\n for (const child of content.children) {\n if (!(child instanceof HTMLElement)) continue;\n if (child.dataset.lineAnnotation !== FILE_ANNOTATION_DOM_KEY) {\n continue;\n }\n height = Math.max(height ?? 0, child.getBoundingClientRect().height);\n }\n }\n return height;\n}\n\ninterface HeightDeltaPrefix {\n lineIndexes: number[];\n prefixTotals: number[];\n}\n\nfunction createHeightDeltaPrefix(\n heightDeltas: Map<number, number>\n): HeightDeltaPrefix {\n const entries = Array.from(heightDeltas).sort((a, b) => a[0] - b[0]);\n const lineIndexes: number[] = [];\n const prefixTotals = [0];\n let total = 0;\n for (const [lineIndex, delta] of entries) {\n lineIndexes.push(lineIndex);\n total += delta;\n prefixTotals.push(total);\n }\n return { lineIndexes, prefixTotals };\n}\n\nfunction sumHeightDeltas(\n { lineIndexes, prefixTotals }: HeightDeltaPrefix,\n startLineIndex: number,\n endLineIndex: number\n): number {\n if (startLineIndex >= endLineIndex || lineIndexes.length === 0) {\n return 0;\n }\n const start = lowerBound(lineIndexes, startLineIndex);\n const end = lowerBound(lineIndexes, endLineIndex);\n return (prefixTotals[end] ?? 0) - (prefixTotals[start] ?? 0);\n}\n\nfunction lowerBound(values: number[], target: number): number {\n let low = 0;\n let high = values.length;\n while (low < high) {\n const mid = (low + high) >> 1;\n const value = values[mid];\n if (value == null) {\n throw new Error('VirtualizedFileDiff: invalid prefix index');\n }\n if (value < target) {\n low = mid + 1;\n } else {\n high = mid;\n }\n }\n return low;\n}\n\nfunction getNextCheckpointIndex(renderedLineIndex: number): number {\n return (\n Math.ceil(\n renderedLineIndex / VIRTUALIZED_FILE_DIFF_LAYOUT_CHECKPOINT_INTERVAL\n ) * VIRTUALIZED_FILE_DIFF_LAYOUT_CHECKPOINT_INTERVAL\n );\n}\n\nfunction countMetadataOffsetsBefore(\n metadataOffsets: number[],\n offset: number\n): number {\n let count = 0;\n for (const metadataOffset of metadataOffsets) {\n if (metadataOffset < offset) {\n count++;\n }\n }\n return count;\n}\n\nfunction getHunkMetadataOffsets({\n diffStyle,\n hunk,\n rowCount,\n}: {\n diffStyle: 'split' | 'unified';\n hunk: Hunk;\n rowCount: number;\n}): number[] {\n if (rowCount <= 0 || (!hunk.noEOFCRAdditions && !hunk.noEOFCRDeletions)) {\n return [];\n }\n\n const lastContent = hunk.hunkContent.at(-1);\n if (lastContent == null) {\n return [];\n }\n\n if (lastContent.type === 'context') {\n return [rowCount - 1];\n }\n\n const splitCount = Math.max(lastContent.deletions, lastContent.additions);\n const unifiedCount = lastContent.deletions + lastContent.additions;\n if (diffStyle === 'split') {\n return splitCount > 0 && (hunk.noEOFCRAdditions || hunk.noEOFCRDeletions)\n ? [rowCount - 1]\n : [];\n }\n\n const offsets: number[] = [];\n const contentStartOffset = rowCount - unifiedCount;\n if (lastContent.deletions > 0 && hunk.noEOFCRDeletions) {\n offsets.push(contentStartOffset + lastContent.deletions - 1);\n }\n if (lastContent.additions > 0 && hunk.noEOFCRAdditions) {\n offsets.push(rowCount - 1);\n }\n return offsets;\n}\n\nfunction hasDiffLayoutOptionChanged<LAnnotation, Caret>(\n previousOptions: FileDiffOptions<LAnnotation, Caret>,\n nextOptions: FileDiffOptions<LAnnotation, Caret>\n): boolean {\n return (\n (previousOptions.diffStyle ?? 'split') !==\n (nextOptions.diffStyle ?? 'split') ||\n (previousOptions.overflow ?? 'scroll') !==\n (nextOptions.overflow ?? 'scroll') ||\n (previousOptions.collapsed ?? false) !== (nextOptions.collapsed ?? false) ||\n (previousOptions.disableLineNumbers ?? false) !==\n (nextOptions.disableLineNumbers ?? false) ||\n (previousOptions.disableFileHeader ?? false) !==\n (nextOptions.disableFileHeader ?? false) ||\n (previousOptions.diffIndicators ?? 'bars') !==\n (nextOptions.diffIndicators ?? 'bars') ||\n (previousOptions.hunkSeparators ?? 'line-info') !==\n (nextOptions.hunkSeparators ?? 'line-info') ||\n Boolean(previousOptions.loadDiffFiles) !==\n Boolean(nextOptions.loadDiffFiles) ||\n (previousOptions.expandUnchanged ?? false) !==\n (nextOptions.expandUnchanged ?? false) ||\n (previousOptions.collapsedContextThreshold ??\n DEFAULT_COLLAPSED_CONTEXT_THRESHOLD) !==\n (nextOptions.collapsedContextThreshold ??\n DEFAULT_COLLAPSED_CONTEXT_THRESHOLD) ||\n previousOptions.unsafeCSS !== nextOptions.unsafeCSS\n );\n}\n\nfunction hasDiffEstimateOptionChanged<LAnnotation, Caret>(\n previousOptions: FileDiffOptions<LAnnotation, Caret>,\n nextOptions: FileDiffOptions<LAnnotation, Caret>\n): boolean {\n return (\n (previousOptions.disableFileHeader ?? false) !==\n (nextOptions.disableFileHeader ?? false) ||\n (previousOptions.hunkSeparators ?? 'line-info') !==\n (nextOptions.hunkSeparators ?? 'line-info') ||\n Boolean(previousOptions.loadDiffFiles) !==\n Boolean(nextOptions.loadDiffFiles) ||\n (previousOptions.expandUnchanged ?? false) !==\n (nextOptions.expandUnchanged ?? false) ||\n (previousOptions.collapsedContextThreshold ??\n DEFAULT_COLLAPSED_CONTEXT_THRESHOLD) !==\n (nextOptions.collapsedContextThreshold ??\n DEFAULT_COLLAPSED_CONTEXT_THRESHOLD)\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\nfunction getOptionHunkSeparatorType<LAnnotation, Caret>(\n hunkSeparators:\n | FileDiffOptions<LAnnotation, Caret>['hunkSeparators']\n | undefined\n): HunkSeparators {\n return typeof hunkSeparators === 'function'\n ? 'custom'\n : (hunkSeparators ?? 'line-info');\n}\n\nfunction areOptionalFilesEqual(\n fileA: FileContents | null | undefined,\n fileB: FileContents | null | undefined\n): boolean {\n if (fileA == null || fileB == null) {\n return fileA == null && fileB == null;\n }\n return areFilesEqual(fileA, fileB);\n}\n\n// Extracts the view-specific line index from the data-line-index attribute.\n// Format is \"unifiedIndex,splitIndex\"\nfunction parseLineIndex(\n lineIndexAttr: string,\n diffStyle: 'split' | 'unified'\n): number {\n const [unifiedIndex, splitIndex] = lineIndexAttr.split(',').map(Number);\n return diffStyle === 'split' ? splitIndex : unifiedIndex;\n}\n"],"mappings":"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"}
|
|
@@ -967,17 +967,15 @@ var Editor = class {
|
|
|
967
967
|
if (typeof selectionRaw.getComposedRanges === "function") composedRange = selectionRaw.getComposedRanges({ shadowRoots: [shadowRoot] })?.[0];
|
|
968
968
|
else composedRange = getShadowRootRange(shadowRoot);
|
|
969
969
|
if (composedRange === void 0 || !this.#rangeBelongsToEditor(composedRange)) return;
|
|
970
|
-
|
|
970
|
+
const selection = convertSelection(composedRange, 0);
|
|
971
971
|
if (selection === void 0) return;
|
|
972
972
|
if (this.#isContentMouseDown && this.#shiftKeyPressed && this.#selections !== void 0 && this.#selections.length > 0) {
|
|
973
973
|
const primarySelection = this.#selections.at(-1);
|
|
974
974
|
this.#updateSelections([extendSelection(primarySelection, selection)]);
|
|
975
975
|
return;
|
|
976
976
|
}
|
|
977
|
-
if (this.#
|
|
978
|
-
|
|
979
|
-
else this.#selectionStart = selection;
|
|
980
|
-
} else if (this.#selectionStart !== void 0) selection.direction = createSelectionFrom(this.#selectionStart, selection).direction;
|
|
977
|
+
if (this.#selectionStart !== void 0) selection.direction = createSelectionFrom(this.#selectionStart, selection).direction;
|
|
978
|
+
else if (this.#isContentMouseDown) this.#selectionStart = selection;
|
|
981
979
|
else if (this.#selections !== void 0 && this.#selections.length === 1) {
|
|
982
980
|
const previous = this.#selections[0];
|
|
983
981
|
if (comparePosition(previous.start, selection.start) === 0 && comparePosition(previous.end, selection.end) === 0) selection.direction = previous.direction;
|