@pierre/diffs 1.3.0-beta.6 → 1.3.0-beta.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/CodeView.d.ts +4 -1
- package/dist/components/CodeView.d.ts.map +1 -1
- package/dist/components/CodeView.js +45 -6
- package/dist/components/CodeView.js.map +1 -1
- package/dist/components/File.d.ts.map +1 -1
- package/dist/components/File.js +5 -2
- package/dist/components/File.js.map +1 -1
- package/dist/components/FileDiff.d.ts +36 -23
- package/dist/components/FileDiff.d.ts.map +1 -1
- package/dist/components/FileDiff.js +126 -58
- package/dist/components/FileDiff.js.map +1 -1
- package/dist/components/UnresolvedFile.d.ts +3 -2
- package/dist/components/UnresolvedFile.d.ts.map +1 -1
- package/dist/components/UnresolvedFile.js +4 -2
- package/dist/components/UnresolvedFile.js.map +1 -1
- package/dist/components/VirtualizedFile.d.ts.map +1 -1
- package/dist/components/VirtualizedFile.js +3 -7
- package/dist/components/VirtualizedFile.js.map +1 -1
- package/dist/components/VirtualizedFileDiff.d.ts +10 -4
- package/dist/components/VirtualizedFileDiff.d.ts.map +1 -1
- package/dist/components/VirtualizedFileDiff.js +178 -49
- package/dist/components/VirtualizedFileDiff.js.map +1 -1
- package/dist/editor/editor.d.ts +2 -2
- package/dist/editor/editor.d.ts.map +1 -1
- package/dist/editor/editor.js +163 -106
- package/dist/editor/editor.js.map +1 -1
- package/dist/editor/editor2.js +1 -1
- package/dist/editor/selection.d.ts +1 -1
- package/dist/editor/selection.d.ts.map +1 -1
- package/dist/editor/selection.js +87 -37
- package/dist/editor/selection.js.map +1 -1
- package/dist/editor/textMeasure.d.ts.map +1 -1
- package/dist/editor/textMeasure.js +25 -7
- package/dist/editor/textMeasure.js.map +1 -1
- package/dist/editor/tokenzier.d.ts +2 -0
- package/dist/editor/tokenzier.d.ts.map +1 -1
- package/dist/editor/tokenzier.js +11 -3
- package/dist/editor/tokenzier.js.map +1 -1
- package/dist/editor/utils.d.ts +3 -1
- package/dist/editor/utils.d.ts.map +1 -1
- package/dist/editor/utils.js +14 -1
- package/dist/editor/utils.js.map +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.js +3 -1
- package/dist/managers/InteractionManager.d.ts.map +1 -1
- package/dist/managers/InteractionManager.js +0 -1
- package/dist/managers/InteractionManager.js.map +1 -1
- package/dist/react/EditorContext.js.map +1 -1
- package/dist/react/MultiFileDiff.d.ts +3 -4
- package/dist/react/MultiFileDiff.d.ts.map +1 -1
- package/dist/react/MultiFileDiff.js.map +1 -1
- package/dist/react/index.d.ts +2 -2
- package/dist/react/utils/useFileDiffInstance.js +14 -15
- package/dist/react/utils/useFileDiffInstance.js.map +1 -1
- package/dist/renderers/DiffHunksRenderer.d.ts +2 -2
- package/dist/renderers/DiffHunksRenderer.d.ts.map +1 -1
- package/dist/renderers/DiffHunksRenderer.js +29 -16
- package/dist/renderers/DiffHunksRenderer.js.map +1 -1
- package/dist/renderers/FileRenderer.js.map +1 -1
- package/dist/ssr/index.d.ts +2 -2
- package/dist/ssr/preloadDiffs.d.ts +11 -10
- package/dist/ssr/preloadDiffs.d.ts.map +1 -1
- package/dist/ssr/preloadDiffs.js +14 -6
- package/dist/ssr/preloadDiffs.js.map +1 -1
- package/dist/types.d.ts +59 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/areHunkDataEqual.js +1 -1
- package/dist/utils/areHunkDataEqual.js.map +1 -1
- package/dist/utils/awaitWithTimeout.d.ts +5 -0
- package/dist/utils/awaitWithTimeout.d.ts.map +1 -0
- package/dist/utils/awaitWithTimeout.js +15 -0
- package/dist/utils/awaitWithTimeout.js.map +1 -0
- package/dist/utils/cloneFileDiffMetadata.d.ts +7 -0
- package/dist/utils/cloneFileDiffMetadata.d.ts.map +1 -0
- package/dist/utils/cloneFileDiffMetadata.js +16 -0
- package/dist/utils/cloneFileDiffMetadata.js.map +1 -0
- package/dist/utils/computeEstimatedDiffHeights.d.ts +3 -1
- package/dist/utils/computeEstimatedDiffHeights.d.ts.map +1 -1
- package/dist/utils/computeEstimatedDiffHeights.js +8 -1
- package/dist/utils/computeEstimatedDiffHeights.js.map +1 -1
- package/dist/utils/createPreElement.js +0 -1
- package/dist/utils/createPreElement.js.map +1 -1
- package/dist/utils/getDiffFileInput.d.ts +14 -0
- package/dist/utils/getDiffFileInput.d.ts.map +1 -0
- package/dist/utils/getDiffFileInput.js +24 -0
- package/dist/utils/getDiffFileInput.js.map +1 -0
- package/dist/utils/getDiffHunksRendererOptions.js +1 -0
- package/dist/utils/getDiffHunksRendererOptions.js.map +1 -1
- package/dist/utils/getFiletypeFromFileName.d.ts.map +1 -1
- package/dist/utils/getFiletypeFromFileName.js +2 -0
- package/dist/utils/getFiletypeFromFileName.js.map +1 -1
- package/dist/utils/hydratePartialDiff.d.ts +10 -0
- package/dist/utils/hydratePartialDiff.d.ts.map +1 -0
- package/dist/utils/hydratePartialDiff.js +140 -0
- package/dist/utils/hydratePartialDiff.js.map +1 -0
- package/dist/utils/iterateOverDiff.js +3 -3
- package/dist/utils/iterateOverDiff.js.map +1 -1
- package/dist/utils/parseDiffFromFile.d.ts +1 -1
- package/dist/utils/parseDiffFromFile.d.ts.map +1 -1
- package/dist/utils/parseDiffFromFile.js +26 -5
- package/dist/utils/parseDiffFromFile.js.map +1 -1
- package/dist/utils/setWrapperNodeProps.js +0 -1
- package/dist/utils/setWrapperNodeProps.js.map +1 -1
- package/dist/utils/updateDiffHunks.d.ts +5 -1
- package/dist/utils/updateDiffHunks.d.ts.map +1 -1
- package/dist/utils/updateDiffHunks.js +26 -4
- package/dist/utils/updateDiffHunks.js.map +1 -1
- package/dist/worker/WorkerPoolManager.d.ts +7 -2
- package/dist/worker/WorkerPoolManager.d.ts.map +1 -1
- package/dist/worker/WorkerPoolManager.js +78 -15
- package/dist/worker/WorkerPoolManager.js.map +1 -1
- package/dist/worker/index.d.ts +2 -2
- package/dist/worker/types.d.ts +7 -1
- package/dist/worker/types.d.ts.map +1 -1
- package/dist/worker/worker-portable.js +5 -3
- package/dist/worker/worker-portable.js.map +1 -1
- package/dist/worker/worker.js +5 -3
- package/dist/worker/worker.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InteractionManager.js","names":[],"sources":["../../src/managers/InteractionManager.ts"],"sourcesContent":["import { toHtml } from 'hast-util-to-html';\n\nimport type {\n AnnotationSide,\n DiffLineEventBaseProps,\n DiffTokenEventBaseProps,\n ExpansionDirections,\n LineEventBaseProps,\n LineTypes,\n MergeConflictResolution,\n SelectedLineRange,\n SelectionPoint,\n SelectionSide,\n TokenEventBase,\n} from '../types';\nimport { areSelectionPointsEqual } from '../utils/areSelectionPointsEqual';\nimport { areSelectionsEqual } from '../utils/areSelectionsEqual';\nimport { createGutterUtilityElement } from '../utils/createGutterUtilityElement';\n\ninterface TokenCache {\n tokenElement: HTMLElement;\n lineCharStart: number;\n lineCharEnd: number;\n tokenText: string;\n}\n\ninterface ExpandCache {\n hunkIndex: number | undefined;\n direction: ExpansionDirections;\n all: boolean;\n}\n\nexport type LogTypes = 'click' | 'move' | 'both' | 'none';\n\nexport type InteractionManagerMode = 'file' | 'diff';\n\nexport interface OnLineClickProps extends LineEventBaseProps {\n event: PointerEvent;\n}\n\nexport interface OnLineEnterLeaveProps extends LineEventBaseProps {\n event: PointerEvent;\n}\n\nexport interface OnDiffLineClickProps extends DiffLineEventBaseProps {\n event: PointerEvent;\n}\n\nexport interface OnDiffLineEnterLeaveProps extends DiffLineEventBaseProps {\n event: PointerEvent;\n}\n\nexport interface SelectionWriteOptions {\n notify?: boolean;\n // Limit the selected-line highlight to one side's column of a split diff.\n // The editor sets this to 'additions' so its active-line highlight stays on\n // the editable pane instead of also lighting up the read-only deletions\n // pane. It has no effect on unified or single-file views, whose one code\n // column carries no side attribute.\n activeLineSide?: SelectionSide;\n // Highlight only the gutter line number, not the line background. The editor\n // sets this while text is selected: the caret line keeps its highlighted\n // number, but the full-line background gives way to the text selection.\n lineNumberOnly?: boolean;\n}\n\nexport type GetLineIndexUtility = (\n lineNumber: number,\n side?: SelectionSide\n) => [number, number] | undefined;\n\ntype EventClickProps<TMode extends InteractionManagerMode> =\n TMode extends 'file' ? OnLineClickProps : OnDiffLineClickProps;\n\ntype PointerEventEnterLeaveProps<TMode extends InteractionManagerMode> =\n TMode extends 'file' ? OnLineEnterLeaveProps : OnDiffLineEnterLeaveProps;\n\ntype EventBaseProps<TMode extends InteractionManagerMode> = TMode extends 'file'\n ? LineEventBaseProps\n : DiffLineEventBaseProps;\n\nexport type OnTokenEventProps<TMode extends InteractionManagerMode> =\n TMode extends 'file' ? TokenEventBase : DiffTokenEventBaseProps;\n\ninterface ExpandoEventProps {\n type: 'line-info';\n hunkIndex: number;\n direction: ExpansionDirections;\n all: boolean;\n}\n\nexport type GetHoveredLineResult<TMode extends InteractionManagerMode> =\n TMode extends 'file'\n ? { lineNumber: number }\n : { lineNumber: number; side: AnnotationSide };\n\ninterface SelectionInfo {\n lineNumber: number;\n eventSide: SelectionSide | undefined;\n lineIndex: number;\n}\n\ntype SelectionHitSource = 'event-path' | 'coordinates-first';\n\ninterface SelectionHitOptions {\n source: SelectionHitSource;\n excludeUtility?: boolean;\n}\n\ninterface SelectionInfoOptions extends SelectionHitOptions {\n requireNumberColumn: boolean;\n}\n\ninterface SelectionEnds {\n top: SelectionPoint;\n bottom: SelectionPoint;\n}\n\ninterface ResolvedLineTarget<TMode extends InteractionManagerMode> {\n kind: 'line';\n lineType: LineTypes;\n lineElement: HTMLElement;\n lineNumber: number;\n numberColumn: boolean;\n numberElement: HTMLElement;\n side: TMode extends 'diff' ? AnnotationSide : undefined;\n splitLineIndex: number | undefined;\n}\n\ninterface ResolvedTokenTarget<TMode extends InteractionManagerMode> {\n kind: 'token';\n lineType: LineTypes;\n lineElement: HTMLElement;\n lineNumber: number;\n numberColumn: boolean;\n numberElement: HTMLElement;\n side: TMode extends 'diff' ? AnnotationSide : undefined;\n splitLineIndex: number | undefined;\n tokenElement: HTMLElement;\n tokenText: string;\n lineCharStart: number;\n lineCharEnd: number;\n}\n\nexport interface MergeConflictActionTarget {\n kind: 'merge-conflict-action';\n resolution: MergeConflictResolution;\n conflictIndex: number;\n}\n\ntype ResolvedPointerTarget<TMode extends InteractionManagerMode> =\n | ResolvedLineTarget<TMode>\n | ResolvedTokenTarget<TMode>\n | ExpandoEventProps\n | MergeConflictActionTarget;\n\ntype LinePointerTarget<TMode extends InteractionManagerMode> =\n ResolvedLineTarget<TMode>;\n\ntype TokenPointerTarget<TMode extends InteractionManagerMode> =\n ResolvedTokenTarget<TMode>;\n\ntype HoverableLinePointerTarget<TMode extends InteractionManagerMode> =\n | LinePointerTarget<TMode>\n | TokenPointerTarget<TMode>;\n\ninterface SessionIdle {\n mode: 'idle';\n}\n\ninterface SessionSelecting {\n mode: 'selecting';\n pointerId: number;\n}\n\ninterface SessionPendingSingleLineUnselect {\n mode: 'pendingSingleLineUnselect';\n pointerId: number;\n anchor: SelectionPoint;\n pending: SelectionPoint;\n}\n\ninterface SessionGutterSelecting {\n mode: 'gutterSelecting';\n pointerId: number;\n anchor: SelectionPoint;\n current: SelectionPoint;\n}\n\ntype PointerSession =\n | SessionIdle\n | SessionSelecting\n | SessionPendingSingleLineUnselect\n | SessionGutterSelecting;\n\nexport interface InteractionManagerBaseOptions<\n TMode extends InteractionManagerMode,\n> {\n lineHoverHighlight?: 'disabled' | 'both' | 'number' | 'line';\n enableTokenInteractionsOnWhitespace?: boolean;\n enableGutterUtility?: boolean;\n onGutterUtilityClick?(range: SelectedLineRange): unknown;\n onLineClick?(props: EventClickProps<TMode>): unknown;\n onLineNumberClick?(props: EventClickProps<TMode>): unknown;\n onLineEnter?(props: PointerEventEnterLeaveProps<TMode>): unknown;\n onLineLeave?(props: PointerEventEnterLeaveProps<TMode>): unknown;\n onTokenClick?(props: OnTokenEventProps<TMode>, event: MouseEvent): unknown;\n onTokenEnter?(props: OnTokenEventProps<TMode>, event: PointerEvent): unknown;\n onTokenLeave?(props: OnTokenEventProps<TMode>, event: PointerEvent): unknown;\n __debugPointerEvents?: LogTypes;\n enableLineSelection?: boolean;\n controlledSelection?: boolean;\n onLineSelected?: (range: SelectedLineRange | null) => void;\n onLineSelectionStart?: (range: SelectedLineRange | null) => void;\n onLineSelectionChange?: (range: SelectedLineRange | null) => void;\n onLineSelectionEnd?: (range: SelectedLineRange | null) => void;\n getLineIndex?: GetLineIndexUtility;\n}\n\nexport interface InteractionManagerOptions<\n TMode extends InteractionManagerMode,\n> extends InteractionManagerBaseOptions<TMode> {\n usesCustomGutterUtility?: boolean;\n onHunkExpand?(\n hunkIndex: number,\n direction: ExpansionDirections,\n expansionLineCountOverride?: number\n ): unknown;\n onMergeConflictActionClick?(target: MergeConflictActionTarget): void;\n}\n\ninterface HandlePointerEventProps {\n eventType: 'click' | 'move';\n event: PointerEvent | MouseEvent;\n}\n\nexport class InteractionManager<TMode extends InteractionManagerMode> {\n private hoveredLine: EventBaseProps<TMode> | undefined;\n private hoveredToken: OnTokenEventProps<TMode> | undefined;\n private pre: HTMLPreElement | undefined;\n\n private gutterUtilityLine: EventBaseProps<TMode> | undefined;\n private gutterUtilityContainer: HTMLDivElement | undefined;\n private gutterUtilityButton: HTMLButtonElement | undefined;\n private gutterUtilitySlot: HTMLSlotElement | undefined;\n\n private interactiveLinesAttr = false;\n private interactiveLineNumbersAttr = false;\n\n private hasPointerListeners = false;\n private hasDocumentPointerListeners = false;\n\n private selectedRange: SelectedLineRange | null = null;\n // When set, the active-line highlight is confined to this side's column in a\n // split diff (see SelectionWriteOptions.activeLineSide). Tracks the current\n // selectedRange and is cleared by any gutter-driven selection. Only the\n // editor's own active-line highlight sets a side, so a non-null value also\n // marks the selection as editor-driven (see highlightLineNumberOnly).\n private activeLineHighlightSide: SelectionSide | undefined;\n // When true, the active-line highlight marks only the gutter line number and\n // not the line background (see SelectionWriteOptions.lineNumberOnly).\n private activeLineNumberOnly = false;\n // True while an editor is attached (edit mode). The editor draws selection as\n // text, so a host or gutter line selection then highlights only the gutter\n // line numbers, never the full-line background.\n private editorAttached = false;\n private proposedSelectedRange: SelectedLineRange | null | undefined;\n private renderedSelectionRange: SelectedLineRange | null | undefined;\n private selectionAnchor: SelectionPoint | undefined;\n private queuedSelectionRender: number | undefined;\n private pointerSession: PointerSession = { mode: 'idle' };\n\n constructor(\n private mode: TMode,\n private options: InteractionManagerOptions<TMode>\n ) {}\n\n setOptions(options: InteractionManagerOptions<TMode>): void {\n this.options = options;\n }\n\n cleanUp(): void {\n this.pre?.removeEventListener('click', this.handlePointerClick);\n this.pre?.removeEventListener('pointerdown', this.handlePointerDown);\n this.pre?.removeEventListener('pointermove', this.handlePointerMove);\n this.pre?.removeEventListener('pointerleave', this.handlePointerLeave);\n this.pre?.removeAttribute('data-interactive-lines');\n this.pre?.removeAttribute('data-interactive-line-numbers');\n this.pre = undefined;\n this.gutterUtilityContainer?.remove();\n this.gutterUtilityLine = undefined;\n this.gutterUtilityContainer = undefined;\n this.gutterUtilityButton = undefined;\n this.gutterUtilitySlot = undefined;\n this.clearHoveredLine();\n this.clearHoveredToken();\n this.detachDocumentPointerListeners();\n this.clearPointerSession();\n if (this.queuedSelectionRender != null) {\n cancelAnimationFrame(this.queuedSelectionRender);\n this.queuedSelectionRender = undefined;\n }\n this.interactiveLinesAttr = false;\n this.interactiveLineNumbersAttr = false;\n this.hasPointerListeners = false;\n }\n\n setup(pre: HTMLPreElement): void {\n this.setSelectionDirty();\n const { usesCustomGutterUtility = false, enableGutterUtility = false } =\n this.options;\n\n const newContainer = this.pre !== pre;\n if (newContainer) {\n this.cleanUp();\n this.pre = pre;\n }\n\n if (enableGutterUtility) {\n this.ensureGutterUtilityNode(usesCustomGutterUtility);\n } else if (this.gutterUtilityContainer != null) {\n this.gutterUtilityContainer.remove();\n this.gutterUtilityLine = undefined;\n this.gutterUtilityContainer = undefined;\n this.gutterUtilityButton = undefined;\n this.gutterUtilitySlot = undefined;\n if (this.pointerSession.mode === 'gutterSelecting') {\n this.clearPointerSession();\n this.detachDocumentPointerListeners();\n }\n }\n\n this.syncPointerListeners(pre);\n this.updateInteractiveLineAttributes();\n this.renderSelection();\n this.placeUtility();\n }\n\n setSelectionDirty(): void {\n this.renderedSelectionRange = undefined;\n }\n\n // Toggle edit mode. While an editor is attached, host and gutter line\n // selections are shown as gutter-number-only highlights (the editor renders\n // the selected text itself), so the full-line background is suppressed.\n setEditorAttached(attached: boolean): void {\n if (this.editorAttached === attached) {\n return;\n }\n this.editorAttached = attached;\n this.setSelectionDirty();\n this.renderSelection();\n }\n\n isSelectionDirty(): boolean {\n return this.renderedSelectionRange === null;\n }\n\n setSelection(\n range: SelectedLineRange | null,\n options?: SelectionWriteOptions\n ): void {\n const isRangeChange = !(\n range === this.selectedRange ||\n areSelectionsEqual(range ?? undefined, this.selectedRange ?? undefined)\n );\n if (!this.isSelectionDirty() && !isRangeChange) {\n return;\n }\n this.proposedSelectedRange = undefined;\n this.selectedRange = range;\n this.activeLineHighlightSide = options?.activeLineSide;\n this.activeLineNumberOnly = options?.lineNumberOnly ?? false;\n this.renderSelection();\n this.placeUtility();\n if (isRangeChange && options?.notify !== false) {\n this.notifySelectionCommitted();\n }\n }\n\n getSelection(): SelectedLineRange | null {\n return this.selectedRange;\n }\n\n getHoveredLine = (): GetHoveredLineResult<TMode> | undefined => {\n const gutterUtilityLine = this.gutterUtilityLine ?? this.hoveredLine;\n if (gutterUtilityLine != null) {\n if (this.mode === 'diff' && gutterUtilityLine.type === 'diff-line') {\n return {\n lineNumber: gutterUtilityLine.lineNumber,\n side: gutterUtilityLine.annotationSide,\n } as GetHoveredLineResult<TMode>;\n }\n if (this.mode === 'file' && gutterUtilityLine.type === 'line') {\n return {\n lineNumber: gutterUtilityLine.lineNumber,\n } as GetHoveredLineResult<TMode>;\n }\n }\n return undefined;\n };\n\n handlePointerClick = (event: MouseEvent): void => {\n const {\n onHunkExpand,\n onLineClick,\n onLineNumberClick,\n onTokenClick,\n onMergeConflictActionClick,\n } = this.options;\n if (\n onHunkExpand == null &&\n onLineClick == null &&\n onLineNumberClick == null &&\n onMergeConflictActionClick == null &&\n onTokenClick == null\n ) {\n return;\n }\n if (\n this.options.onGutterUtilityClick != null &&\n isGutterUtilityPath(event.composedPath())\n ) {\n return;\n }\n debugLogIfEnabled(\n this.options.__debugPointerEvents,\n 'click',\n 'FileDiff.DEBUG.handlePointerClick:',\n event\n );\n this.handlePointerEvent({ eventType: 'click', event });\n };\n\n handlePointerMove = (event: PointerEvent): void => {\n // Touch and pen moves are active drag/scroll gestures, not hover. Keeping\n // hover mouse-only prevents content scrolls from leaving stale utilities.\n if (event.pointerType !== 'mouse') {\n return;\n }\n\n const {\n lineHoverHighlight = 'disabled',\n onLineEnter,\n onLineLeave,\n onTokenEnter,\n onTokenLeave,\n enableGutterUtility = false,\n } = this.options;\n if (\n lineHoverHighlight === 'disabled' &&\n !enableGutterUtility &&\n onLineEnter == null &&\n onLineLeave == null &&\n onTokenEnter == null &&\n onTokenLeave == null\n ) {\n return;\n }\n debugLogIfEnabled(\n this.options.__debugPointerEvents,\n 'move',\n 'FileDiff.DEBUG.handlePointerMove:',\n event\n );\n // should we perhaps throttle this a bit because move can be fast as fuk\n // boiiii\n this.handlePointerEvent({ eventType: 'move', event });\n };\n\n handlePointerLeave = (event: PointerEvent): void => {\n const { __debugPointerEvents } = this.options;\n debugLogIfEnabled(\n __debugPointerEvents,\n 'move',\n 'FileDiff.DEBUG.handlePointerLeave: no event'\n );\n if (this.hoveredLine == null && this.hoveredToken == null) {\n debugLogIfEnabled(\n __debugPointerEvents,\n 'move',\n 'FileDiff.DEBUG.handlePointerLeave: returned early, no hovered line or token'\n );\n return;\n }\n if (this.hoveredToken != null) {\n this.options.onTokenLeave?.(this.hoveredToken, event);\n this.clearHoveredToken();\n }\n\n if (this.hoveredLine != null) {\n this.options.onLineLeave?.({\n ...this.hoveredLine,\n event,\n } as PointerEventEnterLeaveProps<TMode>);\n this.clearHoveredLine();\n }\n this.placeUtility();\n };\n\n private handlePointerEvent({ eventType, event }: HandlePointerEventProps) {\n const { __debugPointerEvents } = this.options;\n const composedPath = event.composedPath();\n debugLogIfEnabled(\n __debugPointerEvents,\n eventType,\n 'FileDiff.DEBUG.handlePointerEvent:',\n { eventType, composedPath }\n );\n const target = this.resolvePointerTarget(composedPath);\n debugLogIfEnabled(\n __debugPointerEvents,\n eventType,\n 'FileDiff.DEBUG.handlePointerEvent: resolvePointerTarget result:',\n target\n );\n\n const {\n onLineClick,\n onLineNumberClick,\n onLineEnter,\n onLineLeave,\n onTokenClick,\n onTokenEnter,\n onTokenLeave,\n onHunkExpand,\n onMergeConflictActionClick,\n } = this.options;\n\n switch (eventType) {\n case 'move': {\n const sameLine =\n isHoverableLinePointerTarget(target) &&\n this.hoveredLine?.lineElement === target.lineElement;\n const sameToken =\n isTokenPointerTarget(target) &&\n this.hoveredToken?.tokenElement === target.tokenElement;\n\n // Handle token transitions\n if (!sameToken) {\n if (this.hoveredToken != null) {\n onTokenLeave?.(this.hoveredToken, event as PointerEvent);\n this.clearHoveredToken();\n }\n if (isTokenPointerTarget(target)) {\n this.setHoveredToken(this.toTokenEventBaseProps(target));\n onTokenEnter?.(\n this.hoveredToken as OnTokenEventProps<TMode>,\n event as PointerEvent\n );\n }\n }\n\n // Handle line transitions\n if (!sameLine) {\n if (this.hoveredLine != null) {\n onLineLeave?.({\n ...this.hoveredLine,\n event: event as PointerEvent,\n } as PointerEventEnterLeaveProps<TMode>);\n this.clearHoveredLine();\n }\n if (isHoverableLinePointerTarget(target)) {\n this.setHoveredLine(this.toEventBaseProps(target));\n this.placeUtility();\n onLineEnter?.({\n ...this.hoveredLine,\n event: event as PointerEvent,\n } as PointerEventEnterLeaveProps<TMode>);\n } else {\n this.placeUtility();\n }\n }\n break;\n }\n case 'click': {\n if (target == null) {\n break;\n }\n if (\n isMergeConflictActionPointerTarget(target) &&\n onMergeConflictActionClick != null\n ) {\n onMergeConflictActionClick(target);\n break;\n }\n if (isExpandoPointerTarget(target) && onHunkExpand != null) {\n onHunkExpand(\n target.hunkIndex,\n target.all || event.shiftKey ? 'both' : target.direction,\n target.all || event.shiftKey ? Number.POSITIVE_INFINITY : undefined\n );\n break;\n }\n\n if (!isHoverableLinePointerTarget(target)) {\n break;\n }\n\n if (isTokenPointerTarget(target) && onTokenClick != null) {\n onTokenClick(this.toTokenEventBaseProps(target), event as MouseEvent);\n }\n\n const eventBase = this.toEventBaseProps(target);\n if (onLineNumberClick != null && target.numberColumn) {\n onLineNumberClick({\n ...eventBase,\n event: event as PointerEvent,\n } as EventClickProps<TMode>);\n } else if (onLineClick != null) {\n onLineClick({\n ...eventBase,\n event: event as PointerEvent,\n } as EventClickProps<TMode>);\n }\n break;\n }\n }\n }\n\n private syncPointerListeners(pre: HTMLPreElement): void {\n const {\n __debugPointerEvents,\n lineHoverHighlight = 'disabled',\n onLineClick,\n onLineNumberClick,\n onLineEnter,\n onLineLeave,\n onTokenClick,\n onTokenEnter,\n onTokenLeave,\n onHunkExpand,\n onMergeConflictActionClick,\n enableGutterUtility = false,\n enableLineSelection = false,\n onGutterUtilityClick,\n } = this.options;\n const enableGutterSelection = onGutterUtilityClick != null;\n const shouldAttachPointerListeners =\n lineHoverHighlight !== 'disabled' ||\n onLineClick != null ||\n onLineNumberClick != null ||\n onLineEnter != null ||\n onLineLeave != null ||\n onTokenClick != null ||\n onTokenEnter != null ||\n onTokenLeave != null ||\n onHunkExpand != null ||\n onMergeConflictActionClick != null ||\n enableGutterUtility ||\n enableLineSelection ||\n enableGutterSelection;\n\n if (shouldAttachPointerListeners && !this.hasPointerListeners) {\n pre.addEventListener('click', this.handlePointerClick);\n pre.addEventListener('pointerdown', this.handlePointerDown);\n pre.addEventListener('pointermove', this.handlePointerMove);\n pre.addEventListener('pointerleave', this.handlePointerLeave);\n this.hasPointerListeners = true;\n\n debugLogIfEnabled(\n __debugPointerEvents,\n 'click',\n 'FileDiff.DEBUG.attachEventListeners: Attaching click events for:',\n (() => {\n const reasons: string[] = [];\n if (\n __debugPointerEvents === 'both' ||\n __debugPointerEvents === 'click'\n ) {\n if (onLineClick != null) {\n reasons.push('onLineClick');\n }\n if (onLineNumberClick != null) {\n reasons.push('onLineNumberClick');\n }\n if (onHunkExpand != null) {\n reasons.push('expandable hunk separators');\n }\n if (onMergeConflictActionClick != null) {\n reasons.push('merge conflict actions');\n }\n }\n return reasons;\n })()\n );\n debugLogIfEnabled(\n __debugPointerEvents,\n 'move',\n 'FileDiff.DEBUG.attachEventListeners: Attaching pointer move event'\n );\n debugLogIfEnabled(\n __debugPointerEvents,\n 'move',\n 'FileDiff.DEBUG.attachEventListeners: Attaching pointer leave event'\n );\n } else if (!shouldAttachPointerListeners && this.hasPointerListeners) {\n pre.removeEventListener('click', this.handlePointerClick);\n pre.removeEventListener('pointerdown', this.handlePointerDown);\n pre.removeEventListener('pointermove', this.handlePointerMove);\n pre.removeEventListener('pointerleave', this.handlePointerLeave);\n this.hasPointerListeners = false;\n }\n\n const hasActiveLineSelectionSession =\n this.pointerSession.mode === 'selecting' ||\n this.pointerSession.mode === 'pendingSingleLineUnselect';\n const hasActiveGutterSelectionSession =\n this.pointerSession.mode === 'gutterSelecting';\n if (\n (!enableLineSelection && hasActiveLineSelectionSession) ||\n (!enableGutterSelection && hasActiveGutterSelectionSession)\n ) {\n this.clearPointerSession();\n this.detachDocumentPointerListeners();\n this.selectionAnchor = undefined;\n this.clearPendingSingleLineState();\n }\n }\n\n private updateInteractiveLineAttributes(): void {\n if (this.pre == null) {\n return;\n }\n\n const {\n onLineClick,\n onLineNumberClick,\n enableLineSelection = false,\n } = this.options;\n\n const shouldHaveInteractiveLines = onLineClick != null;\n const shouldHaveInteractiveLineNumbers =\n onLineNumberClick != null || enableLineSelection;\n\n if (shouldHaveInteractiveLines && !this.interactiveLinesAttr) {\n this.pre.setAttribute('data-interactive-lines', '');\n this.interactiveLinesAttr = true;\n } else if (!shouldHaveInteractiveLines && this.interactiveLinesAttr) {\n this.pre.removeAttribute('data-interactive-lines');\n this.interactiveLinesAttr = false;\n }\n\n if (shouldHaveInteractiveLineNumbers && !this.interactiveLineNumbersAttr) {\n this.pre.setAttribute('data-interactive-line-numbers', '');\n this.interactiveLineNumbersAttr = true;\n } else if (\n !shouldHaveInteractiveLineNumbers &&\n this.interactiveLineNumbersAttr\n ) {\n this.pre.removeAttribute('data-interactive-line-numbers');\n this.interactiveLineNumbersAttr = false;\n }\n }\n\n private handlePointerDown = (event: PointerEvent): void => {\n if (\n (event.pointerType === 'mouse' && event.button !== 0) ||\n this.pre == null ||\n this.pointerSession.mode !== 'idle'\n ) {\n return;\n }\n\n const path = event.composedPath();\n if (\n isGutterUtilityPath(path) &&\n this.options.onGutterUtilityClick != null\n ) {\n this.startGutterSelectionFromPointerDown(event);\n } else {\n if (event.pointerType !== 'mouse') {\n this.revealUtilityFromGutterPath(path);\n }\n this.startLineSelectionFromPointerDown(event);\n }\n };\n\n private startLineSelectionFromPointerDown(event: PointerEvent): void {\n const { enableLineSelection = false } = this.options;\n if (!enableLineSelection) {\n return;\n }\n\n const pointerInfo = this.resolveSelectionInfo(event, {\n source: 'event-path',\n requireNumberColumn: true,\n });\n if (pointerInfo == null) {\n return;\n }\n\n const { pre } = this;\n if (pre == null) {\n return;\n }\n\n event.preventDefault();\n const { lineNumber, eventSide, lineIndex } = pointerInfo;\n\n if (event.shiftKey && this.selectedRange != null) {\n const rowRange = this.getIndexesFromSelection(\n this.selectedRange,\n pre.getAttribute('data-diff-type') === 'split'\n );\n if (rowRange == null) {\n return;\n }\n const useStart =\n rowRange.start <= rowRange.end\n ? lineIndex >= rowRange.start\n : lineIndex <= rowRange.end;\n this.selectionAnchor = {\n lineNumber: useStart\n ? this.selectedRange.start\n : this.selectedRange.end,\n side: useStart\n ? this.selectedRange.side\n : (this.selectedRange.endSide ?? this.selectedRange.side),\n };\n this.updateSelection(lineNumber, eventSide, false);\n this.notifySelectionStart(this.getCurrentSelectionRange());\n this.pointerSession = { mode: 'selecting', pointerId: event.pointerId };\n this.attachDocumentPointerListeners();\n return;\n }\n\n if (\n this.selectedRange?.start === lineNumber &&\n this.selectedRange?.end === lineNumber\n ) {\n const point = { lineNumber, side: eventSide };\n this.selectionAnchor = point;\n this.pointerSession = {\n mode: 'pendingSingleLineUnselect',\n pointerId: event.pointerId,\n anchor: point,\n pending: point,\n };\n this.attachDocumentPointerListeners();\n return;\n }\n\n if (this.options.controlledSelection === true) {\n this.proposedSelectedRange = null;\n } else {\n this.selectedRange = null;\n }\n this.placeUtility();\n this.selectionAnchor = { lineNumber, side: eventSide };\n this.updateSelection(lineNumber, eventSide, false);\n this.notifySelectionStart(this.getCurrentSelectionRange());\n this.pointerSession = { mode: 'selecting', pointerId: event.pointerId };\n this.attachDocumentPointerListeners();\n }\n\n private startGutterSelectionFromPointerDown(event: PointerEvent): void {\n const { enableLineSelection = false, onGutterUtilityClick } = this.options;\n if (onGutterUtilityClick == null) {\n return;\n }\n // If a selection already exists, the utility represents that whole range.\n // Dragging should start from the visual top and extend from the visual\n // bottom, regardless of the direction the range was originally created.\n const selectedEndpoints = this.currentSelectionEnds();\n const point =\n selectedEndpoints?.bottom ??\n this.resolveSelectionPoint(event, {\n source: 'event-path',\n excludeUtility: false,\n });\n const anchor = selectedEndpoints?.top ?? point;\n if (point == null || anchor == null) {\n return;\n }\n event.preventDefault();\n event.stopPropagation();\n this.pointerSession = {\n mode: 'gutterSelecting',\n pointerId: event.pointerId,\n anchor,\n current: point,\n };\n if (enableLineSelection) {\n this.selectionAnchor = {\n lineNumber: anchor.lineNumber,\n side: anchor.side,\n };\n this.updateSelection(point.lineNumber, point.side, false);\n this.notifySelectionStart(this.getCurrentSelectionRange());\n }\n this.attachDocumentPointerListeners();\n }\n\n private handleDocumentPointerMove = (event: PointerEvent): void => {\n const { enableLineSelection = false } = this.options;\n switch (this.pointerSession.mode) {\n case 'idle':\n return;\n case 'gutterSelecting': {\n if (event.pointerId !== this.pointerSession.pointerId) {\n return;\n }\n event.preventDefault();\n const point = this.resolveSelectionPoint(event, {\n source: 'coordinates-first',\n });\n if (point == null) {\n return;\n }\n this.pointerSession.current = point;\n if (enableLineSelection === true) {\n this.updateSelection(point.lineNumber, point.side);\n }\n return;\n }\n case 'selecting': {\n if (event.pointerId !== this.pointerSession.pointerId) {\n return;\n }\n event.preventDefault();\n const pointerInfo = this.resolveSelectionInfo(event, {\n source: 'coordinates-first',\n requireNumberColumn: false,\n });\n if (pointerInfo == null || this.selectionAnchor == null) {\n return;\n }\n this.updateSelection(pointerInfo.lineNumber, pointerInfo.eventSide);\n return;\n }\n case 'pendingSingleLineUnselect': {\n if (event.pointerId !== this.pointerSession.pointerId) {\n return;\n }\n event.preventDefault();\n const pointerInfo = this.resolveSelectionInfo(event, {\n source: 'coordinates-first',\n requireNumberColumn: false,\n });\n if (pointerInfo == null || this.selectionAnchor == null) {\n return;\n }\n const point = {\n lineNumber: pointerInfo.lineNumber,\n side: pointerInfo.eventSide,\n };\n if (areSelectionPointsEqual(this.pointerSession.pending, point)) {\n return;\n }\n this.updateSelection(\n pointerInfo.lineNumber,\n pointerInfo.eventSide,\n false\n );\n this.notifySelectionStart(this.getCurrentSelectionRange());\n this.notifySelectionChangeDelta();\n this.pointerSession = {\n mode: 'selecting',\n pointerId: event.pointerId,\n };\n return;\n }\n }\n };\n\n private handleDocumentPointerUp = (event: PointerEvent): void => {\n const { enableLineSelection = false, onGutterUtilityClick } = this.options;\n switch (this.pointerSession.mode) {\n case 'idle':\n return;\n case 'gutterSelecting': {\n if (event.pointerId !== this.pointerSession.pointerId) {\n return;\n }\n event.preventDefault();\n const point = this.resolveSelectionPoint(event, {\n source: 'coordinates-first',\n });\n if (point != null) {\n this.pointerSession.current = point;\n if (enableLineSelection) {\n this.updateSelection(point.lineNumber, point.side);\n }\n }\n onGutterUtilityClick?.(\n this.buildSelectedLineRange(\n this.pointerSession.anchor,\n this.pointerSession.current\n )\n );\n this.selectionAnchor = undefined;\n if (enableLineSelection) {\n this.notifySelectionEnd(this.getCurrentSelectionRange());\n this.notifySelectionCommitted();\n this.clearProposedSelection();\n }\n this.clearPointerSession();\n this.detachDocumentPointerListeners();\n return;\n }\n case 'pendingSingleLineUnselect': {\n if (event.pointerId !== this.pointerSession.pointerId) {\n return;\n }\n event.preventDefault();\n this.updateSelection(null, undefined, false);\n this.selectionAnchor = undefined;\n this.clearPendingSingleLineState();\n this.detachDocumentPointerListeners();\n this.notifySelectionEnd(this.getCurrentSelectionRange());\n this.notifySelectionCommitted();\n this.clearProposedSelection();\n return;\n }\n case 'selecting': {\n if (event.pointerId !== this.pointerSession.pointerId) {\n return;\n }\n event.preventDefault();\n this.selectionAnchor = undefined;\n this.detachDocumentPointerListeners();\n this.clearPointerSession();\n this.notifySelectionEnd(this.getCurrentSelectionRange());\n this.notifySelectionCommitted();\n this.clearProposedSelection();\n }\n }\n };\n\n private handleDocumentPointerCancel = (event: PointerEvent): void => {\n switch (this.pointerSession.mode) {\n case 'idle':\n return;\n case 'gutterSelecting':\n case 'selecting':\n case 'pendingSingleLineUnselect': {\n if ('pointerId' in this.pointerSession) {\n if (event.pointerId !== this.pointerSession.pointerId) {\n return;\n }\n }\n this.selectionAnchor = undefined;\n this.clearProposedSelection();\n this.clearPendingSingleLineState();\n this.clearPointerSession();\n this.detachDocumentPointerListeners();\n }\n }\n };\n\n private clearHoveredLine() {\n if (this.hoveredLine == null) {\n return;\n }\n this.hoveredLine.lineElement.removeAttribute('data-hovered');\n this.hoveredLine.numberElement.removeAttribute('data-hovered');\n this.hoveredLine = undefined;\n }\n\n private setHoveredLine(hoveredLine: EventBaseProps<TMode>) {\n const { lineHoverHighlight = 'disabled' } = this.options;\n if (this.hoveredLine != null) {\n this.clearHoveredLine();\n }\n this.hoveredLine = hoveredLine;\n if (lineHoverHighlight !== 'disabled') {\n if (lineHoverHighlight === 'both' || lineHoverHighlight === 'line') {\n this.hoveredLine.lineElement.setAttribute('data-hovered', '');\n }\n if (lineHoverHighlight === 'both' || lineHoverHighlight === 'number') {\n this.hoveredLine.numberElement.setAttribute('data-hovered', '');\n }\n }\n }\n\n private clearHoveredToken() {\n if (this.hoveredToken == null) {\n return;\n }\n this.hoveredToken = undefined;\n }\n\n private setHoveredToken(hoveredToken: OnTokenEventProps<TMode>) {\n if (this.hoveredToken != null) {\n this.clearHoveredToken();\n }\n this.hoveredToken = hoveredToken;\n }\n\n private ensureGutterUtilityNode(useCustomGutterUtility: boolean): void {\n if (this.gutterUtilityContainer == null) {\n this.gutterUtilityContainer = document.createElement('div');\n this.gutterUtilityContainer.setAttribute('data-gutter-utility-slot', '');\n }\n if (useCustomGutterUtility) {\n if (this.gutterUtilityButton != null) {\n this.gutterUtilityButton.remove();\n this.gutterUtilityButton = undefined;\n }\n if (this.gutterUtilitySlot == null) {\n this.gutterUtilitySlot = document.createElement('slot');\n this.gutterUtilitySlot.name = 'gutter-utility-slot';\n }\n if (this.gutterUtilitySlot.parentNode !== this.gutterUtilityContainer) {\n this.gutterUtilityContainer.replaceChildren(this.gutterUtilitySlot);\n }\n } else {\n this.gutterUtilitySlot?.remove();\n this.gutterUtilitySlot = undefined;\n if (this.gutterUtilityButton == null) {\n const tempDiv = document.createElement('div');\n tempDiv.innerHTML = toHtml(createGutterUtilityElement());\n const utilityButton = tempDiv.firstElementChild;\n if (!(utilityButton instanceof HTMLButtonElement)) {\n throw new Error(\n 'InteractionManager.ensureGutterUtilityNode: Node element should be a button'\n );\n }\n utilityButton.remove();\n this.gutterUtilityButton = utilityButton;\n }\n if (this.gutterUtilityButton.parentNode !== this.gutterUtilityContainer) {\n this.gutterUtilityContainer.replaceChildren(this.gutterUtilityButton);\n }\n }\n }\n\n private revealUtilityFromGutterPath(path: (EventTarget | undefined)[]): void {\n if (this.placeUtilityFromSelection()) {\n return;\n }\n const target = this.resolvePointerTarget(path);\n if (isLinePointerTarget(target) && target.numberColumn) {\n this.showUtilityOnLine(this.toEventBaseProps(target));\n }\n }\n\n // The gutter utility follows the active selection first because a selected\n // range is more stable than transient hover/touch state. Without a\n // selection, desktop hover and mobile tap reveal can still place it on a\n // single row.\n private placeUtility(): void {\n if (this.placeUtilityFromSelection()) {\n return;\n }\n if (this.hoveredLine != null) {\n this.showUtilityOnLine(this.hoveredLine);\n return;\n }\n this.hideUtility();\n }\n\n private placeUtilityFromSelection(): boolean {\n const endpoints = this.currentSelectionEnds();\n if (endpoints == null) {\n return false;\n }\n const target = this.targetForSelectionPoint(endpoints.bottom);\n if (target == null) {\n this.hideUtility();\n } else {\n this.showUtilityOnLine(this.toEventBaseProps(target));\n }\n return true;\n }\n\n private showUtilityOnLine(line: EventBaseProps<TMode>): void {\n if (this.gutterUtilityContainer == null) {\n return;\n }\n this.gutterUtilityLine = line;\n line.numberElement.appendChild(this.gutterUtilityContainer);\n }\n\n private hideUtility(): void {\n this.gutterUtilityContainer?.remove();\n this.gutterUtilityLine = undefined;\n }\n\n // Selection ranges preserve drag direction, so compare rendered row indexes to\n // find the visually top-most and bottom-most endpoints.\n private currentSelectionEnds(): SelectionEnds | undefined {\n const range = this.getCurrentSelectionRange();\n return range == null ? undefined : this.selectionEnds(range);\n }\n\n private selectionEnds(range: SelectedLineRange): SelectionEnds | undefined {\n const start: SelectionPoint = {\n lineNumber: range.start,\n side: range.side,\n };\n const end: SelectionPoint = {\n lineNumber: range.end,\n side: range.endSide ?? range.side,\n };\n const startIndex = this.selectionPointRowIndex(start);\n const endIndex = this.selectionPointRowIndex(end);\n if (startIndex == null || endIndex == null) {\n return undefined;\n }\n return startIndex > endIndex\n ? { top: end, bottom: start }\n : { top: start, bottom: end };\n }\n\n private selectionPointRowIndex(point: SelectionPoint): number | undefined {\n const indexes = this.getLineIndex(point.lineNumber, point.side);\n if (indexes == null) {\n return undefined;\n }\n return this.isSplitDiff() ? indexes[1] : indexes[0];\n }\n\n private targetForSelectionPoint(\n point: SelectionPoint\n ): LinePointerTarget<TMode> | undefined {\n if (this.pre == null) {\n return undefined;\n }\n const indexes = this.getLineIndex(point.lineNumber, point.side);\n if (indexes == null) {\n return undefined;\n }\n const lineIndex =\n this.mode === 'diff' ? `${indexes[0]},${indexes[1]}` : `${indexes[0]}`;\n // Rebuild the real gutter-row target from the selection point so the\n // utility can anchor to the visible row even when the point came from\n // controlled state rather than a pointer event.\n const candidates = this.pre.querySelectorAll(\n `[data-column-number=\"${point.lineNumber}\"][data-line-index=\"${lineIndex}\"]`\n );\n for (const element of candidates) {\n if (!(element instanceof HTMLElement)) {\n continue;\n }\n const target = this.resolvePointerTarget(getElementPath(element));\n if (!isLinePointerTarget(target)) {\n continue;\n }\n if (\n this.mode === 'diff' &&\n point.side != null &&\n target.side !== point.side\n ) {\n continue;\n }\n return target;\n }\n return undefined;\n }\n\n private attachDocumentPointerListeners(): void {\n if (this.hasDocumentPointerListeners) {\n return;\n }\n document.addEventListener('pointermove', this.handleDocumentPointerMove);\n document.addEventListener('pointerup', this.handleDocumentPointerUp);\n document.addEventListener(\n 'pointercancel',\n this.handleDocumentPointerCancel\n );\n this.hasDocumentPointerListeners = true;\n }\n\n private detachDocumentPointerListeners(): void {\n if (!this.hasDocumentPointerListeners) {\n return;\n }\n document.removeEventListener('pointermove', this.handleDocumentPointerMove);\n document.removeEventListener('pointerup', this.handleDocumentPointerUp);\n document.removeEventListener(\n 'pointercancel',\n this.handleDocumentPointerCancel\n );\n this.hasDocumentPointerListeners = false;\n }\n\n private clearPointerSession(): void {\n this.pointerSession = { mode: 'idle' };\n }\n\n private clearPendingSingleLineState(): void {\n if (this.pointerSession.mode === 'pendingSingleLineUnselect') {\n this.pointerSession = { mode: 'idle' };\n }\n }\n\n private selectionInfoFromPath(\n path: (EventTarget | undefined)[],\n requireNumberColumn: boolean\n ): SelectionInfo | undefined {\n const target = this.resolvePointerTarget(path);\n if (!isLinePointerTarget(target)) {\n return undefined;\n }\n if (requireNumberColumn && !target.numberColumn) {\n return undefined;\n }\n if (target.splitLineIndex == null) {\n return undefined;\n }\n\n return {\n lineIndex: target.splitLineIndex,\n lineNumber: target.lineNumber,\n eventSide: this.mode === 'diff' ? target.side : undefined,\n };\n }\n\n private resolveSelectionInfo(\n event: PointerEvent,\n options: SelectionInfoOptions\n ): SelectionInfo | undefined {\n const path = this.resolveSelectionPath(event, options);\n return path != null\n ? this.selectionInfoFromPath(path, options.requireNumberColumn)\n : undefined;\n }\n\n private selectionPointFromPath(\n path: (EventTarget | undefined)[]\n ): SelectionPoint | undefined {\n const target = this.resolvePointerTarget(path);\n if (!isLinePointerTarget(target)) {\n return undefined;\n }\n return {\n lineNumber: target.lineNumber,\n side: this.mode === 'diff' ? target.side : undefined,\n };\n }\n\n private resolveSelectionPoint(\n event: PointerEvent,\n options: SelectionHitOptions\n ): SelectionPoint | undefined {\n const path = this.resolveSelectionPath(event, options);\n return path != null ? this.selectionPointFromPath(path) : undefined;\n }\n\n private resolveSelectionPath(\n event: PointerEvent,\n options: SelectionHitOptions\n ): (EventTarget | undefined)[] | undefined {\n const excludeUtility = options.excludeUtility !== false;\n switch (options.source) {\n case 'event-path':\n return this.pathFromEventPath(event.composedPath(), excludeUtility);\n case 'coordinates-first': {\n // Touch pointers can keep dispatching move/up events to the element\n // where the drag began. Prefer the row currently under the finger,\n // then fall back only when coordinate hit-testing is unavailable.\n const coordinatePath = this.pathFromCoordinates(event, excludeUtility);\n if (coordinatePath !== undefined) {\n return coordinatePath ?? undefined;\n }\n return this.pathFromEventPath(event.composedPath(), excludeUtility);\n }\n }\n }\n\n private pathFromCoordinates(\n event: PointerEvent,\n excludeUtility: boolean\n ): (EventTarget | undefined)[] | null | undefined {\n const coordinateTarget = this.hitTest(event);\n if (coordinateTarget === undefined) {\n return undefined;\n }\n if (coordinateTarget === null) {\n return null;\n }\n // A coordinate hit can be a token span, line-number span, utility overlay,\n // or separator. Normalize valid descendants back to their row; invalid\n // hits intentionally return null so the last selected row stays sticky.\n return this.pathFromElement(coordinateTarget, excludeUtility) ?? null;\n }\n\n private pathFromEventPath(\n path: (EventTarget | undefined)[],\n excludeUtility: boolean\n ): (EventTarget | undefined)[] | undefined {\n if (excludeUtility && isGutterUtilityPath(path)) {\n return undefined;\n }\n for (const element of path) {\n if (element instanceof Element) {\n return this.pathFromElement(element, excludeUtility);\n }\n }\n return undefined;\n }\n\n private pathFromElement(\n element: Element,\n excludeUtility: boolean\n ): (EventTarget | undefined)[] | undefined {\n const path = getElementPath(element);\n if (excludeUtility && isGutterUtilityPath(path)) {\n return undefined;\n }\n // Selection is row-based, not child-element-based. Lateral movement over\n // tokens, annotations, or line-number text should still update to the\n // nearest content or gutter row; anything else is ignored by returning\n // undefined.\n const row = closestSelectableRow(element);\n if (row != null) {\n return getElementPath(row);\n }\n return this.pathFromAnnotationSlot(element);\n }\n\n private pathFromAnnotationSlot(\n element: Element\n ): (EventTarget | undefined)[] | undefined {\n const point = selectionPointFromAnnotationSlotName(\n getAnnotationSlotName(element)\n );\n if (point == null) {\n return undefined;\n }\n const target = this.targetForSelectionPoint(point);\n return target != null ? getElementPath(target.lineElement) : undefined;\n }\n\n private hitTest(event: PointerEvent): Element | null | undefined {\n // Return undefined when coordinate hit-testing cannot run at all, which\n // allows callers to fall back to the event path for tests and older DOMs.\n // Return null when hit-testing ran but found no element, so active drags\n // keep their previous endpoint instead of using a stale captured target.\n if (!Number.isFinite(event.clientX) || !Number.isFinite(event.clientY)) {\n return undefined;\n }\n const root = this.pre?.getRootNode();\n const elementFromPointRoot = hasElementFromPoint(root)\n ? root\n : hasElementFromPoint(document)\n ? document\n : undefined;\n if (elementFromPointRoot == null) {\n return undefined;\n }\n const element = elementFromPointRoot.elementFromPoint(\n event.clientX,\n event.clientY\n );\n return element;\n }\n\n private getLineIndex(\n lineNumber: number,\n side?: SelectionSide\n ): [number, number] | undefined {\n const { getLineIndex } = this.options;\n return getLineIndex != null\n ? getLineIndex(lineNumber, side)\n : [lineNumber - 1, lineNumber - 1];\n }\n\n private getCurrentSelectionRange(): SelectedLineRange | null {\n return this.proposedSelectedRange !== undefined\n ? this.proposedSelectedRange\n : this.selectedRange;\n }\n\n private clearProposedSelection(): void {\n this.proposedSelectedRange = undefined;\n }\n\n private updateSelection(\n currentLine: number | null,\n side?: SelectionSide,\n emitChange = true\n ): void {\n const previousRange = this.getCurrentSelectionRange();\n let nextRange: SelectedLineRange | null;\n if (currentLine == null) {\n nextRange = null;\n } else {\n const anchorSide = this.selectionAnchor?.side ?? side;\n const anchorLine = this.selectionAnchor?.lineNumber ?? currentLine;\n nextRange = this.buildSelectionRange(\n anchorLine,\n currentLine,\n anchorSide,\n side\n );\n }\n if (\n areSelectionsEqual(previousRange ?? undefined, nextRange ?? undefined)\n ) {\n return;\n }\n // A gutter selection spans both columns and the full line, so drop any\n // side or number-only restriction left over from the editor's active-line\n // highlight.\n this.activeLineHighlightSide = undefined;\n this.activeLineNumberOnly = false;\n if (this.options.controlledSelection === true) {\n this.proposedSelectedRange = nextRange;\n } else {\n this.selectedRange = nextRange;\n this.queuedSelectionRender ??= requestAnimationFrame(\n this.renderSelection\n );\n }\n this.placeUtility();\n if (emitChange) {\n this.notifySelectionChangeDelta();\n }\n }\n\n private getIndexesFromSelection(\n selectedRange: SelectedLineRange,\n split: boolean\n ): { start: number; end: number } | undefined {\n if (this.pre == null) {\n return undefined;\n }\n const startIndexes = this.getLineIndex(\n selectedRange.start,\n selectedRange.side\n );\n const finalIndexes = this.getLineIndex(\n selectedRange.end,\n selectedRange.endSide ?? selectedRange.side\n );\n\n return startIndexes != null && finalIndexes != null\n ? {\n start: split ? startIndexes[1] : startIndexes[0],\n end: split ? finalIndexes[1] : finalIndexes[0],\n }\n : undefined;\n }\n\n // Whether to highlight only the gutter line number and leave the full-line\n // background for the editor's text selection. The decision splits on who drove\n // the selection, which activeLineHighlightSide records: the editor's own\n // active-line highlight always sets a side, while gutter and host selections\n // never do. Re-evaluated on every render so toggling edit mode\n // (setEditorAttached) reflows the current selection.\n private highlightLineNumberOnly(): boolean {\n // The editor's own side-confined active-line highlight controls the\n // background itself via lineNumberOnly: off for a bare caret (keep the\n // background), on once text is selected so the text selection is the only\n // line-level marker.\n if (this.activeLineHighlightSide != null) {\n return this.activeLineNumberOnly;\n }\n // A gutter or host line selection: number-only when the caller asked for it,\n // or while an editor is attached — in edit mode the editor renders the\n // selected text itself, so the full-line background gives way to it.\n return this.activeLineNumberOnly || this.editorAttached;\n }\n\n private renderSelection = (): void => {\n if (this.queuedSelectionRender != null) {\n cancelAnimationFrame(this.queuedSelectionRender);\n this.queuedSelectionRender = undefined;\n }\n if (\n this.pre == null ||\n this.renderedSelectionRange === this.selectedRange\n ) {\n return;\n }\n\n const allSelected = this.pre.querySelectorAll('[data-selected-line]');\n for (const element of allSelected) {\n element.removeAttribute('data-selected-line');\n }\n\n this.renderedSelectionRange = this.selectedRange;\n if (this.selectedRange == null) {\n return;\n }\n\n const { children: codeElements } = this.pre;\n if (codeElements.length === 0) {\n return;\n }\n if (codeElements.length > 2) {\n console.error(codeElements);\n throw new Error(\n 'InteractionManager.renderSelection: Somehow there are more than 2 code elements...'\n );\n }\n const split = this.pre.getAttribute('data-diff-type') === 'split';\n const rowRange = this.getIndexesFromSelection(this.selectedRange, split);\n if (rowRange == null) {\n console.error({ rowRange, selectedRange: this.selectedRange });\n throw new Error('InteractionManager.renderSelection: No valid rowRange');\n }\n const isSingle = rowRange.start === rowRange.end;\n const first = Math.min(rowRange.start, rowRange.end);\n const last = Math.max(rowRange.start, rowRange.end);\n const numberOnly = this.highlightLineNumberOnly();\n for (const code of codeElements) {\n // When the highlight is confined to one side (the editor's active-line\n // highlight), skip the opposite split-diff column. The deletions column\n // carries `data-deletions` and the additions column `data-additions`; a\n // unified or single-file column has neither, so it is never skipped.\n const side = this.activeLineHighlightSide;\n if (\n side != null &&\n ((side === 'additions' && code.hasAttribute('data-deletions')) ||\n (side === 'deletions' && code.hasAttribute('data-additions')))\n ) {\n continue;\n }\n const [gutter, content] = code.children;\n const len = content.children.length;\n if (len !== gutter.children.length) {\n throw new Error(\n 'InteractionManager.renderSelection: gutter and content children dont match, something is wrong'\n );\n }\n for (let i = 0; i < len; i++) {\n const contentElement = content.children[i];\n const gutterElement = gutter.children[i];\n if (\n !(contentElement instanceof HTMLElement) ||\n !(gutterElement instanceof HTMLElement)\n ) {\n continue;\n }\n\n const lineIndex = this.parseLineIndex(contentElement, split);\n if ((lineIndex ?? 0) > last) {\n break;\n }\n if (lineIndex == null || lineIndex < first) {\n continue;\n }\n let attributeValue = isSingle\n ? 'single'\n : lineIndex === first\n ? 'first'\n : lineIndex === last\n ? 'last'\n : '';\n gutterElement.setAttribute('data-selected-line', attributeValue);\n // A number-only highlight marks just the gutter number, leaving the\n // line background and any annotation rows untouched.\n if (numberOnly) {\n continue;\n }\n contentElement.setAttribute('data-selected-line', attributeValue);\n if (\n gutterElement.nextSibling instanceof HTMLElement &&\n contentElement.nextSibling instanceof HTMLElement &&\n (contentElement.nextSibling.hasAttribute('data-line-annotation') ||\n contentElement.nextSibling.hasAttribute(\n 'data-merge-conflict-actions'\n ))\n ) {\n if (isSingle) {\n attributeValue = 'last';\n contentElement.setAttribute('data-selected-line', 'first');\n } else if (lineIndex === first) {\n attributeValue = '';\n } else if (lineIndex === last) {\n contentElement.setAttribute('data-selected-line', '');\n }\n contentElement.nextSibling.setAttribute(\n 'data-selected-line',\n attributeValue\n );\n gutterElement.nextSibling.setAttribute(\n 'data-selected-line',\n attributeValue\n );\n }\n }\n }\n };\n\n private notifySelectionCommitted(): void {\n this.options.onLineSelected?.(this.getCurrentSelectionRange() ?? null);\n }\n\n private notifySelectionChangeDelta(): void {\n this.options.onLineSelectionChange?.(\n this.getCurrentSelectionRange() ?? null\n );\n }\n\n private notifySelectionStart(range: SelectedLineRange | null): void {\n this.options.onLineSelectionStart?.(range);\n }\n\n private notifySelectionEnd(range: SelectedLineRange | null): void {\n this.options.onLineSelectionEnd?.(range);\n }\n\n private toEventBaseProps(\n target: HoverableLinePointerTarget<TMode>\n ): EventBaseProps<TMode> {\n if (this.mode === 'file') {\n return {\n type: 'line',\n lineElement: target.lineElement,\n lineNumber: target.lineNumber,\n numberColumn: target.numberColumn,\n numberElement: target.numberElement,\n } as EventBaseProps<TMode>;\n }\n\n return {\n type: 'diff-line',\n annotationSide: target.side as AnnotationSide,\n lineType: target.lineType,\n lineElement: target.lineElement,\n numberElement: target.numberElement,\n lineNumber: target.lineNumber,\n numberColumn: target.numberColumn,\n } as EventBaseProps<TMode>;\n }\n\n private toTokenEventBaseProps({\n lineCharEnd,\n lineCharStart,\n lineNumber,\n side,\n tokenElement,\n tokenText,\n }: TokenPointerTarget<TMode>): OnTokenEventProps<TMode> {\n if (this.mode === 'file') {\n return {\n type: 'token',\n lineCharEnd,\n lineCharStart,\n lineNumber,\n tokenElement,\n tokenText,\n } as OnTokenEventProps<TMode>;\n }\n\n return {\n type: 'token',\n lineCharEnd,\n lineCharStart,\n lineNumber,\n side,\n tokenElement,\n tokenText,\n } as OnTokenEventProps<TMode>;\n }\n\n private buildSelectedLineRange(\n anchor: SelectionPoint,\n current: SelectionPoint\n ): SelectedLineRange {\n return this.buildSelectionRange(\n anchor.lineNumber,\n current.lineNumber,\n anchor.side,\n current.side\n );\n }\n\n private buildSelectionRange(\n start: number,\n end: number,\n side?: SelectionSide,\n endSide?: SelectionSide\n ): SelectedLineRange {\n return {\n start,\n end,\n ...(side != null ? { side } : {}),\n ...(side !== endSide && endSide != null ? { endSide } : {}),\n };\n }\n\n private resolvePointerTarget(\n path: (EventTarget | undefined)[]\n ): ResolvedPointerTarget<TMode> | undefined {\n let numberColumn = false;\n let lineType: LineTypes | undefined;\n let codeElement: HTMLElement | undefined;\n let lineElement: HTMLElement | undefined;\n let lineIndexValue: string | undefined;\n let numberElement: HTMLElement | undefined;\n let tokenElement: HTMLElement | undefined;\n let tokenInfo: TokenCache | undefined;\n let expandInfo: ExpandCache | undefined;\n let lineNumber: number | undefined;\n let mergeConflictActionTarget: MergeConflictActionTarget | undefined;\n\n for (const element of path) {\n if (!(element instanceof HTMLElement)) {\n continue;\n }\n\n if (\n mergeConflictActionTarget == null &&\n element.hasAttribute('data-merge-conflict-action')\n ) {\n const resolutionValue =\n element.getAttribute('data-merge-conflict-action') ?? undefined;\n const conflictIndexValue =\n element.getAttribute('data-merge-conflict-conflict-index') ??\n undefined;\n const conflictIndex =\n conflictIndexValue != null\n ? Number.parseInt(conflictIndexValue, 10)\n : Number.NaN;\n if (\n isMergeConflictResolution(resolutionValue) &&\n Number.isFinite(conflictIndex)\n ) {\n mergeConflictActionTarget = {\n kind: 'merge-conflict-action',\n resolution: resolutionValue,\n conflictIndex,\n };\n }\n }\n\n if (tokenElement == null && element.hasAttribute('data-char')) {\n tokenElement = element;\n const startAttr = element.getAttribute('data-char');\n\n if (startAttr != null) {\n const lineCharStart = Number.parseInt(startAttr, 10);\n if (!Number.isNaN(lineCharStart)) {\n const tokenText = element.textContent ?? '';\n const lineCharEnd = lineCharStart + tokenText.length;\n if (\n tokenText.trim() !== '' ||\n this.options.enableTokenInteractionsOnWhitespace === true\n ) {\n tokenInfo = {\n tokenElement,\n lineCharStart,\n lineCharEnd,\n tokenText,\n };\n }\n continue;\n }\n }\n }\n\n const columnNumber =\n numberElement == null\n ? (element.getAttribute('data-column-number') ?? undefined)\n : undefined;\n if (columnNumber != null) {\n numberElement = element;\n lineNumber = Number.parseInt(columnNumber, 10);\n numberColumn = true;\n lineType = getLineTypeFromElement(element);\n lineIndexValue = element.getAttribute('data-line-index') ?? undefined;\n continue;\n }\n\n const lineAttr =\n lineElement == null\n ? (element.getAttribute('data-line') ?? undefined)\n : undefined;\n if (lineAttr != null) {\n lineElement = element;\n lineNumber = Number.parseInt(lineAttr, 10);\n lineType = getLineTypeFromElement(element);\n lineIndexValue = element.getAttribute('data-line-index') ?? undefined;\n continue;\n }\n\n if (\n expandInfo == null &&\n (element.hasAttribute('data-expand-button') ||\n element.hasAttribute('data-unmodified-lines'))\n ) {\n expandInfo = {\n hunkIndex: undefined,\n direction: (() => {\n if (element.hasAttribute('data-expand-up')) {\n return 'up';\n }\n if (element.hasAttribute('data-expand-down')) {\n return 'down';\n }\n return 'both';\n })(),\n all: element.hasAttribute('data-expand-all-button'),\n };\n continue;\n }\n\n const expandIndexValue =\n expandInfo != null\n ? (element.getAttribute('data-expand-index') ?? undefined)\n : undefined;\n if (expandInfo != null && expandIndexValue != null) {\n const expandIndex = Number.parseInt(expandIndexValue, 10);\n if (!Number.isNaN(expandIndex)) {\n expandInfo.hunkIndex = expandIndex;\n }\n continue;\n }\n\n if (codeElement == null && element.hasAttribute('data-code')) {\n codeElement = element;\n break;\n }\n }\n\n if (mergeConflictActionTarget != null) {\n return mergeConflictActionTarget as ResolvedPointerTarget<TMode>;\n }\n\n if (expandInfo?.hunkIndex != null) {\n return {\n type: 'line-info',\n hunkIndex: expandInfo.hunkIndex,\n direction: expandInfo.direction,\n all: expandInfo.all,\n } as ResolvedPointerTarget<TMode>;\n }\n\n lineElement ??=\n lineIndexValue != null\n ? queryHTMLElement(\n codeElement,\n `[data-line][data-line-index=\"${lineIndexValue}\"]`\n )\n : undefined;\n numberElement ??=\n lineIndexValue != null\n ? queryHTMLElement(\n codeElement,\n `[data-column-number][data-line-index=\"${lineIndexValue}\"]`\n )\n : undefined;\n\n if (\n codeElement == null ||\n lineElement == null ||\n numberElement == null ||\n lineType == null ||\n lineNumber == null ||\n Number.isNaN(lineNumber)\n ) {\n return undefined;\n }\n\n const splitLineIndex = this.parseLineIndex(lineElement, this.isSplitDiff());\n\n if (tokenInfo != null) {\n if (this.mode === 'file') {\n return {\n kind: 'token',\n lineType,\n lineElement,\n lineNumber,\n numberColumn,\n numberElement,\n side: undefined,\n splitLineIndex,\n ...tokenInfo,\n } as ResolvedPointerTarget<TMode>;\n }\n\n return {\n kind: 'token',\n lineType,\n lineElement,\n lineNumber,\n numberColumn,\n numberElement,\n side: getAnnotationSide(lineType, codeElement),\n splitLineIndex,\n ...tokenInfo,\n } as ResolvedPointerTarget<TMode>;\n }\n\n // Otherwise return line target\n if (this.mode === 'file') {\n return {\n kind: 'line',\n lineType,\n lineElement,\n lineNumber,\n numberColumn,\n numberElement,\n side: undefined,\n splitLineIndex,\n } as ResolvedPointerTarget<TMode>;\n }\n\n return {\n kind: 'line',\n lineType,\n lineElement,\n lineNumber,\n numberColumn,\n numberElement,\n side: getAnnotationSide(lineType, codeElement),\n splitLineIndex,\n } as ResolvedPointerTarget<TMode>;\n }\n\n private isSplitDiff(): boolean {\n return this.pre?.getAttribute('data-diff-type') === 'split';\n }\n\n private parseLineIndex(\n element: HTMLElement,\n split: boolean\n ): number | undefined {\n const lineIndexes = (element.getAttribute('data-line-index') ?? '')\n .split(',')\n .map((value) => Number.parseInt(value, 10))\n .filter((value) => !Number.isNaN(value));\n\n if (split && lineIndexes.length === 2) {\n return lineIndexes[1];\n }\n if (!split) {\n return lineIndexes[0];\n }\n return undefined;\n }\n}\n\ntype InteractionPluckOptions<TMode extends InteractionManagerMode> =\n InteractionManagerBaseOptions<TMode> & {\n renderGutterUtility?(\n getHoveredRow: () => GetHoveredLineResult<TMode> | undefined\n ): HTMLElement | null | undefined;\n };\n\nexport function pluckInteractionOptions<TMode extends InteractionManagerMode>(\n {\n enableTokenInteractionsOnWhitespace,\n enableGutterUtility,\n lineHoverHighlight,\n onGutterUtilityClick,\n onLineClick,\n onLineEnter,\n onLineLeave,\n onLineNumberClick,\n onTokenClick,\n onTokenEnter,\n onTokenLeave,\n renderGutterUtility,\n __debugPointerEvents,\n enableLineSelection,\n controlledSelection,\n onLineSelected,\n onLineSelectionStart,\n onLineSelectionChange,\n onLineSelectionEnd,\n }: InteractionPluckOptions<TMode>,\n onHunkExpand?: (\n hunkIndex: number,\n direction: ExpansionDirections,\n expansionLineCountOverride?: number\n ) => unknown,\n getLineIndex?: GetLineIndexUtility,\n onMergeConflictActionClick?: (target: MergeConflictActionTarget) => void\n): InteractionManagerOptions<TMode> {\n return {\n enableTokenInteractionsOnWhitespace,\n enableGutterUtility: resolveEnableGutterUtilityOption({\n enableGutterUtility,\n renderGutterUtility,\n onGutterUtilityClick,\n }),\n usesCustomGutterUtility: renderGutterUtility != null,\n lineHoverHighlight,\n\n onGutterUtilityClick,\n onHunkExpand,\n onMergeConflictActionClick,\n onLineClick,\n onLineEnter,\n onLineLeave,\n onLineNumberClick,\n onTokenClick,\n onTokenEnter,\n onTokenLeave,\n __debugPointerEvents,\n\n enableLineSelection,\n controlledSelection,\n onLineSelected,\n onLineSelectionStart,\n onLineSelectionChange,\n onLineSelectionEnd,\n\n getLineIndex,\n };\n}\n\nfunction resolveEnableGutterUtilityOption<\n TMode extends InteractionManagerMode,\n>({\n enableGutterUtility,\n renderGutterUtility,\n onGutterUtilityClick,\n}: Pick<\n InteractionPluckOptions<TMode>,\n 'enableGutterUtility' | 'renderGutterUtility' | 'onGutterUtilityClick'\n>): boolean {\n if (onGutterUtilityClick != null && renderGutterUtility != null) {\n throw new Error(\n \"Cannot use both 'onGutterUtilityClick' and 'renderGutterUtility'. Use only one gutter utility API.\"\n );\n }\n return enableGutterUtility ?? false;\n}\n\nfunction isLinePointerTarget<TMode extends InteractionManagerMode>(\n target: ResolvedPointerTarget<TMode> | undefined\n): target is LinePointerTarget<TMode> {\n return target != null && 'kind' in target && target.kind === 'line';\n}\n\nfunction isTokenPointerTarget<TMode extends InteractionManagerMode>(\n target: ResolvedPointerTarget<TMode> | undefined\n): target is TokenPointerTarget<TMode> {\n return target != null && 'kind' in target && target.kind === 'token';\n}\n\nfunction isHoverableLinePointerTarget<TMode extends InteractionManagerMode>(\n target: ResolvedPointerTarget<TMode> | undefined\n): target is HoverableLinePointerTarget<TMode> {\n return isLinePointerTarget(target) || isTokenPointerTarget(target);\n}\n\nfunction isExpandoPointerTarget<TMode extends InteractionManagerMode>(\n target: ResolvedPointerTarget<TMode>\n): target is ExpandoEventProps {\n return 'type' in target && target.type === 'line-info';\n}\n\nfunction isMergeConflictActionPointerTarget<\n TMode extends InteractionManagerMode,\n>(target: ResolvedPointerTarget<TMode>): target is MergeConflictActionTarget {\n return 'kind' in target && target.kind === 'merge-conflict-action';\n}\n\nfunction isMergeConflictResolution(\n value: string | undefined\n): value is MergeConflictResolution {\n return value === 'current' || value === 'incoming' || value === 'both';\n}\n\nfunction queryHTMLElement(\n parent: HTMLElement | undefined,\n query: string\n): HTMLElement | undefined {\n const element = parent?.querySelector(query);\n return element instanceof HTMLElement ? element : undefined;\n}\n\nfunction getElementPath(element: Node): EventTarget[] {\n const path: EventTarget[] = [];\n let current: Node | null = element;\n while (current != null) {\n path.push(current);\n current = current.parentNode;\n }\n return path;\n}\n\n// Pointer hits often land on text/token descendants. This normalizes those\n// hits back to the row elements InteractionManager knows how to resolve.\nfunction closestSelectableRow(element: Element): HTMLElement | undefined {\n const row = element.closest('[data-line], [data-column-number]');\n if (row instanceof HTMLElement) {\n return row;\n }\n\n const annotationRow = element.closest(\n '[data-line-annotation], [data-gutter-buffer=\"annotation\"]'\n );\n if (!(annotationRow instanceof HTMLElement)) {\n return undefined;\n }\n\n const previousRow = annotationRow.previousElementSibling;\n return previousRow instanceof HTMLElement &&\n (previousRow.hasAttribute('data-line') ||\n previousRow.hasAttribute('data-column-number'))\n ? previousRow\n : undefined;\n}\n\nfunction getAnnotationSlotName(element: Element): string | undefined {\n const slottedElement = element.closest('[slot^=\"annotation-\"]');\n if (slottedElement instanceof HTMLElement) {\n return slottedElement.getAttribute('slot') ?? undefined;\n }\n\n if (element instanceof HTMLElement) {\n const slotName = element.getAttribute('name') ?? undefined;\n return slotName != null && slotName.startsWith('annotation-')\n ? slotName\n : undefined;\n }\n\n return undefined;\n}\n\nfunction selectionPointFromAnnotationSlotName(\n slotName: string | undefined\n): SelectionPoint | undefined {\n if (slotName == null) {\n return undefined;\n }\n\n const match = /^annotation-(?:(additions|deletions)-)?(\\d+)$/.exec(slotName);\n if (match == null) {\n return undefined;\n }\n\n const lineNumber = Number.parseInt(match[2], 10);\n if (!Number.isFinite(lineNumber) || lineNumber <= 0) {\n return undefined;\n }\n\n const side = match[1] as SelectionSide | undefined;\n return { lineNumber, side };\n}\n\ninterface ElementFromPointRoot {\n elementFromPoint(x: number, y: number): Element | null;\n}\n\nfunction hasElementFromPoint(\n value: Node | undefined\n): value is Node & ElementFromPointRoot {\n return (\n value != null &&\n typeof (value as Partial<ElementFromPointRoot>).elementFromPoint ===\n 'function'\n );\n}\n\nfunction getAnnotationSide(\n lineType: LineTypes,\n codeElement: HTMLElement\n): AnnotationSide {\n switch (lineType) {\n case 'change-deletion':\n return 'deletions';\n case 'change-addition':\n return 'additions';\n default:\n return codeElement.hasAttribute('data-deletions')\n ? 'deletions'\n : 'additions';\n }\n}\n\nfunction getLineTypeFromElement(element: HTMLElement): LineTypes | undefined {\n const lineType = element.getAttribute('data-line-type');\n if (lineType == null) {\n return undefined;\n }\n switch (lineType) {\n case 'change-deletion':\n case 'change-addition':\n case 'context':\n case 'context-expanded':\n return lineType;\n default:\n return undefined;\n }\n}\n\nfunction isGutterUtilityPath(path: (EventTarget | undefined)[]): boolean {\n for (const element of path) {\n if (!(element instanceof HTMLElement)) {\n continue;\n }\n if (\n element.hasAttribute('data-utility-button') ||\n element.hasAttribute('data-gutter-utility-slot') ||\n // Custom React/DOM utilities are slotted into the same utility surface,\n // so treat both the assigned content and the slot node itself as\n // utility hits.\n element.getAttribute('slot') === 'gutter-utility-slot' ||\n element.getAttribute('name') === 'gutter-utility-slot'\n ) {\n return true;\n }\n }\n return false;\n}\n\nfunction debugLogIfEnabled(\n debugLogType: LogTypes | undefined = 'none',\n logIfType: 'move' | 'click',\n ...args: unknown[]\n) {\n switch (debugLogType) {\n case 'none':\n return;\n case 'both':\n break;\n case 'click':\n if (logIfType !== 'click') {\n return;\n }\n break;\n case 'move':\n if (logIfType !== 'move') {\n return;\n }\n break;\n }\n console.log(...args);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"InteractionManager.js","names":[],"sources":["../../src/managers/InteractionManager.ts"],"sourcesContent":["import { toHtml } from 'hast-util-to-html';\n\nimport type {\n AnnotationSide,\n DiffLineEventBaseProps,\n DiffTokenEventBaseProps,\n ExpansionDirections,\n LineEventBaseProps,\n LineTypes,\n MergeConflictResolution,\n SelectedLineRange,\n SelectionPoint,\n SelectionSide,\n TokenEventBase,\n} from '../types';\nimport { areSelectionPointsEqual } from '../utils/areSelectionPointsEqual';\nimport { areSelectionsEqual } from '../utils/areSelectionsEqual';\nimport { createGutterUtilityElement } from '../utils/createGutterUtilityElement';\n\ninterface TokenCache {\n tokenElement: HTMLElement;\n lineCharStart: number;\n lineCharEnd: number;\n tokenText: string;\n}\n\ninterface ExpandCache {\n hunkIndex: number | undefined;\n direction: ExpansionDirections;\n all: boolean;\n}\n\nexport type LogTypes = 'click' | 'move' | 'both' | 'none';\n\nexport type InteractionManagerMode = 'file' | 'diff';\n\nexport interface OnLineClickProps extends LineEventBaseProps {\n event: PointerEvent;\n}\n\nexport interface OnLineEnterLeaveProps extends LineEventBaseProps {\n event: PointerEvent;\n}\n\nexport interface OnDiffLineClickProps extends DiffLineEventBaseProps {\n event: PointerEvent;\n}\n\nexport interface OnDiffLineEnterLeaveProps extends DiffLineEventBaseProps {\n event: PointerEvent;\n}\n\nexport interface SelectionWriteOptions {\n notify?: boolean;\n // Limit the selected-line highlight to one side's column of a split diff.\n // The editor sets this to 'additions' so its active-line highlight stays on\n // the editable pane instead of also lighting up the read-only deletions\n // pane. It has no effect on unified or single-file views, whose one code\n // column carries no side attribute.\n activeLineSide?: SelectionSide;\n // Highlight only the gutter line number, not the line background. The editor\n // sets this while text is selected: the caret line keeps its highlighted\n // number, but the full-line background gives way to the text selection.\n lineNumberOnly?: boolean;\n}\n\nexport type GetLineIndexUtility = (\n lineNumber: number,\n side?: SelectionSide\n) => [number, number] | undefined;\n\ntype EventClickProps<TMode extends InteractionManagerMode> =\n TMode extends 'file' ? OnLineClickProps : OnDiffLineClickProps;\n\ntype PointerEventEnterLeaveProps<TMode extends InteractionManagerMode> =\n TMode extends 'file' ? OnLineEnterLeaveProps : OnDiffLineEnterLeaveProps;\n\ntype EventBaseProps<TMode extends InteractionManagerMode> = TMode extends 'file'\n ? LineEventBaseProps\n : DiffLineEventBaseProps;\n\nexport type OnTokenEventProps<TMode extends InteractionManagerMode> =\n TMode extends 'file' ? TokenEventBase : DiffTokenEventBaseProps;\n\ninterface ExpandoEventProps {\n type: 'line-info';\n hunkIndex: number;\n direction: ExpansionDirections;\n all: boolean;\n}\n\nexport type GetHoveredLineResult<TMode extends InteractionManagerMode> =\n TMode extends 'file'\n ? { lineNumber: number }\n : { lineNumber: number; side: AnnotationSide };\n\ninterface SelectionInfo {\n lineNumber: number;\n eventSide: SelectionSide | undefined;\n lineIndex: number;\n}\n\ntype SelectionHitSource = 'event-path' | 'coordinates-first';\n\ninterface SelectionHitOptions {\n source: SelectionHitSource;\n excludeUtility?: boolean;\n}\n\ninterface SelectionInfoOptions extends SelectionHitOptions {\n requireNumberColumn: boolean;\n}\n\ninterface SelectionEnds {\n top: SelectionPoint;\n bottom: SelectionPoint;\n}\n\ninterface ResolvedLineTarget<TMode extends InteractionManagerMode> {\n kind: 'line';\n lineType: LineTypes;\n lineElement: HTMLElement;\n lineNumber: number;\n numberColumn: boolean;\n numberElement: HTMLElement;\n side: TMode extends 'diff' ? AnnotationSide : undefined;\n splitLineIndex: number | undefined;\n}\n\ninterface ResolvedTokenTarget<TMode extends InteractionManagerMode> {\n kind: 'token';\n lineType: LineTypes;\n lineElement: HTMLElement;\n lineNumber: number;\n numberColumn: boolean;\n numberElement: HTMLElement;\n side: TMode extends 'diff' ? AnnotationSide : undefined;\n splitLineIndex: number | undefined;\n tokenElement: HTMLElement;\n tokenText: string;\n lineCharStart: number;\n lineCharEnd: number;\n}\n\nexport interface MergeConflictActionTarget {\n kind: 'merge-conflict-action';\n resolution: MergeConflictResolution;\n conflictIndex: number;\n}\n\ntype ResolvedPointerTarget<TMode extends InteractionManagerMode> =\n | ResolvedLineTarget<TMode>\n | ResolvedTokenTarget<TMode>\n | ExpandoEventProps\n | MergeConflictActionTarget;\n\ntype LinePointerTarget<TMode extends InteractionManagerMode> =\n ResolvedLineTarget<TMode>;\n\ntype TokenPointerTarget<TMode extends InteractionManagerMode> =\n ResolvedTokenTarget<TMode>;\n\ntype HoverableLinePointerTarget<TMode extends InteractionManagerMode> =\n | LinePointerTarget<TMode>\n | TokenPointerTarget<TMode>;\n\ninterface SessionIdle {\n mode: 'idle';\n}\n\ninterface SessionSelecting {\n mode: 'selecting';\n pointerId: number;\n}\n\ninterface SessionPendingSingleLineUnselect {\n mode: 'pendingSingleLineUnselect';\n pointerId: number;\n anchor: SelectionPoint;\n pending: SelectionPoint;\n}\n\ninterface SessionGutterSelecting {\n mode: 'gutterSelecting';\n pointerId: number;\n anchor: SelectionPoint;\n current: SelectionPoint;\n}\n\ntype PointerSession =\n | SessionIdle\n | SessionSelecting\n | SessionPendingSingleLineUnselect\n | SessionGutterSelecting;\n\nexport interface InteractionManagerBaseOptions<\n TMode extends InteractionManagerMode,\n> {\n lineHoverHighlight?: 'disabled' | 'both' | 'number' | 'line';\n enableTokenInteractionsOnWhitespace?: boolean;\n enableGutterUtility?: boolean;\n onGutterUtilityClick?(range: SelectedLineRange): unknown;\n onLineClick?(props: EventClickProps<TMode>): unknown;\n onLineNumberClick?(props: EventClickProps<TMode>): unknown;\n onLineEnter?(props: PointerEventEnterLeaveProps<TMode>): unknown;\n onLineLeave?(props: PointerEventEnterLeaveProps<TMode>): unknown;\n onTokenClick?(props: OnTokenEventProps<TMode>, event: MouseEvent): unknown;\n onTokenEnter?(props: OnTokenEventProps<TMode>, event: PointerEvent): unknown;\n onTokenLeave?(props: OnTokenEventProps<TMode>, event: PointerEvent): unknown;\n __debugPointerEvents?: LogTypes;\n enableLineSelection?: boolean;\n controlledSelection?: boolean;\n onLineSelected?: (range: SelectedLineRange | null) => void;\n onLineSelectionStart?: (range: SelectedLineRange | null) => void;\n onLineSelectionChange?: (range: SelectedLineRange | null) => void;\n onLineSelectionEnd?: (range: SelectedLineRange | null) => void;\n getLineIndex?: GetLineIndexUtility;\n}\n\nexport interface InteractionManagerOptions<\n TMode extends InteractionManagerMode,\n> extends InteractionManagerBaseOptions<TMode> {\n usesCustomGutterUtility?: boolean;\n onHunkExpand?(\n hunkIndex: number,\n direction: ExpansionDirections,\n expansionLineCountOverride?: number\n ): unknown;\n onMergeConflictActionClick?(target: MergeConflictActionTarget): void;\n}\n\ninterface HandlePointerEventProps {\n eventType: 'click' | 'move';\n event: PointerEvent | MouseEvent;\n}\n\nexport class InteractionManager<TMode extends InteractionManagerMode> {\n private hoveredLine: EventBaseProps<TMode> | undefined;\n private hoveredToken: OnTokenEventProps<TMode> | undefined;\n private pre: HTMLPreElement | undefined;\n\n private gutterUtilityLine: EventBaseProps<TMode> | undefined;\n private gutterUtilityContainer: HTMLDivElement | undefined;\n private gutterUtilityButton: HTMLButtonElement | undefined;\n private gutterUtilitySlot: HTMLSlotElement | undefined;\n\n private interactiveLinesAttr = false;\n private interactiveLineNumbersAttr = false;\n\n private hasPointerListeners = false;\n private hasDocumentPointerListeners = false;\n\n private selectedRange: SelectedLineRange | null = null;\n // When set, the active-line highlight is confined to this side's column in a\n // split diff (see SelectionWriteOptions.activeLineSide). Tracks the current\n // selectedRange and is cleared by any gutter-driven selection. Only the\n // editor's own active-line highlight sets a side, so a non-null value also\n // marks the selection as editor-driven (see highlightLineNumberOnly).\n private activeLineHighlightSide: SelectionSide | undefined;\n // When true, the active-line highlight marks only the gutter line number and\n // not the line background (see SelectionWriteOptions.lineNumberOnly).\n private activeLineNumberOnly = false;\n // True while an editor is attached (edit mode). The editor draws selection as\n // text, so a host or gutter line selection then highlights only the gutter\n // line numbers, never the full-line background.\n private editorAttached = false;\n private proposedSelectedRange: SelectedLineRange | null | undefined;\n private renderedSelectionRange: SelectedLineRange | null | undefined;\n private selectionAnchor: SelectionPoint | undefined;\n private queuedSelectionRender: number | undefined;\n private pointerSession: PointerSession = { mode: 'idle' };\n\n constructor(\n private mode: TMode,\n private options: InteractionManagerOptions<TMode>\n ) {}\n\n setOptions(options: InteractionManagerOptions<TMode>): void {\n this.options = options;\n }\n\n cleanUp(): void {\n this.pre?.removeEventListener('click', this.handlePointerClick);\n this.pre?.removeEventListener('pointerdown', this.handlePointerDown);\n this.pre?.removeEventListener('pointermove', this.handlePointerMove);\n this.pre?.removeEventListener('pointerleave', this.handlePointerLeave);\n this.pre?.removeAttribute('data-interactive-lines');\n this.pre?.removeAttribute('data-interactive-line-numbers');\n this.pre = undefined;\n this.gutterUtilityContainer?.remove();\n this.gutterUtilityLine = undefined;\n this.gutterUtilityContainer = undefined;\n this.gutterUtilityButton = undefined;\n this.gutterUtilitySlot = undefined;\n this.clearHoveredLine();\n this.clearHoveredToken();\n this.detachDocumentPointerListeners();\n this.clearPointerSession();\n if (this.queuedSelectionRender != null) {\n cancelAnimationFrame(this.queuedSelectionRender);\n this.queuedSelectionRender = undefined;\n }\n this.interactiveLinesAttr = false;\n this.interactiveLineNumbersAttr = false;\n this.hasPointerListeners = false;\n }\n\n setup(pre: HTMLPreElement): void {\n this.setSelectionDirty();\n const { usesCustomGutterUtility = false, enableGutterUtility = false } =\n this.options;\n\n const newContainer = this.pre !== pre;\n if (newContainer) {\n this.cleanUp();\n this.pre = pre;\n }\n\n if (enableGutterUtility) {\n this.ensureGutterUtilityNode(usesCustomGutterUtility);\n } else if (this.gutterUtilityContainer != null) {\n this.gutterUtilityContainer.remove();\n this.gutterUtilityLine = undefined;\n this.gutterUtilityContainer = undefined;\n this.gutterUtilityButton = undefined;\n this.gutterUtilitySlot = undefined;\n if (this.pointerSession.mode === 'gutterSelecting') {\n this.clearPointerSession();\n this.detachDocumentPointerListeners();\n }\n }\n\n this.syncPointerListeners(pre);\n this.updateInteractiveLineAttributes();\n this.renderSelection();\n this.placeUtility();\n }\n\n setSelectionDirty(): void {\n this.renderedSelectionRange = undefined;\n }\n\n // Toggle edit mode. While an editor is attached, host and gutter line\n // selections are shown as gutter-number-only highlights (the editor renders\n // the selected text itself), so the full-line background is suppressed.\n setEditorAttached(attached: boolean): void {\n if (this.editorAttached === attached) {\n return;\n }\n this.editorAttached = attached;\n this.setSelectionDirty();\n this.renderSelection();\n }\n\n isSelectionDirty(): boolean {\n return this.renderedSelectionRange === null;\n }\n\n setSelection(\n range: SelectedLineRange | null,\n options?: SelectionWriteOptions\n ): void {\n const isRangeChange = !(\n range === this.selectedRange ||\n areSelectionsEqual(range ?? undefined, this.selectedRange ?? undefined)\n );\n if (!this.isSelectionDirty() && !isRangeChange) {\n return;\n }\n this.proposedSelectedRange = undefined;\n this.selectedRange = range;\n this.activeLineHighlightSide = options?.activeLineSide;\n this.activeLineNumberOnly = options?.lineNumberOnly ?? false;\n this.renderSelection();\n this.placeUtility();\n if (isRangeChange && options?.notify !== false) {\n this.notifySelectionCommitted();\n }\n }\n\n getSelection(): SelectedLineRange | null {\n return this.selectedRange;\n }\n\n getHoveredLine = (): GetHoveredLineResult<TMode> | undefined => {\n const gutterUtilityLine = this.gutterUtilityLine ?? this.hoveredLine;\n if (gutterUtilityLine != null) {\n if (this.mode === 'diff' && gutterUtilityLine.type === 'diff-line') {\n return {\n lineNumber: gutterUtilityLine.lineNumber,\n side: gutterUtilityLine.annotationSide,\n } as GetHoveredLineResult<TMode>;\n }\n if (this.mode === 'file' && gutterUtilityLine.type === 'line') {\n return {\n lineNumber: gutterUtilityLine.lineNumber,\n } as GetHoveredLineResult<TMode>;\n }\n }\n return undefined;\n };\n\n handlePointerClick = (event: MouseEvent): void => {\n const {\n onHunkExpand,\n onLineClick,\n onLineNumberClick,\n onTokenClick,\n onMergeConflictActionClick,\n } = this.options;\n if (\n onHunkExpand == null &&\n onLineClick == null &&\n onLineNumberClick == null &&\n onMergeConflictActionClick == null &&\n onTokenClick == null\n ) {\n return;\n }\n if (\n this.options.onGutterUtilityClick != null &&\n isGutterUtilityPath(event.composedPath())\n ) {\n return;\n }\n debugLogIfEnabled(\n this.options.__debugPointerEvents,\n 'click',\n 'FileDiff.DEBUG.handlePointerClick:',\n event\n );\n this.handlePointerEvent({ eventType: 'click', event });\n };\n\n handlePointerMove = (event: PointerEvent): void => {\n // Touch and pen moves are active drag/scroll gestures, not hover. Keeping\n // hover mouse-only prevents content scrolls from leaving stale utilities.\n if (event.pointerType !== 'mouse') {\n return;\n }\n\n const {\n lineHoverHighlight = 'disabled',\n onLineEnter,\n onLineLeave,\n onTokenEnter,\n onTokenLeave,\n enableGutterUtility = false,\n } = this.options;\n if (\n lineHoverHighlight === 'disabled' &&\n !enableGutterUtility &&\n onLineEnter == null &&\n onLineLeave == null &&\n onTokenEnter == null &&\n onTokenLeave == null\n ) {\n return;\n }\n debugLogIfEnabled(\n this.options.__debugPointerEvents,\n 'move',\n 'FileDiff.DEBUG.handlePointerMove:',\n event\n );\n // should we perhaps throttle this a bit because move can be fast as fuk\n // boiiii\n this.handlePointerEvent({ eventType: 'move', event });\n };\n\n handlePointerLeave = (event: PointerEvent): void => {\n const { __debugPointerEvents } = this.options;\n debugLogIfEnabled(\n __debugPointerEvents,\n 'move',\n 'FileDiff.DEBUG.handlePointerLeave: no event'\n );\n if (this.hoveredLine == null && this.hoveredToken == null) {\n debugLogIfEnabled(\n __debugPointerEvents,\n 'move',\n 'FileDiff.DEBUG.handlePointerLeave: returned early, no hovered line or token'\n );\n return;\n }\n if (this.hoveredToken != null) {\n this.options.onTokenLeave?.(this.hoveredToken, event);\n this.clearHoveredToken();\n }\n\n if (this.hoveredLine != null) {\n this.options.onLineLeave?.({\n ...this.hoveredLine,\n event,\n } as PointerEventEnterLeaveProps<TMode>);\n this.clearHoveredLine();\n }\n this.placeUtility();\n };\n\n private handlePointerEvent({ eventType, event }: HandlePointerEventProps) {\n const { __debugPointerEvents } = this.options;\n const composedPath = event.composedPath();\n debugLogIfEnabled(\n __debugPointerEvents,\n eventType,\n 'FileDiff.DEBUG.handlePointerEvent:',\n { eventType, composedPath }\n );\n const target = this.resolvePointerTarget(composedPath);\n debugLogIfEnabled(\n __debugPointerEvents,\n eventType,\n 'FileDiff.DEBUG.handlePointerEvent: resolvePointerTarget result:',\n target\n );\n\n const {\n onLineClick,\n onLineNumberClick,\n onLineEnter,\n onLineLeave,\n onTokenClick,\n onTokenEnter,\n onTokenLeave,\n onHunkExpand,\n onMergeConflictActionClick,\n } = this.options;\n\n switch (eventType) {\n case 'move': {\n const sameLine =\n isHoverableLinePointerTarget(target) &&\n this.hoveredLine?.lineElement === target.lineElement;\n const sameToken =\n isTokenPointerTarget(target) &&\n this.hoveredToken?.tokenElement === target.tokenElement;\n\n // Handle token transitions\n if (!sameToken) {\n if (this.hoveredToken != null) {\n onTokenLeave?.(this.hoveredToken, event as PointerEvent);\n this.clearHoveredToken();\n }\n if (isTokenPointerTarget(target)) {\n this.setHoveredToken(this.toTokenEventBaseProps(target));\n onTokenEnter?.(\n this.hoveredToken as OnTokenEventProps<TMode>,\n event as PointerEvent\n );\n }\n }\n\n // Handle line transitions\n if (!sameLine) {\n if (this.hoveredLine != null) {\n onLineLeave?.({\n ...this.hoveredLine,\n event: event as PointerEvent,\n } as PointerEventEnterLeaveProps<TMode>);\n this.clearHoveredLine();\n }\n if (isHoverableLinePointerTarget(target)) {\n this.setHoveredLine(this.toEventBaseProps(target));\n this.placeUtility();\n onLineEnter?.({\n ...this.hoveredLine,\n event: event as PointerEvent,\n } as PointerEventEnterLeaveProps<TMode>);\n } else {\n this.placeUtility();\n }\n }\n break;\n }\n case 'click': {\n if (target == null) {\n break;\n }\n if (\n isMergeConflictActionPointerTarget(target) &&\n onMergeConflictActionClick != null\n ) {\n onMergeConflictActionClick(target);\n break;\n }\n if (isExpandoPointerTarget(target) && onHunkExpand != null) {\n onHunkExpand(\n target.hunkIndex,\n target.all || event.shiftKey ? 'both' : target.direction,\n target.all || event.shiftKey ? Number.POSITIVE_INFINITY : undefined\n );\n break;\n }\n\n if (!isHoverableLinePointerTarget(target)) {\n break;\n }\n\n if (isTokenPointerTarget(target) && onTokenClick != null) {\n onTokenClick(this.toTokenEventBaseProps(target), event as MouseEvent);\n }\n\n const eventBase = this.toEventBaseProps(target);\n if (onLineNumberClick != null && target.numberColumn) {\n onLineNumberClick({\n ...eventBase,\n event: event as PointerEvent,\n } as EventClickProps<TMode>);\n } else if (onLineClick != null) {\n onLineClick({\n ...eventBase,\n event: event as PointerEvent,\n } as EventClickProps<TMode>);\n }\n break;\n }\n }\n }\n\n private syncPointerListeners(pre: HTMLPreElement): void {\n const {\n __debugPointerEvents,\n lineHoverHighlight = 'disabled',\n onLineClick,\n onLineNumberClick,\n onLineEnter,\n onLineLeave,\n onTokenClick,\n onTokenEnter,\n onTokenLeave,\n onHunkExpand,\n onMergeConflictActionClick,\n enableGutterUtility = false,\n enableLineSelection = false,\n onGutterUtilityClick,\n } = this.options;\n const enableGutterSelection = onGutterUtilityClick != null;\n const shouldAttachPointerListeners =\n lineHoverHighlight !== 'disabled' ||\n onLineClick != null ||\n onLineNumberClick != null ||\n onLineEnter != null ||\n onLineLeave != null ||\n onTokenClick != null ||\n onTokenEnter != null ||\n onTokenLeave != null ||\n onHunkExpand != null ||\n onMergeConflictActionClick != null ||\n enableGutterUtility ||\n enableLineSelection ||\n enableGutterSelection;\n\n if (shouldAttachPointerListeners && !this.hasPointerListeners) {\n pre.addEventListener('click', this.handlePointerClick);\n pre.addEventListener('pointerdown', this.handlePointerDown);\n pre.addEventListener('pointermove', this.handlePointerMove);\n pre.addEventListener('pointerleave', this.handlePointerLeave);\n this.hasPointerListeners = true;\n\n debugLogIfEnabled(\n __debugPointerEvents,\n 'click',\n 'FileDiff.DEBUG.attachEventListeners: Attaching click events for:',\n (() => {\n const reasons: string[] = [];\n if (\n __debugPointerEvents === 'both' ||\n __debugPointerEvents === 'click'\n ) {\n if (onLineClick != null) {\n reasons.push('onLineClick');\n }\n if (onLineNumberClick != null) {\n reasons.push('onLineNumberClick');\n }\n if (onHunkExpand != null) {\n reasons.push('expandable hunk separators');\n }\n if (onMergeConflictActionClick != null) {\n reasons.push('merge conflict actions');\n }\n }\n return reasons;\n })()\n );\n debugLogIfEnabled(\n __debugPointerEvents,\n 'move',\n 'FileDiff.DEBUG.attachEventListeners: Attaching pointer move event'\n );\n debugLogIfEnabled(\n __debugPointerEvents,\n 'move',\n 'FileDiff.DEBUG.attachEventListeners: Attaching pointer leave event'\n );\n } else if (!shouldAttachPointerListeners && this.hasPointerListeners) {\n pre.removeEventListener('click', this.handlePointerClick);\n pre.removeEventListener('pointerdown', this.handlePointerDown);\n pre.removeEventListener('pointermove', this.handlePointerMove);\n pre.removeEventListener('pointerleave', this.handlePointerLeave);\n this.hasPointerListeners = false;\n }\n\n const hasActiveLineSelectionSession =\n this.pointerSession.mode === 'selecting' ||\n this.pointerSession.mode === 'pendingSingleLineUnselect';\n const hasActiveGutterSelectionSession =\n this.pointerSession.mode === 'gutterSelecting';\n if (\n (!enableLineSelection && hasActiveLineSelectionSession) ||\n (!enableGutterSelection && hasActiveGutterSelectionSession)\n ) {\n this.clearPointerSession();\n this.detachDocumentPointerListeners();\n this.selectionAnchor = undefined;\n this.clearPendingSingleLineState();\n }\n }\n\n private updateInteractiveLineAttributes(): void {\n if (this.pre == null) {\n return;\n }\n\n const {\n onLineClick,\n onLineNumberClick,\n enableLineSelection = false,\n } = this.options;\n\n const shouldHaveInteractiveLines = onLineClick != null;\n const shouldHaveInteractiveLineNumbers =\n onLineNumberClick != null || enableLineSelection;\n\n if (shouldHaveInteractiveLines && !this.interactiveLinesAttr) {\n this.pre.setAttribute('data-interactive-lines', '');\n this.interactiveLinesAttr = true;\n } else if (!shouldHaveInteractiveLines && this.interactiveLinesAttr) {\n this.pre.removeAttribute('data-interactive-lines');\n this.interactiveLinesAttr = false;\n }\n\n if (shouldHaveInteractiveLineNumbers && !this.interactiveLineNumbersAttr) {\n this.pre.setAttribute('data-interactive-line-numbers', '');\n this.interactiveLineNumbersAttr = true;\n } else if (\n !shouldHaveInteractiveLineNumbers &&\n this.interactiveLineNumbersAttr\n ) {\n this.pre.removeAttribute('data-interactive-line-numbers');\n this.interactiveLineNumbersAttr = false;\n }\n }\n\n private handlePointerDown = (event: PointerEvent): void => {\n if (\n (event.pointerType === 'mouse' && event.button !== 0) ||\n this.pre == null ||\n this.pointerSession.mode !== 'idle'\n ) {\n return;\n }\n\n const path = event.composedPath();\n if (\n isGutterUtilityPath(path) &&\n this.options.onGutterUtilityClick != null\n ) {\n this.startGutterSelectionFromPointerDown(event);\n } else {\n if (event.pointerType !== 'mouse') {\n this.revealUtilityFromGutterPath(path);\n }\n this.startLineSelectionFromPointerDown(event);\n }\n };\n\n private startLineSelectionFromPointerDown(event: PointerEvent): void {\n const { enableLineSelection = false } = this.options;\n if (!enableLineSelection) {\n return;\n }\n\n const pointerInfo = this.resolveSelectionInfo(event, {\n source: 'event-path',\n requireNumberColumn: true,\n });\n if (pointerInfo == null) {\n return;\n }\n\n const { pre } = this;\n if (pre == null) {\n return;\n }\n\n // Intentionally no preventDefault here. The line-number gutter uses\n // `user-select: none`, so a drag that starts on it never begins a native\n // text selection. Calling preventDefault would also cancel the browser's\n // native focus change, which stops a focusable host wrapper from receiving\n // focus (and the keyboard events it needs) when a line number is clicked.\n const { lineNumber, eventSide, lineIndex } = pointerInfo;\n\n if (event.shiftKey && this.selectedRange != null) {\n const rowRange = this.getIndexesFromSelection(\n this.selectedRange,\n pre.getAttribute('data-diff-type') === 'split'\n );\n if (rowRange == null) {\n return;\n }\n const useStart =\n rowRange.start <= rowRange.end\n ? lineIndex >= rowRange.start\n : lineIndex <= rowRange.end;\n this.selectionAnchor = {\n lineNumber: useStart\n ? this.selectedRange.start\n : this.selectedRange.end,\n side: useStart\n ? this.selectedRange.side\n : (this.selectedRange.endSide ?? this.selectedRange.side),\n };\n this.updateSelection(lineNumber, eventSide, false);\n this.notifySelectionStart(this.getCurrentSelectionRange());\n this.pointerSession = { mode: 'selecting', pointerId: event.pointerId };\n this.attachDocumentPointerListeners();\n return;\n }\n\n if (\n this.selectedRange?.start === lineNumber &&\n this.selectedRange?.end === lineNumber\n ) {\n const point = { lineNumber, side: eventSide };\n this.selectionAnchor = point;\n this.pointerSession = {\n mode: 'pendingSingleLineUnselect',\n pointerId: event.pointerId,\n anchor: point,\n pending: point,\n };\n this.attachDocumentPointerListeners();\n return;\n }\n\n if (this.options.controlledSelection === true) {\n this.proposedSelectedRange = null;\n } else {\n this.selectedRange = null;\n }\n this.placeUtility();\n this.selectionAnchor = { lineNumber, side: eventSide };\n this.updateSelection(lineNumber, eventSide, false);\n this.notifySelectionStart(this.getCurrentSelectionRange());\n this.pointerSession = { mode: 'selecting', pointerId: event.pointerId };\n this.attachDocumentPointerListeners();\n }\n\n private startGutterSelectionFromPointerDown(event: PointerEvent): void {\n const { enableLineSelection = false, onGutterUtilityClick } = this.options;\n if (onGutterUtilityClick == null) {\n return;\n }\n // If a selection already exists, the utility represents that whole range.\n // Dragging should start from the visual top and extend from the visual\n // bottom, regardless of the direction the range was originally created.\n const selectedEndpoints = this.currentSelectionEnds();\n const point =\n selectedEndpoints?.bottom ??\n this.resolveSelectionPoint(event, {\n source: 'event-path',\n excludeUtility: false,\n });\n const anchor = selectedEndpoints?.top ?? point;\n if (point == null || anchor == null) {\n return;\n }\n event.preventDefault();\n event.stopPropagation();\n this.pointerSession = {\n mode: 'gutterSelecting',\n pointerId: event.pointerId,\n anchor,\n current: point,\n };\n if (enableLineSelection) {\n this.selectionAnchor = {\n lineNumber: anchor.lineNumber,\n side: anchor.side,\n };\n this.updateSelection(point.lineNumber, point.side, false);\n this.notifySelectionStart(this.getCurrentSelectionRange());\n }\n this.attachDocumentPointerListeners();\n }\n\n private handleDocumentPointerMove = (event: PointerEvent): void => {\n const { enableLineSelection = false } = this.options;\n switch (this.pointerSession.mode) {\n case 'idle':\n return;\n case 'gutterSelecting': {\n if (event.pointerId !== this.pointerSession.pointerId) {\n return;\n }\n event.preventDefault();\n const point = this.resolveSelectionPoint(event, {\n source: 'coordinates-first',\n });\n if (point == null) {\n return;\n }\n this.pointerSession.current = point;\n if (enableLineSelection === true) {\n this.updateSelection(point.lineNumber, point.side);\n }\n return;\n }\n case 'selecting': {\n if (event.pointerId !== this.pointerSession.pointerId) {\n return;\n }\n event.preventDefault();\n const pointerInfo = this.resolveSelectionInfo(event, {\n source: 'coordinates-first',\n requireNumberColumn: false,\n });\n if (pointerInfo == null || this.selectionAnchor == null) {\n return;\n }\n this.updateSelection(pointerInfo.lineNumber, pointerInfo.eventSide);\n return;\n }\n case 'pendingSingleLineUnselect': {\n if (event.pointerId !== this.pointerSession.pointerId) {\n return;\n }\n event.preventDefault();\n const pointerInfo = this.resolveSelectionInfo(event, {\n source: 'coordinates-first',\n requireNumberColumn: false,\n });\n if (pointerInfo == null || this.selectionAnchor == null) {\n return;\n }\n const point = {\n lineNumber: pointerInfo.lineNumber,\n side: pointerInfo.eventSide,\n };\n if (areSelectionPointsEqual(this.pointerSession.pending, point)) {\n return;\n }\n this.updateSelection(\n pointerInfo.lineNumber,\n pointerInfo.eventSide,\n false\n );\n this.notifySelectionStart(this.getCurrentSelectionRange());\n this.notifySelectionChangeDelta();\n this.pointerSession = {\n mode: 'selecting',\n pointerId: event.pointerId,\n };\n return;\n }\n }\n };\n\n private handleDocumentPointerUp = (event: PointerEvent): void => {\n const { enableLineSelection = false, onGutterUtilityClick } = this.options;\n switch (this.pointerSession.mode) {\n case 'idle':\n return;\n case 'gutterSelecting': {\n if (event.pointerId !== this.pointerSession.pointerId) {\n return;\n }\n event.preventDefault();\n const point = this.resolveSelectionPoint(event, {\n source: 'coordinates-first',\n });\n if (point != null) {\n this.pointerSession.current = point;\n if (enableLineSelection) {\n this.updateSelection(point.lineNumber, point.side);\n }\n }\n onGutterUtilityClick?.(\n this.buildSelectedLineRange(\n this.pointerSession.anchor,\n this.pointerSession.current\n )\n );\n this.selectionAnchor = undefined;\n if (enableLineSelection) {\n this.notifySelectionEnd(this.getCurrentSelectionRange());\n this.notifySelectionCommitted();\n this.clearProposedSelection();\n }\n this.clearPointerSession();\n this.detachDocumentPointerListeners();\n return;\n }\n case 'pendingSingleLineUnselect': {\n if (event.pointerId !== this.pointerSession.pointerId) {\n return;\n }\n event.preventDefault();\n this.updateSelection(null, undefined, false);\n this.selectionAnchor = undefined;\n this.clearPendingSingleLineState();\n this.detachDocumentPointerListeners();\n this.notifySelectionEnd(this.getCurrentSelectionRange());\n this.notifySelectionCommitted();\n this.clearProposedSelection();\n return;\n }\n case 'selecting': {\n if (event.pointerId !== this.pointerSession.pointerId) {\n return;\n }\n event.preventDefault();\n this.selectionAnchor = undefined;\n this.detachDocumentPointerListeners();\n this.clearPointerSession();\n this.notifySelectionEnd(this.getCurrentSelectionRange());\n this.notifySelectionCommitted();\n this.clearProposedSelection();\n }\n }\n };\n\n private handleDocumentPointerCancel = (event: PointerEvent): void => {\n switch (this.pointerSession.mode) {\n case 'idle':\n return;\n case 'gutterSelecting':\n case 'selecting':\n case 'pendingSingleLineUnselect': {\n if ('pointerId' in this.pointerSession) {\n if (event.pointerId !== this.pointerSession.pointerId) {\n return;\n }\n }\n this.selectionAnchor = undefined;\n this.clearProposedSelection();\n this.clearPendingSingleLineState();\n this.clearPointerSession();\n this.detachDocumentPointerListeners();\n }\n }\n };\n\n private clearHoveredLine() {\n if (this.hoveredLine == null) {\n return;\n }\n this.hoveredLine.lineElement.removeAttribute('data-hovered');\n this.hoveredLine.numberElement.removeAttribute('data-hovered');\n this.hoveredLine = undefined;\n }\n\n private setHoveredLine(hoveredLine: EventBaseProps<TMode>) {\n const { lineHoverHighlight = 'disabled' } = this.options;\n if (this.hoveredLine != null) {\n this.clearHoveredLine();\n }\n this.hoveredLine = hoveredLine;\n if (lineHoverHighlight !== 'disabled') {\n if (lineHoverHighlight === 'both' || lineHoverHighlight === 'line') {\n this.hoveredLine.lineElement.setAttribute('data-hovered', '');\n }\n if (lineHoverHighlight === 'both' || lineHoverHighlight === 'number') {\n this.hoveredLine.numberElement.setAttribute('data-hovered', '');\n }\n }\n }\n\n private clearHoveredToken() {\n if (this.hoveredToken == null) {\n return;\n }\n this.hoveredToken = undefined;\n }\n\n private setHoveredToken(hoveredToken: OnTokenEventProps<TMode>) {\n if (this.hoveredToken != null) {\n this.clearHoveredToken();\n }\n this.hoveredToken = hoveredToken;\n }\n\n private ensureGutterUtilityNode(useCustomGutterUtility: boolean): void {\n if (this.gutterUtilityContainer == null) {\n this.gutterUtilityContainer = document.createElement('div');\n this.gutterUtilityContainer.setAttribute('data-gutter-utility-slot', '');\n }\n if (useCustomGutterUtility) {\n if (this.gutterUtilityButton != null) {\n this.gutterUtilityButton.remove();\n this.gutterUtilityButton = undefined;\n }\n if (this.gutterUtilitySlot == null) {\n this.gutterUtilitySlot = document.createElement('slot');\n this.gutterUtilitySlot.name = 'gutter-utility-slot';\n }\n if (this.gutterUtilitySlot.parentNode !== this.gutterUtilityContainer) {\n this.gutterUtilityContainer.replaceChildren(this.gutterUtilitySlot);\n }\n } else {\n this.gutterUtilitySlot?.remove();\n this.gutterUtilitySlot = undefined;\n if (this.gutterUtilityButton == null) {\n const tempDiv = document.createElement('div');\n tempDiv.innerHTML = toHtml(createGutterUtilityElement());\n const utilityButton = tempDiv.firstElementChild;\n if (!(utilityButton instanceof HTMLButtonElement)) {\n throw new Error(\n 'InteractionManager.ensureGutterUtilityNode: Node element should be a button'\n );\n }\n utilityButton.remove();\n this.gutterUtilityButton = utilityButton;\n }\n if (this.gutterUtilityButton.parentNode !== this.gutterUtilityContainer) {\n this.gutterUtilityContainer.replaceChildren(this.gutterUtilityButton);\n }\n }\n }\n\n private revealUtilityFromGutterPath(path: (EventTarget | undefined)[]): void {\n if (this.placeUtilityFromSelection()) {\n return;\n }\n const target = this.resolvePointerTarget(path);\n if (isLinePointerTarget(target) && target.numberColumn) {\n this.showUtilityOnLine(this.toEventBaseProps(target));\n }\n }\n\n // The gutter utility follows the active selection first because a selected\n // range is more stable than transient hover/touch state. Without a\n // selection, desktop hover and mobile tap reveal can still place it on a\n // single row.\n private placeUtility(): void {\n if (this.placeUtilityFromSelection()) {\n return;\n }\n if (this.hoveredLine != null) {\n this.showUtilityOnLine(this.hoveredLine);\n return;\n }\n this.hideUtility();\n }\n\n private placeUtilityFromSelection(): boolean {\n const endpoints = this.currentSelectionEnds();\n if (endpoints == null) {\n return false;\n }\n const target = this.targetForSelectionPoint(endpoints.bottom);\n if (target == null) {\n this.hideUtility();\n } else {\n this.showUtilityOnLine(this.toEventBaseProps(target));\n }\n return true;\n }\n\n private showUtilityOnLine(line: EventBaseProps<TMode>): void {\n if (this.gutterUtilityContainer == null) {\n return;\n }\n this.gutterUtilityLine = line;\n line.numberElement.appendChild(this.gutterUtilityContainer);\n }\n\n private hideUtility(): void {\n this.gutterUtilityContainer?.remove();\n this.gutterUtilityLine = undefined;\n }\n\n // Selection ranges preserve drag direction, so compare rendered row indexes to\n // find the visually top-most and bottom-most endpoints.\n private currentSelectionEnds(): SelectionEnds | undefined {\n const range = this.getCurrentSelectionRange();\n return range == null ? undefined : this.selectionEnds(range);\n }\n\n private selectionEnds(range: SelectedLineRange): SelectionEnds | undefined {\n const start: SelectionPoint = {\n lineNumber: range.start,\n side: range.side,\n };\n const end: SelectionPoint = {\n lineNumber: range.end,\n side: range.endSide ?? range.side,\n };\n const startIndex = this.selectionPointRowIndex(start);\n const endIndex = this.selectionPointRowIndex(end);\n if (startIndex == null || endIndex == null) {\n return undefined;\n }\n return startIndex > endIndex\n ? { top: end, bottom: start }\n : { top: start, bottom: end };\n }\n\n private selectionPointRowIndex(point: SelectionPoint): number | undefined {\n const indexes = this.getLineIndex(point.lineNumber, point.side);\n if (indexes == null) {\n return undefined;\n }\n return this.isSplitDiff() ? indexes[1] : indexes[0];\n }\n\n private targetForSelectionPoint(\n point: SelectionPoint\n ): LinePointerTarget<TMode> | undefined {\n if (this.pre == null) {\n return undefined;\n }\n const indexes = this.getLineIndex(point.lineNumber, point.side);\n if (indexes == null) {\n return undefined;\n }\n const lineIndex =\n this.mode === 'diff' ? `${indexes[0]},${indexes[1]}` : `${indexes[0]}`;\n // Rebuild the real gutter-row target from the selection point so the\n // utility can anchor to the visible row even when the point came from\n // controlled state rather than a pointer event.\n const candidates = this.pre.querySelectorAll(\n `[data-column-number=\"${point.lineNumber}\"][data-line-index=\"${lineIndex}\"]`\n );\n for (const element of candidates) {\n if (!(element instanceof HTMLElement)) {\n continue;\n }\n const target = this.resolvePointerTarget(getElementPath(element));\n if (!isLinePointerTarget(target)) {\n continue;\n }\n if (\n this.mode === 'diff' &&\n point.side != null &&\n target.side !== point.side\n ) {\n continue;\n }\n return target;\n }\n return undefined;\n }\n\n private attachDocumentPointerListeners(): void {\n if (this.hasDocumentPointerListeners) {\n return;\n }\n document.addEventListener('pointermove', this.handleDocumentPointerMove);\n document.addEventListener('pointerup', this.handleDocumentPointerUp);\n document.addEventListener(\n 'pointercancel',\n this.handleDocumentPointerCancel\n );\n this.hasDocumentPointerListeners = true;\n }\n\n private detachDocumentPointerListeners(): void {\n if (!this.hasDocumentPointerListeners) {\n return;\n }\n document.removeEventListener('pointermove', this.handleDocumentPointerMove);\n document.removeEventListener('pointerup', this.handleDocumentPointerUp);\n document.removeEventListener(\n 'pointercancel',\n this.handleDocumentPointerCancel\n );\n this.hasDocumentPointerListeners = false;\n }\n\n private clearPointerSession(): void {\n this.pointerSession = { mode: 'idle' };\n }\n\n private clearPendingSingleLineState(): void {\n if (this.pointerSession.mode === 'pendingSingleLineUnselect') {\n this.pointerSession = { mode: 'idle' };\n }\n }\n\n private selectionInfoFromPath(\n path: (EventTarget | undefined)[],\n requireNumberColumn: boolean\n ): SelectionInfo | undefined {\n const target = this.resolvePointerTarget(path);\n if (!isLinePointerTarget(target)) {\n return undefined;\n }\n if (requireNumberColumn && !target.numberColumn) {\n return undefined;\n }\n if (target.splitLineIndex == null) {\n return undefined;\n }\n\n return {\n lineIndex: target.splitLineIndex,\n lineNumber: target.lineNumber,\n eventSide: this.mode === 'diff' ? target.side : undefined,\n };\n }\n\n private resolveSelectionInfo(\n event: PointerEvent,\n options: SelectionInfoOptions\n ): SelectionInfo | undefined {\n const path = this.resolveSelectionPath(event, options);\n return path != null\n ? this.selectionInfoFromPath(path, options.requireNumberColumn)\n : undefined;\n }\n\n private selectionPointFromPath(\n path: (EventTarget | undefined)[]\n ): SelectionPoint | undefined {\n const target = this.resolvePointerTarget(path);\n if (!isLinePointerTarget(target)) {\n return undefined;\n }\n return {\n lineNumber: target.lineNumber,\n side: this.mode === 'diff' ? target.side : undefined,\n };\n }\n\n private resolveSelectionPoint(\n event: PointerEvent,\n options: SelectionHitOptions\n ): SelectionPoint | undefined {\n const path = this.resolveSelectionPath(event, options);\n return path != null ? this.selectionPointFromPath(path) : undefined;\n }\n\n private resolveSelectionPath(\n event: PointerEvent,\n options: SelectionHitOptions\n ): (EventTarget | undefined)[] | undefined {\n const excludeUtility = options.excludeUtility !== false;\n switch (options.source) {\n case 'event-path':\n return this.pathFromEventPath(event.composedPath(), excludeUtility);\n case 'coordinates-first': {\n // Touch pointers can keep dispatching move/up events to the element\n // where the drag began. Prefer the row currently under the finger,\n // then fall back only when coordinate hit-testing is unavailable.\n const coordinatePath = this.pathFromCoordinates(event, excludeUtility);\n if (coordinatePath !== undefined) {\n return coordinatePath ?? undefined;\n }\n return this.pathFromEventPath(event.composedPath(), excludeUtility);\n }\n }\n }\n\n private pathFromCoordinates(\n event: PointerEvent,\n excludeUtility: boolean\n ): (EventTarget | undefined)[] | null | undefined {\n const coordinateTarget = this.hitTest(event);\n if (coordinateTarget === undefined) {\n return undefined;\n }\n if (coordinateTarget === null) {\n return null;\n }\n // A coordinate hit can be a token span, line-number span, utility overlay,\n // or separator. Normalize valid descendants back to their row; invalid\n // hits intentionally return null so the last selected row stays sticky.\n return this.pathFromElement(coordinateTarget, excludeUtility) ?? null;\n }\n\n private pathFromEventPath(\n path: (EventTarget | undefined)[],\n excludeUtility: boolean\n ): (EventTarget | undefined)[] | undefined {\n if (excludeUtility && isGutterUtilityPath(path)) {\n return undefined;\n }\n for (const element of path) {\n if (element instanceof Element) {\n return this.pathFromElement(element, excludeUtility);\n }\n }\n return undefined;\n }\n\n private pathFromElement(\n element: Element,\n excludeUtility: boolean\n ): (EventTarget | undefined)[] | undefined {\n const path = getElementPath(element);\n if (excludeUtility && isGutterUtilityPath(path)) {\n return undefined;\n }\n // Selection is row-based, not child-element-based. Lateral movement over\n // tokens, annotations, or line-number text should still update to the\n // nearest content or gutter row; anything else is ignored by returning\n // undefined.\n const row = closestSelectableRow(element);\n if (row != null) {\n return getElementPath(row);\n }\n return this.pathFromAnnotationSlot(element);\n }\n\n private pathFromAnnotationSlot(\n element: Element\n ): (EventTarget | undefined)[] | undefined {\n const point = selectionPointFromAnnotationSlotName(\n getAnnotationSlotName(element)\n );\n if (point == null) {\n return undefined;\n }\n const target = this.targetForSelectionPoint(point);\n return target != null ? getElementPath(target.lineElement) : undefined;\n }\n\n private hitTest(event: PointerEvent): Element | null | undefined {\n // Return undefined when coordinate hit-testing cannot run at all, which\n // allows callers to fall back to the event path for tests and older DOMs.\n // Return null when hit-testing ran but found no element, so active drags\n // keep their previous endpoint instead of using a stale captured target.\n if (!Number.isFinite(event.clientX) || !Number.isFinite(event.clientY)) {\n return undefined;\n }\n const root = this.pre?.getRootNode();\n const elementFromPointRoot = hasElementFromPoint(root)\n ? root\n : hasElementFromPoint(document)\n ? document\n : undefined;\n if (elementFromPointRoot == null) {\n return undefined;\n }\n const element = elementFromPointRoot.elementFromPoint(\n event.clientX,\n event.clientY\n );\n return element;\n }\n\n private getLineIndex(\n lineNumber: number,\n side?: SelectionSide\n ): [number, number] | undefined {\n const { getLineIndex } = this.options;\n return getLineIndex != null\n ? getLineIndex(lineNumber, side)\n : [lineNumber - 1, lineNumber - 1];\n }\n\n private getCurrentSelectionRange(): SelectedLineRange | null {\n return this.proposedSelectedRange !== undefined\n ? this.proposedSelectedRange\n : this.selectedRange;\n }\n\n private clearProposedSelection(): void {\n this.proposedSelectedRange = undefined;\n }\n\n private updateSelection(\n currentLine: number | null,\n side?: SelectionSide,\n emitChange = true\n ): void {\n const previousRange = this.getCurrentSelectionRange();\n let nextRange: SelectedLineRange | null;\n if (currentLine == null) {\n nextRange = null;\n } else {\n const anchorSide = this.selectionAnchor?.side ?? side;\n const anchorLine = this.selectionAnchor?.lineNumber ?? currentLine;\n nextRange = this.buildSelectionRange(\n anchorLine,\n currentLine,\n anchorSide,\n side\n );\n }\n if (\n areSelectionsEqual(previousRange ?? undefined, nextRange ?? undefined)\n ) {\n return;\n }\n // A gutter selection spans both columns and the full line, so drop any\n // side or number-only restriction left over from the editor's active-line\n // highlight.\n this.activeLineHighlightSide = undefined;\n this.activeLineNumberOnly = false;\n if (this.options.controlledSelection === true) {\n this.proposedSelectedRange = nextRange;\n } else {\n this.selectedRange = nextRange;\n this.queuedSelectionRender ??= requestAnimationFrame(\n this.renderSelection\n );\n }\n this.placeUtility();\n if (emitChange) {\n this.notifySelectionChangeDelta();\n }\n }\n\n private getIndexesFromSelection(\n selectedRange: SelectedLineRange,\n split: boolean\n ): { start: number; end: number } | undefined {\n if (this.pre == null) {\n return undefined;\n }\n const startIndexes = this.getLineIndex(\n selectedRange.start,\n selectedRange.side\n );\n const finalIndexes = this.getLineIndex(\n selectedRange.end,\n selectedRange.endSide ?? selectedRange.side\n );\n\n return startIndexes != null && finalIndexes != null\n ? {\n start: split ? startIndexes[1] : startIndexes[0],\n end: split ? finalIndexes[1] : finalIndexes[0],\n }\n : undefined;\n }\n\n // Whether to highlight only the gutter line number and leave the full-line\n // background for the editor's text selection. The decision splits on who drove\n // the selection, which activeLineHighlightSide records: the editor's own\n // active-line highlight always sets a side, while gutter and host selections\n // never do. Re-evaluated on every render so toggling edit mode\n // (setEditorAttached) reflows the current selection.\n private highlightLineNumberOnly(): boolean {\n // The editor's own side-confined active-line highlight controls the\n // background itself via lineNumberOnly: off for a bare caret (keep the\n // background), on once text is selected so the text selection is the only\n // line-level marker.\n if (this.activeLineHighlightSide != null) {\n return this.activeLineNumberOnly;\n }\n // A gutter or host line selection: number-only when the caller asked for it,\n // or while an editor is attached — in edit mode the editor renders the\n // selected text itself, so the full-line background gives way to it.\n return this.activeLineNumberOnly || this.editorAttached;\n }\n\n private renderSelection = (): void => {\n if (this.queuedSelectionRender != null) {\n cancelAnimationFrame(this.queuedSelectionRender);\n this.queuedSelectionRender = undefined;\n }\n if (\n this.pre == null ||\n this.renderedSelectionRange === this.selectedRange\n ) {\n return;\n }\n\n const allSelected = this.pre.querySelectorAll('[data-selected-line]');\n for (const element of allSelected) {\n element.removeAttribute('data-selected-line');\n }\n\n this.renderedSelectionRange = this.selectedRange;\n if (this.selectedRange == null) {\n return;\n }\n\n const { children: codeElements } = this.pre;\n if (codeElements.length === 0) {\n return;\n }\n if (codeElements.length > 2) {\n console.error(codeElements);\n throw new Error(\n 'InteractionManager.renderSelection: Somehow there are more than 2 code elements...'\n );\n }\n const split = this.pre.getAttribute('data-diff-type') === 'split';\n const rowRange = this.getIndexesFromSelection(this.selectedRange, split);\n if (rowRange == null) {\n console.error({ rowRange, selectedRange: this.selectedRange });\n throw new Error('InteractionManager.renderSelection: No valid rowRange');\n }\n const isSingle = rowRange.start === rowRange.end;\n const first = Math.min(rowRange.start, rowRange.end);\n const last = Math.max(rowRange.start, rowRange.end);\n const numberOnly = this.highlightLineNumberOnly();\n for (const code of codeElements) {\n // When the highlight is confined to one side (the editor's active-line\n // highlight), skip the opposite split-diff column. The deletions column\n // carries `data-deletions` and the additions column `data-additions`; a\n // unified or single-file column has neither, so it is never skipped.\n const side = this.activeLineHighlightSide;\n if (\n side != null &&\n ((side === 'additions' && code.hasAttribute('data-deletions')) ||\n (side === 'deletions' && code.hasAttribute('data-additions')))\n ) {\n continue;\n }\n const [gutter, content] = code.children;\n const len = content.children.length;\n if (len !== gutter.children.length) {\n throw new Error(\n 'InteractionManager.renderSelection: gutter and content children dont match, something is wrong'\n );\n }\n for (let i = 0; i < len; i++) {\n const contentElement = content.children[i];\n const gutterElement = gutter.children[i];\n if (\n !(contentElement instanceof HTMLElement) ||\n !(gutterElement instanceof HTMLElement)\n ) {\n continue;\n }\n\n const lineIndex = this.parseLineIndex(contentElement, split);\n if ((lineIndex ?? 0) > last) {\n break;\n }\n if (lineIndex == null || lineIndex < first) {\n continue;\n }\n let attributeValue = isSingle\n ? 'single'\n : lineIndex === first\n ? 'first'\n : lineIndex === last\n ? 'last'\n : '';\n gutterElement.setAttribute('data-selected-line', attributeValue);\n // A number-only highlight marks just the gutter number, leaving the\n // line background and any annotation rows untouched.\n if (numberOnly) {\n continue;\n }\n contentElement.setAttribute('data-selected-line', attributeValue);\n if (\n gutterElement.nextSibling instanceof HTMLElement &&\n contentElement.nextSibling instanceof HTMLElement &&\n (contentElement.nextSibling.hasAttribute('data-line-annotation') ||\n contentElement.nextSibling.hasAttribute(\n 'data-merge-conflict-actions'\n ))\n ) {\n if (isSingle) {\n attributeValue = 'last';\n contentElement.setAttribute('data-selected-line', 'first');\n } else if (lineIndex === first) {\n attributeValue = '';\n } else if (lineIndex === last) {\n contentElement.setAttribute('data-selected-line', '');\n }\n contentElement.nextSibling.setAttribute(\n 'data-selected-line',\n attributeValue\n );\n gutterElement.nextSibling.setAttribute(\n 'data-selected-line',\n attributeValue\n );\n }\n }\n }\n };\n\n private notifySelectionCommitted(): void {\n this.options.onLineSelected?.(this.getCurrentSelectionRange() ?? null);\n }\n\n private notifySelectionChangeDelta(): void {\n this.options.onLineSelectionChange?.(\n this.getCurrentSelectionRange() ?? null\n );\n }\n\n private notifySelectionStart(range: SelectedLineRange | null): void {\n this.options.onLineSelectionStart?.(range);\n }\n\n private notifySelectionEnd(range: SelectedLineRange | null): void {\n this.options.onLineSelectionEnd?.(range);\n }\n\n private toEventBaseProps(\n target: HoverableLinePointerTarget<TMode>\n ): EventBaseProps<TMode> {\n if (this.mode === 'file') {\n return {\n type: 'line',\n lineElement: target.lineElement,\n lineNumber: target.lineNumber,\n numberColumn: target.numberColumn,\n numberElement: target.numberElement,\n } as EventBaseProps<TMode>;\n }\n\n return {\n type: 'diff-line',\n annotationSide: target.side as AnnotationSide,\n lineType: target.lineType,\n lineElement: target.lineElement,\n numberElement: target.numberElement,\n lineNumber: target.lineNumber,\n numberColumn: target.numberColumn,\n } as EventBaseProps<TMode>;\n }\n\n private toTokenEventBaseProps({\n lineCharEnd,\n lineCharStart,\n lineNumber,\n side,\n tokenElement,\n tokenText,\n }: TokenPointerTarget<TMode>): OnTokenEventProps<TMode> {\n if (this.mode === 'file') {\n return {\n type: 'token',\n lineCharEnd,\n lineCharStart,\n lineNumber,\n tokenElement,\n tokenText,\n } as OnTokenEventProps<TMode>;\n }\n\n return {\n type: 'token',\n lineCharEnd,\n lineCharStart,\n lineNumber,\n side,\n tokenElement,\n tokenText,\n } as OnTokenEventProps<TMode>;\n }\n\n private buildSelectedLineRange(\n anchor: SelectionPoint,\n current: SelectionPoint\n ): SelectedLineRange {\n return this.buildSelectionRange(\n anchor.lineNumber,\n current.lineNumber,\n anchor.side,\n current.side\n );\n }\n\n private buildSelectionRange(\n start: number,\n end: number,\n side?: SelectionSide,\n endSide?: SelectionSide\n ): SelectedLineRange {\n return {\n start,\n end,\n ...(side != null ? { side } : {}),\n ...(side !== endSide && endSide != null ? { endSide } : {}),\n };\n }\n\n private resolvePointerTarget(\n path: (EventTarget | undefined)[]\n ): ResolvedPointerTarget<TMode> | undefined {\n let numberColumn = false;\n let lineType: LineTypes | undefined;\n let codeElement: HTMLElement | undefined;\n let lineElement: HTMLElement | undefined;\n let lineIndexValue: string | undefined;\n let numberElement: HTMLElement | undefined;\n let tokenElement: HTMLElement | undefined;\n let tokenInfo: TokenCache | undefined;\n let expandInfo: ExpandCache | undefined;\n let lineNumber: number | undefined;\n let mergeConflictActionTarget: MergeConflictActionTarget | undefined;\n\n for (const element of path) {\n if (!(element instanceof HTMLElement)) {\n continue;\n }\n\n if (\n mergeConflictActionTarget == null &&\n element.hasAttribute('data-merge-conflict-action')\n ) {\n const resolutionValue =\n element.getAttribute('data-merge-conflict-action') ?? undefined;\n const conflictIndexValue =\n element.getAttribute('data-merge-conflict-conflict-index') ??\n undefined;\n const conflictIndex =\n conflictIndexValue != null\n ? Number.parseInt(conflictIndexValue, 10)\n : Number.NaN;\n if (\n isMergeConflictResolution(resolutionValue) &&\n Number.isFinite(conflictIndex)\n ) {\n mergeConflictActionTarget = {\n kind: 'merge-conflict-action',\n resolution: resolutionValue,\n conflictIndex,\n };\n }\n }\n\n if (tokenElement == null && element.hasAttribute('data-char')) {\n tokenElement = element;\n const startAttr = element.getAttribute('data-char');\n\n if (startAttr != null) {\n const lineCharStart = Number.parseInt(startAttr, 10);\n if (!Number.isNaN(lineCharStart)) {\n const tokenText = element.textContent ?? '';\n const lineCharEnd = lineCharStart + tokenText.length;\n if (\n tokenText.trim() !== '' ||\n this.options.enableTokenInteractionsOnWhitespace === true\n ) {\n tokenInfo = {\n tokenElement,\n lineCharStart,\n lineCharEnd,\n tokenText,\n };\n }\n continue;\n }\n }\n }\n\n const columnNumber =\n numberElement == null\n ? (element.getAttribute('data-column-number') ?? undefined)\n : undefined;\n if (columnNumber != null) {\n numberElement = element;\n lineNumber = Number.parseInt(columnNumber, 10);\n numberColumn = true;\n lineType = getLineTypeFromElement(element);\n lineIndexValue = element.getAttribute('data-line-index') ?? undefined;\n continue;\n }\n\n const lineAttr =\n lineElement == null\n ? (element.getAttribute('data-line') ?? undefined)\n : undefined;\n if (lineAttr != null) {\n lineElement = element;\n lineNumber = Number.parseInt(lineAttr, 10);\n lineType = getLineTypeFromElement(element);\n lineIndexValue = element.getAttribute('data-line-index') ?? undefined;\n continue;\n }\n\n if (\n expandInfo == null &&\n (element.hasAttribute('data-expand-button') ||\n element.hasAttribute('data-unmodified-lines'))\n ) {\n expandInfo = {\n hunkIndex: undefined,\n direction: (() => {\n if (element.hasAttribute('data-expand-up')) {\n return 'up';\n }\n if (element.hasAttribute('data-expand-down')) {\n return 'down';\n }\n return 'both';\n })(),\n all: element.hasAttribute('data-expand-all-button'),\n };\n continue;\n }\n\n const expandIndexValue =\n expandInfo != null\n ? (element.getAttribute('data-expand-index') ?? undefined)\n : undefined;\n if (expandInfo != null && expandIndexValue != null) {\n const expandIndex = Number.parseInt(expandIndexValue, 10);\n if (!Number.isNaN(expandIndex)) {\n expandInfo.hunkIndex = expandIndex;\n }\n continue;\n }\n\n if (codeElement == null && element.hasAttribute('data-code')) {\n codeElement = element;\n break;\n }\n }\n\n if (mergeConflictActionTarget != null) {\n return mergeConflictActionTarget as ResolvedPointerTarget<TMode>;\n }\n\n if (expandInfo?.hunkIndex != null) {\n return {\n type: 'line-info',\n hunkIndex: expandInfo.hunkIndex,\n direction: expandInfo.direction,\n all: expandInfo.all,\n } as ResolvedPointerTarget<TMode>;\n }\n\n lineElement ??=\n lineIndexValue != null\n ? queryHTMLElement(\n codeElement,\n `[data-line][data-line-index=\"${lineIndexValue}\"]`\n )\n : undefined;\n numberElement ??=\n lineIndexValue != null\n ? queryHTMLElement(\n codeElement,\n `[data-column-number][data-line-index=\"${lineIndexValue}\"]`\n )\n : undefined;\n\n if (\n codeElement == null ||\n lineElement == null ||\n numberElement == null ||\n lineType == null ||\n lineNumber == null ||\n Number.isNaN(lineNumber)\n ) {\n return undefined;\n }\n\n const splitLineIndex = this.parseLineIndex(lineElement, this.isSplitDiff());\n\n if (tokenInfo != null) {\n if (this.mode === 'file') {\n return {\n kind: 'token',\n lineType,\n lineElement,\n lineNumber,\n numberColumn,\n numberElement,\n side: undefined,\n splitLineIndex,\n ...tokenInfo,\n } as ResolvedPointerTarget<TMode>;\n }\n\n return {\n kind: 'token',\n lineType,\n lineElement,\n lineNumber,\n numberColumn,\n numberElement,\n side: getAnnotationSide(lineType, codeElement),\n splitLineIndex,\n ...tokenInfo,\n } as ResolvedPointerTarget<TMode>;\n }\n\n // Otherwise return line target\n if (this.mode === 'file') {\n return {\n kind: 'line',\n lineType,\n lineElement,\n lineNumber,\n numberColumn,\n numberElement,\n side: undefined,\n splitLineIndex,\n } as ResolvedPointerTarget<TMode>;\n }\n\n return {\n kind: 'line',\n lineType,\n lineElement,\n lineNumber,\n numberColumn,\n numberElement,\n side: getAnnotationSide(lineType, codeElement),\n splitLineIndex,\n } as ResolvedPointerTarget<TMode>;\n }\n\n private isSplitDiff(): boolean {\n return this.pre?.getAttribute('data-diff-type') === 'split';\n }\n\n private parseLineIndex(\n element: HTMLElement,\n split: boolean\n ): number | undefined {\n const lineIndexes = (element.getAttribute('data-line-index') ?? '')\n .split(',')\n .map((value) => Number.parseInt(value, 10))\n .filter((value) => !Number.isNaN(value));\n\n if (split && lineIndexes.length === 2) {\n return lineIndexes[1];\n }\n if (!split) {\n return lineIndexes[0];\n }\n return undefined;\n }\n}\n\ntype InteractionPluckOptions<TMode extends InteractionManagerMode> =\n InteractionManagerBaseOptions<TMode> & {\n renderGutterUtility?(\n getHoveredRow: () => GetHoveredLineResult<TMode> | undefined\n ): HTMLElement | null | undefined;\n };\n\nexport function pluckInteractionOptions<TMode extends InteractionManagerMode>(\n {\n enableTokenInteractionsOnWhitespace,\n enableGutterUtility,\n lineHoverHighlight,\n onGutterUtilityClick,\n onLineClick,\n onLineEnter,\n onLineLeave,\n onLineNumberClick,\n onTokenClick,\n onTokenEnter,\n onTokenLeave,\n renderGutterUtility,\n __debugPointerEvents,\n enableLineSelection,\n controlledSelection,\n onLineSelected,\n onLineSelectionStart,\n onLineSelectionChange,\n onLineSelectionEnd,\n }: InteractionPluckOptions<TMode>,\n onHunkExpand?: (\n hunkIndex: number,\n direction: ExpansionDirections,\n expansionLineCountOverride?: number\n ) => unknown,\n getLineIndex?: GetLineIndexUtility,\n onMergeConflictActionClick?: (target: MergeConflictActionTarget) => void\n): InteractionManagerOptions<TMode> {\n return {\n enableTokenInteractionsOnWhitespace,\n enableGutterUtility: resolveEnableGutterUtilityOption({\n enableGutterUtility,\n renderGutterUtility,\n onGutterUtilityClick,\n }),\n usesCustomGutterUtility: renderGutterUtility != null,\n lineHoverHighlight,\n\n onGutterUtilityClick,\n onHunkExpand,\n onMergeConflictActionClick,\n onLineClick,\n onLineEnter,\n onLineLeave,\n onLineNumberClick,\n onTokenClick,\n onTokenEnter,\n onTokenLeave,\n __debugPointerEvents,\n\n enableLineSelection,\n controlledSelection,\n onLineSelected,\n onLineSelectionStart,\n onLineSelectionChange,\n onLineSelectionEnd,\n\n getLineIndex,\n };\n}\n\nfunction resolveEnableGutterUtilityOption<\n TMode extends InteractionManagerMode,\n>({\n enableGutterUtility,\n renderGutterUtility,\n onGutterUtilityClick,\n}: Pick<\n InteractionPluckOptions<TMode>,\n 'enableGutterUtility' | 'renderGutterUtility' | 'onGutterUtilityClick'\n>): boolean {\n if (onGutterUtilityClick != null && renderGutterUtility != null) {\n throw new Error(\n \"Cannot use both 'onGutterUtilityClick' and 'renderGutterUtility'. Use only one gutter utility API.\"\n );\n }\n return enableGutterUtility ?? false;\n}\n\nfunction isLinePointerTarget<TMode extends InteractionManagerMode>(\n target: ResolvedPointerTarget<TMode> | undefined\n): target is LinePointerTarget<TMode> {\n return target != null && 'kind' in target && target.kind === 'line';\n}\n\nfunction isTokenPointerTarget<TMode extends InteractionManagerMode>(\n target: ResolvedPointerTarget<TMode> | undefined\n): target is TokenPointerTarget<TMode> {\n return target != null && 'kind' in target && target.kind === 'token';\n}\n\nfunction isHoverableLinePointerTarget<TMode extends InteractionManagerMode>(\n target: ResolvedPointerTarget<TMode> | undefined\n): target is HoverableLinePointerTarget<TMode> {\n return isLinePointerTarget(target) || isTokenPointerTarget(target);\n}\n\nfunction isExpandoPointerTarget<TMode extends InteractionManagerMode>(\n target: ResolvedPointerTarget<TMode>\n): target is ExpandoEventProps {\n return 'type' in target && target.type === 'line-info';\n}\n\nfunction isMergeConflictActionPointerTarget<\n TMode extends InteractionManagerMode,\n>(target: ResolvedPointerTarget<TMode>): target is MergeConflictActionTarget {\n return 'kind' in target && target.kind === 'merge-conflict-action';\n}\n\nfunction isMergeConflictResolution(\n value: string | undefined\n): value is MergeConflictResolution {\n return value === 'current' || value === 'incoming' || value === 'both';\n}\n\nfunction queryHTMLElement(\n parent: HTMLElement | undefined,\n query: string\n): HTMLElement | undefined {\n const element = parent?.querySelector(query);\n return element instanceof HTMLElement ? element : undefined;\n}\n\nfunction getElementPath(element: Node): EventTarget[] {\n const path: EventTarget[] = [];\n let current: Node | null = element;\n while (current != null) {\n path.push(current);\n current = current.parentNode;\n }\n return path;\n}\n\n// Pointer hits often land on text/token descendants. This normalizes those\n// hits back to the row elements InteractionManager knows how to resolve.\nfunction closestSelectableRow(element: Element): HTMLElement | undefined {\n const row = element.closest('[data-line], [data-column-number]');\n if (row instanceof HTMLElement) {\n return row;\n }\n\n const annotationRow = element.closest(\n '[data-line-annotation], [data-gutter-buffer=\"annotation\"]'\n );\n if (!(annotationRow instanceof HTMLElement)) {\n return undefined;\n }\n\n const previousRow = annotationRow.previousElementSibling;\n return previousRow instanceof HTMLElement &&\n (previousRow.hasAttribute('data-line') ||\n previousRow.hasAttribute('data-column-number'))\n ? previousRow\n : undefined;\n}\n\nfunction getAnnotationSlotName(element: Element): string | undefined {\n const slottedElement = element.closest('[slot^=\"annotation-\"]');\n if (slottedElement instanceof HTMLElement) {\n return slottedElement.getAttribute('slot') ?? undefined;\n }\n\n if (element instanceof HTMLElement) {\n const slotName = element.getAttribute('name') ?? undefined;\n return slotName != null && slotName.startsWith('annotation-')\n ? slotName\n : undefined;\n }\n\n return undefined;\n}\n\nfunction selectionPointFromAnnotationSlotName(\n slotName: string | undefined\n): SelectionPoint | undefined {\n if (slotName == null) {\n return undefined;\n }\n\n const match = /^annotation-(?:(additions|deletions)-)?(\\d+)$/.exec(slotName);\n if (match == null) {\n return undefined;\n }\n\n const lineNumber = Number.parseInt(match[2], 10);\n if (!Number.isFinite(lineNumber) || lineNumber <= 0) {\n return undefined;\n }\n\n const side = match[1] as SelectionSide | undefined;\n return { lineNumber, side };\n}\n\ninterface ElementFromPointRoot {\n elementFromPoint(x: number, y: number): Element | null;\n}\n\nfunction hasElementFromPoint(\n value: Node | undefined\n): value is Node & ElementFromPointRoot {\n return (\n value != null &&\n typeof (value as Partial<ElementFromPointRoot>).elementFromPoint ===\n 'function'\n );\n}\n\nfunction getAnnotationSide(\n lineType: LineTypes,\n codeElement: HTMLElement\n): AnnotationSide {\n switch (lineType) {\n case 'change-deletion':\n return 'deletions';\n case 'change-addition':\n return 'additions';\n default:\n return codeElement.hasAttribute('data-deletions')\n ? 'deletions'\n : 'additions';\n }\n}\n\nfunction getLineTypeFromElement(element: HTMLElement): LineTypes | undefined {\n const lineType = element.getAttribute('data-line-type');\n if (lineType == null) {\n return undefined;\n }\n switch (lineType) {\n case 'change-deletion':\n case 'change-addition':\n case 'context':\n case 'context-expanded':\n return lineType;\n default:\n return undefined;\n }\n}\n\nfunction isGutterUtilityPath(path: (EventTarget | undefined)[]): boolean {\n for (const element of path) {\n if (!(element instanceof HTMLElement)) {\n continue;\n }\n if (\n element.hasAttribute('data-utility-button') ||\n element.hasAttribute('data-gutter-utility-slot') ||\n // Custom React/DOM utilities are slotted into the same utility surface,\n // so treat both the assigned content and the slot node itself as\n // utility hits.\n element.getAttribute('slot') === 'gutter-utility-slot' ||\n element.getAttribute('name') === 'gutter-utility-slot'\n ) {\n return true;\n }\n }\n return false;\n}\n\nfunction debugLogIfEnabled(\n debugLogType: LogTypes | undefined = 'none',\n logIfType: 'move' | 'click',\n ...args: unknown[]\n) {\n switch (debugLogType) {\n case 'none':\n return;\n case 'both':\n break;\n case 'click':\n if (logIfType !== 'click') {\n return;\n }\n break;\n case 'move':\n if (logIfType !== 'move') {\n return;\n }\n break;\n }\n console.log(...args);\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EditorContext.js","names":[],"sources":["../../src/react/EditorContext.tsx"],"sourcesContent":["'use client';\n\nimport type { Context, PropsWithChildren } from 'react';\nimport { createContext, useContext, useEffect } from 'react';\n\nimport { Editor } from '../editor';\n\nexport const EditorContext: Context<Editor<unknown> | undefined> =\n createContext<Editor<unknown> | undefined>(undefined);\n\nexport function EditorProvider({\n children,\n editor,\n}: PropsWithChildren<{ editor: Editor<unknown> }>): React.JSX.Element {\n useEffect(() => {\n return () => {\n editor.cleanUp();\n };\n }, [editor]);\n return (\n <EditorContext.Provider value={editor}>{children}</EditorContext.Provider>\n );\n}\n\nexport function useEditor<LAnnotation>(): Editor<LAnnotation> | undefined {\n return useContext(EditorContext) as Editor<LAnnotation> | undefined;\n}\n"],"mappings":";;;;AAOA,MAAa,gBACX,cAA2C,KAAA,CAAS;AAEtD,SAAgB,eAAe,EAC7B,UACA,UACoE;CACpE,gBAAgB;EACd,aAAa;GACX,OAAO,QAAQ;EACjB;CACF,GAAG,CAAC,MAAM,CAAC;CACX,OACE,oBAAC,cAAc,UAAf;EAAwB,OAAO;EAAS;CAAiC,CAAA;AAE7E;AAEA,SAAgB,YAA0D;CACxE,OAAO,WAAW,aAAa;AACjC"}
|
|
1
|
+
{"version":3,"file":"EditorContext.js","names":[],"sources":["../../src/react/EditorContext.tsx"],"sourcesContent":["'use client';\n\nimport type { Context, PropsWithChildren } from 'react';\nimport { createContext, useContext, useEffect } from 'react';\n\nimport type { Editor } from '../editor';\n\nexport const EditorContext: Context<Editor<unknown> | undefined> =\n createContext<Editor<unknown> | undefined>(undefined);\n\nexport function EditorProvider({\n children,\n editor,\n}: PropsWithChildren<{ editor: Editor<unknown> }>): React.JSX.Element {\n useEffect(() => {\n return () => {\n editor.cleanUp();\n };\n }, [editor]);\n return (\n <EditorContext.Provider value={editor}>{children}</EditorContext.Provider>\n );\n}\n\nexport function useEditor<LAnnotation>(): Editor<LAnnotation> | undefined {\n return useContext(EditorContext) as Editor<LAnnotation> | undefined;\n}\n"],"mappings":";;;;AAOA,MAAa,gBACX,cAA2C,KAAA,CAAS;AAEtD,SAAgB,eAAe,EAC7B,UACA,UACoE;CACpE,gBAAgB;EACd,aAAa;GACX,OAAO,QAAQ;EACjB;CACF,GAAG,CAAC,MAAM,CAAC;CACX,OACE,oBAAC,cAAc,UAAf;EAAwB,OAAO;EAAS;CAAiC,CAAA;AAE7E;AAEA,SAAgB,YAA0D;CACxE,OAAO,WAAW,aAAa;AACjC"}
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import { FileContents } from "../types.js";
|
|
1
|
+
import { DiffFileInput, FileContents } from "../types.js";
|
|
2
2
|
import { DiffBasePropsReact } from "./types.js";
|
|
3
3
|
|
|
4
4
|
//#region src/react/MultiFileDiff.d.ts
|
|
5
|
-
interface
|
|
6
|
-
oldFile: FileContents;
|
|
7
|
-
newFile: FileContents;
|
|
5
|
+
interface MultiFileDiffBaseProps<LAnnotation> extends DiffBasePropsReact<LAnnotation> {
|
|
8
6
|
disableWorkerPool?: boolean;
|
|
9
7
|
contentEditable?: boolean;
|
|
10
8
|
}
|
|
9
|
+
type MultiFileDiffProps<LAnnotation> = MultiFileDiffBaseProps<LAnnotation> & DiffFileInput;
|
|
11
10
|
declare function MultiFileDiff<LAnnotation = undefined>({
|
|
12
11
|
oldFile,
|
|
13
12
|
newFile,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultiFileDiff.d.ts","names":[],"sources":["../../src/react/MultiFileDiff.tsx"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"MultiFileDiff.d.ts","names":[],"sources":["../../src/react/MultiFileDiff.tsx"],"mappings":";;;;UAcU,sBAAA,sBAEA,kBAAkB,CAAC,WAAA;EAC3B,iBAAA;EACA,eAAA;AAAA;AAAA,KAGU,kBAAA,gBACV,sBAAA,CAAuB,WAAA,IAAe,aAAA;AAAA,iBAExB,aAAA;EACd,OAAA;EACA,OAAA;EACA,OAAA;EACA,OAAA;EACA,eAAA;EACA,aAAA;EACA,SAAA;EACA,KAAA;EACA,eAAA;EACA,gBAAA;EACA,kBAAA;EACA,kBAAA;EACA,0BAAA;EACA,oBAAA;EACA,mBAAA;EACA,iBAAA;EACA;AAAA,GACC,kBAAA,CAAmB,WAAA,IAAe,KAAA,CAAM,GAAA,CAAI,OAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultiFileDiff.js","names":[],"sources":["../../src/react/MultiFileDiff.tsx"],"sourcesContent":["'use client';\n\nimport { useMemo } from 'react';\n\nimport { DIFFS_TAG_NAME } from '../constants';\nimport type { FileContents } from '../types';\nimport { parseDiffFromFile } from '../utils/parseDiffFromFile';\nimport type { DiffBasePropsReact } from './types';\nimport { renderDiffChildren } from './utils/renderDiffChildren';\nimport { templateRender } from './utils/templateRender';\nimport { useFileDiffInstance } from './utils/useFileDiffInstance';\n\nexport type { FileContents };\n\
|
|
1
|
+
{"version":3,"file":"MultiFileDiff.js","names":[],"sources":["../../src/react/MultiFileDiff.tsx"],"sourcesContent":["'use client';\n\nimport { useMemo } from 'react';\n\nimport { DIFFS_TAG_NAME } from '../constants';\nimport type { DiffFileInput, FileContents } from '../types';\nimport { parseDiffFromFile } from '../utils/parseDiffFromFile';\nimport type { DiffBasePropsReact } from './types';\nimport { renderDiffChildren } from './utils/renderDiffChildren';\nimport { templateRender } from './utils/templateRender';\nimport { useFileDiffInstance } from './utils/useFileDiffInstance';\n\nexport type { FileContents };\n\ninterface MultiFileDiffBaseProps<\n LAnnotation,\n> extends DiffBasePropsReact<LAnnotation> {\n disableWorkerPool?: boolean;\n contentEditable?: boolean;\n}\n\nexport type MultiFileDiffProps<LAnnotation> =\n MultiFileDiffBaseProps<LAnnotation> & DiffFileInput;\n\nexport function MultiFileDiff<LAnnotation = undefined>({\n oldFile,\n newFile,\n options,\n metrics,\n lineAnnotations,\n selectedLines,\n className,\n style,\n prerenderedHTML,\n renderAnnotation,\n renderCustomHeader,\n renderHeaderPrefix,\n renderHeaderFilenameSuffix,\n renderHeaderMetadata,\n renderGutterUtility,\n disableWorkerPool = false,\n contentEditable = false,\n}: MultiFileDiffProps<LAnnotation>): React.JSX.Element {\n const fileDiff = useMemo(() => {\n return parseDiffFromFile(oldFile, newFile, options?.parseDiffOptions);\n }, [oldFile, newFile, options?.parseDiffOptions]);\n const { ref, getHoveredLine } = useFileDiffInstance({\n fileDiff,\n options,\n metrics,\n lineAnnotations,\n selectedLines,\n prerenderedHTML,\n hasGutterRenderUtility: renderGutterUtility != null,\n hasCustomHeader: renderCustomHeader != null,\n disableWorkerPool,\n contentEditable,\n });\n const children = renderDiffChildren({\n fileDiff,\n renderCustomHeader,\n renderHeaderPrefix,\n renderHeaderFilenameSuffix,\n renderHeaderMetadata,\n renderAnnotation,\n lineAnnotations,\n renderGutterUtility,\n getHoveredLine,\n });\n return (\n <DIFFS_TAG_NAME ref={ref} className={className} style={style}>\n {templateRender(children, prerenderedHTML)}\n </DIFFS_TAG_NAME>\n );\n}\n"],"mappings":";;;;;;;;;AAwBA,SAAgB,cAAuC,EACrD,SACA,SACA,SACA,SACA,iBACA,eACA,WACA,OACA,iBACA,kBACA,oBACA,oBACA,4BACA,sBACA,qBACA,oBAAoB,OACpB,kBAAkB,SACmC;CACrD,MAAM,WAAW,cAAc;EAC7B,OAAO,kBAAkB,SAAS,SAAS,SAAS,gBAAgB;CACtE,GAAG;EAAC;EAAS;EAAS,SAAS;CAAgB,CAAC;CAChD,MAAM,EAAE,KAAK,mBAAmB,oBAAoB;EAClD;EACA;EACA;EACA;EACA;EACA;EACA,wBAAwB,uBAAuB;EAC/C,iBAAiB,sBAAsB;EACvC;EACA;CACF,CAAC;CAYD,OACE,oBAAC,gBAAD;EAAqB;EAAgB;EAAkB;YACpD,eAbY,mBAAmB;GAClC;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF,CAG2B,GAAG,eAAe;CAC3B,CAAA;AAEpB"}
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
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, DiffIndicators, DiffLineAnnotation, DiffLineEventBaseProps, DiffTokenEventBaseProps, DiffsBaseComponent, DiffsComponentOptions, DiffsEditableComponent, DiffsEditor, DiffsEditorSelection, DiffsHighlighter, DiffsTextDocument, DiffsThemeNames, ExpansionDirections, ExtensionFormatMap, FileContents, FileDiffMetadata, FileHeaderRenderMode, ForceDiffPlainTextOptions, ForceFilePlainTextOptions, GapSpan, HighlightedToken, HighlighterTypes, Hunk, HunkData, HunkExpansionRegion, HunkLineType, HunkSeparators, LanguageRegistration, LineAnnotation, LineDiffTypes, LineEventBaseProps, LineInfo, LineSpans, LineTypes, 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, 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";
|
|
2
2
|
import { WorkerInitializationRenderOptions, WorkerPoolOptions } from "../worker/types.js";
|
|
3
3
|
import { FileOptions } from "../components/File.js";
|
|
4
4
|
import { CodeView, CodeViewHandle, CodeViewProps, ControlledCodeViewProps, UncontrolledCodeViewProps } from "./CodeView.js";
|
|
@@ -18,4 +18,4 @@ import { templateRender } from "./utils/templateRender.js";
|
|
|
18
18
|
import { useFileDiffInstance } from "./utils/useFileDiffInstance.js";
|
|
19
19
|
import { useFileInstance } from "./utils/useFileInstance.js";
|
|
20
20
|
import { useStableCallback } from "./utils/useStableCallback.js";
|
|
21
|
-
export { AnnotationLineMap, AnnotationSide, AnnotationSpan, AppliedThemeStyleCache, BaseCodeOptions, BaseDiffOptions, BaseDiffOptionsWithDefaults, type BundledLanguage, ChangeContent, ChangeTypes, CodeColumnType, type CodeToHastOptions, CodeView, CodeViewDiffItem, CodeViewFileItem, CodeViewHandle, CodeViewItem, CodeViewItemScrollTarget, CodeViewLayout, CodeViewLineScrollTarget, CodeViewPositionScrollTarget, CodeViewProps, CodeViewRangeScrollTarget, CodeViewScrollBehavior, CodeViewScrollTarget, ConflictResolverTypes, ContextContent, ControlledCodeViewProps, type CreatePatchOptionsNonabortable, CustomPreProperties, type DecorationItem, DiffAcceptRejectHunkConfig, DiffAcceptRejectHunkType, DiffBasePropsReact, DiffIndicators, DiffLineAnnotation, DiffLineEventBaseProps, DiffTokenEventBaseProps, DiffsBaseComponent, DiffsComponentOptions, DiffsEditableComponent, DiffsEditor, DiffsEditorSelection, DiffsHighlighter, DiffsTextDocument, DiffsThemeNames, EditorContext, EditorProvider, ExpansionDirections, ExtensionFormatMap, File, FileContents, FileDiff, FileDiffMetadata, FileDiffProps, FileHeaderRenderMode, type FileOptions, FileProps, ForceDiffPlainTextOptions, ForceFilePlainTextOptions, GapSpan, GutterUtilitySlotStyles, HighlightedToken, HighlighterTypes, Hunk, HunkData, HunkExpansionRegion, HunkLineType, HunkSeparators, type LanguageRegistration, LineAnnotation, LineDiffTypes, LineEventBaseProps, LineInfo, LineSpans, LineTypes, MergeConflictActionPayload, MergeConflictActionsTypeOption, MergeConflictMarkerRow, MergeConflictMarkerRowType, MergeConflictRegion, MergeConflictResolution, MergeConflictSlotStyles, MultiFileDiff, MultiFileDiffProps, NumericScrollLineAnchor, ObservedAnnotationNodes, ObservedGridNodes, ParsedPatch, PatchDiff, PatchDiffProps, PendingCodeViewLayoutReset, PostRenderPhase, PrePropertiesConfig, ProcessFileConflictData, RenderDiffFilesResult, RenderDiffOptions, RenderDiffResult, RenderFileMetadata, RenderFileOptions, RenderFileResult, RenderHeaderFilenameSuffixCallback, RenderHeaderMetadataCallback, RenderHeaderPrefixCallback, RenderMergeConflictActionContext, RenderMergeConflictActions, RenderRange, RenderWindow, RenderedDiffASTCache, RenderedFileASTCache, SelectedLineRange, SelectionPoint, SelectionSide, SharedRenderState, type ShikiTransformer, SmoothScrollSettings, StickySpecs, SupportedLanguages, type ThemeRegistration, type ThemeRegistrationResolved, ThemeTypes, ThemedDiffResult, ThemedFileResult, type ThemedToken, ThemesType, TokenEventBase, UncontrolledCodeViewProps, UnresolvedFile, UnresolvedFileProps, UnresolvedFileReactOptions, VirtualFileMetrics, VirtualWindowSpecs, Virtualizer, VirtualizerContext, type WorkerInitializationRenderOptions, WorkerPoolContext, WorkerPoolContextProvider, type WorkerPoolOptions, noopRender, renderDiffChildren, renderFileChildren, templateRender, useEditor, useFileDiffInstance, useFileInstance, useStableCallback, useVirtualizer, useWorkerPool };
|
|
21
|
+
export { AnnotationLineMap, AnnotationSide, AnnotationSpan, AppliedThemeStyleCache, BaseCodeOptions, BaseDiffOptions, BaseDiffOptionsWithDefaults, type BundledLanguage, ChangeContent, ChangeTypes, CodeColumnType, type CodeToHastOptions, CodeView, CodeViewDiffItem, CodeViewFileItem, CodeViewHandle, CodeViewItem, CodeViewItemScrollTarget, CodeViewLayout, CodeViewLineScrollTarget, CodeViewPositionScrollTarget, CodeViewProps, CodeViewRangeScrollTarget, CodeViewScrollBehavior, CodeViewScrollTarget, ConflictResolverTypes, ContextContent, ControlledCodeViewProps, type CreatePatchOptionsNonabortable, CustomPreProperties, type DecorationItem, DiffAcceptRejectHunkConfig, DiffAcceptRejectHunkType, DiffBasePropsReact, DiffFileInput, DiffIndicators, DiffLineAnnotation, DiffLineEventBaseProps, DiffTokenEventBaseProps, DiffsBaseComponent, DiffsComponentOptions, DiffsEditableComponent, DiffsEditor, DiffsEditorSelection, DiffsHighlighter, DiffsTextDocument, DiffsThemeNames, EditorContext, EditorProvider, ExpansionDirections, ExtensionFormatMap, File, FileContents, FileDiff, FileDiffContentsLoader, FileDiffLoadedChangedFiles, FileDiffLoadedFiles, FileDiffLoadedPureRenamedFile, FileDiffMetadata, FileDiffProps, FileHeaderRenderMode, type FileOptions, FileProps, ForceDiffPlainTextOptions, ForceFilePlainTextOptions, GapSpan, GutterUtilitySlotStyles, HighlightedToken, HighlighterTypes, Hunk, HunkData, HunkExpansionRegion, HunkLineType, HunkSeparators, type LanguageRegistration, LineAnnotation, LineDiffTypes, LineEventBaseProps, LineInfo, LineSpans, LineTypes, MaybeDiffFileInput, MergeConflictActionPayload, MergeConflictActionsTypeOption, MergeConflictMarkerRow, MergeConflictMarkerRowType, MergeConflictRegion, MergeConflictResolution, MergeConflictSlotStyles, MultiFileDiff, MultiFileDiffProps, NumericScrollLineAnchor, ObservedAnnotationNodes, ObservedGridNodes, ParsedPatch, PatchDiff, PatchDiffProps, PendingCodeViewLayoutReset, PostRenderPhase, PrePropertiesConfig, ProcessFileConflictData, RenderDiffFilesResult, RenderDiffOptions, RenderDiffResult, RenderFileMetadata, RenderFileOptions, RenderFileResult, RenderHeaderFilenameSuffixCallback, RenderHeaderMetadataCallback, RenderHeaderPrefixCallback, RenderMergeConflictActionContext, RenderMergeConflictActions, RenderRange, RenderWindow, RenderedDiffASTCache, RenderedFileASTCache, SelectedLineRange, SelectionPoint, SelectionSide, SharedRenderState, type ShikiTransformer, SmoothScrollSettings, StickySpecs, SupportedLanguages, type ThemeRegistration, type ThemeRegistrationResolved, ThemeTypes, ThemedDiffResult, ThemedFileResult, type ThemedToken, ThemesType, TokenEventBase, UncontrolledCodeViewProps, UnresolvedFile, UnresolvedFileProps, UnresolvedFileReactOptions, VirtualFileMetrics, VirtualWindowSpecs, Virtualizer, VirtualizerContext, type WorkerInitializationRenderOptions, WorkerPoolContext, WorkerPoolContextProvider, type WorkerPoolOptions, noopRender, renderDiffChildren, renderFileChildren, templateRender, useEditor, useFileDiffInstance, useFileInstance, useStableCallback, useVirtualizer, useWorkerPool };
|