@pierre/diffs 1.2.1 → 1.2.3
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 +22 -7
- package/dist/components/CodeView.d.ts.map +1 -1
- package/dist/components/CodeView.js +202 -105
- package/dist/components/CodeView.js.map +1 -1
- package/dist/components/File.d.ts +2 -0
- package/dist/components/File.d.ts.map +1 -1
- package/dist/components/File.js +13 -9
- 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 +12 -6
- package/dist/components/FileDiff.js.map +1 -1
- package/dist/components/UnresolvedFile.d.ts.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 +23 -6
- package/dist/components/VirtualizedFile.js.map +1 -1
- package/dist/components/VirtualizedFileDiff.d.ts +9 -8
- package/dist/components/VirtualizedFileDiff.d.ts.map +1 -1
- package/dist/components/VirtualizedFileDiff.js +329 -142
- package/dist/components/VirtualizedFileDiff.js.map +1 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -3
- package/dist/react/index.d.ts +2 -2
- package/dist/renderers/DiffHunksRenderer.d.ts +1 -0
- package/dist/renderers/DiffHunksRenderer.d.ts.map +1 -1
- package/dist/renderers/DiffHunksRenderer.js +19 -9
- package/dist/renderers/DiffHunksRenderer.js.map +1 -1
- package/dist/renderers/FileRenderer.d.ts +1 -0
- package/dist/renderers/FileRenderer.d.ts.map +1 -1
- package/dist/renderers/FileRenderer.js +12 -6
- package/dist/renderers/FileRenderer.js.map +1 -1
- package/dist/ssr/index.d.ts +2 -2
- package/dist/types.d.ts +7 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/computeEstimatedDiffHeights.d.ts +28 -0
- package/dist/utils/computeEstimatedDiffHeights.d.ts.map +1 -0
- package/dist/utils/computeEstimatedDiffHeights.js +111 -0
- package/dist/utils/computeEstimatedDiffHeights.js.map +1 -0
- package/dist/utils/getDiffHunksRendererOptions.d.ts +8 -0
- package/dist/utils/getDiffHunksRendererOptions.d.ts.map +1 -0
- package/dist/utils/getDiffHunksRendererOptions.js +31 -0
- package/dist/utils/getDiffHunksRendererOptions.js.map +1 -0
- package/dist/utils/getFileRendererOptions.d.ts +8 -0
- package/dist/utils/getFileRendererOptions.d.ts.map +1 -0
- package/dist/utils/getFileRendererOptions.js +24 -0
- package/dist/utils/getFileRendererOptions.js.map +1 -0
- package/dist/utils/iterateOverDiff.js +29 -30
- package/dist/utils/iterateOverDiff.js.map +1 -1
- package/dist/utils/parsePatchFiles.js +8 -1
- package/dist/utils/parsePatchFiles.js.map +1 -1
- package/dist/utils/virtualDiffLayout.d.ts +65 -0
- package/dist/utils/virtualDiffLayout.d.ts.map +1 -0
- package/dist/utils/virtualDiffLayout.js +94 -0
- package/dist/utils/virtualDiffLayout.js.map +1 -0
- package/dist/worker/WorkerPoolManager.d.ts +4 -1
- package/dist/worker/WorkerPoolManager.d.ts.map +1 -1
- package/dist/worker/WorkerPoolManager.js +49 -24
- package/dist/worker/WorkerPoolManager.js.map +1 -1
- package/dist/worker/types.d.ts +2 -0
- package/dist/worker/types.d.ts.map +1 -1
- package/dist/worker/worker-portable.js +163 -40
- package/dist/worker/worker-portable.js.map +1 -1
- package/dist/worker/worker.js +60 -30
- package/dist/worker/worker.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { CORE_CSS_ATTRIBUTE, DEFAULT_CODE_VIEW_FILE_METRICS, DEFAULT_CODE_VIEW_LAYOUT, DEFAULT_SMOOTH_SCROLL_SETTINGS, DEFAULT_THEMES, DIFFS_DEVELOPMENT_BUILD, DIFFS_TAG_NAME, THEME_CSS_ATTRIBUTE, UNSAFE_CSS_ATTRIBUTE } from "../constants.js";
|
|
1
|
+
import { CORE_CSS_ATTRIBUTE, DEFAULT_CODE_VIEW_FILE_METRICS, DEFAULT_CODE_VIEW_LAYOUT, DEFAULT_COLLAPSED_CONTEXT_THRESHOLD, DEFAULT_SMOOTH_SCROLL_SETTINGS, DEFAULT_THEMES, DIFFS_DEVELOPMENT_BUILD, DIFFS_TAG_NAME, THEME_CSS_ATTRIBUTE, UNSAFE_CSS_ATTRIBUTE } from "../constants.js";
|
|
2
2
|
import { dequeueRender, queueRender } from "../managers/UniversalRenderingManager.js";
|
|
3
3
|
import { areObjectsEqual } from "../utils/areObjectsEqual.js";
|
|
4
|
-
import { areSelectionsEqual } from "../utils/areSelectionsEqual.js";
|
|
5
4
|
import { areThemesEqual } from "../utils/areThemesEqual.js";
|
|
5
|
+
import { areOptionsEqual } from "../utils/areOptionsEqual.js";
|
|
6
|
+
import { areSelectionsEqual } from "../utils/areSelectionsEqual.js";
|
|
6
7
|
import { createWindowFromScrollPosition } from "../utils/createWindowFromScrollPosition.js";
|
|
7
8
|
import { isStyleNode } from "../utils/isStyleNode.js";
|
|
8
9
|
import { prefersReducedMotion } from "../utils/prefersReducedMotion.js";
|
|
@@ -83,6 +84,26 @@ const CODE_VIEW_SELECTION_CALLBACK_KEYS = [
|
|
|
83
84
|
"onLineSelectionChange",
|
|
84
85
|
"onLineSelectionEnd"
|
|
85
86
|
];
|
|
87
|
+
const CODE_VIEW_ITEM_OPTIONS_STATE = Symbol("CodeView.itemOptionsState");
|
|
88
|
+
function defineOptionsState(options, state) {
|
|
89
|
+
Object.defineProperty(options, CODE_VIEW_ITEM_OPTIONS_STATE, {
|
|
90
|
+
configurable: false,
|
|
91
|
+
enumerable: false,
|
|
92
|
+
value: state
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
function getItemOptionsState(options) {
|
|
96
|
+
return options[CODE_VIEW_ITEM_OPTIONS_STATE];
|
|
97
|
+
}
|
|
98
|
+
function defineItemOption(target, key, get) {
|
|
99
|
+
Object.defineProperty(target, key, {
|
|
100
|
+
configurable: false,
|
|
101
|
+
enumerable: true,
|
|
102
|
+
get() {
|
|
103
|
+
return get(this);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
}
|
|
86
107
|
const DEFAULT_SCROLL_INTERACTION_RESTORE_DELAY_MS = 120;
|
|
87
108
|
const SCROLLING_CODE_OVERFLOW_FIX_VARIABLE = "--diffs-overflow-override";
|
|
88
109
|
const SCROLL_REBASE_CONTAINER_HEIGHT = 12e6;
|
|
@@ -90,7 +111,6 @@ const SCROLL_REBASE_TRIGGER_TOP = 1e6;
|
|
|
90
111
|
const SCROLL_REBASE_TARGET_TOP = 2e6;
|
|
91
112
|
const SCROLL_REBASE_TARGET_BOTTOM = SCROLL_REBASE_CONTAINER_HEIGHT - SCROLL_REBASE_TARGET_TOP;
|
|
92
113
|
const SCROLL_REBASE_THRESHOLD = SCROLL_REBASE_CONTAINER_HEIGHT - SCROLL_REBASE_TRIGGER_TOP;
|
|
93
|
-
const CODE_VIEW_ELEMENT_POOL_LIMIT = 32;
|
|
94
114
|
const MOBILE_SAFARI = (() => {
|
|
95
115
|
const { navigator } = globalThis;
|
|
96
116
|
const userAgent = navigator.userAgent;
|
|
@@ -112,6 +132,8 @@ var CodeView = class CodeView {
|
|
|
112
132
|
selectedLines = null;
|
|
113
133
|
instanceToItem = /* @__PURE__ */ new Map();
|
|
114
134
|
layoutDirtyIndex;
|
|
135
|
+
pendingLayoutReset;
|
|
136
|
+
renderOptionsRevision = 0;
|
|
115
137
|
slotCoordinator;
|
|
116
138
|
slotSnapshot;
|
|
117
139
|
scrollListeners = /* @__PURE__ */ new Set();
|
|
@@ -138,6 +160,8 @@ var CodeView = class CodeView {
|
|
|
138
160
|
stickyBottom: -1
|
|
139
161
|
};
|
|
140
162
|
itemMetricsCache = DEFAULT_CODE_VIEW_FILE_METRICS;
|
|
163
|
+
fileOptionsPrototype;
|
|
164
|
+
diffOptionsPrototype;
|
|
141
165
|
pendingScrollTarget;
|
|
142
166
|
pendingLayoutAnchor;
|
|
143
167
|
scrollAnimation;
|
|
@@ -147,6 +171,8 @@ var CodeView = class CodeView {
|
|
|
147
171
|
stickyContainer = document.createElement("div");
|
|
148
172
|
stickyOffset = document.createElement("div");
|
|
149
173
|
elementPool = [];
|
|
174
|
+
elementPoolVersion = 0;
|
|
175
|
+
elementPoolTracker = /* @__PURE__ */ new WeakMap();
|
|
150
176
|
pendingElementPool = [];
|
|
151
177
|
options;
|
|
152
178
|
workerManager;
|
|
@@ -154,6 +180,8 @@ var CodeView = class CodeView {
|
|
|
154
180
|
constructor(options = { theme: DEFAULT_THEMES }, workerManager, isContainerManaged = false) {
|
|
155
181
|
this.options = options;
|
|
156
182
|
this.computeMetricsCache(options.itemMetrics);
|
|
183
|
+
this.fileOptionsPrototype = this.createFileOptionsPrototype();
|
|
184
|
+
this.diffOptionsPrototype = this.createDiffOptionsPrototype();
|
|
157
185
|
this.workerManager = workerManager;
|
|
158
186
|
this.isContainerManaged = isContainerManaged;
|
|
159
187
|
this.stickyOffset.style.contain = "layout size";
|
|
@@ -249,6 +277,7 @@ var CodeView = class CodeView {
|
|
|
249
277
|
}
|
|
250
278
|
setup(root) {
|
|
251
279
|
if (this.root != null) throw new Error("CodeView.setup: already setup");
|
|
280
|
+
this.workerManager?.subscribeToThemeChanges(this);
|
|
252
281
|
this.root = root;
|
|
253
282
|
this.root.style.overflowAnchor = "none";
|
|
254
283
|
this.container ??= document.createElement("div");
|
|
@@ -291,6 +320,7 @@ var CodeView = class CodeView {
|
|
|
291
320
|
this.idToItem.clear();
|
|
292
321
|
this.instanceToItem.clear();
|
|
293
322
|
this.layoutDirtyIndex = void 0;
|
|
323
|
+
this.pendingLayoutReset = void 0;
|
|
294
324
|
this.stickyContainer.textContent = "";
|
|
295
325
|
this.stickyOffset.style.height = "";
|
|
296
326
|
this.container?.style.removeProperty("height");
|
|
@@ -313,6 +343,7 @@ var CodeView = class CodeView {
|
|
|
313
343
|
this.reset();
|
|
314
344
|
this.clearElementPool();
|
|
315
345
|
this.restoreScrollInteractions();
|
|
346
|
+
this.workerManager?.unsubscribeToThemeChanges(this);
|
|
316
347
|
this.resizeObserver?.disconnect();
|
|
317
348
|
this.resizeObserver = void 0;
|
|
318
349
|
this.root?.removeEventListener("scroll", this.handleScroll);
|
|
@@ -342,9 +373,18 @@ var CodeView = class CodeView {
|
|
|
342
373
|
if (item == null) return;
|
|
343
374
|
item.instance.primeHighlightCache();
|
|
344
375
|
}
|
|
376
|
+
getElementPoolLimit() {
|
|
377
|
+
const viewportSize = this.getHeight() + this.config.overscrollSize * 2;
|
|
378
|
+
const { diffHeaderHeight } = this.itemMetricsCache;
|
|
379
|
+
return Math.max(8, Math.ceil(viewportSize / Math.max(diffHeaderHeight, 10)) + 1) * (this.isContainerManaged ? 2 : 1);
|
|
380
|
+
}
|
|
345
381
|
acquireElement() {
|
|
346
382
|
this.promotePendingPooledElements();
|
|
347
|
-
|
|
383
|
+
let element = this.elementPool.pop();
|
|
384
|
+
while (element != null && !this.isElementPoolGenerationCurrent(element)) element = this.elementPool.pop();
|
|
385
|
+
element ??= document.createElement(DIFFS_TAG_NAME);
|
|
386
|
+
this.markElementPoolGenerationCurrent(element);
|
|
387
|
+
return element;
|
|
348
388
|
}
|
|
349
389
|
releaseRenderedItem(item) {
|
|
350
390
|
const { element } = item;
|
|
@@ -352,10 +392,10 @@ var CodeView = class CodeView {
|
|
|
352
392
|
item.element = void 0;
|
|
353
393
|
if (element == null) return;
|
|
354
394
|
element.remove();
|
|
355
|
-
this.
|
|
395
|
+
this.cleanElement(element);
|
|
356
396
|
this.queueElementForPool(element);
|
|
357
397
|
}
|
|
358
|
-
|
|
398
|
+
cleanElement(element) {
|
|
359
399
|
const { shadowRoot } = element;
|
|
360
400
|
if (shadowRoot != null) {
|
|
361
401
|
for (const child of Array.from(shadowRoot.children)) if (!isPooledShadowChild(child)) child.remove();
|
|
@@ -363,7 +403,8 @@ var CodeView = class CodeView {
|
|
|
363
403
|
if (!this.isContainerManaged) element.replaceChildren();
|
|
364
404
|
}
|
|
365
405
|
queueElementForPool(element) {
|
|
366
|
-
|
|
406
|
+
const poolLimit = this.getElementPoolLimit();
|
|
407
|
+
if (!this.isElementPoolGenerationCurrent(element) || this.getElementPoolSize() >= poolLimit) return;
|
|
367
408
|
if (this.isElementClean(element)) this.elementPool.push(element);
|
|
368
409
|
else this.pendingElementPool.push(element);
|
|
369
410
|
}
|
|
@@ -371,8 +412,9 @@ var CodeView = class CodeView {
|
|
|
371
412
|
if (this.pendingElementPool.length === 0) return;
|
|
372
413
|
const { pendingElementPool: pendingElements } = this;
|
|
373
414
|
this.pendingElementPool = [];
|
|
374
|
-
|
|
375
|
-
|
|
415
|
+
const poolLimit = this.getElementPoolLimit();
|
|
416
|
+
for (const element of pendingElements) if (this.isElementPoolGenerationCurrent(element) && this.isElementClean(element) && this.elementPool.length < poolLimit) this.elementPool.push(element);
|
|
417
|
+
else if (this.isElementPoolGenerationCurrent(element) && this.getElementPoolSize() < poolLimit) this.pendingElementPool.push(element);
|
|
376
418
|
}
|
|
377
419
|
isElementClean(element) {
|
|
378
420
|
return element.childNodes.length === 0;
|
|
@@ -384,6 +426,16 @@ var CodeView = class CodeView {
|
|
|
384
426
|
this.elementPool.length = 0;
|
|
385
427
|
this.pendingElementPool.length = 0;
|
|
386
428
|
}
|
|
429
|
+
invalidateElementPool() {
|
|
430
|
+
this.elementPoolVersion++;
|
|
431
|
+
this.clearElementPool();
|
|
432
|
+
}
|
|
433
|
+
markElementPoolGenerationCurrent(element) {
|
|
434
|
+
this.elementPoolTracker.set(element, this.elementPoolVersion);
|
|
435
|
+
}
|
|
436
|
+
isElementPoolGenerationCurrent(element) {
|
|
437
|
+
return this.elementPoolTracker.get(element) === this.elementPoolVersion;
|
|
438
|
+
}
|
|
387
439
|
resolveEffectiveScrollBehavior(target, destination) {
|
|
388
440
|
if (prefersReducedMotion()) return "instant";
|
|
389
441
|
if (target.behavior !== "smooth-auto") return target.behavior ?? "instant";
|
|
@@ -446,8 +498,7 @@ var CodeView = class CodeView {
|
|
|
446
498
|
this.idToItem.delete(oldId);
|
|
447
499
|
item.item.id = newId;
|
|
448
500
|
this.idToItem.set(newId, item);
|
|
449
|
-
|
|
450
|
-
else item.instance.setOptions(this.createOptions(item.item));
|
|
501
|
+
this.updateItemOptionsId(item.instance.options, newId);
|
|
451
502
|
if (this.selectedLines?.id === oldId) {
|
|
452
503
|
this.selectedLines = {
|
|
453
504
|
...this.selectedLines,
|
|
@@ -504,25 +555,36 @@ var CodeView = class CodeView {
|
|
|
504
555
|
canSkipRenderForAppend(appendedTop) {
|
|
505
556
|
return this.container != null && this.renderState.firstIndex !== -1 && this.pendingScrollTarget == null && this.scrollAnimation == null && this.layoutDirtyIndex == null && appendedTop > this.windowSpecs.bottom;
|
|
506
557
|
}
|
|
558
|
+
onThemeChange() {
|
|
559
|
+
this.invalidateElementPool();
|
|
560
|
+
}
|
|
507
561
|
setOptions(options) {
|
|
508
562
|
if (options == null) return;
|
|
509
563
|
this.capturePendingLayoutAnchor();
|
|
564
|
+
const { options: prevOptions } = this;
|
|
510
565
|
const previousLayout = this.getLayout();
|
|
511
566
|
const { itemMetricsCache: previousItemMetrics } = this;
|
|
512
|
-
if (shouldClearPool(
|
|
567
|
+
if (shouldClearPool(prevOptions, options)) this.invalidateElementPool();
|
|
513
568
|
this.options = options;
|
|
514
569
|
const nextItemMetrics = this.computeMetricsCache(options.itemMetrics);
|
|
515
570
|
const itemMetricsChanged = !areObjectsEqual(previousItemMetrics, nextItemMetrics);
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
571
|
+
const layoutChanged = !areObjectsEqual(previousLayout, this.getLayout());
|
|
572
|
+
if (layoutChanged) this.syncLayout();
|
|
573
|
+
const itemLayoutChanged = itemMetricsChanged || hasItemLayoutOptionChanged(prevOptions, options);
|
|
574
|
+
if (itemLayoutChanged) {
|
|
575
|
+
const previousReset = this.pendingLayoutReset;
|
|
576
|
+
this.pendingLayoutReset = {
|
|
577
|
+
metrics: itemMetricsChanged ? nextItemMetrics : previousReset?.metrics,
|
|
578
|
+
resetFileLayoutCache: true,
|
|
579
|
+
resetDiffLayoutCache: true,
|
|
580
|
+
includeEstimatedDiffHeights: previousReset?.includeEstimatedDiffHeights === true || itemMetricsChanged || hasCodeViewDiffEstimateOptionChanged(prevOptions, options)
|
|
581
|
+
};
|
|
523
582
|
}
|
|
524
|
-
|
|
525
|
-
|
|
583
|
+
if (layoutChanged || itemLayoutChanged) {
|
|
584
|
+
this.markLayoutDirtyFromIndex(0);
|
|
585
|
+
this.scrollDirty = true;
|
|
586
|
+
}
|
|
587
|
+
if (!areOptionsEqual(prevOptions, options)) this.renderOptionsRevision++;
|
|
526
588
|
if (!this.isContainerManaged && this.items.length > 0) this.render();
|
|
527
589
|
}
|
|
528
590
|
capturePendingLayoutAnchor() {
|
|
@@ -601,41 +663,33 @@ var CodeView = class CodeView {
|
|
|
601
663
|
}
|
|
602
664
|
createItem(input, index, top) {
|
|
603
665
|
const { itemMetricsCache: itemMetrics } = this;
|
|
604
|
-
if (input.type === "diff")
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
666
|
+
if (input.type === "diff") {
|
|
667
|
+
const instance$1 = new VirtualizedFileDiff(this.createDiffOptions(input.id), this, itemMetrics, this.workerManager, this.isContainerManaged);
|
|
668
|
+
return {
|
|
669
|
+
type: "diff",
|
|
670
|
+
item: input,
|
|
671
|
+
version: input.version,
|
|
672
|
+
index,
|
|
673
|
+
top,
|
|
674
|
+
height: 0,
|
|
675
|
+
element: void 0,
|
|
676
|
+
renderedOptionsRevision: this.renderOptionsRevision,
|
|
677
|
+
instance: instance$1
|
|
678
|
+
};
|
|
679
|
+
}
|
|
680
|
+
const instance = new VirtualizedFile(this.createFileOptions(input.id), this, itemMetrics, this.workerManager, this.isContainerManaged);
|
|
614
681
|
return {
|
|
615
682
|
type: "file",
|
|
616
683
|
item: input,
|
|
617
684
|
version: input.version,
|
|
618
685
|
index,
|
|
619
|
-
instance: new VirtualizedFile(this.createOptions(input), this, itemMetrics, this.workerManager, this.isContainerManaged),
|
|
620
686
|
top,
|
|
621
687
|
height: 0,
|
|
622
|
-
element: void 0
|
|
688
|
+
element: void 0,
|
|
689
|
+
renderedOptionsRevision: this.renderOptionsRevision,
|
|
690
|
+
instance
|
|
623
691
|
};
|
|
624
692
|
}
|
|
625
|
-
getItemById(itemId) {
|
|
626
|
-
const item = this.idToItem.get(itemId);
|
|
627
|
-
if (item == null) console.error(`CodeView.getItemById: unknown item id "${itemId}"`);
|
|
628
|
-
return item;
|
|
629
|
-
}
|
|
630
|
-
getItemByMode(itemId, mode) {
|
|
631
|
-
const item = this.getItemById(itemId);
|
|
632
|
-
if (item == null) return;
|
|
633
|
-
if (item.type !== mode) {
|
|
634
|
-
console.error(`CodeView.getItemByMode: item id "${itemId}" is not a ${mode}`);
|
|
635
|
-
return;
|
|
636
|
-
}
|
|
637
|
-
return item;
|
|
638
|
-
}
|
|
639
693
|
applySelectedLines(selection, options) {
|
|
640
694
|
const { selectedLines: prevSelection } = this;
|
|
641
695
|
if (selection == null && prevSelection == null || selection != null && prevSelection?.id === selection.id && areSelectionsEqual(prevSelection.range, selection.range)) return;
|
|
@@ -663,57 +717,86 @@ var CodeView = class CodeView {
|
|
|
663
717
|
renamePendingLayoutAnchor(oldId, newId) {
|
|
664
718
|
if (this.pendingLayoutAnchor?.id === oldId) this.pendingLayoutAnchor.id = newId;
|
|
665
719
|
}
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
720
|
+
createFileOptionsPrototype() {
|
|
721
|
+
const prototype = {};
|
|
722
|
+
for (const key of CODE_VIEW_FILE_OPTION_KEYS) defineItemOption(prototype, key, () => this.options[key]);
|
|
723
|
+
defineItemOption(prototype, "stickyHeader", () => this.options.stickyHeaders);
|
|
724
|
+
defineItemOption(prototype, "collapsed", (receiver) => this.getItemOptions(getItemOptionsState(receiver), "file")?.item.collapsed === true);
|
|
725
|
+
for (const key of CODE_VIEW_SHARED_CALLBACK_KEYS) this.defineItemSharedCallback(prototype, "file", key);
|
|
726
|
+
for (const key of CODE_VIEW_SELECTION_CALLBACK_KEYS) this.defineItemSelectionCallback(prototype, "file", key);
|
|
727
|
+
return prototype;
|
|
728
|
+
}
|
|
729
|
+
createDiffOptionsPrototype() {
|
|
730
|
+
const prototype = {};
|
|
731
|
+
for (const key of CODE_VIEW_DIFF_OPTION_KEYS) defineItemOption(prototype, key, () => this.options[key]);
|
|
732
|
+
defineItemOption(prototype, "stickyHeader", () => this.options.stickyHeaders);
|
|
733
|
+
defineItemOption(prototype, "hunkSeparators", () => this.options.hunkSeparators);
|
|
734
|
+
defineItemOption(prototype, "collapsed", (receiver) => this.getItemOptions(getItemOptionsState(receiver), "diff")?.item.collapsed === true);
|
|
735
|
+
for (const key of CODE_VIEW_SHARED_CALLBACK_KEYS) this.defineItemSharedCallback(prototype, "diff", key);
|
|
736
|
+
for (const key of CODE_VIEW_SELECTION_CALLBACK_KEYS) this.defineItemSelectionCallback(prototype, "diff", key);
|
|
737
|
+
return prototype;
|
|
738
|
+
}
|
|
739
|
+
createFileOptions(id) {
|
|
740
|
+
const options = Object.create(this.fileOptionsPrototype);
|
|
741
|
+
defineOptionsState(options, { id });
|
|
742
|
+
return options;
|
|
672
743
|
}
|
|
673
|
-
|
|
674
|
-
const
|
|
675
|
-
|
|
676
|
-
return
|
|
677
|
-
}
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
if (this.options
|
|
689
|
-
|
|
744
|
+
createDiffOptions(id) {
|
|
745
|
+
const options = Object.create(this.diffOptionsPrototype);
|
|
746
|
+
defineOptionsState(options, { id });
|
|
747
|
+
return options;
|
|
748
|
+
}
|
|
749
|
+
updateItemOptionsId(options, id) {
|
|
750
|
+
getItemOptionsState(options).id = id;
|
|
751
|
+
}
|
|
752
|
+
getItemOptions(state, mode) {
|
|
753
|
+
const item = this.idToItem.get(state.id);
|
|
754
|
+
if (item == null || item.type !== mode) return;
|
|
755
|
+
return item;
|
|
756
|
+
}
|
|
757
|
+
defineItemSharedCallback(options, mode, key) {
|
|
758
|
+
defineItemOption(options, key, (receiver) => {
|
|
759
|
+
if (this.options[key] == null) return;
|
|
760
|
+
const state = getItemOptionsState(receiver);
|
|
761
|
+
const callbackCache = state.callbackCache ??= {};
|
|
762
|
+
let wrapped = callbackCache[key];
|
|
763
|
+
if (wrapped == null) {
|
|
764
|
+
wrapped = ((...args) => {
|
|
765
|
+
const latest = this.getItemOptions(state, mode);
|
|
766
|
+
if (latest == null) return;
|
|
767
|
+
const callback = this.options[key];
|
|
768
|
+
return callback?.(...args, latest);
|
|
769
|
+
});
|
|
770
|
+
callbackCache[key] = wrapped;
|
|
690
771
|
}
|
|
691
|
-
|
|
692
|
-
return callback?.(range, item);
|
|
772
|
+
return wrapped;
|
|
693
773
|
});
|
|
694
774
|
}
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
775
|
+
defineItemSelectionCallback(options, mode, key) {
|
|
776
|
+
defineItemOption(options, key, (receiver) => {
|
|
777
|
+
if (this.options.enableLineSelection !== true) return;
|
|
778
|
+
const state = getItemOptionsState(receiver);
|
|
779
|
+
const callbackCache = state.callbackCache ??= {};
|
|
780
|
+
let wrapped = callbackCache[key];
|
|
781
|
+
if (wrapped == null) {
|
|
782
|
+
wrapped = ((range) => {
|
|
783
|
+
const latest = this.getItemOptions(state, mode);
|
|
784
|
+
if (latest == null) return;
|
|
785
|
+
const selection = range == null ? null : {
|
|
786
|
+
id: latest.item.id,
|
|
787
|
+
range
|
|
788
|
+
};
|
|
789
|
+
if (this.options.controlledSelection !== true) {
|
|
790
|
+
if (range != null || this.selectedLines?.id === latest.item.id) this.applySelectedLines(selection, { notify: false });
|
|
791
|
+
}
|
|
792
|
+
this.options.onSelectedLinesChange?.(selection);
|
|
793
|
+
const callback = this.options[key];
|
|
794
|
+
return callback?.(range, latest);
|
|
795
|
+
});
|
|
796
|
+
callbackCache[key] = wrapped;
|
|
797
|
+
}
|
|
798
|
+
return wrapped;
|
|
799
|
+
});
|
|
717
800
|
}
|
|
718
801
|
/**
|
|
719
802
|
* Track the earliest index whose measured layout may now be stale. Later
|
|
@@ -815,8 +898,7 @@ var CodeView = class CodeView {
|
|
|
815
898
|
if (item.version === nextItem.version) return false;
|
|
816
899
|
item.item = nextItem;
|
|
817
900
|
item.version = nextItem.version;
|
|
818
|
-
|
|
819
|
-
else item.instance.setOptions(this.createOptions(item.item));
|
|
901
|
+
item.renderedOptionsRevision = -1;
|
|
820
902
|
return true;
|
|
821
903
|
}
|
|
822
904
|
getMaxScrollTopForHeight(scrollHeight) {
|
|
@@ -1095,8 +1177,9 @@ var CodeView = class CodeView {
|
|
|
1095
1177
|
let computeScrollCorrection = this.pendingLayoutAnchor != null;
|
|
1096
1178
|
let scrollAnchor = this.getScrollAnchor(scrollTopAfterLayout);
|
|
1097
1179
|
if (this.layoutDirtyIndex != null) {
|
|
1098
|
-
this.recomputeLayout(this.layoutDirtyIndex);
|
|
1180
|
+
this.recomputeLayout(this.layoutDirtyIndex, this.pendingLayoutReset);
|
|
1099
1181
|
this.layoutDirtyIndex = void 0;
|
|
1182
|
+
this.pendingLayoutReset = void 0;
|
|
1100
1183
|
computeScrollCorrection = true;
|
|
1101
1184
|
}
|
|
1102
1185
|
if (computeScrollCorrection && scrollAnchor != null) {
|
|
@@ -1146,11 +1229,17 @@ var CodeView = class CodeView {
|
|
|
1146
1229
|
item.element = this.acquireElement();
|
|
1147
1230
|
syncRenderedItemOrder(this.stickyContainer, item.element, prevElement);
|
|
1148
1231
|
instance.virtualizedSetup();
|
|
1149
|
-
if (renderItem(item, item.element))
|
|
1232
|
+
if (renderItem(item, item.element)) {
|
|
1233
|
+
item.renderedOptionsRevision = this.renderOptionsRevision;
|
|
1234
|
+
updatedItems.add(item);
|
|
1235
|
+
}
|
|
1150
1236
|
prevElement = item.element;
|
|
1151
1237
|
} else {
|
|
1152
1238
|
syncRenderedItemOrder(this.stickyContainer, item.element, prevElement);
|
|
1153
|
-
if (renderItem(item))
|
|
1239
|
+
if (renderItem(item, void 0, item.renderedOptionsRevision !== this.renderOptionsRevision)) {
|
|
1240
|
+
item.renderedOptionsRevision = this.renderOptionsRevision;
|
|
1241
|
+
updatedItems.add(item);
|
|
1242
|
+
}
|
|
1154
1243
|
prevElement = item.element;
|
|
1155
1244
|
}
|
|
1156
1245
|
}
|
|
@@ -1475,7 +1564,7 @@ var CodeView = class CodeView {
|
|
|
1475
1564
|
* onward is remeasured so downstream positions and total scroll height stay
|
|
1476
1565
|
* consistent after inserts, removals, or versioned item updates.
|
|
1477
1566
|
*/
|
|
1478
|
-
recomputeLayout(startIndex = 0) {
|
|
1567
|
+
recomputeLayout(startIndex = 0, reset) {
|
|
1479
1568
|
if (this.items.length === 0) {
|
|
1480
1569
|
this.scrollHeight = 0;
|
|
1481
1570
|
return;
|
|
@@ -1491,8 +1580,8 @@ var CodeView = class CodeView {
|
|
|
1491
1580
|
const item = this.items[index];
|
|
1492
1581
|
if (item == null) throw new Error("CodeView.recomputeLayout: invalid item index");
|
|
1493
1582
|
item.top = runningTop;
|
|
1494
|
-
if (item.type === "diff") item.height = item.instance.
|
|
1495
|
-
else item.height = item.instance.
|
|
1583
|
+
if (item.type === "diff") item.height = item.instance.prepareCodeViewItem(item.item.fileDiff, runningTop, reset);
|
|
1584
|
+
else item.height = item.instance.prepareCodeViewItem(item.item.file, runningTop, reset);
|
|
1496
1585
|
runningTop += item.height;
|
|
1497
1586
|
if (index < this.items.length - 1) runningTop += layout.gap;
|
|
1498
1587
|
}
|
|
@@ -1513,12 +1602,18 @@ var CodeView = class CodeView {
|
|
|
1513
1602
|
};
|
|
1514
1603
|
function prepareItemInstance(item) {
|
|
1515
1604
|
item.instance.cleanUp(true);
|
|
1516
|
-
if (item.type === "diff") return item.instance.
|
|
1517
|
-
else return item.instance.
|
|
1605
|
+
if (item.type === "diff") return item.instance.prepareCodeViewItem(item.item.fileDiff, item.top);
|
|
1606
|
+
else return item.instance.prepareCodeViewItem(item.item.file, item.top);
|
|
1518
1607
|
}
|
|
1519
1608
|
function shouldClearPool(previousOptions, nextOptions) {
|
|
1520
1609
|
return !areThemesEqual(previousOptions.theme ?? DEFAULT_THEMES, nextOptions.theme ?? DEFAULT_THEMES) || (previousOptions.themeType ?? "system") !== (nextOptions.themeType ?? "system") || previousOptions.unsafeCSS !== nextOptions.unsafeCSS;
|
|
1521
1610
|
}
|
|
1611
|
+
function hasItemLayoutOptionChanged(previousOptions, nextOptions) {
|
|
1612
|
+
return (previousOptions.overflow ?? "scroll") !== (nextOptions.overflow ?? "scroll") || (previousOptions.disableLineNumbers ?? false) !== (nextOptions.disableLineNumbers ?? false) || (previousOptions.disableFileHeader ?? false) !== (nextOptions.disableFileHeader ?? false) || previousOptions.unsafeCSS !== nextOptions.unsafeCSS || (previousOptions.diffStyle ?? "split") !== (nextOptions.diffStyle ?? "split") || (previousOptions.diffIndicators ?? "bars") !== (nextOptions.diffIndicators ?? "bars") || (previousOptions.hunkSeparators ?? "line-info") !== (nextOptions.hunkSeparators ?? "line-info") || (previousOptions.expandUnchanged ?? false) !== (nextOptions.expandUnchanged ?? false) || (previousOptions.collapsedContextThreshold ?? DEFAULT_COLLAPSED_CONTEXT_THRESHOLD) !== (nextOptions.collapsedContextThreshold ?? DEFAULT_COLLAPSED_CONTEXT_THRESHOLD);
|
|
1613
|
+
}
|
|
1614
|
+
function hasCodeViewDiffEstimateOptionChanged(previousOptions, nextOptions) {
|
|
1615
|
+
return (previousOptions.disableFileHeader ?? false) !== (nextOptions.disableFileHeader ?? false) || (previousOptions.hunkSeparators ?? "line-info") !== (nextOptions.hunkSeparators ?? "line-info") || (previousOptions.expandUnchanged ?? false) !== (nextOptions.expandUnchanged ?? false) || (previousOptions.collapsedContextThreshold ?? DEFAULT_COLLAPSED_CONTEXT_THRESHOLD) !== (nextOptions.collapsedContextThreshold ?? DEFAULT_COLLAPSED_CONTEXT_THRESHOLD);
|
|
1616
|
+
}
|
|
1522
1617
|
function isPooledShadowChild(child) {
|
|
1523
1618
|
if (child instanceof SVGElement) return true;
|
|
1524
1619
|
return isStyleNode(child) && (child.hasAttribute(CORE_CSS_ATTRIBUTE) || child.hasAttribute(THEME_CSS_ATTRIBUTE) || child.hasAttribute(UNSAFE_CSS_ATTRIBUTE));
|
|
@@ -1532,17 +1627,19 @@ function formatSelectedLinePoint(lineNumber, side) {
|
|
|
1532
1627
|
if (side == null) return `${lineNumber}`;
|
|
1533
1628
|
return `${side === "deletions" ? "D" : "A"}${lineNumber}`;
|
|
1534
1629
|
}
|
|
1535
|
-
function renderItem(item, fileContainer) {
|
|
1630
|
+
function renderItem(item, fileContainer, forceRender = false) {
|
|
1536
1631
|
if (item.type === "diff") return item.instance.render({
|
|
1537
1632
|
deferManagers: true,
|
|
1538
1633
|
fileContainer,
|
|
1539
1634
|
fileDiff: item.item.fileDiff,
|
|
1635
|
+
forceRender,
|
|
1540
1636
|
lineAnnotations: item.item.annotations
|
|
1541
1637
|
});
|
|
1542
1638
|
else return item.instance.render({
|
|
1543
1639
|
deferManagers: true,
|
|
1544
1640
|
fileContainer,
|
|
1545
1641
|
file: item.item.file,
|
|
1642
|
+
forceRender,
|
|
1546
1643
|
lineAnnotations: item.item.annotations
|
|
1547
1644
|
});
|
|
1548
1645
|
}
|