@pierre/diffs 1.2.12 → 1.3.0-beta.10
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 +91 -6
- package/dist/components/CodeView.d.ts.map +1 -1
- package/dist/components/CodeView.js +300 -38
- package/dist/components/CodeView.js.map +1 -1
- package/dist/components/File.d.ts +14 -3
- package/dist/components/File.d.ts.map +1 -1
- package/dist/components/File.js +98 -12
- package/dist/components/File.js.map +1 -1
- package/dist/components/FileDiff.d.ts +68 -19
- package/dist/components/FileDiff.d.ts.map +1 -1
- package/dist/components/FileDiff.js +363 -25
- package/dist/components/FileDiff.js.map +1 -1
- package/dist/components/FileStream.d.ts.map +1 -1
- package/dist/components/FileStream.js +2 -1
- package/dist/components/FileStream.js.map +1 -1
- package/dist/components/UnresolvedFile.d.ts +2 -2
- package/dist/components/UnresolvedFile.d.ts.map +1 -1
- package/dist/components/UnresolvedFile.js +2 -2
- package/dist/components/UnresolvedFile.js.map +1 -1
- package/dist/components/VirtualizedFile.d.ts +4 -2
- package/dist/components/VirtualizedFile.d.ts.map +1 -1
- package/dist/components/VirtualizedFile.js +59 -47
- package/dist/components/VirtualizedFile.js.map +1 -1
- package/dist/components/VirtualizedFileDiff.d.ts +27 -5
- package/dist/components/VirtualizedFileDiff.d.ts.map +1 -1
- package/dist/components/VirtualizedFileDiff.js +262 -56
- package/dist/components/VirtualizedFileDiff.js.map +1 -1
- package/dist/components/Virtualizer.d.ts +4 -1
- package/dist/components/Virtualizer.d.ts.map +1 -1
- package/dist/components/Virtualizer.js +21 -4
- package/dist/components/Virtualizer.js.map +1 -1
- package/dist/constants.d.ts +4 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +4 -1
- package/dist/constants.js.map +1 -1
- package/dist/editor/command.d.ts +7 -0
- package/dist/editor/command.d.ts.map +1 -0
- package/dist/editor/command.js +54 -0
- package/dist/editor/command.js.map +1 -0
- package/dist/editor/editStack.d.ts +71 -0
- package/dist/editor/editStack.d.ts.map +1 -0
- package/dist/editor/editStack.js +218 -0
- package/dist/editor/editStack.js.map +1 -0
- package/dist/editor/editor.d.ts +105 -0
- package/dist/editor/editor.d.ts.map +1 -0
- package/dist/editor/editor.js +2545 -0
- package/dist/editor/editor.js.map +1 -0
- package/dist/editor/editor2.js +6 -0
- package/dist/editor/editor2.js.map +1 -0
- package/dist/editor/index.d.ts +5 -0
- package/dist/editor/index.js +3 -0
- package/dist/editor/languages.d.ts +26 -0
- package/dist/editor/languages.d.ts.map +1 -0
- package/dist/editor/languages.js +363 -0
- package/dist/editor/languages.js.map +1 -0
- package/dist/editor/lineAnnotations.d.ts +9 -0
- package/dist/editor/lineAnnotations.d.ts.map +1 -0
- package/dist/editor/lineAnnotations.js +212 -0
- package/dist/editor/lineAnnotations.js.map +1 -0
- package/dist/editor/marker.d.ts +38 -0
- package/dist/editor/marker.d.ts.map +1 -0
- package/dist/editor/marker.js +245 -0
- package/dist/editor/marker.js.map +1 -0
- package/dist/editor/matchBrackets.d.ts +9 -0
- package/dist/editor/matchBrackets.d.ts.map +1 -0
- package/dist/editor/matchBrackets.js +138 -0
- package/dist/editor/matchBrackets.js.map +1 -0
- package/dist/editor/pieceTable.d.ts +41 -0
- package/dist/editor/pieceTable.d.ts.map +1 -0
- package/dist/editor/pieceTable.js +671 -0
- package/dist/editor/pieceTable.js.map +1 -0
- package/dist/editor/platform.d.ts +19 -0
- package/dist/editor/platform.d.ts.map +1 -0
- package/dist/editor/platform.js +57 -0
- package/dist/editor/platform.js.map +1 -0
- package/dist/editor/popover.d.ts +65 -0
- package/dist/editor/popover.d.ts.map +1 -0
- package/dist/editor/popover.js +187 -0
- package/dist/editor/popover.js.map +1 -0
- package/dist/editor/searchPanel.d.ts +40 -0
- package/dist/editor/searchPanel.d.ts.map +1 -0
- package/dist/editor/searchPanel.js +318 -0
- package/dist/editor/searchPanel.js.map +1 -0
- package/dist/editor/selection.d.ts +211 -0
- package/dist/editor/selection.d.ts.map +1 -0
- package/dist/editor/selection.js +1626 -0
- package/dist/editor/selection.js.map +1 -0
- package/dist/editor/selectionAction.d.ts +46 -0
- package/dist/editor/selectionAction.d.ts.map +1 -0
- package/dist/editor/selectionAction.js +64 -0
- package/dist/editor/selectionAction.js.map +1 -0
- package/dist/editor/sprite.d.ts +8 -0
- package/dist/editor/sprite.d.ts.map +1 -0
- package/dist/editor/sprite.js +45 -0
- package/dist/editor/sprite.js.map +1 -0
- package/dist/editor/stateStorage.d.ts +15 -0
- package/dist/editor/stateStorage.d.ts.map +1 -0
- package/dist/editor/stateStorage.js +65 -0
- package/dist/editor/stateStorage.js.map +1 -0
- package/dist/editor/textDocument.d.ts +77 -0
- package/dist/editor/textDocument.d.ts.map +1 -0
- package/dist/editor/textDocument.js +271 -0
- package/dist/editor/textDocument.js.map +1 -0
- package/dist/editor/textMeasure.d.ts +61 -0
- package/dist/editor/textMeasure.d.ts.map +1 -0
- package/dist/editor/textMeasure.js +209 -0
- package/dist/editor/textMeasure.js.map +1 -0
- package/dist/editor/tokenizer.d.ts +41 -0
- package/dist/editor/tokenizer.d.ts.map +1 -0
- package/dist/editor/tokenizer.js +513 -0
- package/dist/editor/tokenizer.js.map +1 -0
- package/dist/editor/utils.d.ts +21 -0
- package/dist/editor/utils.d.ts.map +1 -0
- package/dist/editor/utils.js +68 -0
- package/dist/editor/utils.js.map +1 -0
- package/dist/index.d.ts +10 -8
- package/dist/index.js +12 -10
- package/dist/managers/InteractionManager.d.ts +7 -0
- package/dist/managers/InteractionManager.d.ts.map +1 -1
- package/dist/managers/InteractionManager.js +22 -1
- package/dist/managers/InteractionManager.js.map +1 -1
- package/dist/managers/ResizeManager.d.ts +10 -2
- package/dist/managers/ResizeManager.d.ts.map +1 -1
- package/dist/managers/ResizeManager.js +33 -13
- package/dist/managers/ResizeManager.js.map +1 -1
- package/dist/managers/UniversalRenderingManager.d.ts +2 -1
- package/dist/managers/UniversalRenderingManager.d.ts.map +1 -1
- package/dist/managers/UniversalRenderingManager.js +6 -1
- package/dist/managers/UniversalRenderingManager.js.map +1 -1
- package/dist/react/CodeView.d.ts +26 -1
- package/dist/react/CodeView.d.ts.map +1 -1
- package/dist/react/CodeView.js +82 -19
- package/dist/react/CodeView.js.map +1 -1
- package/dist/react/EditContext.d.ts +15 -0
- package/dist/react/EditContext.d.ts.map +1 -0
- package/dist/react/EditContext.js +23 -0
- package/dist/react/EditContext.js.map +1 -0
- package/dist/react/File.d.ts +3 -1
- package/dist/react/File.d.ts.map +1 -1
- package/dist/react/File.js +4 -2
- package/dist/react/File.js.map +1 -1
- package/dist/react/FileDiff.d.ts +4 -1
- package/dist/react/FileDiff.d.ts.map +1 -1
- package/dist/react/FileDiff.js +4 -2
- package/dist/react/FileDiff.js.map +1 -1
- package/dist/react/MultiFileDiff.d.ts +7 -5
- package/dist/react/MultiFileDiff.d.ts.map +1 -1
- package/dist/react/MultiFileDiff.js +4 -2
- package/dist/react/MultiFileDiff.js.map +1 -1
- package/dist/react/PatchDiff.d.ts +4 -1
- package/dist/react/PatchDiff.d.ts.map +1 -1
- package/dist/react/PatchDiff.js +4 -2
- package/dist/react/PatchDiff.js.map +1 -1
- package/dist/react/UnresolvedFile.d.ts +1 -0
- package/dist/react/UnresolvedFile.d.ts.map +1 -1
- package/dist/react/UnresolvedFile.js +2 -1
- package/dist/react/UnresolvedFile.js.map +1 -1
- package/dist/react/index.d.ts +3 -2
- package/dist/react/index.js +2 -1
- package/dist/react/types.d.ts +3 -0
- package/dist/react/types.d.ts.map +1 -1
- package/dist/react/utils/renderDiffChildren.d.ts +2 -0
- package/dist/react/utils/renderDiffChildren.d.ts.map +1 -1
- package/dist/react/utils/renderDiffChildren.js +16 -8
- package/dist/react/utils/renderDiffChildren.js.map +1 -1
- package/dist/react/utils/renderFileChildren.d.ts +2 -0
- package/dist/react/utils/renderFileChildren.d.ts.map +1 -1
- package/dist/react/utils/renderFileChildren.js +16 -8
- package/dist/react/utils/renderFileChildren.js.map +1 -1
- package/dist/react/utils/useFileDiffInstance.d.ts +3 -1
- package/dist/react/utils/useFileDiffInstance.d.ts.map +1 -1
- package/dist/react/utils/useFileDiffInstance.js +30 -6
- package/dist/react/utils/useFileDiffInstance.js.map +1 -1
- package/dist/react/utils/useFileInstance.d.ts +4 -1
- package/dist/react/utils/useFileInstance.d.ts.map +1 -1
- package/dist/react/utils/useFileInstance.js +30 -5
- package/dist/react/utils/useFileInstance.js.map +1 -1
- package/dist/renderers/DiffHunksRenderer.d.ts +28 -2
- package/dist/renderers/DiffHunksRenderer.d.ts.map +1 -1
- package/dist/renderers/DiffHunksRenderer.js +244 -22
- package/dist/renderers/DiffHunksRenderer.js.map +1 -1
- package/dist/renderers/FileRenderer.d.ts +8 -1
- package/dist/renderers/FileRenderer.d.ts.map +1 -1
- package/dist/renderers/FileRenderer.js +155 -45
- 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 +15 -7
- package/dist/ssr/preloadDiffs.js.map +1 -1
- package/dist/style.js +1 -1
- package/dist/types.d.ts +282 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/applyLineTextWithNewline.d.ts +5 -0
- package/dist/utils/applyLineTextWithNewline.d.ts.map +1 -0
- package/dist/utils/applyLineTextWithNewline.js +11 -0
- package/dist/utils/applyLineTextWithNewline.js.map +1 -0
- package/dist/utils/areHunkDataEqual.js +1 -1
- package/dist/utils/areHunkDataEqual.js.map +1 -1
- package/dist/utils/areManagedSnapshotsEqual.d.ts +2 -2
- package/dist/utils/areManagedSnapshotsEqual.d.ts.map +1 -1
- package/dist/utils/areManagedSnapshotsEqual.js +5 -0
- package/dist/utils/areManagedSnapshotsEqual.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/cleanLastNewline.js +6 -1
- package/dist/utils/cleanLastNewline.js.map +1 -1
- 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/computeFileOffsets.d.ts +21 -0
- package/dist/utils/computeFileOffsets.d.ts.map +1 -0
- package/dist/utils/computeFileOffsets.js +51 -0
- package/dist/utils/computeFileOffsets.js.map +1 -0
- package/dist/utils/createCodeViewHeaderFooterHostElement.d.ts +5 -0
- package/dist/utils/createCodeViewHeaderFooterHostElement.d.ts.map +1 -0
- package/dist/utils/createCodeViewHeaderFooterHostElement.js +19 -0
- package/dist/utils/createCodeViewHeaderFooterHostElement.js.map +1 -0
- package/dist/utils/createFileHeaderElement.d.ts.map +1 -1
- package/dist/utils/createFileHeaderElement.js +5 -1
- package/dist/utils/createFileHeaderElement.js.map +1 -1
- package/dist/utils/createTransformerWithState.js +9 -0
- package/dist/utils/createTransformerWithState.js.map +1 -1
- package/dist/utils/editSessionHunks.d.ts +84 -0
- package/dist/utils/editSessionHunks.d.ts.map +1 -0
- package/dist/utils/editSessionHunks.js +366 -0
- package/dist/utils/editSessionHunks.js.map +1 -0
- 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/parsePatchFiles.d.ts.map +1 -1
- package/dist/utils/parsePatchFiles.js +2 -0
- package/dist/utils/parsePatchFiles.js.map +1 -1
- package/dist/utils/realignChangeContent.d.ts +28 -0
- package/dist/utils/realignChangeContent.d.ts.map +1 -0
- package/dist/utils/realignChangeContent.js +142 -0
- package/dist/utils/realignChangeContent.js.map +1 -0
- package/dist/utils/renderDiffWithHighlighter.js +1 -1
- package/dist/utils/renderFileWithHighlighter.d.ts.map +1 -1
- package/dist/utils/renderFileWithHighlighter.js +5 -14
- package/dist/utils/renderFileWithHighlighter.js.map +1 -1
- package/dist/utils/updateDiffHunks.d.ts +24 -0
- package/dist/utils/updateDiffHunks.d.ts.map +1 -0
- package/dist/utils/updateDiffHunks.js +235 -0
- package/dist/utils/updateDiffHunks.js.map +1 -0
- package/dist/utils/virtualDiffLayout.d.ts +40 -1
- package/dist/utils/virtualDiffLayout.d.ts.map +1 -1
- package/dist/utils/virtualDiffLayout.js +96 -1
- package/dist/utils/virtualDiffLayout.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 +83 -18
- package/dist/worker/WorkerPoolManager.js.map +1 -1
- package/dist/worker/index.d.ts +2 -2
- package/dist/worker/types.d.ts +11 -1
- package/dist/worker/types.d.ts.map +1 -1
- package/dist/worker/worker-portable.js +46 -66
- package/dist/worker/worker-portable.js.map +1 -1
- package/dist/worker/worker.js +46 -66
- package/dist/worker/worker.js.map +1 -1
- package/package.json +12 -5
- package/dist/utils/iterateOverFile.d.ts +0 -50
- package/dist/utils/iterateOverFile.d.ts.map +0 -1
- package/dist/utils/iterateOverFile.js +0 -49
- package/dist/utils/iterateOverFile.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ResizeManager.js","names":[],"sources":["../../src/managers/ResizeManager.ts"],"sourcesContent":["import type { ObservedAnnotationNodes, ObservedGridNodes } from '../types';\n\ninterface CodeColumnUpdate {\n codeInlineSize?: number;\n numberInlineSize?: number;\n measuredNumberInlineSize?: number;\n}\n\ntype CodeUpdateMap = Map<ObservedGridNodes, CodeColumnUpdate>;\n\ninterface AnnotationSetup {\n child1: HTMLElement;\n child2: HTMLElement;\n item: ObservedAnnotationNodes;\n newHeight: number;\n}\n\nexport class ResizeManager {\n // Shared static resizeObserver that all ResizeManagers use\n private static resizeObserver: ResizeObserver | undefined;\n private static managersByElement = new Map<Element, ResizeManager>();\n\n private static getResizeObserver(): ResizeObserver {\n const resizeObserver =\n ResizeManager.resizeObserver ??\n new ResizeObserver(ResizeManager.handleSharedResizeEntries);\n ResizeManager.resizeObserver = resizeObserver;\n return resizeObserver;\n }\n\n private static handleSharedResizeEntries(entries: ResizeObserverEntry[]) {\n // First we need to batch all elements by manager, so callbacks are\n // properly aligned with a per-instance ResizeManager\n const entriesByManager = new Map<ResizeManager, ResizeObserverEntry[]>();\n for (const entry of entries) {\n const manager = ResizeManager.managersByElement.get(entry.target);\n if (manager == null) {\n continue;\n }\n const managerEntries = entriesByManager.get(manager);\n if (managerEntries == null) {\n entriesByManager.set(manager, [entry]);\n } else {\n managerEntries.push(entry);\n }\n }\n\n for (const [manager, managerEntries] of entriesByManager) {\n manager.handleResizeEntries(managerEntries);\n }\n }\n\n private observedNodes = new Map<\n HTMLElement,\n ObservedAnnotationNodes | ObservedGridNodes\n >();\n\n setup(pre: HTMLPreElement, disableAnnotations: boolean): void {\n const annotationUpdates = new Set<AnnotationSetup>();\n let columnCount = 0;\n const observedNodes = new Map(this.observedNodes);\n this.observedNodes.clear();\n\n for (const element of pre.children) {\n if (columnCount === 2) {\n break;\n }\n const codeElement: HTMLElement | undefined = (() => {\n if (element instanceof HTMLElement && element.tagName === 'CODE') {\n return element;\n }\n return undefined;\n })();\n if (codeElement == null) {\n continue;\n }\n columnCount++;\n let item: ObservedGridNodes | ObservedAnnotationNodes | undefined =\n observedNodes.get(codeElement);\n if (item != null && item.type !== 'code') {\n throw new Error(\n 'ResizeManager.setup: somehow a code node is being used for an annotation, should be impossible'\n );\n }\n\n let numberElement = codeElement.firstElementChild;\n if (!(numberElement instanceof HTMLElement)) {\n numberElement = null;\n }\n if (item != null) {\n this.observedNodes.set(codeElement, item);\n observedNodes.delete(codeElement);\n if (item.numberElement !== numberElement) {\n if (item.numberElement != null) {\n this.unobserve(item.numberElement);\n observedNodes.delete(item.numberElement);\n }\n if (numberElement != null) {\n this.observe(numberElement);\n observedNodes.delete(numberElement);\n this.observedNodes.set(numberElement, item);\n }\n item.numberElement = numberElement;\n item.numberWidth = 0;\n } else if (item.numberElement != null) {\n observedNodes.delete(item.numberElement);\n this.observedNodes.set(item.numberElement, item);\n // If there is a resize, let the resize handler handle it...\n } else {\n item.numberWidth = 0;\n }\n } else {\n item = {\n type: 'code',\n codeElement,\n numberElement,\n codeWidth: 'auto',\n numberWidth: 0,\n };\n this.observedNodes.set(codeElement, item);\n this.observe(codeElement);\n if (numberElement != null) {\n this.observedNodes.set(numberElement, item);\n this.observe(numberElement);\n }\n }\n }\n\n if (columnCount > 1 && !disableAnnotations) {\n const annotationElements = pre.querySelectorAll(\n '[data-line-annotation*=\",\"]'\n );\n\n const elementMap = new Map<string, HTMLElement[]>();\n // Iterate through all the matched elements and organize them into pairs\n // based on the data-line-annotation attribute\n for (const element of annotationElements) {\n if (!(element instanceof HTMLElement)) {\n continue;\n }\n const lineAnnotation =\n element.getAttribute('data-line-annotation') ?? '';\n if (!/^-?\\d+,-?\\d+$/.test(lineAnnotation)) {\n console.error(\n 'DiffFileRenderer.setupResizeObserver: Invalid element or annotation',\n { lineAnnotation, element }\n );\n continue;\n }\n let pairs = elementMap.get(lineAnnotation);\n if (pairs == null) {\n pairs = [];\n elementMap.set(lineAnnotation, pairs);\n }\n pairs.push(element);\n }\n\n for (const [key, pair] of elementMap) {\n if (pair.length !== 2) {\n console.error(\n 'DiffFileRenderer.setupResizeObserver: Bad Pair',\n key,\n pair\n );\n continue;\n }\n const [container1, container2] = pair;\n const child1 = container1.firstElementChild;\n const child2 = container2.firstElementChild;\n if (\n !(container1 instanceof HTMLElement) ||\n !(container2 instanceof HTMLElement) ||\n !(child1 instanceof HTMLElement) ||\n !(child2 instanceof HTMLElement)\n ) {\n continue;\n }\n\n let item = observedNodes.get(child1);\n\n if (item != null) {\n this.observedNodes.set(child1, item);\n this.observedNodes.set(child2, item);\n observedNodes.delete(child1);\n observedNodes.delete(child2);\n continue;\n }\n\n const child1Height = child1.getBoundingClientRect().height;\n const child2Height = child2.getBoundingClientRect().height;\n item = {\n type: 'annotations',\n column1: {\n container: container1,\n child: child1,\n childHeight: child1Height,\n },\n column2: {\n container: container2,\n child: child2,\n childHeight: child2Height,\n },\n currentHeight: 'auto',\n };\n annotationUpdates.add({\n child1,\n child2,\n item,\n newHeight: Math.max(child1Height, child2Height),\n });\n }\n\n // Measure all annotation heights first, then apply the paired min-height\n // styles after the read phase so setup does not bounce between layout\n // reads and writes for every annotation pair.\n for (const pendingUpdate of annotationUpdates) {\n this.applyNewHeight(pendingUpdate.item, pendingUpdate.newHeight);\n this.observedNodes.set(pendingUpdate.child1, pendingUpdate.item);\n this.observedNodes.set(pendingUpdate.child2, pendingUpdate.item);\n this.observe(pendingUpdate.child1);\n this.observe(pendingUpdate.child2);\n }\n annotationUpdates.clear();\n }\n\n // Cleanup any old nodes that might still be observed\n for (const [element, item] of observedNodes) {\n this.unobserve(element);\n if (item.type === 'code') {\n cleanupStaleCodeItem(item);\n } else {\n cleanupStaleAnnotationItem(item);\n }\n }\n observedNodes.clear();\n }\n\n cleanUp(): void {\n for (const element of this.observedNodes.keys()) {\n this.unobserve(element);\n }\n this.observedNodes.clear();\n }\n\n private observe(element: HTMLElement): void {\n const { managersByElement } = ResizeManager;\n const owner = managersByElement.get(element);\n // Already registered\n if (owner === this) {\n return;\n }\n // If we've already somehow registered with another manager, we in for a\n // world of pain, so complain loudly\n else if (owner != null && owner !== this) {\n throw new Error(\n 'ResizeManager.observe: element is already owned by another ResizeManager'\n );\n }\n managersByElement.set(element, this);\n ResizeManager.getResizeObserver().observe(element);\n }\n\n private unobserve(element: HTMLElement): void {\n const { managersByElement, resizeObserver } = ResizeManager;\n const owner = managersByElement.get(element);\n if (owner == null) {\n return;\n } else if (owner !== this) {\n throw new Error(\n 'ResizeManager.unobserve: element is owned by another ResizeManager'\n );\n }\n\n managersByElement.delete(element);\n resizeObserver?.unobserve(element);\n if (resizeObserver != null && managersByElement.size === 0) {\n resizeObserver.disconnect();\n ResizeManager.resizeObserver = undefined;\n }\n }\n\n private handleResizeEntries(entries: ResizeObserverEntry[]) {\n const codeUpdates: CodeUpdateMap = new Map();\n const annotationUpdates: Set<ObservedAnnotationNodes> = new Set();\n for (const entry of entries) {\n const { target, borderBoxSize, contentBoxSize } = entry;\n if (!(target instanceof HTMLElement)) {\n console.error(\n 'ResizeManager.handleResizeEntries: Invalid element for ResizeObserver',\n entry\n );\n continue;\n }\n const item = this.observedNodes.get(target);\n if (item == null) {\n console.error(\n 'ResizeManager.handleResizeEntries: Not a valid observed node',\n entry\n );\n continue;\n }\n if (item.type === 'annotations') {\n const column = (() => {\n if (target === item.column1.child) {\n return item.column1;\n }\n if (target === item.column2.child) {\n return item.column2;\n }\n return undefined;\n })();\n\n if (column == null) {\n console.error(\n `ResizeManager.handleResizeEntries: Couldn't find a column for`,\n { item, target }\n );\n continue;\n }\n\n column.childHeight = borderBoxSize[0].blockSize;\n annotationUpdates.add(item);\n } else if (item.type === 'code') {\n const update = codeUpdates.get(item) ?? {};\n const inlineSize = contentBoxSize[0].inlineSize;\n if (target === item.codeElement) {\n update.codeInlineSize = inlineSize;\n } else if (target === item.numberElement) {\n update.numberInlineSize = inlineSize;\n }\n codeUpdates.set(item, update);\n }\n }\n this.applyAnnotationUpdates(annotationUpdates);\n annotationUpdates.clear();\n this.applyColumnUpdates(codeUpdates);\n codeUpdates.clear();\n }\n\n private applyAnnotationUpdates(\n annotationUpdates: Set<ObservedAnnotationNodes>\n ) {\n for (const item of annotationUpdates) {\n this.applyNewHeight(\n item,\n Math.max(item.column1.childHeight, item.column2.childHeight)\n );\n }\n }\n\n private applyColumnUpdates = (queuedUpdates: CodeUpdateMap) => {\n for (const [item, update] of queuedUpdates) {\n const nextCodeWidth =\n update.codeInlineSize != null\n ? resolveCodeWidth(update.codeInlineSize)\n : item.codeWidth;\n const nextNumberWidth =\n update.numberInlineSize != null\n ? resolveNumberWidth(update.numberInlineSize)\n : item.numberWidth;\n const codeWidthChanged = nextCodeWidth !== item.codeWidth;\n const numberWidthChanged = nextNumberWidth !== item.numberWidth;\n\n if (!codeWidthChanged && !numberWidthChanged) {\n continue;\n }\n\n item.codeWidth = nextCodeWidth;\n item.numberWidth = nextNumberWidth;\n\n if (codeWidthChanged) {\n item.codeElement.style.setProperty(\n '--diffs-column-width',\n `${typeof nextCodeWidth === 'number' ? `${nextCodeWidth}px` : 'auto'}`\n );\n }\n\n if (numberWidthChanged) {\n item.codeElement.style.setProperty(\n '--diffs-column-number-width',\n `${nextNumberWidth === 0 ? 'auto' : `${nextNumberWidth}px`}`\n );\n }\n\n if (\n codeWidthChanged ||\n (numberWidthChanged && nextCodeWidth !== 'auto')\n ) {\n const targetWidth =\n typeof nextCodeWidth === 'number'\n ? Math.max(nextCodeWidth - nextNumberWidth, 0)\n : 0;\n item.codeElement.style.setProperty(\n '--diffs-column-content-width',\n `${targetWidth > 0 ? `${targetWidth}px` : 'auto'}`\n );\n }\n }\n };\n\n private applyNewHeight(item: ObservedAnnotationNodes, newHeight: number) {\n if (newHeight !== item.currentHeight) {\n item.currentHeight = Math.max(newHeight, 0);\n item.column1.container.style.setProperty(\n '--diffs-annotation-min-height',\n `${item.currentHeight}px`\n );\n item.column2.container.style.setProperty(\n '--diffs-annotation-min-height',\n `${item.currentHeight}px`\n );\n }\n }\n}\n\nfunction resolveCodeWidth(inlineSize: number): number | 'auto' {\n const width = Math.max(Math.floor(inlineSize), 0);\n return width === 0 ? 'auto' : width;\n}\n\nfunction resolveNumberWidth(inlineSize: number): number {\n return Math.max(Math.ceil(inlineSize), 0);\n}\n\nfunction cleanupStaleCodeItem(item: ObservedGridNodes): void {\n if (item.codeElement.isConnected) {\n item.codeElement.style.removeProperty('--diffs-column-content-width');\n item.codeElement.style.removeProperty('--diffs-column-number-width');\n item.codeElement.style.removeProperty('--diffs-column-width');\n }\n}\n\nfunction cleanupStaleAnnotationItem(item: ObservedAnnotationNodes): void {\n if (item.column1.container.isConnected) {\n item.column1.container.style.removeProperty(\n '--diffs-annotation-min-height'\n );\n }\n if (item.column2.container.isConnected) {\n item.column2.container.style.removeProperty(\n '--diffs-annotation-min-height'\n );\n }\n}\n"],"mappings":";AAiBA,IAAa,gBAAb,MAAa,cAAc;CAEzB,OAAe;CACf,OAAe,oCAAoB,IAAI,IAA4B;CAEnE,OAAe,oBAAoC;EACjD,MAAM,iBACJ,cAAc,kBACd,IAAI,eAAe,cAAc,yBAAyB;EAC5D,cAAc,iBAAiB;EAC/B,OAAO;CACT;CAEA,OAAe,0BAA0B,SAAgC;EAGvE,MAAM,mCAAmB,IAAI,IAA0C;EACvE,KAAK,MAAM,SAAS,SAAS;GAC3B,MAAM,UAAU,cAAc,kBAAkB,IAAI,MAAM,MAAM;GAChE,IAAI,WAAW,MACb;GAEF,MAAM,iBAAiB,iBAAiB,IAAI,OAAO;GACnD,IAAI,kBAAkB,MACpB,iBAAiB,IAAI,SAAS,CAAC,KAAK,CAAC;QAErC,eAAe,KAAK,KAAK;EAE7B;EAEA,KAAK,MAAM,CAAC,SAAS,mBAAmB,kBACtC,QAAQ,oBAAoB,cAAc;CAE9C;CAEA,gCAAwB,IAAI,IAG1B;CAEF,MAAM,KAAqB,oBAAmC;EAC5D,MAAM,oCAAoB,IAAI,IAAqB;EACnD,IAAI,cAAc;EAClB,MAAM,gBAAgB,IAAI,IAAI,KAAK,aAAa;EAChD,KAAK,cAAc,MAAM;EAEzB,KAAK,MAAM,WAAW,IAAI,UAAU;GAClC,IAAI,gBAAgB,GAClB;GAEF,MAAM,qBAA8C;IAClD,IAAI,mBAAmB,eAAe,QAAQ,YAAY,QACxD,OAAO;GAGX,EAAA,CAAG;GACH,IAAI,eAAe,MACjB;GAEF;GACA,IAAI,OACF,cAAc,IAAI,WAAW;GAC/B,IAAI,QAAQ,QAAQ,KAAK,SAAS,QAChC,MAAM,IAAI,MACR,gGACF;GAGF,IAAI,gBAAgB,YAAY;GAChC,IAAI,EAAE,yBAAyB,cAC7B,gBAAgB;GAElB,IAAI,QAAQ,MAAM;IAChB,KAAK,cAAc,IAAI,aAAa,IAAI;IACxC,cAAc,OAAO,WAAW;IAChC,IAAI,KAAK,kBAAkB,eAAe;KACxC,IAAI,KAAK,iBAAiB,MAAM;MAC9B,KAAK,UAAU,KAAK,aAAa;MACjC,cAAc,OAAO,KAAK,aAAa;KACzC;KACA,IAAI,iBAAiB,MAAM;MACzB,KAAK,QAAQ,aAAa;MAC1B,cAAc,OAAO,aAAa;MAClC,KAAK,cAAc,IAAI,eAAe,IAAI;KAC5C;KACA,KAAK,gBAAgB;KACrB,KAAK,cAAc;IACrB,OAAO,IAAI,KAAK,iBAAiB,MAAM;KACrC,cAAc,OAAO,KAAK,aAAa;KACvC,KAAK,cAAc,IAAI,KAAK,eAAe,IAAI;IAEjD,OACE,KAAK,cAAc;GAEvB,OAAO;IACL,OAAO;KACL,MAAM;KACN;KACA;KACA,WAAW;KACX,aAAa;IACf;IACA,KAAK,cAAc,IAAI,aAAa,IAAI;IACxC,KAAK,QAAQ,WAAW;IACxB,IAAI,iBAAiB,MAAM;KACzB,KAAK,cAAc,IAAI,eAAe,IAAI;KAC1C,KAAK,QAAQ,aAAa;IAC5B;GACF;EACF;EAEA,IAAI,cAAc,KAAK,CAAC,oBAAoB;GAC1C,MAAM,qBAAqB,IAAI,iBAC7B,+BACF;GAEA,MAAM,6BAAa,IAAI,IAA2B;GAGlD,KAAK,MAAM,WAAW,oBAAoB;IACxC,IAAI,EAAE,mBAAmB,cACvB;IAEF,MAAM,iBACJ,QAAQ,aAAa,sBAAsB,KAAK;IAClD,IAAI,CAAC,gBAAgB,KAAK,cAAc,GAAG;KACzC,QAAQ,MACN,uEACA;MAAE;MAAgB;KAAQ,CAC5B;KACA;IACF;IACA,IAAI,QAAQ,WAAW,IAAI,cAAc;IACzC,IAAI,SAAS,MAAM;KACjB,QAAQ,CAAC;KACT,WAAW,IAAI,gBAAgB,KAAK;IACtC;IACA,MAAM,KAAK,OAAO;GACpB;GAEA,KAAK,MAAM,CAAC,KAAK,SAAS,YAAY;IACpC,IAAI,KAAK,WAAW,GAAG;KACrB,QAAQ,MACN,kDACA,KACA,IACF;KACA;IACF;IACA,MAAM,CAAC,YAAY,cAAc;IACjC,MAAM,SAAS,WAAW;IAC1B,MAAM,SAAS,WAAW;IAC1B,IACE,EAAE,sBAAsB,gBACxB,EAAE,sBAAsB,gBACxB,EAAE,kBAAkB,gBACpB,EAAE,kBAAkB,cAEpB;IAGF,IAAI,OAAO,cAAc,IAAI,MAAM;IAEnC,IAAI,QAAQ,MAAM;KAChB,KAAK,cAAc,IAAI,QAAQ,IAAI;KACnC,KAAK,cAAc,IAAI,QAAQ,IAAI;KACnC,cAAc,OAAO,MAAM;KAC3B,cAAc,OAAO,MAAM;KAC3B;IACF;IAEA,MAAM,eAAe,OAAO,sBAAsB,CAAC,CAAC;IACpD,MAAM,eAAe,OAAO,sBAAsB,CAAC,CAAC;IACpD,OAAO;KACL,MAAM;KACN,SAAS;MACP,WAAW;MACX,OAAO;MACP,aAAa;KACf;KACA,SAAS;MACP,WAAW;MACX,OAAO;MACP,aAAa;KACf;KACA,eAAe;IACjB;IACA,kBAAkB,IAAI;KACpB;KACA;KACA;KACA,WAAW,KAAK,IAAI,cAAc,YAAY;IAChD,CAAC;GACH;GAKA,KAAK,MAAM,iBAAiB,mBAAmB;IAC7C,KAAK,eAAe,cAAc,MAAM,cAAc,SAAS;IAC/D,KAAK,cAAc,IAAI,cAAc,QAAQ,cAAc,IAAI;IAC/D,KAAK,cAAc,IAAI,cAAc,QAAQ,cAAc,IAAI;IAC/D,KAAK,QAAQ,cAAc,MAAM;IACjC,KAAK,QAAQ,cAAc,MAAM;GACnC;GACA,kBAAkB,MAAM;EAC1B;EAGA,KAAK,MAAM,CAAC,SAAS,SAAS,eAAe;GAC3C,KAAK,UAAU,OAAO;GACtB,IAAI,KAAK,SAAS,QAChB,qBAAqB,IAAI;QAEzB,2BAA2B,IAAI;EAEnC;EACA,cAAc,MAAM;CACtB;CAEA,UAAgB;EACd,KAAK,MAAM,WAAW,KAAK,cAAc,KAAK,GAC5C,KAAK,UAAU,OAAO;EAExB,KAAK,cAAc,MAAM;CAC3B;CAEA,QAAgB,SAA4B;EAC1C,MAAM,EAAE,sBAAsB;EAC9B,MAAM,QAAQ,kBAAkB,IAAI,OAAO;EAE3C,IAAI,UAAU,MACZ;OAIG,IAAI,SAAS,QAAQ,UAAU,MAClC,MAAM,IAAI,MACR,0EACF;EAEF,kBAAkB,IAAI,SAAS,IAAI;EACnC,cAAc,kBAAkB,CAAC,CAAC,QAAQ,OAAO;CACnD;CAEA,UAAkB,SAA4B;EAC5C,MAAM,EAAE,mBAAmB,mBAAmB;EAC9C,MAAM,QAAQ,kBAAkB,IAAI,OAAO;EAC3C,IAAI,SAAS,MACX;OACK,IAAI,UAAU,MACnB,MAAM,IAAI,MACR,oEACF;EAGF,kBAAkB,OAAO,OAAO;EAChC,gBAAgB,UAAU,OAAO;EACjC,IAAI,kBAAkB,QAAQ,kBAAkB,SAAS,GAAG;GAC1D,eAAe,WAAW;GAC1B,cAAc,iBAAiB,KAAA;EACjC;CACF;CAEA,oBAA4B,SAAgC;EAC1D,MAAM,8BAA6B,IAAI,IAAI;EAC3C,MAAM,oCAAkD,IAAI,IAAI;EAChE,KAAK,MAAM,SAAS,SAAS;GAC3B,MAAM,EAAE,QAAQ,eAAe,mBAAmB;GAClD,IAAI,EAAE,kBAAkB,cAAc;IACpC,QAAQ,MACN,yEACA,KACF;IACA;GACF;GACA,MAAM,OAAO,KAAK,cAAc,IAAI,MAAM;GAC1C,IAAI,QAAQ,MAAM;IAChB,QAAQ,MACN,gEACA,KACF;IACA;GACF;GACA,IAAI,KAAK,SAAS,eAAe;IAC/B,MAAM,gBAAgB;KACpB,IAAI,WAAW,KAAK,QAAQ,OAC1B,OAAO,KAAK;KAEd,IAAI,WAAW,KAAK,QAAQ,OAC1B,OAAO,KAAK;IAGhB,EAAA,CAAG;IAEH,IAAI,UAAU,MAAM;KAClB,QAAQ,MACN,iEACA;MAAE;MAAM;KAAO,CACjB;KACA;IACF;IAEA,OAAO,cAAc,cAAc,EAAE,CAAC;IACtC,kBAAkB,IAAI,IAAI;GAC5B,OAAO,IAAI,KAAK,SAAS,QAAQ;IAC/B,MAAM,SAAS,YAAY,IAAI,IAAI,KAAK,CAAC;IACzC,MAAM,aAAa,eAAe,EAAE,CAAC;IACrC,IAAI,WAAW,KAAK,aAClB,OAAO,iBAAiB;SACnB,IAAI,WAAW,KAAK,eACzB,OAAO,mBAAmB;IAE5B,YAAY,IAAI,MAAM,MAAM;GAC9B;EACF;EACA,KAAK,uBAAuB,iBAAiB;EAC7C,kBAAkB,MAAM;EACxB,KAAK,mBAAmB,WAAW;EACnC,YAAY,MAAM;CACpB;CAEA,uBACE,mBACA;EACA,KAAK,MAAM,QAAQ,mBACjB,KAAK,eACH,MACA,KAAK,IAAI,KAAK,QAAQ,aAAa,KAAK,QAAQ,WAAW,CAC7D;CAEJ;CAEA,sBAA8B,kBAAiC;EAC7D,KAAK,MAAM,CAAC,MAAM,WAAW,eAAe;GAC1C,MAAM,gBACJ,OAAO,kBAAkB,OACrB,iBAAiB,OAAO,cAAc,IACtC,KAAK;GACX,MAAM,kBACJ,OAAO,oBAAoB,OACvB,mBAAmB,OAAO,gBAAgB,IAC1C,KAAK;GACX,MAAM,mBAAmB,kBAAkB,KAAK;GAChD,MAAM,qBAAqB,oBAAoB,KAAK;GAEpD,IAAI,CAAC,oBAAoB,CAAC,oBACxB;GAGF,KAAK,YAAY;GACjB,KAAK,cAAc;GAEnB,IAAI,kBACF,KAAK,YAAY,MAAM,YACrB,wBACA,GAAG,OAAO,kBAAkB,WAAW,GAAG,cAAc,MAAM,QAChE;GAGF,IAAI,oBACF,KAAK,YAAY,MAAM,YACrB,+BACA,GAAG,oBAAoB,IAAI,SAAS,GAAG,gBAAgB,KACzD;GAGF,IACE,oBACC,sBAAsB,kBAAkB,QACzC;IACA,MAAM,cACJ,OAAO,kBAAkB,WACrB,KAAK,IAAI,gBAAgB,iBAAiB,CAAC,IAC3C;IACN,KAAK,YAAY,MAAM,YACrB,gCACA,GAAG,cAAc,IAAI,GAAG,YAAY,MAAM,QAC5C;GACF;EACF;CACF;CAEA,eAAuB,MAA+B,WAAmB;EACvE,IAAI,cAAc,KAAK,eAAe;GACpC,KAAK,gBAAgB,KAAK,IAAI,WAAW,CAAC;GAC1C,KAAK,QAAQ,UAAU,MAAM,YAC3B,iCACA,GAAG,KAAK,cAAc,GACxB;GACA,KAAK,QAAQ,UAAU,MAAM,YAC3B,iCACA,GAAG,KAAK,cAAc,GACxB;EACF;CACF;AACF;AAEA,SAAS,iBAAiB,YAAqC;CAC7D,MAAM,QAAQ,KAAK,IAAI,KAAK,MAAM,UAAU,GAAG,CAAC;CAChD,OAAO,UAAU,IAAI,SAAS;AAChC;AAEA,SAAS,mBAAmB,YAA4B;CACtD,OAAO,KAAK,IAAI,KAAK,KAAK,UAAU,GAAG,CAAC;AAC1C;AAEA,SAAS,qBAAqB,MAA+B;CAC3D,IAAI,KAAK,YAAY,aAAa;EAChC,KAAK,YAAY,MAAM,eAAe,8BAA8B;EACpE,KAAK,YAAY,MAAM,eAAe,6BAA6B;EACnE,KAAK,YAAY,MAAM,eAAe,sBAAsB;CAC9D;AACF;AAEA,SAAS,2BAA2B,MAAqC;CACvE,IAAI,KAAK,QAAQ,UAAU,aACzB,KAAK,QAAQ,UAAU,MAAM,eAC3B,+BACF;CAEF,IAAI,KAAK,QAAQ,UAAU,aACzB,KAAK,QAAQ,UAAU,MAAM,eAC3B,+BACF;AAEJ"}
|
|
1
|
+
{"version":3,"file":"ResizeManager.js","names":[],"sources":["../../src/managers/ResizeManager.ts"],"sourcesContent":["import type { ObservedAnnotationNodes, ObservedGridNodes } from '../types';\n\ninterface CodeColumnUpdate {\n codeInlineSize?: number;\n numberInlineSize?: number;\n measuredNumberInlineSize?: number;\n}\n\ninterface CodeColumnVariableChanges {\n codeWidthChanged: boolean;\n numberWidthChanged: boolean;\n}\n\ntype CodeUpdateMap = Map<ObservedGridNodes, CodeColumnUpdate>;\n\nexport type ResizeManagerColumnVariableMode = 'apply' | 'measure';\n\nexport interface ResizeManagerSetupOptions {\n disableAnnotations: boolean;\n columnVariables?: ResizeManagerColumnVariableMode;\n}\n\ninterface AnnotationSetup {\n child1: HTMLElement;\n child2: HTMLElement;\n item: ObservedAnnotationNodes;\n newHeight: number;\n}\n\nexport class ResizeManager {\n // Shared static resizeObserver that all ResizeManagers use\n private static resizeObserver: ResizeObserver | undefined;\n private static managersByElement = new Map<Element, ResizeManager>();\n\n private static getResizeObserver(): ResizeObserver {\n const resizeObserver =\n ResizeManager.resizeObserver ??\n new ResizeObserver(ResizeManager.handleSharedResizeEntries);\n ResizeManager.resizeObserver = resizeObserver;\n return resizeObserver;\n }\n\n private static handleSharedResizeEntries(entries: ResizeObserverEntry[]) {\n // First we need to batch all elements by manager, so callbacks are\n // properly aligned with a per-instance ResizeManager\n const entriesByManager = new Map<ResizeManager, ResizeObserverEntry[]>();\n for (const entry of entries) {\n const manager = ResizeManager.managersByElement.get(entry.target);\n if (manager == null) {\n continue;\n }\n const managerEntries = entriesByManager.get(manager);\n if (managerEntries == null) {\n entriesByManager.set(manager, [entry]);\n } else {\n managerEntries.push(entry);\n }\n }\n\n for (const [manager, managerEntries] of entriesByManager) {\n manager.handleResizeEntries(managerEntries);\n }\n }\n\n private observedNodes = new Map<\n HTMLElement,\n ObservedAnnotationNodes | ObservedGridNodes\n >();\n\n setup(\n pre: HTMLPreElement,\n { disableAnnotations, columnVariables = 'apply' }: ResizeManagerSetupOptions\n ): void {\n const annotationUpdates = new Set<AnnotationSetup>();\n const applyColumnVariables = columnVariables === 'apply';\n let columnCount = 0;\n const observedNodes = new Map(this.observedNodes);\n this.observedNodes.clear();\n\n for (const element of pre.children) {\n if (columnCount === 2) {\n break;\n }\n const codeElement: HTMLElement | undefined = (() => {\n if (element instanceof HTMLElement && element.tagName === 'CODE') {\n return element;\n }\n return undefined;\n })();\n if (codeElement == null) {\n continue;\n }\n columnCount++;\n let item: ObservedGridNodes | ObservedAnnotationNodes | undefined =\n observedNodes.get(codeElement);\n if (item != null && item.type !== 'code') {\n throw new Error(\n 'ResizeManager.setup: somehow a code node is being used for an annotation, should be impossible'\n );\n }\n\n let numberElement = codeElement.firstElementChild;\n if (!(numberElement instanceof HTMLElement)) {\n numberElement = null;\n }\n if (item != null) {\n this.observedNodes.set(codeElement, item);\n observedNodes.delete(codeElement);\n if (item.numberElement !== numberElement) {\n if (item.numberElement != null) {\n this.unobserve(item.numberElement);\n observedNodes.delete(item.numberElement);\n }\n if (numberElement != null) {\n this.observe(numberElement);\n observedNodes.delete(numberElement);\n this.observedNodes.set(numberElement, item);\n }\n item.numberElement = numberElement;\n item.numberWidth = 0;\n } else if (item.numberElement != null) {\n observedNodes.delete(item.numberElement);\n this.observedNodes.set(item.numberElement, item);\n // If there is a resize, let the resize handler handle it...\n } else {\n item.numberWidth = 0;\n }\n syncColumnVariableMode(item, applyColumnVariables);\n } else {\n item = {\n type: 'code',\n codeElement,\n numberElement,\n codeWidth: 'auto',\n numberWidth: 0,\n applyColumnVariables,\n };\n this.observedNodes.set(codeElement, item);\n this.observe(codeElement);\n if (numberElement != null) {\n this.observedNodes.set(numberElement, item);\n this.observe(numberElement);\n }\n }\n }\n\n if (columnCount > 1 && !disableAnnotations) {\n const annotationElements = pre.querySelectorAll(\n '[data-line-annotation*=\",\"]'\n );\n\n const elementMap = new Map<string, HTMLElement[]>();\n // Iterate through all the matched elements and organize them into pairs\n // based on the data-line-annotation attribute\n for (const element of annotationElements) {\n if (!(element instanceof HTMLElement)) {\n continue;\n }\n const lineAnnotation =\n element.getAttribute('data-line-annotation') ?? '';\n if (!/^-?\\d+,-?\\d+$/.test(lineAnnotation)) {\n console.error(\n 'DiffFileRenderer.setupResizeObserver: Invalid element or annotation',\n { lineAnnotation, element }\n );\n continue;\n }\n let pairs = elementMap.get(lineAnnotation);\n if (pairs == null) {\n pairs = [];\n elementMap.set(lineAnnotation, pairs);\n }\n pairs.push(element);\n }\n\n for (const [key, pair] of elementMap) {\n if (pair.length !== 2) {\n console.error(\n 'DiffFileRenderer.setupResizeObserver: Bad Pair',\n key,\n pair\n );\n continue;\n }\n const [container1, container2] = pair;\n const child1 = container1.firstElementChild;\n const child2 = container2.firstElementChild;\n if (\n !(container1 instanceof HTMLElement) ||\n !(container2 instanceof HTMLElement) ||\n !(child1 instanceof HTMLElement) ||\n !(child2 instanceof HTMLElement)\n ) {\n continue;\n }\n\n let item = observedNodes.get(child1);\n\n if (item != null) {\n this.observedNodes.set(child1, item);\n this.observedNodes.set(child2, item);\n observedNodes.delete(child1);\n observedNodes.delete(child2);\n continue;\n }\n\n const child1Height = child1.getBoundingClientRect().height;\n const child2Height = child2.getBoundingClientRect().height;\n item = {\n type: 'annotations',\n column1: {\n container: container1,\n child: child1,\n childHeight: child1Height,\n },\n column2: {\n container: container2,\n child: child2,\n childHeight: child2Height,\n },\n currentHeight: 'auto',\n };\n annotationUpdates.add({\n child1,\n child2,\n item,\n newHeight: Math.max(child1Height, child2Height),\n });\n }\n\n // Measure all annotation heights first, then apply the paired min-height\n // styles after the read phase so setup does not bounce between layout\n // reads and writes for every annotation pair.\n for (const pendingUpdate of annotationUpdates) {\n this.applyNewHeight(pendingUpdate.item, pendingUpdate.newHeight);\n this.observedNodes.set(pendingUpdate.child1, pendingUpdate.item);\n this.observedNodes.set(pendingUpdate.child2, pendingUpdate.item);\n this.observe(pendingUpdate.child1);\n this.observe(pendingUpdate.child2);\n }\n annotationUpdates.clear();\n }\n\n // Cleanup any old nodes that might still be observed\n for (const [element, item] of observedNodes) {\n this.unobserve(element);\n if (item.type === 'code') {\n cleanupStaleCodeItem(item);\n } else {\n cleanupStaleAnnotationItem(item);\n }\n }\n observedNodes.clear();\n }\n\n cleanUp(): void {\n for (const element of this.observedNodes.keys()) {\n this.unobserve(element);\n }\n this.observedNodes.clear();\n }\n\n private observe(element: HTMLElement): void {\n const { managersByElement } = ResizeManager;\n const owner = managersByElement.get(element);\n // Already registered\n if (owner === this) {\n return;\n }\n // If we've already somehow registered with another manager, we in for a\n // world of pain, so complain loudly\n else if (owner != null && owner !== this) {\n throw new Error(\n 'ResizeManager.observe: element is already owned by another ResizeManager'\n );\n }\n managersByElement.set(element, this);\n ResizeManager.getResizeObserver().observe(element);\n }\n\n private unobserve(element: HTMLElement): void {\n const { managersByElement, resizeObserver } = ResizeManager;\n const owner = managersByElement.get(element);\n if (owner == null) {\n return;\n } else if (owner !== this) {\n throw new Error(\n 'ResizeManager.unobserve: element is owned by another ResizeManager'\n );\n }\n\n managersByElement.delete(element);\n resizeObserver?.unobserve(element);\n if (resizeObserver != null && managersByElement.size === 0) {\n resizeObserver.disconnect();\n ResizeManager.resizeObserver = undefined;\n }\n }\n\n private handleResizeEntries(entries: ResizeObserverEntry[]) {\n const codeUpdates: CodeUpdateMap = new Map();\n const annotationUpdates: Set<ObservedAnnotationNodes> = new Set();\n for (const entry of entries) {\n const { target, borderBoxSize, contentBoxSize } = entry;\n if (!(target instanceof HTMLElement)) {\n console.error(\n 'ResizeManager.handleResizeEntries: Invalid element for ResizeObserver',\n entry\n );\n continue;\n }\n const item = this.observedNodes.get(target);\n if (item == null) {\n console.error(\n 'ResizeManager.handleResizeEntries: Not a valid observed node',\n entry\n );\n continue;\n }\n if (item.type === 'annotations') {\n const column = (() => {\n if (target === item.column1.child) {\n return item.column1;\n }\n if (target === item.column2.child) {\n return item.column2;\n }\n return undefined;\n })();\n\n if (column == null) {\n console.error(\n `ResizeManager.handleResizeEntries: Couldn't find a column for`,\n { item, target }\n );\n continue;\n }\n\n column.childHeight = borderBoxSize[0].blockSize;\n annotationUpdates.add(item);\n } else if (item.type === 'code') {\n const update = codeUpdates.get(item) ?? {};\n const inlineSize = contentBoxSize[0].inlineSize;\n if (target === item.codeElement) {\n update.codeInlineSize = inlineSize;\n } else if (target === item.numberElement) {\n update.numberInlineSize = inlineSize;\n }\n codeUpdates.set(item, update);\n }\n }\n this.applyAnnotationUpdates(annotationUpdates);\n annotationUpdates.clear();\n this.applyColumnUpdates(codeUpdates);\n codeUpdates.clear();\n }\n\n private applyAnnotationUpdates(\n annotationUpdates: Set<ObservedAnnotationNodes>\n ) {\n for (const item of annotationUpdates) {\n this.applyNewHeight(\n item,\n Math.max(item.column1.childHeight, item.column2.childHeight)\n );\n }\n }\n\n private applyColumnUpdates = (queuedUpdates: CodeUpdateMap) => {\n for (const [item, update] of queuedUpdates) {\n const nextCodeWidth =\n update.codeInlineSize != null\n ? resolveCodeWidth(update.codeInlineSize)\n : item.codeWidth;\n const nextNumberWidth =\n update.numberInlineSize != null\n ? resolveNumberWidth(update.numberInlineSize)\n : item.numberWidth;\n const codeWidthChanged = nextCodeWidth !== item.codeWidth;\n const numberWidthChanged = nextNumberWidth !== item.numberWidth;\n\n if (!codeWidthChanged && !numberWidthChanged) {\n continue;\n }\n\n item.codeWidth = nextCodeWidth;\n item.numberWidth = nextNumberWidth;\n\n if (item.applyColumnVariables) {\n applyCodeColumnVariables(item, {\n codeWidthChanged,\n numberWidthChanged,\n });\n }\n }\n };\n\n private applyNewHeight(item: ObservedAnnotationNodes, newHeight: number) {\n if (newHeight !== item.currentHeight) {\n item.currentHeight = Math.max(newHeight, 0);\n item.column1.container.style.setProperty(\n '--diffs-annotation-min-height',\n `${item.currentHeight}px`\n );\n item.column2.container.style.setProperty(\n '--diffs-annotation-min-height',\n `${item.currentHeight}px`\n );\n }\n }\n}\n\nfunction resolveCodeWidth(inlineSize: number): number | 'auto' {\n const width = Math.max(Math.floor(inlineSize), 0);\n return width === 0 ? 'auto' : width;\n}\n\nfunction resolveNumberWidth(inlineSize: number): number {\n return Math.max(Math.ceil(inlineSize), 0);\n}\n\nfunction syncColumnVariableMode(\n item: ObservedGridNodes,\n applyColumnVariables: boolean\n): void {\n if (item.applyColumnVariables === applyColumnVariables) {\n return;\n }\n\n item.applyColumnVariables = applyColumnVariables;\n if (applyColumnVariables) {\n applyCodeColumnVariables(item, {\n codeWidthChanged: true,\n numberWidthChanged: true,\n });\n } else {\n removeCodeColumnVariables(item);\n }\n}\n\nfunction applyCodeColumnVariables(\n item: ObservedGridNodes,\n { codeWidthChanged, numberWidthChanged }: CodeColumnVariableChanges\n): void {\n const { codeElement, codeWidth, numberWidth } = item;\n if (codeWidthChanged) {\n codeElement.style.setProperty(\n '--diffs-column-width',\n `${typeof codeWidth === 'number' ? `${codeWidth}px` : 'auto'}`\n );\n }\n\n if (numberWidthChanged) {\n codeElement.style.setProperty(\n '--diffs-column-number-width',\n `${numberWidth === 0 ? 'auto' : `${numberWidth}px`}`\n );\n }\n\n if (codeWidthChanged || (numberWidthChanged && codeWidth !== 'auto')) {\n const targetWidth =\n typeof codeWidth === 'number' ? Math.max(codeWidth - numberWidth, 0) : 0;\n codeElement.style.setProperty(\n '--diffs-column-content-width',\n `${targetWidth > 0 ? `${targetWidth}px` : 'auto'}`\n );\n }\n}\n\nfunction removeCodeColumnVariables(item: ObservedGridNodes): void {\n item.codeElement.style.removeProperty('--diffs-column-content-width');\n item.codeElement.style.removeProperty('--diffs-column-number-width');\n item.codeElement.style.removeProperty('--diffs-column-width');\n}\n\nfunction cleanupStaleCodeItem(item: ObservedGridNodes): void {\n if (item.codeElement.isConnected) {\n removeCodeColumnVariables(item);\n }\n}\n\nfunction cleanupStaleAnnotationItem(item: ObservedAnnotationNodes): void {\n if (item.column1.container.isConnected) {\n item.column1.container.style.removeProperty(\n '--diffs-annotation-min-height'\n );\n }\n if (item.column2.container.isConnected) {\n item.column2.container.style.removeProperty(\n '--diffs-annotation-min-height'\n );\n }\n}\n"],"mappings":"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"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
type Callback = (time: number) => unknown;
|
|
3
3
|
declare function queueRender(callback: Callback): void;
|
|
4
4
|
declare function dequeueRender(callback: Callback): void;
|
|
5
|
+
declare function clearRenderQueue(): void;
|
|
5
6
|
//#endregion
|
|
6
|
-
export { dequeueRender, queueRender };
|
|
7
|
+
export { clearRenderQueue, dequeueRender, queueRender };
|
|
7
8
|
//# sourceMappingURL=UniversalRenderingManager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UniversalRenderingManager.d.ts","names":[],"sources":["../../src/managers/UniversalRenderingManager.ts"],"mappings":";KAAK,QAAA,IAAY,IAAY;AAAA,iBAMb,WAAA,CAAY,QAAkB,EAAR,QAAQ;AAAA,iBAK9B,aAAA,CAAc,QAAkB,EAAR,QAAQ"}
|
|
1
|
+
{"version":3,"file":"UniversalRenderingManager.d.ts","names":[],"sources":["../../src/managers/UniversalRenderingManager.ts"],"mappings":";KAAK,QAAA,IAAY,IAAY;AAAA,iBAMb,WAAA,CAAY,QAAkB,EAAR,QAAQ;AAAA,iBAK9B,aAAA,CAAc,QAAkB,EAAR,QAAQ;AAAA,iBAWhC,gBAAA"}
|
|
@@ -12,6 +12,11 @@ function dequeueRender(callback) {
|
|
|
12
12
|
frameId = null;
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
|
+
function clearRenderQueue() {
|
|
16
|
+
callbacks.clear();
|
|
17
|
+
if (frameId != null && typeof cancelAnimationFrame === "function") cancelAnimationFrame(frameId);
|
|
18
|
+
frameId = null;
|
|
19
|
+
}
|
|
15
20
|
function render(time) {
|
|
16
21
|
const toIterate = new Set(callbacks);
|
|
17
22
|
callbacks.clear();
|
|
@@ -24,6 +29,6 @@ function render(time) {
|
|
|
24
29
|
else frameId = null;
|
|
25
30
|
}
|
|
26
31
|
//#endregion
|
|
27
|
-
export { dequeueRender, queueRender };
|
|
32
|
+
export { clearRenderQueue, dequeueRender, queueRender };
|
|
28
33
|
|
|
29
34
|
//# sourceMappingURL=UniversalRenderingManager.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UniversalRenderingManager.js","names":[],"sources":["../../src/managers/UniversalRenderingManager.ts"],"sourcesContent":["type Callback = (time: number) => unknown;\n\nconst callbacks = new Set<Callback>();\nlet frameId: null | number = null;\n\n// TODO(amadeus): Figure out a proper name for this module...\nexport function queueRender(callback: Callback): void {\n callbacks.add(callback);\n frameId ??= requestAnimationFrame(render);\n}\n\nexport function dequeueRender(callback: Callback): void {\n callbacks.delete(callback);\n if (callbacks.size === 0 && frameId != null) {\n cancelAnimationFrame(frameId);\n frameId = null;\n }\n}\n\nfunction render(time: number): void {\n const toIterate = new Set(callbacks);\n callbacks.clear();\n for (const callback of toIterate) {\n try {\n callback(time);\n } catch (error) {\n console.error(error);\n }\n }\n // If render picked up any new callbacks, lets trigger a new\n // requestAnimationFrame\n if (callbacks.size > 0) {\n frameId = requestAnimationFrame(render);\n } else {\n frameId = null;\n }\n}\n"],"mappings":";AAEA,MAAM,4BAAY,IAAI,IAAc;AACpC,IAAI,UAAyB;AAG7B,SAAgB,YAAY,UAA0B;CACpD,UAAU,IAAI,QAAQ;CACtB,YAAY,sBAAsB,MAAM;AAC1C;AAEA,SAAgB,cAAc,UAA0B;CACtD,UAAU,OAAO,QAAQ;CACzB,IAAI,UAAU,SAAS,KAAK,WAAW,MAAM;EAC3C,qBAAqB,OAAO;EAC5B,UAAU;CACZ;AACF;AAEA,SAAS,OAAO,MAAoB;CAClC,MAAM,YAAY,IAAI,IAAI,SAAS;CACnC,UAAU,MAAM;CAChB,KAAK,MAAM,YAAY,WACrB,IAAI;EACF,SAAS,IAAI;CACf,SAAS,OAAO;EACd,QAAQ,MAAM,KAAK;CACrB;CAIF,IAAI,UAAU,OAAO,GACnB,UAAU,sBAAsB,MAAM;MAEtC,UAAU;AAEd"}
|
|
1
|
+
{"version":3,"file":"UniversalRenderingManager.js","names":[],"sources":["../../src/managers/UniversalRenderingManager.ts"],"sourcesContent":["type Callback = (time: number) => unknown;\n\nconst callbacks = new Set<Callback>();\nlet frameId: null | number = null;\n\n// TODO(amadeus): Figure out a proper name for this module...\nexport function queueRender(callback: Callback): void {\n callbacks.add(callback);\n frameId ??= requestAnimationFrame(render);\n}\n\nexport function dequeueRender(callback: Callback): void {\n callbacks.delete(callback);\n if (callbacks.size === 0 && frameId != null) {\n cancelAnimationFrame(frameId);\n frameId = null;\n }\n}\n\n// Drops every queued callback and cancels the pending frame. The guard\n// matters in test teardown, where the harness may have already removed the\n// requestAnimationFrame globals.\nexport function clearRenderQueue(): void {\n callbacks.clear();\n if (frameId != null && typeof cancelAnimationFrame === 'function') {\n cancelAnimationFrame(frameId);\n }\n frameId = null;\n}\n\nfunction render(time: number): void {\n const toIterate = new Set(callbacks);\n callbacks.clear();\n for (const callback of toIterate) {\n try {\n callback(time);\n } catch (error) {\n console.error(error);\n }\n }\n // If render picked up any new callbacks, lets trigger a new\n // requestAnimationFrame\n if (callbacks.size > 0) {\n frameId = requestAnimationFrame(render);\n } else {\n frameId = null;\n }\n}\n"],"mappings":";AAEA,MAAM,4BAAY,IAAI,IAAc;AACpC,IAAI,UAAyB;AAG7B,SAAgB,YAAY,UAA0B;CACpD,UAAU,IAAI,QAAQ;CACtB,YAAY,sBAAsB,MAAM;AAC1C;AAEA,SAAgB,cAAc,UAA0B;CACtD,UAAU,OAAO,QAAQ;CACzB,IAAI,UAAU,SAAS,KAAK,WAAW,MAAM;EAC3C,qBAAqB,OAAO;EAC5B,UAAU;CACZ;AACF;AAKA,SAAgB,mBAAyB;CACvC,UAAU,MAAM;CAChB,IAAI,WAAW,QAAQ,OAAO,yBAAyB,YACrD,qBAAqB,OAAO;CAE9B,UAAU;AACZ;AAEA,SAAS,OAAO,MAAoB;CAClC,MAAM,YAAY,IAAI,IAAI,SAAS;CACnC,UAAU,MAAM;CAChB,KAAK,MAAM,YAAY,WACrB,IAAI;EACF,SAAS,IAAI;CACf,SAAS,OAAO;EACd,QAAQ,MAAM,KAAK;CACrB;CAIF,IAAI,UAAU,OAAO,GACnB,UAAU,sBAAsB,MAAM;MAEtC,UAAU;AAEd"}
|
package/dist/react/CodeView.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CodeViewItem, CodeViewScrollTarget, DiffLineAnnotation, LineAnnotation } from "../types.js";
|
|
1
|
+
import { CodeViewCreateEditorOptions, CodeViewItem, CodeViewScrollTarget, DiffLineAnnotation, DiffsEditor, FileContents, LineAnnotation } from "../types.js";
|
|
2
2
|
import { GetHoveredLineResult } from "../managers/InteractionManager.js";
|
|
3
3
|
import { CodeView as CodeView$1, CodeViewLineSelection, CodeViewOptions } from "../components/CodeView.js";
|
|
4
4
|
import { CSSProperties, ReactNode, Ref } from "react";
|
|
@@ -14,8 +14,32 @@ interface CodeViewBaseProps<LAnnotation> {
|
|
|
14
14
|
selectedLines?: CodeViewLineSelection | null;
|
|
15
15
|
onSelectedLinesChange?(selection: CodeViewLineSelection | null): void;
|
|
16
16
|
onScroll?(scrollTop: number, viewer: CodeView$1<LAnnotation>): void;
|
|
17
|
+
/** Render a non-virtualized node at the very start of the scroll content,
|
|
18
|
+
* before the first item. Always rendered; scrolls with the content. */
|
|
19
|
+
renderCodeViewHeader?(): ReactNode;
|
|
20
|
+
/** Render a non-virtualized node at the very end of the scroll content, after
|
|
21
|
+
* the last item. Always rendered; scrolls with the content. */
|
|
22
|
+
renderCodeViewFooter?(): ReactNode;
|
|
23
|
+
/**
|
|
24
|
+
* Enables editing for items with `edit: true`. Pass the given options into
|
|
25
|
+
* the editor constructor — `new Editor(options)` from `@pierre/diffs/editor`
|
|
26
|
+
* — so document changes route to `onItemEditChange` and
|
|
27
|
+
* `onItemEditComplete`. CodeView owns the returned editor's lifecycle.
|
|
28
|
+
*/
|
|
29
|
+
createEditor?(options: CodeViewCreateEditorOptions<LAnnotation>): DiffsEditor<LAnnotation> | undefined;
|
|
30
|
+
/** Called with the owning item on every edited-document change. */
|
|
31
|
+
onItemEditChange?(item: CodeViewItem<LAnnotation>, file: FileContents, lineAnnotations?: DiffLineAnnotation<LAnnotation>[]): void;
|
|
32
|
+
/**
|
|
33
|
+
* Called once with the final contents when an item's edit session ends
|
|
34
|
+
* (edit turned off, item removed or collapsed). Not called for sessions
|
|
35
|
+
* that produced no changes. Committing is user-space: make one combined
|
|
36
|
+
* item write carrying the new file/fileDiff (with a fresh `cacheKey`,
|
|
37
|
+
* since the contents changed) along with `edit: false`.
|
|
38
|
+
*/
|
|
39
|
+
onItemEditComplete?(item: CodeViewItem<LAnnotation>, file: FileContents, lineAnnotations?: DiffLineAnnotation<LAnnotation>[]): void;
|
|
17
40
|
renderCustomHeader?(item: CodeViewItem<LAnnotation>): ReactNode;
|
|
18
41
|
renderHeaderPrefix?(item: CodeViewItem<LAnnotation>): ReactNode;
|
|
42
|
+
renderHeaderFilenameSuffix?(item: CodeViewItem<LAnnotation>): ReactNode;
|
|
19
43
|
renderHeaderMetadata?(item: CodeViewItem<LAnnotation>): ReactNode;
|
|
20
44
|
renderAnnotation?(annotation: LineAnnotation<LAnnotation> | DiffLineAnnotation<LAnnotation>, item: CodeViewItem<LAnnotation>): ReactNode;
|
|
21
45
|
renderGutterUtility?(getHoveredLine: CodeViewGutterUtilityGetter, item: CodeViewItem<LAnnotation>): ReactNode;
|
|
@@ -38,6 +62,7 @@ interface CodeViewHandle<LAnnotation> {
|
|
|
38
62
|
setSelectedLines(selection: CodeViewLineSelection | null): void;
|
|
39
63
|
getSelectedLines(): CodeViewLineSelection | null;
|
|
40
64
|
clearSelectedLines(): void;
|
|
65
|
+
getEditor(id: string): DiffsEditor<LAnnotation> | undefined;
|
|
41
66
|
getInstance(): CodeView$1<LAnnotation> | undefined;
|
|
42
67
|
}
|
|
43
68
|
type CodeViewComponent = <LAnnotation = undefined>(props: CodeViewProps<LAnnotation> & {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeView.d.ts","names":[],"sources":["../../src/react/CodeView.tsx"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"CodeView.d.ts","names":[],"sources":["../../src/react/CodeView.tsx"],"mappings":";;;;;;KA6CK,2BAAA,UACM,oBAAA,+BACA,oBAAoB;AAAA,UAErB,iBAAA;EACR,OAAA,GAAU,eAAA,CAAgB,WAAA;EAC1B,SAAA;EACA,KAAA,GAAQ,aAAA;EACR,YAAA,GAAe,GAAA,CAAI,cAAA;EACnB,iBAAA;EACA,aAAA,GAAgB,qBAAA;EAChB,qBAAA,EAAuB,SAAA,EAAW,qBAAA;EAClC,QAAA,EAAU,SAAA,UAAmB,MAAA,EAAQ,UAAA,CAAc,WAAA;EAR3C;;EAWR,oBAAA,KAAyB,SAAA;EAVC;;EAa1B,oBAAA,KAAyB,SAAA;EAVN;;;;;;EAiBnB,YAAA,EACE,OAAA,EAAS,2BAAA,CAA4B,WAAA,IACpC,WAAA,CAAY,WAAA;EATU;EAWzB,gBAAA,EACE,IAAA,EAAM,YAAA,CAAa,WAAA,GACnB,IAAA,EAAM,YAAA,EACN,eAAA,GAAkB,kBAAA,CAAmB,WAAA;EAN5B;;;;;;;EAeX,kBAAA,EACE,IAAA,EAAM,YAAA,CAAa,WAAA,GACnB,IAAA,EAAM,YAAA,EACN,eAAA,GAAkB,kBAAA,CAAmB,WAAA;EAEvC,kBAAA,EAAoB,IAAA,EAAM,YAAA,CAAa,WAAA,IAAe,SAAA;EACtD,kBAAA,EAAoB,IAAA,EAAM,YAAA,CAAa,WAAA,IAAe,SAAA;EACtD,0BAAA,EAA4B,IAAA,EAAM,YAAA,CAAa,WAAA,IAAe,SAAA;EAC9D,oBAAA,EAAsB,IAAA,EAAM,YAAA,CAAa,WAAA,IAAe,SAAA;EACxD,gBAAA,EACE,UAAA,EAAY,cAAA,CAAe,WAAA,IAAe,kBAAA,CAAmB,WAAA,GAC7D,IAAA,EAAM,YAAA,CAAa,WAAA,IAClB,SAAA;EACH,mBAAA,EACE,cAAA,EAAgB,2BAAA,EAChB,IAAA,EAAM,YAAA,CAAa,WAAA,IAClB,SAAA;AAAA;AAAA,UAGY,uBAAA,sBAEP,iBAAA,CAAkB,WAAA;EAC1B,KAAA,WAAgB,YAAA,CAAa,WAAA;EAC7B,YAAA;AAAA;AAAA,UAGe,yBAAA,sBAEP,iBAAA,CAAkB,WAAA;EAG1B,YAAA,YAAwB,YAAA,CAAa,WAAA;EACrC,KAAA;AAAA;AAAA,KAGU,aAAA,4BACR,uBAAA,CAAwB,WAAA,IACxB,yBAAA,CAA0B,WAAA;AAAA,UAEb,cAAA;EACf,QAAA,CAAS,KAAA,WAAgB,YAAA,CAAa,WAAA;EACtC,OAAA,CAAQ,EAAA,WAAa,YAAA,CAAa,WAAA;EAClC,UAAA,CAAW,IAAA,EAAM,YAAA,CAAa,WAAA;EAC9B,YAAA,CAAa,KAAA,UAAe,KAAA;EAC5B,QAAA,CAAS,MAAA,EAAQ,oBAAA;EACjB,gBAAA,CAAiB,SAAA,EAAW,qBAAA;EAC5B,gBAAA,IAAoB,qBAAA;EACpB,kBAAA;EACA,SAAA,CAAU,EAAA,WAAa,WAAA,CAAY,WAAA;EACnC,WAAA,IAAe,UAAA,CAAc,WAAA;AAAA;AAAA,KAG1B,iBAAA,6BACH,KAAA,EAAO,aAAA,CAAc,WAAA;EACnB,GAAA,GAAM,KAAA,CAAM,GAAA,CAAI,cAAA,CAAe,WAAA;AAAA,MAE9B,KAAA,CAAM,GAAA,CAAI,OAAA;AAAA,cAqcF,QAAA,EAAwC,iBAAiB"}
|
package/dist/react/CodeView.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
|
+
import { areManagedSnapshotsEqual } from "../utils/areManagedSnapshotsEqual.js";
|
|
2
3
|
import { areOptionsEqual } from "../utils/areOptionsEqual.js";
|
|
3
4
|
import { CodeView as CodeView$1 } from "../components/CodeView.js";
|
|
4
|
-
import { areManagedSnapshotsEqual } from "../utils/areManagedSnapshotsEqual.js";
|
|
5
5
|
import { renderDiffChildren } from "./utils/renderDiffChildren.js";
|
|
6
6
|
import { renderFileChildren } from "./utils/renderFileChildren.js";
|
|
7
7
|
import { useStableCallback } from "./utils/useStableCallback.js";
|
|
@@ -22,32 +22,54 @@ function createDefaultCache(controlled) {
|
|
|
22
22
|
};
|
|
23
23
|
}
|
|
24
24
|
function CodeViewInner(props, ref) {
|
|
25
|
-
const { className, containerRef, disableWorkerPool = false, initialItems, items: controlledItems, onScroll, onSelectedLinesChange, options, renderAnnotation, renderCustomHeader, renderGutterUtility, renderHeaderMetadata, renderHeaderPrefix, selectedLines, style } = props;
|
|
25
|
+
const { className, containerRef, createEditor, disableWorkerPool = false, initialItems, items: controlledItems, onItemEditChange, onItemEditComplete, onScroll, onSelectedLinesChange, options, renderAnnotation, renderCodeViewFooter, renderCodeViewHeader, renderCustomHeader, renderGutterUtility, renderHeaderFilenameSuffix, renderHeaderMetadata, renderHeaderPrefix, selectedLines, style } = props;
|
|
26
26
|
const controlled = controlledItems !== void 0;
|
|
27
27
|
const poolManager = useContext(WorkerPoolContext);
|
|
28
28
|
const cachedDataRef = useRef(createDefaultCache(controlled));
|
|
29
29
|
const hasCustomHeader = renderCustomHeader != null;
|
|
30
30
|
const hasAnnotationRenderer = renderAnnotation != null;
|
|
31
31
|
const hasGutterRenderer = renderGutterUtility != null;
|
|
32
|
-
const hasHeaderRenderers = hasCustomHeader || renderHeaderPrefix != null || renderHeaderMetadata != null;
|
|
32
|
+
const hasHeaderRenderers = hasCustomHeader || renderHeaderPrefix != null || renderHeaderFilenameSuffix != null || renderHeaderMetadata != null;
|
|
33
33
|
const hasRenderers = hasHeaderRenderers || hasAnnotationRenderer || hasGutterRenderer;
|
|
34
|
+
const hasCodeViewHeader = renderCodeViewHeader != null;
|
|
35
|
+
const hasCodeViewFooter = renderCodeViewFooter != null;
|
|
34
36
|
const emitSelectedLinesChange = useStableCallback((selection) => {
|
|
35
37
|
onSelectedLinesChange?.(selection);
|
|
36
38
|
});
|
|
37
39
|
const controlledSelection = selectedLines !== void 0;
|
|
40
|
+
const stableCreateEditor = useStableCallback((editorOptions) => createEditor?.(editorOptions));
|
|
41
|
+
const emitItemEditChange = useStableCallback((item, file, lineAnnotations) => {
|
|
42
|
+
onItemEditChange?.(item, file, lineAnnotations);
|
|
43
|
+
});
|
|
44
|
+
const emitItemEditComplete = useStableCallback((item, file, lineAnnotations) => {
|
|
45
|
+
onItemEditComplete?.(item, file, lineAnnotations);
|
|
46
|
+
});
|
|
38
47
|
const managedOptions = useMemo(() => createManagedCodeViewOptions({
|
|
39
48
|
options,
|
|
40
49
|
hasCustomHeader,
|
|
41
50
|
hasGutterRenderer,
|
|
51
|
+
hasCodeViewHeader,
|
|
52
|
+
hasCodeViewFooter,
|
|
42
53
|
onSelectedLinesChange: onSelectedLinesChange != null ? emitSelectedLinesChange : void 0,
|
|
43
|
-
controlledSelection
|
|
54
|
+
controlledSelection,
|
|
55
|
+
createEditor: createEditor != null ? stableCreateEditor : void 0,
|
|
56
|
+
onItemEditChange: onItemEditChange != null ? emitItemEditChange : void 0,
|
|
57
|
+
onItemEditComplete: onItemEditComplete != null ? emitItemEditComplete : void 0
|
|
44
58
|
}), [
|
|
45
59
|
options,
|
|
46
60
|
hasCustomHeader,
|
|
47
61
|
hasGutterRenderer,
|
|
62
|
+
hasCodeViewHeader,
|
|
63
|
+
hasCodeViewFooter,
|
|
48
64
|
onSelectedLinesChange,
|
|
49
65
|
emitSelectedLinesChange,
|
|
50
|
-
controlledSelection
|
|
66
|
+
controlledSelection,
|
|
67
|
+
createEditor,
|
|
68
|
+
stableCreateEditor,
|
|
69
|
+
onItemEditChange,
|
|
70
|
+
emitItemEditChange,
|
|
71
|
+
onItemEditComplete,
|
|
72
|
+
emitItemEditComplete
|
|
51
73
|
]);
|
|
52
74
|
const [slotContentStore] = useState(() => createSlotContentStore());
|
|
53
75
|
const [, forceUpdate] = useState({});
|
|
@@ -71,7 +93,7 @@ function CodeViewInner(props, ref) {
|
|
|
71
93
|
});
|
|
72
94
|
});
|
|
73
95
|
const slotCoordinator = useMemo(() => {
|
|
74
|
-
if (!hasHeaderRenderers && !hasAnnotationRenderer && !hasGutterRenderer) return;
|
|
96
|
+
if (!hasHeaderRenderers && !hasAnnotationRenderer && !hasGutterRenderer && !hasCodeViewHeader && !hasCodeViewFooter) return;
|
|
75
97
|
else return {
|
|
76
98
|
hasHeaderRenderers,
|
|
77
99
|
hasAnnotationRenderer,
|
|
@@ -82,7 +104,9 @@ function CodeViewInner(props, ref) {
|
|
|
82
104
|
onSnapshotChange,
|
|
83
105
|
hasAnnotationRenderer,
|
|
84
106
|
hasGutterRenderer,
|
|
85
|
-
hasHeaderRenderers
|
|
107
|
+
hasHeaderRenderers,
|
|
108
|
+
hasCodeViewHeader,
|
|
109
|
+
hasCodeViewFooter
|
|
86
110
|
]);
|
|
87
111
|
useIsometricEffect(() => {
|
|
88
112
|
return onScroll != null ? cachedDataRef.current.instance?.subscribeToScroll(onScroll) : void 0;
|
|
@@ -194,6 +218,14 @@ function CodeViewInner(props, ref) {
|
|
|
194
218
|
emitSelectedLinesChange(null);
|
|
195
219
|
}
|
|
196
220
|
},
|
|
221
|
+
getEditor(id) {
|
|
222
|
+
const { instance } = cachedDataRef.current;
|
|
223
|
+
if (instance == null) {
|
|
224
|
+
console.error("CodeView.getEditor: no valid instance exists", id);
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
return instance.getEditor(id);
|
|
228
|
+
},
|
|
197
229
|
getInstance() {
|
|
198
230
|
return cachedDataRef.current.instance;
|
|
199
231
|
}
|
|
@@ -202,13 +234,16 @@ function CodeViewInner(props, ref) {
|
|
|
202
234
|
ref: nodeRef,
|
|
203
235
|
className,
|
|
204
236
|
style
|
|
205
|
-
}), hasRenderers && /* @__PURE__ */ jsx(SlotPortals, {
|
|
237
|
+
}), (hasRenderers || hasCodeViewHeader || hasCodeViewFooter) && /* @__PURE__ */ jsx(SlotPortals, {
|
|
206
238
|
managedContentStore: slotContentStore,
|
|
207
239
|
renderCustomHeader,
|
|
208
240
|
renderHeaderPrefix,
|
|
241
|
+
renderHeaderFilenameSuffix,
|
|
209
242
|
renderHeaderMetadata,
|
|
210
243
|
renderAnnotation,
|
|
211
|
-
renderGutterUtility
|
|
244
|
+
renderGutterUtility,
|
|
245
|
+
renderCodeViewHeader,
|
|
246
|
+
renderCodeViewFooter
|
|
212
247
|
})] });
|
|
213
248
|
}
|
|
214
249
|
const CodeView = forwardRef(CodeViewInner);
|
|
@@ -247,38 +282,65 @@ function createSlotContentStore() {
|
|
|
247
282
|
}
|
|
248
283
|
};
|
|
249
284
|
}
|
|
250
|
-
function createManagedCodeViewOptions({ options, hasCustomHeader, hasGutterRenderer, onSelectedLinesChange, controlledSelection }) {
|
|
251
|
-
if (!hasCustomHeader && !hasGutterRenderer && onSelectedLinesChange == null && !controlledSelection) return options;
|
|
285
|
+
function createManagedCodeViewOptions({ options, hasCustomHeader, hasGutterRenderer, hasCodeViewHeader, hasCodeViewFooter, onSelectedLinesChange, controlledSelection, createEditor, onItemEditChange, onItemEditComplete }) {
|
|
286
|
+
if (!hasCustomHeader && !hasGutterRenderer && !hasCodeViewHeader && !hasCodeViewFooter && onSelectedLinesChange == null && !controlledSelection && createEditor == null && onItemEditChange == null && onItemEditComplete == null) return options ?? {};
|
|
252
287
|
options = {
|
|
253
288
|
...options,
|
|
254
289
|
controlledSelection,
|
|
255
290
|
onSelectedLinesChange
|
|
256
291
|
};
|
|
292
|
+
if (createEditor != null) options.createEditor = createEditor;
|
|
293
|
+
if (onItemEditChange != null) options.onItemEditChange = onItemEditChange;
|
|
294
|
+
if (onItemEditComplete != null) options.onItemEditComplete = onItemEditComplete;
|
|
257
295
|
if (hasCustomHeader) options.renderCustomHeader = noopRender;
|
|
258
296
|
if (hasGutterRenderer) options.renderGutterUtility = noopRender;
|
|
297
|
+
if (hasCodeViewHeader) options.renderCodeViewHeader = noopRender;
|
|
298
|
+
if (hasCodeViewFooter) options.renderCodeViewFooter = noopRender;
|
|
259
299
|
return options;
|
|
260
300
|
}
|
|
261
|
-
const SlotPortals = memo(function SlotPortals({ managedContentStore, renderCustomHeader, renderHeaderPrefix, renderHeaderMetadata, renderAnnotation, renderGutterUtility }) {
|
|
301
|
+
const SlotPortals = memo(function SlotPortals({ managedContentStore, renderCustomHeader, renderHeaderPrefix, renderHeaderFilenameSuffix, renderHeaderMetadata, renderAnnotation, renderGutterUtility, renderCodeViewHeader, renderCodeViewFooter }) {
|
|
302
|
+
"use no memo";
|
|
262
303
|
const subscribe = useStableCallback((listener) => managedContentStore.subscribe(listener));
|
|
263
304
|
const getSnapshot = useStableCallback(() => managedContentStore.getSnapshot());
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
305
|
+
const snapshot = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
306
|
+
let itemKeys = "";
|
|
307
|
+
for (const item of snapshot?.items ?? []) itemKeys += `${item.id}:${item.version}:${item.type}`;
|
|
308
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
309
|
+
useMemo(() => {
|
|
310
|
+
return snapshot?.items?.map((renderedItem) => createPortal(renderCodeViewItemChildren({
|
|
311
|
+
renderedItem,
|
|
312
|
+
renderCustomHeader,
|
|
313
|
+
renderHeaderPrefix,
|
|
314
|
+
renderHeaderFilenameSuffix,
|
|
315
|
+
renderHeaderMetadata,
|
|
316
|
+
renderAnnotation,
|
|
317
|
+
renderGutterUtility
|
|
318
|
+
}), renderedItem.element, renderedItem.id));
|
|
319
|
+
}, [
|
|
267
320
|
renderCustomHeader,
|
|
268
321
|
renderHeaderPrefix,
|
|
322
|
+
renderHeaderFilenameSuffix,
|
|
269
323
|
renderHeaderMetadata,
|
|
270
324
|
renderAnnotation,
|
|
271
|
-
renderGutterUtility
|
|
272
|
-
|
|
273
|
-
|
|
325
|
+
renderGutterUtility,
|
|
326
|
+
itemKeys
|
|
327
|
+
]),
|
|
328
|
+
useMemo(() => {
|
|
329
|
+
return renderCodeViewHeader != null && snapshot?.header != null ? createPortal(renderCodeViewHeader(), snapshot.header) : null;
|
|
330
|
+
}, [renderCodeViewHeader, snapshot?.header]),
|
|
331
|
+
useMemo(() => {
|
|
332
|
+
return renderCodeViewFooter != null && snapshot?.footer != null ? createPortal(renderCodeViewFooter(), snapshot.footer) : null;
|
|
333
|
+
}, [renderCodeViewFooter, snapshot?.footer])
|
|
334
|
+
] });
|
|
274
335
|
});
|
|
275
|
-
function renderCodeViewItemChildren({ renderedItem, renderCustomHeader, renderHeaderPrefix, renderHeaderMetadata, renderAnnotation, renderGutterUtility }) {
|
|
336
|
+
function renderCodeViewItemChildren({ renderedItem, renderCustomHeader, renderHeaderPrefix, renderHeaderFilenameSuffix, renderHeaderMetadata, renderAnnotation, renderGutterUtility }) {
|
|
276
337
|
if (renderedItem.type === "diff") {
|
|
277
338
|
const { item, instance } = renderedItem;
|
|
278
339
|
return renderDiffChildren({
|
|
279
340
|
fileDiff: item.fileDiff,
|
|
280
341
|
renderCustomHeader: renderCustomHeader != null ? () => renderCustomHeader(item) : void 0,
|
|
281
342
|
renderHeaderPrefix: renderHeaderPrefix != null ? () => renderHeaderPrefix(item) : void 0,
|
|
343
|
+
renderHeaderFilenameSuffix: renderHeaderFilenameSuffix != null ? () => renderHeaderFilenameSuffix(item) : void 0,
|
|
282
344
|
renderHeaderMetadata: renderHeaderMetadata != null ? () => renderHeaderMetadata(item) : void 0,
|
|
283
345
|
renderAnnotation: renderAnnotation != null ? (annotation) => renderAnnotation(annotation, item) : void 0,
|
|
284
346
|
lineAnnotations: item.annotations,
|
|
@@ -291,6 +353,7 @@ function renderCodeViewItemChildren({ renderedItem, renderCustomHeader, renderHe
|
|
|
291
353
|
file: item.file,
|
|
292
354
|
renderCustomHeader: renderCustomHeader != null ? () => renderCustomHeader(item) : void 0,
|
|
293
355
|
renderHeaderPrefix: renderHeaderPrefix != null ? () => renderHeaderPrefix(item) : void 0,
|
|
356
|
+
renderHeaderFilenameSuffix: renderHeaderFilenameSuffix != null ? () => renderHeaderFilenameSuffix(item) : void 0,
|
|
294
357
|
renderHeaderMetadata: renderHeaderMetadata != null ? () => renderHeaderMetadata(item) : void 0,
|
|
295
358
|
renderAnnotation: renderAnnotation != null ? (annotation) => renderAnnotation(annotation, item) : void 0,
|
|
296
359
|
lineAnnotations: item.annotations,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeView.js","names":["CodeViewClass"],"sources":["../../src/react/CodeView.tsx"],"sourcesContent":["'use client';\n\nimport {\n type CSSProperties,\n forwardRef,\n memo,\n type ReactNode,\n type Ref,\n useContext,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n useSyncExternalStore,\n} from 'react';\nimport { createPortal, flushSync } from 'react-dom';\n\nimport {\n areOptionsEqual,\n CodeView as CodeViewClass,\n type CodeViewCoordinator,\n type CodeViewItem,\n type CodeViewLineSelection,\n type CodeViewOptions,\n type CodeViewRenderedItem,\n type CodeViewScrollTarget,\n type DiffLineAnnotation,\n type GetHoveredLineResult,\n type LineAnnotation,\n} from '../index';\nimport { areManagedSnapshotsEqual } from '../utils/areManagedSnapshotsEqual';\nimport { renderDiffChildren } from './utils/renderDiffChildren';\nimport { renderFileChildren } from './utils/renderFileChildren';\nimport { useStableCallback } from './utils/useStableCallback';\nimport { WorkerPoolContext } from './WorkerPoolContext';\n\nconst useIsometricEffect =\n typeof window === 'undefined' ? useEffect : useLayoutEffect;\n\ntype CodeViewGutterUtilityGetter =\n | (() => GetHoveredLineResult<'file'> | undefined)\n | (() => GetHoveredLineResult<'diff'> | undefined);\n\ninterface CodeViewBaseProps<LAnnotation> {\n options?: CodeViewOptions<LAnnotation>;\n className?: string;\n style?: CSSProperties;\n containerRef?: Ref<HTMLDivElement>;\n disableWorkerPool?: boolean;\n selectedLines?: CodeViewLineSelection | null;\n onSelectedLinesChange?(selection: CodeViewLineSelection | null): void;\n onScroll?(scrollTop: number, viewer: CodeViewClass<LAnnotation>): void;\n renderCustomHeader?(item: CodeViewItem<LAnnotation>): ReactNode;\n renderHeaderPrefix?(item: CodeViewItem<LAnnotation>): ReactNode;\n renderHeaderMetadata?(item: CodeViewItem<LAnnotation>): ReactNode;\n renderAnnotation?(\n annotation: LineAnnotation<LAnnotation> | DiffLineAnnotation<LAnnotation>,\n item: CodeViewItem<LAnnotation>\n ): ReactNode;\n renderGutterUtility?(\n getHoveredLine: CodeViewGutterUtilityGetter,\n item: CodeViewItem<LAnnotation>\n ): ReactNode;\n}\n\nexport interface ControlledCodeViewProps<\n LAnnotation,\n> extends CodeViewBaseProps<LAnnotation> {\n items: readonly CodeViewItem<LAnnotation>[];\n initialItems?: never;\n}\n\nexport interface UncontrolledCodeViewProps<\n LAnnotation,\n> extends CodeViewBaseProps<LAnnotation> {\n // Seeds the imperative CodeView instance once. Later item changes should go\n // through the ref API instead of being reconciled from React props.\n initialItems?: readonly CodeViewItem<LAnnotation>[];\n items?: never;\n}\n\nexport type CodeViewProps<LAnnotation = undefined> =\n | ControlledCodeViewProps<LAnnotation>\n | UncontrolledCodeViewProps<LAnnotation>;\n\nexport interface CodeViewHandle<LAnnotation> {\n addItems(items: readonly CodeViewItem<LAnnotation>[]): void;\n getItem(id: string): CodeViewItem<LAnnotation> | undefined;\n updateItem(item: CodeViewItem<LAnnotation>): boolean;\n updateItemId(oldId: string, newId: string): boolean;\n scrollTo(target: CodeViewScrollTarget): void;\n setSelectedLines(selection: CodeViewLineSelection | null): void;\n getSelectedLines(): CodeViewLineSelection | null;\n clearSelectedLines(): void;\n getInstance(): CodeViewClass<LAnnotation> | undefined;\n}\n\ntype CodeViewComponent = <LAnnotation = undefined>(\n props: CodeViewProps<LAnnotation> & {\n ref?: React.Ref<CodeViewHandle<LAnnotation>>;\n }\n) => React.JSX.Element;\n\ntype SlotPortalsComponent = <LAnnotation = undefined>(\n props: SlotPortalsProps<LAnnotation>\n) => React.JSX.Element;\n\ninterface ManagedContentStore<LAnnotation> {\n getSnapshot(): CodeViewRenderedItem<LAnnotation>[] | undefined;\n publish(snapshot: CodeViewRenderedItem<LAnnotation>[] | undefined): void;\n subscribe(listener: () => void): () => void;\n}\n\ninterface CachedDataRef<LAnnotation> {\n instance: CodeViewClass<LAnnotation> | undefined;\n items: readonly CodeViewItem<LAnnotation>[] | undefined;\n controlled: boolean;\n managedOptions: CodeViewOptions<LAnnotation> | undefined;\n disableFlushSync: boolean;\n slotCoordinator: CodeViewCoordinator<LAnnotation> | undefined;\n}\n\nfunction createDefaultCache<LAnnotation>(\n controlled: boolean\n): CachedDataRef<LAnnotation> {\n return {\n instance: undefined,\n items: undefined,\n controlled,\n managedOptions: undefined,\n disableFlushSync: false,\n slotCoordinator: undefined,\n };\n}\n\nfunction CodeViewInner<LAnnotation = undefined>(\n props: CodeViewProps<LAnnotation>,\n ref: React.ForwardedRef<CodeViewHandle<LAnnotation>>\n): React.JSX.Element {\n const {\n className,\n containerRef,\n disableWorkerPool = false,\n initialItems,\n items: controlledItems,\n onScroll,\n onSelectedLinesChange,\n options,\n renderAnnotation,\n renderCustomHeader,\n renderGutterUtility,\n renderHeaderMetadata,\n renderHeaderPrefix,\n selectedLines,\n style,\n } = props;\n const controlled = controlledItems !== undefined;\n const poolManager = useContext(WorkerPoolContext);\n const cachedDataRef = useRef<CachedDataRef<LAnnotation>>(\n createDefaultCache<LAnnotation>(controlled)\n );\n const hasCustomHeader = renderCustomHeader != null;\n const hasAnnotationRenderer = renderAnnotation != null;\n const hasGutterRenderer = renderGutterUtility != null;\n const hasHeaderRenderers =\n hasCustomHeader ||\n renderHeaderPrefix != null ||\n renderHeaderMetadata != null;\n const hasRenderers =\n hasHeaderRenderers || hasAnnotationRenderer || hasGutterRenderer;\n const emitSelectedLinesChange = useStableCallback(\n (selection: CodeViewLineSelection | null) => {\n onSelectedLinesChange?.(selection);\n }\n );\n const controlledSelection = selectedLines !== undefined;\n\n const managedOptions = useMemo(\n () =>\n createManagedCodeViewOptions({\n options,\n hasCustomHeader,\n hasGutterRenderer,\n onSelectedLinesChange:\n onSelectedLinesChange != null ? emitSelectedLinesChange : undefined,\n controlledSelection,\n }),\n [\n options,\n hasCustomHeader,\n hasGutterRenderer,\n onSelectedLinesChange,\n emitSelectedLinesChange,\n controlledSelection,\n ]\n );\n\n const [slotContentStore] = useState<ManagedContentStore<LAnnotation>>(() =>\n createSlotContentStore()\n );\n const [, forceUpdate] = useState<unknown>({});\n\n const nodeRef = useStableCallback((node: HTMLDivElement | null) => {\n // If we have a pre-existing instance and there's no node or the node being\n // passed in is NOT the same as before, then we need to clean up and\n // garbage collect the old instance\n if (\n cachedDataRef.current.instance != null &&\n (node == null ||\n node !== cachedDataRef.current.instance.getContainerElement())\n ) {\n cachedDataRef.current.instance.cleanUp();\n slotContentStore.publish(undefined);\n cachedDataRef.current = createDefaultCache<LAnnotation>(controlled);\n }\n\n // If our node matches the existing node then we should not attempt to\n // setup. This is a case that should never be possible to hit, but just in\n // case, lets make sure we don't re-setup an instance that is already setup\n // properly\n if (\n node != null &&\n node !== cachedDataRef.current.instance?.getContainerElement()\n ) {\n cachedDataRef.current.instance = new CodeViewClass<LAnnotation>(\n managedOptions,\n !disableWorkerPool ? poolManager : undefined,\n true\n );\n cachedDataRef.current.instance.setup(node);\n }\n\n if (typeof containerRef === 'function') {\n containerRef(node);\n } else if (containerRef != null) {\n containerRef.current = node;\n }\n });\n\n const onSnapshotChange = useStableCallback(\n (snapshot: CodeViewRenderedItem<LAnnotation>[] | undefined) => {\n if (cachedDataRef.current.disableFlushSync) {\n slotContentStore.publish(snapshot);\n } else {\n flushSync(() => {\n slotContentStore.publish(snapshot);\n });\n }\n }\n );\n\n const slotCoordinator: CodeViewCoordinator<LAnnotation> | undefined =\n useMemo(() => {\n if (!hasHeaderRenderers && !hasAnnotationRenderer && !hasGutterRenderer) {\n return undefined;\n } else {\n return {\n hasHeaderRenderers,\n hasAnnotationRenderer,\n hasGutterRenderer,\n onSnapshotChange,\n };\n }\n }, [\n onSnapshotChange,\n hasAnnotationRenderer,\n hasGutterRenderer,\n hasHeaderRenderers,\n ]);\n\n useIsometricEffect(() => {\n return onScroll != null\n ? cachedDataRef.current.instance?.subscribeToScroll(onScroll)\n : undefined;\n });\n\n useIsometricEffect(() => {\n const {\n instance,\n controlled: prevControlled,\n items: prevItems,\n managedOptions: prevManagedOptions,\n slotCoordinator: prevSlotCoordinator,\n } = cachedDataRef.current;\n if (instance == null) {\n return;\n }\n\n try {\n cachedDataRef.current.disableFlushSync = true;\n let shouldRender = false;\n\n if (!areOptionsEqual(managedOptions, prevManagedOptions)) {\n cachedDataRef.current.managedOptions = managedOptions;\n instance.setOptions(managedOptions);\n shouldRender = true;\n }\n\n if (prevControlled !== controlled) {\n console.error(\n 'CodeView: cannot switch between controlled and uncontrolled modes. Remount with a new key instead.'\n );\n return;\n }\n\n if (controlled) {\n if (controlledItems !== prevItems) {\n if (areItemListsEqual(prevItems, controlledItems)) {\n cachedDataRef.current.items = controlledItems;\n } else if (isAppendOnlyItemUpdate(prevItems, controlledItems)) {\n cachedDataRef.current.items = controlledItems;\n instance.addItems(controlledItems.slice(prevItems.length));\n } else {\n cachedDataRef.current.items = controlledItems;\n instance.setItems(controlledItems);\n shouldRender = true;\n }\n }\n }\n // If uncontrolled, we should only ever set items once, and just depend\n // on imperative instance changes going forward\n else if (prevItems == null) {\n const seedItems = initialItems ?? [];\n cachedDataRef.current.items = seedItems;\n if (seedItems.length > 0) {\n instance.setItems(seedItems);\n shouldRender = true;\n }\n }\n\n if (selectedLines !== undefined) {\n instance.setSelectedLines(selectedLines, { notify: false });\n }\n\n const slotPublish = instance.setSlotCoordinator(slotCoordinator);\n let forceInlinePublish = false;\n if (slotCoordinator !== prevSlotCoordinator) {\n if (slotCoordinator == null || prevSlotCoordinator == null) {\n forceInlinePublish = true;\n }\n cachedDataRef.current.slotCoordinator = slotCoordinator;\n }\n\n if (shouldRender || slotPublish) {\n instance.render(true);\n }\n\n // FIXME(amadeus): This feels kinda bad and flakey with regards to how\n // other things are working... it makes me think that we should\n // re-architect the slotCoordinator a bit, and maybe DON'T make it an\n // undefineable thing...\n if (slotPublish && slotCoordinator == null) {\n slotContentStore.publish(undefined);\n }\n\n if (forceInlinePublish) {\n forceUpdate({});\n }\n } finally {\n cachedDataRef.current.disableFlushSync = false;\n }\n });\n\n // Setup the ref handler\n useImperativeHandle(\n ref,\n (): CodeViewHandle<LAnnotation> => ({\n addItems(items) {\n const { controlled, instance } = cachedDataRef.current;\n assertUncontrolledCodeViewAction(controlled, 'addItems');\n if (instance == null) {\n console.error(\n 'CodeView.addItems: no valid instance to append items with',\n items\n );\n } else {\n instance.addItems(items);\n }\n },\n getItem(id) {\n const { instance } = cachedDataRef.current;\n if (instance == null) {\n console.error('CodeView.getItem: no valid instance exists', id);\n return undefined;\n } else {\n return instance.getItem(id);\n }\n },\n updateItem(item) {\n const { controlled, instance } = cachedDataRef.current;\n assertUncontrolledCodeViewAction(controlled, 'updateItem');\n if (instance == null) {\n console.error(\n 'CodeView.updateItem: no valid instance to update item with',\n item\n );\n return false;\n }\n\n return instance.updateItem(item);\n },\n updateItemId(oldId, newId) {\n const { controlled, instance } = cachedDataRef.current;\n assertUncontrolledCodeViewAction(controlled, 'updateItemId');\n if (instance == null) {\n console.error(\n 'CodeView.updateItemId: no valid instance to update item id with',\n oldId,\n newId\n );\n return false;\n }\n\n return instance.updateItemId(oldId, newId);\n },\n scrollTo(target) {\n const { instance } = cachedDataRef.current;\n if (instance == null) {\n console.error(\n 'CodeView.scrollTo: no valid instance to scroll with',\n target\n );\n } else {\n instance.scrollTo(target);\n }\n },\n setSelectedLines(selection) {\n const { instance } = cachedDataRef.current;\n if (instance == null) {\n console.error(\n 'CodeView.setSelectedLines: no valid instance to update selection with',\n selection\n );\n } else {\n instance.setSelectedLines(selection, { notify: false });\n emitSelectedLinesChange(selection);\n }\n },\n getSelectedLines() {\n const { instance } = cachedDataRef.current;\n if (instance == null) {\n console.error('CodeView.getSelectedLines: no valid instance exists');\n return null;\n } else {\n return instance.getSelectedLines();\n }\n },\n clearSelectedLines() {\n const { instance } = cachedDataRef.current;\n if (instance == null) {\n console.error(\n 'CodeView.clearSelectedLines: no valid instance to update selection with'\n );\n } else {\n instance.clearSelectedLines({ notify: false });\n emitSelectedLinesChange(null);\n }\n },\n getInstance() {\n return cachedDataRef.current.instance;\n },\n }),\n [emitSelectedLinesChange]\n );\n\n return (\n <>\n <div ref={nodeRef} className={className} style={style} />\n {hasRenderers && (\n <SlotPortals<LAnnotation>\n managedContentStore={slotContentStore}\n renderCustomHeader={renderCustomHeader}\n renderHeaderPrefix={renderHeaderPrefix}\n renderHeaderMetadata={renderHeaderMetadata}\n renderAnnotation={renderAnnotation}\n renderGutterUtility={renderGutterUtility}\n />\n )}\n </>\n );\n}\n\n// React was a mistake\nexport const CodeView = forwardRef(CodeViewInner) as CodeViewComponent;\n\nfunction isAppendOnlyItemUpdate<LAnnotation>(\n previousItems: readonly CodeViewItem<LAnnotation>[] | undefined,\n nextItems: readonly CodeViewItem<LAnnotation>[]\n): previousItems is readonly CodeViewItem<LAnnotation>[] {\n if (previousItems == null || nextItems.length <= previousItems.length) {\n return false;\n }\n\n if (previousItems.length === 0) {\n return true;\n }\n\n for (let index = 0; index < previousItems.length; index++) {\n if (nextItems[index] !== previousItems[index]) {\n return false;\n }\n }\n\n return true;\n}\n\nfunction areItemListsEqual<LAnnotation>(\n previousItems: readonly CodeViewItem<LAnnotation>[] | undefined,\n nextItems: readonly CodeViewItem<LAnnotation>[]\n): boolean {\n if (previousItems == null || previousItems.length !== nextItems.length) {\n return false;\n }\n\n for (let index = 0; index < previousItems.length; index++) {\n if (previousItems[index] !== nextItems[index]) {\n return false;\n }\n }\n\n return true;\n}\n\nfunction assertUncontrolledCodeViewAction(\n controlled: boolean,\n action: string\n): void {\n if (!controlled) {\n return;\n }\n\n throw new Error(\n `CodeView.${action} cannot be used when CodeView is controlled. Use initialItems for imperative item updates.`\n );\n}\n\nfunction createSlotContentStore<\n LAnnotation,\n>(): ManagedContentStore<LAnnotation> {\n let snapshot: CodeViewRenderedItem<LAnnotation>[] | undefined;\n const listeners = new Set<() => void>();\n\n return {\n getSnapshot() {\n return snapshot;\n },\n publish(nextSnapshot) {\n if (areManagedSnapshotsEqual(snapshot, nextSnapshot)) {\n return;\n }\n\n snapshot = nextSnapshot;\n for (const listener of listeners) {\n listener();\n }\n },\n subscribe(listener) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n };\n}\n\ninterface CreateManagedCodeViewOptionsProps<LAnnotation> {\n options: CodeViewOptions<LAnnotation> | undefined;\n hasCustomHeader: boolean;\n hasGutterRenderer: boolean;\n onSelectedLinesChange?(selection: CodeViewLineSelection | null): void;\n controlledSelection: boolean;\n}\n\nfunction createManagedCodeViewOptions<LAnnotation>({\n options,\n hasCustomHeader,\n hasGutterRenderer,\n onSelectedLinesChange,\n controlledSelection,\n}: CreateManagedCodeViewOptionsProps<LAnnotation>):\n | CodeViewOptions<LAnnotation>\n | undefined {\n if (\n !hasCustomHeader &&\n !hasGutterRenderer &&\n onSelectedLinesChange == null &&\n !controlledSelection\n ) {\n return options;\n }\n options = { ...options, controlledSelection, onSelectedLinesChange };\n\n // The imperative CodeView adapters use this callback's presence to\n // switch file and diff headers into custom-slot mode. React portals\n // provide the actual header content, so this placeholder\n // intentionally returns nothing.\n if (hasCustomHeader) {\n options.renderCustomHeader = noopRender;\n }\n\n // The imperative CodeView adapters use this callback's presence to\n // create the custom gutter utility slot. React portals provide the\n // actual content, so this placeholder intentionally returns nothing.\n if (hasGutterRenderer) {\n options.renderGutterUtility = noopRender;\n }\n\n return options;\n}\n\ninterface RenderCodeViewItemChildrenProps<LAnnotation> {\n renderedItem: CodeViewRenderedItem<LAnnotation>;\n renderCustomHeader: CodeViewBaseProps<LAnnotation>['renderCustomHeader'];\n renderHeaderPrefix: CodeViewBaseProps<LAnnotation>['renderHeaderPrefix'];\n renderHeaderMetadata: CodeViewBaseProps<LAnnotation>['renderHeaderMetadata'];\n renderAnnotation: CodeViewBaseProps<LAnnotation>['renderAnnotation'];\n renderGutterUtility: CodeViewBaseProps<LAnnotation>['renderGutterUtility'];\n}\n\ninterface SlotPortalsProps<LAnnotation> {\n managedContentStore: ManagedContentStore<LAnnotation>;\n renderCustomHeader: CodeViewBaseProps<LAnnotation>['renderCustomHeader'];\n renderHeaderPrefix: CodeViewBaseProps<LAnnotation>['renderHeaderPrefix'];\n renderHeaderMetadata: CodeViewBaseProps<LAnnotation>['renderHeaderMetadata'];\n renderAnnotation: CodeViewBaseProps<LAnnotation>['renderAnnotation'];\n renderGutterUtility: CodeViewBaseProps<LAnnotation>['renderGutterUtility'];\n}\n\nconst SlotPortals = memo(function SlotPortals<LAnnotation>({\n managedContentStore,\n renderCustomHeader,\n renderHeaderPrefix,\n renderHeaderMetadata,\n renderAnnotation,\n renderGutterUtility,\n}: SlotPortalsProps<LAnnotation>) {\n const subscribe = useStableCallback((listener: () => void) =>\n managedContentStore.subscribe(listener)\n );\n const getSnapshot = useStableCallback(() =>\n managedContentStore.getSnapshot()\n );\n const renderedItems = useSyncExternalStore<\n CodeViewRenderedItem<LAnnotation>[] | undefined\n >(subscribe, getSnapshot, getSnapshot);\n return renderedItems?.map((renderedItem) => {\n return createPortal(\n renderCodeViewItemChildren({\n renderedItem,\n renderCustomHeader,\n renderHeaderPrefix,\n renderHeaderMetadata,\n renderAnnotation,\n renderGutterUtility,\n }),\n renderedItem.element,\n renderedItem.id\n );\n });\n}) as SlotPortalsComponent;\n\nfunction renderCodeViewItemChildren<LAnnotation>({\n renderedItem,\n renderCustomHeader,\n renderHeaderPrefix,\n renderHeaderMetadata,\n renderAnnotation,\n renderGutterUtility,\n}: RenderCodeViewItemChildrenProps<LAnnotation>): ReactNode {\n if (renderedItem.type === 'diff') {\n const { item, instance } = renderedItem;\n return renderDiffChildren({\n fileDiff: item.fileDiff,\n renderCustomHeader:\n renderCustomHeader != null ? () => renderCustomHeader(item) : undefined,\n renderHeaderPrefix:\n renderHeaderPrefix != null ? () => renderHeaderPrefix(item) : undefined,\n renderHeaderMetadata:\n renderHeaderMetadata != null\n ? () => renderHeaderMetadata(item)\n : undefined,\n renderAnnotation:\n renderAnnotation != null\n ? (annotation) => renderAnnotation(annotation, item)\n : undefined,\n lineAnnotations: item.annotations,\n renderGutterUtility:\n renderGutterUtility != null\n ? (getHoveredLine) => renderGutterUtility(getHoveredLine, item)\n : undefined,\n getHoveredLine: instance.getHoveredLine,\n });\n } else {\n const { item, instance } = renderedItem;\n return renderFileChildren({\n file: item.file,\n renderCustomHeader:\n renderCustomHeader != null ? () => renderCustomHeader(item) : undefined,\n renderHeaderPrefix:\n renderHeaderPrefix != null ? () => renderHeaderPrefix(item) : undefined,\n renderHeaderMetadata:\n renderHeaderMetadata != null\n ? () => renderHeaderMetadata(item)\n : undefined,\n renderAnnotation:\n renderAnnotation != null\n ? (annotation) => renderAnnotation(annotation, item)\n : undefined,\n lineAnnotations: item.annotations,\n renderGutterUtility:\n renderGutterUtility != null\n ? (getHoveredLine) => renderGutterUtility(getHoveredLine, item)\n : undefined,\n getHoveredLine: instance.getHoveredLine,\n });\n }\n}\n\nfunction noopRender() {\n return undefined;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CodeView.js","names":["CodeViewClass"],"sources":["../../src/react/CodeView.tsx"],"sourcesContent":["'use client';\n\nimport {\n type CSSProperties,\n forwardRef,\n memo,\n type ReactNode,\n type Ref,\n useContext,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n useSyncExternalStore,\n} from 'react';\nimport { createPortal, flushSync } from 'react-dom';\n\nimport {\n areOptionsEqual,\n CodeView as CodeViewClass,\n type CodeViewCoordinator,\n type CodeViewCreateEditorOptions,\n type CodeViewItem,\n type CodeViewLineSelection,\n type CodeViewOptions,\n type CodeViewRenderedItem,\n type CodeViewScrollTarget,\n type CodeViewSlotSnapshot,\n type DiffLineAnnotation,\n type DiffsEditor,\n type FileContents,\n type GetHoveredLineResult,\n type LineAnnotation,\n} from '../index';\nimport { areManagedSnapshotsEqual } from '../utils/areManagedSnapshotsEqual';\nimport { renderDiffChildren } from './utils/renderDiffChildren';\nimport { renderFileChildren } from './utils/renderFileChildren';\nimport { useStableCallback } from './utils/useStableCallback';\nimport { WorkerPoolContext } from './WorkerPoolContext';\n\nconst useIsometricEffect =\n typeof window === 'undefined' ? useEffect : useLayoutEffect;\n\ntype CodeViewGutterUtilityGetter =\n | (() => GetHoveredLineResult<'file'> | undefined)\n | (() => GetHoveredLineResult<'diff'> | undefined);\n\ninterface CodeViewBaseProps<LAnnotation> {\n options?: CodeViewOptions<LAnnotation>;\n className?: string;\n style?: CSSProperties;\n containerRef?: Ref<HTMLDivElement>;\n disableWorkerPool?: boolean;\n selectedLines?: CodeViewLineSelection | null;\n onSelectedLinesChange?(selection: CodeViewLineSelection | null): void;\n onScroll?(scrollTop: number, viewer: CodeViewClass<LAnnotation>): void;\n /** Render a non-virtualized node at the very start of the scroll content,\n * before the first item. Always rendered; scrolls with the content. */\n renderCodeViewHeader?(): ReactNode;\n /** Render a non-virtualized node at the very end of the scroll content, after\n * the last item. Always rendered; scrolls with the content. */\n renderCodeViewFooter?(): ReactNode;\n /**\n * Enables editing for items with `edit: true`. Pass the given options into\n * the editor constructor — `new Editor(options)` from `@pierre/diffs/editor`\n * — so document changes route to `onItemEditChange` and\n * `onItemEditComplete`. CodeView owns the returned editor's lifecycle.\n */\n createEditor?(\n options: CodeViewCreateEditorOptions<LAnnotation>\n ): DiffsEditor<LAnnotation> | undefined;\n /** Called with the owning item on every edited-document change. */\n onItemEditChange?(\n item: CodeViewItem<LAnnotation>,\n file: FileContents,\n lineAnnotations?: DiffLineAnnotation<LAnnotation>[]\n ): void;\n /**\n * Called once with the final contents when an item's edit session ends\n * (edit turned off, item removed or collapsed). Not called for sessions\n * that produced no changes. Committing is user-space: make one combined\n * item write carrying the new file/fileDiff (with a fresh `cacheKey`,\n * since the contents changed) along with `edit: false`.\n */\n onItemEditComplete?(\n item: CodeViewItem<LAnnotation>,\n file: FileContents,\n lineAnnotations?: DiffLineAnnotation<LAnnotation>[]\n ): void;\n renderCustomHeader?(item: CodeViewItem<LAnnotation>): ReactNode;\n renderHeaderPrefix?(item: CodeViewItem<LAnnotation>): ReactNode;\n renderHeaderFilenameSuffix?(item: CodeViewItem<LAnnotation>): ReactNode;\n renderHeaderMetadata?(item: CodeViewItem<LAnnotation>): ReactNode;\n renderAnnotation?(\n annotation: LineAnnotation<LAnnotation> | DiffLineAnnotation<LAnnotation>,\n item: CodeViewItem<LAnnotation>\n ): ReactNode;\n renderGutterUtility?(\n getHoveredLine: CodeViewGutterUtilityGetter,\n item: CodeViewItem<LAnnotation>\n ): ReactNode;\n}\n\nexport interface ControlledCodeViewProps<\n LAnnotation,\n> extends CodeViewBaseProps<LAnnotation> {\n items: readonly CodeViewItem<LAnnotation>[];\n initialItems?: never;\n}\n\nexport interface UncontrolledCodeViewProps<\n LAnnotation,\n> extends CodeViewBaseProps<LAnnotation> {\n // Seeds the imperative CodeView instance once. Later item changes should go\n // through the ref API instead of being reconciled from React props.\n initialItems?: readonly CodeViewItem<LAnnotation>[];\n items?: never;\n}\n\nexport type CodeViewProps<LAnnotation = undefined> =\n | ControlledCodeViewProps<LAnnotation>\n | UncontrolledCodeViewProps<LAnnotation>;\n\nexport interface CodeViewHandle<LAnnotation> {\n addItems(items: readonly CodeViewItem<LAnnotation>[]): void;\n getItem(id: string): CodeViewItem<LAnnotation> | undefined;\n updateItem(item: CodeViewItem<LAnnotation>): boolean;\n updateItemId(oldId: string, newId: string): boolean;\n scrollTo(target: CodeViewScrollTarget): void;\n setSelectedLines(selection: CodeViewLineSelection | null): void;\n getSelectedLines(): CodeViewLineSelection | null;\n clearSelectedLines(): void;\n getEditor(id: string): DiffsEditor<LAnnotation> | undefined;\n getInstance(): CodeViewClass<LAnnotation> | undefined;\n}\n\ntype CodeViewComponent = <LAnnotation = undefined>(\n props: CodeViewProps<LAnnotation> & {\n ref?: React.Ref<CodeViewHandle<LAnnotation>>;\n }\n) => React.JSX.Element;\n\ntype SlotPortalsComponent = <LAnnotation = undefined>(\n props: SlotPortalsProps<LAnnotation>\n) => React.JSX.Element;\n\ninterface ManagedContentStore<LAnnotation> {\n getSnapshot(): CodeViewSlotSnapshot<LAnnotation> | undefined;\n publish(snapshot: CodeViewSlotSnapshot<LAnnotation> | undefined): void;\n subscribe(listener: () => void): () => void;\n}\n\ninterface CachedDataRef<LAnnotation> {\n instance: CodeViewClass<LAnnotation> | undefined;\n items: readonly CodeViewItem<LAnnotation>[] | undefined;\n controlled: boolean;\n managedOptions: CodeViewOptions<LAnnotation> | undefined;\n disableFlushSync: boolean;\n slotCoordinator: CodeViewCoordinator<LAnnotation> | undefined;\n}\n\nfunction createDefaultCache<LAnnotation>(\n controlled: boolean\n): CachedDataRef<LAnnotation> {\n return {\n instance: undefined,\n items: undefined,\n controlled,\n managedOptions: undefined,\n disableFlushSync: false,\n slotCoordinator: undefined,\n };\n}\n\nfunction CodeViewInner<LAnnotation = undefined>(\n props: CodeViewProps<LAnnotation>,\n ref: React.ForwardedRef<CodeViewHandle<LAnnotation>>\n): React.JSX.Element {\n const {\n className,\n containerRef,\n createEditor,\n disableWorkerPool = false,\n initialItems,\n items: controlledItems,\n onItemEditChange,\n onItemEditComplete,\n onScroll,\n onSelectedLinesChange,\n options,\n renderAnnotation,\n renderCodeViewFooter,\n renderCodeViewHeader,\n renderCustomHeader,\n renderGutterUtility,\n renderHeaderFilenameSuffix,\n renderHeaderMetadata,\n renderHeaderPrefix,\n selectedLines,\n style,\n } = props;\n const controlled = controlledItems !== undefined;\n const poolManager = useContext(WorkerPoolContext);\n const cachedDataRef = useRef<CachedDataRef<LAnnotation>>(\n createDefaultCache<LAnnotation>(controlled)\n );\n const hasCustomHeader = renderCustomHeader != null;\n const hasAnnotationRenderer = renderAnnotation != null;\n const hasGutterRenderer = renderGutterUtility != null;\n const hasHeaderRenderers =\n hasCustomHeader ||\n renderHeaderPrefix != null ||\n renderHeaderFilenameSuffix != null ||\n renderHeaderMetadata != null;\n const hasRenderers =\n hasHeaderRenderers || hasAnnotationRenderer || hasGutterRenderer;\n const hasCodeViewHeader = renderCodeViewHeader != null;\n const hasCodeViewFooter = renderCodeViewFooter != null;\n const emitSelectedLinesChange = useStableCallback(\n (selection: CodeViewLineSelection | null) => {\n onSelectedLinesChange?.(selection);\n }\n );\n const controlledSelection = selectedLines !== undefined;\n\n // Stable identities for the editor callbacks so inline props don't churn\n // managedOptions (a changed options object forces a full item re-render).\n const stableCreateEditor = useStableCallback(\n (editorOptions: CodeViewCreateEditorOptions<LAnnotation>) =>\n createEditor?.(editorOptions)\n );\n const emitItemEditChange = useStableCallback(\n (\n item: CodeViewItem<LAnnotation>,\n file: FileContents,\n lineAnnotations?: DiffLineAnnotation<LAnnotation>[]\n ) => {\n onItemEditChange?.(item, file, lineAnnotations);\n }\n );\n const emitItemEditComplete = useStableCallback(\n (\n item: CodeViewItem<LAnnotation>,\n file: FileContents,\n lineAnnotations?: DiffLineAnnotation<LAnnotation>[]\n ) => {\n onItemEditComplete?.(item, file, lineAnnotations);\n }\n );\n\n const managedOptions = useMemo(\n () =>\n createManagedCodeViewOptions({\n options,\n hasCustomHeader,\n hasGutterRenderer,\n hasCodeViewHeader,\n hasCodeViewFooter,\n onSelectedLinesChange:\n onSelectedLinesChange != null ? emitSelectedLinesChange : undefined,\n controlledSelection,\n createEditor: createEditor != null ? stableCreateEditor : undefined,\n onItemEditChange:\n onItemEditChange != null ? emitItemEditChange : undefined,\n onItemEditComplete:\n onItemEditComplete != null ? emitItemEditComplete : undefined,\n }),\n [\n options,\n hasCustomHeader,\n hasGutterRenderer,\n hasCodeViewHeader,\n hasCodeViewFooter,\n onSelectedLinesChange,\n emitSelectedLinesChange,\n controlledSelection,\n createEditor,\n stableCreateEditor,\n onItemEditChange,\n emitItemEditChange,\n onItemEditComplete,\n emitItemEditComplete,\n ]\n );\n\n const [slotContentStore] = useState<ManagedContentStore<LAnnotation>>(() =>\n createSlotContentStore()\n );\n const [, forceUpdate] = useState<unknown>({});\n\n const nodeRef = useStableCallback((node: HTMLDivElement | null) => {\n // If we have a pre-existing instance and there's no node or the node being\n // passed in is NOT the same as before, then we need to clean up and\n // garbage collect the old instance\n if (\n cachedDataRef.current.instance != null &&\n (node == null ||\n node !== cachedDataRef.current.instance.getContainerElement())\n ) {\n cachedDataRef.current.instance.cleanUp();\n slotContentStore.publish(undefined);\n cachedDataRef.current = createDefaultCache<LAnnotation>(controlled);\n }\n\n // If our node matches the existing node then we should not attempt to\n // setup. This is a case that should never be possible to hit, but just in\n // case, lets make sure we don't re-setup an instance that is already setup\n // properly\n if (\n node != null &&\n node !== cachedDataRef.current.instance?.getContainerElement()\n ) {\n cachedDataRef.current.instance = new CodeViewClass<LAnnotation>(\n managedOptions,\n !disableWorkerPool ? poolManager : undefined,\n true\n );\n cachedDataRef.current.instance.setup(node);\n }\n\n if (typeof containerRef === 'function') {\n containerRef(node);\n } else if (containerRef != null) {\n containerRef.current = node;\n }\n });\n\n const onSnapshotChange = useStableCallback(\n (snapshot: CodeViewSlotSnapshot<LAnnotation> | undefined) => {\n if (cachedDataRef.current.disableFlushSync) {\n slotContentStore.publish(snapshot);\n } else {\n flushSync(() => {\n slotContentStore.publish(snapshot);\n });\n }\n }\n );\n\n const slotCoordinator: CodeViewCoordinator<LAnnotation> | undefined =\n useMemo(() => {\n // A coordinator is needed whenever React portals anything — per-item\n // slots and codeview header and footer\n if (\n !hasHeaderRenderers &&\n !hasAnnotationRenderer &&\n !hasGutterRenderer &&\n !hasCodeViewHeader &&\n !hasCodeViewFooter\n ) {\n return undefined;\n } else {\n return {\n hasHeaderRenderers,\n hasAnnotationRenderer,\n hasGutterRenderer,\n onSnapshotChange,\n };\n }\n }, [\n onSnapshotChange,\n hasAnnotationRenderer,\n hasGutterRenderer,\n hasHeaderRenderers,\n hasCodeViewHeader,\n hasCodeViewFooter,\n ]);\n\n useIsometricEffect(() => {\n return onScroll != null\n ? cachedDataRef.current.instance?.subscribeToScroll(onScroll)\n : undefined;\n });\n\n useIsometricEffect(() => {\n const {\n instance,\n controlled: prevControlled,\n items: prevItems,\n managedOptions: prevManagedOptions,\n slotCoordinator: prevSlotCoordinator,\n } = cachedDataRef.current;\n if (instance == null) {\n return;\n }\n\n try {\n cachedDataRef.current.disableFlushSync = true;\n let shouldRender = false;\n\n if (!areOptionsEqual(managedOptions, prevManagedOptions)) {\n cachedDataRef.current.managedOptions = managedOptions;\n instance.setOptions(managedOptions);\n shouldRender = true;\n }\n\n if (prevControlled !== controlled) {\n console.error(\n 'CodeView: cannot switch between controlled and uncontrolled modes. Remount with a new key instead.'\n );\n return;\n }\n\n if (controlled) {\n if (controlledItems !== prevItems) {\n if (areItemListsEqual(prevItems, controlledItems)) {\n cachedDataRef.current.items = controlledItems;\n } else if (isAppendOnlyItemUpdate(prevItems, controlledItems)) {\n cachedDataRef.current.items = controlledItems;\n instance.addItems(controlledItems.slice(prevItems.length));\n } else {\n cachedDataRef.current.items = controlledItems;\n instance.setItems(controlledItems);\n shouldRender = true;\n }\n }\n }\n // If uncontrolled, we should only ever set items once, and just depend\n // on imperative instance changes going forward\n else if (prevItems == null) {\n const seedItems = initialItems ?? [];\n cachedDataRef.current.items = seedItems;\n if (seedItems.length > 0) {\n instance.setItems(seedItems);\n shouldRender = true;\n }\n }\n\n if (selectedLines !== undefined) {\n instance.setSelectedLines(selectedLines, { notify: false });\n }\n\n const slotPublish = instance.setSlotCoordinator(slotCoordinator);\n let forceInlinePublish = false;\n if (slotCoordinator !== prevSlotCoordinator) {\n if (slotCoordinator == null || prevSlotCoordinator == null) {\n forceInlinePublish = true;\n }\n cachedDataRef.current.slotCoordinator = slotCoordinator;\n }\n\n if (shouldRender || slotPublish) {\n instance.render(true);\n }\n\n // FIXME(amadeus): This feels kinda bad and flakey with regards to how\n // other things are working... it makes me think that we should\n // re-architect the slotCoordinator a bit, and maybe DON'T make it an\n // undefineable thing...\n if (slotPublish && slotCoordinator == null) {\n slotContentStore.publish(undefined);\n }\n\n if (forceInlinePublish) {\n forceUpdate({});\n }\n } finally {\n cachedDataRef.current.disableFlushSync = false;\n }\n });\n\n // Setup the ref handler\n useImperativeHandle(\n ref,\n (): CodeViewHandle<LAnnotation> => ({\n addItems(items) {\n const { controlled, instance } = cachedDataRef.current;\n assertUncontrolledCodeViewAction(controlled, 'addItems');\n if (instance == null) {\n console.error(\n 'CodeView.addItems: no valid instance to append items with',\n items\n );\n } else {\n instance.addItems(items);\n }\n },\n getItem(id) {\n const { instance } = cachedDataRef.current;\n if (instance == null) {\n console.error('CodeView.getItem: no valid instance exists', id);\n return undefined;\n } else {\n return instance.getItem(id);\n }\n },\n updateItem(item) {\n const { controlled, instance } = cachedDataRef.current;\n assertUncontrolledCodeViewAction(controlled, 'updateItem');\n if (instance == null) {\n console.error(\n 'CodeView.updateItem: no valid instance to update item with',\n item\n );\n return false;\n }\n\n return instance.updateItem(item);\n },\n updateItemId(oldId, newId) {\n const { controlled, instance } = cachedDataRef.current;\n assertUncontrolledCodeViewAction(controlled, 'updateItemId');\n if (instance == null) {\n console.error(\n 'CodeView.updateItemId: no valid instance to update item id with',\n oldId,\n newId\n );\n return false;\n }\n\n return instance.updateItemId(oldId, newId);\n },\n scrollTo(target) {\n const { instance } = cachedDataRef.current;\n if (instance == null) {\n console.error(\n 'CodeView.scrollTo: no valid instance to scroll with',\n target\n );\n } else {\n instance.scrollTo(target);\n }\n },\n setSelectedLines(selection) {\n const { instance } = cachedDataRef.current;\n if (instance == null) {\n console.error(\n 'CodeView.setSelectedLines: no valid instance to update selection with',\n selection\n );\n } else {\n instance.setSelectedLines(selection, { notify: false });\n emitSelectedLinesChange(selection);\n }\n },\n getSelectedLines() {\n const { instance } = cachedDataRef.current;\n if (instance == null) {\n console.error('CodeView.getSelectedLines: no valid instance exists');\n return null;\n } else {\n return instance.getSelectedLines();\n }\n },\n clearSelectedLines() {\n const { instance } = cachedDataRef.current;\n if (instance == null) {\n console.error(\n 'CodeView.clearSelectedLines: no valid instance to update selection with'\n );\n } else {\n instance.clearSelectedLines({ notify: false });\n emitSelectedLinesChange(null);\n }\n },\n getEditor(id) {\n const { instance } = cachedDataRef.current;\n if (instance == null) {\n console.error('CodeView.getEditor: no valid instance exists', id);\n return undefined;\n }\n\n return instance.getEditor(id);\n },\n getInstance() {\n return cachedDataRef.current.instance;\n },\n }),\n [emitSelectedLinesChange]\n );\n\n return (\n <>\n <div ref={nodeRef} className={className} style={style} />\n {(hasRenderers || hasCodeViewHeader || hasCodeViewFooter) && (\n <SlotPortals<LAnnotation>\n managedContentStore={slotContentStore}\n renderCustomHeader={renderCustomHeader}\n renderHeaderPrefix={renderHeaderPrefix}\n renderHeaderFilenameSuffix={renderHeaderFilenameSuffix}\n renderHeaderMetadata={renderHeaderMetadata}\n renderAnnotation={renderAnnotation}\n renderGutterUtility={renderGutterUtility}\n renderCodeViewHeader={renderCodeViewHeader}\n renderCodeViewFooter={renderCodeViewFooter}\n />\n )}\n </>\n );\n}\n\n// React was a mistake\nexport const CodeView = forwardRef(CodeViewInner) as CodeViewComponent;\n\nfunction isAppendOnlyItemUpdate<LAnnotation>(\n previousItems: readonly CodeViewItem<LAnnotation>[] | undefined,\n nextItems: readonly CodeViewItem<LAnnotation>[]\n): previousItems is readonly CodeViewItem<LAnnotation>[] {\n if (previousItems == null || nextItems.length <= previousItems.length) {\n return false;\n }\n\n if (previousItems.length === 0) {\n return true;\n }\n\n for (let index = 0; index < previousItems.length; index++) {\n if (nextItems[index] !== previousItems[index]) {\n return false;\n }\n }\n\n return true;\n}\n\nfunction areItemListsEqual<LAnnotation>(\n previousItems: readonly CodeViewItem<LAnnotation>[] | undefined,\n nextItems: readonly CodeViewItem<LAnnotation>[]\n): boolean {\n if (previousItems == null || previousItems.length !== nextItems.length) {\n return false;\n }\n\n for (let index = 0; index < previousItems.length; index++) {\n if (previousItems[index] !== nextItems[index]) {\n return false;\n }\n }\n\n return true;\n}\n\nfunction assertUncontrolledCodeViewAction(\n controlled: boolean,\n action: string\n): void {\n if (!controlled) {\n return;\n }\n\n throw new Error(\n `CodeView.${action} cannot be used when CodeView is controlled. Use initialItems for imperative item updates.`\n );\n}\n\nfunction createSlotContentStore<\n LAnnotation,\n>(): ManagedContentStore<LAnnotation> {\n let snapshot: CodeViewSlotSnapshot<LAnnotation> | undefined;\n const listeners = new Set<() => void>();\n\n return {\n getSnapshot() {\n return snapshot;\n },\n publish(nextSnapshot) {\n if (areManagedSnapshotsEqual(snapshot, nextSnapshot)) {\n return;\n }\n\n snapshot = nextSnapshot;\n for (const listener of listeners) {\n listener();\n }\n },\n subscribe(listener) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n };\n}\n\ninterface CreateManagedCodeViewOptionsProps<LAnnotation> {\n options: CodeViewOptions<LAnnotation> | undefined;\n hasCustomHeader: boolean;\n hasGutterRenderer: boolean;\n hasCodeViewHeader: boolean;\n hasCodeViewFooter: boolean;\n onSelectedLinesChange?(selection: CodeViewLineSelection | null): void;\n controlledSelection: boolean;\n createEditor: CodeViewOptions<LAnnotation>['createEditor'];\n onItemEditChange: CodeViewOptions<LAnnotation>['onItemEditChange'];\n onItemEditComplete: CodeViewOptions<LAnnotation>['onItemEditComplete'];\n}\n\nfunction createManagedCodeViewOptions<LAnnotation>({\n options,\n hasCustomHeader,\n hasGutterRenderer,\n hasCodeViewHeader,\n hasCodeViewFooter,\n onSelectedLinesChange,\n controlledSelection,\n createEditor,\n onItemEditChange,\n onItemEditComplete,\n}: CreateManagedCodeViewOptionsProps<LAnnotation>):\n | CodeViewOptions<LAnnotation>\n | undefined {\n if (\n !hasCustomHeader &&\n !hasGutterRenderer &&\n !hasCodeViewHeader &&\n !hasCodeViewFooter &&\n onSelectedLinesChange == null &&\n !controlledSelection &&\n createEditor == null &&\n onItemEditChange == null &&\n onItemEditComplete == null\n ) {\n return options ?? {};\n }\n options = { ...options, controlledSelection, onSelectedLinesChange };\n\n // Prop-level editor callbacks win over their options-object counterparts,\n // but an absent prop must not clobber a value provided via `options`.\n if (createEditor != null) {\n options.createEditor = createEditor;\n }\n if (onItemEditChange != null) {\n options.onItemEditChange = onItemEditChange;\n }\n if (onItemEditComplete != null) {\n options.onItemEditComplete = onItemEditComplete;\n }\n\n // The imperative CodeView adapters use this callback's presence to\n // switch file and diff headers into custom-slot mode. React portals\n // provide the actual header content, so this placeholder\n // intentionally returns nothing.\n if (hasCustomHeader) {\n options.renderCustomHeader = noopRender;\n }\n\n // The imperative CodeView adapters use this callback's presence to\n // create the custom gutter utility slot. React portals provide the\n // actual content, so this placeholder intentionally returns nothing.\n if (hasGutterRenderer) {\n options.renderGutterUtility = noopRender;\n }\n\n // The imperative CodeView adapters use these callbacks' presence to create the\n // header/footer host elements. React portals the actual content into them (via\n // the slot snapshot), so these placeholders intentionally return nothing.\n if (hasCodeViewHeader) {\n options.renderCodeViewHeader = noopRender;\n }\n if (hasCodeViewFooter) {\n options.renderCodeViewFooter = noopRender;\n }\n\n return options;\n}\n\ninterface RenderCodeViewItemChildrenProps<LAnnotation> {\n renderedItem: CodeViewRenderedItem<LAnnotation>;\n renderCustomHeader: CodeViewBaseProps<LAnnotation>['renderCustomHeader'];\n renderHeaderPrefix: CodeViewBaseProps<LAnnotation>['renderHeaderPrefix'];\n renderHeaderFilenameSuffix: CodeViewBaseProps<LAnnotation>['renderHeaderFilenameSuffix'];\n renderHeaderMetadata: CodeViewBaseProps<LAnnotation>['renderHeaderMetadata'];\n renderAnnotation: CodeViewBaseProps<LAnnotation>['renderAnnotation'];\n renderGutterUtility: CodeViewBaseProps<LAnnotation>['renderGutterUtility'];\n}\n\ninterface SlotPortalsProps<LAnnotation> {\n managedContentStore: ManagedContentStore<LAnnotation>;\n renderCustomHeader: CodeViewBaseProps<LAnnotation>['renderCustomHeader'];\n renderHeaderPrefix: CodeViewBaseProps<LAnnotation>['renderHeaderPrefix'];\n renderHeaderFilenameSuffix: CodeViewBaseProps<LAnnotation>['renderHeaderFilenameSuffix'];\n renderHeaderMetadata: CodeViewBaseProps<LAnnotation>['renderHeaderMetadata'];\n renderAnnotation: CodeViewBaseProps<LAnnotation>['renderAnnotation'];\n renderGutterUtility: CodeViewBaseProps<LAnnotation>['renderGutterUtility'];\n renderCodeViewHeader: CodeViewBaseProps<LAnnotation>['renderCodeViewHeader'];\n renderCodeViewFooter: CodeViewBaseProps<LAnnotation>['renderCodeViewFooter'];\n}\n\nconst SlotPortals = memo(function SlotPortals<LAnnotation>({\n managedContentStore,\n renderCustomHeader,\n renderHeaderPrefix,\n renderHeaderFilenameSuffix,\n renderHeaderMetadata,\n renderAnnotation,\n renderGutterUtility,\n renderCodeViewHeader,\n renderCodeViewFooter,\n}: SlotPortalsProps<LAnnotation>) {\n 'use no memo';\n const subscribe = useStableCallback((listener: () => void) =>\n managedContentStore.subscribe(listener)\n );\n const getSnapshot = useStableCallback(() =>\n managedContentStore.getSnapshot()\n );\n const snapshot = useSyncExternalStore<\n CodeViewSlotSnapshot<LAnnotation> | undefined\n >(subscribe, getSnapshot, getSnapshot);\n let itemKeys = '';\n for (const item of snapshot?.items ?? []) {\n itemKeys += `${item.id}:${item.version}:${item.type}`;\n }\n // NOTE(amadeus): And just like that, the react compiler do be failing us\n // lol... we need to pre-render everything for items, headers and footers to\n // not trigger needless renders while scrolling\n const renderedItems = useMemo(\n () => {\n return snapshot?.items?.map((renderedItem) =>\n createPortal(\n renderCodeViewItemChildren({\n renderedItem,\n renderCustomHeader,\n renderHeaderPrefix,\n renderHeaderFilenameSuffix,\n renderHeaderMetadata,\n renderAnnotation,\n renderGutterUtility,\n }),\n renderedItem.element,\n renderedItem.id\n )\n );\n },\n // oxlint-disable-next-line react-hooks/exhaustive-deps\n [\n renderCustomHeader,\n renderHeaderPrefix,\n renderHeaderFilenameSuffix,\n renderHeaderMetadata,\n renderAnnotation,\n renderGutterUtility,\n itemKeys,\n ]\n );\n const renderedHeader = useMemo(() => {\n return renderCodeViewHeader != null && snapshot?.header != null\n ? createPortal(renderCodeViewHeader(), snapshot.header)\n : null;\n }, [renderCodeViewHeader, snapshot?.header]);\n const renderedFooter = useMemo(() => {\n return renderCodeViewFooter != null && snapshot?.footer != null\n ? createPortal(renderCodeViewFooter(), snapshot.footer)\n : null;\n }, [renderCodeViewFooter, snapshot?.footer]);\n return (\n <>\n {renderedItems}\n {renderedHeader}\n {renderedFooter}\n </>\n );\n}) as SlotPortalsComponent;\n\nfunction renderCodeViewItemChildren<LAnnotation>({\n renderedItem,\n renderCustomHeader,\n renderHeaderPrefix,\n renderHeaderFilenameSuffix,\n renderHeaderMetadata,\n renderAnnotation,\n renderGutterUtility,\n}: RenderCodeViewItemChildrenProps<LAnnotation>): ReactNode {\n if (renderedItem.type === 'diff') {\n const { item, instance } = renderedItem;\n return renderDiffChildren({\n fileDiff: item.fileDiff,\n renderCustomHeader:\n renderCustomHeader != null ? () => renderCustomHeader(item) : undefined,\n renderHeaderPrefix:\n renderHeaderPrefix != null ? () => renderHeaderPrefix(item) : undefined,\n renderHeaderFilenameSuffix:\n renderHeaderFilenameSuffix != null\n ? () => renderHeaderFilenameSuffix(item)\n : undefined,\n renderHeaderMetadata:\n renderHeaderMetadata != null\n ? () => renderHeaderMetadata(item)\n : undefined,\n renderAnnotation:\n renderAnnotation != null\n ? (annotation) => renderAnnotation(annotation, item)\n : undefined,\n lineAnnotations: item.annotations,\n renderGutterUtility:\n renderGutterUtility != null\n ? (getHoveredLine) => renderGutterUtility(getHoveredLine, item)\n : undefined,\n getHoveredLine: instance.getHoveredLine,\n });\n } else {\n const { item, instance } = renderedItem;\n return renderFileChildren({\n file: item.file,\n renderCustomHeader:\n renderCustomHeader != null ? () => renderCustomHeader(item) : undefined,\n renderHeaderPrefix:\n renderHeaderPrefix != null ? () => renderHeaderPrefix(item) : undefined,\n renderHeaderFilenameSuffix:\n renderHeaderFilenameSuffix != null\n ? () => renderHeaderFilenameSuffix(item)\n : undefined,\n renderHeaderMetadata:\n renderHeaderMetadata != null\n ? () => renderHeaderMetadata(item)\n : undefined,\n renderAnnotation:\n renderAnnotation != null\n ? (annotation) => renderAnnotation(annotation, item)\n : undefined,\n lineAnnotations: item.annotations,\n renderGutterUtility:\n renderGutterUtility != null\n ? (getHoveredLine) => renderGutterUtility(getHoveredLine, item)\n : undefined,\n getHoveredLine: instance.getHoveredLine,\n });\n }\n}\n\nfunction noopRender() {\n return undefined;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Editor } from "../editor/editor.js";
|
|
2
|
+
import { Context, PropsWithChildren } from "react";
|
|
3
|
+
|
|
4
|
+
//#region src/react/EditContext.d.ts
|
|
5
|
+
declare const EditContext: Context<Editor<any> | undefined>;
|
|
6
|
+
declare function EditProvider({
|
|
7
|
+
children,
|
|
8
|
+
editor
|
|
9
|
+
}: PropsWithChildren<{
|
|
10
|
+
editor: Editor<any>;
|
|
11
|
+
}>): React.JSX.Element;
|
|
12
|
+
declare function useEditor<LAnnotation>(): Editor<LAnnotation> | undefined;
|
|
13
|
+
//#endregion
|
|
14
|
+
export { EditContext, EditProvider, useEditor };
|
|
15
|
+
//# sourceMappingURL=EditContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EditContext.d.ts","names":[],"sources":["../../src/react/EditContext.tsx"],"mappings":";;;;cAQa,WAAA,EAAa,OAAO,CAAC,MAAA;AAAA,iBAIlB,YAAA;EACd,QAAA;EACA;AAAA,GACC,iBAAA;EAAoB,MAAA,EAAQ,MAAA;AAAA,KAAiB,KAAA,CAAM,GAAA,CAAI,OAAA;AAAA,iBAS1C,SAAA,iBAA0B,MAAM,CAAC,WAAA"}
|