@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.
Files changed (288) hide show
  1. package/dist/components/CodeView.d.ts +91 -6
  2. package/dist/components/CodeView.d.ts.map +1 -1
  3. package/dist/components/CodeView.js +300 -38
  4. package/dist/components/CodeView.js.map +1 -1
  5. package/dist/components/File.d.ts +14 -3
  6. package/dist/components/File.d.ts.map +1 -1
  7. package/dist/components/File.js +98 -12
  8. package/dist/components/File.js.map +1 -1
  9. package/dist/components/FileDiff.d.ts +68 -19
  10. package/dist/components/FileDiff.d.ts.map +1 -1
  11. package/dist/components/FileDiff.js +363 -25
  12. package/dist/components/FileDiff.js.map +1 -1
  13. package/dist/components/FileStream.d.ts.map +1 -1
  14. package/dist/components/FileStream.js +2 -1
  15. package/dist/components/FileStream.js.map +1 -1
  16. package/dist/components/UnresolvedFile.d.ts +2 -2
  17. package/dist/components/UnresolvedFile.d.ts.map +1 -1
  18. package/dist/components/UnresolvedFile.js +2 -2
  19. package/dist/components/UnresolvedFile.js.map +1 -1
  20. package/dist/components/VirtualizedFile.d.ts +4 -2
  21. package/dist/components/VirtualizedFile.d.ts.map +1 -1
  22. package/dist/components/VirtualizedFile.js +59 -47
  23. package/dist/components/VirtualizedFile.js.map +1 -1
  24. package/dist/components/VirtualizedFileDiff.d.ts +27 -5
  25. package/dist/components/VirtualizedFileDiff.d.ts.map +1 -1
  26. package/dist/components/VirtualizedFileDiff.js +262 -56
  27. package/dist/components/VirtualizedFileDiff.js.map +1 -1
  28. package/dist/components/Virtualizer.d.ts +4 -1
  29. package/dist/components/Virtualizer.d.ts.map +1 -1
  30. package/dist/components/Virtualizer.js +21 -4
  31. package/dist/components/Virtualizer.js.map +1 -1
  32. package/dist/constants.d.ts +4 -1
  33. package/dist/constants.d.ts.map +1 -1
  34. package/dist/constants.js +4 -1
  35. package/dist/constants.js.map +1 -1
  36. package/dist/editor/command.d.ts +7 -0
  37. package/dist/editor/command.d.ts.map +1 -0
  38. package/dist/editor/command.js +54 -0
  39. package/dist/editor/command.js.map +1 -0
  40. package/dist/editor/editStack.d.ts +71 -0
  41. package/dist/editor/editStack.d.ts.map +1 -0
  42. package/dist/editor/editStack.js +218 -0
  43. package/dist/editor/editStack.js.map +1 -0
  44. package/dist/editor/editor.d.ts +105 -0
  45. package/dist/editor/editor.d.ts.map +1 -0
  46. package/dist/editor/editor.js +2545 -0
  47. package/dist/editor/editor.js.map +1 -0
  48. package/dist/editor/editor2.js +6 -0
  49. package/dist/editor/editor2.js.map +1 -0
  50. package/dist/editor/index.d.ts +5 -0
  51. package/dist/editor/index.js +3 -0
  52. package/dist/editor/languages.d.ts +26 -0
  53. package/dist/editor/languages.d.ts.map +1 -0
  54. package/dist/editor/languages.js +363 -0
  55. package/dist/editor/languages.js.map +1 -0
  56. package/dist/editor/lineAnnotations.d.ts +9 -0
  57. package/dist/editor/lineAnnotations.d.ts.map +1 -0
  58. package/dist/editor/lineAnnotations.js +212 -0
  59. package/dist/editor/lineAnnotations.js.map +1 -0
  60. package/dist/editor/marker.d.ts +38 -0
  61. package/dist/editor/marker.d.ts.map +1 -0
  62. package/dist/editor/marker.js +245 -0
  63. package/dist/editor/marker.js.map +1 -0
  64. package/dist/editor/matchBrackets.d.ts +9 -0
  65. package/dist/editor/matchBrackets.d.ts.map +1 -0
  66. package/dist/editor/matchBrackets.js +138 -0
  67. package/dist/editor/matchBrackets.js.map +1 -0
  68. package/dist/editor/pieceTable.d.ts +41 -0
  69. package/dist/editor/pieceTable.d.ts.map +1 -0
  70. package/dist/editor/pieceTable.js +671 -0
  71. package/dist/editor/pieceTable.js.map +1 -0
  72. package/dist/editor/platform.d.ts +19 -0
  73. package/dist/editor/platform.d.ts.map +1 -0
  74. package/dist/editor/platform.js +57 -0
  75. package/dist/editor/platform.js.map +1 -0
  76. package/dist/editor/popover.d.ts +65 -0
  77. package/dist/editor/popover.d.ts.map +1 -0
  78. package/dist/editor/popover.js +187 -0
  79. package/dist/editor/popover.js.map +1 -0
  80. package/dist/editor/searchPanel.d.ts +40 -0
  81. package/dist/editor/searchPanel.d.ts.map +1 -0
  82. package/dist/editor/searchPanel.js +318 -0
  83. package/dist/editor/searchPanel.js.map +1 -0
  84. package/dist/editor/selection.d.ts +211 -0
  85. package/dist/editor/selection.d.ts.map +1 -0
  86. package/dist/editor/selection.js +1626 -0
  87. package/dist/editor/selection.js.map +1 -0
  88. package/dist/editor/selectionAction.d.ts +46 -0
  89. package/dist/editor/selectionAction.d.ts.map +1 -0
  90. package/dist/editor/selectionAction.js +64 -0
  91. package/dist/editor/selectionAction.js.map +1 -0
  92. package/dist/editor/sprite.d.ts +8 -0
  93. package/dist/editor/sprite.d.ts.map +1 -0
  94. package/dist/editor/sprite.js +45 -0
  95. package/dist/editor/sprite.js.map +1 -0
  96. package/dist/editor/stateStorage.d.ts +15 -0
  97. package/dist/editor/stateStorage.d.ts.map +1 -0
  98. package/dist/editor/stateStorage.js +65 -0
  99. package/dist/editor/stateStorage.js.map +1 -0
  100. package/dist/editor/textDocument.d.ts +77 -0
  101. package/dist/editor/textDocument.d.ts.map +1 -0
  102. package/dist/editor/textDocument.js +271 -0
  103. package/dist/editor/textDocument.js.map +1 -0
  104. package/dist/editor/textMeasure.d.ts +61 -0
  105. package/dist/editor/textMeasure.d.ts.map +1 -0
  106. package/dist/editor/textMeasure.js +209 -0
  107. package/dist/editor/textMeasure.js.map +1 -0
  108. package/dist/editor/tokenizer.d.ts +41 -0
  109. package/dist/editor/tokenizer.d.ts.map +1 -0
  110. package/dist/editor/tokenizer.js +513 -0
  111. package/dist/editor/tokenizer.js.map +1 -0
  112. package/dist/editor/utils.d.ts +21 -0
  113. package/dist/editor/utils.d.ts.map +1 -0
  114. package/dist/editor/utils.js +68 -0
  115. package/dist/editor/utils.js.map +1 -0
  116. package/dist/index.d.ts +10 -8
  117. package/dist/index.js +12 -10
  118. package/dist/managers/InteractionManager.d.ts +7 -0
  119. package/dist/managers/InteractionManager.d.ts.map +1 -1
  120. package/dist/managers/InteractionManager.js +22 -1
  121. package/dist/managers/InteractionManager.js.map +1 -1
  122. package/dist/managers/ResizeManager.d.ts +10 -2
  123. package/dist/managers/ResizeManager.d.ts.map +1 -1
  124. package/dist/managers/ResizeManager.js +33 -13
  125. package/dist/managers/ResizeManager.js.map +1 -1
  126. package/dist/managers/UniversalRenderingManager.d.ts +2 -1
  127. package/dist/managers/UniversalRenderingManager.d.ts.map +1 -1
  128. package/dist/managers/UniversalRenderingManager.js +6 -1
  129. package/dist/managers/UniversalRenderingManager.js.map +1 -1
  130. package/dist/react/CodeView.d.ts +26 -1
  131. package/dist/react/CodeView.d.ts.map +1 -1
  132. package/dist/react/CodeView.js +82 -19
  133. package/dist/react/CodeView.js.map +1 -1
  134. package/dist/react/EditContext.d.ts +15 -0
  135. package/dist/react/EditContext.d.ts.map +1 -0
  136. package/dist/react/EditContext.js +23 -0
  137. package/dist/react/EditContext.js.map +1 -0
  138. package/dist/react/File.d.ts +3 -1
  139. package/dist/react/File.d.ts.map +1 -1
  140. package/dist/react/File.js +4 -2
  141. package/dist/react/File.js.map +1 -1
  142. package/dist/react/FileDiff.d.ts +4 -1
  143. package/dist/react/FileDiff.d.ts.map +1 -1
  144. package/dist/react/FileDiff.js +4 -2
  145. package/dist/react/FileDiff.js.map +1 -1
  146. package/dist/react/MultiFileDiff.d.ts +7 -5
  147. package/dist/react/MultiFileDiff.d.ts.map +1 -1
  148. package/dist/react/MultiFileDiff.js +4 -2
  149. package/dist/react/MultiFileDiff.js.map +1 -1
  150. package/dist/react/PatchDiff.d.ts +4 -1
  151. package/dist/react/PatchDiff.d.ts.map +1 -1
  152. package/dist/react/PatchDiff.js +4 -2
  153. package/dist/react/PatchDiff.js.map +1 -1
  154. package/dist/react/UnresolvedFile.d.ts +1 -0
  155. package/dist/react/UnresolvedFile.d.ts.map +1 -1
  156. package/dist/react/UnresolvedFile.js +2 -1
  157. package/dist/react/UnresolvedFile.js.map +1 -1
  158. package/dist/react/index.d.ts +3 -2
  159. package/dist/react/index.js +2 -1
  160. package/dist/react/types.d.ts +3 -0
  161. package/dist/react/types.d.ts.map +1 -1
  162. package/dist/react/utils/renderDiffChildren.d.ts +2 -0
  163. package/dist/react/utils/renderDiffChildren.d.ts.map +1 -1
  164. package/dist/react/utils/renderDiffChildren.js +16 -8
  165. package/dist/react/utils/renderDiffChildren.js.map +1 -1
  166. package/dist/react/utils/renderFileChildren.d.ts +2 -0
  167. package/dist/react/utils/renderFileChildren.d.ts.map +1 -1
  168. package/dist/react/utils/renderFileChildren.js +16 -8
  169. package/dist/react/utils/renderFileChildren.js.map +1 -1
  170. package/dist/react/utils/useFileDiffInstance.d.ts +3 -1
  171. package/dist/react/utils/useFileDiffInstance.d.ts.map +1 -1
  172. package/dist/react/utils/useFileDiffInstance.js +30 -6
  173. package/dist/react/utils/useFileDiffInstance.js.map +1 -1
  174. package/dist/react/utils/useFileInstance.d.ts +4 -1
  175. package/dist/react/utils/useFileInstance.d.ts.map +1 -1
  176. package/dist/react/utils/useFileInstance.js +30 -5
  177. package/dist/react/utils/useFileInstance.js.map +1 -1
  178. package/dist/renderers/DiffHunksRenderer.d.ts +28 -2
  179. package/dist/renderers/DiffHunksRenderer.d.ts.map +1 -1
  180. package/dist/renderers/DiffHunksRenderer.js +244 -22
  181. package/dist/renderers/DiffHunksRenderer.js.map +1 -1
  182. package/dist/renderers/FileRenderer.d.ts +8 -1
  183. package/dist/renderers/FileRenderer.d.ts.map +1 -1
  184. package/dist/renderers/FileRenderer.js +155 -45
  185. package/dist/renderers/FileRenderer.js.map +1 -1
  186. package/dist/ssr/index.d.ts +2 -2
  187. package/dist/ssr/preloadDiffs.d.ts +11 -10
  188. package/dist/ssr/preloadDiffs.d.ts.map +1 -1
  189. package/dist/ssr/preloadDiffs.js +15 -7
  190. package/dist/ssr/preloadDiffs.js.map +1 -1
  191. package/dist/style.js +1 -1
  192. package/dist/types.d.ts +282 -5
  193. package/dist/types.d.ts.map +1 -1
  194. package/dist/utils/applyLineTextWithNewline.d.ts +5 -0
  195. package/dist/utils/applyLineTextWithNewline.d.ts.map +1 -0
  196. package/dist/utils/applyLineTextWithNewline.js +11 -0
  197. package/dist/utils/applyLineTextWithNewline.js.map +1 -0
  198. package/dist/utils/areHunkDataEqual.js +1 -1
  199. package/dist/utils/areHunkDataEqual.js.map +1 -1
  200. package/dist/utils/areManagedSnapshotsEqual.d.ts +2 -2
  201. package/dist/utils/areManagedSnapshotsEqual.d.ts.map +1 -1
  202. package/dist/utils/areManagedSnapshotsEqual.js +5 -0
  203. package/dist/utils/areManagedSnapshotsEqual.js.map +1 -1
  204. package/dist/utils/awaitWithTimeout.d.ts +5 -0
  205. package/dist/utils/awaitWithTimeout.d.ts.map +1 -0
  206. package/dist/utils/awaitWithTimeout.js +15 -0
  207. package/dist/utils/awaitWithTimeout.js.map +1 -0
  208. package/dist/utils/cleanLastNewline.js +6 -1
  209. package/dist/utils/cleanLastNewline.js.map +1 -1
  210. package/dist/utils/cloneFileDiffMetadata.d.ts +7 -0
  211. package/dist/utils/cloneFileDiffMetadata.d.ts.map +1 -0
  212. package/dist/utils/cloneFileDiffMetadata.js +16 -0
  213. package/dist/utils/cloneFileDiffMetadata.js.map +1 -0
  214. package/dist/utils/computeEstimatedDiffHeights.d.ts +3 -1
  215. package/dist/utils/computeEstimatedDiffHeights.d.ts.map +1 -1
  216. package/dist/utils/computeEstimatedDiffHeights.js +8 -1
  217. package/dist/utils/computeEstimatedDiffHeights.js.map +1 -1
  218. package/dist/utils/computeFileOffsets.d.ts +21 -0
  219. package/dist/utils/computeFileOffsets.d.ts.map +1 -0
  220. package/dist/utils/computeFileOffsets.js +51 -0
  221. package/dist/utils/computeFileOffsets.js.map +1 -0
  222. package/dist/utils/createCodeViewHeaderFooterHostElement.d.ts +5 -0
  223. package/dist/utils/createCodeViewHeaderFooterHostElement.d.ts.map +1 -0
  224. package/dist/utils/createCodeViewHeaderFooterHostElement.js +19 -0
  225. package/dist/utils/createCodeViewHeaderFooterHostElement.js.map +1 -0
  226. package/dist/utils/createFileHeaderElement.d.ts.map +1 -1
  227. package/dist/utils/createFileHeaderElement.js +5 -1
  228. package/dist/utils/createFileHeaderElement.js.map +1 -1
  229. package/dist/utils/createTransformerWithState.js +9 -0
  230. package/dist/utils/createTransformerWithState.js.map +1 -1
  231. package/dist/utils/editSessionHunks.d.ts +84 -0
  232. package/dist/utils/editSessionHunks.d.ts.map +1 -0
  233. package/dist/utils/editSessionHunks.js +366 -0
  234. package/dist/utils/editSessionHunks.js.map +1 -0
  235. package/dist/utils/getDiffFileInput.d.ts +14 -0
  236. package/dist/utils/getDiffFileInput.d.ts.map +1 -0
  237. package/dist/utils/getDiffFileInput.js +24 -0
  238. package/dist/utils/getDiffFileInput.js.map +1 -0
  239. package/dist/utils/getDiffHunksRendererOptions.js +1 -0
  240. package/dist/utils/getDiffHunksRendererOptions.js.map +1 -1
  241. package/dist/utils/getFiletypeFromFileName.d.ts.map +1 -1
  242. package/dist/utils/getFiletypeFromFileName.js +2 -0
  243. package/dist/utils/getFiletypeFromFileName.js.map +1 -1
  244. package/dist/utils/hydratePartialDiff.d.ts +10 -0
  245. package/dist/utils/hydratePartialDiff.d.ts.map +1 -0
  246. package/dist/utils/hydratePartialDiff.js +140 -0
  247. package/dist/utils/hydratePartialDiff.js.map +1 -0
  248. package/dist/utils/iterateOverDiff.js +3 -3
  249. package/dist/utils/iterateOverDiff.js.map +1 -1
  250. package/dist/utils/parseDiffFromFile.d.ts +1 -1
  251. package/dist/utils/parseDiffFromFile.d.ts.map +1 -1
  252. package/dist/utils/parseDiffFromFile.js +26 -5
  253. package/dist/utils/parseDiffFromFile.js.map +1 -1
  254. package/dist/utils/parsePatchFiles.d.ts.map +1 -1
  255. package/dist/utils/parsePatchFiles.js +2 -0
  256. package/dist/utils/parsePatchFiles.js.map +1 -1
  257. package/dist/utils/realignChangeContent.d.ts +28 -0
  258. package/dist/utils/realignChangeContent.d.ts.map +1 -0
  259. package/dist/utils/realignChangeContent.js +142 -0
  260. package/dist/utils/realignChangeContent.js.map +1 -0
  261. package/dist/utils/renderDiffWithHighlighter.js +1 -1
  262. package/dist/utils/renderFileWithHighlighter.d.ts.map +1 -1
  263. package/dist/utils/renderFileWithHighlighter.js +5 -14
  264. package/dist/utils/renderFileWithHighlighter.js.map +1 -1
  265. package/dist/utils/updateDiffHunks.d.ts +24 -0
  266. package/dist/utils/updateDiffHunks.d.ts.map +1 -0
  267. package/dist/utils/updateDiffHunks.js +235 -0
  268. package/dist/utils/updateDiffHunks.js.map +1 -0
  269. package/dist/utils/virtualDiffLayout.d.ts +40 -1
  270. package/dist/utils/virtualDiffLayout.d.ts.map +1 -1
  271. package/dist/utils/virtualDiffLayout.js +96 -1
  272. package/dist/utils/virtualDiffLayout.js.map +1 -1
  273. package/dist/worker/WorkerPoolManager.d.ts +7 -2
  274. package/dist/worker/WorkerPoolManager.d.ts.map +1 -1
  275. package/dist/worker/WorkerPoolManager.js +83 -18
  276. package/dist/worker/WorkerPoolManager.js.map +1 -1
  277. package/dist/worker/index.d.ts +2 -2
  278. package/dist/worker/types.d.ts +11 -1
  279. package/dist/worker/types.d.ts.map +1 -1
  280. package/dist/worker/worker-portable.js +46 -66
  281. package/dist/worker/worker-portable.js.map +1 -1
  282. package/dist/worker/worker.js +46 -66
  283. package/dist/worker/worker.js.map +1 -1
  284. package/package.json +12 -5
  285. package/dist/utils/iterateOverFile.d.ts +0 -50
  286. package/dist/utils/iterateOverFile.d.ts.map +0 -1
  287. package/dist/utils/iterateOverFile.js +0 -49
  288. package/dist/utils/iterateOverFile.js.map +0 -1
@@ -1,10 +1,13 @@
1
1
  import { DEFAULT_CODE_VIEW_FILE_METRICS, DEFAULT_CODE_VIEW_LAYOUT, DEFAULT_SMOOTH_SCROLL_SETTINGS, DEFAULT_THEMES, DIFFS_DEVELOPMENT_BUILD, DIFFS_TAG_NAME } from "../constants.js";
2
2
  import { dequeueRender, queueRender } from "../managers/UniversalRenderingManager.js";
3
+ import { areManagedSnapshotsEqual } from "../utils/areManagedSnapshotsEqual.js";
3
4
  import { areObjectsEqual } from "../utils/areObjectsEqual.js";
4
5
  import { areThemesEqual } from "../utils/areThemesEqual.js";
5
6
  import { areOptionsEqual } from "../utils/areOptionsEqual.js";
6
7
  import { areSelectionsEqual } from "../utils/areSelectionsEqual.js";
8
+ import { createCodeViewHeaderFooterHostElement } from "../utils/createCodeViewHeaderFooterHostElement.js";
7
9
  import { createWindowFromScrollPosition } from "../utils/createWindowFromScrollPosition.js";
10
+ import { finishEditSessionForDiff } from "../utils/editSessionHunks.js";
8
11
  import { isStyleNode } from "../utils/isStyleNode.js";
9
12
  import { prefersReducedMotion } from "../utils/prefersReducedMotion.js";
10
13
  import { roundToDevicePixel } from "../utils/roundToDevicePixel.js";
@@ -28,6 +31,7 @@ const CODE_VIEW_DIFF_OPTION_KEYS = [
28
31
  "diffIndicators",
29
32
  "disableBackground",
30
33
  "expandUnchanged",
34
+ "loadDiffFiles",
31
35
  "collapsedContextThreshold",
32
36
  "lineDiffType",
33
37
  "maxLineDiffLength",
@@ -61,9 +65,16 @@ const CODE_VIEW_FILE_OPTION_KEYS = [
61
65
  "controlledSelection",
62
66
  "disableErrorHandling"
63
67
  ];
68
+ const CODE_VIEW_EDIT_FORCED_OPTION_KEYS = /* @__PURE__ */ new Set([
69
+ "useTokenTransformer",
70
+ "enableGutterUtility",
71
+ "enableLineSelection",
72
+ "lineHoverHighlight"
73
+ ]);
64
74
  const CODE_VIEW_SHARED_CALLBACK_KEYS = [
65
75
  "renderCustomHeader",
66
76
  "renderHeaderPrefix",
77
+ "renderHeaderFilenameSuffix",
67
78
  "renderHeaderMetadata",
68
79
  "renderAnnotation",
69
80
  "renderGutterUtility",
@@ -129,6 +140,8 @@ var CodeView = class CodeView {
129
140
  items = [];
130
141
  idToItem = /* @__PURE__ */ new Map();
131
142
  selectedLines = null;
143
+ itemEditors = /* @__PURE__ */ new Map();
144
+ attachedEditors = /* @__PURE__ */ new Set();
132
145
  instanceToItem = /* @__PURE__ */ new Map();
133
146
  layoutDirtyIndex;
134
147
  pendingLayoutReset;
@@ -170,12 +183,23 @@ var CodeView = class CodeView {
170
183
  container = document.createElement("div");
171
184
  stickyContainer = document.createElement("div");
172
185
  stickyOffset = document.createElement("div");
186
+ header = {
187
+ element: void 0,
188
+ render: void 0,
189
+ height: 0
190
+ };
191
+ footer = {
192
+ element: void 0,
193
+ render: void 0,
194
+ height: 0
195
+ };
173
196
  elementPool = [];
174
197
  elementPoolVersion = 0;
175
198
  elementPoolTracker = /* @__PURE__ */ new WeakMap();
176
199
  pendingElementPool = [];
177
200
  options;
178
201
  workerManager;
202
+ isReadySubscription;
179
203
  isContainerManaged;
180
204
  constructor(options = { theme: DEFAULT_THEMES }, workerManager, isContainerManaged = false) {
181
205
  this.options = options;
@@ -195,6 +219,9 @@ var CodeView = class CodeView {
195
219
  getLayout() {
196
220
  return this.options.layout ?? DEFAULT_CODE_VIEW_LAYOUT;
197
221
  }
222
+ getItemTopOffset() {
223
+ return this.getLayout().paddingTop + this.header.height;
224
+ }
198
225
  computeMetricsCache(itemMetrics) {
199
226
  this.itemMetricsCache = {
200
227
  hunkLineCount: itemMetrics?.hunkLineCount ?? DEFAULT_CODE_VIEW_FILE_METRICS.hunkLineCount,
@@ -297,6 +324,43 @@ var CodeView = class CodeView {
297
324
  this.container?.style.setProperty("margin-top", `${paddingTop}px`);
298
325
  this.container?.style.setProperty("margin-bottom", `${paddingBottom}px`);
299
326
  }
327
+ reconcileHeaderFooterHosts() {
328
+ const headerChanged = this.reconcileHost("header");
329
+ const footerChanged = this.reconcileHost("footer");
330
+ return headerChanged || footerChanged;
331
+ }
332
+ reconcileHost(type) {
333
+ const { root, container } = this;
334
+ if (root == null || container == null) return false;
335
+ const host = type === "header" ? this.header : this.footer;
336
+ const render = type === "header" ? this.options.renderCodeViewHeader : this.options.renderCodeViewFooter;
337
+ if (render == null) {
338
+ if (host.element == null) return false;
339
+ this.resizeObserver?.unobserve(host.element);
340
+ host.element.remove();
341
+ host.element = void 0;
342
+ host.render = void 0;
343
+ this.setHostHeight(host, 0);
344
+ return false;
345
+ }
346
+ if (host.element != null && render === host.render) return false;
347
+ const element = host.element ?? createCodeViewHeaderFooterHostElement(type, container, this.resizeObserver);
348
+ host.element = element;
349
+ const content = render();
350
+ if (content != null) element.replaceChildren(content);
351
+ else if (!this.isContainerManaged && element.children.length > 0) element.textContent = "";
352
+ host.render = render;
353
+ return true;
354
+ }
355
+ setHostHeight(host, height) {
356
+ if (host.height === height) return;
357
+ host.height = height;
358
+ this.scrollDirty = true;
359
+ }
360
+ measureMountedHosts() {
361
+ if (this.header.element != null) this.setHostHeight(this.header, this.header.element.getBoundingClientRect().height);
362
+ if (this.footer.element != null) this.setHostHeight(this.footer, this.footer.element.getBoundingClientRect().height);
363
+ }
300
364
  setup(root) {
301
365
  if (this.root != null) throw new Error("CodeView.setup: already setup");
302
366
  this.workerManager?.subscribeToThemeChanges(this);
@@ -336,8 +400,13 @@ var CodeView = class CodeView {
336
400
  };
337
401
  }
338
402
  reset() {
403
+ dequeueRender(this.computeRenderRangeAndEmit);
404
+ this.clearReadySubscription();
339
405
  this.restoreScrollInteractions();
340
406
  this.cleanAllRenderedItems();
407
+ for (const record of this.itemEditors.values()) record.editor.cleanUp();
408
+ this.itemEditors.clear();
409
+ this.attachedEditors.clear();
341
410
  this.selectedLines = null;
342
411
  this.items.length = 0;
343
412
  this.idToItem.clear();
@@ -380,6 +449,14 @@ var CodeView = class CodeView {
380
449
  this.stickyOffset.remove();
381
450
  this.stickyContainer.remove();
382
451
  this.stickyContainer.textContent = "";
452
+ this.header.element?.remove();
453
+ this.header.element = void 0;
454
+ this.header.render = void 0;
455
+ this.header.height = 0;
456
+ this.footer.element?.remove();
457
+ this.footer.element = void 0;
458
+ this.footer.render = void 0;
459
+ this.footer.height = 0;
383
460
  this.root = void 0;
384
461
  this.container = void 0;
385
462
  }
@@ -414,6 +491,7 @@ var CodeView = class CodeView {
414
491
  const { element } = item;
415
492
  if (element != null && this.renderedItemOwnsFocus(element)) this.shouldFixContainerFocus = true;
416
493
  item.instance.cleanUp(true);
494
+ this.attachedEditors.delete(item.item.id);
417
495
  item.element = void 0;
418
496
  if (element == null) return;
419
497
  element.remove();
@@ -506,6 +584,14 @@ var CodeView = class CodeView {
506
584
  getItem(itemId) {
507
585
  return this.idToItem.get(itemId)?.item;
508
586
  }
587
+ /**
588
+ * Get the live editor for an item currently in edit mode. Use this to drive
589
+ * editor APIs CodeView does not wrap (applyEdits, undo, setMarkers, …).
590
+ * Returns undefined once the item leaves edit mode.
591
+ */
592
+ getEditor(itemId) {
593
+ return this.itemEditors.get(itemId)?.editor;
594
+ }
509
595
  updateItem(input) {
510
596
  const item = this.idToItem.get(input.id);
511
597
  if (item == null) {
@@ -517,6 +603,7 @@ var CodeView = class CodeView {
517
603
  this.scrollDirty = true;
518
604
  this.render();
519
605
  this.syncSelection();
606
+ this.syncItemEditors();
520
607
  return true;
521
608
  }
522
609
  updateItemId(oldId, newId) {
@@ -541,6 +628,13 @@ var CodeView = class CodeView {
541
628
  };
542
629
  this.options.onSelectedLinesChange?.(this.selectedLines);
543
630
  }
631
+ const editorRecord = this.itemEditors.get(oldId);
632
+ if (editorRecord != null) {
633
+ editorRecord.state.id = newId;
634
+ this.itemEditors.delete(oldId);
635
+ this.itemEditors.set(newId, editorRecord);
636
+ if (this.attachedEditors.delete(oldId)) this.attachedEditors.add(newId);
637
+ }
544
638
  this.renamePendingScrollTarget(oldId, newId);
545
639
  this.renamePendingLayoutAnchor(oldId, newId);
546
640
  this.render();
@@ -548,17 +642,25 @@ var CodeView = class CodeView {
548
642
  }
549
643
  addItem(input) {
550
644
  this.addItems([input]);
551
- this.syncSelection();
552
645
  }
553
646
  addItems(inputs) {
554
647
  this.appendItemsInternal(inputs);
555
648
  this.syncSelection();
649
+ this.syncItemEditors();
556
650
  }
557
651
  setItems(items) {
558
- if (items.length === 0) this.reset();
559
- else if (this.items.length === 0) this.appendItemsInternal(items);
652
+ if (items.length === 0) {
653
+ const completions = [];
654
+ for (const record of this.itemEditors.values()) {
655
+ const { lastChange } = record.state;
656
+ if (lastChange != null) completions.push(lastChange);
657
+ }
658
+ this.reset();
659
+ for (const { item, file, lineAnnotations } of completions) this.options.onItemEditComplete?.(item, file, lineAnnotations);
660
+ } else if (this.items.length === 0) this.appendItemsInternal(items);
560
661
  else if (!this.tryAppendItems(items)) this.reconcileItems(items);
561
662
  this.syncSelection();
663
+ this.syncItemEditors();
562
664
  }
563
665
  /**
564
666
  * Append new records to the viewer while preserving existing layout state.
@@ -620,7 +722,9 @@ var CodeView = class CodeView {
620
722
  this.scrollDirty = true;
621
723
  }
622
724
  if (!areOptionsEqual(prevOptions, options)) this.renderOptionsRevision++;
623
- if (!this.isContainerManaged && this.items.length > 0) this.render();
725
+ this.syncItemEditors();
726
+ const headerFooterChanged = prevOptions.renderCodeViewHeader !== options.renderCodeViewHeader || prevOptions.renderCodeViewFooter !== options.renderCodeViewFooter;
727
+ if (!this.isContainerManaged && (this.items.length > 0 || headerFooterChanged)) this.render();
624
728
  }
625
729
  capturePendingLayoutAnchor() {
626
730
  if (this.root == null || this.items.length === 0 || this.pendingScrollTarget != null) return;
@@ -633,6 +737,25 @@ var CodeView = class CodeView {
633
737
  this.computeRenderRangeAndEmit();
634
738
  } else queueRender(this.computeRenderRangeAndEmit);
635
739
  }
740
+ isReady() {
741
+ const { workerManager } = this;
742
+ if (workerManager == null || workerManager.isInitialized() || workerManager.getStats().workersFailed) {
743
+ this.clearReadySubscription();
744
+ return true;
745
+ }
746
+ this.isReadySubscription ??= workerManager.subscribeToStatChanges((stats) => {
747
+ if (stats.managerState !== "initialized" && !stats.workersFailed) return;
748
+ this.clearReadySubscription();
749
+ this.render(true);
750
+ });
751
+ if (workerManager.getStats().managerState === "waiting") workerManager.initialize().catch(() => {});
752
+ return false;
753
+ }
754
+ clearReadySubscription() {
755
+ if (this.isReadySubscription == null) return;
756
+ this.isReadySubscription();
757
+ this.isReadySubscription = void 0;
758
+ }
636
759
  instanceChanged(instance, layoutDirty) {
637
760
  const item = this.instanceToItem.get(instance);
638
761
  if (item == null) throw new Error("CodeView.instanceChanged: An instance has changed that is not registered");
@@ -645,6 +768,12 @@ var CodeView = class CodeView {
645
768
  getContainerElement() {
646
769
  return this.root;
647
770
  }
771
+ getHeaderElement() {
772
+ return this.header.element;
773
+ }
774
+ getFooterElement() {
775
+ return this.footer.element;
776
+ }
648
777
  getRenderedItems() {
649
778
  const { firstIndex, lastIndex } = this.renderState;
650
779
  if (firstIndex === -1 || lastIndex === -1 || lastIndex < firstIndex) return [];
@@ -678,7 +807,18 @@ var CodeView = class CodeView {
678
807
  return true;
679
808
  }
680
809
  getSlotSnapshot(coordinator) {
681
- return getSlotSnapshot(this.getRenderedItems(), coordinator);
810
+ return this.buildSlotSnapshot(coordinator);
811
+ }
812
+ buildSlotSnapshot(coordinator) {
813
+ const items = getSlotItems(this.getRenderedItems(), coordinator);
814
+ const { element: header } = this.header;
815
+ const { element: footer } = this.footer;
816
+ if (items == null && header == null && footer == null) return;
817
+ return {
818
+ items,
819
+ header,
820
+ footer
821
+ };
682
822
  }
683
823
  subscribeToScroll(listener) {
684
824
  this.scrollListeners.add(listener);
@@ -694,7 +834,7 @@ var CodeView = class CodeView {
694
834
  getTopForItem(id) {
695
835
  const item = this.idToItem.get(id);
696
836
  if (item == null) return;
697
- return item.top + this.getLayout().paddingTop;
837
+ return item.top + this.getItemTopOffset();
698
838
  }
699
839
  createItem(input, index, top) {
700
840
  const { itemMetricsCache: itemMetrics } = this;
@@ -741,6 +881,83 @@ var CodeView = class CodeView {
741
881
  }
742
882
  item.instance.setSelectedLines(this.selectedLines.range, { notify: false });
743
883
  }
884
+ isItemInEditMode(item) {
885
+ return this.options.createEditor != null && item.item.edit === true && item.item.collapsed !== true;
886
+ }
887
+ isReceiverEdited(receiver, mode) {
888
+ const state = getItemOptionsState(receiver);
889
+ if (state == null) return false;
890
+ const item = this.getItemOptions(state, mode);
891
+ return item != null && this.isItemInEditMode(item);
892
+ }
893
+ /**
894
+ * Attach (or lazily create) the editor for a mounted edit-mode item. Called
895
+ * from the render loop so every mounted item passes through it: fresh
896
+ * mounts, remounts after virtualization released the item, and items whose
897
+ * edit flag was just turned on. Editors persist across unmounts, so a
898
+ * remounted item re-attaches its existing editor and resumes the retained
899
+ * document; the renderers keep the host's file/diff data in sync with the
900
+ * session so the remount paints the edited text.
901
+ */
902
+ attachItemEditor(item) {
903
+ const { id } = item.item;
904
+ const { createEditor } = this.options;
905
+ if (createEditor == null || item.element == null || this.attachedEditors.has(id) || !this.isItemInEditMode(item)) return;
906
+ let record = this.itemEditors.get(id);
907
+ if (record == null) {
908
+ const state = { id };
909
+ const editor = createEditor({ onChange: (file, lineAnnotations) => {
910
+ const latest = this.idToItem.get(state.id);
911
+ if (latest == null) return;
912
+ state.lastChange = {
913
+ item: latest.item,
914
+ file,
915
+ lineAnnotations
916
+ };
917
+ this.options.onItemEditChange?.(latest.item, file, lineAnnotations);
918
+ } });
919
+ if (editor == null) return;
920
+ record = {
921
+ editor,
922
+ state
923
+ };
924
+ this.itemEditors.set(id, record);
925
+ }
926
+ if (this.selectedLines?.id === id) this.applySelectedLines(null, { notify: false });
927
+ record.editor.edit(item.instance);
928
+ this.attachedEditors.add(id);
929
+ }
930
+ /**
931
+ * Drop editors for items that can no longer be edited: removed, edit turned
932
+ * off, collapsed, or the createEditor option was unset. Attachment happens
933
+ * in the render loop via attachItemEditor, so this only reconciles editors
934
+ * CodeView is already holding.
935
+ */
936
+ syncItemEditors() {
937
+ if (this.itemEditors.size === 0) return;
938
+ const completions = [];
939
+ for (const [id, record] of this.itemEditors) {
940
+ const item = this.idToItem.get(id);
941
+ if (item != null && this.isItemInEditMode(item)) continue;
942
+ record.editor.cleanUp();
943
+ this.itemEditors.delete(id);
944
+ this.attachedEditors.delete(id);
945
+ const itemSnapshot = item?.item ?? record.state.lastChange?.item;
946
+ if (itemSnapshot?.type === "diff") {
947
+ if (item != null && item.type === "diff" && item.instance.completeEditSession()) {
948
+ this.markItemLayoutDirty(item);
949
+ this.render();
950
+ }
951
+ finishEditSessionForDiff(itemSnapshot.fileDiff);
952
+ }
953
+ const { lastChange } = record.state;
954
+ if (lastChange != null) completions.push(item == null ? lastChange : {
955
+ ...lastChange,
956
+ item: item.item
957
+ });
958
+ }
959
+ for (const { item, file, lineAnnotations } of completions) this.options.onItemEditComplete?.(item, file, lineAnnotations);
960
+ }
744
961
  renamePendingScrollTarget(oldId, newId) {
745
962
  const { pendingScrollTarget } = this;
746
963
  if (pendingScrollTarget == null || pendingScrollTarget.type === "position" || pendingScrollTarget.id !== oldId) return;
@@ -754,19 +971,41 @@ var CodeView = class CodeView {
754
971
  }
755
972
  createFileOptionsPrototype() {
756
973
  const prototype = {};
757
- for (const key of CODE_VIEW_FILE_OPTION_KEYS) defineItemOption(prototype, key, () => this.options[key]);
974
+ for (const key of CODE_VIEW_FILE_OPTION_KEYS) {
975
+ if (CODE_VIEW_EDIT_FORCED_OPTION_KEYS.has(key)) continue;
976
+ defineItemOption(prototype, key, () => this.options[key]);
977
+ }
978
+ defineItemOption(prototype, "useTokenTransformer", (receiver) => this.isReceiverEdited(receiver, "file") ? true : this.options.useTokenTransformer);
979
+ defineItemOption(prototype, "enableGutterUtility", (receiver) => this.isReceiverEdited(receiver, "file") ? false : this.options.enableGutterUtility);
980
+ defineItemOption(prototype, "enableLineSelection", (receiver) => this.isReceiverEdited(receiver, "file") ? false : this.options.enableLineSelection);
981
+ defineItemOption(prototype, "lineHoverHighlight", (receiver) => this.isReceiverEdited(receiver, "file") ? "disabled" : this.options.lineHoverHighlight);
758
982
  defineItemOption(prototype, "stickyHeader", () => this.options.stickyHeaders);
759
- defineItemOption(prototype, "collapsed", (receiver) => this.getItemOptions(getItemOptionsState(receiver), "file")?.item.collapsed === true);
983
+ defineItemOption(prototype, "collapsed", (receiver) => {
984
+ const state = getItemOptionsState(receiver);
985
+ if (state == null) return;
986
+ return this.getItemOptions(state, "file")?.item.collapsed;
987
+ });
760
988
  for (const key of CODE_VIEW_SHARED_CALLBACK_KEYS) this.defineItemSharedCallback(prototype, "file", key);
761
989
  for (const key of CODE_VIEW_SELECTION_CALLBACK_KEYS) this.defineItemSelectionCallback(prototype, "file", key);
762
990
  return prototype;
763
991
  }
764
992
  createDiffOptionsPrototype() {
765
993
  const prototype = {};
766
- for (const key of CODE_VIEW_DIFF_OPTION_KEYS) defineItemOption(prototype, key, () => this.options[key]);
994
+ for (const key of CODE_VIEW_DIFF_OPTION_KEYS) {
995
+ if (CODE_VIEW_EDIT_FORCED_OPTION_KEYS.has(key)) continue;
996
+ defineItemOption(prototype, key, () => this.options[key]);
997
+ }
998
+ defineItemOption(prototype, "useTokenTransformer", (receiver) => this.isReceiverEdited(receiver, "diff") ? true : this.options.useTokenTransformer);
999
+ defineItemOption(prototype, "enableGutterUtility", (receiver) => this.isReceiverEdited(receiver, "diff") ? false : this.options.enableGutterUtility);
1000
+ defineItemOption(prototype, "enableLineSelection", (receiver) => this.isReceiverEdited(receiver, "diff") ? false : this.options.enableLineSelection);
1001
+ defineItemOption(prototype, "lineHoverHighlight", (receiver) => this.isReceiverEdited(receiver, "diff") ? "disabled" : this.options.lineHoverHighlight);
767
1002
  defineItemOption(prototype, "stickyHeader", () => this.options.stickyHeaders);
768
1003
  defineItemOption(prototype, "hunkSeparators", () => this.options.hunkSeparators);
769
- defineItemOption(prototype, "collapsed", (receiver) => this.getItemOptions(getItemOptionsState(receiver), "diff")?.item.collapsed === true);
1004
+ defineItemOption(prototype, "collapsed", (receiver) => {
1005
+ const state = getItemOptionsState(receiver);
1006
+ if (state == null) return;
1007
+ return this.getItemOptions(state, "diff")?.item.collapsed;
1008
+ });
770
1009
  for (const key of CODE_VIEW_SHARED_CALLBACK_KEYS) this.defineItemSharedCallback(prototype, "diff", key);
771
1010
  for (const key of CODE_VIEW_SELECTION_CALLBACK_KEYS) this.defineItemSelectionCallback(prototype, "diff", key);
772
1011
  return prototype;
@@ -782,7 +1021,9 @@ var CodeView = class CodeView {
782
1021
  return options;
783
1022
  }
784
1023
  updateItemOptionsId(options, id) {
785
- getItemOptionsState(options).id = id;
1024
+ const state = getItemOptionsState(options);
1025
+ if (state == null) throw new Error(`CodeView.updateItemOptionsId: No valid state`);
1026
+ state.id = id;
786
1027
  }
787
1028
  getItemOptions(state, mode) {
788
1029
  const item = this.idToItem.get(state.id);
@@ -793,6 +1034,7 @@ var CodeView = class CodeView {
793
1034
  defineItemOption(options, key, (receiver) => {
794
1035
  if (this.options[key] == null) return;
795
1036
  const state = getItemOptionsState(receiver);
1037
+ if (state == null) return;
796
1038
  const callbackCache = state.callbackCache ??= {};
797
1039
  let wrapped = callbackCache[key];
798
1040
  if (wrapped == null) {
@@ -811,6 +1053,9 @@ var CodeView = class CodeView {
811
1053
  defineItemOption(options, key, (receiver) => {
812
1054
  if (this.options.enableLineSelection !== true) return;
813
1055
  const state = getItemOptionsState(receiver);
1056
+ if (state == null) return;
1057
+ const item = this.getItemOptions(state, mode);
1058
+ if (item != null && this.isItemInEditMode(item)) return;
814
1059
  const callbackCache = state.callbackCache ??= {};
815
1060
  let wrapped = callbackCache[key];
816
1061
  if (wrapped == null) {
@@ -938,7 +1183,7 @@ var CodeView = class CodeView {
938
1183
  }
939
1184
  getMaxScrollTopForHeight(scrollHeight) {
940
1185
  const { paddingBottom, paddingTop } = this.getLayout();
941
- return Math.max(paddingTop + scrollHeight + paddingBottom - this.getHeight(), 0);
1186
+ return Math.max(paddingTop + this.header.height + scrollHeight + this.footer.height + paddingBottom - this.getHeight(), 0);
942
1187
  }
943
1188
  getMaxScrollTop() {
944
1189
  return this.getMaxScrollTopForHeight(this.getScrollHeight());
@@ -1050,7 +1295,7 @@ var CodeView = class CodeView {
1050
1295
  const rect = this.getScrollTargetRect(target);
1051
1296
  if (rect == null) return;
1052
1297
  const offset = target.offset ?? 0;
1053
- const targetTop = this.getLayout().paddingTop + rect.top;
1298
+ const targetTop = this.getItemTopOffset() + rect.top;
1054
1299
  const targetBottom = targetTop + rect.height;
1055
1300
  const currentTop = this.getScrollTop();
1056
1301
  const visibleTop = currentTop + (target.type === "line" || target.type === "range" ? this.getStickyHeaderOffset() : 0);
@@ -1102,7 +1347,7 @@ var CodeView = class CodeView {
1102
1347
  * and stickyOffset if necessary
1103
1348
  */
1104
1349
  resolveAlignedScrollPosition(targetTop, targetHeight, align, offset = 0, stickyOffset = 0) {
1105
- targetTop += this.getLayout().paddingTop;
1350
+ targetTop += this.getItemTopOffset();
1106
1351
  const viewportHeight = this.getHeight();
1107
1352
  if (align === "center" && targetHeight + offset < viewportHeight) return targetTop - (viewportHeight - targetHeight) / 2 + offset;
1108
1353
  if (align === "end") return targetTop - (viewportHeight - targetHeight) + offset;
@@ -1206,6 +1451,7 @@ var CodeView = class CodeView {
1206
1451
  }
1207
1452
  computeRenderRangeAndEmit = (timestamp = performance.now()) => {
1208
1453
  if (CodeView.__STOP || this.container == null) return;
1454
+ if (!this.isReady()) return;
1209
1455
  const viewportHeight = this.getHeight();
1210
1456
  const initialScrollTop = this.getScrollTop();
1211
1457
  let scrollTopAfterLayout = initialScrollTop;
@@ -1233,7 +1479,7 @@ var CodeView = class CodeView {
1233
1479
  const fitPerfectly = !computeScrollCorrection && (this.renderState.scrollTop === -1 || Math.abs(targetScrollTop - this.renderState.scrollTop) > viewportHeight + this.config.overscrollSize * 2);
1234
1480
  if (fitPerfectly) scrollAnchor = void 0;
1235
1481
  this.windowSpecs = createWindowFromScrollPosition({
1236
- scrollTop: targetScrollTop,
1482
+ scrollTop: targetScrollTop - this.header.height,
1237
1483
  height: viewportHeight,
1238
1484
  scrollHeight: this.getScrollHeight(),
1239
1485
  fitPerfectly,
@@ -1252,6 +1498,7 @@ var CodeView = class CodeView {
1252
1498
  if (item == null) throw new Error(`CodeView.computeRenderRangeAndEmit: No item at index: ${index}`);
1253
1499
  if (!(item.top > top - item.height && item.top <= bottom)) this.releaseRenderedItem(item);
1254
1500
  }
1501
+ const hostsChanged = this.reconcileHeaderFooterHosts();
1255
1502
  let prevElement;
1256
1503
  const updatedItems = /* @__PURE__ */ new Set();
1257
1504
  const startingIndex = this.findFirstVisibleIndex(top);
@@ -1277,10 +1524,13 @@ var CodeView = class CodeView {
1277
1524
  }
1278
1525
  prevElement = item.element;
1279
1526
  }
1527
+ if (item.item.edit === true) this.attachItemEditor(item);
1280
1528
  }
1281
1529
  this.renderState.firstIndex = startingIndex <= lastRenderedIndex ? startingIndex : -1;
1282
1530
  this.renderState.lastIndex = lastRenderedIndex;
1283
1531
  this.flushSlotCoordinator();
1532
+ this.flushManagers(updatedItems);
1533
+ if (hostsChanged) this.measureMountedHosts();
1284
1534
  this.reconcileRenderedItems(updatedItems);
1285
1535
  this.syncContainerHeight();
1286
1536
  this.updateStickyPositioning();
@@ -1305,7 +1555,7 @@ var CodeView = class CodeView {
1305
1555
  this.scrollAnimation = void 0;
1306
1556
  }
1307
1557
  this.renderState.scrollTop = roundToDevicePixel(syncedScrollTop);
1308
- this.flushManagers(updatedItems);
1558
+ this.updateStickyPositioning();
1309
1559
  this.validateStickyContainerHeight();
1310
1560
  this.fixContainerFocus();
1311
1561
  if (fitPerfectly || this.scrollAnimation != null) this.render();
@@ -1419,6 +1669,25 @@ var CodeView = class CodeView {
1419
1669
  this.scrollAnimation = void 0;
1420
1670
  }
1421
1671
  }
1672
+ } else if (entry.target === this.header.element || entry.target === this.footer.element) {
1673
+ const host = entry.target === this.header.element ? this.header : this.footer;
1674
+ const blockSize = entry.borderBoxSize[0].blockSize;
1675
+ if (blockSize !== host.height) {
1676
+ const currentScrollTop = this.getScrollTop();
1677
+ const anchor = this.getScrollAnchor(currentScrollTop);
1678
+ this.setHostHeight(host, blockSize);
1679
+ const anchoredScrollTop = anchor != null ? this.resolveAnchoredScrollTop(anchor) : void 0;
1680
+ if (anchoredScrollTop != null) {
1681
+ const resizeAnchorDelta = anchoredScrollTop - currentScrollTop;
1682
+ this.applyScrollFix(anchoredScrollTop, currentScrollTop, this.windowSpecs);
1683
+ if (this.scrollAnimation != null) this.scrollAnimation.position += resizeAnchorDelta;
1684
+ }
1685
+ if (this.pendingScrollTarget != null && this.isPendingTargetSettled(this.pendingScrollTarget)) {
1686
+ this.pendingScrollTarget = void 0;
1687
+ this.scrollAnimation = void 0;
1688
+ }
1689
+ this.render();
1690
+ }
1422
1691
  } else {
1423
1692
  this.scrollDirty = true;
1424
1693
  this.heightDirty = true;
@@ -1441,6 +1710,7 @@ var CodeView = class CodeView {
1441
1710
  */
1442
1711
  getScrollAnchor(scrollTop) {
1443
1712
  if (this.pendingLayoutAnchor != null) return this.pendingLayoutAnchor;
1713
+ if (scrollTop <= 0) return;
1444
1714
  const { firstIndex, lastIndex, stickyTop, stickyBottom } = this.renderState;
1445
1715
  if (firstIndex === -1 || lastIndex === -1) return;
1446
1716
  const viewportHeight = this.getHeight();
@@ -1448,7 +1718,7 @@ var CodeView = class CodeView {
1448
1718
  for (let index = firstIndex; index <= lastIndex; index++) {
1449
1719
  const item = this.items[index];
1450
1720
  if (item == null) continue;
1451
- const absoluteItemTop = this.getLayout().paddingTop + item.top;
1721
+ const absoluteItemTop = this.getItemTopOffset() + item.top;
1452
1722
  if (absoluteItemTop + item.height <= scrollTop) continue;
1453
1723
  if (absoluteItemTop >= scrollTop + viewportHeight) break;
1454
1724
  if (absoluteItemTop >= scrollTop) return {
@@ -1480,14 +1750,14 @@ var CodeView = class CodeView {
1480
1750
  resolveAnchoredScrollTop(anchor) {
1481
1751
  const item = this.idToItem.get(anchor.id);
1482
1752
  if (item == null) return;
1483
- const { paddingTop } = this.getLayout();
1753
+ const itemTopOffset = this.getItemTopOffset();
1484
1754
  if (anchor.type === "item") {
1485
- const absoluteItemTop = paddingTop + item.top;
1755
+ const absoluteItemTop = itemTopOffset + item.top;
1486
1756
  return this.clampScrollTop(absoluteItemTop - anchor.viewportOffset);
1487
1757
  }
1488
1758
  const linePosition = item.type === "diff" ? item.instance.getLinePosition(anchor.lineNumber, anchor.side) : item.instance.getLinePosition(anchor.lineNumber);
1489
1759
  if (linePosition == null) return;
1490
- const absoluteLineTop = paddingTop + item.top + linePosition.top;
1760
+ const absoluteLineTop = itemTopOffset + item.top + linePosition.top;
1491
1761
  return this.clampScrollTop(absoluteLineTop - anchor.viewportOffset);
1492
1762
  }
1493
1763
  /**
@@ -1544,11 +1814,10 @@ var CodeView = class CodeView {
1544
1814
  }
1545
1815
  flushSlotCoordinator() {
1546
1816
  if (this.slotCoordinator == null) return;
1547
- const { onSnapshotChange } = this.slotCoordinator;
1548
- const slotSnapshot = getSlotSnapshot(this.getRenderedItems(), this.slotCoordinator);
1549
- if (areSlotSnapshotsEqual(this.slotSnapshot, slotSnapshot)) return;
1817
+ const slotSnapshot = this.buildSlotSnapshot(this.slotCoordinator);
1818
+ if (areManagedSnapshotsEqual(this.slotSnapshot, slotSnapshot)) return;
1550
1819
  this.slotSnapshot = slotSnapshot;
1551
- onSnapshotChange(slotSnapshot);
1820
+ this.slotCoordinator.onSnapshotChange(slotSnapshot);
1552
1821
  }
1553
1822
  notifyScroll() {
1554
1823
  if (this.scrollListeners.size === 0) return;
@@ -1617,8 +1886,11 @@ var CodeView = class CodeView {
1617
1886
  const item = this.items[index];
1618
1887
  if (item == null) throw new Error("CodeView.recomputeLayout: invalid item index");
1619
1888
  item.top = runningTop;
1620
- if (item.type === "diff") item.height = item.instance.prepareCodeViewItem(item.item.fileDiff, runningTop, reset, item.item.annotations ?? []);
1621
- else item.height = item.instance.prepareCodeViewItem(item.item.file, runningTop, reset, item.item.annotations ?? []);
1889
+ if (item.type === "diff") {
1890
+ const fileDiff = item.instance.consumeCodeViewLayoutChanges(item.item.fileDiff);
1891
+ if (fileDiff != null) Object.assign(item.item.fileDiff, fileDiff);
1892
+ item.height = item.instance.prepareCodeViewItem(item.item.fileDiff, runningTop, reset, item.item.annotations ?? []);
1893
+ } else item.height = item.instance.prepareCodeViewItem(item.item.file, runningTop, reset, item.item.annotations ?? []);
1622
1894
  runningTop += item.height;
1623
1895
  if (index < this.items.length - 1) runningTop += layout.gap;
1624
1896
  }
@@ -1696,7 +1968,7 @@ function syncRenderedItemOrder(container, element, prevElement) {
1696
1968
  function hasAnnotations(item) {
1697
1969
  return (item.annotations?.length ?? 0) > 0;
1698
1970
  }
1699
- function getSlotSnapshot(renderedItems, { hasHeaderRenderers, hasAnnotationRenderer, hasGutterRenderer }) {
1971
+ function getSlotItems(renderedItems, { hasHeaderRenderers, hasAnnotationRenderer, hasGutterRenderer }) {
1700
1972
  if (renderedItems.length === 0) return;
1701
1973
  if (hasHeaderRenderers || hasGutterRenderer) return renderedItems;
1702
1974
  if (!hasAnnotationRenderer) return;
@@ -1704,17 +1976,7 @@ function getSlotSnapshot(renderedItems, { hasHeaderRenderers, hasAnnotationRende
1704
1976
  for (const renderedItem of renderedItems) if (hasAnnotations(renderedItem.item)) slotSnapshot.push(renderedItem);
1705
1977
  return slotSnapshot.length > 0 ? slotSnapshot : void 0;
1706
1978
  }
1707
- function areSlotSnapshotsEqual(previous, next) {
1708
- if (previous == null || next == null) return previous === next;
1709
- if (previous.length !== next.length) return false;
1710
- for (let index = 0; index < previous.length; index++) {
1711
- const previousItem = previous[index];
1712
- const nextItem = next[index];
1713
- if (previousItem == null || nextItem == null || previousItem.id !== nextItem.id || previousItem.type !== nextItem.type || previousItem.element !== nextItem.element || previousItem.version !== nextItem.version) return false;
1714
- }
1715
- return true;
1716
- }
1717
1979
  //#endregion
1718
- export { CodeView };
1980
+ export { CODE_VIEW_DIFF_OPTION_KEYS, CODE_VIEW_FILE_OPTION_KEYS, CodeView };
1719
1981
 
1720
1982
  //# sourceMappingURL=CodeView.js.map