{"version":3,"file":"VirtualizedFile.js","names":["virtualizer: Virtualizer","metrics: VirtualFileMetrics","idealStartHunk","startingLine","clampedTotalLines","bufferBefore","hunkOffsets: number[]","firstVisibleHunk: number | undefined","centerHunk: number | undefined","overflowCounter: number | undefined","lineHeight"],"sources":["../../src/components/VirtualizedFile.ts"],"sourcesContent":["import { DEFAULT_VIRTUAL_FILE_METRICS } from '../constants';\nimport type {\n  FileContents,\n  RenderRange,\n  RenderWindow,\n  VirtualFileMetrics,\n} from '../types';\nimport { iterateOverFile } from '../utils/iterateOverFile';\nimport type { WorkerPoolManager } from '../worker';\nimport { File, type FileOptions, type FileRenderProps } from './File';\nimport type { Virtualizer } from './Virtualizer';\n\nlet instanceId = -1;\n\nexport class VirtualizedFile<\n  LAnnotation = undefined,\n> extends File<LAnnotation> {\n  override readonly __id: string = `virtualized-file:${++instanceId}`;\n\n  public top: number | undefined;\n  public height: number = 0;\n  // Sparse map: line index -> measured height\n  // Only stores lines that differ from what is returned from default line\n  // height\n  private heightCache: Map<number, number> = new Map();\n  private isVisible: boolean = false;\n  private isSetup: boolean = false;\n\n  constructor(\n    options: FileOptions<LAnnotation> | undefined,\n    private virtualizer: Virtualizer,\n    private metrics: VirtualFileMetrics = DEFAULT_VIRTUAL_FILE_METRICS,\n    workerManager?: WorkerPoolManager,\n    isContainerManaged = false\n  ) {\n    super(options, workerManager, isContainerManaged);\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\n  // metadata.\n  public getLineHeight(lineIndex: number, hasMetadataLine = false): number {\n    const cached = this.heightCache.get(lineIndex);\n    if (cached != null) {\n      return cached;\n    }\n    const multiplier = hasMetadataLine ? 2 : 1;\n    return this.metrics.lineHeight * multiplier;\n  }\n\n  // Override setOptions to clear height cache when overflow changes\n  override setOptions(options: FileOptions<LAnnotation> | undefined): void {\n    if (options == null) return;\n    const previousOverflow = this.options.overflow;\n    const previousCollapsed = this.options.collapsed;\n\n    super.setOptions(options);\n\n    if (\n      previousOverflow !== this.options.overflow ||\n      previousCollapsed !== this.options.collapsed\n    ) {\n      this.heightCache.clear();\n      this.computeApproximateSize();\n      this.renderRange = undefined;\n    }\n    this.virtualizer.instanceChanged(this);\n  }\n\n  // Measure rendered lines and update height cache.\n  // Called after render to reconcile estimated vs actual heights.\n  public reconcileHeights(): void {\n    if (this.fileContainer == null || this.file == null) {\n      this.height = 0;\n      return;\n    }\n    const { overflow = 'scroll' } = this.options;\n    this.top = this.virtualizer.getOffsetInScrollContainer(this.fileContainer);\n\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      this.lineAnnotations.length === 0 &&\n      !this.virtualizer.config.resizeDebugging\n    ) {\n      return;\n    }\n\n    let hasLineHeightChange = false;\n\n    // Single code element (no split mode)\n    if (this.code == null) return;\n    const content = this.code.children[1]; // Content column (gutter is [0])\n    if (!(content instanceof HTMLElement)) return;\n\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 = Number(lineIndexAttr);\n      let measuredHeight = line.getBoundingClientRect().height;\n      let hasMetadata = false;\n\n      // Annotations or noNewline metadata increase the size of their 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\n      const expectedHeight = this.getLineHeight(lineIndex, hasMetadata);\n\n      if (measuredHeight === expectedHeight) {\n        continue;\n      }\n\n      hasLineHeightChange = true;\n      // Line is back to standard height (e.g., after window resize)\n      // Remove from cache\n      if (measuredHeight === this.metrics.lineHeight * (hasMetadata ? 2 : 1)) {\n        this.heightCache.delete(lineIndex);\n      }\n      // Non-standard height, cache it\n      else {\n        this.heightCache.set(lineIndex, measuredHeight);\n      }\n    }\n\n    if (hasLineHeightChange || this.virtualizer.config.resizeDebugging) {\n      this.computeApproximateSize();\n    }\n  }\n\n  public onRender = (dirty: boolean): boolean => {\n    if (this.fileContainer == null || this.file == null) {\n      return false;\n    }\n    if (dirty) {\n      this.top = this.virtualizer.getOffsetInScrollContainer(\n        this.fileContainer\n      );\n    }\n    return this.render({ file: this.file });\n  };\n\n  override cleanUp(): void {\n    if (this.fileContainer != null) {\n      this.virtualizer.disconnect(this.fileContainer);\n    }\n    this.isSetup = false;\n    super.cleanUp();\n  }\n\n  // Compute the approximate size of the file using cached line heights.\n  // Uses lineHeight for lines without cached measurements.\n  private computeApproximateSize(): void {\n    const isFirstCompute = this.height === 0;\n    this.height = 0;\n    if (this.file == null) {\n      return;\n    }\n\n    const {\n      disableFileHeader = false,\n      collapsed = false,\n      overflow = 'scroll',\n    } = this.options;\n    const { diffHeaderHeight, fileGap, lineHeight } = this.metrics;\n    const lines = this.getOrCreateLineCache(this.file);\n\n    // Header or initial padding\n    if (!disableFileHeader) {\n      this.height += diffHeaderHeight;\n    } else {\n      this.height += fileGap;\n    }\n    if (collapsed) {\n      return;\n    }\n\n    if (overflow === 'scroll' && this.lineAnnotations.length === 0) {\n      this.height += this.getOrCreateLineCache(this.file).length * lineHeight;\n    } else {\n      iterateOverFile({\n        lines,\n        callback: ({ lineIndex }) => {\n          this.height += this.getLineHeight(lineIndex, false);\n        },\n      });\n    }\n\n    // Bottom padding\n    if (lines.length > 0) {\n      this.height += fileGap;\n    }\n\n    if (\n      this.fileContainer != null &&\n      this.virtualizer.config.resizeDebugging &&\n      !isFirstCompute\n    ) {\n      const rect = this.fileContainer.getBoundingClientRect();\n      if (rect.height !== this.height) {\n        console.log(\n          'VirtualizedFile.computeApproximateSize: computed height doesnt match',\n          {\n            name: this.file.name,\n            elementHeight: rect.height,\n            computedHeight: this.height,\n          }\n        );\n      } else {\n        console.log(\n          'VirtualizedFile.computeApproximateSize: computed height IS CORRECT'\n        );\n      }\n    }\n  }\n\n  public setVisibility(visible: boolean): void {\n    if (this.fileContainer == null) {\n      return;\n    }\n    if (visible && !this.isVisible) {\n      this.top = this.virtualizer.getOffsetInScrollContainer(\n        this.fileContainer\n      );\n      this.isVisible = true;\n    } else if (!visible && this.isVisible) {\n      this.isVisible = false;\n      this.rerender();\n    }\n  }\n\n  override render({\n    fileContainer,\n    file,\n    ...props\n  }: FileRenderProps<LAnnotation>): boolean {\n    const { isSetup } = this;\n\n    this.file ??= file;\n\n    fileContainer = this.getOrCreateFileContainerNode(fileContainer);\n\n    if (this.file == null) {\n      console.error(\n        'VirtualizedFile.render: attempting to virtually render when we dont have file'\n      );\n      return false;\n    }\n\n    if (!isSetup) {\n      this.computeApproximateSize();\n      this.virtualizer.connect(fileContainer, this);\n      this.top ??= this.virtualizer.getOffsetInScrollContainer(fileContainer);\n      this.isVisible = this.virtualizer.isInstanceVisible(\n        this.top,\n        this.height\n      );\n      this.isSetup = true;\n    } else {\n      this.top ??= this.virtualizer.getOffsetInScrollContainer(fileContainer);\n    }\n\n    if (!this.isVisible) {\n      return this.renderPlaceholder(this.height);\n    }\n\n    const windowSpecs = this.virtualizer.getWindowSpecs();\n    const renderRange = this.computeRenderRangeFromWindow(\n      this.file,\n      this.top,\n      windowSpecs\n    );\n    return super.render({\n      file: this.file,\n      fileContainer,\n      renderRange,\n      ...props,\n    });\n  }\n\n  private computeRenderRangeFromWindow(\n    file: FileContents,\n    fileTop: number,\n    { top, bottom }: RenderWindow\n  ): RenderRange {\n    const { disableFileHeader = false, overflow = 'scroll' } = this.options;\n    const { diffHeaderHeight, fileGap, hunkLineCount, lineHeight } =\n      this.metrics;\n    const lines = this.getOrCreateLineCache(file);\n    const lineCount = lines.length;\n    const fileHeight = this.height;\n    const headerRegion = disableFileHeader ? fileGap : diffHeaderHeight;\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 - fileGap,\n      };\n    }\n\n    // Small file, just render it all\n    if (lineCount <= hunkLineCount) {\n      return {\n        startingLine: 0,\n        totalLines: hunkLineCount,\n        bufferBefore: 0,\n        bufferAfter: 0,\n      };\n    }\n\n    // Calculate totalLines based on viewport size\n    const estimatedTargetLines = Math.ceil(\n      Math.max(bottom - top, 0) / lineHeight\n    );\n    const totalLines =\n      Math.ceil(estimatedTargetLines / hunkLineCount) * hunkLineCount +\n      hunkLineCount * 2;\n    const totalHunks = totalLines / hunkLineCount;\n    const viewportCenter = (top + bottom) / 2;\n\n    // Simple case: overflow scroll with no annotations - pure math!\n    if (overflow === 'scroll' && this.lineAnnotations.length === 0) {\n      // Find which line is at viewport center\n      const centerLine = Math.floor(\n        (viewportCenter - (fileTop + headerRegion)) / lineHeight\n      );\n      const centerHunk = Math.floor(centerLine / hunkLineCount);\n\n      // Calculate ideal start centered around viewport\n      const idealStartHunk = centerHunk - Math.floor(totalHunks / 2);\n      const totalHunksInFile = Math.ceil(lineCount / hunkLineCount);\n      const startingLine =\n        Math.max(0, Math.min(idealStartHunk, totalHunksInFile)) * hunkLineCount;\n\n      const clampedTotalLines =\n        idealStartHunk < 0\n          ? totalLines + idealStartHunk * hunkLineCount\n          : totalLines;\n\n      const bufferBefore = startingLine * lineHeight;\n      const renderedLines = Math.min(\n        clampedTotalLines,\n        lineCount - startingLine\n      );\n      const bufferAfter = Math.max(\n        0,\n        (lineCount - startingLine - renderedLines) * lineHeight\n      );\n\n      return {\n        startingLine,\n        totalLines: clampedTotalLines,\n        bufferBefore,\n        bufferAfter,\n      };\n    }\n\n    // Complex case: need to account for line annotations or wrap overflow\n    const overflowHunks = totalHunks;\n    const hunkOffsets: number[] = [];\n\n    let absoluteLineTop = fileTop + headerRegion;\n    let currentLine = 0;\n    let firstVisibleHunk: number | undefined;\n    let centerHunk: number | undefined;\n    let overflowCounter: number | undefined;\n\n    iterateOverFile({\n      lines,\n      callback: ({ lineIndex }) => {\n        const isAtHunkBoundary = currentLine % hunkLineCount === 0;\n\n        if (isAtHunkBoundary) {\n          hunkOffsets.push(absoluteLineTop - (fileTop + headerRegion));\n\n          if (overflowCounter != null) {\n            if (overflowCounter <= 0) {\n              return true;\n            }\n            overflowCounter--;\n          }\n        }\n\n        const lineHeight = this.getLineHeight(lineIndex, false);\n        const currentHunk = Math.floor(currentLine / hunkLineCount);\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 (absoluteLineTop + lineHeight > viewportCenter) {\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        return false;\n      },\n    });\n\n    // No visible lines found\n    if (firstVisibleHunk == null) {\n      return {\n        startingLine: 0,\n        totalLines: 0,\n        bufferBefore: 0,\n        bufferAfter: fileHeight - headerRegion - fileGap,\n      };\n    }\n\n    // Calculate balanced startingLine centered around the viewport center\n    const collectedHunks = hunkOffsets.length;\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(0, collectedHunks - totalHunks);\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 bufferBefore = hunkOffsets[startHunk] ?? 0;\n\n    // Calculate bufferAfter\n    const finalHunkIndex = startHunk + clampedTotalLines / hunkLineCount;\n    const bufferAfter =\n      finalHunkIndex < hunkOffsets.length\n        ? fileHeight - headerRegion - hunkOffsets[finalHunkIndex] - fileGap\n        : fileHeight - (absoluteLineTop - fileTop) - fileGap;\n\n    return {\n      startingLine,\n      totalLines: clampedTotalLines,\n      bufferBefore,\n      bufferAfter,\n    };\n  }\n}\n"],"mappings":"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"}