@pierre/diffs 1.3.0-beta.7 → 1.3.0-beta.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/CodeView.d.ts +86 -4
- package/dist/components/CodeView.d.ts.map +1 -1
- package/dist/components/CodeView.js +248 -33
- package/dist/components/CodeView.js.map +1 -1
- package/dist/components/File.d.ts +1 -0
- package/dist/components/File.d.ts.map +1 -1
- package/dist/components/File.js +15 -4
- package/dist/components/File.js.map +1 -1
- package/dist/components/FileDiff.d.ts +2 -0
- package/dist/components/FileDiff.d.ts.map +1 -1
- package/dist/components/FileDiff.js +21 -6
- 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/VirtualizedFile.d.ts.map +1 -1
- package/dist/components/VirtualizedFile.js +3 -1
- package/dist/components/VirtualizedFile.js.map +1 -1
- package/dist/components/VirtualizedFileDiff.d.ts +3 -1
- package/dist/components/VirtualizedFileDiff.d.ts.map +1 -1
- package/dist/components/VirtualizedFileDiff.js +14 -6
- package/dist/components/VirtualizedFileDiff.js.map +1 -1
- package/dist/components/Virtualizer.d.ts +2 -0
- package/dist/components/Virtualizer.d.ts.map +1 -1
- package/dist/components/Virtualizer.js +18 -4
- package/dist/components/Virtualizer.js.map +1 -1
- package/dist/constants.d.ts +3 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +3 -1
- package/dist/constants.js.map +1 -1
- package/dist/editor/command.d.ts +1 -1
- package/dist/editor/command.d.ts.map +1 -1
- package/dist/editor/command.js +8 -0
- package/dist/editor/command.js.map +1 -1
- package/dist/editor/editStack.d.ts.map +1 -1
- package/dist/editor/editStack.js +1 -1
- package/dist/editor/editStack.js.map +1 -1
- package/dist/editor/editor.d.ts +8 -1
- package/dist/editor/editor.d.ts.map +1 -1
- package/dist/editor/editor.js +188 -42
- package/dist/editor/editor.js.map +1 -1
- package/dist/editor/editor2.js +1 -1
- package/dist/editor/lineAnnotations.d.ts.map +1 -1
- package/dist/editor/lineAnnotations.js +84 -12
- package/dist/editor/lineAnnotations.js.map +1 -1
- package/dist/editor/marker.d.ts +5 -3
- package/dist/editor/marker.d.ts.map +1 -1
- package/dist/editor/marker.js +35 -12
- package/dist/editor/marker.js.map +1 -1
- package/dist/editor/matchBrackets.d.ts +8 -0
- package/dist/editor/matchBrackets.d.ts.map +1 -0
- package/dist/editor/matchBrackets.js +146 -0
- package/dist/editor/matchBrackets.js.map +1 -0
- package/dist/editor/popover.d.ts +45 -0
- package/dist/editor/popover.d.ts.map +1 -0
- package/dist/editor/popover.js +145 -0
- package/dist/editor/popover.js.map +1 -0
- package/dist/editor/searchPanel.d.ts +1 -0
- package/dist/editor/searchPanel.d.ts.map +1 -1
- package/dist/editor/searchPanel.js +6 -6
- package/dist/editor/searchPanel.js.map +1 -1
- package/dist/editor/selection.d.ts +13 -1
- package/dist/editor/selection.d.ts.map +1 -1
- package/dist/editor/selection.js +55 -4
- package/dist/editor/selection.js.map +1 -1
- package/dist/editor/selectionAction.d.ts +20 -3
- package/dist/editor/selectionAction.d.ts.map +1 -1
- package/dist/editor/selectionAction.js +41 -10
- package/dist/editor/selectionAction.js.map +1 -1
- package/dist/editor/textDocument.d.ts +2 -0
- package/dist/editor/textDocument.d.ts.map +1 -1
- package/dist/editor/textDocument.js +22 -6
- package/dist/editor/textDocument.js.map +1 -1
- package/dist/editor/tokenzier.d.ts +4 -7
- package/dist/editor/tokenzier.d.ts.map +1 -1
- package/dist/editor/tokenzier.js +76 -35
- package/dist/editor/tokenzier.js.map +1 -1
- package/dist/index.d.ts +7 -7
- package/dist/index.js +5 -5
- 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 +25 -1
- package/dist/react/CodeView.d.ts.map +1 -1
- package/dist/react/CodeView.js +76 -17
- package/dist/react/CodeView.js.map +1 -1
- package/dist/react/EditorContext.d.ts +2 -2
- package/dist/react/EditorContext.d.ts.map +1 -1
- package/dist/react/EditorContext.js.map +1 -1
- package/dist/react/index.d.ts +2 -2
- package/dist/renderers/DiffHunksRenderer.d.ts +1 -1
- package/dist/renderers/DiffHunksRenderer.d.ts.map +1 -1
- package/dist/renderers/DiffHunksRenderer.js +24 -15
- package/dist/renderers/DiffHunksRenderer.js.map +1 -1
- package/dist/renderers/FileRenderer.d.ts +2 -1
- package/dist/renderers/FileRenderer.d.ts.map +1 -1
- package/dist/renderers/FileRenderer.js +58 -38
- package/dist/renderers/FileRenderer.js.map +1 -1
- package/dist/ssr/index.d.ts +2 -2
- package/dist/types.d.ts +42 -2
- 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/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/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/updateDiffHunks.d.ts.map +1 -1
- package/dist/utils/updateDiffHunks.js +23 -1
- package/dist/utils/updateDiffHunks.js.map +1 -1
- package/dist/worker/WorkerPoolManager.d.ts.map +1 -1
- package/dist/worker/WorkerPoolManager.js +4 -2
- package/dist/worker/WorkerPoolManager.js.map +1 -1
- package/dist/worker/types.d.ts +4 -0
- package/dist/worker/types.d.ts.map +1 -1
- package/dist/worker/worker-portable.js.map +1 -1
- package/dist/worker/worker.js.map +1 -1
- package/package.json +4 -2
|
@@ -1,9 +1,11 @@
|
|
|
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";
|
|
8
10
|
import { isStyleNode } from "../utils/isStyleNode.js";
|
|
9
11
|
import { prefersReducedMotion } from "../utils/prefersReducedMotion.js";
|
|
@@ -62,6 +64,13 @@ const CODE_VIEW_FILE_OPTION_KEYS = [
|
|
|
62
64
|
"controlledSelection",
|
|
63
65
|
"disableErrorHandling"
|
|
64
66
|
];
|
|
67
|
+
const CODE_VIEW_EDIT_FORCED_OPTION_KEYS = /* @__PURE__ */ new Set([
|
|
68
|
+
"useTokenTransformer",
|
|
69
|
+
"enableGutterUtility",
|
|
70
|
+
"enableLineSelection",
|
|
71
|
+
"lineHoverHighlight",
|
|
72
|
+
"expandUnchanged"
|
|
73
|
+
]);
|
|
65
74
|
const CODE_VIEW_SHARED_CALLBACK_KEYS = [
|
|
66
75
|
"renderCustomHeader",
|
|
67
76
|
"renderHeaderPrefix",
|
|
@@ -131,6 +140,8 @@ var CodeView = class CodeView {
|
|
|
131
140
|
items = [];
|
|
132
141
|
idToItem = /* @__PURE__ */ new Map();
|
|
133
142
|
selectedLines = null;
|
|
143
|
+
itemEditors = /* @__PURE__ */ new Map();
|
|
144
|
+
attachedEditors = /* @__PURE__ */ new Set();
|
|
134
145
|
instanceToItem = /* @__PURE__ */ new Map();
|
|
135
146
|
layoutDirtyIndex;
|
|
136
147
|
pendingLayoutReset;
|
|
@@ -172,6 +183,16 @@ var CodeView = class CodeView {
|
|
|
172
183
|
container = document.createElement("div");
|
|
173
184
|
stickyContainer = document.createElement("div");
|
|
174
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
|
+
};
|
|
175
196
|
elementPool = [];
|
|
176
197
|
elementPoolVersion = 0;
|
|
177
198
|
elementPoolTracker = /* @__PURE__ */ new WeakMap();
|
|
@@ -198,6 +219,9 @@ var CodeView = class CodeView {
|
|
|
198
219
|
getLayout() {
|
|
199
220
|
return this.options.layout ?? DEFAULT_CODE_VIEW_LAYOUT;
|
|
200
221
|
}
|
|
222
|
+
getItemTopOffset() {
|
|
223
|
+
return this.getLayout().paddingTop + this.header.height;
|
|
224
|
+
}
|
|
201
225
|
computeMetricsCache(itemMetrics) {
|
|
202
226
|
this.itemMetricsCache = {
|
|
203
227
|
hunkLineCount: itemMetrics?.hunkLineCount ?? DEFAULT_CODE_VIEW_FILE_METRICS.hunkLineCount,
|
|
@@ -300,6 +324,43 @@ var CodeView = class CodeView {
|
|
|
300
324
|
this.container?.style.setProperty("margin-top", `${paddingTop}px`);
|
|
301
325
|
this.container?.style.setProperty("margin-bottom", `${paddingBottom}px`);
|
|
302
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
|
+
}
|
|
303
364
|
setup(root) {
|
|
304
365
|
if (this.root != null) throw new Error("CodeView.setup: already setup");
|
|
305
366
|
this.workerManager?.subscribeToThemeChanges(this);
|
|
@@ -339,9 +400,13 @@ var CodeView = class CodeView {
|
|
|
339
400
|
};
|
|
340
401
|
}
|
|
341
402
|
reset() {
|
|
403
|
+
dequeueRender(this.computeRenderRangeAndEmit);
|
|
342
404
|
this.clearReadySubscription();
|
|
343
405
|
this.restoreScrollInteractions();
|
|
344
406
|
this.cleanAllRenderedItems();
|
|
407
|
+
for (const record of this.itemEditors.values()) record.editor.cleanUp();
|
|
408
|
+
this.itemEditors.clear();
|
|
409
|
+
this.attachedEditors.clear();
|
|
345
410
|
this.selectedLines = null;
|
|
346
411
|
this.items.length = 0;
|
|
347
412
|
this.idToItem.clear();
|
|
@@ -384,6 +449,14 @@ var CodeView = class CodeView {
|
|
|
384
449
|
this.stickyOffset.remove();
|
|
385
450
|
this.stickyContainer.remove();
|
|
386
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;
|
|
387
460
|
this.root = void 0;
|
|
388
461
|
this.container = void 0;
|
|
389
462
|
}
|
|
@@ -418,6 +491,7 @@ var CodeView = class CodeView {
|
|
|
418
491
|
const { element } = item;
|
|
419
492
|
if (element != null && this.renderedItemOwnsFocus(element)) this.shouldFixContainerFocus = true;
|
|
420
493
|
item.instance.cleanUp(true);
|
|
494
|
+
this.attachedEditors.delete(item.item.id);
|
|
421
495
|
item.element = void 0;
|
|
422
496
|
if (element == null) return;
|
|
423
497
|
element.remove();
|
|
@@ -510,6 +584,14 @@ var CodeView = class CodeView {
|
|
|
510
584
|
getItem(itemId) {
|
|
511
585
|
return this.idToItem.get(itemId)?.item;
|
|
512
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
|
+
}
|
|
513
595
|
updateItem(input) {
|
|
514
596
|
const item = this.idToItem.get(input.id);
|
|
515
597
|
if (item == null) {
|
|
@@ -521,6 +603,7 @@ var CodeView = class CodeView {
|
|
|
521
603
|
this.scrollDirty = true;
|
|
522
604
|
this.render();
|
|
523
605
|
this.syncSelection();
|
|
606
|
+
this.syncItemEditors();
|
|
524
607
|
return true;
|
|
525
608
|
}
|
|
526
609
|
updateItemId(oldId, newId) {
|
|
@@ -545,6 +628,13 @@ var CodeView = class CodeView {
|
|
|
545
628
|
};
|
|
546
629
|
this.options.onSelectedLinesChange?.(this.selectedLines);
|
|
547
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
|
+
}
|
|
548
638
|
this.renamePendingScrollTarget(oldId, newId);
|
|
549
639
|
this.renamePendingLayoutAnchor(oldId, newId);
|
|
550
640
|
this.render();
|
|
@@ -552,17 +642,25 @@ var CodeView = class CodeView {
|
|
|
552
642
|
}
|
|
553
643
|
addItem(input) {
|
|
554
644
|
this.addItems([input]);
|
|
555
|
-
this.syncSelection();
|
|
556
645
|
}
|
|
557
646
|
addItems(inputs) {
|
|
558
647
|
this.appendItemsInternal(inputs);
|
|
559
648
|
this.syncSelection();
|
|
649
|
+
this.syncItemEditors();
|
|
560
650
|
}
|
|
561
651
|
setItems(items) {
|
|
562
|
-
if (items.length === 0)
|
|
563
|
-
|
|
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);
|
|
564
661
|
else if (!this.tryAppendItems(items)) this.reconcileItems(items);
|
|
565
662
|
this.syncSelection();
|
|
663
|
+
this.syncItemEditors();
|
|
566
664
|
}
|
|
567
665
|
/**
|
|
568
666
|
* Append new records to the viewer while preserving existing layout state.
|
|
@@ -624,7 +722,9 @@ var CodeView = class CodeView {
|
|
|
624
722
|
this.scrollDirty = true;
|
|
625
723
|
}
|
|
626
724
|
if (!areOptionsEqual(prevOptions, options)) this.renderOptionsRevision++;
|
|
627
|
-
|
|
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();
|
|
628
728
|
}
|
|
629
729
|
capturePendingLayoutAnchor() {
|
|
630
730
|
if (this.root == null || this.items.length === 0 || this.pendingScrollTarget != null) return;
|
|
@@ -668,6 +768,12 @@ var CodeView = class CodeView {
|
|
|
668
768
|
getContainerElement() {
|
|
669
769
|
return this.root;
|
|
670
770
|
}
|
|
771
|
+
getHeaderElement() {
|
|
772
|
+
return this.header.element;
|
|
773
|
+
}
|
|
774
|
+
getFooterElement() {
|
|
775
|
+
return this.footer.element;
|
|
776
|
+
}
|
|
671
777
|
getRenderedItems() {
|
|
672
778
|
const { firstIndex, lastIndex } = this.renderState;
|
|
673
779
|
if (firstIndex === -1 || lastIndex === -1 || lastIndex < firstIndex) return [];
|
|
@@ -701,7 +807,18 @@ var CodeView = class CodeView {
|
|
|
701
807
|
return true;
|
|
702
808
|
}
|
|
703
809
|
getSlotSnapshot(coordinator) {
|
|
704
|
-
return
|
|
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
|
+
};
|
|
705
822
|
}
|
|
706
823
|
subscribeToScroll(listener) {
|
|
707
824
|
this.scrollListeners.add(listener);
|
|
@@ -717,7 +834,7 @@ var CodeView = class CodeView {
|
|
|
717
834
|
getTopForItem(id) {
|
|
718
835
|
const item = this.idToItem.get(id);
|
|
719
836
|
if (item == null) return;
|
|
720
|
-
return item.top + this.
|
|
837
|
+
return item.top + this.getItemTopOffset();
|
|
721
838
|
}
|
|
722
839
|
createItem(input, index, top) {
|
|
723
840
|
const { itemMetricsCache: itemMetrics } = this;
|
|
@@ -764,6 +881,75 @@ var CodeView = class CodeView {
|
|
|
764
881
|
}
|
|
765
882
|
item.instance.setSelectedLines(this.selectedLines.range, { notify: false });
|
|
766
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 { lastChange } = record.state;
|
|
946
|
+
if (lastChange != null) completions.push(item == null ? lastChange : {
|
|
947
|
+
...lastChange,
|
|
948
|
+
item: item.item
|
|
949
|
+
});
|
|
950
|
+
}
|
|
951
|
+
for (const { item, file, lineAnnotations } of completions) this.options.onItemEditComplete?.(item, file, lineAnnotations);
|
|
952
|
+
}
|
|
767
953
|
renamePendingScrollTarget(oldId, newId) {
|
|
768
954
|
const { pendingScrollTarget } = this;
|
|
769
955
|
if (pendingScrollTarget == null || pendingScrollTarget.type === "position" || pendingScrollTarget.id !== oldId) return;
|
|
@@ -777,7 +963,14 @@ var CodeView = class CodeView {
|
|
|
777
963
|
}
|
|
778
964
|
createFileOptionsPrototype() {
|
|
779
965
|
const prototype = {};
|
|
780
|
-
for (const key of CODE_VIEW_FILE_OPTION_KEYS)
|
|
966
|
+
for (const key of CODE_VIEW_FILE_OPTION_KEYS) {
|
|
967
|
+
if (CODE_VIEW_EDIT_FORCED_OPTION_KEYS.has(key)) continue;
|
|
968
|
+
defineItemOption(prototype, key, () => this.options[key]);
|
|
969
|
+
}
|
|
970
|
+
defineItemOption(prototype, "useTokenTransformer", (receiver) => this.isReceiverEdited(receiver, "file") ? true : this.options.useTokenTransformer);
|
|
971
|
+
defineItemOption(prototype, "enableGutterUtility", (receiver) => this.isReceiverEdited(receiver, "file") ? false : this.options.enableGutterUtility);
|
|
972
|
+
defineItemOption(prototype, "enableLineSelection", (receiver) => this.isReceiverEdited(receiver, "file") ? false : this.options.enableLineSelection);
|
|
973
|
+
defineItemOption(prototype, "lineHoverHighlight", (receiver) => this.isReceiverEdited(receiver, "file") ? "disabled" : this.options.lineHoverHighlight);
|
|
781
974
|
defineItemOption(prototype, "stickyHeader", () => this.options.stickyHeaders);
|
|
782
975
|
defineItemOption(prototype, "collapsed", (receiver) => {
|
|
783
976
|
const state = getItemOptionsState(receiver);
|
|
@@ -790,7 +983,15 @@ var CodeView = class CodeView {
|
|
|
790
983
|
}
|
|
791
984
|
createDiffOptionsPrototype() {
|
|
792
985
|
const prototype = {};
|
|
793
|
-
for (const key of CODE_VIEW_DIFF_OPTION_KEYS)
|
|
986
|
+
for (const key of CODE_VIEW_DIFF_OPTION_KEYS) {
|
|
987
|
+
if (CODE_VIEW_EDIT_FORCED_OPTION_KEYS.has(key)) continue;
|
|
988
|
+
defineItemOption(prototype, key, () => this.options[key]);
|
|
989
|
+
}
|
|
990
|
+
defineItemOption(prototype, "useTokenTransformer", (receiver) => this.isReceiverEdited(receiver, "diff") ? true : this.options.useTokenTransformer);
|
|
991
|
+
defineItemOption(prototype, "enableGutterUtility", (receiver) => this.isReceiverEdited(receiver, "diff") ? false : this.options.enableGutterUtility);
|
|
992
|
+
defineItemOption(prototype, "enableLineSelection", (receiver) => this.isReceiverEdited(receiver, "diff") ? false : this.options.enableLineSelection);
|
|
993
|
+
defineItemOption(prototype, "lineHoverHighlight", (receiver) => this.isReceiverEdited(receiver, "diff") ? "disabled" : this.options.lineHoverHighlight);
|
|
994
|
+
defineItemOption(prototype, "expandUnchanged", (receiver) => this.isReceiverEdited(receiver, "diff") ? true : this.options.expandUnchanged);
|
|
794
995
|
defineItemOption(prototype, "stickyHeader", () => this.options.stickyHeaders);
|
|
795
996
|
defineItemOption(prototype, "hunkSeparators", () => this.options.hunkSeparators);
|
|
796
997
|
defineItemOption(prototype, "collapsed", (receiver) => {
|
|
@@ -846,6 +1047,8 @@ var CodeView = class CodeView {
|
|
|
846
1047
|
if (this.options.enableLineSelection !== true) return;
|
|
847
1048
|
const state = getItemOptionsState(receiver);
|
|
848
1049
|
if (state == null) return;
|
|
1050
|
+
const item = this.getItemOptions(state, mode);
|
|
1051
|
+
if (item != null && this.isItemInEditMode(item)) return;
|
|
849
1052
|
const callbackCache = state.callbackCache ??= {};
|
|
850
1053
|
let wrapped = callbackCache[key];
|
|
851
1054
|
if (wrapped == null) {
|
|
@@ -973,7 +1176,7 @@ var CodeView = class CodeView {
|
|
|
973
1176
|
}
|
|
974
1177
|
getMaxScrollTopForHeight(scrollHeight) {
|
|
975
1178
|
const { paddingBottom, paddingTop } = this.getLayout();
|
|
976
|
-
return Math.max(paddingTop + scrollHeight + paddingBottom - this.getHeight(), 0);
|
|
1179
|
+
return Math.max(paddingTop + this.header.height + scrollHeight + this.footer.height + paddingBottom - this.getHeight(), 0);
|
|
977
1180
|
}
|
|
978
1181
|
getMaxScrollTop() {
|
|
979
1182
|
return this.getMaxScrollTopForHeight(this.getScrollHeight());
|
|
@@ -1085,7 +1288,7 @@ var CodeView = class CodeView {
|
|
|
1085
1288
|
const rect = this.getScrollTargetRect(target);
|
|
1086
1289
|
if (rect == null) return;
|
|
1087
1290
|
const offset = target.offset ?? 0;
|
|
1088
|
-
const targetTop = this.
|
|
1291
|
+
const targetTop = this.getItemTopOffset() + rect.top;
|
|
1089
1292
|
const targetBottom = targetTop + rect.height;
|
|
1090
1293
|
const currentTop = this.getScrollTop();
|
|
1091
1294
|
const visibleTop = currentTop + (target.type === "line" || target.type === "range" ? this.getStickyHeaderOffset() : 0);
|
|
@@ -1137,7 +1340,7 @@ var CodeView = class CodeView {
|
|
|
1137
1340
|
* and stickyOffset if necessary
|
|
1138
1341
|
*/
|
|
1139
1342
|
resolveAlignedScrollPosition(targetTop, targetHeight, align, offset = 0, stickyOffset = 0) {
|
|
1140
|
-
targetTop += this.
|
|
1343
|
+
targetTop += this.getItemTopOffset();
|
|
1141
1344
|
const viewportHeight = this.getHeight();
|
|
1142
1345
|
if (align === "center" && targetHeight + offset < viewportHeight) return targetTop - (viewportHeight - targetHeight) / 2 + offset;
|
|
1143
1346
|
if (align === "end") return targetTop - (viewportHeight - targetHeight) + offset;
|
|
@@ -1269,7 +1472,7 @@ var CodeView = class CodeView {
|
|
|
1269
1472
|
const fitPerfectly = !computeScrollCorrection && (this.renderState.scrollTop === -1 || Math.abs(targetScrollTop - this.renderState.scrollTop) > viewportHeight + this.config.overscrollSize * 2);
|
|
1270
1473
|
if (fitPerfectly) scrollAnchor = void 0;
|
|
1271
1474
|
this.windowSpecs = createWindowFromScrollPosition({
|
|
1272
|
-
scrollTop: targetScrollTop,
|
|
1475
|
+
scrollTop: targetScrollTop - this.header.height,
|
|
1273
1476
|
height: viewportHeight,
|
|
1274
1477
|
scrollHeight: this.getScrollHeight(),
|
|
1275
1478
|
fitPerfectly,
|
|
@@ -1288,6 +1491,7 @@ var CodeView = class CodeView {
|
|
|
1288
1491
|
if (item == null) throw new Error(`CodeView.computeRenderRangeAndEmit: No item at index: ${index}`);
|
|
1289
1492
|
if (!(item.top > top - item.height && item.top <= bottom)) this.releaseRenderedItem(item);
|
|
1290
1493
|
}
|
|
1494
|
+
const hostsChanged = this.reconcileHeaderFooterHosts();
|
|
1291
1495
|
let prevElement;
|
|
1292
1496
|
const updatedItems = /* @__PURE__ */ new Set();
|
|
1293
1497
|
const startingIndex = this.findFirstVisibleIndex(top);
|
|
@@ -1313,11 +1517,13 @@ var CodeView = class CodeView {
|
|
|
1313
1517
|
}
|
|
1314
1518
|
prevElement = item.element;
|
|
1315
1519
|
}
|
|
1520
|
+
if (item.item.edit === true) this.attachItemEditor(item);
|
|
1316
1521
|
}
|
|
1317
1522
|
this.renderState.firstIndex = startingIndex <= lastRenderedIndex ? startingIndex : -1;
|
|
1318
1523
|
this.renderState.lastIndex = lastRenderedIndex;
|
|
1319
1524
|
this.flushSlotCoordinator();
|
|
1320
1525
|
this.flushManagers(updatedItems);
|
|
1526
|
+
if (hostsChanged) this.measureMountedHosts();
|
|
1321
1527
|
this.reconcileRenderedItems(updatedItems);
|
|
1322
1528
|
this.syncContainerHeight();
|
|
1323
1529
|
this.updateStickyPositioning();
|
|
@@ -1456,6 +1662,25 @@ var CodeView = class CodeView {
|
|
|
1456
1662
|
this.scrollAnimation = void 0;
|
|
1457
1663
|
}
|
|
1458
1664
|
}
|
|
1665
|
+
} else if (entry.target === this.header.element || entry.target === this.footer.element) {
|
|
1666
|
+
const host = entry.target === this.header.element ? this.header : this.footer;
|
|
1667
|
+
const blockSize = entry.borderBoxSize[0].blockSize;
|
|
1668
|
+
if (blockSize !== host.height) {
|
|
1669
|
+
const currentScrollTop = this.getScrollTop();
|
|
1670
|
+
const anchor = this.getScrollAnchor(currentScrollTop);
|
|
1671
|
+
this.setHostHeight(host, blockSize);
|
|
1672
|
+
const anchoredScrollTop = anchor != null ? this.resolveAnchoredScrollTop(anchor) : void 0;
|
|
1673
|
+
if (anchoredScrollTop != null) {
|
|
1674
|
+
const resizeAnchorDelta = anchoredScrollTop - currentScrollTop;
|
|
1675
|
+
this.applyScrollFix(anchoredScrollTop, currentScrollTop, this.windowSpecs);
|
|
1676
|
+
if (this.scrollAnimation != null) this.scrollAnimation.position += resizeAnchorDelta;
|
|
1677
|
+
}
|
|
1678
|
+
if (this.pendingScrollTarget != null && this.isPendingTargetSettled(this.pendingScrollTarget)) {
|
|
1679
|
+
this.pendingScrollTarget = void 0;
|
|
1680
|
+
this.scrollAnimation = void 0;
|
|
1681
|
+
}
|
|
1682
|
+
this.render();
|
|
1683
|
+
}
|
|
1459
1684
|
} else {
|
|
1460
1685
|
this.scrollDirty = true;
|
|
1461
1686
|
this.heightDirty = true;
|
|
@@ -1478,6 +1703,7 @@ var CodeView = class CodeView {
|
|
|
1478
1703
|
*/
|
|
1479
1704
|
getScrollAnchor(scrollTop) {
|
|
1480
1705
|
if (this.pendingLayoutAnchor != null) return this.pendingLayoutAnchor;
|
|
1706
|
+
if (scrollTop <= 0) return;
|
|
1481
1707
|
const { firstIndex, lastIndex, stickyTop, stickyBottom } = this.renderState;
|
|
1482
1708
|
if (firstIndex === -1 || lastIndex === -1) return;
|
|
1483
1709
|
const viewportHeight = this.getHeight();
|
|
@@ -1485,7 +1711,7 @@ var CodeView = class CodeView {
|
|
|
1485
1711
|
for (let index = firstIndex; index <= lastIndex; index++) {
|
|
1486
1712
|
const item = this.items[index];
|
|
1487
1713
|
if (item == null) continue;
|
|
1488
|
-
const absoluteItemTop = this.
|
|
1714
|
+
const absoluteItemTop = this.getItemTopOffset() + item.top;
|
|
1489
1715
|
if (absoluteItemTop + item.height <= scrollTop) continue;
|
|
1490
1716
|
if (absoluteItemTop >= scrollTop + viewportHeight) break;
|
|
1491
1717
|
if (absoluteItemTop >= scrollTop) return {
|
|
@@ -1517,14 +1743,14 @@ var CodeView = class CodeView {
|
|
|
1517
1743
|
resolveAnchoredScrollTop(anchor) {
|
|
1518
1744
|
const item = this.idToItem.get(anchor.id);
|
|
1519
1745
|
if (item == null) return;
|
|
1520
|
-
const
|
|
1746
|
+
const itemTopOffset = this.getItemTopOffset();
|
|
1521
1747
|
if (anchor.type === "item") {
|
|
1522
|
-
const absoluteItemTop =
|
|
1748
|
+
const absoluteItemTop = itemTopOffset + item.top;
|
|
1523
1749
|
return this.clampScrollTop(absoluteItemTop - anchor.viewportOffset);
|
|
1524
1750
|
}
|
|
1525
1751
|
const linePosition = item.type === "diff" ? item.instance.getLinePosition(anchor.lineNumber, anchor.side) : item.instance.getLinePosition(anchor.lineNumber);
|
|
1526
1752
|
if (linePosition == null) return;
|
|
1527
|
-
const absoluteLineTop =
|
|
1753
|
+
const absoluteLineTop = itemTopOffset + item.top + linePosition.top;
|
|
1528
1754
|
return this.clampScrollTop(absoluteLineTop - anchor.viewportOffset);
|
|
1529
1755
|
}
|
|
1530
1756
|
/**
|
|
@@ -1581,11 +1807,10 @@ var CodeView = class CodeView {
|
|
|
1581
1807
|
}
|
|
1582
1808
|
flushSlotCoordinator() {
|
|
1583
1809
|
if (this.slotCoordinator == null) return;
|
|
1584
|
-
const
|
|
1585
|
-
|
|
1586
|
-
if (areSlotSnapshotsEqual(this.slotSnapshot, slotSnapshot)) return;
|
|
1810
|
+
const slotSnapshot = this.buildSlotSnapshot(this.slotCoordinator);
|
|
1811
|
+
if (areManagedSnapshotsEqual(this.slotSnapshot, slotSnapshot)) return;
|
|
1587
1812
|
this.slotSnapshot = slotSnapshot;
|
|
1588
|
-
onSnapshotChange(slotSnapshot);
|
|
1813
|
+
this.slotCoordinator.onSnapshotChange(slotSnapshot);
|
|
1589
1814
|
}
|
|
1590
1815
|
notifyScroll() {
|
|
1591
1816
|
if (this.scrollListeners.size === 0) return;
|
|
@@ -1656,7 +1881,7 @@ var CodeView = class CodeView {
|
|
|
1656
1881
|
item.top = runningTop;
|
|
1657
1882
|
if (item.type === "diff") {
|
|
1658
1883
|
const fileDiff = item.instance.consumeCodeViewLayoutChanges(item.item.fileDiff);
|
|
1659
|
-
if (fileDiff != null) item.item.fileDiff
|
|
1884
|
+
if (fileDiff != null) Object.assign(item.item.fileDiff, fileDiff);
|
|
1660
1885
|
item.height = item.instance.prepareCodeViewItem(item.item.fileDiff, runningTop, reset, item.item.annotations ?? []);
|
|
1661
1886
|
} else item.height = item.instance.prepareCodeViewItem(item.item.file, runningTop, reset, item.item.annotations ?? []);
|
|
1662
1887
|
runningTop += item.height;
|
|
@@ -1736,7 +1961,7 @@ function syncRenderedItemOrder(container, element, prevElement) {
|
|
|
1736
1961
|
function hasAnnotations(item) {
|
|
1737
1962
|
return (item.annotations?.length ?? 0) > 0;
|
|
1738
1963
|
}
|
|
1739
|
-
function
|
|
1964
|
+
function getSlotItems(renderedItems, { hasHeaderRenderers, hasAnnotationRenderer, hasGutterRenderer }) {
|
|
1740
1965
|
if (renderedItems.length === 0) return;
|
|
1741
1966
|
if (hasHeaderRenderers || hasGutterRenderer) return renderedItems;
|
|
1742
1967
|
if (!hasAnnotationRenderer) return;
|
|
@@ -1744,17 +1969,7 @@ function getSlotSnapshot(renderedItems, { hasHeaderRenderers, hasAnnotationRende
|
|
|
1744
1969
|
for (const renderedItem of renderedItems) if (hasAnnotations(renderedItem.item)) slotSnapshot.push(renderedItem);
|
|
1745
1970
|
return slotSnapshot.length > 0 ? slotSnapshot : void 0;
|
|
1746
1971
|
}
|
|
1747
|
-
function areSlotSnapshotsEqual(previous, next) {
|
|
1748
|
-
if (previous == null || next == null) return previous === next;
|
|
1749
|
-
if (previous.length !== next.length) return false;
|
|
1750
|
-
for (let index = 0; index < previous.length; index++) {
|
|
1751
|
-
const previousItem = previous[index];
|
|
1752
|
-
const nextItem = next[index];
|
|
1753
|
-
if (previousItem == null || nextItem == null || previousItem.id !== nextItem.id || previousItem.type !== nextItem.type || previousItem.element !== nextItem.element || previousItem.version !== nextItem.version) return false;
|
|
1754
|
-
}
|
|
1755
|
-
return true;
|
|
1756
|
-
}
|
|
1757
1972
|
//#endregion
|
|
1758
|
-
export { CodeView };
|
|
1973
|
+
export { CODE_VIEW_DIFF_OPTION_KEYS, CODE_VIEW_FILE_OPTION_KEYS, CodeView };
|
|
1759
1974
|
|
|
1760
1975
|
//# sourceMappingURL=CodeView.js.map
|