@pierre/diffs 1.3.0-beta.7 → 1.3.0-beta.9

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.
Files changed (129) hide show
  1. package/dist/components/CodeView.d.ts +86 -4
  2. package/dist/components/CodeView.d.ts.map +1 -1
  3. package/dist/components/CodeView.js +248 -33
  4. package/dist/components/CodeView.js.map +1 -1
  5. package/dist/components/File.d.ts +1 -0
  6. package/dist/components/File.d.ts.map +1 -1
  7. package/dist/components/File.js +15 -4
  8. package/dist/components/File.js.map +1 -1
  9. package/dist/components/FileDiff.d.ts +2 -0
  10. package/dist/components/FileDiff.d.ts.map +1 -1
  11. package/dist/components/FileDiff.js +21 -6
  12. package/dist/components/FileDiff.js.map +1 -1
  13. package/dist/components/FileStream.d.ts.map +1 -1
  14. package/dist/components/FileStream.js +2 -1
  15. package/dist/components/FileStream.js.map +1 -1
  16. package/dist/components/VirtualizedFile.d.ts.map +1 -1
  17. package/dist/components/VirtualizedFile.js +3 -1
  18. package/dist/components/VirtualizedFile.js.map +1 -1
  19. package/dist/components/VirtualizedFileDiff.d.ts +3 -1
  20. package/dist/components/VirtualizedFileDiff.d.ts.map +1 -1
  21. package/dist/components/VirtualizedFileDiff.js +14 -6
  22. package/dist/components/VirtualizedFileDiff.js.map +1 -1
  23. package/dist/components/Virtualizer.d.ts +2 -0
  24. package/dist/components/Virtualizer.d.ts.map +1 -1
  25. package/dist/components/Virtualizer.js +18 -4
  26. package/dist/components/Virtualizer.js.map +1 -1
  27. package/dist/constants.d.ts +3 -1
  28. package/dist/constants.d.ts.map +1 -1
  29. package/dist/constants.js +3 -1
  30. package/dist/constants.js.map +1 -1
  31. package/dist/editor/command.d.ts +1 -1
  32. package/dist/editor/command.d.ts.map +1 -1
  33. package/dist/editor/command.js +8 -0
  34. package/dist/editor/command.js.map +1 -1
  35. package/dist/editor/editStack.d.ts.map +1 -1
  36. package/dist/editor/editStack.js +1 -1
  37. package/dist/editor/editStack.js.map +1 -1
  38. package/dist/editor/editor.d.ts +8 -1
  39. package/dist/editor/editor.d.ts.map +1 -1
  40. package/dist/editor/editor.js +188 -42
  41. package/dist/editor/editor.js.map +1 -1
  42. package/dist/editor/editor2.js +1 -1
  43. package/dist/editor/lineAnnotations.d.ts.map +1 -1
  44. package/dist/editor/lineAnnotations.js +84 -12
  45. package/dist/editor/lineAnnotations.js.map +1 -1
  46. package/dist/editor/marker.d.ts +5 -3
  47. package/dist/editor/marker.d.ts.map +1 -1
  48. package/dist/editor/marker.js +35 -12
  49. package/dist/editor/marker.js.map +1 -1
  50. package/dist/editor/matchBrackets.d.ts +8 -0
  51. package/dist/editor/matchBrackets.d.ts.map +1 -0
  52. package/dist/editor/matchBrackets.js +146 -0
  53. package/dist/editor/matchBrackets.js.map +1 -0
  54. package/dist/editor/popover.d.ts +45 -0
  55. package/dist/editor/popover.d.ts.map +1 -0
  56. package/dist/editor/popover.js +145 -0
  57. package/dist/editor/popover.js.map +1 -0
  58. package/dist/editor/searchPanel.d.ts +1 -0
  59. package/dist/editor/searchPanel.d.ts.map +1 -1
  60. package/dist/editor/searchPanel.js +6 -6
  61. package/dist/editor/searchPanel.js.map +1 -1
  62. package/dist/editor/selection.d.ts +13 -1
  63. package/dist/editor/selection.d.ts.map +1 -1
  64. package/dist/editor/selection.js +55 -4
  65. package/dist/editor/selection.js.map +1 -1
  66. package/dist/editor/selectionAction.d.ts +20 -3
  67. package/dist/editor/selectionAction.d.ts.map +1 -1
  68. package/dist/editor/selectionAction.js +41 -10
  69. package/dist/editor/selectionAction.js.map +1 -1
  70. package/dist/editor/textDocument.d.ts +2 -0
  71. package/dist/editor/textDocument.d.ts.map +1 -1
  72. package/dist/editor/textDocument.js +22 -6
  73. package/dist/editor/textDocument.js.map +1 -1
  74. package/dist/editor/tokenzier.d.ts +4 -7
  75. package/dist/editor/tokenzier.d.ts.map +1 -1
  76. package/dist/editor/tokenzier.js +76 -35
  77. package/dist/editor/tokenzier.js.map +1 -1
  78. package/dist/index.d.ts +7 -7
  79. package/dist/index.js +5 -5
  80. package/dist/managers/ResizeManager.d.ts +10 -2
  81. package/dist/managers/ResizeManager.d.ts.map +1 -1
  82. package/dist/managers/ResizeManager.js +33 -13
  83. package/dist/managers/ResizeManager.js.map +1 -1
  84. package/dist/managers/UniversalRenderingManager.d.ts +2 -1
  85. package/dist/managers/UniversalRenderingManager.d.ts.map +1 -1
  86. package/dist/managers/UniversalRenderingManager.js +6 -1
  87. package/dist/managers/UniversalRenderingManager.js.map +1 -1
  88. package/dist/react/CodeView.d.ts +25 -1
  89. package/dist/react/CodeView.d.ts.map +1 -1
  90. package/dist/react/CodeView.js +76 -17
  91. package/dist/react/CodeView.js.map +1 -1
  92. package/dist/react/EditorContext.d.ts +2 -2
  93. package/dist/react/EditorContext.d.ts.map +1 -1
  94. package/dist/react/EditorContext.js.map +1 -1
  95. package/dist/react/index.d.ts +2 -2
  96. package/dist/renderers/DiffHunksRenderer.d.ts +1 -1
  97. package/dist/renderers/DiffHunksRenderer.d.ts.map +1 -1
  98. package/dist/renderers/DiffHunksRenderer.js +24 -15
  99. package/dist/renderers/DiffHunksRenderer.js.map +1 -1
  100. package/dist/renderers/FileRenderer.d.ts +2 -1
  101. package/dist/renderers/FileRenderer.d.ts.map +1 -1
  102. package/dist/renderers/FileRenderer.js +58 -38
  103. package/dist/renderers/FileRenderer.js.map +1 -1
  104. package/dist/ssr/index.d.ts +2 -2
  105. package/dist/types.d.ts +42 -2
  106. package/dist/types.d.ts.map +1 -1
  107. package/dist/utils/applyLineTextWithNewline.d.ts +5 -0
  108. package/dist/utils/applyLineTextWithNewline.d.ts.map +1 -0
  109. package/dist/utils/applyLineTextWithNewline.js +11 -0
  110. package/dist/utils/applyLineTextWithNewline.js.map +1 -0
  111. package/dist/utils/areManagedSnapshotsEqual.d.ts +2 -2
  112. package/dist/utils/areManagedSnapshotsEqual.d.ts.map +1 -1
  113. package/dist/utils/areManagedSnapshotsEqual.js +5 -0
  114. package/dist/utils/areManagedSnapshotsEqual.js.map +1 -1
  115. package/dist/utils/createCodeViewHeaderFooterHostElement.d.ts +5 -0
  116. package/dist/utils/createCodeViewHeaderFooterHostElement.d.ts.map +1 -0
  117. package/dist/utils/createCodeViewHeaderFooterHostElement.js +19 -0
  118. package/dist/utils/createCodeViewHeaderFooterHostElement.js.map +1 -0
  119. package/dist/utils/updateDiffHunks.d.ts.map +1 -1
  120. package/dist/utils/updateDiffHunks.js +23 -1
  121. package/dist/utils/updateDiffHunks.js.map +1 -1
  122. package/dist/worker/WorkerPoolManager.d.ts.map +1 -1
  123. package/dist/worker/WorkerPoolManager.js +4 -2
  124. package/dist/worker/WorkerPoolManager.js.map +1 -1
  125. package/dist/worker/types.d.ts +4 -0
  126. package/dist/worker/types.d.ts.map +1 -1
  127. package/dist/worker/worker-portable.js.map +1 -1
  128. package/dist/worker/worker.js.map +1 -1
  129. package/package.json +4 -2
@@ -1 +1 @@
1
- {"version":3,"file":"tokenzier.js","names":["#textDocument","#grammar","#highlighter","#buildStateStack","#backgroundJobId","#backgroundTokenize","#themeType","#mediaQueryList","#emitThemeChange","#disposes","#tokenizeMaxLineLength","#setStyle","#onDeferTokenize","#onThemeChange","#debug","#ensureGrammar","#colorMap","#setTheme","#stateStack","#scheduleBackgroundTokenize","#themeName","#detachMessageListener","#tokenizeLineAt","#prebuildStateStack","#isStopped","#isPaused","#lastLine","#backgroundChangedLineRanges","#backgroundChangedRangeIndex","#postTokenizeMessage","#isMessageListenerAttached","#onMessage","#attachMessageListener"],"sources":["../../src/editor/tokenzier.ts"],"sourcesContent":["import {\n EncodedTokenMetadata,\n type IGrammar,\n INITIAL,\n type StateStack,\n} from 'shiki/textmate';\n\nimport { DEFAULT_THEMES } from '../constants';\nimport type {\n BaseCodeOptions,\n DiffsHighlighter,\n HighlightedToken,\n RenderRange,\n} from '../types';\nimport type { TextDocument, TextDocumentChange } from './textDocument';\nimport { addEventListener, debounce, h } from './utils';\n\nexport interface EditorTokenizerProps {\n highlighter: DiffsHighlighter;\n textDocument: TextDocument<unknown>;\n codeOptions: BaseCodeOptions;\n setStyle: (style: string) => void;\n onDeferTokenize: (\n lines: Map<number, Array<HighlightedToken>>,\n themeType: 'dark' | 'light'\n ) => void;\n // Fired after the active theme (light/dark mode or theme name) changes and the\n // new theme CSS has been applied. Lets the editor recompute overlay pieces\n // that captured a resolved theme color, e.g. rounded selection corner masks.\n onThemeChange?: () => void;\n __debug?: boolean;\n}\n\n/** Stoppable code tokenizer for the editor */\nexport class EditorTokenizer {\n static TOKENIZE_TIME_LIMIT = 500;\n\n #highlighter: DiffsHighlighter;\n #grammar: IGrammar | undefined;\n #mediaQueryList: MediaQueryList;\n #themeType: 'light' | 'dark';\n // The resolved name of the theme currently applied to the editor (e.g.\n // `github-light`). Tracked so `syncTheme` can detect a host-driven theme swap\n // even when the light/dark mode itself is unchanged.\n #themeName = '';\n #colorMap: string[];\n #textDocument: TextDocument<unknown>;\n #tokenizeMaxLineLength: number;\n #setStyle: EditorTokenizerProps['setStyle'];\n #onDeferTokenize: EditorTokenizerProps['onDeferTokenize'];\n #onThemeChange: EditorTokenizerProps['onThemeChange'];\n #debug: boolean;\n #disposes?: (() => void)[];\n\n // state\n #stateStack: StateStack[] = [INITIAL]; // cached state stack by line index\n #lastLine: number = -1;\n #isStopped: boolean = true;\n #isPaused: boolean = false;\n #backgroundJobId: number = 0;\n #backgroundChangedLineRanges: readonly [number, number][] | undefined;\n #backgroundChangedRangeIndex: number = 0;\n #isMessageListenerAttached: boolean = false;\n\n #prebuildStateStack = debounce(async (renderRange?: RenderRange) => {\n const { startingLine = 0, totalLines = Infinity } = renderRange ?? {};\n const endLine = Math.min(\n totalLines === Infinity ? Infinity : startingLine + totalLines,\n this.#textDocument.lineCount\n );\n if (\n this.#grammar === undefined &&\n !isGrammarlessLanguage(this.#textDocument.languageId)\n ) {\n await this.#highlighter.loadLanguage(this.#textDocument.languageId);\n this.#grammar = this.#highlighter.getLanguage(\n this.#textDocument.languageId\n );\n }\n this.#buildStateStack(endLine);\n }, 500);\n\n #onMessage = ({ data }: MessageEvent<unknown>) => {\n if (typeof data !== 'object' || data === null) {\n return;\n }\n const { type, jobId } = data as {\n type?: unknown;\n jobId?: unknown;\n };\n if (\n type === 'tokenize' &&\n typeof jobId === 'number' &&\n jobId === this.#backgroundJobId\n ) {\n this.#backgroundTokenize(jobId);\n }\n };\n\n get themeType(): 'light' | 'dark' {\n return this.#themeType;\n }\n\n constructor({\n codeOptions,\n highlighter,\n textDocument,\n setStyle,\n onDeferTokenize,\n onThemeChange,\n __debug,\n }: EditorTokenizerProps) {\n const {\n themeType = 'system',\n theme = DEFAULT_THEMES,\n tokenizeMaxLineLength = 1000,\n } = codeOptions;\n this.#mediaQueryList = window.matchMedia('(prefers-color-scheme: dark)');\n if (themeType === 'system') {\n this.#themeType = this.#mediaQueryList.matches ? 'dark' : 'light';\n } else {\n this.#themeType = themeType;\n }\n // Only track the document/system color scheme when the surface follows it\n // (`themeType: 'system'`). A surface pinned to an explicit 'dark'/'light'\n // theme keeps that theme regardless of the page, so re-tokenizing after an\n // edit must emit the same `--diffs-token-{theme}` variable the SSR markup\n // used; otherwise the edited tokens fall back to the default foreground.\n if (typeof theme !== 'string' && themeType === 'system') {\n const observer = new MutationObserver((mutations) => {\n for (const { type, attributeName } of mutations) {\n if (\n type === 'attributes' &&\n attributeName !== null &&\n (attributeName === 'class' || attributeName.startsWith('data-'))\n ) {\n const themeType =\n getComputedStyle(document.body).colorScheme === 'dark'\n ? 'dark'\n : 'light';\n this.#emitThemeChange(theme[themeType], themeType);\n break;\n }\n }\n });\n observer.observe(document.documentElement, { attributes: true });\n observer.observe(document.body, { attributes: true });\n this.#disposes = [\n addEventListener(this.#mediaQueryList, 'change', (e) => {\n const themeType = e.matches ? 'dark' : 'light';\n this.#emitThemeChange(theme[themeType], themeType);\n }),\n () => observer.disconnect(),\n ];\n }\n this.#highlighter = highlighter;\n this.#textDocument = textDocument;\n this.#tokenizeMaxLineLength = tokenizeMaxLineLength;\n this.#setStyle = setStyle;\n this.#onDeferTokenize = onDeferTokenize;\n this.#onThemeChange = onThemeChange;\n this.#debug = __debug ?? false;\n this.#ensureGrammar();\n this.#colorMap = [];\n this.#setTheme(typeof theme === 'string' ? theme : theme[this.#themeType]);\n }\n\n // By default, diffs components support dual themes, but the tokenizer only renders\n // the preferred theme. When the theme type is changed, the tokenizer will re-tokenize the document.\n #emitThemeChange(themeName: string, themeType: 'light' | 'dark') {\n this.#themeType = themeType;\n this.#setTheme(themeName);\n this.stopBackgroundTokenize();\n this.#stateStack = [INITIAL];\n if (this.#grammar !== undefined && this.#textDocument.lineCount > 0) {\n this.#scheduleBackgroundTokenize(0);\n }\n // The theme CSS is now applied, so overlay pieces that captured a resolved\n // theme color (e.g. rounded selection corner masks) can recompute against\n // the new colors instead of keeping the old light/dark value.\n this.#onThemeChange?.();\n }\n\n // Re-apply the editor's theme from the surface's current code options. Edit\n // mode reuses a single tokenizer across re-renders, so when the host swaps the\n // theme — a theme picker, a light/dark toggle, etc. — we must recompute the\n // active theme and re-tokenize. Without this the editor keeps rendering the\n // theme it captured when it first attached (stale line-highlight background\n // and token colors). System-driven changes are still handled by the\n // observers wired up in the constructor; this covers explicit `themeType`/\n // `theme` option changes that those observers don't see.\n syncTheme(codeOptions: BaseCodeOptions): void {\n const { themeType = 'system', theme = DEFAULT_THEMES } = codeOptions;\n const nextThemeType =\n themeType === 'system'\n ? this.#mediaQueryList.matches\n ? 'dark'\n : 'light'\n : themeType;\n const nextThemeName =\n typeof theme === 'string' ? theme : theme[nextThemeType];\n if (\n nextThemeType === this.#themeType &&\n nextThemeName === this.#themeName\n ) {\n return;\n }\n this.#emitThemeChange(nextThemeName, nextThemeType);\n }\n\n #setTheme(themeName: string) {\n this.#themeName = themeName;\n this.#colorMap = this.#highlighter.setTheme(themeName).colorMap;\n const { colors = {} } = this.#highlighter.getTheme(themeName);\n const selectionBackground = colors['editor.selectionBackground'];\n const lineHighlightBackground = colors['editor.lineHighlightBackground'];\n const cursorForeground = colors['editorCursor.foreground'];\n const findMatchBackground = colors['editor.findMatchBackground'];\n const findMatchHighlightBackground =\n colors['editor.findMatchHighlightBackground'];\n const hintForeground = colors['editorHint.foreground'];\n const infoForeground = colors['editorInfo.foreground'];\n const warningForeground = colors['editorWarning.foreground'];\n const errorForeground = colors['editorError.foreground'];\n this.#setStyle(`:host {\n --diffs-editor-selection-bg: ${selectionBackground ?? 'var(--diffs-line-bg)'};\n --diffs-editor-line-highlight-bg: ${lineHighlightBackground ?? 'var(--diffs-line-bg)'};\n --diffs-editor-match-bg: ${findMatchBackground ?? 'unset'};\n --diffs-editor-match-highlight-bg: ${findMatchHighlightBackground ?? 'unset'};\n --diffs-editor-cursor-fg: ${cursorForeground ?? 'unset'};\n --diffs-editor-hint-fg: ${hintForeground ?? 'unset'};\n --diffs-editor-info-fg: ${infoForeground ?? 'unset'};\n --diffs-editor-warning-fg: ${warningForeground ?? 'unset'};\n --diffs-editor-error-fg: ${errorForeground ?? 'unset'};\n }`);\n }\n\n cleanUp(): void {\n this.stopBackgroundTokenize();\n this.#detachMessageListener();\n this.#disposes?.forEach((dispose) => dispose());\n this.#disposes = undefined;\n }\n\n // to use `tokenize`, call `prebuildStateStackMap` first to prebuild\n // the state stack map for the given render range.\n tokenize(\n change: TextDocumentChange,\n renderRange?: RenderRange\n ): Map<number, Array<HighlightedToken>> {\n this.#ensureGrammar();\n if (\n this.#grammar === undefined &&\n !isGrammarlessLanguage(this.#textDocument.languageId)\n ) {\n throw new Error(\n `Grammar for language \"${this.#textDocument.languageId}\" not loaded`\n );\n }\n\n const { lineCount } = this.#textDocument;\n const { startingLine = 0, totalLines = Infinity } = renderRange ?? {};\n const renderRangeEndLine =\n totalLines === Infinity\n ? lineCount\n : Math.min(startingLine + totalLines, lineCount);\n\n const dirtyStart = change.startLine;\n const viewStart = Math.max(startingLine, dirtyStart);\n const crossesRenderRangeEnd =\n renderRange !== undefined &&\n totalLines !== Infinity &&\n change.lineDelta > 0 &&\n dirtyStart < renderRangeEndLine &&\n change.endLine >= renderRangeEndLine;\n const canReuseCachedStates = change.lineDelta === 0;\n const canCacheTokenizedStates =\n canReuseCachedStates ||\n renderRange === undefined ||\n dirtyStart >= viewStart;\n const changedLineRanges: readonly [number, number][] = canReuseCachedStates\n ? (change.changedLineRanges ?? [[dirtyStart, change.endLine]])\n : [[dirtyStart, change.endLine]];\n let offscreenSyncEnd = -1;\n if (dirtyStart < viewStart) {\n for (const [rangeStart, rangeEnd] of changedLineRanges) {\n if (rangeStart < viewStart) {\n offscreenSyncEnd = Math.max(\n offscreenSyncEnd,\n Math.min(rangeEnd, viewStart - 1)\n );\n }\n }\n }\n const shouldFlushOffscreenLines =\n offscreenSyncEnd >= dirtyStart &&\n (canReuseCachedStates || change.lineDelta < 0);\n if (canReuseCachedStates) {\n this.#buildStateStack(dirtyStart);\n } else {\n this.#stateStack.length = Math.min(\n this.#stateStack.length,\n dirtyStart + 1\n );\n if (renderRange === undefined || dirtyStart >= viewStart) {\n this.#buildStateStack(viewStart);\n }\n }\n\n let changedRangeIndex = 0;\n let currentChangedRangeEnd = changedLineRanges[changedRangeIndex][1];\n let backgroundStartLine: number | undefined;\n let backgroundChangedRangeIndex = 0;\n let line = canReuseCachedStates\n ? changedLineRanges[changedRangeIndex][0]\n : viewStart;\n let settled = false;\n const dirtyLines: Map<number, Array<HighlightedToken>> = new Map();\n const offscreenDirtyLines:\n | Map<number, Array<HighlightedToken>>\n | undefined = shouldFlushOffscreenLines ? new Map() : undefined;\n if (offscreenDirtyLines !== undefined && !canReuseCachedStates) {\n const offscreenEnd = Math.min(\n offscreenSyncEnd + 1,\n viewStart,\n renderRangeEndLine\n );\n if (offscreenEnd > dirtyStart) {\n this.#buildStateStack(offscreenEnd);\n let offscreenLine = dirtyStart;\n let offscreenState = this.#stateStack[offscreenLine] ?? INITIAL;\n for (; offscreenLine < offscreenEnd; offscreenLine++) {\n const resolved = this.#tokenizeLineAt(offscreenLine, offscreenState);\n offscreenState = resolved.state;\n offscreenDirtyLines.set(offscreenLine, resolved.resolvedTokens);\n }\n if (canCacheTokenizedStates) {\n this.#stateStack[offscreenEnd] = offscreenState;\n }\n }\n }\n // Seed the loop's grammar state after the offscreen flush, not before it.\n // When a delete's removed lines reach the viewport's first line, the flush\n // rebuilds the cached state up to `line`; reading it earlier would capture\n // the truncated INITIAL state and color the viewport as if outside an open\n // construct (block comment, template literal) it is actually inside.\n let state = this.#stateStack[line] ?? INITIAL;\n for (; line < renderRangeEndLine; ) {\n const previousNextState = canReuseCachedStates\n ? this.#stateStack[line + 1]\n : undefined;\n if (canCacheTokenizedStates) {\n this.#stateStack[line] = state;\n }\n\n const { resolvedTokens, state: nextState } = this.#tokenizeLineAt(\n line,\n state\n );\n state = nextState;\n\n if (line >= viewStart) {\n dirtyLines.set(line, resolvedTokens);\n } else {\n offscreenDirtyLines?.set(line, resolvedTokens);\n }\n\n if (canCacheTokenizedStates) {\n this.#stateStack[line + 1] = state;\n }\n settled =\n line >= currentChangedRangeEnd &&\n canReuseCachedStates &&\n previousNextState !== undefined &&\n state.equals(previousNextState);\n if (settled) {\n changedRangeIndex++;\n const nextRange = changedLineRanges[changedRangeIndex];\n if (nextRange === undefined) {\n break;\n }\n if (nextRange[0] >= renderRangeEndLine) {\n backgroundStartLine = nextRange[0];\n backgroundChangedRangeIndex = changedRangeIndex;\n break;\n }\n if (this.#stateStack[nextRange[0]] === undefined) {\n currentChangedRangeEnd = nextRange[1];\n line++;\n } else {\n line = nextRange[0];\n state = this.#stateStack[line] ?? state;\n currentChangedRangeEnd = nextRange[1];\n }\n settled = false;\n continue;\n }\n line++;\n }\n\n if (canCacheTokenizedStates) {\n if (line < renderRangeEndLine) {\n this.#stateStack[line + 1] = state;\n } else {\n this.#stateStack[line] = state;\n }\n }\n\n if (offscreenDirtyLines !== undefined && offscreenDirtyLines.size > 0) {\n this.#onDeferTokenize(offscreenDirtyLines, this.#themeType);\n }\n\n if (backgroundStartLine !== undefined) {\n this.#scheduleBackgroundTokenize(\n backgroundStartLine,\n changedLineRanges,\n backgroundChangedRangeIndex\n );\n } else if (!settled && line < lineCount) {\n const backgroundLine =\n crossesRenderRangeEnd && dirtyStart >= viewStart\n ? renderRangeEndLine\n : dirtyStart < viewStart && !canReuseCachedStates\n ? dirtyStart\n : line;\n this.#scheduleBackgroundTokenize(\n backgroundLine,\n canReuseCachedStates ? changedLineRanges : undefined,\n changedRangeIndex\n );\n }\n\n return dirtyLines;\n }\n\n prebuildStateStack(renderRange?: RenderRange): void {\n this.#ensureGrammar();\n this.#prebuildStateStack(renderRange);\n }\n\n #ensureGrammar(): void {\n if (\n this.#grammar === undefined &&\n !isGrammarlessLanguage(this.#textDocument.languageId) &&\n this.#highlighter\n .getLoadedLanguages()\n .includes(this.#textDocument.languageId)\n ) {\n this.#grammar = this.#highlighter.getLanguage(\n this.#textDocument.languageId\n );\n }\n }\n\n stopBackgroundTokenize(): void {\n if (this.#isStopped) {\n return;\n }\n this.#isStopped = true;\n this.#isPaused = false;\n this.#lastLine = -1;\n this.#backgroundChangedLineRanges = undefined;\n this.#backgroundChangedRangeIndex = 0;\n this.#detachMessageListener();\n }\n\n pauseBackgroundTokenize(): void {\n if (this.#isStopped || this.#isPaused) {\n return;\n }\n if (this.#debug) {\n console.log('[diffs/editor] background tokenization paused', {\n jobId: this.#backgroundJobId,\n });\n }\n this.#isPaused = true;\n }\n\n resumeBackgroundTokenize(): void {\n if (\n this.#isStopped ||\n !this.#isPaused ||\n this.#grammar === undefined ||\n this.#lastLine < 0\n ) {\n return;\n }\n if (this.#debug) {\n console.log('[diffs/editor] background tokenization resumed', {\n jobId: this.#backgroundJobId,\n });\n }\n this.#isPaused = false;\n this.#postTokenizeMessage(this.#backgroundJobId);\n }\n\n #attachMessageListener(): void {\n if (this.#isMessageListenerAttached) {\n return;\n }\n globalThis.addEventListener('message', this.#onMessage);\n this.#isMessageListenerAttached = true;\n }\n\n #detachMessageListener(): void {\n if (!this.#isMessageListenerAttached) {\n return;\n }\n globalThis.removeEventListener('message', this.#onMessage);\n this.#isMessageListenerAttached = false;\n }\n\n #postTokenizeMessage(jobId: number): void {\n // use `postMessage` instead of `setTimeout(fn, 0)` to avoid 4ms delay\n globalThis.postMessage({ type: 'tokenize', jobId });\n }\n\n #scheduleBackgroundTokenize(\n startLine: number,\n changedLineRanges?: readonly [number, number][],\n changedRangeIndex = 0\n ): void {\n if (isGrammarlessLanguage(this.#textDocument.languageId)) {\n return;\n }\n\n const jobId = ++this.#backgroundJobId;\n\n if (this.#debug) {\n console.log('[diffs/editor] background tokenization scheduled', {\n jobId,\n startLine,\n changedLineRanges,\n changedRangeIndex,\n });\n }\n\n this.#isStopped = false;\n this.#isPaused = false;\n this.#lastLine = startLine;\n this.#backgroundChangedLineRanges = changedLineRanges;\n this.#backgroundChangedRangeIndex = changedRangeIndex;\n this.#attachMessageListener();\n this.#postTokenizeMessage(jobId);\n }\n\n #tokenizeLineAt(\n line: number,\n state: StateStack\n ): { resolvedTokens: Array<HighlightedToken>; state: StateStack } {\n const lineText = this.#textDocument.getLineText(line);\n if (lineText.length > this.#tokenizeMaxLineLength) {\n console.warn(\n `[diffs] Line(${line}) too long to tokenize: ${lineText.length}`\n );\n return { resolvedTokens: [[0, '', lineText]], state };\n }\n if (\n this.#grammar === undefined ||\n lineText === '' ||\n lineText.trim() === ''\n ) {\n return { resolvedTokens: [[0, '', lineText]], state };\n }\n const result = tokenizeLine(\n this.#grammar,\n this.#colorMap,\n lineText,\n state,\n EditorTokenizer.TOKENIZE_TIME_LIMIT\n );\n return {\n resolvedTokens: result.resolvedTokens,\n state: result.ruleStack,\n };\n }\n\n #buildStateStack(endAt: number) {\n const boundedEndAt = Math.min(\n Math.max(0, endAt),\n this.#textDocument.lineCount\n );\n if (this.#stateStack.length > boundedEndAt || this.#grammar === undefined) {\n return;\n }\n let line = this.#stateStack.length - 1;\n let state = this.#stateStack[line] ?? INITIAL;\n for (; line < boundedEndAt; line++) {\n this.#stateStack[line] = state;\n const lineText = this.#textDocument.getLineText(line);\n if (\n lineText.length <= this.#tokenizeMaxLineLength &&\n lineText !== '' &&\n lineText.trim() !== ''\n ) {\n state = this.#grammar.tokenizeLine2(\n lineText,\n state,\n EditorTokenizer.TOKENIZE_TIME_LIMIT\n ).ruleStack;\n }\n }\n this.#stateStack[line] = state;\n }\n\n #backgroundTokenize(jobId: number) {\n if (\n this.#isStopped ||\n this.#isPaused ||\n this.#grammar === undefined ||\n jobId !== this.#backgroundJobId\n ) {\n return;\n }\n\n const t = performance.now();\n const lines = new Map<number, Array<HighlightedToken>>();\n const totalLines = this.#textDocument.lineCount;\n const changedLineRanges = this.#backgroundChangedLineRanges;\n\n let line = this.#lastLine;\n let state = this.#stateStack[line] ?? INITIAL;\n let settled = false;\n let changedRangeIndex = this.#backgroundChangedRangeIndex;\n let currentChangedRangeEnd = changedLineRanges?.[changedRangeIndex]?.[1];\n for (; line < totalLines; ) {\n this.#stateStack[line] = state;\n\n const previousNextState =\n currentChangedRangeEnd !== undefined\n ? this.#stateStack[line + 1]\n : undefined;\n const lineText = this.#textDocument.getLineText(line);\n if (lineText.length > this.#tokenizeMaxLineLength) {\n console.warn(\n `[diffs] Line(${line}) too long to tokenize: ${lineText.length}`\n );\n lines.set(line, [[0, '', lineText]]);\n } else if (lineText === '' || lineText.trim() === '') {\n lines.set(line, [[0, '', lineText]]);\n } else {\n const ret = tokenizeLine(\n this.#grammar,\n this.#colorMap,\n lineText,\n state,\n EditorTokenizer.TOKENIZE_TIME_LIMIT\n );\n lines.set(line, ret.resolvedTokens);\n state = ret.ruleStack;\n }\n\n this.#stateStack[line + 1] = state;\n settled =\n currentChangedRangeEnd !== undefined &&\n line >= currentChangedRangeEnd &&\n previousNextState !== undefined &&\n state.equals(previousNextState);\n line++;\n if (settled) {\n changedRangeIndex++;\n const nextRange = changedLineRanges?.[changedRangeIndex];\n if (nextRange === undefined) {\n break;\n }\n currentChangedRangeEnd = nextRange[1];\n if (this.#stateStack[nextRange[0]] === undefined) {\n settled = false;\n } else {\n line = nextRange[0];\n state = this.#stateStack[line] ?? state;\n settled = false;\n continue;\n }\n }\n\n // limit the time of partial tokenize to 1ms\n if (performance.now() - t > 1) {\n break;\n }\n }\n\n this.#onDeferTokenize(lines, this.#themeType);\n if (this.#isStopped || this.#isPaused || jobId !== this.#backgroundJobId) {\n return;\n }\n\n if (settled || line >= totalLines) {\n this.stopBackgroundTokenize();\n return;\n }\n\n this.#lastLine = line;\n this.#backgroundChangedRangeIndex = changedRangeIndex;\n this.#postTokenizeMessage(jobId);\n }\n}\n\nexport function tokenizeLine(\n grammar: IGrammar,\n colorMap: string[],\n lineText: string,\n stateStack: StateStack,\n timeLimit?: number\n): {\n ruleStack: StateStack;\n resolvedTokens: Array<HighlightedToken>;\n} {\n const result = grammar.tokenizeLine2(lineText, stateStack, timeLimit);\n if (result.stoppedEarly) {\n console.warn(\n `[diffs] Time limit reached when tokenizing line: ${lineText.substring(0, 100)}`\n );\n }\n const rawTokens = result.tokens;\n const tokensLength = rawTokens.length / 2;\n const resolvedTokens: Array<HighlightedToken> = [];\n for (let j = 0; j < tokensLength; j++) {\n const offset = rawTokens[2 * j];\n const nextOffset =\n j + 1 < tokensLength ? rawTokens[2 * j + 2] : lineText.length;\n if (offset === nextOffset) {\n // should never reach here, skip if happens anyway\n continue;\n }\n const metadata = rawTokens[2 * j + 1];\n const bg = EncodedTokenMetadata.getForeground(metadata);\n const fg = colorMap[bg];\n const tokenText = lineText.slice(offset, nextOffset);\n resolvedTokens.push([offset, fg, tokenText]);\n }\n return {\n ruleStack: result.ruleStack,\n resolvedTokens,\n };\n}\n\nexport function renderLineTokens(\n tokens: Array<HighlightedToken>,\n themeType: 'light' | 'dark'\n): (HTMLElement | string)[] {\n return tokens.map(([char, fg, textContent]) => {\n if (char === 0 && fg === '') {\n if (textContent === '') {\n return h('br');\n }\n return textContent;\n }\n return h('span', {\n dataset: {\n char: char.toString(),\n },\n style: `--diffs-token-${themeType}:${fg};`,\n textContent: textContent,\n });\n });\n}\n\n// Shiki special-cases `text` and `ansi` in codeToHast but does not expose grammars.\nfunction isGrammarlessLanguage(languageId: string): boolean {\n return languageId === 'text' || languageId === 'ansi';\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"tokenzier.js","names":["#textDocument","#grammar","#highlighter","#buildStateStack","#backgroundJobId","#backgroundTokenize","#themeType","#matchBrackets","#ensureGrammar","#bracketIgnoredRanges","#stateStack","#tokenizeLineAt","#mediaQueryList","#emitThemeChange","#disposes","#tokenizeMaxLineLength","#setStyle","#onDeferTokenize","#onThemeChange","#debug","#colorMap","#setTheme","#scheduleBackgroundTokenize","#themeName","#detachMessageListener","#prebuildStateStack","#isStopped","#isPaused","#lastLine","#backgroundChangedLineRanges","#backgroundChangedRangeIndex","#postTokenizeMessage","#isMessageListenerAttached","#onMessage","#attachMessageListener","#cacheBracketIgnoredRanges"],"sources":["../../src/editor/tokenzier.ts"],"sourcesContent":["import {\n EncodedTokenMetadata,\n type IGrammar,\n INITIAL,\n type StateStack,\n} from 'shiki/textmate';\n\nimport { DEFAULT_THEMES } from '../constants';\nimport type {\n BaseCodeOptions,\n DiffsHighlighter,\n HighlightedToken,\n RenderRange,\n} from '../types';\nimport type { TextDocument, TextDocumentChange } from './textDocument';\nimport { addEventListener, debounce, h } from './utils';\n\nconst TOKENIZE_TIME_LIMIT = 500;\n\nexport interface EditorTokenizerProps {\n highlighter: DiffsHighlighter;\n textDocument: TextDocument<unknown>;\n codeOptions: BaseCodeOptions;\n matchBrackets?: boolean;\n setStyle: (style: string) => void;\n onDeferTokenize: (\n lines: Map<number, Array<HighlightedToken>>,\n themeType: 'dark' | 'light'\n ) => void;\n // Fired after the active theme (light/dark mode or theme name) changes and the\n // new theme CSS has been applied. Lets the editor recompute overlay pieces\n // that captured a resolved theme color, e.g. rounded selection corner masks.\n onThemeChange?: () => void;\n __debug?: boolean;\n}\n\n/** Stoppable code tokenizer for the editor */\nexport class EditorTokenizer {\n #highlighter: DiffsHighlighter;\n #grammar: IGrammar | undefined;\n #mediaQueryList: MediaQueryList;\n #themeType: 'light' | 'dark';\n #themeName = '';\n #colorMap: string[];\n #textDocument: TextDocument<unknown>;\n #tokenizeMaxLineLength: number;\n #setStyle: EditorTokenizerProps['setStyle'];\n #onDeferTokenize: EditorTokenizerProps['onDeferTokenize'];\n #onThemeChange: EditorTokenizerProps['onThemeChange'];\n #matchBrackets: boolean;\n #debug: boolean;\n #disposes?: (() => void)[];\n\n // state\n #stateStack: StateStack[] = [INITIAL]; // cached state stack by line index\n #lastLine: number = -1;\n #isStopped: boolean = true;\n #isPaused: boolean = false;\n #backgroundJobId: number = 0;\n #backgroundChangedLineRanges: readonly [number, number][] | undefined;\n #backgroundChangedRangeIndex: number = 0;\n #bracketIgnoredRanges: Map<number, [number, number][] | null> = new Map();\n #isMessageListenerAttached: boolean = false;\n\n #prebuildStateStack = debounce(async (renderRange?: RenderRange) => {\n const { startingLine = 0, totalLines = Infinity } = renderRange ?? {};\n const endLine = Math.min(\n totalLines === Infinity ? Infinity : startingLine + totalLines,\n this.#textDocument.lineCount\n );\n if (\n this.#grammar === undefined &&\n !isGrammarlessLanguage(this.#textDocument.languageId)\n ) {\n await this.#highlighter.loadLanguage(this.#textDocument.languageId);\n this.#grammar = this.#highlighter.getLanguage(\n this.#textDocument.languageId\n );\n }\n this.#buildStateStack(endLine);\n }, 500);\n\n #onMessage = ({ data }: MessageEvent<unknown>) => {\n if (typeof data !== 'object' || data === null) {\n return;\n }\n const { type, jobId } = data as {\n type?: unknown;\n jobId?: unknown;\n };\n if (\n type === 'tokenize' &&\n typeof jobId === 'number' &&\n jobId === this.#backgroundJobId\n ) {\n this.#backgroundTokenize(jobId);\n }\n };\n\n get themeType(): 'light' | 'dark' {\n return this.#themeType;\n }\n\n getStringCommentRegexpRangesInLine(\n lineIndex: number\n ): [number, number][] | null {\n if (\n !this.#matchBrackets ||\n lineIndex < 0 ||\n lineIndex >= this.#textDocument.lineCount\n ) {\n return null;\n }\n this.#ensureGrammar();\n if (this.#grammar === undefined) {\n return null;\n }\n if (!this.#bracketIgnoredRanges.has(lineIndex)) {\n this.#buildStateStack(lineIndex);\n const state = this.#stateStack[lineIndex] ?? INITIAL;\n const result = this.#tokenizeLineAt(lineIndex, state);\n this.#stateStack[lineIndex + 1] = result.state;\n }\n return this.#bracketIgnoredRanges.get(lineIndex) ?? null;\n }\n\n constructor({\n codeOptions,\n highlighter,\n textDocument,\n matchBrackets,\n setStyle,\n onDeferTokenize,\n onThemeChange,\n __debug,\n }: EditorTokenizerProps) {\n const {\n themeType = 'system',\n theme = DEFAULT_THEMES,\n tokenizeMaxLineLength = 1000,\n } = codeOptions;\n this.#mediaQueryList = window.matchMedia('(prefers-color-scheme: dark)');\n if (themeType === 'system') {\n this.#themeType = this.#mediaQueryList.matches ? 'dark' : 'light';\n } else {\n this.#themeType = themeType;\n }\n // Only track the document/system color scheme when the surface follows it\n // (`themeType: 'system'`). A surface pinned to an explicit 'dark'/'light'\n // theme keeps that theme regardless of the page, so re-tokenizing after an\n // edit must emit the same `--diffs-token-{theme}` variable the SSR markup\n // used; otherwise the edited tokens fall back to the default foreground.\n if (typeof theme !== 'string' && themeType === 'system') {\n const observer = new MutationObserver((mutations) => {\n for (const { type, attributeName } of mutations) {\n if (\n type === 'attributes' &&\n attributeName !== null &&\n (attributeName === 'class' || attributeName.startsWith('data-'))\n ) {\n const themeType =\n getComputedStyle(document.body).colorScheme === 'dark'\n ? 'dark'\n : 'light';\n this.#emitThemeChange(theme[themeType], themeType);\n break;\n }\n }\n });\n observer.observe(document.documentElement, { attributes: true });\n observer.observe(document.body, { attributes: true });\n this.#disposes = [\n addEventListener(this.#mediaQueryList, 'change', (e) => {\n const themeType = e.matches ? 'dark' : 'light';\n this.#emitThemeChange(theme[themeType], themeType);\n }),\n () => observer.disconnect(),\n ];\n }\n this.#highlighter = highlighter;\n this.#textDocument = textDocument;\n this.#tokenizeMaxLineLength = tokenizeMaxLineLength;\n this.#setStyle = setStyle;\n this.#onDeferTokenize = onDeferTokenize;\n this.#onThemeChange = onThemeChange;\n this.#matchBrackets = matchBrackets !== false;\n this.#debug = __debug ?? false;\n this.#ensureGrammar();\n this.#colorMap = [];\n this.#setTheme(typeof theme === 'string' ? theme : theme[this.#themeType]);\n }\n\n // By default, diffs components support dual themes, but the tokenizer only renders\n // the preferred theme. When the theme type is changed, the tokenizer will re-tokenize the document.\n #emitThemeChange(themeName: string, themeType: 'light' | 'dark') {\n this.#themeType = themeType;\n this.#setTheme(themeName);\n this.stopBackgroundTokenize();\n this.#stateStack = [INITIAL];\n if (this.#grammar !== undefined && this.#textDocument.lineCount > 0) {\n this.#scheduleBackgroundTokenize(0);\n }\n // The theme CSS is now applied, so overlay pieces that captured a resolved\n // theme color (e.g. rounded selection corner masks) can recompute against\n // the new colors instead of keeping the old light/dark value.\n this.#onThemeChange?.();\n }\n\n // Re-apply the editor's theme from the surface's current code options. Edit\n // mode reuses a single tokenizer across re-renders, so when the host swaps the\n // theme — a theme picker, a light/dark toggle, etc. — we must recompute the\n // active theme and re-tokenize. Without this the editor keeps rendering the\n // theme it captured when it first attached (stale line-highlight background\n // and token colors). System-driven changes are still handled by the\n // observers wired up in the constructor; this covers explicit `themeType`/\n // `theme` option changes that those observers don't see.\n syncTheme(codeOptions: BaseCodeOptions): void {\n const { themeType = 'system', theme = DEFAULT_THEMES } = codeOptions;\n const nextThemeType =\n themeType === 'system'\n ? this.#mediaQueryList.matches\n ? 'dark'\n : 'light'\n : themeType;\n const nextThemeName =\n typeof theme === 'string' ? theme : theme[nextThemeType];\n if (\n nextThemeType === this.#themeType &&\n nextThemeName === this.#themeName\n ) {\n return;\n }\n this.#emitThemeChange(nextThemeName, nextThemeType);\n }\n\n #setTheme(themeName: string) {\n this.#themeName = themeName;\n this.#colorMap = this.#highlighter.setTheme(themeName).colorMap;\n const { colors = {} } = this.#highlighter.getTheme(themeName);\n const selectionBackground = colors['editor.selectionBackground'];\n const lineHighlightBackground = colors['editor.lineHighlightBackground'];\n const cursorForeground = colors['editorCursor.foreground'];\n const findMatchBackground = colors['editor.findMatchBackground'];\n const findMatchHighlightBackground =\n colors['editor.findMatchHighlightBackground'];\n const bracketMatchBackground = colors['editorBracketMatch.background'];\n const bracketMatchBorder = colors['editorBracketMatch.border'];\n const hintForeground = colors['editorHint.foreground'];\n const infoForeground = colors['editorInfo.foreground'];\n const warningForeground = colors['editorWarning.foreground'];\n const errorForeground = colors['editorError.foreground'];\n this.#setStyle(`:host {\n --diffs-editor-selection-bg: ${selectionBackground ?? 'var(--diffs-line-bg)'};\n --diffs-editor-line-highlight-bg: ${lineHighlightBackground ?? 'var(--diffs-line-bg)'};\n --diffs-editor-match-bg: ${findMatchBackground ?? 'initial'};\n --diffs-editor-match-highlight-bg: ${findMatchHighlightBackground ?? 'initial'};\n --diffs-editor-bracket-match-bg: ${bracketMatchBackground ?? 'initial'};\n --diffs-editor-bracket-match-border: ${bracketMatchBorder ?? 'initial'};\n --diffs-editor-cursor-fg: ${cursorForeground ?? 'initial'};\n --diffs-editor-hint-fg: ${hintForeground ?? 'initial'};\n --diffs-editor-info-fg: ${infoForeground ?? 'initial'};\n --diffs-editor-warning-fg: ${warningForeground ?? 'initial'};\n --diffs-editor-error-fg: ${errorForeground ?? 'initial'};\n }`);\n }\n\n cleanUp(): void {\n this.stopBackgroundTokenize();\n this.#detachMessageListener();\n this.#disposes?.forEach((dispose) => dispose());\n this.#disposes = undefined;\n }\n\n // to use `tokenize`, call `prebuildStateStackMap` first to prebuild\n // the state stack map for the given render range.\n tokenize(\n change: TextDocumentChange,\n renderRange?: RenderRange\n ): Map<number, Array<HighlightedToken>> {\n this.#ensureGrammar();\n if (\n this.#grammar === undefined &&\n !isGrammarlessLanguage(this.#textDocument.languageId)\n ) {\n throw new Error(\n `Grammar for language \"${this.#textDocument.languageId}\" not loaded`\n );\n }\n\n if (this.#matchBrackets) {\n // Clear ignored token ranges for lines invalidated by the edit.\n for (const line of this.#bracketIgnoredRanges.keys()) {\n if (line >= change.startLine) {\n this.#bracketIgnoredRanges.delete(line);\n }\n }\n }\n\n const { lineCount } = this.#textDocument;\n const { startingLine = 0, totalLines = Infinity } = renderRange ?? {};\n const renderRangeEndLine =\n totalLines === Infinity\n ? lineCount\n : Math.min(startingLine + totalLines, lineCount);\n\n const dirtyStart = change.startLine;\n const viewStart = Math.max(startingLine, dirtyStart);\n const crossesRenderRangeEnd =\n renderRange !== undefined &&\n totalLines !== Infinity &&\n change.lineDelta > 0 &&\n dirtyStart < renderRangeEndLine &&\n change.endLine >= renderRangeEndLine;\n const canReuseCachedStates = change.lineDelta === 0;\n const canCacheTokenizedStates =\n canReuseCachedStates ||\n renderRange === undefined ||\n dirtyStart >= viewStart;\n const changedLineRanges: readonly [number, number][] = canReuseCachedStates\n ? (change.changedLineRanges ?? [[dirtyStart, change.endLine]])\n : [[dirtyStart, change.endLine]];\n let offscreenSyncEnd = -1;\n if (dirtyStart < viewStart) {\n for (const [rangeStart, rangeEnd] of changedLineRanges) {\n if (rangeStart < viewStart) {\n offscreenSyncEnd = Math.max(\n offscreenSyncEnd,\n Math.min(rangeEnd, viewStart - 1)\n );\n }\n }\n }\n const shouldFlushOffscreenLines =\n offscreenSyncEnd >= dirtyStart &&\n (canReuseCachedStates || change.lineDelta < 0);\n if (canReuseCachedStates) {\n this.#buildStateStack(dirtyStart);\n } else {\n this.#stateStack.length = Math.min(\n this.#stateStack.length,\n dirtyStart + 1\n );\n if (renderRange === undefined || dirtyStart >= viewStart) {\n this.#buildStateStack(viewStart);\n }\n }\n\n let changedRangeIndex = 0;\n let currentChangedRangeEnd = changedLineRanges[changedRangeIndex][1];\n let backgroundStartLine: number | undefined;\n let backgroundChangedRangeIndex = 0;\n let line = canReuseCachedStates\n ? changedLineRanges[changedRangeIndex][0]\n : viewStart;\n let settled = false;\n const dirtyLines: Map<number, Array<HighlightedToken>> = new Map();\n const offscreenDirtyLines:\n | Map<number, Array<HighlightedToken>>\n | undefined = shouldFlushOffscreenLines ? new Map() : undefined;\n if (offscreenDirtyLines !== undefined && !canReuseCachedStates) {\n const offscreenEnd = Math.min(\n offscreenSyncEnd + 1,\n viewStart,\n renderRangeEndLine\n );\n if (offscreenEnd > dirtyStart) {\n this.#buildStateStack(offscreenEnd);\n let offscreenLine = dirtyStart;\n let offscreenState = this.#stateStack[offscreenLine] ?? INITIAL;\n for (; offscreenLine < offscreenEnd; offscreenLine++) {\n const resolved = this.#tokenizeLineAt(offscreenLine, offscreenState);\n offscreenState = resolved.state;\n offscreenDirtyLines.set(offscreenLine, resolved.resolvedTokens);\n }\n if (canCacheTokenizedStates) {\n this.#stateStack[offscreenEnd] = offscreenState;\n }\n }\n }\n // Seed the loop's grammar state after the offscreen flush, not before it.\n // When a delete's removed lines reach the viewport's first line, the flush\n // rebuilds the cached state up to `line`; reading it earlier would capture\n // the truncated INITIAL state and color the viewport as if outside an open\n // construct (block comment, template literal) it is actually inside.\n let state = this.#stateStack[line] ?? INITIAL;\n for (; line < renderRangeEndLine; ) {\n const previousNextState = canReuseCachedStates\n ? this.#stateStack[line + 1]\n : undefined;\n if (canCacheTokenizedStates) {\n this.#stateStack[line] = state;\n }\n\n const { resolvedTokens, state: nextState } = this.#tokenizeLineAt(\n line,\n state\n );\n state = nextState;\n\n if (line >= viewStart) {\n dirtyLines.set(line, resolvedTokens);\n } else {\n offscreenDirtyLines?.set(line, resolvedTokens);\n }\n\n if (canCacheTokenizedStates) {\n this.#stateStack[line + 1] = state;\n }\n settled =\n line >= currentChangedRangeEnd &&\n canReuseCachedStates &&\n previousNextState !== undefined &&\n state.equals(previousNextState);\n if (settled) {\n changedRangeIndex++;\n const nextRange = changedLineRanges[changedRangeIndex];\n if (nextRange === undefined) {\n break;\n }\n if (nextRange[0] >= renderRangeEndLine) {\n backgroundStartLine = nextRange[0];\n backgroundChangedRangeIndex = changedRangeIndex;\n break;\n }\n if (this.#stateStack[nextRange[0]] === undefined) {\n currentChangedRangeEnd = nextRange[1];\n line++;\n } else {\n line = nextRange[0];\n state = this.#stateStack[line] ?? state;\n currentChangedRangeEnd = nextRange[1];\n }\n settled = false;\n continue;\n }\n line++;\n }\n\n if (canCacheTokenizedStates) {\n if (line < renderRangeEndLine) {\n this.#stateStack[line + 1] = state;\n } else {\n this.#stateStack[line] = state;\n }\n }\n\n if (offscreenDirtyLines !== undefined && offscreenDirtyLines.size > 0) {\n this.#onDeferTokenize(offscreenDirtyLines, this.#themeType);\n }\n\n if (backgroundStartLine !== undefined) {\n this.#scheduleBackgroundTokenize(\n backgroundStartLine,\n changedLineRanges,\n backgroundChangedRangeIndex\n );\n } else if (!settled && line < lineCount) {\n const backgroundLine =\n crossesRenderRangeEnd && dirtyStart >= viewStart\n ? renderRangeEndLine\n : dirtyStart < viewStart && !canReuseCachedStates\n ? dirtyStart\n : line;\n this.#scheduleBackgroundTokenize(\n backgroundLine,\n canReuseCachedStates ? changedLineRanges : undefined,\n changedRangeIndex\n );\n }\n\n return dirtyLines;\n }\n\n prebuildStateStack(renderRange?: RenderRange): void {\n this.#ensureGrammar();\n this.#prebuildStateStack(renderRange);\n }\n\n stopBackgroundTokenize(): void {\n if (this.#isStopped) {\n return;\n }\n this.#isStopped = true;\n this.#isPaused = false;\n this.#lastLine = -1;\n this.#backgroundChangedLineRanges = undefined;\n this.#backgroundChangedRangeIndex = 0;\n this.#detachMessageListener();\n }\n\n pauseBackgroundTokenize(): void {\n if (this.#isStopped || this.#isPaused) {\n return;\n }\n if (this.#debug) {\n console.log('[diffs/editor] background tokenization paused', {\n jobId: this.#backgroundJobId,\n });\n }\n this.#isPaused = true;\n }\n\n resumeBackgroundTokenize(): void {\n if (\n this.#isStopped ||\n !this.#isPaused ||\n this.#grammar === undefined ||\n this.#lastLine < 0\n ) {\n return;\n }\n if (this.#debug) {\n console.log('[diffs/editor] background tokenization resumed', {\n jobId: this.#backgroundJobId,\n });\n }\n this.#isPaused = false;\n this.#postTokenizeMessage(this.#backgroundJobId);\n }\n\n #ensureGrammar(): void {\n if (\n this.#grammar === undefined &&\n !isGrammarlessLanguage(this.#textDocument.languageId) &&\n this.#highlighter\n .getLoadedLanguages()\n .includes(this.#textDocument.languageId)\n ) {\n this.#grammar = this.#highlighter.getLanguage(\n this.#textDocument.languageId\n );\n }\n }\n\n #attachMessageListener(): void {\n if (this.#isMessageListenerAttached) {\n return;\n }\n globalThis.addEventListener('message', this.#onMessage);\n this.#isMessageListenerAttached = true;\n }\n\n #detachMessageListener(): void {\n if (!this.#isMessageListenerAttached) {\n return;\n }\n globalThis.removeEventListener('message', this.#onMessage);\n this.#isMessageListenerAttached = false;\n }\n\n #postTokenizeMessage(jobId: number): void {\n // use `postMessage` instead of `setTimeout(fn, 0)` to avoid 4ms delay\n globalThis.postMessage({ type: 'tokenize', jobId });\n }\n\n #scheduleBackgroundTokenize(\n startLine: number,\n changedLineRanges?: readonly [number, number][],\n changedRangeIndex = 0\n ): void {\n if (isGrammarlessLanguage(this.#textDocument.languageId)) {\n return;\n }\n\n const jobId = ++this.#backgroundJobId;\n\n if (this.#debug) {\n console.log('[diffs/editor] background tokenization scheduled', {\n jobId,\n startLine,\n changedLineRanges,\n changedRangeIndex,\n });\n }\n\n this.#isStopped = false;\n this.#isPaused = false;\n this.#lastLine = startLine;\n this.#backgroundChangedLineRanges = changedLineRanges;\n this.#backgroundChangedRangeIndex = changedRangeIndex;\n this.#attachMessageListener();\n this.#postTokenizeMessage(jobId);\n }\n\n #tokenizeLineAt(\n line: number,\n state: StateStack\n ): { resolvedTokens: Array<HighlightedToken>; state: StateStack } {\n const lineText = this.#textDocument.getLineText(line);\n if (lineText.length > this.#tokenizeMaxLineLength) {\n console.warn(\n `[diffs] Line(${line}) too long to tokenize: ${lineText.length}`\n );\n this.#cacheBracketIgnoredRanges(line, null);\n return { resolvedTokens: [[0, '', lineText]], state };\n }\n if (\n this.#grammar === undefined ||\n lineText === '' ||\n lineText.trim() === ''\n ) {\n this.#cacheBracketIgnoredRanges(line, null);\n return { resolvedTokens: [[0, '', lineText]], state };\n }\n const result = tokenizeLine(\n this.#grammar,\n this.#colorMap,\n lineText,\n state,\n TOKENIZE_TIME_LIMIT,\n this.#matchBrackets\n );\n this.#cacheBracketIgnoredRanges(line, result.bracketIgnoredRanges);\n return {\n resolvedTokens: result.resolvedTokens,\n state: result.ruleStack,\n };\n }\n\n #cacheBracketIgnoredRanges(\n line: number,\n ranges: [number, number][] | null\n ): void {\n if (this.#matchBrackets) {\n this.#bracketIgnoredRanges.set(line, ranges);\n }\n }\n\n #buildStateStack(endAt: number) {\n const boundedEndAt = Math.min(\n Math.max(0, endAt),\n this.#textDocument.lineCount\n );\n if (this.#stateStack.length > boundedEndAt || this.#grammar === undefined) {\n return;\n }\n let line = this.#stateStack.length - 1;\n let state = this.#stateStack[line] ?? INITIAL;\n for (; line < boundedEndAt; line++) {\n this.#stateStack[line] = state;\n const lineText = this.#textDocument.getLineText(line);\n if (\n lineText.length <= this.#tokenizeMaxLineLength &&\n lineText !== '' &&\n lineText.trim() !== ''\n ) {\n const result = tokenizeLine(\n this.#grammar,\n this.#colorMap,\n lineText,\n state,\n TOKENIZE_TIME_LIMIT,\n this.#matchBrackets\n );\n this.#cacheBracketIgnoredRanges(line, result.bracketIgnoredRanges);\n state = result.ruleStack;\n } else {\n this.#cacheBracketIgnoredRanges(line, null);\n }\n }\n this.#stateStack[line] = state;\n }\n\n #backgroundTokenize(jobId: number) {\n if (\n this.#isStopped ||\n this.#isPaused ||\n this.#grammar === undefined ||\n jobId !== this.#backgroundJobId\n ) {\n return;\n }\n\n const t = performance.now();\n const lines = new Map<number, Array<HighlightedToken>>();\n const totalLines = this.#textDocument.lineCount;\n const changedLineRanges = this.#backgroundChangedLineRanges;\n\n let line = this.#lastLine;\n let state = this.#stateStack[line] ?? INITIAL;\n let settled = false;\n let changedRangeIndex = this.#backgroundChangedRangeIndex;\n let currentChangedRangeEnd = changedLineRanges?.[changedRangeIndex]?.[1];\n for (; line < totalLines; ) {\n this.#stateStack[line] = state;\n\n const previousNextState =\n currentChangedRangeEnd !== undefined\n ? this.#stateStack[line + 1]\n : undefined;\n const lineText = this.#textDocument.getLineText(line);\n if (lineText.length > this.#tokenizeMaxLineLength) {\n console.warn(\n `[diffs] Line(${line}) too long to tokenize: ${lineText.length}`\n );\n lines.set(line, [[0, '', lineText]]);\n this.#cacheBracketIgnoredRanges(line, null);\n } else if (lineText === '' || lineText.trim() === '') {\n lines.set(line, [[0, '', lineText]]);\n this.#cacheBracketIgnoredRanges(line, null);\n } else {\n const ret = tokenizeLine(\n this.#grammar,\n this.#colorMap,\n lineText,\n state,\n TOKENIZE_TIME_LIMIT,\n this.#matchBrackets\n );\n lines.set(line, ret.resolvedTokens);\n this.#cacheBracketIgnoredRanges(line, ret.bracketIgnoredRanges);\n state = ret.ruleStack;\n }\n\n this.#stateStack[line + 1] = state;\n settled =\n currentChangedRangeEnd !== undefined &&\n line >= currentChangedRangeEnd &&\n previousNextState !== undefined &&\n state.equals(previousNextState);\n line++;\n if (settled) {\n changedRangeIndex++;\n const nextRange = changedLineRanges?.[changedRangeIndex];\n if (nextRange === undefined) {\n break;\n }\n currentChangedRangeEnd = nextRange[1];\n if (this.#stateStack[nextRange[0]] === undefined) {\n settled = false;\n } else {\n line = nextRange[0];\n state = this.#stateStack[line] ?? state;\n settled = false;\n continue;\n }\n }\n\n // limit the time of partial tokenize to 1ms\n if (performance.now() - t > 1) {\n break;\n }\n }\n\n this.#onDeferTokenize(lines, this.#themeType);\n if (this.#isStopped || this.#isPaused || jobId !== this.#backgroundJobId) {\n return;\n }\n\n if (settled || line >= totalLines) {\n this.stopBackgroundTokenize();\n return;\n }\n\n this.#lastLine = line;\n this.#backgroundChangedRangeIndex = changedRangeIndex;\n this.#postTokenizeMessage(jobId);\n }\n}\n\nfunction tokenizeLine(\n grammar: IGrammar,\n colorMap: string[],\n lineText: string,\n stateStack: StateStack,\n timeLimit?: number,\n collectBracketIgnoredRanges = true\n): {\n ruleStack: StateStack;\n resolvedTokens: Array<HighlightedToken>;\n bracketIgnoredRanges: [number, number][];\n} {\n const result = grammar.tokenizeLine2(lineText, stateStack, timeLimit);\n if (result.stoppedEarly) {\n console.warn(\n `[diffs] Time limit reached when tokenizing line: ${lineText.substring(0, 100)}`\n );\n }\n const rawTokens = result.tokens;\n const tokensLength = rawTokens.length / 2;\n const resolvedTokens: Array<HighlightedToken> = [];\n const bracketIgnoredRanges: [number, number][] = [];\n for (let j = 0; j < tokensLength; j++) {\n const offset = rawTokens[2 * j];\n const nextOffset =\n j + 1 < tokensLength ? rawTokens[2 * j + 2] : lineText.length;\n if (offset === nextOffset) {\n // should never reach here, skip if happens anyway\n continue;\n }\n const metadata = rawTokens[2 * j + 1];\n const fg = EncodedTokenMetadata.getForeground(metadata);\n const tokenText = lineText.slice(offset, nextOffset);\n resolvedTokens.push([offset, colorMap[fg], tokenText]);\n if (\n collectBracketIgnoredRanges &&\n EncodedTokenMetadata.getTokenType(metadata) > 0\n ) {\n bracketIgnoredRanges.push([offset, nextOffset]);\n }\n }\n return {\n ruleStack: result.ruleStack,\n resolvedTokens,\n bracketIgnoredRanges,\n };\n}\n\nexport function renderLineTokens(\n tokens: Array<HighlightedToken>,\n themeType: 'light' | 'dark'\n): (HTMLElement | string)[] {\n return tokens.map(([char, fg, textContent]) => {\n if (char === 0 && fg === '') {\n if (textContent === '') {\n return h('br');\n }\n return textContent;\n }\n return h('span', {\n dataset: {\n char: char.toString(),\n },\n style: `--diffs-token-${themeType}:${fg};`,\n textContent: textContent,\n });\n });\n}\n\n// Shiki special-cases `text` and `ansi` in codeToHast but does not expose grammars.\nfunction isGrammarlessLanguage(languageId: string): boolean {\n return languageId === 'text' || languageId === 'ansi';\n}\n"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { AnnotationLineMap, AnnotationSide, AnnotationSpan, AppliedThemeStyleCache, BaseCodeOptions, BaseDiffOptions, BaseDiffOptionsWithDefaults, BundledLanguage, ChangeContent, ChangeTypes, CodeColumnType, CodeToHastOptions, CodeViewDiffItem, CodeViewFileItem, CodeViewItem, CodeViewItemScrollTarget, CodeViewLayout, CodeViewLineScrollTarget, CodeViewPositionScrollTarget, CodeViewRangeScrollTarget, CodeViewScrollBehavior, CodeViewScrollTarget, ConflictResolverTypes, ContextContent, CreatePatchOptionsNonabortable, CustomPreProperties, DecorationItem, DiffAcceptRejectHunkConfig, DiffAcceptRejectHunkType, DiffFileInput, DiffIndicators, DiffLineAnnotation, DiffLineEventBaseProps, DiffTokenEventBaseProps, DiffsBaseComponent, DiffsComponentOptions, DiffsEditableComponent, DiffsEditor, DiffsEditorSelection, DiffsHighlighter, DiffsTextDocument, DiffsThemeNames, ExpansionDirections, ExtensionFormatMap, FileContents, FileDiffContentsLoader, FileDiffLoadedChangedFiles, FileDiffLoadedFiles, FileDiffLoadedPureRenamedFile, FileDiffMetadata, FileHeaderRenderMode, ForceDiffPlainTextOptions, ForceFilePlainTextOptions, GapSpan, HighlightedToken, HighlighterTypes, Hunk, HunkData, HunkExpansionRegion, HunkLineType, HunkSeparators, LanguageRegistration, LineAnnotation, LineDiffTypes, LineEventBaseProps, LineInfo, LineSpans, LineTypes, MaybeDiffFileInput, MergeConflictActionPayload, MergeConflictMarkerRow, MergeConflictMarkerRowType, MergeConflictRegion, MergeConflictResolution, NumericScrollLineAnchor, ObservedAnnotationNodes, ObservedGridNodes, ParsedPatch, PendingCodeViewLayoutReset, PostRenderPhase, PrePropertiesConfig, ProcessFileConflictData, RenderDiffFilesResult, RenderDiffOptions, RenderDiffResult, RenderFileMetadata, RenderFileOptions, RenderFileResult, RenderHeaderFilenameSuffixCallback, RenderHeaderMetadataCallback, RenderHeaderPrefixCallback, RenderRange, RenderWindow, RenderedDiffASTCache, RenderedFileASTCache, SelectedLineRange, SelectionPoint, SelectionSide, SharedRenderState, ShikiTransformer, SmoothScrollSettings, StickySpecs, SupportedLanguages, ThemeRegistration, ThemeRegistrationResolved, ThemeTypes, ThemedDiffResult, ThemedFileResult, ThemedToken, ThemesType, TokenEventBase, VirtualFileMetrics, VirtualWindowSpecs } from "./types.js";
1
+ import { AnnotationLineMap, AnnotationSide, AnnotationSpan, AppliedThemeStyleCache, BaseCodeOptions, BaseDiffOptions, BaseDiffOptionsWithDefaults, BundledLanguage, ChangeContent, ChangeTypes, CodeColumnType, CodeToHastOptions, CodeViewCreateEditorOptions, CodeViewDiffItem, CodeViewFileItem, CodeViewItem, CodeViewItemScrollTarget, CodeViewLayout, CodeViewLineScrollTarget, CodeViewPositionScrollTarget, CodeViewRangeScrollTarget, CodeViewScrollBehavior, CodeViewScrollTarget, ConflictResolverTypes, ContextContent, CreatePatchOptionsNonabortable, CustomPreProperties, DecorationItem, DiffAcceptRejectHunkConfig, DiffAcceptRejectHunkType, DiffFileInput, DiffIndicators, DiffLineAnnotation, DiffLineEventBaseProps, DiffTokenEventBaseProps, DiffsBaseComponent, DiffsComponentOptions, DiffsEditableComponent, DiffsEditor, DiffsEditorHost, DiffsEditorSelection, DiffsHighlighter, DiffsTextDocument, DiffsThemeNames, ExpansionDirections, ExtensionFormatMap, FileContents, FileDiffContentsLoader, FileDiffLoadedChangedFiles, FileDiffLoadedFiles, FileDiffLoadedPureRenamedFile, FileDiffMetadata, FileHeaderRenderMode, ForceDiffPlainTextOptions, ForceFilePlainTextOptions, GapSpan, HighlightedToken, HighlighterTypes, Hunk, HunkData, HunkExpansionRegion, HunkLineType, HunkSeparators, LanguageRegistration, LineAnnotation, LineDiffTypes, LineEventBaseProps, LineInfo, LineSpans, LineTypes, MaybeDiffFileInput, MergeConflictActionPayload, MergeConflictMarkerRow, MergeConflictMarkerRowType, MergeConflictRegion, MergeConflictResolution, NumericScrollLineAnchor, ObservedAnnotationNodes, ObservedGridNodes, ParsedPatch, PendingCodeViewLayoutReset, PostRenderPhase, PrePropertiesConfig, ProcessFileConflictData, RenderDiffFilesResult, RenderDiffOptions, RenderDiffResult, RenderFileMetadata, RenderFileOptions, RenderFileResult, RenderHeaderFilenameSuffixCallback, RenderHeaderMetadataCallback, RenderHeaderPrefixCallback, RenderRange, RenderWindow, RenderedDiffASTCache, RenderedFileASTCache, SelectedLineRange, SelectionPoint, SelectionSide, SharedRenderState, ShikiTransformer, SmoothScrollSettings, StickySpecs, SupportedLanguages, ThemeRegistration, ThemeRegistrationResolved, ThemeTypes, ThemedDiffResult, ThemedFileResult, ThemedToken, ThemesType, TokenEventBase, VirtualFileMetrics, VirtualWindowSpecs } from "./types.js";
2
2
  import { GetHoveredLineResult, GetLineIndexUtility, InteractionManager, InteractionManagerBaseOptions, InteractionManagerMode, InteractionManagerOptions, LogTypes, MergeConflictActionTarget, OnDiffLineClickProps, OnDiffLineEnterLeaveProps, OnLineClickProps, OnLineEnterLeaveProps, OnTokenEventProps, SelectionWriteOptions, pluckInteractionOptions } from "./managers/InteractionManager.js";
3
- import { ResizeManager } from "./managers/ResizeManager.js";
3
+ import { ResizeManager, ResizeManagerColumnVariableMode, ResizeManagerSetupOptions } from "./managers/ResizeManager.js";
4
4
  import { FileRenderResult, FileRenderer, FileRendererOptions } from "./renderers/FileRenderer.js";
5
5
  import { File, FileHydrateProps, FileOptions, FileRenderProps } from "./components/File.js";
6
6
  import { ScrollSyncManager } from "./managers/ScrollSyncManager.js";
@@ -8,9 +8,9 @@ import { DiffHunksRenderer, DiffHunksRendererOptions, DiffHunksRendererOptionsWi
8
8
  import { FileDiff, FileDiffHydrationProps, FileDiffOptions, FileDiffRenderBaseProps, FileDiffRenderProps, FileDiffType } from "./components/FileDiff.js";
9
9
  import { Virtualizer, VirtualizerConfig } from "./components/Virtualizer.js";
10
10
  import { VirtualizedFile } from "./components/VirtualizedFile.js";
11
- import { VirtualizedFileDiff } from "./components/VirtualizedFileDiff.js";
12
- import { CodeView, CodeViewCoordinator, CodeViewLineSelection, CodeViewOptions, CodeViewRenderedDiffItem, CodeViewRenderedFileItem, CodeViewRenderedItem, CodeViewScrollListener } from "./components/CodeView.js";
13
- import { ALTERNATE_FILE_NAMES_GIT, COMMIT_METADATA_SPLIT, CORE_CSS_ATTRIBUTE, CUSTOM_HEADER_SLOT_ID, DEFAULT_CODE_VIEW_FILE_METRICS, DEFAULT_CODE_VIEW_LAYOUT, DEFAULT_COLLAPSED_CONTEXT_THRESHOLD, DEFAULT_EXPANDED_REGION, DEFAULT_RENDER_RANGE, DEFAULT_SMOOTH_SCROLL_SETTINGS, DEFAULT_THEMES, DEFAULT_TOKENIZE_MAX_LENGTH, DEFAULT_VIRTUAL_FILE_METRICS, DIFFS_DEVELOPMENT_BUILD, DIFFS_SCROLLBAR_GUTTER_MEASURED_PROPERTY, DIFFS_SCROLLBAR_MEASURE_ATTRIBUTE, DIFFS_TAG_NAME, EMPTY_RENDER_RANGE, FILENAME_HEADER_REGEX, FILENAME_HEADER_REGEX_GIT, FILE_CONTEXT_BLOB, GIT_DIFF_FILE_BREAK_REGEX, HEADER_FILENAME_SUFFIX_SLOT_ID, HEADER_METADATA_SLOT_ID, HEADER_PREFIX_SLOT_ID, HUNK_HEADER, INDEX_LINE_METADATA, MERGE_CONFLICT_BASE_MARKER_REGEX, MERGE_CONFLICT_END_MARKER_REGEX, MERGE_CONFLICT_SEPARATOR_MARKER_REGEX, MERGE_CONFLICT_START_MARKER_REGEX, SPLIT_WITH_NEWLINES, THEME_CSS_ATTRIBUTE, UNIFIED_DIFF_FILE_BREAK_REGEX, UNSAFE_CSS_ATTRIBUTE } from "./constants.js";
11
+ import { VIRTUALIZED_FILE_DIFF_LAYOUT_CHECKPOINT_INTERVAL, VirtualizedFileDiff } from "./components/VirtualizedFileDiff.js";
12
+ import { CODE_VIEW_DIFF_OPTION_KEYS, CODE_VIEW_FILE_OPTION_KEYS, CodeView, CodeViewCoordinator, CodeViewLineSelection, CodeViewOptions, CodeViewRenderedDiffItem, CodeViewRenderedFileItem, CodeViewRenderedItem, CodeViewScrollListener, CodeViewSlotSnapshot } from "./components/CodeView.js";
13
+ import { ALTERNATE_FILE_NAMES_GIT, CODE_VIEW_FOOTER_ATTRIBUTE, CODE_VIEW_HEADER_ATTRIBUTE, COMMIT_METADATA_SPLIT, CORE_CSS_ATTRIBUTE, CUSTOM_HEADER_SLOT_ID, DEFAULT_CODE_VIEW_FILE_METRICS, DEFAULT_CODE_VIEW_LAYOUT, DEFAULT_COLLAPSED_CONTEXT_THRESHOLD, DEFAULT_EXPANDED_REGION, DEFAULT_RENDER_RANGE, DEFAULT_SMOOTH_SCROLL_SETTINGS, DEFAULT_THEMES, DEFAULT_TOKENIZE_MAX_LENGTH, DEFAULT_VIRTUAL_FILE_METRICS, DIFFS_DEVELOPMENT_BUILD, DIFFS_SCROLLBAR_GUTTER_MEASURED_PROPERTY, DIFFS_SCROLLBAR_MEASURE_ATTRIBUTE, DIFFS_TAG_NAME, EMPTY_RENDER_RANGE, FILENAME_HEADER_REGEX, FILENAME_HEADER_REGEX_GIT, FILE_CONTEXT_BLOB, GIT_DIFF_FILE_BREAK_REGEX, HEADER_FILENAME_SUFFIX_SLOT_ID, HEADER_METADATA_SLOT_ID, HEADER_PREFIX_SLOT_ID, HUNK_HEADER, INDEX_LINE_METADATA, MERGE_CONFLICT_BASE_MARKER_REGEX, MERGE_CONFLICT_END_MARKER_REGEX, MERGE_CONFLICT_SEPARATOR_MARKER_REGEX, MERGE_CONFLICT_START_MARKER_REGEX, SPLIT_WITH_NEWLINES, THEME_CSS_ATTRIBUTE, UNIFIED_DIFF_FILE_BREAK_REGEX, UNSAFE_CSS_ATTRIBUTE } from "./constants.js";
14
14
  import { CodeToTokenTransformStreamOptions, RecallToken, ShikiStreamTokenizerEnqueueResult, ShikiStreamTokenizerOptions } from "./shiki-stream/types.js";
15
15
  import { ShikiStreamTokenizer } from "./shiki-stream/tokenizer.js";
16
16
  import { CodeToTokenTransformStream } from "./shiki-stream/stream.js";
@@ -38,7 +38,7 @@ import { registerCustomCSSVariableTheme } from "./highlighter/themes/registerCus
38
38
  import { CustomThemeLoader, registerCustomTheme } from "./highlighter/themes/registerCustomTheme.js";
39
39
  import { resolveTheme } from "./highlighter/themes/resolveTheme.js";
40
40
  import { resolveThemes } from "./highlighter/themes/resolveThemes.js";
41
- import { dequeueRender, queueRender } from "./managers/UniversalRenderingManager.js";
41
+ import { clearRenderQueue, dequeueRender, queueRender } from "./managers/UniversalRenderingManager.js";
42
42
  import { SVGSpriteNames, SVGSpriteSheet } from "./sprite.js";
43
43
  import { areDiffLineAnnotationsEqual } from "./utils/areDiffLineAnnotationsEqual.js";
44
44
  import { areDiffRenderOptionsEqual } from "./utils/areDiffRenderOptionsEqual.js";
@@ -107,4 +107,4 @@ import { setLanguageOverride } from "./utils/setLanguageOverride.js";
107
107
  import { setPreNodeProperties } from "./utils/setWrapperNodeProps.js";
108
108
  import { trimPatchContext } from "./utils/trimPatchContext.js";
109
109
  import { codeToHtml, createCssVariablesTheme as createCSSVariablesTheme } from "shiki";
110
- export { ALTERNATE_FILE_NAMES_GIT, type AnnotationLineMap, type AnnotationSide, type AnnotationSpan, type AppliedThemeStyleCache, AttachedLanguages, AttachedThemes, type BaseCodeOptions, type BaseDiffOptions, type BaseDiffOptionsWithDefaults, type BundledLanguage, COMMIT_METADATA_SPLIT, CORE_CSS_ATTRIBUTE, CUSTOM_HEADER_SLOT_ID, type ChangeContent, type ChangeTypes, type CodeColumnType, type CodeToHastOptions, CodeToTokenTransformStream, CodeToTokenTransformStreamOptions, CodeView, CodeViewCoordinator, type CodeViewDiffItem, type CodeViewFileItem, type CodeViewItem, type CodeViewItemScrollTarget, type CodeViewLayout, type CodeViewLineScrollTarget, CodeViewLineSelection, CodeViewOptions, type CodeViewPositionScrollTarget, type CodeViewRangeScrollTarget, CodeViewRenderedDiffItem, CodeViewRenderedFileItem, CodeViewRenderedItem, type CodeViewScrollBehavior, CodeViewScrollListener, type CodeViewScrollTarget, type ConflictResolverTypes, type ContextContent, CreateFileHeaderElementProps, type CreatePatchOptionsNonabortable, type CustomPreProperties, CustomThemeLoader, DEFAULT_CODE_VIEW_FILE_METRICS, DEFAULT_CODE_VIEW_LAYOUT, DEFAULT_COLLAPSED_CONTEXT_THRESHOLD, DEFAULT_EXPANDED_REGION, DEFAULT_RENDER_RANGE, DEFAULT_SMOOTH_SCROLL_SETTINGS, DEFAULT_THEMES, DEFAULT_TOKENIZE_MAX_LENGTH, DEFAULT_VIRTUAL_FILE_METRICS, DIFFS_DEVELOPMENT_BUILD, DIFFS_SCROLLBAR_GUTTER_MEASURED_PROPERTY, DIFFS_SCROLLBAR_MEASURE_ATTRIBUTE, DIFFS_TAG_NAME, type DecorationItem, type DiffAcceptRejectHunkConfig, type DiffAcceptRejectHunkType, type DiffFileInput, DiffHunksRenderer, DiffHunksRendererOptions, DiffHunksRendererOptionsWithDefaults, type DiffIndicators, type DiffLineAnnotation, type DiffLineEventBaseProps, type DiffTokenEventBaseProps, type DiffsBaseComponent, type DiffsComponentOptions, type DiffsEditableComponent, type DiffsEditor, type DiffsEditorSelection, type DiffsHighlighter, type DiffsTextDocument, type DiffsThemeNames, EMPTY_RENDER_RANGE, EXTENSION_TO_FILE_FORMAT, type ExpansionDirections, type ExtensionFormatMap, FILENAME_HEADER_REGEX, FILENAME_HEADER_REGEX_GIT, FILE_CONTEXT_BLOB, File, type FileContents, FileDiff, type FileDiffContentsLoader, FileDiffHydrationProps, type FileDiffLoadedChangedFiles, type FileDiffLoadedFiles, type FileDiffLoadedPureRenamedFile, type FileDiffMetadata, FileDiffOptions, FileDiffRenderBaseProps, FileDiffRenderProps, FileDiffType, type FileHeaderRenderMode, FileHydrateProps, FileOptions, FileRenderProps, FileRenderResult, FileRenderer, FileRendererOptions, FileStream, FileStreamOptions, type ForceDiffPlainTextOptions, type ForceFilePlainTextOptions, GIT_DIFF_FILE_BREAK_REGEX, type GapSpan, GetHoveredLineResult, GetLineIndexUtility, HEADER_FILENAME_SUFFIX_SLOT_ID, HEADER_METADATA_SLOT_ID, HEADER_PREFIX_SLOT_ID, HUNK_HEADER, type HighlightedToken, type HighlighterTypes, type Hunk, type HunkData, type HunkExpansionRegion, type HunkLineType, type HunkSeparators, HunksRenderResult, INDEX_LINE_METADATA, InjectedRow, InteractionManager, InteractionManagerBaseOptions, InteractionManagerMode, InteractionManagerOptions, type LanguageRegistration, type LineAnnotation, LineDecoration, type LineDiffTypes, type LineEventBaseProps, type LineInfo, type LineSpans, type LineTypes, LogTypes, MERGE_CONFLICT_BASE_MARKER_REGEX, MERGE_CONFLICT_END_MARKER_REGEX, MERGE_CONFLICT_SEPARATOR_MARKER_REGEX, MERGE_CONFLICT_START_MARKER_REGEX, type MaybeDiffFileInput, type MergeConflictActionPayload, MergeConflictActionTarget, MergeConflictActionsTypeOption, type MergeConflictMarkerRow, type MergeConflictMarkerRowType, type MergeConflictRegion, type MergeConflictResolution, type NumericScrollLineAnchor, type ObservedAnnotationNodes, type ObservedGridNodes, OnDiffLineClickProps, OnDiffLineEnterLeaveProps, OnLineClickProps, OnLineEnterLeaveProps, OnTokenEventProps, ParsedLine, type ParsedPatch, type PendingCodeViewLayoutReset, type PostRenderPhase, type PrePropertiesConfig, type ProcessFileConflictData, RecallToken, RegisteredCustomLanguages, type RenderDiffFilesResult, type RenderDiffOptions, type RenderDiffResult, type RenderFileMetadata, type RenderFileOptions, type RenderFileResult, type RenderHeaderFilenameSuffixCallback, type RenderHeaderMetadataCallback, type RenderHeaderPrefixCallback, RenderMergeConflictActions, type RenderRange, type RenderWindow, type RenderedDiffASTCache, type RenderedFileASTCache, RenderedLineContext, ResizeManager, ResolvedLanguages, ResolvingLanguages, SPLIT_WITH_NEWLINES, SVGSpriteNames, SVGSpriteSheet, ScrollSyncManager, type SelectedLineRange, type SelectionPoint, type SelectionSide, SelectionWriteOptions, type SharedRenderState, ShikiStreamTokenizer, ShikiStreamTokenizerEnqueueResult, ShikiStreamTokenizerOptions, type ShikiTransformer, type SmoothScrollSettings, SplitInjectedRow, SplitInjectedRowPlacement, SplitLineDecorationProps, type StickySpecs, type SupportedLanguages, THEME_CSS_ATTRIBUTE, type ThemeRegistration, type ThemeRegistrationResolved, type ThemeTypes, type ThemedDiffResult, type ThemedFileResult, type ThemedToken, type ThemesType, type TokenEventBase, UNIFIED_DIFF_FILE_BREAK_REGEX, UNSAFE_CSS_ATTRIBUTE, UnifiedInjectedRowPlacement, UnifiedLineDecorationProps, UnresolvedFile, UnresolvedFileHydrationProps, UnresolvedFileOptions, UnresolvedFileRenderProps, type VirtualFileMetrics, type VirtualWindowSpecs, VirtualizedFile, VirtualizedFileDiff, Virtualizer, VirtualizerConfig, areDiffLineAnnotationsEqual, areDiffRenderOptionsEqual, areDiffTargetsEqual, areFileRenderOptionsEqual, areFilesEqual, areHunkDataEqual, areLanguagesAttached, areLineAnnotationsEqual, areObjectsEqual, areOptionsEqual, arePrePropertiesEqual, areRenderRangesEqual, areSelectionsEqual, areThemesAttached, areThemesEqual, areVirtualWindowSpecsEqual, areWorkerStatsEqual, attachResolvedLanguages, attachResolvedThemes, cleanLastNewline, cleanUpResolvedLanguages, cleanUpResolvedThemes, cloneFileDiffMetadata, codeToHtml, createAnnotationElement, createAnnotationWrapperNode, createCSSVariablesTheme, createDiffSpanDecoration, createEmptyRowBuffer, createFileHeaderElement, createGutterGap, createGutterItem, createGutterUtilityContentNode, createGutterUtilityElement, createGutterWrapper, createHastElement, createIconElement, createNoNewlineElement, createPreElement, createPreWrapperProperties, createRowNodes, createSeparator, createSpanFromToken, createStyleElement, createTextNodeElement, createThemeStyleElement, createTransformerWithState, createUnsafeCSSStyleNode, createWindowFromScrollPosition, dequeueRender, detachString, diffAcceptRejectHunk, disposeHighlighter, findCodeElement, formatCSSVariablePrefix, getCustomExtensionsMap, getCustomExtensionsVersion, getFiletypeFromFileName, getHighlighterIfLoaded, getHighlighterOptions, getHighlighterThemeStyles, getHunkSeparatorSlotName, getIconForType, getLineAnnotationName, getLineEndingType, getLineNodes, getOrCreateCodeNode, getResolvedLanguages, getResolvedOrResolveLanguage, getResolvedOrResolveTheme, getResolvedThemes, getSharedHighlighter, getSingularPatch, getThemes, getTotalLineCountFromHunks, getUnresolvedDiffHunksRendererOptions, hasResolvedLanguages, hasResolvedThemes, hydratePartialDiff, isDefaultRenderRange, isHighlighterLoaded, isHighlighterLoading, isHighlighterNull, isWorkerContext, parseDiffFromFile, parseLineType, parsePatchFiles, patchScrollbarGutterSize, pluckInteractionOptions, prefersReducedMotion, preloadHighlighter, prerenderHTMLIfNecessary, processFile, processLine, processPatch, pushOrJoinSpan, queueRender, registerCustomCSSVariableTheme, registerCustomLanguage, registerCustomTheme, releaseStringDetachBuffer, renderDiffWithHighlighter, renderFileWithHighlighter, replaceCustomExtensions, resolveConflict, resolveLanguage, resolveLanguages, resolveRegion, resolveTheme, resolveThemes, setCustomExtension, setLanguageOverride, setPreNodeProperties, trimPatchContext, wrapCoreCSS, wrapThemeCSS, wrapUnsafeCSS };
110
+ export { ALTERNATE_FILE_NAMES_GIT, type AnnotationLineMap, type AnnotationSide, type AnnotationSpan, type AppliedThemeStyleCache, AttachedLanguages, AttachedThemes, type BaseCodeOptions, type BaseDiffOptions, type BaseDiffOptionsWithDefaults, type BundledLanguage, CODE_VIEW_DIFF_OPTION_KEYS, CODE_VIEW_FILE_OPTION_KEYS, CODE_VIEW_FOOTER_ATTRIBUTE, CODE_VIEW_HEADER_ATTRIBUTE, COMMIT_METADATA_SPLIT, CORE_CSS_ATTRIBUTE, CUSTOM_HEADER_SLOT_ID, type ChangeContent, type ChangeTypes, type CodeColumnType, type CodeToHastOptions, CodeToTokenTransformStream, CodeToTokenTransformStreamOptions, CodeView, CodeViewCoordinator, type CodeViewCreateEditorOptions, type CodeViewDiffItem, type CodeViewFileItem, type CodeViewItem, type CodeViewItemScrollTarget, type CodeViewLayout, type CodeViewLineScrollTarget, CodeViewLineSelection, CodeViewOptions, type CodeViewPositionScrollTarget, type CodeViewRangeScrollTarget, CodeViewRenderedDiffItem, CodeViewRenderedFileItem, CodeViewRenderedItem, type CodeViewScrollBehavior, CodeViewScrollListener, type CodeViewScrollTarget, CodeViewSlotSnapshot, type ConflictResolverTypes, type ContextContent, CreateFileHeaderElementProps, type CreatePatchOptionsNonabortable, type CustomPreProperties, CustomThemeLoader, DEFAULT_CODE_VIEW_FILE_METRICS, DEFAULT_CODE_VIEW_LAYOUT, DEFAULT_COLLAPSED_CONTEXT_THRESHOLD, DEFAULT_EXPANDED_REGION, DEFAULT_RENDER_RANGE, DEFAULT_SMOOTH_SCROLL_SETTINGS, DEFAULT_THEMES, DEFAULT_TOKENIZE_MAX_LENGTH, DEFAULT_VIRTUAL_FILE_METRICS, DIFFS_DEVELOPMENT_BUILD, DIFFS_SCROLLBAR_GUTTER_MEASURED_PROPERTY, DIFFS_SCROLLBAR_MEASURE_ATTRIBUTE, DIFFS_TAG_NAME, type DecorationItem, type DiffAcceptRejectHunkConfig, type DiffAcceptRejectHunkType, type DiffFileInput, DiffHunksRenderer, DiffHunksRendererOptions, DiffHunksRendererOptionsWithDefaults, type DiffIndicators, type DiffLineAnnotation, type DiffLineEventBaseProps, type DiffTokenEventBaseProps, type DiffsBaseComponent, type DiffsComponentOptions, type DiffsEditableComponent, type DiffsEditor, type DiffsEditorHost, type DiffsEditorSelection, type DiffsHighlighter, type DiffsTextDocument, type DiffsThemeNames, EMPTY_RENDER_RANGE, EXTENSION_TO_FILE_FORMAT, type ExpansionDirections, type ExtensionFormatMap, FILENAME_HEADER_REGEX, FILENAME_HEADER_REGEX_GIT, FILE_CONTEXT_BLOB, File, type FileContents, FileDiff, type FileDiffContentsLoader, FileDiffHydrationProps, type FileDiffLoadedChangedFiles, type FileDiffLoadedFiles, type FileDiffLoadedPureRenamedFile, type FileDiffMetadata, FileDiffOptions, FileDiffRenderBaseProps, FileDiffRenderProps, FileDiffType, type FileHeaderRenderMode, FileHydrateProps, FileOptions, FileRenderProps, FileRenderResult, FileRenderer, FileRendererOptions, FileStream, FileStreamOptions, type ForceDiffPlainTextOptions, type ForceFilePlainTextOptions, GIT_DIFF_FILE_BREAK_REGEX, type GapSpan, GetHoveredLineResult, GetLineIndexUtility, HEADER_FILENAME_SUFFIX_SLOT_ID, HEADER_METADATA_SLOT_ID, HEADER_PREFIX_SLOT_ID, HUNK_HEADER, type HighlightedToken, type HighlighterTypes, type Hunk, type HunkData, type HunkExpansionRegion, type HunkLineType, type HunkSeparators, HunksRenderResult, INDEX_LINE_METADATA, InjectedRow, InteractionManager, InteractionManagerBaseOptions, InteractionManagerMode, InteractionManagerOptions, type LanguageRegistration, type LineAnnotation, LineDecoration, type LineDiffTypes, type LineEventBaseProps, type LineInfo, type LineSpans, type LineTypes, LogTypes, MERGE_CONFLICT_BASE_MARKER_REGEX, MERGE_CONFLICT_END_MARKER_REGEX, MERGE_CONFLICT_SEPARATOR_MARKER_REGEX, MERGE_CONFLICT_START_MARKER_REGEX, type MaybeDiffFileInput, type MergeConflictActionPayload, MergeConflictActionTarget, MergeConflictActionsTypeOption, type MergeConflictMarkerRow, type MergeConflictMarkerRowType, type MergeConflictRegion, type MergeConflictResolution, type NumericScrollLineAnchor, type ObservedAnnotationNodes, type ObservedGridNodes, OnDiffLineClickProps, OnDiffLineEnterLeaveProps, OnLineClickProps, OnLineEnterLeaveProps, OnTokenEventProps, ParsedLine, type ParsedPatch, type PendingCodeViewLayoutReset, type PostRenderPhase, type PrePropertiesConfig, type ProcessFileConflictData, RecallToken, RegisteredCustomLanguages, type RenderDiffFilesResult, type RenderDiffOptions, type RenderDiffResult, type RenderFileMetadata, type RenderFileOptions, type RenderFileResult, type RenderHeaderFilenameSuffixCallback, type RenderHeaderMetadataCallback, type RenderHeaderPrefixCallback, RenderMergeConflictActions, type RenderRange, type RenderWindow, type RenderedDiffASTCache, type RenderedFileASTCache, RenderedLineContext, ResizeManager, ResizeManagerColumnVariableMode, ResizeManagerSetupOptions, ResolvedLanguages, ResolvingLanguages, SPLIT_WITH_NEWLINES, SVGSpriteNames, SVGSpriteSheet, ScrollSyncManager, type SelectedLineRange, type SelectionPoint, type SelectionSide, SelectionWriteOptions, type SharedRenderState, ShikiStreamTokenizer, ShikiStreamTokenizerEnqueueResult, ShikiStreamTokenizerOptions, type ShikiTransformer, type SmoothScrollSettings, SplitInjectedRow, SplitInjectedRowPlacement, SplitLineDecorationProps, type StickySpecs, type SupportedLanguages, THEME_CSS_ATTRIBUTE, type ThemeRegistration, type ThemeRegistrationResolved, type ThemeTypes, type ThemedDiffResult, type ThemedFileResult, type ThemedToken, type ThemesType, type TokenEventBase, UNIFIED_DIFF_FILE_BREAK_REGEX, UNSAFE_CSS_ATTRIBUTE, UnifiedInjectedRowPlacement, UnifiedLineDecorationProps, UnresolvedFile, UnresolvedFileHydrationProps, UnresolvedFileOptions, UnresolvedFileRenderProps, VIRTUALIZED_FILE_DIFF_LAYOUT_CHECKPOINT_INTERVAL, type VirtualFileMetrics, type VirtualWindowSpecs, VirtualizedFile, VirtualizedFileDiff, Virtualizer, VirtualizerConfig, areDiffLineAnnotationsEqual, areDiffRenderOptionsEqual, areDiffTargetsEqual, areFileRenderOptionsEqual, areFilesEqual, areHunkDataEqual, areLanguagesAttached, areLineAnnotationsEqual, areObjectsEqual, areOptionsEqual, arePrePropertiesEqual, areRenderRangesEqual, areSelectionsEqual, areThemesAttached, areThemesEqual, areVirtualWindowSpecsEqual, areWorkerStatsEqual, attachResolvedLanguages, attachResolvedThemes, cleanLastNewline, cleanUpResolvedLanguages, cleanUpResolvedThemes, clearRenderQueue, cloneFileDiffMetadata, codeToHtml, createAnnotationElement, createAnnotationWrapperNode, createCSSVariablesTheme, createDiffSpanDecoration, createEmptyRowBuffer, createFileHeaderElement, createGutterGap, createGutterItem, createGutterUtilityContentNode, createGutterUtilityElement, createGutterWrapper, createHastElement, createIconElement, createNoNewlineElement, createPreElement, createPreWrapperProperties, createRowNodes, createSeparator, createSpanFromToken, createStyleElement, createTextNodeElement, createThemeStyleElement, createTransformerWithState, createUnsafeCSSStyleNode, createWindowFromScrollPosition, dequeueRender, detachString, diffAcceptRejectHunk, disposeHighlighter, findCodeElement, formatCSSVariablePrefix, getCustomExtensionsMap, getCustomExtensionsVersion, getFiletypeFromFileName, getHighlighterIfLoaded, getHighlighterOptions, getHighlighterThemeStyles, getHunkSeparatorSlotName, getIconForType, getLineAnnotationName, getLineEndingType, getLineNodes, getOrCreateCodeNode, getResolvedLanguages, getResolvedOrResolveLanguage, getResolvedOrResolveTheme, getResolvedThemes, getSharedHighlighter, getSingularPatch, getThemes, getTotalLineCountFromHunks, getUnresolvedDiffHunksRendererOptions, hasResolvedLanguages, hasResolvedThemes, hydratePartialDiff, isDefaultRenderRange, isHighlighterLoaded, isHighlighterLoading, isHighlighterNull, isWorkerContext, parseDiffFromFile, parseLineType, parsePatchFiles, patchScrollbarGutterSize, pluckInteractionOptions, prefersReducedMotion, preloadHighlighter, prerenderHTMLIfNecessary, processFile, processLine, processPatch, pushOrJoinSpan, queueRender, registerCustomCSSVariableTheme, registerCustomLanguage, registerCustomTheme, releaseStringDetachBuffer, renderDiffWithHighlighter, renderFileWithHighlighter, replaceCustomExtensions, resolveConflict, resolveLanguage, resolveLanguages, resolveRegion, resolveTheme, resolveThemes, setCustomExtension, setLanguageOverride, setPreNodeProperties, trimPatchContext, wrapCoreCSS, wrapThemeCSS, wrapUnsafeCSS };
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { ALTERNATE_FILE_NAMES_GIT, COMMIT_METADATA_SPLIT, CORE_CSS_ATTRIBUTE, CUSTOM_HEADER_SLOT_ID, DEFAULT_CODE_VIEW_FILE_METRICS, DEFAULT_CODE_VIEW_LAYOUT, DEFAULT_COLLAPSED_CONTEXT_THRESHOLD, DEFAULT_EXPANDED_REGION, DEFAULT_RENDER_RANGE, DEFAULT_SMOOTH_SCROLL_SETTINGS, DEFAULT_THEMES, DEFAULT_TOKENIZE_MAX_LENGTH, DEFAULT_VIRTUAL_FILE_METRICS, DIFFS_DEVELOPMENT_BUILD, DIFFS_SCROLLBAR_GUTTER_MEASURED_PROPERTY, DIFFS_SCROLLBAR_MEASURE_ATTRIBUTE, DIFFS_TAG_NAME, EMPTY_RENDER_RANGE, FILENAME_HEADER_REGEX, FILENAME_HEADER_REGEX_GIT, FILE_CONTEXT_BLOB, GIT_DIFF_FILE_BREAK_REGEX, HEADER_FILENAME_SUFFIX_SLOT_ID, HEADER_METADATA_SLOT_ID, HEADER_PREFIX_SLOT_ID, HUNK_HEADER, INDEX_LINE_METADATA, MERGE_CONFLICT_BASE_MARKER_REGEX, MERGE_CONFLICT_END_MARKER_REGEX, MERGE_CONFLICT_SEPARATOR_MARKER_REGEX, MERGE_CONFLICT_START_MARKER_REGEX, SPLIT_WITH_NEWLINES, THEME_CSS_ATTRIBUTE, UNIFIED_DIFF_FILE_BREAK_REGEX, UNSAFE_CSS_ATTRIBUTE } from "./constants.js";
2
- import { dequeueRender, queueRender } from "./managers/UniversalRenderingManager.js";
1
+ import { ALTERNATE_FILE_NAMES_GIT, CODE_VIEW_FOOTER_ATTRIBUTE, CODE_VIEW_HEADER_ATTRIBUTE, COMMIT_METADATA_SPLIT, CORE_CSS_ATTRIBUTE, CUSTOM_HEADER_SLOT_ID, DEFAULT_CODE_VIEW_FILE_METRICS, DEFAULT_CODE_VIEW_LAYOUT, DEFAULT_COLLAPSED_CONTEXT_THRESHOLD, DEFAULT_EXPANDED_REGION, DEFAULT_RENDER_RANGE, DEFAULT_SMOOTH_SCROLL_SETTINGS, DEFAULT_THEMES, DEFAULT_TOKENIZE_MAX_LENGTH, DEFAULT_VIRTUAL_FILE_METRICS, DIFFS_DEVELOPMENT_BUILD, DIFFS_SCROLLBAR_GUTTER_MEASURED_PROPERTY, DIFFS_SCROLLBAR_MEASURE_ATTRIBUTE, DIFFS_TAG_NAME, EMPTY_RENDER_RANGE, FILENAME_HEADER_REGEX, FILENAME_HEADER_REGEX_GIT, FILE_CONTEXT_BLOB, GIT_DIFF_FILE_BREAK_REGEX, HEADER_FILENAME_SUFFIX_SLOT_ID, HEADER_METADATA_SLOT_ID, HEADER_PREFIX_SLOT_ID, HUNK_HEADER, INDEX_LINE_METADATA, MERGE_CONFLICT_BASE_MARKER_REGEX, MERGE_CONFLICT_END_MARKER_REGEX, MERGE_CONFLICT_SEPARATOR_MARKER_REGEX, MERGE_CONFLICT_START_MARKER_REGEX, SPLIT_WITH_NEWLINES, THEME_CSS_ATTRIBUTE, UNIFIED_DIFF_FILE_BREAK_REGEX, UNSAFE_CSS_ATTRIBUTE } from "./constants.js";
2
+ import { clearRenderQueue, dequeueRender, queueRender } from "./managers/UniversalRenderingManager.js";
3
3
  import { areObjectsEqual } from "./utils/areObjectsEqual.js";
4
4
  import { areThemesEqual } from "./utils/areThemesEqual.js";
5
5
  import { areOptionsEqual } from "./utils/areOptionsEqual.js";
@@ -76,8 +76,8 @@ import { DiffHunksRenderer } from "./renderers/DiffHunksRenderer.js";
76
76
  import { areDiffLineAnnotationsEqual } from "./utils/areDiffLineAnnotationsEqual.js";
77
77
  import { areHunkDataEqual } from "./utils/areHunkDataEqual.js";
78
78
  import { FileDiff } from "./components/FileDiff.js";
79
- import { VirtualizedFileDiff } from "./components/VirtualizedFileDiff.js";
80
- import { CodeView } from "./components/CodeView.js";
79
+ import { VIRTUALIZED_FILE_DIFF_LAYOUT_CHECKPOINT_INTERVAL, VirtualizedFileDiff } from "./components/VirtualizedFileDiff.js";
80
+ import { CODE_VIEW_DIFF_OPTION_KEYS, CODE_VIEW_FILE_OPTION_KEYS, CodeView } from "./components/CodeView.js";
81
81
  import { ShikiStreamTokenizer } from "./shiki-stream/tokenizer.js";
82
82
  import { CodeToTokenTransformStream } from "./shiki-stream/stream.js";
83
83
  import { createSpanFromToken } from "./utils/createSpanNodeFromToken.js";
@@ -105,4 +105,4 @@ import { parseLineType } from "./utils/parseLineType.js";
105
105
  import { setLanguageOverride } from "./utils/setLanguageOverride.js";
106
106
  import { trimPatchContext } from "./utils/trimPatchContext.js";
107
107
  import { codeToHtml, createCssVariablesTheme as createCSSVariablesTheme } from "shiki";
108
- export { ALTERNATE_FILE_NAMES_GIT, AttachedLanguages, AttachedThemes, COMMIT_METADATA_SPLIT, CORE_CSS_ATTRIBUTE, CUSTOM_HEADER_SLOT_ID, CodeToTokenTransformStream, CodeView, DEFAULT_CODE_VIEW_FILE_METRICS, DEFAULT_CODE_VIEW_LAYOUT, DEFAULT_COLLAPSED_CONTEXT_THRESHOLD, DEFAULT_EXPANDED_REGION, DEFAULT_RENDER_RANGE, DEFAULT_SMOOTH_SCROLL_SETTINGS, DEFAULT_THEMES, DEFAULT_TOKENIZE_MAX_LENGTH, DEFAULT_VIRTUAL_FILE_METRICS, DIFFS_DEVELOPMENT_BUILD, DIFFS_SCROLLBAR_GUTTER_MEASURED_PROPERTY, DIFFS_SCROLLBAR_MEASURE_ATTRIBUTE, DIFFS_TAG_NAME, DiffHunksRenderer, EMPTY_RENDER_RANGE, EXTENSION_TO_FILE_FORMAT, FILENAME_HEADER_REGEX, FILENAME_HEADER_REGEX_GIT, FILE_CONTEXT_BLOB, File, FileDiff, FileRenderer, FileStream, GIT_DIFF_FILE_BREAK_REGEX, HEADER_FILENAME_SUFFIX_SLOT_ID, HEADER_METADATA_SLOT_ID, HEADER_PREFIX_SLOT_ID, HUNK_HEADER, INDEX_LINE_METADATA, InteractionManager, MERGE_CONFLICT_BASE_MARKER_REGEX, MERGE_CONFLICT_END_MARKER_REGEX, MERGE_CONFLICT_SEPARATOR_MARKER_REGEX, MERGE_CONFLICT_START_MARKER_REGEX, RegisteredCustomLanguages, ResizeManager, ResolvedLanguages, ResolvingLanguages, SPLIT_WITH_NEWLINES, SVGSpriteSheet, ScrollSyncManager, ShikiStreamTokenizer, THEME_CSS_ATTRIBUTE, UNIFIED_DIFF_FILE_BREAK_REGEX, UNSAFE_CSS_ATTRIBUTE, UnresolvedFile, VirtualizedFile, VirtualizedFileDiff, Virtualizer, areDiffLineAnnotationsEqual, areDiffRenderOptionsEqual, areDiffTargetsEqual, areFileRenderOptionsEqual, areFilesEqual, areHunkDataEqual, areLanguagesAttached, areLineAnnotationsEqual, areObjectsEqual, areOptionsEqual, arePrePropertiesEqual, areRenderRangesEqual, areSelectionsEqual, areThemesAttached, areThemesEqual, areVirtualWindowSpecsEqual, areWorkerStatsEqual, attachResolvedLanguages, attachResolvedThemes, cleanLastNewline, cleanUpResolvedLanguages, cleanUpResolvedThemes, cloneFileDiffMetadata, codeToHtml, createAnnotationElement, createAnnotationWrapperNode, createCSSVariablesTheme, createDiffSpanDecoration, createEmptyRowBuffer, createFileHeaderElement, createGutterGap, createGutterItem, createGutterUtilityContentNode, createGutterUtilityElement, createGutterWrapper, createHastElement, createIconElement, createNoNewlineElement, createPreElement, createPreWrapperProperties, createRowNodes, createSeparator, createSpanFromToken, createStyleElement, createTextNodeElement, createThemeStyleElement, createTransformerWithState, createUnsafeCSSStyleNode, createWindowFromScrollPosition, dequeueRender, detachString, diffAcceptRejectHunk, disposeHighlighter, findCodeElement, formatCSSVariablePrefix, getCustomExtensionsMap, getCustomExtensionsVersion, getFiletypeFromFileName, getHighlighterIfLoaded, getHighlighterOptions, getHighlighterThemeStyles, getHunkSeparatorSlotName, getIconForType, getLineAnnotationName, getLineEndingType, getLineNodes, getOrCreateCodeNode, getResolvedLanguages, getResolvedOrResolveLanguage, getResolvedOrResolveTheme, getResolvedThemes, getSharedHighlighter, getSingularPatch, getThemes, getTotalLineCountFromHunks, getUnresolvedDiffHunksRendererOptions, hasResolvedLanguages, hasResolvedThemes, hydratePartialDiff, isDefaultRenderRange, isHighlighterLoaded, isHighlighterLoading, isHighlighterNull, isWorkerContext, parseDiffFromFile, parseLineType, parsePatchFiles, patchScrollbarGutterSize, pluckInteractionOptions, prefersReducedMotion, preloadHighlighter, prerenderHTMLIfNecessary, processFile, processLine, processPatch, pushOrJoinSpan, queueRender, registerCustomCSSVariableTheme, registerCustomLanguage, registerCustomTheme, releaseStringDetachBuffer, renderDiffWithHighlighter, renderFileWithHighlighter, replaceCustomExtensions, resolveConflict, resolveLanguage, resolveLanguages, resolveRegion, resolveTheme, resolveThemes, setCustomExtension, setLanguageOverride, setPreNodeProperties, trimPatchContext, wrapCoreCSS, wrapThemeCSS, wrapUnsafeCSS };
108
+ export { ALTERNATE_FILE_NAMES_GIT, AttachedLanguages, AttachedThemes, CODE_VIEW_DIFF_OPTION_KEYS, CODE_VIEW_FILE_OPTION_KEYS, CODE_VIEW_FOOTER_ATTRIBUTE, CODE_VIEW_HEADER_ATTRIBUTE, COMMIT_METADATA_SPLIT, CORE_CSS_ATTRIBUTE, CUSTOM_HEADER_SLOT_ID, CodeToTokenTransformStream, CodeView, DEFAULT_CODE_VIEW_FILE_METRICS, DEFAULT_CODE_VIEW_LAYOUT, DEFAULT_COLLAPSED_CONTEXT_THRESHOLD, DEFAULT_EXPANDED_REGION, DEFAULT_RENDER_RANGE, DEFAULT_SMOOTH_SCROLL_SETTINGS, DEFAULT_THEMES, DEFAULT_TOKENIZE_MAX_LENGTH, DEFAULT_VIRTUAL_FILE_METRICS, DIFFS_DEVELOPMENT_BUILD, DIFFS_SCROLLBAR_GUTTER_MEASURED_PROPERTY, DIFFS_SCROLLBAR_MEASURE_ATTRIBUTE, DIFFS_TAG_NAME, DiffHunksRenderer, EMPTY_RENDER_RANGE, EXTENSION_TO_FILE_FORMAT, FILENAME_HEADER_REGEX, FILENAME_HEADER_REGEX_GIT, FILE_CONTEXT_BLOB, File, FileDiff, FileRenderer, FileStream, GIT_DIFF_FILE_BREAK_REGEX, HEADER_FILENAME_SUFFIX_SLOT_ID, HEADER_METADATA_SLOT_ID, HEADER_PREFIX_SLOT_ID, HUNK_HEADER, INDEX_LINE_METADATA, InteractionManager, MERGE_CONFLICT_BASE_MARKER_REGEX, MERGE_CONFLICT_END_MARKER_REGEX, MERGE_CONFLICT_SEPARATOR_MARKER_REGEX, MERGE_CONFLICT_START_MARKER_REGEX, RegisteredCustomLanguages, ResizeManager, ResolvedLanguages, ResolvingLanguages, SPLIT_WITH_NEWLINES, SVGSpriteSheet, ScrollSyncManager, ShikiStreamTokenizer, THEME_CSS_ATTRIBUTE, UNIFIED_DIFF_FILE_BREAK_REGEX, UNSAFE_CSS_ATTRIBUTE, UnresolvedFile, VIRTUALIZED_FILE_DIFF_LAYOUT_CHECKPOINT_INTERVAL, VirtualizedFile, VirtualizedFileDiff, Virtualizer, areDiffLineAnnotationsEqual, areDiffRenderOptionsEqual, areDiffTargetsEqual, areFileRenderOptionsEqual, areFilesEqual, areHunkDataEqual, areLanguagesAttached, areLineAnnotationsEqual, areObjectsEqual, areOptionsEqual, arePrePropertiesEqual, areRenderRangesEqual, areSelectionsEqual, areThemesAttached, areThemesEqual, areVirtualWindowSpecsEqual, areWorkerStatsEqual, attachResolvedLanguages, attachResolvedThemes, cleanLastNewline, cleanUpResolvedLanguages, cleanUpResolvedThemes, clearRenderQueue, cloneFileDiffMetadata, codeToHtml, createAnnotationElement, createAnnotationWrapperNode, createCSSVariablesTheme, createDiffSpanDecoration, createEmptyRowBuffer, createFileHeaderElement, createGutterGap, createGutterItem, createGutterUtilityContentNode, createGutterUtilityElement, createGutterWrapper, createHastElement, createIconElement, createNoNewlineElement, createPreElement, createPreWrapperProperties, createRowNodes, createSeparator, createSpanFromToken, createStyleElement, createTextNodeElement, createThemeStyleElement, createTransformerWithState, createUnsafeCSSStyleNode, createWindowFromScrollPosition, dequeueRender, detachString, diffAcceptRejectHunk, disposeHighlighter, findCodeElement, formatCSSVariablePrefix, getCustomExtensionsMap, getCustomExtensionsVersion, getFiletypeFromFileName, getHighlighterIfLoaded, getHighlighterOptions, getHighlighterThemeStyles, getHunkSeparatorSlotName, getIconForType, getLineAnnotationName, getLineEndingType, getLineNodes, getOrCreateCodeNode, getResolvedLanguages, getResolvedOrResolveLanguage, getResolvedOrResolveTheme, getResolvedThemes, getSharedHighlighter, getSingularPatch, getThemes, getTotalLineCountFromHunks, getUnresolvedDiffHunksRendererOptions, hasResolvedLanguages, hasResolvedThemes, hydratePartialDiff, isDefaultRenderRange, isHighlighterLoaded, isHighlighterLoading, isHighlighterNull, isWorkerContext, parseDiffFromFile, parseLineType, parsePatchFiles, patchScrollbarGutterSize, pluckInteractionOptions, prefersReducedMotion, preloadHighlighter, prerenderHTMLIfNecessary, processFile, processLine, processPatch, pushOrJoinSpan, queueRender, registerCustomCSSVariableTheme, registerCustomLanguage, registerCustomTheme, releaseStringDetachBuffer, renderDiffWithHighlighter, renderFileWithHighlighter, replaceCustomExtensions, resolveConflict, resolveLanguage, resolveLanguages, resolveRegion, resolveTheme, resolveThemes, setCustomExtension, setLanguageOverride, setPreNodeProperties, trimPatchContext, wrapCoreCSS, wrapThemeCSS, wrapUnsafeCSS };
@@ -1,11 +1,19 @@
1
1
  //#region src/managers/ResizeManager.d.ts
2
+ type ResizeManagerColumnVariableMode = 'apply' | 'measure';
3
+ interface ResizeManagerSetupOptions {
4
+ disableAnnotations: boolean;
5
+ columnVariables?: ResizeManagerColumnVariableMode;
6
+ }
2
7
  declare class ResizeManager {
3
8
  private static resizeObserver;
4
9
  private static managersByElement;
5
10
  private static getResizeObserver;
6
11
  private static handleSharedResizeEntries;
7
12
  private observedNodes;
8
- setup(pre: HTMLPreElement, disableAnnotations: boolean): void;
13
+ setup(pre: HTMLPreElement, {
14
+ disableAnnotations,
15
+ columnVariables
16
+ }: ResizeManagerSetupOptions): void;
9
17
  cleanUp(): void;
10
18
  private observe;
11
19
  private unobserve;
@@ -15,5 +23,5 @@ declare class ResizeManager {
15
23
  private applyNewHeight;
16
24
  }
17
25
  //#endregion
18
- export { ResizeManager };
26
+ export { ResizeManager, ResizeManagerColumnVariableMode, ResizeManagerSetupOptions };
19
27
  //# sourceMappingURL=ResizeManager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ResizeManager.d.ts","names":[],"sources":["../../src/managers/ResizeManager.ts"],"mappings":";cAiBa,aAAA;EAAA,eAEI,cAAA;EAAA,eACA,iBAAA;EAAA,eAEA,iBAAA;EAAA,eAQA,yBAAA;EAAA,QAsBP,aAAA;EAKR,KAAA,CAAM,GAAA,EAAK,cAAc,EAAE,kBAAA;EAoL3B,OAAA;EAAA,QAOQ,OAAA;EAAA,QAkBA,SAAA;EAAA,QAmBA,mBAAA;EAAA,QA0DA,sBAAA;EAAA,QAWA,kBAAA;EAAA,QAkDA,cAAA;AAAA"}
1
+ {"version":3,"file":"ResizeManager.d.ts","names":[],"sources":["../../src/managers/ResizeManager.ts"],"mappings":";KAeY,+BAAA;AAAA,UAEK,yBAAA;EACf,kBAAA;EACA,eAAA,GAAkB,+BAA+B;AAAA;AAAA,cAUtC,aAAA;EAAA,eAEI,cAAA;EAAA,eACA,iBAAA;EAAA,eAEA,iBAAA;EAAA,eAQA,yBAAA;EAAA,QAsBP,aAAA;EAKR,KAAA,CACE,GAAA,EAAK,cAAA;IACH,kBAAA;IAAoB;EAAA,GAA6B,yBAAA;EAwLrD,OAAA;EAAA,QAOQ,OAAA;EAAA,QAkBA,SAAA;EAAA,QAmBA,mBAAA;EAAA,QA0DA,sBAAA;EAAA,QAWA,kBAAA;EAAA,QA6BA,cAAA;AAAA"}
@@ -19,8 +19,9 @@ var ResizeManager = class ResizeManager {
19
19
  for (const [manager, managerEntries] of entriesByManager) manager.handleResizeEntries(managerEntries);
20
20
  }
21
21
  observedNodes = /* @__PURE__ */ new Map();
22
- setup(pre, disableAnnotations) {
22
+ setup(pre, { disableAnnotations, columnVariables = "apply" }) {
23
23
  const annotationUpdates = /* @__PURE__ */ new Set();
24
+ const applyColumnVariables = columnVariables === "apply";
24
25
  let columnCount = 0;
25
26
  const observedNodes = new Map(this.observedNodes);
26
27
  this.observedNodes.clear();
@@ -54,13 +55,15 @@ var ResizeManager = class ResizeManager {
54
55
  observedNodes.delete(item.numberElement);
55
56
  this.observedNodes.set(item.numberElement, item);
56
57
  } else item.numberWidth = 0;
58
+ syncColumnVariableMode(item, applyColumnVariables);
57
59
  } else {
58
60
  item = {
59
61
  type: "code",
60
62
  codeElement,
61
63
  numberElement,
62
64
  codeWidth: "auto",
63
- numberWidth: 0
65
+ numberWidth: 0,
66
+ applyColumnVariables
64
67
  };
65
68
  this.observedNodes.set(codeElement, item);
66
69
  this.observe(codeElement);
@@ -223,12 +226,10 @@ var ResizeManager = class ResizeManager {
223
226
  if (!codeWidthChanged && !numberWidthChanged) continue;
224
227
  item.codeWidth = nextCodeWidth;
225
228
  item.numberWidth = nextNumberWidth;
226
- if (codeWidthChanged) item.codeElement.style.setProperty("--diffs-column-width", `${typeof nextCodeWidth === "number" ? `${nextCodeWidth}px` : "auto"}`);
227
- if (numberWidthChanged) item.codeElement.style.setProperty("--diffs-column-number-width", `${nextNumberWidth === 0 ? "auto" : `${nextNumberWidth}px`}`);
228
- if (codeWidthChanged || numberWidthChanged && nextCodeWidth !== "auto") {
229
- const targetWidth = typeof nextCodeWidth === "number" ? Math.max(nextCodeWidth - nextNumberWidth, 0) : 0;
230
- item.codeElement.style.setProperty("--diffs-column-content-width", `${targetWidth > 0 ? `${targetWidth}px` : "auto"}`);
231
- }
229
+ if (item.applyColumnVariables) applyCodeColumnVariables(item, {
230
+ codeWidthChanged,
231
+ numberWidthChanged
232
+ });
232
233
  }
233
234
  };
234
235
  applyNewHeight(item, newHeight) {
@@ -246,13 +247,32 @@ function resolveCodeWidth(inlineSize) {
246
247
  function resolveNumberWidth(inlineSize) {
247
248
  return Math.max(Math.ceil(inlineSize), 0);
248
249
  }
249
- function cleanupStaleCodeItem(item) {
250
- if (item.codeElement.isConnected) {
251
- item.codeElement.style.removeProperty("--diffs-column-content-width");
252
- item.codeElement.style.removeProperty("--diffs-column-number-width");
253
- item.codeElement.style.removeProperty("--diffs-column-width");
250
+ function syncColumnVariableMode(item, applyColumnVariables) {
251
+ if (item.applyColumnVariables === applyColumnVariables) return;
252
+ item.applyColumnVariables = applyColumnVariables;
253
+ if (applyColumnVariables) applyCodeColumnVariables(item, {
254
+ codeWidthChanged: true,
255
+ numberWidthChanged: true
256
+ });
257
+ else removeCodeColumnVariables(item);
258
+ }
259
+ function applyCodeColumnVariables(item, { codeWidthChanged, numberWidthChanged }) {
260
+ const { codeElement, codeWidth, numberWidth } = item;
261
+ if (codeWidthChanged) codeElement.style.setProperty("--diffs-column-width", `${typeof codeWidth === "number" ? `${codeWidth}px` : "auto"}`);
262
+ if (numberWidthChanged) codeElement.style.setProperty("--diffs-column-number-width", `${numberWidth === 0 ? "auto" : `${numberWidth}px`}`);
263
+ if (codeWidthChanged || numberWidthChanged && codeWidth !== "auto") {
264
+ const targetWidth = typeof codeWidth === "number" ? Math.max(codeWidth - numberWidth, 0) : 0;
265
+ codeElement.style.setProperty("--diffs-column-content-width", `${targetWidth > 0 ? `${targetWidth}px` : "auto"}`);
254
266
  }
255
267
  }
268
+ function removeCodeColumnVariables(item) {
269
+ item.codeElement.style.removeProperty("--diffs-column-content-width");
270
+ item.codeElement.style.removeProperty("--diffs-column-number-width");
271
+ item.codeElement.style.removeProperty("--diffs-column-width");
272
+ }
273
+ function cleanupStaleCodeItem(item) {
274
+ if (item.codeElement.isConnected) removeCodeColumnVariables(item);
275
+ }
256
276
  function cleanupStaleAnnotationItem(item) {
257
277
  if (item.column1.container.isConnected) item.column1.container.style.removeProperty("--diffs-annotation-min-height");
258
278
  if (item.column2.container.isConnected) item.column2.container.style.removeProperty("--diffs-annotation-min-height");
@@ -1 +1 @@
1
- {"version":3,"file":"ResizeManager.js","names":[],"sources":["../../src/managers/ResizeManager.ts"],"sourcesContent":["import type { ObservedAnnotationNodes, ObservedGridNodes } from '../types';\n\ninterface CodeColumnUpdate {\n codeInlineSize?: number;\n numberInlineSize?: number;\n measuredNumberInlineSize?: number;\n}\n\ntype CodeUpdateMap = Map<ObservedGridNodes, CodeColumnUpdate>;\n\ninterface AnnotationSetup {\n child1: HTMLElement;\n child2: HTMLElement;\n item: ObservedAnnotationNodes;\n newHeight: number;\n}\n\nexport class ResizeManager {\n // Shared static resizeObserver that all ResizeManagers use\n private static resizeObserver: ResizeObserver | undefined;\n private static managersByElement = new Map<Element, ResizeManager>();\n\n private static getResizeObserver(): ResizeObserver {\n const resizeObserver =\n ResizeManager.resizeObserver ??\n new ResizeObserver(ResizeManager.handleSharedResizeEntries);\n ResizeManager.resizeObserver = resizeObserver;\n return resizeObserver;\n }\n\n private static handleSharedResizeEntries(entries: ResizeObserverEntry[]) {\n // First we need to batch all elements by manager, so callbacks are\n // properly aligned with a per-instance ResizeManager\n const entriesByManager = new Map<ResizeManager, ResizeObserverEntry[]>();\n for (const entry of entries) {\n const manager = ResizeManager.managersByElement.get(entry.target);\n if (manager == null) {\n continue;\n }\n const managerEntries = entriesByManager.get(manager);\n if (managerEntries == null) {\n entriesByManager.set(manager, [entry]);\n } else {\n managerEntries.push(entry);\n }\n }\n\n for (const [manager, managerEntries] of entriesByManager) {\n manager.handleResizeEntries(managerEntries);\n }\n }\n\n private observedNodes = new Map<\n HTMLElement,\n ObservedAnnotationNodes | ObservedGridNodes\n >();\n\n setup(pre: HTMLPreElement, disableAnnotations: boolean): void {\n const annotationUpdates = new Set<AnnotationSetup>();\n let columnCount = 0;\n const observedNodes = new Map(this.observedNodes);\n this.observedNodes.clear();\n\n for (const element of pre.children) {\n if (columnCount === 2) {\n break;\n }\n const codeElement: HTMLElement | undefined = (() => {\n if (element instanceof HTMLElement && element.tagName === 'CODE') {\n return element;\n }\n return undefined;\n })();\n if (codeElement == null) {\n continue;\n }\n columnCount++;\n let item: ObservedGridNodes | ObservedAnnotationNodes | undefined =\n observedNodes.get(codeElement);\n if (item != null && item.type !== 'code') {\n throw new Error(\n 'ResizeManager.setup: somehow a code node is being used for an annotation, should be impossible'\n );\n }\n\n let numberElement = codeElement.firstElementChild;\n if (!(numberElement instanceof HTMLElement)) {\n numberElement = null;\n }\n if (item != null) {\n this.observedNodes.set(codeElement, item);\n observedNodes.delete(codeElement);\n if (item.numberElement !== numberElement) {\n if (item.numberElement != null) {\n this.unobserve(item.numberElement);\n observedNodes.delete(item.numberElement);\n }\n if (numberElement != null) {\n this.observe(numberElement);\n observedNodes.delete(numberElement);\n this.observedNodes.set(numberElement, item);\n }\n item.numberElement = numberElement;\n item.numberWidth = 0;\n } else if (item.numberElement != null) {\n observedNodes.delete(item.numberElement);\n this.observedNodes.set(item.numberElement, item);\n // If there is a resize, let the resize handler handle it...\n } else {\n item.numberWidth = 0;\n }\n } else {\n item = {\n type: 'code',\n codeElement,\n numberElement,\n codeWidth: 'auto',\n numberWidth: 0,\n };\n this.observedNodes.set(codeElement, item);\n this.observe(codeElement);\n if (numberElement != null) {\n this.observedNodes.set(numberElement, item);\n this.observe(numberElement);\n }\n }\n }\n\n if (columnCount > 1 && !disableAnnotations) {\n const annotationElements = pre.querySelectorAll(\n '[data-line-annotation*=\",\"]'\n );\n\n const elementMap = new Map<string, HTMLElement[]>();\n // Iterate through all the matched elements and organize them into pairs\n // based on the data-line-annotation attribute\n for (const element of annotationElements) {\n if (!(element instanceof HTMLElement)) {\n continue;\n }\n const lineAnnotation =\n element.getAttribute('data-line-annotation') ?? '';\n if (!/^-?\\d+,-?\\d+$/.test(lineAnnotation)) {\n console.error(\n 'DiffFileRenderer.setupResizeObserver: Invalid element or annotation',\n { lineAnnotation, element }\n );\n continue;\n }\n let pairs = elementMap.get(lineAnnotation);\n if (pairs == null) {\n pairs = [];\n elementMap.set(lineAnnotation, pairs);\n }\n pairs.push(element);\n }\n\n for (const [key, pair] of elementMap) {\n if (pair.length !== 2) {\n console.error(\n 'DiffFileRenderer.setupResizeObserver: Bad Pair',\n key,\n pair\n );\n continue;\n }\n const [container1, container2] = pair;\n const child1 = container1.firstElementChild;\n const child2 = container2.firstElementChild;\n if (\n !(container1 instanceof HTMLElement) ||\n !(container2 instanceof HTMLElement) ||\n !(child1 instanceof HTMLElement) ||\n !(child2 instanceof HTMLElement)\n ) {\n continue;\n }\n\n let item = observedNodes.get(child1);\n\n if (item != null) {\n this.observedNodes.set(child1, item);\n this.observedNodes.set(child2, item);\n observedNodes.delete(child1);\n observedNodes.delete(child2);\n continue;\n }\n\n const child1Height = child1.getBoundingClientRect().height;\n const child2Height = child2.getBoundingClientRect().height;\n item = {\n type: 'annotations',\n column1: {\n container: container1,\n child: child1,\n childHeight: child1Height,\n },\n column2: {\n container: container2,\n child: child2,\n childHeight: child2Height,\n },\n currentHeight: 'auto',\n };\n annotationUpdates.add({\n child1,\n child2,\n item,\n newHeight: Math.max(child1Height, child2Height),\n });\n }\n\n // Measure all annotation heights first, then apply the paired min-height\n // styles after the read phase so setup does not bounce between layout\n // reads and writes for every annotation pair.\n for (const pendingUpdate of annotationUpdates) {\n this.applyNewHeight(pendingUpdate.item, pendingUpdate.newHeight);\n this.observedNodes.set(pendingUpdate.child1, pendingUpdate.item);\n this.observedNodes.set(pendingUpdate.child2, pendingUpdate.item);\n this.observe(pendingUpdate.child1);\n this.observe(pendingUpdate.child2);\n }\n annotationUpdates.clear();\n }\n\n // Cleanup any old nodes that might still be observed\n for (const [element, item] of observedNodes) {\n this.unobserve(element);\n if (item.type === 'code') {\n cleanupStaleCodeItem(item);\n } else {\n cleanupStaleAnnotationItem(item);\n }\n }\n observedNodes.clear();\n }\n\n cleanUp(): void {\n for (const element of this.observedNodes.keys()) {\n this.unobserve(element);\n }\n this.observedNodes.clear();\n }\n\n private observe(element: HTMLElement): void {\n const { managersByElement } = ResizeManager;\n const owner = managersByElement.get(element);\n // Already registered\n if (owner === this) {\n return;\n }\n // If we've already somehow registered with another manager, we in for a\n // world of pain, so complain loudly\n else if (owner != null && owner !== this) {\n throw new Error(\n 'ResizeManager.observe: element is already owned by another ResizeManager'\n );\n }\n managersByElement.set(element, this);\n ResizeManager.getResizeObserver().observe(element);\n }\n\n private unobserve(element: HTMLElement): void {\n const { managersByElement, resizeObserver } = ResizeManager;\n const owner = managersByElement.get(element);\n if (owner == null) {\n return;\n } else if (owner !== this) {\n throw new Error(\n 'ResizeManager.unobserve: element is owned by another ResizeManager'\n );\n }\n\n managersByElement.delete(element);\n resizeObserver?.unobserve(element);\n if (resizeObserver != null && managersByElement.size === 0) {\n resizeObserver.disconnect();\n ResizeManager.resizeObserver = undefined;\n }\n }\n\n private handleResizeEntries(entries: ResizeObserverEntry[]) {\n const codeUpdates: CodeUpdateMap = new Map();\n const annotationUpdates: Set<ObservedAnnotationNodes> = new Set();\n for (const entry of entries) {\n const { target, borderBoxSize, contentBoxSize } = entry;\n if (!(target instanceof HTMLElement)) {\n console.error(\n 'ResizeManager.handleResizeEntries: Invalid element for ResizeObserver',\n entry\n );\n continue;\n }\n const item = this.observedNodes.get(target);\n if (item == null) {\n console.error(\n 'ResizeManager.handleResizeEntries: Not a valid observed node',\n entry\n );\n continue;\n }\n if (item.type === 'annotations') {\n const column = (() => {\n if (target === item.column1.child) {\n return item.column1;\n }\n if (target === item.column2.child) {\n return item.column2;\n }\n return undefined;\n })();\n\n if (column == null) {\n console.error(\n `ResizeManager.handleResizeEntries: Couldn't find a column for`,\n { item, target }\n );\n continue;\n }\n\n column.childHeight = borderBoxSize[0].blockSize;\n annotationUpdates.add(item);\n } else if (item.type === 'code') {\n const update = codeUpdates.get(item) ?? {};\n const inlineSize = contentBoxSize[0].inlineSize;\n if (target === item.codeElement) {\n update.codeInlineSize = inlineSize;\n } else if (target === item.numberElement) {\n update.numberInlineSize = inlineSize;\n }\n codeUpdates.set(item, update);\n }\n }\n this.applyAnnotationUpdates(annotationUpdates);\n annotationUpdates.clear();\n this.applyColumnUpdates(codeUpdates);\n codeUpdates.clear();\n }\n\n private applyAnnotationUpdates(\n annotationUpdates: Set<ObservedAnnotationNodes>\n ) {\n for (const item of annotationUpdates) {\n this.applyNewHeight(\n item,\n Math.max(item.column1.childHeight, item.column2.childHeight)\n );\n }\n }\n\n private applyColumnUpdates = (queuedUpdates: CodeUpdateMap) => {\n for (const [item, update] of queuedUpdates) {\n const nextCodeWidth =\n update.codeInlineSize != null\n ? resolveCodeWidth(update.codeInlineSize)\n : item.codeWidth;\n const nextNumberWidth =\n update.numberInlineSize != null\n ? resolveNumberWidth(update.numberInlineSize)\n : item.numberWidth;\n const codeWidthChanged = nextCodeWidth !== item.codeWidth;\n const numberWidthChanged = nextNumberWidth !== item.numberWidth;\n\n if (!codeWidthChanged && !numberWidthChanged) {\n continue;\n }\n\n item.codeWidth = nextCodeWidth;\n item.numberWidth = nextNumberWidth;\n\n if (codeWidthChanged) {\n item.codeElement.style.setProperty(\n '--diffs-column-width',\n `${typeof nextCodeWidth === 'number' ? `${nextCodeWidth}px` : 'auto'}`\n );\n }\n\n if (numberWidthChanged) {\n item.codeElement.style.setProperty(\n '--diffs-column-number-width',\n `${nextNumberWidth === 0 ? 'auto' : `${nextNumberWidth}px`}`\n );\n }\n\n if (\n codeWidthChanged ||\n (numberWidthChanged && nextCodeWidth !== 'auto')\n ) {\n const targetWidth =\n typeof nextCodeWidth === 'number'\n ? Math.max(nextCodeWidth - nextNumberWidth, 0)\n : 0;\n item.codeElement.style.setProperty(\n '--diffs-column-content-width',\n `${targetWidth > 0 ? `${targetWidth}px` : 'auto'}`\n );\n }\n }\n };\n\n private applyNewHeight(item: ObservedAnnotationNodes, newHeight: number) {\n if (newHeight !== item.currentHeight) {\n item.currentHeight = Math.max(newHeight, 0);\n item.column1.container.style.setProperty(\n '--diffs-annotation-min-height',\n `${item.currentHeight}px`\n );\n item.column2.container.style.setProperty(\n '--diffs-annotation-min-height',\n `${item.currentHeight}px`\n );\n }\n }\n}\n\nfunction resolveCodeWidth(inlineSize: number): number | 'auto' {\n const width = Math.max(Math.floor(inlineSize), 0);\n return width === 0 ? 'auto' : width;\n}\n\nfunction resolveNumberWidth(inlineSize: number): number {\n return Math.max(Math.ceil(inlineSize), 0);\n}\n\nfunction cleanupStaleCodeItem(item: ObservedGridNodes): void {\n if (item.codeElement.isConnected) {\n item.codeElement.style.removeProperty('--diffs-column-content-width');\n item.codeElement.style.removeProperty('--diffs-column-number-width');\n item.codeElement.style.removeProperty('--diffs-column-width');\n }\n}\n\nfunction cleanupStaleAnnotationItem(item: ObservedAnnotationNodes): void {\n if (item.column1.container.isConnected) {\n item.column1.container.style.removeProperty(\n '--diffs-annotation-min-height'\n );\n }\n if (item.column2.container.isConnected) {\n item.column2.container.style.removeProperty(\n '--diffs-annotation-min-height'\n );\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ResizeManager.js","names":[],"sources":["../../src/managers/ResizeManager.ts"],"sourcesContent":["import type { ObservedAnnotationNodes, ObservedGridNodes } from '../types';\n\ninterface CodeColumnUpdate {\n codeInlineSize?: number;\n numberInlineSize?: number;\n measuredNumberInlineSize?: number;\n}\n\ninterface CodeColumnVariableChanges {\n codeWidthChanged: boolean;\n numberWidthChanged: boolean;\n}\n\ntype CodeUpdateMap = Map<ObservedGridNodes, CodeColumnUpdate>;\n\nexport type ResizeManagerColumnVariableMode = 'apply' | 'measure';\n\nexport interface ResizeManagerSetupOptions {\n disableAnnotations: boolean;\n columnVariables?: ResizeManagerColumnVariableMode;\n}\n\ninterface AnnotationSetup {\n child1: HTMLElement;\n child2: HTMLElement;\n item: ObservedAnnotationNodes;\n newHeight: number;\n}\n\nexport class ResizeManager {\n // Shared static resizeObserver that all ResizeManagers use\n private static resizeObserver: ResizeObserver | undefined;\n private static managersByElement = new Map<Element, ResizeManager>();\n\n private static getResizeObserver(): ResizeObserver {\n const resizeObserver =\n ResizeManager.resizeObserver ??\n new ResizeObserver(ResizeManager.handleSharedResizeEntries);\n ResizeManager.resizeObserver = resizeObserver;\n return resizeObserver;\n }\n\n private static handleSharedResizeEntries(entries: ResizeObserverEntry[]) {\n // First we need to batch all elements by manager, so callbacks are\n // properly aligned with a per-instance ResizeManager\n const entriesByManager = new Map<ResizeManager, ResizeObserverEntry[]>();\n for (const entry of entries) {\n const manager = ResizeManager.managersByElement.get(entry.target);\n if (manager == null) {\n continue;\n }\n const managerEntries = entriesByManager.get(manager);\n if (managerEntries == null) {\n entriesByManager.set(manager, [entry]);\n } else {\n managerEntries.push(entry);\n }\n }\n\n for (const [manager, managerEntries] of entriesByManager) {\n manager.handleResizeEntries(managerEntries);\n }\n }\n\n private observedNodes = new Map<\n HTMLElement,\n ObservedAnnotationNodes | ObservedGridNodes\n >();\n\n setup(\n pre: HTMLPreElement,\n { disableAnnotations, columnVariables = 'apply' }: ResizeManagerSetupOptions\n ): void {\n const annotationUpdates = new Set<AnnotationSetup>();\n const applyColumnVariables = columnVariables === 'apply';\n let columnCount = 0;\n const observedNodes = new Map(this.observedNodes);\n this.observedNodes.clear();\n\n for (const element of pre.children) {\n if (columnCount === 2) {\n break;\n }\n const codeElement: HTMLElement | undefined = (() => {\n if (element instanceof HTMLElement && element.tagName === 'CODE') {\n return element;\n }\n return undefined;\n })();\n if (codeElement == null) {\n continue;\n }\n columnCount++;\n let item: ObservedGridNodes | ObservedAnnotationNodes | undefined =\n observedNodes.get(codeElement);\n if (item != null && item.type !== 'code') {\n throw new Error(\n 'ResizeManager.setup: somehow a code node is being used for an annotation, should be impossible'\n );\n }\n\n let numberElement = codeElement.firstElementChild;\n if (!(numberElement instanceof HTMLElement)) {\n numberElement = null;\n }\n if (item != null) {\n this.observedNodes.set(codeElement, item);\n observedNodes.delete(codeElement);\n if (item.numberElement !== numberElement) {\n if (item.numberElement != null) {\n this.unobserve(item.numberElement);\n observedNodes.delete(item.numberElement);\n }\n if (numberElement != null) {\n this.observe(numberElement);\n observedNodes.delete(numberElement);\n this.observedNodes.set(numberElement, item);\n }\n item.numberElement = numberElement;\n item.numberWidth = 0;\n } else if (item.numberElement != null) {\n observedNodes.delete(item.numberElement);\n this.observedNodes.set(item.numberElement, item);\n // If there is a resize, let the resize handler handle it...\n } else {\n item.numberWidth = 0;\n }\n syncColumnVariableMode(item, applyColumnVariables);\n } else {\n item = {\n type: 'code',\n codeElement,\n numberElement,\n codeWidth: 'auto',\n numberWidth: 0,\n applyColumnVariables,\n };\n this.observedNodes.set(codeElement, item);\n this.observe(codeElement);\n if (numberElement != null) {\n this.observedNodes.set(numberElement, item);\n this.observe(numberElement);\n }\n }\n }\n\n if (columnCount > 1 && !disableAnnotations) {\n const annotationElements = pre.querySelectorAll(\n '[data-line-annotation*=\",\"]'\n );\n\n const elementMap = new Map<string, HTMLElement[]>();\n // Iterate through all the matched elements and organize them into pairs\n // based on the data-line-annotation attribute\n for (const element of annotationElements) {\n if (!(element instanceof HTMLElement)) {\n continue;\n }\n const lineAnnotation =\n element.getAttribute('data-line-annotation') ?? '';\n if (!/^-?\\d+,-?\\d+$/.test(lineAnnotation)) {\n console.error(\n 'DiffFileRenderer.setupResizeObserver: Invalid element or annotation',\n { lineAnnotation, element }\n );\n continue;\n }\n let pairs = elementMap.get(lineAnnotation);\n if (pairs == null) {\n pairs = [];\n elementMap.set(lineAnnotation, pairs);\n }\n pairs.push(element);\n }\n\n for (const [key, pair] of elementMap) {\n if (pair.length !== 2) {\n console.error(\n 'DiffFileRenderer.setupResizeObserver: Bad Pair',\n key,\n pair\n );\n continue;\n }\n const [container1, container2] = pair;\n const child1 = container1.firstElementChild;\n const child2 = container2.firstElementChild;\n if (\n !(container1 instanceof HTMLElement) ||\n !(container2 instanceof HTMLElement) ||\n !(child1 instanceof HTMLElement) ||\n !(child2 instanceof HTMLElement)\n ) {\n continue;\n }\n\n let item = observedNodes.get(child1);\n\n if (item != null) {\n this.observedNodes.set(child1, item);\n this.observedNodes.set(child2, item);\n observedNodes.delete(child1);\n observedNodes.delete(child2);\n continue;\n }\n\n const child1Height = child1.getBoundingClientRect().height;\n const child2Height = child2.getBoundingClientRect().height;\n item = {\n type: 'annotations',\n column1: {\n container: container1,\n child: child1,\n childHeight: child1Height,\n },\n column2: {\n container: container2,\n child: child2,\n childHeight: child2Height,\n },\n currentHeight: 'auto',\n };\n annotationUpdates.add({\n child1,\n child2,\n item,\n newHeight: Math.max(child1Height, child2Height),\n });\n }\n\n // Measure all annotation heights first, then apply the paired min-height\n // styles after the read phase so setup does not bounce between layout\n // reads and writes for every annotation pair.\n for (const pendingUpdate of annotationUpdates) {\n this.applyNewHeight(pendingUpdate.item, pendingUpdate.newHeight);\n this.observedNodes.set(pendingUpdate.child1, pendingUpdate.item);\n this.observedNodes.set(pendingUpdate.child2, pendingUpdate.item);\n this.observe(pendingUpdate.child1);\n this.observe(pendingUpdate.child2);\n }\n annotationUpdates.clear();\n }\n\n // Cleanup any old nodes that might still be observed\n for (const [element, item] of observedNodes) {\n this.unobserve(element);\n if (item.type === 'code') {\n cleanupStaleCodeItem(item);\n } else {\n cleanupStaleAnnotationItem(item);\n }\n }\n observedNodes.clear();\n }\n\n cleanUp(): void {\n for (const element of this.observedNodes.keys()) {\n this.unobserve(element);\n }\n this.observedNodes.clear();\n }\n\n private observe(element: HTMLElement): void {\n const { managersByElement } = ResizeManager;\n const owner = managersByElement.get(element);\n // Already registered\n if (owner === this) {\n return;\n }\n // If we've already somehow registered with another manager, we in for a\n // world of pain, so complain loudly\n else if (owner != null && owner !== this) {\n throw new Error(\n 'ResizeManager.observe: element is already owned by another ResizeManager'\n );\n }\n managersByElement.set(element, this);\n ResizeManager.getResizeObserver().observe(element);\n }\n\n private unobserve(element: HTMLElement): void {\n const { managersByElement, resizeObserver } = ResizeManager;\n const owner = managersByElement.get(element);\n if (owner == null) {\n return;\n } else if (owner !== this) {\n throw new Error(\n 'ResizeManager.unobserve: element is owned by another ResizeManager'\n );\n }\n\n managersByElement.delete(element);\n resizeObserver?.unobserve(element);\n if (resizeObserver != null && managersByElement.size === 0) {\n resizeObserver.disconnect();\n ResizeManager.resizeObserver = undefined;\n }\n }\n\n private handleResizeEntries(entries: ResizeObserverEntry[]) {\n const codeUpdates: CodeUpdateMap = new Map();\n const annotationUpdates: Set<ObservedAnnotationNodes> = new Set();\n for (const entry of entries) {\n const { target, borderBoxSize, contentBoxSize } = entry;\n if (!(target instanceof HTMLElement)) {\n console.error(\n 'ResizeManager.handleResizeEntries: Invalid element for ResizeObserver',\n entry\n );\n continue;\n }\n const item = this.observedNodes.get(target);\n if (item == null) {\n console.error(\n 'ResizeManager.handleResizeEntries: Not a valid observed node',\n entry\n );\n continue;\n }\n if (item.type === 'annotations') {\n const column = (() => {\n if (target === item.column1.child) {\n return item.column1;\n }\n if (target === item.column2.child) {\n return item.column2;\n }\n return undefined;\n })();\n\n if (column == null) {\n console.error(\n `ResizeManager.handleResizeEntries: Couldn't find a column for`,\n { item, target }\n );\n continue;\n }\n\n column.childHeight = borderBoxSize[0].blockSize;\n annotationUpdates.add(item);\n } else if (item.type === 'code') {\n const update = codeUpdates.get(item) ?? {};\n const inlineSize = contentBoxSize[0].inlineSize;\n if (target === item.codeElement) {\n update.codeInlineSize = inlineSize;\n } else if (target === item.numberElement) {\n update.numberInlineSize = inlineSize;\n }\n codeUpdates.set(item, update);\n }\n }\n this.applyAnnotationUpdates(annotationUpdates);\n annotationUpdates.clear();\n this.applyColumnUpdates(codeUpdates);\n codeUpdates.clear();\n }\n\n private applyAnnotationUpdates(\n annotationUpdates: Set<ObservedAnnotationNodes>\n ) {\n for (const item of annotationUpdates) {\n this.applyNewHeight(\n item,\n Math.max(item.column1.childHeight, item.column2.childHeight)\n );\n }\n }\n\n private applyColumnUpdates = (queuedUpdates: CodeUpdateMap) => {\n for (const [item, update] of queuedUpdates) {\n const nextCodeWidth =\n update.codeInlineSize != null\n ? resolveCodeWidth(update.codeInlineSize)\n : item.codeWidth;\n const nextNumberWidth =\n update.numberInlineSize != null\n ? resolveNumberWidth(update.numberInlineSize)\n : item.numberWidth;\n const codeWidthChanged = nextCodeWidth !== item.codeWidth;\n const numberWidthChanged = nextNumberWidth !== item.numberWidth;\n\n if (!codeWidthChanged && !numberWidthChanged) {\n continue;\n }\n\n item.codeWidth = nextCodeWidth;\n item.numberWidth = nextNumberWidth;\n\n if (item.applyColumnVariables) {\n applyCodeColumnVariables(item, {\n codeWidthChanged,\n numberWidthChanged,\n });\n }\n }\n };\n\n private applyNewHeight(item: ObservedAnnotationNodes, newHeight: number) {\n if (newHeight !== item.currentHeight) {\n item.currentHeight = Math.max(newHeight, 0);\n item.column1.container.style.setProperty(\n '--diffs-annotation-min-height',\n `${item.currentHeight}px`\n );\n item.column2.container.style.setProperty(\n '--diffs-annotation-min-height',\n `${item.currentHeight}px`\n );\n }\n }\n}\n\nfunction resolveCodeWidth(inlineSize: number): number | 'auto' {\n const width = Math.max(Math.floor(inlineSize), 0);\n return width === 0 ? 'auto' : width;\n}\n\nfunction resolveNumberWidth(inlineSize: number): number {\n return Math.max(Math.ceil(inlineSize), 0);\n}\n\nfunction syncColumnVariableMode(\n item: ObservedGridNodes,\n applyColumnVariables: boolean\n): void {\n if (item.applyColumnVariables === applyColumnVariables) {\n return;\n }\n\n item.applyColumnVariables = applyColumnVariables;\n if (applyColumnVariables) {\n applyCodeColumnVariables(item, {\n codeWidthChanged: true,\n numberWidthChanged: true,\n });\n } else {\n removeCodeColumnVariables(item);\n }\n}\n\nfunction applyCodeColumnVariables(\n item: ObservedGridNodes,\n { codeWidthChanged, numberWidthChanged }: CodeColumnVariableChanges\n): void {\n const { codeElement, codeWidth, numberWidth } = item;\n if (codeWidthChanged) {\n codeElement.style.setProperty(\n '--diffs-column-width',\n `${typeof codeWidth === 'number' ? `${codeWidth}px` : 'auto'}`\n );\n }\n\n if (numberWidthChanged) {\n codeElement.style.setProperty(\n '--diffs-column-number-width',\n `${numberWidth === 0 ? 'auto' : `${numberWidth}px`}`\n );\n }\n\n if (codeWidthChanged || (numberWidthChanged && codeWidth !== 'auto')) {\n const targetWidth =\n typeof codeWidth === 'number' ? Math.max(codeWidth - numberWidth, 0) : 0;\n codeElement.style.setProperty(\n '--diffs-column-content-width',\n `${targetWidth > 0 ? `${targetWidth}px` : 'auto'}`\n );\n }\n}\n\nfunction removeCodeColumnVariables(item: ObservedGridNodes): void {\n item.codeElement.style.removeProperty('--diffs-column-content-width');\n item.codeElement.style.removeProperty('--diffs-column-number-width');\n item.codeElement.style.removeProperty('--diffs-column-width');\n}\n\nfunction cleanupStaleCodeItem(item: ObservedGridNodes): void {\n if (item.codeElement.isConnected) {\n removeCodeColumnVariables(item);\n }\n}\n\nfunction cleanupStaleAnnotationItem(item: ObservedAnnotationNodes): void {\n if (item.column1.container.isConnected) {\n item.column1.container.style.removeProperty(\n '--diffs-annotation-min-height'\n );\n }\n if (item.column2.container.isConnected) {\n item.column2.container.style.removeProperty(\n '--diffs-annotation-min-height'\n );\n }\n}\n"],"mappings":"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"}
@@ -2,6 +2,7 @@
2
2
  type Callback = (time: number) => unknown;
3
3
  declare function queueRender(callback: Callback): void;
4
4
  declare function dequeueRender(callback: Callback): void;
5
+ declare function clearRenderQueue(): void;
5
6
  //#endregion
6
- export { dequeueRender, queueRender };
7
+ export { clearRenderQueue, dequeueRender, queueRender };
7
8
  //# sourceMappingURL=UniversalRenderingManager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"UniversalRenderingManager.d.ts","names":[],"sources":["../../src/managers/UniversalRenderingManager.ts"],"mappings":";KAAK,QAAA,IAAY,IAAY;AAAA,iBAMb,WAAA,CAAY,QAAkB,EAAR,QAAQ;AAAA,iBAK9B,aAAA,CAAc,QAAkB,EAAR,QAAQ"}
1
+ {"version":3,"file":"UniversalRenderingManager.d.ts","names":[],"sources":["../../src/managers/UniversalRenderingManager.ts"],"mappings":";KAAK,QAAA,IAAY,IAAY;AAAA,iBAMb,WAAA,CAAY,QAAkB,EAAR,QAAQ;AAAA,iBAK9B,aAAA,CAAc,QAAkB,EAAR,QAAQ;AAAA,iBAWhC,gBAAA"}
@@ -12,6 +12,11 @@ function dequeueRender(callback) {
12
12
  frameId = null;
13
13
  }
14
14
  }
15
+ function clearRenderQueue() {
16
+ callbacks.clear();
17
+ if (frameId != null && typeof cancelAnimationFrame === "function") cancelAnimationFrame(frameId);
18
+ frameId = null;
19
+ }
15
20
  function render(time) {
16
21
  const toIterate = new Set(callbacks);
17
22
  callbacks.clear();
@@ -24,6 +29,6 @@ function render(time) {
24
29
  else frameId = null;
25
30
  }
26
31
  //#endregion
27
- export { dequeueRender, queueRender };
32
+ export { clearRenderQueue, dequeueRender, queueRender };
28
33
 
29
34
  //# sourceMappingURL=UniversalRenderingManager.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"UniversalRenderingManager.js","names":[],"sources":["../../src/managers/UniversalRenderingManager.ts"],"sourcesContent":["type Callback = (time: number) => unknown;\n\nconst callbacks = new Set<Callback>();\nlet frameId: null | number = null;\n\n// TODO(amadeus): Figure out a proper name for this module...\nexport function queueRender(callback: Callback): void {\n callbacks.add(callback);\n frameId ??= requestAnimationFrame(render);\n}\n\nexport function dequeueRender(callback: Callback): void {\n callbacks.delete(callback);\n if (callbacks.size === 0 && frameId != null) {\n cancelAnimationFrame(frameId);\n frameId = null;\n }\n}\n\nfunction render(time: number): void {\n const toIterate = new Set(callbacks);\n callbacks.clear();\n for (const callback of toIterate) {\n try {\n callback(time);\n } catch (error) {\n console.error(error);\n }\n }\n // If render picked up any new callbacks, lets trigger a new\n // requestAnimationFrame\n if (callbacks.size > 0) {\n frameId = requestAnimationFrame(render);\n } else {\n frameId = null;\n }\n}\n"],"mappings":";AAEA,MAAM,4BAAY,IAAI,IAAc;AACpC,IAAI,UAAyB;AAG7B,SAAgB,YAAY,UAA0B;CACpD,UAAU,IAAI,QAAQ;CACtB,YAAY,sBAAsB,MAAM;AAC1C;AAEA,SAAgB,cAAc,UAA0B;CACtD,UAAU,OAAO,QAAQ;CACzB,IAAI,UAAU,SAAS,KAAK,WAAW,MAAM;EAC3C,qBAAqB,OAAO;EAC5B,UAAU;CACZ;AACF;AAEA,SAAS,OAAO,MAAoB;CAClC,MAAM,YAAY,IAAI,IAAI,SAAS;CACnC,UAAU,MAAM;CAChB,KAAK,MAAM,YAAY,WACrB,IAAI;EACF,SAAS,IAAI;CACf,SAAS,OAAO;EACd,QAAQ,MAAM,KAAK;CACrB;CAIF,IAAI,UAAU,OAAO,GACnB,UAAU,sBAAsB,MAAM;MAEtC,UAAU;AAEd"}
1
+ {"version":3,"file":"UniversalRenderingManager.js","names":[],"sources":["../../src/managers/UniversalRenderingManager.ts"],"sourcesContent":["type Callback = (time: number) => unknown;\n\nconst callbacks = new Set<Callback>();\nlet frameId: null | number = null;\n\n// TODO(amadeus): Figure out a proper name for this module...\nexport function queueRender(callback: Callback): void {\n callbacks.add(callback);\n frameId ??= requestAnimationFrame(render);\n}\n\nexport function dequeueRender(callback: Callback): void {\n callbacks.delete(callback);\n if (callbacks.size === 0 && frameId != null) {\n cancelAnimationFrame(frameId);\n frameId = null;\n }\n}\n\n// Drops every queued callback and cancels the pending frame. The guard\n// matters in test teardown, where the harness may have already removed the\n// requestAnimationFrame globals.\nexport function clearRenderQueue(): void {\n callbacks.clear();\n if (frameId != null && typeof cancelAnimationFrame === 'function') {\n cancelAnimationFrame(frameId);\n }\n frameId = null;\n}\n\nfunction render(time: number): void {\n const toIterate = new Set(callbacks);\n callbacks.clear();\n for (const callback of toIterate) {\n try {\n callback(time);\n } catch (error) {\n console.error(error);\n }\n }\n // If render picked up any new callbacks, lets trigger a new\n // requestAnimationFrame\n if (callbacks.size > 0) {\n frameId = requestAnimationFrame(render);\n } else {\n frameId = null;\n }\n}\n"],"mappings":";AAEA,MAAM,4BAAY,IAAI,IAAc;AACpC,IAAI,UAAyB;AAG7B,SAAgB,YAAY,UAA0B;CACpD,UAAU,IAAI,QAAQ;CACtB,YAAY,sBAAsB,MAAM;AAC1C;AAEA,SAAgB,cAAc,UAA0B;CACtD,UAAU,OAAO,QAAQ;CACzB,IAAI,UAAU,SAAS,KAAK,WAAW,MAAM;EAC3C,qBAAqB,OAAO;EAC5B,UAAU;CACZ;AACF;AAKA,SAAgB,mBAAyB;CACvC,UAAU,MAAM;CAChB,IAAI,WAAW,QAAQ,OAAO,yBAAyB,YACrD,qBAAqB,OAAO;CAE9B,UAAU;AACZ;AAEA,SAAS,OAAO,MAAoB;CAClC,MAAM,YAAY,IAAI,IAAI,SAAS;CACnC,UAAU,MAAM;CAChB,KAAK,MAAM,YAAY,WACrB,IAAI;EACF,SAAS,IAAI;CACf,SAAS,OAAO;EACd,QAAQ,MAAM,KAAK;CACrB;CAIF,IAAI,UAAU,OAAO,GACnB,UAAU,sBAAsB,MAAM;MAEtC,UAAU;AAEd"}