| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- import { type VirtualFileMetrics, Virtualizer } from "@pierre/diffs"
- type Target = {
- key: Document | HTMLElement
- root: Document | HTMLElement
- content: HTMLElement | undefined
- }
- type Entry = {
- virtualizer: Virtualizer
- refs: number
- }
- const cache = new WeakMap<Document | HTMLElement, Entry>()
- export const virtualMetrics: Partial<VirtualFileMetrics> = {
- lineHeight: 24,
- hunkSeparatorHeight: 24,
- fileGap: 0,
- }
- function scrollable(value: string) {
- return value === "auto" || value === "scroll" || value === "overlay"
- }
- function scrollRoot(container: HTMLElement) {
- let node = container.parentElement
- while (node) {
- const style = getComputedStyle(node)
- if (scrollable(style.overflowY)) return node
- node = node.parentElement
- }
- }
- function target(container: HTMLElement): Target | undefined {
- if (typeof document === "undefined") return
- const review = container.closest("[data-component='session-review']")
- if (review instanceof HTMLElement) {
- const root = scrollRoot(container) ?? review
- const content = review.querySelector("[data-slot='session-review-container']")
- return {
- key: review,
- root,
- content: content instanceof HTMLElement ? content : undefined,
- }
- }
- const root = scrollRoot(container)
- if (root) {
- const content = root.querySelector("[role='log']")
- return {
- key: root,
- root,
- content: content instanceof HTMLElement ? content : undefined,
- }
- }
- return {
- key: document,
- root: document,
- content: undefined,
- }
- }
- export function acquireVirtualizer(container: HTMLElement) {
- const resolved = target(container)
- if (!resolved) return
- let entry = cache.get(resolved.key)
- if (!entry) {
- const virtualizer = new Virtualizer()
- virtualizer.setup(resolved.root, resolved.content)
- entry = {
- virtualizer,
- refs: 0,
- }
- cache.set(resolved.key, entry)
- }
- entry.refs += 1
- let done = false
- return {
- virtualizer: entry.virtualizer,
- release() {
- if (done) return
- done = true
- const current = cache.get(resolved.key)
- if (!current) return
- current.refs -= 1
- if (current.refs > 0) return
- current.virtualizer.cleanUp()
- cache.delete(resolved.key)
- },
- }
- }
|