@pierre/diffs 1.6.0-beta.1 → 1.6.0
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 +3 -2
- package/dist/components/CodeView.d.ts.map +1 -1
- package/dist/components/CodeView.js +18 -14
- package/dist/components/CodeView.js.map +1 -1
- package/dist/components/File.d.ts +31 -9
- package/dist/components/File.d.ts.map +1 -1
- package/dist/components/File.js +165 -84
- package/dist/components/File.js.map +1 -1
- package/dist/components/FileDiff.d.ts +32 -9
- package/dist/components/FileDiff.d.ts.map +1 -1
- package/dist/components/FileDiff.js +213 -124
- package/dist/components/FileDiff.js.map +1 -1
- package/dist/components/UnresolvedFile.d.ts +14 -4
- package/dist/components/UnresolvedFile.d.ts.map +1 -1
- package/dist/components/UnresolvedFile.js +35 -16
- package/dist/components/UnresolvedFile.js.map +1 -1
- package/dist/components/VirtualizedFile.d.ts +3 -2
- package/dist/components/VirtualizedFile.d.ts.map +1 -1
- package/dist/components/VirtualizedFile.js +28 -20
- package/dist/components/VirtualizedFile.js.map +1 -1
- package/dist/components/VirtualizedFileDiff.d.ts +3 -2
- package/dist/components/VirtualizedFileDiff.d.ts.map +1 -1
- package/dist/components/VirtualizedFileDiff.js +31 -24
- package/dist/components/VirtualizedFileDiff.js.map +1 -1
- package/dist/constants.d.ts +2 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +2 -1
- package/dist/constants.js.map +1 -1
- package/dist/editor/platform.d.ts +1 -1
- package/dist/editor/platform.js +5 -4
- package/dist/editor/platform.js.map +1 -1
- package/dist/editor/selection.d.ts +2 -2
- package/dist/editor/selection.d.ts.map +1 -1
- package/dist/editor/selection.js +31 -6
- package/dist/editor/selection.js.map +1 -1
- package/dist/highlighter/shared_highlighter.d.ts +2 -1
- package/dist/highlighter/shared_highlighter.d.ts.map +1 -1
- package/dist/highlighter/shared_highlighter.js +2 -2
- package/dist/highlighter/shared_highlighter.js.map +1 -1
- package/dist/index.d.ts +10 -5
- package/dist/index.js +8 -3
- package/dist/react/CodeView.d.ts +4 -3
- package/dist/react/CodeView.d.ts.map +1 -1
- package/dist/react/CodeView.js +48 -39
- package/dist/react/CodeView.js.map +1 -1
- package/dist/react/File.js +3 -3
- package/dist/react/File.js.map +1 -1
- package/dist/react/FileDiff.js +3 -3
- package/dist/react/FileDiff.js.map +1 -1
- package/dist/react/MultiFileDiff.js +2 -2
- package/dist/react/MultiFileDiff.js.map +1 -1
- package/dist/react/PatchDiff.js +3 -3
- package/dist/react/PatchDiff.js.map +1 -1
- package/dist/react/UnresolvedFile.js +2 -2
- package/dist/react/UnresolvedFile.js.map +1 -1
- package/dist/react/index.d.ts +2 -2
- package/dist/react/types.d.ts +4 -2
- package/dist/react/types.d.ts.map +1 -1
- package/dist/react/utils/renderDiffChildren.js +1 -1
- package/dist/react/utils/renderDiffChildren.js.map +1 -1
- package/dist/react/utils/renderFileChildren.js +1 -1
- package/dist/react/utils/renderFileChildren.js.map +1 -1
- package/dist/react/utils/useFileDiffInstance.d.ts +1 -0
- package/dist/react/utils/useFileDiffInstance.d.ts.map +1 -1
- package/dist/react/utils/useFileDiffInstance.js +29 -24
- package/dist/react/utils/useFileDiffInstance.js.map +1 -1
- package/dist/react/utils/useFileInstance.d.ts +2 -0
- package/dist/react/utils/useFileInstance.d.ts.map +1 -1
- package/dist/react/utils/useFileInstance.js +38 -28
- package/dist/react/utils/useFileInstance.js.map +1 -1
- package/dist/react/utils/useForceUpdate.d.ts +5 -0
- package/dist/react/utils/useForceUpdate.d.ts.map +1 -0
- package/dist/react/utils/useForceUpdate.js +27 -0
- package/dist/react/utils/useForceUpdate.js.map +1 -0
- package/dist/react/utils/useNextRenderData.d.ts +9 -0
- package/dist/react/utils/useNextRenderData.d.ts.map +1 -0
- package/dist/react/utils/useNextRenderData.js +9 -0
- package/dist/react/utils/useNextRenderData.js.map +1 -0
- package/dist/react/utils/useUnresolvedFileInstance.d.ts +1 -0
- package/dist/react/utils/useUnresolvedFileInstance.d.ts.map +1 -1
- package/dist/react/utils/useUnresolvedFileInstance.js +26 -11
- package/dist/react/utils/useUnresolvedFileInstance.js.map +1 -1
- package/dist/renderers/DiffHunksRenderer.d.ts +2 -1
- package/dist/renderers/DiffHunksRenderer.d.ts.map +1 -1
- package/dist/renderers/DiffHunksRenderer.js +62 -32
- package/dist/renderers/DiffHunksRenderer.js.map +1 -1
- package/dist/renderers/FileRenderer.d.ts +4 -1
- package/dist/renderers/FileRenderer.d.ts.map +1 -1
- package/dist/renderers/FileRenderer.js +55 -30
- package/dist/renderers/FileRenderer.js.map +1 -1
- package/dist/renderers/UnresolvedFileHunksRenderer.d.ts.map +1 -1
- package/dist/renderers/UnresolvedFileHunksRenderer.js +1 -1
- package/dist/renderers/UnresolvedFileHunksRenderer.js.map +1 -1
- package/dist/ssr/FileDiffReact.js +1 -1
- package/dist/types.d.ts +10 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/canUseWASM.d.ts +13 -0
- package/dist/utils/canUseWASM.d.ts.map +1 -0
- package/dist/utils/canUseWASM.js +59 -0
- package/dist/utils/canUseWASM.js.map +1 -0
- package/dist/utils/getCodeViewItemRenderData.d.ts +10 -0
- package/dist/utils/getCodeViewItemRenderData.d.ts.map +1 -0
- package/dist/utils/getCodeViewItemRenderData.js +19 -0
- package/dist/utils/getCodeViewItemRenderData.js.map +1 -0
- package/dist/utils/hastToHtml.d.ts +2 -2
- package/dist/utils/hastToHtml.js +2 -2
- package/dist/utils/hastToHtml.js.map +1 -1
- package/dist/utils/hydratePartialDiff.js +4 -0
- package/dist/utils/hydratePartialDiff.js.map +1 -1
- package/dist/utils/parseMergeConflictDiffFromFile.d.ts.map +1 -1
- package/dist/utils/parseMergeConflictDiffFromFile.js +2 -0
- package/dist/utils/parseMergeConflictDiffFromFile.js.map +1 -1
- package/dist/utils/parsePatchFiles.d.ts.map +1 -1
- package/dist/utils/parsePatchFiles.js +24 -4
- package/dist/utils/parsePatchFiles.js.map +1 -1
- package/dist/utils/renderTokenLines.d.ts +6 -1
- package/dist/utils/renderTokenLines.d.ts.map +1 -1
- package/dist/utils/renderTokenLines.js +4 -0
- package/dist/utils/renderTokenLines.js.map +1 -1
- package/dist/utils/resolveRegion.js +20 -10
- package/dist/utils/resolveRegion.js.map +1 -1
- package/dist/utils/tokenStyle.d.ts +5 -1
- package/dist/utils/tokenStyle.d.ts.map +1 -1
- package/dist/utils/tokenStyle.js +5 -1
- package/dist/utils/tokenStyle.js.map +1 -1
- package/dist/utils/tokensToHtml.d.ts +5 -2
- package/dist/utils/tokensToHtml.d.ts.map +1 -1
- package/dist/utils/tokensToHtml.js +5 -2
- package/dist/utils/tokensToHtml.js.map +1 -1
- package/dist/utils/updateDiffHunks.d.ts +2 -2
- package/dist/utils/updateDiffHunks.d.ts.map +1 -1
- package/dist/utils/updateDiffHunks.js +7 -3
- package/dist/utils/updateDiffHunks.js.map +1 -1
- package/dist/worker/WorkerPoolManager.d.ts +12 -0
- package/dist/worker/WorkerPoolManager.d.ts.map +1 -1
- package/dist/worker/WorkerPoolManager.js +99 -21
- package/dist/worker/WorkerPoolManager.js.map +1 -1
- package/dist/worker/{highlights-sAHlxqlf.js → highlights-CpZm9DAR.js} +2 -2
- package/dist/worker/{highlights-sAHlxqlf.js.map → highlights-CpZm9DAR.js.map} +1 -1
- package/dist/worker/{shiki-Bx2JpdqZ.js → shiki-Ci4cdHsM.js} +2 -2
- package/dist/worker/{shiki-Bx2JpdqZ.js.map → shiki-Ci4cdHsM.js.map} +1 -1
- package/dist/worker/{stream-tokenizer-YZ6M1qSx.js → stream-tokenizer-DK9xp5M5.js} +8 -5
- package/dist/worker/stream-tokenizer-DK9xp5M5.js.map +1 -0
- package/dist/worker/types.d.ts +11 -0
- package/dist/worker/types.d.ts.map +1 -1
- package/dist/worker/worker-portable.js +2 -2
- package/dist/worker/worker-portable.js.map +1 -1
- package/dist/worker/worker.js +12 -3
- package/dist/worker/worker.js.map +1 -1
- package/package.json +28 -30
- package/dist/worker/stream-tokenizer-YZ6M1qSx.js.map +0 -1
|
@@ -2,7 +2,7 @@ import { FileContents, FileDiffMetadata, MergeConflictActionPayload, MergeConfli
|
|
|
2
2
|
import { WorkerPoolManager } from "../worker/WorkerPoolManager.js";
|
|
3
3
|
import "../worker/index.js";
|
|
4
4
|
import { HunksRenderResult } from "../renderers/DiffHunksRenderer.js";
|
|
5
|
-
import { FileDiff, FileDiffOptions, FileDiffRenderBaseProps } from "./FileDiff.js";
|
|
5
|
+
import { FileDiff, FileDiffOptions, FileDiffRenderBaseProps, FileDiffRenderData, FileDiffRenderInput } from "./FileDiff.js";
|
|
6
6
|
import { MergeConflictDiffAction } from "../utils/parseMergeConflictDiffFromFile.js";
|
|
7
7
|
import { UnresolvedFileHunksRenderer, UnresolvedFileHunksRendererOptions } from "../renderers/UnresolvedFileHunksRenderer.js";
|
|
8
8
|
//#region src/components/UnresolvedFile.d.ts
|
|
@@ -38,6 +38,14 @@ interface ResolveConflictReturn {
|
|
|
38
38
|
markerRows: MergeConflictMarkerRow[];
|
|
39
39
|
}
|
|
40
40
|
type UnresolvedFileDataCache = GetOrComputeDiffProps;
|
|
41
|
+
interface UnresolvedFileRenderInput<LAnnotation> extends FileDiffRenderInput<LAnnotation> {
|
|
42
|
+
actions: (MergeConflictDiffAction | undefined)[];
|
|
43
|
+
markerRows: MergeConflictMarkerRow[];
|
|
44
|
+
}
|
|
45
|
+
interface UnresolvedFileRenderData<LAnnotation> extends FileDiffRenderData<LAnnotation> {
|
|
46
|
+
actions: (MergeConflictDiffAction | undefined)[];
|
|
47
|
+
markerRows: MergeConflictMarkerRow[];
|
|
48
|
+
}
|
|
41
49
|
declare class UnresolvedFile<LAnnotation = undefined> extends FileDiff<LAnnotation, undefined> {
|
|
42
50
|
options: UnresolvedFileOptions<LAnnotation>;
|
|
43
51
|
readonly __id: string;
|
|
@@ -45,8 +53,9 @@ declare class UnresolvedFile<LAnnotation = undefined> extends FileDiff<LAnnotati
|
|
|
45
53
|
protected computedCache: UnresolvedFileDataCache;
|
|
46
54
|
private conflictActions;
|
|
47
55
|
private markerRows;
|
|
56
|
+
__getNextRenderData({ actions, markerRows, ...input }: UnresolvedFileRenderInput<LAnnotation>): UnresolvedFileRenderData<LAnnotation>;
|
|
48
57
|
private conflictActionCache;
|
|
49
|
-
constructor(options?: UnresolvedFileOptions<LAnnotation>, workerManager?: WorkerPoolManager | undefined,
|
|
58
|
+
constructor(options?: UnresolvedFileOptions<LAnnotation>, workerManager?: WorkerPoolManager | undefined, requestOwnerRender?: () => void);
|
|
50
59
|
setOptions(options: UnresolvedFileOptions<LAnnotation> | undefined): void;
|
|
51
60
|
protected syncInteractionOptions(): void;
|
|
52
61
|
protected createHunksRenderer(options: UnresolvedFileOptions<LAnnotation>): UnresolvedFileHunksRenderer<LAnnotation>;
|
|
@@ -59,7 +68,8 @@ declare class UnresolvedFile<LAnnotation = undefined> extends FileDiff<LAnnotati
|
|
|
59
68
|
render(props?: UnresolvedFileRenderProps<LAnnotation>): boolean;
|
|
60
69
|
resolveConflict(conflictIndex: number, resolution: MergeConflictResolution, fileDiff?: FileDiffMetadata | undefined): ResolveConflictReturn | undefined;
|
|
61
70
|
private resolveConflictAndRender;
|
|
62
|
-
|
|
71
|
+
protected prepareRenderData(fileDiff: FileDiffMetadata): void;
|
|
72
|
+
protected adoptRenderData(fileDiff: FileDiffMetadata): void;
|
|
63
73
|
private handleMergeConflictActionClick;
|
|
64
74
|
private renderMergeConflictActionSlots;
|
|
65
75
|
private renderMergeConflictAction;
|
|
@@ -67,5 +77,5 @@ declare class UnresolvedFile<LAnnotation = undefined> extends FileDiff<LAnnotati
|
|
|
67
77
|
}
|
|
68
78
|
declare function getUnresolvedDiffHunksRendererOptions<LAnnotation>(options?: UnresolvedFileOptions<LAnnotation>, baseOptions?: UnresolvedFileOptions<LAnnotation>): UnresolvedFileHunksRendererOptions;
|
|
69
79
|
//#endregion
|
|
70
|
-
export { MergeConflictActionsTypeOption, RenderMergeConflictActions, UnresolvedFile, UnresolvedFileHydrationProps, UnresolvedFileOptions, UnresolvedFileRenderProps, getUnresolvedDiffHunksRendererOptions };
|
|
80
|
+
export { MergeConflictActionsTypeOption, RenderMergeConflictActions, UnresolvedFile, UnresolvedFileHydrationProps, UnresolvedFileOptions, UnresolvedFileRenderData, UnresolvedFileRenderInput, UnresolvedFileRenderProps, getUnresolvedDiffHunksRendererOptions };
|
|
71
81
|
//# sourceMappingURL=UnresolvedFile.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UnresolvedFile.d.ts","names":[],"sources":["../../src/components/UnresolvedFile.ts"],"mappings":";;;;;;;;
|
|
1
|
+
{"version":3,"file":"UnresolvedFile.d.ts","names":[],"sources":["../../src/components/UnresolvedFile.ts"],"mappings":";;;;;;;;KAwCY,2BAA2B,gBACrC,QAAQ,yBACR,UAAU,eAAe,iBACtB,cAAc;KAEP,+BAA+B,oCAGvC,2BAA2B;UAEd,sBAAsB,qBAAqB,KAC1D,gBAAgB;EAGhB,cACE,MAAM,aACN,UAAU,eAAe,cACzB,OAAO;EAET,2BAA2B,+BAA+B;EAC1D,uBACE,SAAS,4BACT,UAAU,eAAe;EAE3B,wBACE,MAAM,cACN,SAAS;EAEX;;UAGe,0BACf,qBACQ,wBAAwB;EAChC,OAAO;EACP,WAAW;EACX,aAAa;;UAGE,6BAA6B,qBAAqB,KACjE,0BAA0B;EAG1B,OAAO;EACP,eAAe;EACf;;UAQQ;EACR,MAAM;EACN,UAAU;EACV,UAAU;EACV,YAAY;;UASJ;EACR,MAAM;EACN,UAAU;EACV,UAAU;EACV,YAAY;;KAGT,0BAA0B;UAEd,0BACf,qBACQ,oBAAoB;EAC5B,UAAU;EACV,YAAY;;UAGG,yBACf,qBACQ,mBAAmB;EAC3B,UAAU;EACV,YAAY;;cAKD,eAAe,iCAAiC,SAC3D;EAiCkB,SAAS,sBAAsB;WA9B/B;WACA;YAER,eAAe;UAMjB;UACA;EAEQ,sBACd,SACA,eACG,SACF,0BAA0B,eAAe,yBAAyB;UAU7D;EAGR,YACkB,UAAS,sBAAsB,cAG/C,gBAAgB,+BAChB;EAMO,WACP,SAAS,sBAAsB;YAyBd;YAeA,oBACjB,SAAS,sBAAsB,eAC9B,4BAA4B;YAUZ,wBACjB,SAAS,sBAAsB,eAC9B;YAIgB,uBACjB,KAAK,gBACL,QAAQ;EAOD;UAcD;EA6HC,QAAQ,OAAO,6BAA6B;EA8C5C;EAQA,OAAO,QAAO,0BAA0B;EAkC1C,gBACL,uBACA,YAAY,yBACZ,WAAU,+BACT;UA+BK;YAoDW,kBAAkB,UAAU;YAe5B,gBAAgB,UAAU;UAQrC;UAoCA;UA+DA;UAyBA;;iBAyNM,sCAAsC,aACpD,UAAU,sBAAsB,cAChC,cAAc,sBAAsB,eACnC"}
|
|
@@ -2,6 +2,7 @@ import { DEFAULT_THEMES } from "../constants.js";
|
|
|
2
2
|
import { pluckInteractionOptions } from "../managers/InteractionManager.js";
|
|
3
3
|
import { createAnnotationWrapperNode } from "../utils/createAnnotationWrapperNode.js";
|
|
4
4
|
import { shouldUseTokenTransformer } from "../utils/shouldUseTokenTransformer.js";
|
|
5
|
+
import { areDiffTargetsEqual } from "../utils/areDiffTargetsEqual.js";
|
|
5
6
|
import { areFilesEqual } from "../utils/areFilesEqual.js";
|
|
6
7
|
import { splitFileContents } from "../utils/splitFileContents.js";
|
|
7
8
|
import { FileDiff } from "./FileDiff.js";
|
|
@@ -24,9 +25,18 @@ var UnresolvedFile = class extends FileDiff {
|
|
|
24
25
|
};
|
|
25
26
|
conflictActions = [];
|
|
26
27
|
markerRows = [];
|
|
28
|
+
__getNextRenderData({ actions, markerRows, ...input }) {
|
|
29
|
+
const data = super.__getNextRenderData(input);
|
|
30
|
+
const isInput = areDiffTargetsEqual(data.fileDiff, input.fileDiff);
|
|
31
|
+
return {
|
|
32
|
+
...data,
|
|
33
|
+
actions: isInput ? actions : this.conflictActions,
|
|
34
|
+
markerRows: isInput ? markerRows : this.markerRows
|
|
35
|
+
};
|
|
36
|
+
}
|
|
27
37
|
conflictActionCache = /* @__PURE__ */ new Map();
|
|
28
|
-
constructor(options = { theme: DEFAULT_THEMES }, workerManager,
|
|
29
|
-
super(void 0, workerManager,
|
|
38
|
+
constructor(options = { theme: DEFAULT_THEMES }, workerManager, requestOwnerRender) {
|
|
39
|
+
super(void 0, workerManager, requestOwnerRender);
|
|
30
40
|
this.options = options;
|
|
31
41
|
this.setOptions(options);
|
|
32
42
|
}
|
|
@@ -59,6 +69,7 @@ var UnresolvedFile = class extends FileDiff {
|
|
|
59
69
|
markerRows: void 0
|
|
60
70
|
};
|
|
61
71
|
this.conflictActions = [];
|
|
72
|
+
this.markerRows = [];
|
|
62
73
|
super.cleanUp();
|
|
63
74
|
}
|
|
64
75
|
getOrComputeDiff({ file, fileDiff, actions, markerRows }) {
|
|
@@ -129,7 +140,7 @@ var UnresolvedFile = class extends FileDiff {
|
|
|
129
140
|
});
|
|
130
141
|
if (source == null) return;
|
|
131
142
|
this.hydrateElements(fileContainer, prerenderedHTML);
|
|
132
|
-
this.
|
|
143
|
+
this.prepareRenderData(source.fileDiff);
|
|
133
144
|
if (shouldRenderCode(this.pre, source.fileDiff, this.options.collapsed) || shouldRenderHeader(this.headerElement, source.fileDiff, this.options.disableFileHeader)) this.render({
|
|
134
145
|
...props,
|
|
135
146
|
preventEmit: true
|
|
@@ -144,7 +155,8 @@ var UnresolvedFile = class extends FileDiff {
|
|
|
144
155
|
if (!preventEmit) this.emitPostRender();
|
|
145
156
|
}
|
|
146
157
|
rerender() {
|
|
147
|
-
if (!this.enabled || this.fileDiff == null) return;
|
|
158
|
+
if (!this.enabled || this.computedCache.fileDiff == null) return;
|
|
159
|
+
if (this.requestRender()) return;
|
|
148
160
|
this.render({
|
|
149
161
|
forceRender: true,
|
|
150
162
|
renderRange: this.renderRange
|
|
@@ -159,7 +171,6 @@ var UnresolvedFile = class extends FileDiff {
|
|
|
159
171
|
markerRows
|
|
160
172
|
});
|
|
161
173
|
if (source == null) return false;
|
|
162
|
-
this.setActiveMergeConflictState(source.actions, source.markerRows);
|
|
163
174
|
const didRender = super.render({
|
|
164
175
|
...rest,
|
|
165
176
|
fileDiff: source.fileDiff,
|
|
@@ -173,7 +184,7 @@ var UnresolvedFile = class extends FileDiff {
|
|
|
173
184
|
return didRender;
|
|
174
185
|
}
|
|
175
186
|
resolveConflict(conflictIndex, resolution, fileDiff = this.computedCache.fileDiff) {
|
|
176
|
-
const action = this.
|
|
187
|
+
const action = this.computedCache.actions?.[conflictIndex];
|
|
177
188
|
if (fileDiff == null || action == null) return;
|
|
178
189
|
if (action.conflictIndex !== conflictIndex) {
|
|
179
190
|
console.error({
|
|
@@ -186,7 +197,7 @@ var UnresolvedFile = class extends FileDiff {
|
|
|
186
197
|
const previousFile = this.computedCache.file;
|
|
187
198
|
const { file, actions, markerRows } = rebuildFileAndActions({
|
|
188
199
|
fileDiff: newFileDiff,
|
|
189
|
-
previousActions: this.
|
|
200
|
+
previousActions: this.computedCache.actions ?? [],
|
|
190
201
|
resolvedConflictIndex: conflictIndex,
|
|
191
202
|
previousFile,
|
|
192
203
|
resolution
|
|
@@ -199,7 +210,7 @@ var UnresolvedFile = class extends FileDiff {
|
|
|
199
210
|
};
|
|
200
211
|
}
|
|
201
212
|
resolveConflictAndRender(conflictIndex, resolution) {
|
|
202
|
-
const action = this.
|
|
213
|
+
const action = this.computedCache.actions?.[conflictIndex];
|
|
203
214
|
if (action == null) return;
|
|
204
215
|
if (action.conflictIndex !== conflictIndex) {
|
|
205
216
|
console.error({
|
|
@@ -220,17 +231,25 @@ var UnresolvedFile = class extends FileDiff {
|
|
|
220
231
|
actions,
|
|
221
232
|
markerRows
|
|
222
233
|
};
|
|
223
|
-
this
|
|
224
|
-
if (
|
|
234
|
+
const { workerManager } = this;
|
|
235
|
+
if (workerManager?.isWorkingPool() === true && !workerManager.shouldHighlightOnMainThread(fileDiff)) this.hunksRenderer.renderDiff(fileDiff);
|
|
225
236
|
else this.render({ forceRender: true });
|
|
226
237
|
this.options.onMergeConflictResolve?.(file, payload);
|
|
227
238
|
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
if (this.
|
|
239
|
+
prepareRenderData(fileDiff) {
|
|
240
|
+
super.prepareRenderData(fileDiff);
|
|
241
|
+
const latest = areDiffTargetsEqual(fileDiff, this.computedCache.fileDiff);
|
|
242
|
+
if (this.hunksRenderer instanceof UnresolvedFileHunksRenderer) this.hunksRenderer.setConflictState(this.options.mergeConflictActionsType === "none" ? [] : (latest ? this.computedCache.actions : this.conflictActions) ?? [], (latest ? this.computedCache.markerRows : this.markerRows) ?? [], fileDiff);
|
|
243
|
+
}
|
|
244
|
+
adoptRenderData(fileDiff) {
|
|
245
|
+
super.adoptRenderData(fileDiff);
|
|
246
|
+
if (areDiffTargetsEqual(fileDiff, this.computedCache.fileDiff)) {
|
|
247
|
+
this.conflictActions = this.computedCache.actions ?? [];
|
|
248
|
+
this.markerRows = this.computedCache.markerRows ?? [];
|
|
249
|
+
}
|
|
232
250
|
}
|
|
233
251
|
handleMergeConflictActionClick = (target) => {
|
|
252
|
+
if (!this.isComponentManaged && this.options.onMergeConflictAction != null && !areDiffTargetsEqual(this.getRenderedDiff(), this.computedCache.fileDiff)) return;
|
|
234
253
|
const action = this.conflictActions[target.conflictIndex];
|
|
235
254
|
if (action == null) return;
|
|
236
255
|
if (action.conflictIndex !== target.conflictIndex) {
|
|
@@ -251,8 +270,8 @@ var UnresolvedFile = class extends FileDiff {
|
|
|
251
270
|
this.resolveConflictAndRender(target.conflictIndex, target.resolution);
|
|
252
271
|
};
|
|
253
272
|
renderMergeConflictActionSlots() {
|
|
254
|
-
const
|
|
255
|
-
if (this.
|
|
273
|
+
const fileDiff = this.getRenderedDiff();
|
|
274
|
+
if (this.isComponentManaged || this.fileContainer == null || typeof this.options.mergeConflictActionsType !== "function" || this.conflictActions.length === 0 || fileDiff == null) {
|
|
256
275
|
this.clearMergeConflictActionCache();
|
|
257
276
|
return;
|
|
258
277
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UnresolvedFile.js","names":["resolveConflictDiff"],"sources":["../../src/components/UnresolvedFile.ts"],"sourcesContent":["import { DEFAULT_THEMES } from '../constants';\nimport type { MergeConflictActionTarget } from '../managers/InteractionManager';\nimport { pluckInteractionOptions } from '../managers/InteractionManager';\nimport type { HunksRenderResult } from '../renderers/DiffHunksRenderer';\nimport {\n UnresolvedFileHunksRenderer,\n type UnresolvedFileHunksRendererOptions,\n} from '../renderers/UnresolvedFileHunksRenderer';\nimport type {\n FileContents,\n FileDiffMetadata,\n MergeConflictActionPayload,\n MergeConflictMarkerRow,\n MergeConflictRegion,\n MergeConflictResolution,\n PostRenderPhase,\n} from '../types';\nimport { areFilesEqual } from '../utils/areFilesEqual';\nimport { areMergeConflictActionsEqual } from '../utils/areMergeConflictActionsEqual';\nimport { createAnnotationWrapperNode } from '../utils/createAnnotationWrapperNode';\nimport { getMergeConflictActionSlotName } from '../utils/getMergeConflictActionSlotName';\nimport {\n buildMergeConflictMarkerRows,\n getMergeConflictActionAnchor,\n type MergeConflictDiffAction,\n parseMergeConflictDiffFromFile,\n} from '../utils/parseMergeConflictDiffFromFile';\nimport { resolveConflict as resolveConflictDiff } from '../utils/resolveConflict';\nimport { shouldUseTokenTransformer } from '../utils/shouldUseTokenTransformer';\nimport { splitFileContents } from '../utils/splitFileContents';\nimport type { WorkerPoolManager } from '../worker';\nimport {\n FileDiff,\n type FileDiffOptions,\n type FileDiffRenderBaseProps,\n} from './FileDiff';\n\nexport type RenderMergeConflictActions<LAnnotation> = (\n action: MergeConflictDiffAction,\n instance: UnresolvedFile<LAnnotation>\n) => HTMLElement | DocumentFragment | null | undefined;\n\nexport type MergeConflictActionsTypeOption<LAnnotation> =\n | 'none'\n | 'default'\n | RenderMergeConflictActions<LAnnotation>;\n\nexport interface UnresolvedFileOptions<LAnnotation> extends Omit<\n FileDiffOptions<LAnnotation, undefined>,\n 'diffStyle' | 'onPostRender'\n> {\n onPostRender?(\n node: HTMLElement,\n instance: UnresolvedFile<LAnnotation>,\n phase: PostRenderPhase\n ): unknown;\n mergeConflictActionsType?: MergeConflictActionsTypeOption<LAnnotation>;\n onMergeConflictAction?(\n payload: MergeConflictActionPayload,\n instance: UnresolvedFile<LAnnotation>\n ): void;\n onMergeConflictResolve?(\n file: FileContents,\n payload: MergeConflictActionPayload\n ): void;\n maxContextLines?: number;\n}\n\nexport interface UnresolvedFileRenderProps<\n LAnnotation,\n> extends FileDiffRenderBaseProps<LAnnotation> {\n file?: FileContents;\n actions?: (MergeConflictDiffAction | undefined)[];\n markerRows?: MergeConflictMarkerRow[];\n}\n\nexport interface UnresolvedFileHydrationProps<LAnnotation> extends Omit<\n UnresolvedFileRenderProps<LAnnotation>,\n 'file'\n> {\n file?: FileContents;\n fileContainer: HTMLElement;\n prerenderedHTML?: string;\n}\n\ninterface MergeConflictActionElementCache {\n element: HTMLElement;\n action: MergeConflictDiffAction;\n}\n\ninterface GetOrComputeDiffProps {\n file: FileContents | undefined;\n fileDiff: FileDiffMetadata | undefined;\n actions: (MergeConflictDiffAction | undefined)[] | undefined;\n markerRows: MergeConflictMarkerRow[] | undefined;\n}\n\ninterface GetOrComputeDiffResult {\n fileDiff: FileDiffMetadata;\n actions: (MergeConflictDiffAction | undefined)[];\n markerRows: MergeConflictMarkerRow[];\n}\n\ninterface ResolveConflictReturn {\n file: FileContents;\n fileDiff: FileDiffMetadata;\n actions: (MergeConflictDiffAction | undefined)[];\n markerRows: MergeConflictMarkerRow[];\n}\n\ntype UnresolvedFileDataCache = GetOrComputeDiffProps;\n\nlet instanceId = -1;\n\nexport class UnresolvedFile<LAnnotation = undefined> extends FileDiff<\n LAnnotation,\n undefined\n> {\n override readonly __id: string = `unresolved-file:${++instanceId}`;\n override readonly type = 'unresolved-file';\n\n protected computedCache: UnresolvedFileDataCache = {\n file: undefined,\n fileDiff: undefined,\n actions: undefined,\n markerRows: undefined,\n };\n private conflictActions: (MergeConflictDiffAction | undefined)[] = [];\n private markerRows: MergeConflictMarkerRow[] = [];\n private conflictActionCache: Map<string, MergeConflictActionElementCache> =\n new Map();\n\n constructor(\n public override options: UnresolvedFileOptions<LAnnotation> = {\n theme: DEFAULT_THEMES,\n },\n workerManager?: WorkerPoolManager | undefined,\n isContainerManaged = false\n ) {\n super(undefined, workerManager, isContainerManaged);\n this.setOptions(options);\n }\n\n override setOptions(\n options: UnresolvedFileOptions<LAnnotation> | undefined\n ): void {\n if (options == null) {\n return;\n }\n\n if (\n options.onMergeConflictAction != null &&\n options.onMergeConflictResolve != null\n ) {\n throw new Error(\n 'UnresolvedFile: onMergeConflictAction and onMergeConflictResolve are mutually exclusive. Use only one callback.'\n );\n }\n\n this.options = options;\n this.hunksRenderer.setOptions(this.getHunksRendererOptions(options));\n this.syncInteractionOptions();\n }\n\n // UnresolvedFile adds a merge-conflict-action click handler to the\n // InteractionManager. FileDiff.syncInteractionOptions() re-runs on every\n // re-render and during hydration; without this override it would rebuild the\n // interaction options without that handler, so resolving one conflict (which\n // re-renders the diff) would silently disable every remaining action button.\n protected override syncInteractionOptions(): void {\n this.interactionManager.setOptions(\n pluckInteractionOptions(\n this.options,\n typeof this.options.hunkSeparators === 'function' ||\n (this.options.hunkSeparators ?? 'line-info') === 'line-info' ||\n this.options.hunkSeparators === 'line-info-basic'\n ? this.handleExpandHunk\n : undefined,\n this.getLineIndex,\n this.handleMergeConflictActionClick\n )\n );\n }\n\n protected override createHunksRenderer(\n options: UnresolvedFileOptions<LAnnotation>\n ): UnresolvedFileHunksRenderer<LAnnotation> {\n const renderer = new UnresolvedFileHunksRenderer<LAnnotation>(\n this.getHunksRendererOptions(options),\n this.getAnnotationSlotName,\n this.handleHighlightRender,\n this.workerManager\n );\n return renderer;\n }\n\n protected override getHunksRendererOptions(\n options: UnresolvedFileOptions<LAnnotation>\n ): UnresolvedFileHunksRendererOptions {\n return getUnresolvedDiffHunksRendererOptions(options, this.options);\n }\n\n protected override applyPreNodeAttributes(\n pre: HTMLPreElement,\n result: HunksRenderResult\n ): void {\n super.applyPreNodeAttributes(pre, result, {\n 'data-has-merge-conflict': '',\n });\n }\n\n override cleanUp(): void {\n this.emitPostRender(true);\n this.clearMergeConflictActionCache();\n this.computedCache = {\n file: undefined,\n fileDiff: undefined,\n actions: undefined,\n markerRows: undefined,\n };\n this.conflictActions = [];\n super.cleanUp();\n }\n\n private getOrComputeDiff({\n file,\n fileDiff,\n actions,\n markerRows,\n }: GetOrComputeDiffProps): GetOrComputeDiffResult | undefined {\n const { maxContextLines, onMergeConflictAction } = this.options;\n wrapper: {\n // We are dealing with a controlled component\n if (onMergeConflictAction != null) {\n const hasFileDiff = fileDiff != null;\n const hasActions = actions != null;\n const hasMarkerRows = markerRows != null;\n if (hasFileDiff !== hasActions || hasFileDiff !== hasMarkerRows) {\n throw new Error(\n 'UnresolvedFile.getOrComputeDiff: fileDiff, actions, and markerRows must be passed together'\n );\n }\n // If we were provided a new fileDiff/actions/markerRows, we are a FULLY\n // controlled component, which means we will not do any computation\n if (fileDiff != null && actions != null && markerRows != null) {\n this.computedCache = {\n file: file ?? this.computedCache.file,\n fileDiff,\n actions,\n markerRows,\n };\n break wrapper;\n }\n // If we were provided a new file, we should attempt to parse out a new\n // diff/actions if we haven't computed it before. Once we initialize from\n // a file, later updates must flow through fileDiff/actions instead of\n // reparsing from a new file input.\n else if (file != null || this.computedCache.file != null) {\n if (\n file != null &&\n this.computedCache.file != null &&\n !areFilesEqual(file, this.computedCache.file) &&\n this.computedCache.fileDiff != null &&\n this.computedCache.actions != null\n ) {\n throw new Error(\n 'UnresolvedFile.getOrComputeDiff: file can only be used to initialize unresolved state once. Pass fileDiff and actions for subsequent updates.'\n );\n }\n file ??= this.computedCache.file;\n if (file == null) {\n throw new Error(\n 'UnresolvedFile.getOrComputeDiff: file is null, should be impossible'\n );\n }\n if (\n !areFilesEqual(file, this.computedCache.file) ||\n this.computedCache.fileDiff == null ||\n this.computedCache.actions == null\n ) {\n const computed = parseMergeConflictDiffFromFile(\n file,\n maxContextLines\n );\n this.computedCache = {\n file,\n fileDiff: computed.fileDiff,\n actions: computed.actions,\n markerRows: computed.markerRows,\n };\n }\n fileDiff = this.computedCache.fileDiff;\n actions = this.computedCache.actions;\n markerRows = this.computedCache.markerRows;\n break wrapper;\n }\n // Otherwise we should fall through and try to use the cache if it exists\n else {\n fileDiff = this.computedCache.fileDiff;\n actions = this.computedCache.actions;\n markerRows = this.computedCache.markerRows;\n break wrapper;\n }\n }\n // If we are uncontrolled we only rely on the file and only use the first\n // version. After that, the cached diff/action pair is the source of\n // truth and we should not accept a new file input.\n else {\n if (fileDiff != null || actions != null || markerRows != null) {\n throw new Error(\n 'UnresolvedFile.getOrComputeDiff: fileDiff, actions, and markerRows are only usable in controlled mode, you must pass in `onMergeConflictAction`'\n );\n }\n if (\n file != null &&\n this.computedCache.file != null &&\n !areFilesEqual(file, this.computedCache.file)\n ) {\n throw new Error(\n 'UnresolvedFile.getOrComputeDiff: uncontrolled unresolved files parse the file only once. Later updates must come from the cached diff state.'\n );\n }\n this.computedCache.file ??= file;\n if (\n this.computedCache.fileDiff == null &&\n this.computedCache.file != null\n ) {\n const computed = parseMergeConflictDiffFromFile(\n this.computedCache.file,\n maxContextLines\n );\n this.computedCache.fileDiff = computed.fileDiff;\n this.computedCache.actions = computed.actions;\n this.computedCache.markerRows = computed.markerRows;\n }\n // Because we are uncontrolled, the source of truth is the\n // computedCache\n fileDiff = this.computedCache.fileDiff;\n actions = this.computedCache.actions;\n markerRows = this.computedCache.markerRows;\n break wrapper;\n }\n }\n if (fileDiff == null || actions == null || markerRows == null) {\n return undefined;\n }\n return { fileDiff, actions, markerRows };\n }\n\n override hydrate(props: UnresolvedFileHydrationProps<LAnnotation>): void {\n const {\n file,\n fileDiff,\n actions,\n markerRows,\n lineAnnotations,\n fileContainer,\n prerenderedHTML,\n preventEmit = false,\n } = props;\n const source = this.getOrComputeDiff({\n file,\n fileDiff,\n actions,\n markerRows,\n });\n if (source == null) {\n return;\n }\n this.hydrateElements(fileContainer, prerenderedHTML);\n this.setActiveMergeConflictState(source.actions, source.markerRows);\n // If necessary hydration elements don't exist, we should assume a full\n // render\n if (\n shouldRenderCode(this.pre, source.fileDiff, this.options.collapsed) ||\n shouldRenderHeader(\n this.headerElement,\n source.fileDiff,\n this.options.disableFileHeader\n )\n ) {\n this.render({ ...props, preventEmit: true });\n }\n // Otherwise orchestrate our setup\n else {\n this.hydrationSetup({ fileDiff: source.fileDiff, lineAnnotations });\n if (this.pre != null) {\n this.renderMergeConflictActionSlots();\n }\n }\n if (!preventEmit) {\n this.emitPostRender();\n }\n }\n\n override rerender(): void {\n if (!this.enabled || this.fileDiff == null) {\n return;\n }\n this.render({ forceRender: true, renderRange: this.renderRange });\n }\n\n override render(props: UnresolvedFileRenderProps<LAnnotation> = {}): boolean {\n const {\n file,\n fileDiff,\n actions,\n markerRows,\n lineAnnotations,\n preventEmit = false,\n ...rest\n } = props;\n const source = this.getOrComputeDiff({\n file,\n fileDiff,\n actions,\n markerRows,\n });\n if (source == null) {\n return false;\n }\n this.setActiveMergeConflictState(source.actions, source.markerRows);\n const didRender = super.render({\n ...rest,\n fileDiff: source.fileDiff,\n lineAnnotations,\n preventEmit: true,\n });\n if (didRender) {\n this.renderMergeConflictActionSlots();\n if (!preventEmit) {\n this.emitPostRender();\n }\n }\n return didRender;\n }\n\n public resolveConflict(\n conflictIndex: number,\n resolution: MergeConflictResolution,\n fileDiff: FileDiffMetadata | undefined = this.computedCache.fileDiff\n ): ResolveConflictReturn | undefined {\n const action = this.conflictActions[conflictIndex];\n if (fileDiff == null || action == null) {\n return undefined;\n }\n\n if (action.conflictIndex !== conflictIndex) {\n console.error({ conflictIndex, action });\n throw new Error(\n \"UnresolvedFile.resolveConflict: conflictIndex and conflictAction don't match\"\n );\n }\n\n const newFileDiff = resolveConflictDiff(fileDiff, action, resolution);\n const previousFile = this.computedCache.file;\n const { file, actions, markerRows } = rebuildFileAndActions({\n fileDiff: newFileDiff,\n previousActions: this.conflictActions,\n resolvedConflictIndex: conflictIndex,\n previousFile,\n resolution,\n });\n\n return {\n file,\n fileDiff: newFileDiff,\n actions,\n markerRows,\n };\n }\n\n private resolveConflictAndRender(\n conflictIndex: number,\n resolution: MergeConflictResolution\n ): void {\n const action = this.conflictActions[conflictIndex];\n if (action == null) {\n return;\n }\n if (action.conflictIndex !== conflictIndex) {\n console.error({ conflictIndex, action });\n throw new Error(\n \"UnresolvedFile.resolveConflictAndRender: conflictIndex and conflictAction don't match\"\n );\n }\n const payload: MergeConflictActionPayload = {\n resolution,\n conflict: action.conflict,\n };\n const { file, fileDiff, actions, markerRows } =\n this.resolveConflict(conflictIndex, resolution) ?? {};\n if (\n file == null ||\n fileDiff == null ||\n actions == null ||\n markerRows == null\n ) {\n return;\n }\n\n this.computedCache = { file, fileDiff, actions, markerRows };\n this.setActiveMergeConflictState(actions, markerRows);\n // NOTE(amadeus): This is a bit jank, but helps to ensure we don't see a\n // bunch of jittery re-renders as things resolve out. In a more perfect\n // world we would have a more elegant way to kick off a render to the\n // highlighter and then resolve actions in a cleaner way, but time is short\n // right now. Can't let perfect be the enemy of good\n if (this.workerManager != null) {\n // Because we are using a workerManager, if we fire off the renderDiff\n // call, it will eventually get back to us in a callback which will\n // trigger a re-render\n this.hunksRenderer.renderDiff(fileDiff);\n } else {\n this.render({ forceRender: true });\n }\n this.options.onMergeConflictResolve?.(file, payload);\n }\n\n private setActiveMergeConflictState(\n actions: (MergeConflictDiffAction | undefined)[] = this.conflictActions,\n markerRows: MergeConflictMarkerRow[] = this.markerRows\n ): void {\n this.conflictActions = actions;\n this.markerRows = markerRows;\n if (\n this.computedCache.fileDiff != null &&\n this.hunksRenderer instanceof UnresolvedFileHunksRenderer\n ) {\n this.hunksRenderer.setConflictState(\n this.options.mergeConflictActionsType === 'none' ? [] : actions,\n markerRows,\n this.computedCache.fileDiff\n );\n }\n }\n\n private handleMergeConflictActionClick = (\n target: MergeConflictActionTarget\n ): void => {\n const action = this.conflictActions[target.conflictIndex];\n if (action == null) {\n return;\n }\n if (action.conflictIndex !== target.conflictIndex) {\n console.error({ conflictIndex: target.conflictIndex, action });\n throw new Error(\n \"UnresolvedFile.handleMergeConflictActionClick: conflictIndex and conflictAction don't match\"\n );\n }\n const payload: MergeConflictActionPayload = {\n resolution: target.resolution,\n conflict: action.conflict,\n };\n if (this.options.onMergeConflictAction != null) {\n this.options.onMergeConflictAction(payload, this);\n return;\n }\n this.resolveConflictAndRender(target.conflictIndex, target.resolution);\n };\n\n private renderMergeConflictActionSlots(): void {\n const { fileDiff } = this.computedCache;\n if (\n this.isContainerManaged ||\n this.fileContainer == null ||\n typeof this.options.mergeConflictActionsType !== 'function' ||\n this.conflictActions.length === 0 ||\n fileDiff == null\n ) {\n this.clearMergeConflictActionCache();\n return;\n }\n const staleActions = new Map(this.conflictActionCache);\n for (\n let actionIndex = 0;\n actionIndex < this.conflictActions.length;\n actionIndex++\n ) {\n const action = this.conflictActions[actionIndex];\n if (action == null) {\n continue;\n }\n if (action.conflictIndex !== actionIndex) {\n console.error({ conflictIndex: actionIndex, action });\n throw new Error(\n \"UnresolvedFile.renderMergeConflictActionSlots: conflictIndex and conflictAction don't match\"\n );\n }\n const anchor = getMergeConflictActionAnchor(action, fileDiff);\n if (anchor == null) {\n continue;\n }\n const conflictIndex = action.conflictIndex;\n const slotName = getMergeConflictActionSlotName({\n hunkIndex: anchor.hunkIndex,\n lineIndex: anchor.lineIndex,\n conflictIndex,\n });\n const id = `${actionIndex}-${slotName}`;\n let cache = this.conflictActionCache.get(id);\n if (\n cache == null ||\n !areMergeConflictActionsEqual(cache.action, action)\n ) {\n cache?.element.remove();\n const rendered = this.renderMergeConflictAction(action);\n if (rendered == null) {\n continue;\n }\n const element = createAnnotationWrapperNode(slotName);\n element.appendChild(rendered);\n this.fileContainer.appendChild(element);\n cache = { element, action };\n this.conflictActionCache.set(id, cache);\n }\n staleActions.delete(id);\n }\n for (const [id, { element }] of staleActions.entries()) {\n this.conflictActionCache.delete(id);\n element.remove();\n }\n }\n\n private renderMergeConflictAction(\n action: MergeConflictDiffAction\n ): HTMLElement | undefined {\n if (typeof this.options.mergeConflictActionsType !== 'function') {\n return undefined;\n }\n const rendered = this.options.mergeConflictActionsType(action, this);\n if (rendered == null) {\n return undefined;\n }\n if (rendered instanceof HTMLElement) {\n return rendered;\n }\n if (\n typeof DocumentFragment !== 'undefined' &&\n rendered instanceof DocumentFragment\n ) {\n const wrapper = document.createElement('div');\n wrapper.style.display = 'contents';\n wrapper.appendChild(rendered);\n return wrapper;\n }\n return undefined;\n }\n\n private clearMergeConflictActionCache(): void {\n for (const { element } of this.conflictActionCache.values()) {\n element.remove();\n }\n this.conflictActionCache.clear();\n }\n}\n\ninterface RebuildFileAndActionsProps {\n fileDiff: FileDiffMetadata;\n previousActions: (MergeConflictDiffAction | undefined)[];\n resolvedConflictIndex: number;\n // FIXME: Probably should remove this...\n // additionOffset: number;\n // deletionOffset: number;\n previousFile: FileContents | undefined;\n resolution: MergeConflictResolution;\n}\n\n// Rebuild the emitted unresolved file contents and remaining action anchors in\n// one pass over the post-resolution diff state.\nfunction rebuildFileAndActions({\n fileDiff,\n previousActions,\n resolvedConflictIndex,\n previousFile,\n resolution,\n}: RebuildFileAndActionsProps): Pick<\n ResolveConflictReturn,\n 'file' | 'actions' | 'markerRows'\n> {\n const resolvedAction = previousActions[resolvedConflictIndex];\n if (resolvedAction == null) {\n throw new Error(\n 'rebuildFileAndActions: missing resolved action for unresolved file rebuild'\n );\n }\n\n const actions = updateConflictActionsAfterResolution(\n previousActions,\n resolvedConflictIndex,\n resolvedAction,\n resolution\n );\n const markerRows = buildMergeConflictMarkerRows(fileDiff, actions);\n\n const file = rebuildUnresolvedFile({\n fileDiff,\n resolvedAction,\n resolvedConflictIndex,\n previousFile,\n resolution,\n });\n\n return {\n file,\n actions,\n markerRows,\n };\n}\n\ninterface RebuildUnresolvedFileProps {\n fileDiff: FileDiffMetadata;\n resolvedAction: MergeConflictDiffAction;\n resolvedConflictIndex: number;\n previousFile: FileContents | undefined;\n resolution: MergeConflictResolution;\n}\n\n// Rebuild the unresolved file text from the previous unresolved source so we\n// preserve remaining marker blocks exactly while the diff state stays in-place.\nfunction rebuildUnresolvedFile({\n resolvedAction,\n resolvedConflictIndex,\n previousFile,\n fileDiff,\n resolution,\n}: RebuildUnresolvedFileProps): FileContents {\n const previousContents = previousFile?.contents ?? '';\n const lines = splitFileContents(previousContents);\n const { conflict } = resolvedAction;\n const replacementLines = getResolvedConflictReplacementLines(\n lines,\n conflict,\n resolution\n );\n const contents = [\n ...lines.slice(0, conflict.startLineIndex),\n ...replacementLines,\n ...lines.slice(conflict.endLineIndex + 1),\n ].join('');\n\n return {\n name: previousFile?.name ?? fileDiff.name,\n contents,\n cacheKey:\n previousFile?.cacheKey != null\n ? `${previousFile.cacheKey}:mc-${resolvedConflictIndex}-${resolution}`\n : undefined,\n };\n}\n\nfunction getResolvedConflictReplacementLines(\n lines: string[],\n conflict: MergeConflictDiffAction['conflict'],\n resolution: MergeConflictResolution\n): string[] {\n const currentLines = lines.slice(\n conflict.startLineIndex + 1,\n conflict.baseMarkerLineIndex ?? conflict.separatorLineIndex\n );\n const incomingLines = lines.slice(\n conflict.separatorLineIndex + 1,\n conflict.endLineIndex\n );\n\n if (resolution === 'current') {\n return currentLines;\n }\n if (resolution === 'incoming') {\n return incomingLines;\n }\n return [...currentLines, ...incomingLines];\n}\n\n// The diff resolver keeps hunk/content group indexes stable, so the only\n// follow-up update we need here is shifting unresolved source-region line\n// numbers for later conflicts in the rebuilt file text.\nfunction updateConflictActionsAfterResolution(\n previousActions: (MergeConflictDiffAction | undefined)[],\n resolvedConflictIndex: number,\n resolvedAction: MergeConflictDiffAction,\n resolution: MergeConflictResolution\n): (MergeConflictDiffAction | undefined)[] {\n const lineDelta = getResolvedConflictLineDelta(\n resolvedAction.conflict,\n resolution\n );\n\n return previousActions.map((action, index) => {\n if (index === resolvedConflictIndex) {\n return undefined;\n }\n if (action == null) {\n return undefined;\n }\n if (action.conflict.startLineIndex > resolvedAction.conflict.endLineIndex) {\n return {\n ...action,\n conflict: shiftMergeConflictRegion(action.conflict, lineDelta),\n };\n }\n return action;\n });\n}\n\nfunction getResolvedConflictLineDelta(\n conflict: MergeConflictRegion,\n resolution: MergeConflictResolution\n): number {\n const currentLineCount =\n (conflict.baseMarkerLineIndex ?? conflict.separatorLineIndex) -\n conflict.startLineIndex -\n 1;\n const incomingLineCount =\n conflict.endLineIndex - conflict.separatorLineIndex - 1;\n const replacementLineCount =\n resolution === 'current'\n ? currentLineCount\n : resolution === 'incoming'\n ? incomingLineCount\n : currentLineCount + incomingLineCount;\n const conflictLineCount = conflict.endLineIndex - conflict.startLineIndex + 1;\n return replacementLineCount - conflictLineCount;\n}\n\nfunction shiftMergeConflictRegion(\n conflict: MergeConflictRegion,\n lineDelta: number\n): MergeConflictRegion {\n return {\n ...conflict,\n startLineIndex: conflict.startLineIndex + lineDelta,\n startLineNumber: conflict.startLineNumber + lineDelta,\n separatorLineIndex: conflict.separatorLineIndex + lineDelta,\n separatorLineNumber: conflict.separatorLineNumber + lineDelta,\n endLineIndex: conflict.endLineIndex + lineDelta,\n endLineNumber: conflict.endLineNumber + lineDelta,\n baseMarkerLineIndex:\n conflict.baseMarkerLineIndex != null\n ? conflict.baseMarkerLineIndex + lineDelta\n : undefined,\n baseMarkerLineNumber:\n conflict.baseMarkerLineNumber != null\n ? conflict.baseMarkerLineNumber + lineDelta\n : undefined,\n };\n}\n\nfunction shouldRenderCode(\n pre: HTMLPreElement | undefined,\n fileDiff: FileDiffMetadata | undefined,\n collapsed = false\n): boolean {\n return !collapsed && pre == null && fileDiff != null;\n}\n\nfunction shouldRenderHeader(\n headerElement: HTMLElement | undefined,\n fileDiff: FileDiffMetadata | undefined,\n disableFileHeader = false\n): boolean {\n return headerElement == null && fileDiff != null && !disableFileHeader;\n}\n\n// NOTE(amadeus): Should probably pull this out into a util, and make variants\n// for all component types\nexport function getUnresolvedDiffHunksRendererOptions<LAnnotation>(\n options?: UnresolvedFileOptions<LAnnotation>,\n baseOptions?: UnresolvedFileOptions<LAnnotation>\n): UnresolvedFileHunksRendererOptions {\n const merged = { ...baseOptions, ...options };\n return {\n ...merged,\n useTokenTransformer: shouldUseTokenTransformer<'diff'>(merged),\n hunkSeparators:\n typeof options?.hunkSeparators === 'function'\n ? 'custom'\n : options?.hunkSeparators,\n mergeConflictActionsType:\n typeof options?.mergeConflictActionsType === 'function'\n ? 'custom'\n : options?.mergeConflictActionsType,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"UnresolvedFile.js","names":["resolveConflictDiff"],"sources":["../../src/components/UnresolvedFile.ts"],"sourcesContent":["import { DEFAULT_THEMES } from '../constants';\nimport type { MergeConflictActionTarget } from '../managers/InteractionManager';\nimport { pluckInteractionOptions } from '../managers/InteractionManager';\nimport type { HunksRenderResult } from '../renderers/DiffHunksRenderer';\nimport {\n UnresolvedFileHunksRenderer,\n type UnresolvedFileHunksRendererOptions,\n} from '../renderers/UnresolvedFileHunksRenderer';\nimport type {\n FileContents,\n FileDiffMetadata,\n MergeConflictActionPayload,\n MergeConflictMarkerRow,\n MergeConflictRegion,\n MergeConflictResolution,\n PostRenderPhase,\n} from '../types';\nimport { areDiffTargetsEqual } from '../utils/areDiffTargetsEqual';\nimport { areFilesEqual } from '../utils/areFilesEqual';\nimport { areMergeConflictActionsEqual } from '../utils/areMergeConflictActionsEqual';\nimport { createAnnotationWrapperNode } from '../utils/createAnnotationWrapperNode';\nimport { getMergeConflictActionSlotName } from '../utils/getMergeConflictActionSlotName';\nimport {\n buildMergeConflictMarkerRows,\n getMergeConflictActionAnchor,\n type MergeConflictDiffAction,\n parseMergeConflictDiffFromFile,\n} from '../utils/parseMergeConflictDiffFromFile';\nimport { resolveConflict as resolveConflictDiff } from '../utils/resolveConflict';\nimport { shouldUseTokenTransformer } from '../utils/shouldUseTokenTransformer';\nimport { splitFileContents } from '../utils/splitFileContents';\nimport type { WorkerPoolManager } from '../worker';\nimport {\n FileDiff,\n type FileDiffOptions,\n type FileDiffRenderBaseProps,\n type FileDiffRenderData,\n type FileDiffRenderInput,\n} from './FileDiff';\n\nexport type RenderMergeConflictActions<LAnnotation> = (\n action: MergeConflictDiffAction,\n instance: UnresolvedFile<LAnnotation>\n) => HTMLElement | DocumentFragment | null | undefined;\n\nexport type MergeConflictActionsTypeOption<LAnnotation> =\n | 'none'\n | 'default'\n | RenderMergeConflictActions<LAnnotation>;\n\nexport interface UnresolvedFileOptions<LAnnotation> extends Omit<\n FileDiffOptions<LAnnotation, undefined>,\n 'diffStyle' | 'onPostRender'\n> {\n onPostRender?(\n node: HTMLElement,\n instance: UnresolvedFile<LAnnotation>,\n phase: PostRenderPhase\n ): unknown;\n mergeConflictActionsType?: MergeConflictActionsTypeOption<LAnnotation>;\n onMergeConflictAction?(\n payload: MergeConflictActionPayload,\n instance: UnresolvedFile<LAnnotation>\n ): void;\n onMergeConflictResolve?(\n file: FileContents,\n payload: MergeConflictActionPayload\n ): void;\n maxContextLines?: number;\n}\n\nexport interface UnresolvedFileRenderProps<\n LAnnotation,\n> extends FileDiffRenderBaseProps<LAnnotation> {\n file?: FileContents;\n actions?: (MergeConflictDiffAction | undefined)[];\n markerRows?: MergeConflictMarkerRow[];\n}\n\nexport interface UnresolvedFileHydrationProps<LAnnotation> extends Omit<\n UnresolvedFileRenderProps<LAnnotation>,\n 'file'\n> {\n file?: FileContents;\n fileContainer: HTMLElement;\n prerenderedHTML?: string;\n}\n\ninterface MergeConflictActionElementCache {\n element: HTMLElement;\n action: MergeConflictDiffAction;\n}\n\ninterface GetOrComputeDiffProps {\n file: FileContents | undefined;\n fileDiff: FileDiffMetadata | undefined;\n actions: (MergeConflictDiffAction | undefined)[] | undefined;\n markerRows: MergeConflictMarkerRow[] | undefined;\n}\n\ninterface GetOrComputeDiffResult {\n fileDiff: FileDiffMetadata;\n actions: (MergeConflictDiffAction | undefined)[];\n markerRows: MergeConflictMarkerRow[];\n}\n\ninterface ResolveConflictReturn {\n file: FileContents;\n fileDiff: FileDiffMetadata;\n actions: (MergeConflictDiffAction | undefined)[];\n markerRows: MergeConflictMarkerRow[];\n}\n\ntype UnresolvedFileDataCache = GetOrComputeDiffProps;\n\nexport interface UnresolvedFileRenderInput<\n LAnnotation,\n> extends FileDiffRenderInput<LAnnotation> {\n actions: (MergeConflictDiffAction | undefined)[];\n markerRows: MergeConflictMarkerRow[];\n}\n\nexport interface UnresolvedFileRenderData<\n LAnnotation,\n> extends FileDiffRenderData<LAnnotation> {\n actions: (MergeConflictDiffAction | undefined)[];\n markerRows: MergeConflictMarkerRow[];\n}\n\nlet instanceId = -1;\n\nexport class UnresolvedFile<LAnnotation = undefined> extends FileDiff<\n LAnnotation,\n undefined\n> {\n override readonly __id: string = `unresolved-file:${++instanceId}`;\n override readonly type = 'unresolved-file';\n\n protected computedCache: UnresolvedFileDataCache = {\n file: undefined,\n fileDiff: undefined,\n actions: undefined,\n markerRows: undefined,\n };\n private conflictActions: (MergeConflictDiffAction | undefined)[] = [];\n private markerRows: MergeConflictMarkerRow[] = [];\n\n public override __getNextRenderData({\n actions,\n markerRows,\n ...input\n }: UnresolvedFileRenderInput<LAnnotation>): UnresolvedFileRenderData<LAnnotation> {\n const data = super.__getNextRenderData(input);\n const isInput = areDiffTargetsEqual(data.fileDiff, input.fileDiff);\n return {\n ...data,\n actions: isInput ? actions : this.conflictActions,\n markerRows: isInput ? markerRows : this.markerRows,\n };\n }\n\n private conflictActionCache: Map<string, MergeConflictActionElementCache> =\n new Map();\n\n constructor(\n public override options: UnresolvedFileOptions<LAnnotation> = {\n theme: DEFAULT_THEMES,\n },\n workerManager?: WorkerPoolManager | undefined,\n requestOwnerRender?: () => void\n ) {\n super(undefined, workerManager, requestOwnerRender);\n this.setOptions(options);\n }\n\n override setOptions(\n options: UnresolvedFileOptions<LAnnotation> | undefined\n ): void {\n if (options == null) {\n return;\n }\n\n if (\n options.onMergeConflictAction != null &&\n options.onMergeConflictResolve != null\n ) {\n throw new Error(\n 'UnresolvedFile: onMergeConflictAction and onMergeConflictResolve are mutually exclusive. Use only one callback.'\n );\n }\n\n this.options = options;\n this.hunksRenderer.setOptions(this.getHunksRendererOptions(options));\n this.syncInteractionOptions();\n }\n\n // UnresolvedFile adds a merge-conflict-action click handler to the\n // InteractionManager. FileDiff.syncInteractionOptions() re-runs on every\n // re-render and during hydration; without this override it would rebuild the\n // interaction options without that handler, so resolving one conflict (which\n // re-renders the diff) would silently disable every remaining action button.\n protected override syncInteractionOptions(): void {\n this.interactionManager.setOptions(\n pluckInteractionOptions(\n this.options,\n typeof this.options.hunkSeparators === 'function' ||\n (this.options.hunkSeparators ?? 'line-info') === 'line-info' ||\n this.options.hunkSeparators === 'line-info-basic'\n ? this.handleExpandHunk\n : undefined,\n this.getLineIndex,\n this.handleMergeConflictActionClick\n )\n );\n }\n\n protected override createHunksRenderer(\n options: UnresolvedFileOptions<LAnnotation>\n ): UnresolvedFileHunksRenderer<LAnnotation> {\n const renderer = new UnresolvedFileHunksRenderer<LAnnotation>(\n this.getHunksRendererOptions(options),\n this.getAnnotationSlotName,\n this.handleHighlightRender,\n this.workerManager\n );\n return renderer;\n }\n\n protected override getHunksRendererOptions(\n options: UnresolvedFileOptions<LAnnotation>\n ): UnresolvedFileHunksRendererOptions {\n return getUnresolvedDiffHunksRendererOptions(options, this.options);\n }\n\n protected override applyPreNodeAttributes(\n pre: HTMLPreElement,\n result: HunksRenderResult\n ): void {\n super.applyPreNodeAttributes(pre, result, {\n 'data-has-merge-conflict': '',\n });\n }\n\n override cleanUp(): void {\n this.emitPostRender(true);\n this.clearMergeConflictActionCache();\n this.computedCache = {\n file: undefined,\n fileDiff: undefined,\n actions: undefined,\n markerRows: undefined,\n };\n this.conflictActions = [];\n this.markerRows = [];\n super.cleanUp();\n }\n\n private getOrComputeDiff({\n file,\n fileDiff,\n actions,\n markerRows,\n }: GetOrComputeDiffProps): GetOrComputeDiffResult | undefined {\n const { maxContextLines, onMergeConflictAction } = this.options;\n wrapper: {\n // We are dealing with a controlled component\n if (onMergeConflictAction != null) {\n const hasFileDiff = fileDiff != null;\n const hasActions = actions != null;\n const hasMarkerRows = markerRows != null;\n if (hasFileDiff !== hasActions || hasFileDiff !== hasMarkerRows) {\n throw new Error(\n 'UnresolvedFile.getOrComputeDiff: fileDiff, actions, and markerRows must be passed together'\n );\n }\n // If we were provided a new fileDiff/actions/markerRows, we are a FULLY\n // controlled component, which means we will not do any computation\n if (fileDiff != null && actions != null && markerRows != null) {\n this.computedCache = {\n file: file ?? this.computedCache.file,\n fileDiff,\n actions,\n markerRows,\n };\n break wrapper;\n }\n // If we were provided a new file, we should attempt to parse out a new\n // diff/actions if we haven't computed it before. Once we initialize from\n // a file, later updates must flow through fileDiff/actions instead of\n // reparsing from a new file input.\n else if (file != null || this.computedCache.file != null) {\n if (\n file != null &&\n this.computedCache.file != null &&\n !areFilesEqual(file, this.computedCache.file) &&\n this.computedCache.fileDiff != null &&\n this.computedCache.actions != null\n ) {\n throw new Error(\n 'UnresolvedFile.getOrComputeDiff: file can only be used to initialize unresolved state once. Pass fileDiff and actions for subsequent updates.'\n );\n }\n file ??= this.computedCache.file;\n if (file == null) {\n throw new Error(\n 'UnresolvedFile.getOrComputeDiff: file is null, should be impossible'\n );\n }\n if (\n !areFilesEqual(file, this.computedCache.file) ||\n this.computedCache.fileDiff == null ||\n this.computedCache.actions == null\n ) {\n const computed = parseMergeConflictDiffFromFile(\n file,\n maxContextLines\n );\n this.computedCache = {\n file,\n fileDiff: computed.fileDiff,\n actions: computed.actions,\n markerRows: computed.markerRows,\n };\n }\n fileDiff = this.computedCache.fileDiff;\n actions = this.computedCache.actions;\n markerRows = this.computedCache.markerRows;\n break wrapper;\n }\n // Otherwise we should fall through and try to use the cache if it exists\n else {\n fileDiff = this.computedCache.fileDiff;\n actions = this.computedCache.actions;\n markerRows = this.computedCache.markerRows;\n break wrapper;\n }\n }\n // If we are uncontrolled we only rely on the file and only use the first\n // version. After that, the cached diff/action pair is the source of\n // truth and we should not accept a new file input.\n else {\n if (fileDiff != null || actions != null || markerRows != null) {\n throw new Error(\n 'UnresolvedFile.getOrComputeDiff: fileDiff, actions, and markerRows are only usable in controlled mode, you must pass in `onMergeConflictAction`'\n );\n }\n if (\n file != null &&\n this.computedCache.file != null &&\n !areFilesEqual(file, this.computedCache.file)\n ) {\n throw new Error(\n 'UnresolvedFile.getOrComputeDiff: uncontrolled unresolved files parse the file only once. Later updates must come from the cached diff state.'\n );\n }\n this.computedCache.file ??= file;\n if (\n this.computedCache.fileDiff == null &&\n this.computedCache.file != null\n ) {\n const computed = parseMergeConflictDiffFromFile(\n this.computedCache.file,\n maxContextLines\n );\n this.computedCache.fileDiff = computed.fileDiff;\n this.computedCache.actions = computed.actions;\n this.computedCache.markerRows = computed.markerRows;\n }\n // Because we are uncontrolled, the source of truth is the\n // computedCache\n fileDiff = this.computedCache.fileDiff;\n actions = this.computedCache.actions;\n markerRows = this.computedCache.markerRows;\n break wrapper;\n }\n }\n if (fileDiff == null || actions == null || markerRows == null) {\n return undefined;\n }\n return { fileDiff, actions, markerRows };\n }\n\n override hydrate(props: UnresolvedFileHydrationProps<LAnnotation>): void {\n const {\n file,\n fileDiff,\n actions,\n markerRows,\n lineAnnotations,\n fileContainer,\n prerenderedHTML,\n preventEmit = false,\n } = props;\n const source = this.getOrComputeDiff({\n file,\n fileDiff,\n actions,\n markerRows,\n });\n if (source == null) {\n return;\n }\n this.hydrateElements(fileContainer, prerenderedHTML);\n this.prepareRenderData(source.fileDiff);\n // If necessary hydration elements don't exist, we should assume a full\n // render\n if (\n shouldRenderCode(this.pre, source.fileDiff, this.options.collapsed) ||\n shouldRenderHeader(\n this.headerElement,\n source.fileDiff,\n this.options.disableFileHeader\n )\n ) {\n this.render({ ...props, preventEmit: true });\n }\n // Otherwise orchestrate our setup\n else {\n this.hydrationSetup({ fileDiff: source.fileDiff, lineAnnotations });\n if (this.pre != null) {\n this.renderMergeConflictActionSlots();\n }\n }\n if (!preventEmit) {\n this.emitPostRender();\n }\n }\n\n override rerender(): void {\n if (!this.enabled || this.computedCache.fileDiff == null) {\n return;\n }\n if (this.requestRender()) return;\n this.render({ forceRender: true, renderRange: this.renderRange });\n }\n\n override render(props: UnresolvedFileRenderProps<LAnnotation> = {}): boolean {\n const {\n file,\n fileDiff,\n actions,\n markerRows,\n lineAnnotations,\n preventEmit = false,\n ...rest\n } = props;\n const source = this.getOrComputeDiff({\n file,\n fileDiff,\n actions,\n markerRows,\n });\n if (source == null) {\n return false;\n }\n const didRender = super.render({\n ...rest,\n fileDiff: source.fileDiff,\n lineAnnotations,\n preventEmit: true,\n });\n if (didRender) {\n this.renderMergeConflictActionSlots();\n if (!preventEmit) {\n this.emitPostRender();\n }\n }\n return didRender;\n }\n\n public resolveConflict(\n conflictIndex: number,\n resolution: MergeConflictResolution,\n fileDiff: FileDiffMetadata | undefined = this.computedCache.fileDiff\n ): ResolveConflictReturn | undefined {\n const action = this.computedCache.actions?.[conflictIndex];\n if (fileDiff == null || action == null) {\n return undefined;\n }\n\n if (action.conflictIndex !== conflictIndex) {\n console.error({ conflictIndex, action });\n throw new Error(\n \"UnresolvedFile.resolveConflict: conflictIndex and conflictAction don't match\"\n );\n }\n\n const newFileDiff = resolveConflictDiff(fileDiff, action, resolution);\n const previousFile = this.computedCache.file;\n const { file, actions, markerRows } = rebuildFileAndActions({\n fileDiff: newFileDiff,\n previousActions: this.computedCache.actions ?? [],\n resolvedConflictIndex: conflictIndex,\n previousFile,\n resolution,\n });\n\n return {\n file,\n fileDiff: newFileDiff,\n actions,\n markerRows,\n };\n }\n\n private resolveConflictAndRender(\n conflictIndex: number,\n resolution: MergeConflictResolution\n ): void {\n const action = this.computedCache.actions?.[conflictIndex];\n if (action == null) {\n return;\n }\n if (action.conflictIndex !== conflictIndex) {\n console.error({ conflictIndex, action });\n throw new Error(\n \"UnresolvedFile.resolveConflictAndRender: conflictIndex and conflictAction don't match\"\n );\n }\n const payload: MergeConflictActionPayload = {\n resolution,\n conflict: action.conflict,\n };\n const { file, fileDiff, actions, markerRows } =\n this.resolveConflict(conflictIndex, resolution) ?? {};\n if (\n file == null ||\n fileDiff == null ||\n actions == null ||\n markerRows == null\n ) {\n return;\n }\n\n this.computedCache = { file, fileDiff, actions, markerRows };\n // NOTE(amadeus): This is a bit jank, but helps to ensure we don't see a\n // bunch of jittery re-renders as things resolve out. In a more perfect\n // world we would have a more elegant way to kick off a render to the\n // highlighter and then resolve actions in a cleaner way, but time is short\n // right now. Can't let perfect be the enemy of good\n const { workerManager } = this;\n if (\n workerManager?.isWorkingPool() === true &&\n !workerManager.shouldHighlightOnMainThread(fileDiff)\n ) {\n // Because the diff highlights on a worker, if we fire off the renderDiff\n // call, it will eventually get back to us in a callback which will\n // trigger a re-render\n this.hunksRenderer.renderDiff(fileDiff);\n } else {\n this.render({ forceRender: true });\n }\n this.options.onMergeConflictResolve?.(file, payload);\n }\n\n // Use conflict actions and marker rows for the diff being rendered. While\n // a replacement is being highlighted, use the previous diff's actions and rows.\n protected override prepareRenderData(fileDiff: FileDiffMetadata): void {\n super.prepareRenderData(fileDiff);\n const latest = areDiffTargetsEqual(fileDiff, this.computedCache.fileDiff);\n if (this.hunksRenderer instanceof UnresolvedFileHunksRenderer) {\n this.hunksRenderer.setConflictState(\n this.options.mergeConflictActionsType === 'none'\n ? []\n : ((latest ? this.computedCache.actions : this.conflictActions) ??\n []),\n (latest ? this.computedCache.markerRows : this.markerRows) ?? [],\n fileDiff\n );\n }\n }\n\n protected override adoptRenderData(fileDiff: FileDiffMetadata): void {\n super.adoptRenderData(fileDiff);\n if (areDiffTargetsEqual(fileDiff, this.computedCache.fileDiff)) {\n this.conflictActions = this.computedCache.actions ?? [];\n this.markerRows = this.computedCache.markerRows ?? [];\n }\n }\n\n private handleMergeConflictActionClick = (\n target: MergeConflictActionTarget\n ): void => {\n // With onMergeConflictAction, the new diff may reuse an index for a different\n // conflict. Ignore clicks on the old diff until the new one is displayed.\n // Built-in resolution keeps indices stable, so remaining conflicts can still\n // be clicked while highlighting is pending. A wrapper component manages\n // resolution itself and handles every click.\n if (\n !this.isComponentManaged &&\n this.options.onMergeConflictAction != null &&\n !areDiffTargetsEqual(this.getRenderedDiff(), this.computedCache.fileDiff)\n ) {\n return;\n }\n const action = this.conflictActions[target.conflictIndex];\n if (action == null) {\n return;\n }\n if (action.conflictIndex !== target.conflictIndex) {\n console.error({ conflictIndex: target.conflictIndex, action });\n throw new Error(\n \"UnresolvedFile.handleMergeConflictActionClick: conflictIndex and conflictAction don't match\"\n );\n }\n const payload: MergeConflictActionPayload = {\n resolution: target.resolution,\n conflict: action.conflict,\n };\n if (this.options.onMergeConflictAction != null) {\n this.options.onMergeConflictAction(payload, this);\n return;\n }\n this.resolveConflictAndRender(target.conflictIndex, target.resolution);\n };\n\n private renderMergeConflictActionSlots(): void {\n const fileDiff = this.getRenderedDiff();\n if (\n this.isComponentManaged ||\n this.fileContainer == null ||\n typeof this.options.mergeConflictActionsType !== 'function' ||\n this.conflictActions.length === 0 ||\n fileDiff == null\n ) {\n this.clearMergeConflictActionCache();\n return;\n }\n const staleActions = new Map(this.conflictActionCache);\n for (\n let actionIndex = 0;\n actionIndex < this.conflictActions.length;\n actionIndex++\n ) {\n const action = this.conflictActions[actionIndex];\n if (action == null) {\n continue;\n }\n if (action.conflictIndex !== actionIndex) {\n console.error({ conflictIndex: actionIndex, action });\n throw new Error(\n \"UnresolvedFile.renderMergeConflictActionSlots: conflictIndex and conflictAction don't match\"\n );\n }\n const anchor = getMergeConflictActionAnchor(action, fileDiff);\n if (anchor == null) {\n continue;\n }\n const conflictIndex = action.conflictIndex;\n const slotName = getMergeConflictActionSlotName({\n hunkIndex: anchor.hunkIndex,\n lineIndex: anchor.lineIndex,\n conflictIndex,\n });\n const id = `${actionIndex}-${slotName}`;\n let cache = this.conflictActionCache.get(id);\n if (\n cache == null ||\n !areMergeConflictActionsEqual(cache.action, action)\n ) {\n cache?.element.remove();\n const rendered = this.renderMergeConflictAction(action);\n if (rendered == null) {\n continue;\n }\n const element = createAnnotationWrapperNode(slotName);\n element.appendChild(rendered);\n this.fileContainer.appendChild(element);\n cache = { element, action };\n this.conflictActionCache.set(id, cache);\n }\n staleActions.delete(id);\n }\n for (const [id, { element }] of staleActions.entries()) {\n this.conflictActionCache.delete(id);\n element.remove();\n }\n }\n\n private renderMergeConflictAction(\n action: MergeConflictDiffAction\n ): HTMLElement | undefined {\n if (typeof this.options.mergeConflictActionsType !== 'function') {\n return undefined;\n }\n const rendered = this.options.mergeConflictActionsType(action, this);\n if (rendered == null) {\n return undefined;\n }\n if (rendered instanceof HTMLElement) {\n return rendered;\n }\n if (\n typeof DocumentFragment !== 'undefined' &&\n rendered instanceof DocumentFragment\n ) {\n const wrapper = document.createElement('div');\n wrapper.style.display = 'contents';\n wrapper.appendChild(rendered);\n return wrapper;\n }\n return undefined;\n }\n\n private clearMergeConflictActionCache(): void {\n for (const { element } of this.conflictActionCache.values()) {\n element.remove();\n }\n this.conflictActionCache.clear();\n }\n}\n\ninterface RebuildFileAndActionsProps {\n fileDiff: FileDiffMetadata;\n previousActions: (MergeConflictDiffAction | undefined)[];\n resolvedConflictIndex: number;\n // FIXME: Probably should remove this...\n // additionOffset: number;\n // deletionOffset: number;\n previousFile: FileContents | undefined;\n resolution: MergeConflictResolution;\n}\n\n// Rebuild the emitted unresolved file contents and remaining action anchors in\n// one pass over the post-resolution diff state.\nfunction rebuildFileAndActions({\n fileDiff,\n previousActions,\n resolvedConflictIndex,\n previousFile,\n resolution,\n}: RebuildFileAndActionsProps): Pick<\n ResolveConflictReturn,\n 'file' | 'actions' | 'markerRows'\n> {\n const resolvedAction = previousActions[resolvedConflictIndex];\n if (resolvedAction == null) {\n throw new Error(\n 'rebuildFileAndActions: missing resolved action for unresolved file rebuild'\n );\n }\n\n const actions = updateConflictActionsAfterResolution(\n previousActions,\n resolvedConflictIndex,\n resolvedAction,\n resolution\n );\n const markerRows = buildMergeConflictMarkerRows(fileDiff, actions);\n\n const file = rebuildUnresolvedFile({\n fileDiff,\n resolvedAction,\n resolvedConflictIndex,\n previousFile,\n resolution,\n });\n\n return {\n file,\n actions,\n markerRows,\n };\n}\n\ninterface RebuildUnresolvedFileProps {\n fileDiff: FileDiffMetadata;\n resolvedAction: MergeConflictDiffAction;\n resolvedConflictIndex: number;\n previousFile: FileContents | undefined;\n resolution: MergeConflictResolution;\n}\n\n// Rebuild the unresolved file text from the previous unresolved source so we\n// preserve remaining marker blocks exactly while the diff state stays in-place.\nfunction rebuildUnresolvedFile({\n resolvedAction,\n resolvedConflictIndex,\n previousFile,\n fileDiff,\n resolution,\n}: RebuildUnresolvedFileProps): FileContents {\n const previousContents = previousFile?.contents ?? '';\n const lines = splitFileContents(previousContents);\n const { conflict } = resolvedAction;\n const replacementLines = getResolvedConflictReplacementLines(\n lines,\n conflict,\n resolution\n );\n const contents = [\n ...lines.slice(0, conflict.startLineIndex),\n ...replacementLines,\n ...lines.slice(conflict.endLineIndex + 1),\n ].join('');\n\n return {\n name: previousFile?.name ?? fileDiff.name,\n contents,\n cacheKey:\n previousFile?.cacheKey != null\n ? `${previousFile.cacheKey}:mc-${resolvedConflictIndex}-${resolution}`\n : undefined,\n };\n}\n\nfunction getResolvedConflictReplacementLines(\n lines: string[],\n conflict: MergeConflictDiffAction['conflict'],\n resolution: MergeConflictResolution\n): string[] {\n const currentLines = lines.slice(\n conflict.startLineIndex + 1,\n conflict.baseMarkerLineIndex ?? conflict.separatorLineIndex\n );\n const incomingLines = lines.slice(\n conflict.separatorLineIndex + 1,\n conflict.endLineIndex\n );\n\n if (resolution === 'current') {\n return currentLines;\n }\n if (resolution === 'incoming') {\n return incomingLines;\n }\n return [...currentLines, ...incomingLines];\n}\n\n// The diff resolver keeps hunk/content group indexes stable, so the only\n// follow-up update we need here is shifting unresolved source-region line\n// numbers for later conflicts in the rebuilt file text.\nfunction updateConflictActionsAfterResolution(\n previousActions: (MergeConflictDiffAction | undefined)[],\n resolvedConflictIndex: number,\n resolvedAction: MergeConflictDiffAction,\n resolution: MergeConflictResolution\n): (MergeConflictDiffAction | undefined)[] {\n const lineDelta = getResolvedConflictLineDelta(\n resolvedAction.conflict,\n resolution\n );\n\n return previousActions.map((action, index) => {\n if (index === resolvedConflictIndex) {\n return undefined;\n }\n if (action == null) {\n return undefined;\n }\n if (action.conflict.startLineIndex > resolvedAction.conflict.endLineIndex) {\n return {\n ...action,\n conflict: shiftMergeConflictRegion(action.conflict, lineDelta),\n };\n }\n return action;\n });\n}\n\nfunction getResolvedConflictLineDelta(\n conflict: MergeConflictRegion,\n resolution: MergeConflictResolution\n): number {\n const currentLineCount =\n (conflict.baseMarkerLineIndex ?? conflict.separatorLineIndex) -\n conflict.startLineIndex -\n 1;\n const incomingLineCount =\n conflict.endLineIndex - conflict.separatorLineIndex - 1;\n const replacementLineCount =\n resolution === 'current'\n ? currentLineCount\n : resolution === 'incoming'\n ? incomingLineCount\n : currentLineCount + incomingLineCount;\n const conflictLineCount = conflict.endLineIndex - conflict.startLineIndex + 1;\n return replacementLineCount - conflictLineCount;\n}\n\nfunction shiftMergeConflictRegion(\n conflict: MergeConflictRegion,\n lineDelta: number\n): MergeConflictRegion {\n return {\n ...conflict,\n startLineIndex: conflict.startLineIndex + lineDelta,\n startLineNumber: conflict.startLineNumber + lineDelta,\n separatorLineIndex: conflict.separatorLineIndex + lineDelta,\n separatorLineNumber: conflict.separatorLineNumber + lineDelta,\n endLineIndex: conflict.endLineIndex + lineDelta,\n endLineNumber: conflict.endLineNumber + lineDelta,\n baseMarkerLineIndex:\n conflict.baseMarkerLineIndex != null\n ? conflict.baseMarkerLineIndex + lineDelta\n : undefined,\n baseMarkerLineNumber:\n conflict.baseMarkerLineNumber != null\n ? conflict.baseMarkerLineNumber + lineDelta\n : undefined,\n };\n}\n\nfunction shouldRenderCode(\n pre: HTMLPreElement | undefined,\n fileDiff: FileDiffMetadata | undefined,\n collapsed = false\n): boolean {\n return !collapsed && pre == null && fileDiff != null;\n}\n\nfunction shouldRenderHeader(\n headerElement: HTMLElement | undefined,\n fileDiff: FileDiffMetadata | undefined,\n disableFileHeader = false\n): boolean {\n return headerElement == null && fileDiff != null && !disableFileHeader;\n}\n\n// NOTE(amadeus): Should probably pull this out into a util, and make variants\n// for all component types\nexport function getUnresolvedDiffHunksRendererOptions<LAnnotation>(\n options?: UnresolvedFileOptions<LAnnotation>,\n baseOptions?: UnresolvedFileOptions<LAnnotation>\n): UnresolvedFileHunksRendererOptions {\n const merged = { ...baseOptions, ...options };\n return {\n ...merged,\n useTokenTransformer: shouldUseTokenTransformer<'diff'>(merged),\n hunkSeparators:\n typeof options?.hunkSeparators === 'function'\n ? 'custom'\n : options?.hunkSeparators,\n mergeConflictActionsType:\n typeof options?.mergeConflictActionsType === 'function'\n ? 'custom'\n : options?.mergeConflictActionsType,\n };\n}\n"],"mappings":"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"}
|
|
@@ -18,9 +18,8 @@ declare class VirtualizedFile<LAnnotation = undefined, Caret = undefined> extend
|
|
|
18
18
|
private isVisible;
|
|
19
19
|
private isSetup;
|
|
20
20
|
private layoutDirty;
|
|
21
|
-
private forceRenderOverride;
|
|
22
21
|
private currentCollapsed;
|
|
23
|
-
constructor(options: FileOptions<LAnnotation, Caret> | undefined, virtualizer: Virtualizer | CodeView<LAnnotation, Caret>, metrics?: VirtualFileMetrics, workerManager?: WorkerPoolManager,
|
|
22
|
+
constructor(options: FileOptions<LAnnotation, Caret> | undefined, virtualizer: Virtualizer | CodeView<LAnnotation, Caret>, metrics?: VirtualFileMetrics, workerManager?: WorkerPoolManager, requestOwnerRender?: () => void);
|
|
24
23
|
setMetrics(metrics?: Partial<VirtualFileMetrics>, force?: boolean): void;
|
|
25
24
|
setLineAnnotations(lineAnnotations: LineAnnotation<LAnnotation>[]): void;
|
|
26
25
|
private syncLineAnnotations;
|
|
@@ -36,6 +35,7 @@ declare class VirtualizedFile<LAnnotation = undefined, Caret = undefined> extend
|
|
|
36
35
|
onRender: (dirty: boolean) => boolean;
|
|
37
36
|
updateCodeViewLayout(file: FileContents, top: number, reset?: PendingCodeViewLayoutReset, lineAnnotations?: LineAnnotation<LAnnotation>[]): number;
|
|
38
37
|
private getLayoutFile;
|
|
38
|
+
private getLayoutAnnotations;
|
|
39
39
|
getLinePosition(lineNumber: number): {
|
|
40
40
|
top: number;
|
|
41
41
|
height: number;
|
|
@@ -48,6 +48,7 @@ declare class VirtualizedFile<LAnnotation = undefined, Caret = undefined> extend
|
|
|
48
48
|
private computeApproximateSize;
|
|
49
49
|
setVisibility(visible: boolean): void;
|
|
50
50
|
rerender(): void;
|
|
51
|
+
protected get isComponentManaged(): boolean;
|
|
51
52
|
syncGhostTextRows(): void;
|
|
52
53
|
applyDocumentChange(textDocument: TextDocument<'file', LAnnotation>, newLineAnnotations?: LineAnnotation<LAnnotation>[], shouldUpdateBuffer?: boolean): void;
|
|
53
54
|
render({ fileContainer, file, forceRender, lineAnnotations, ...props }: FileRenderProps<LAnnotation>): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VirtualizedFile.d.ts","names":[],"sources":["../../src/components/VirtualizedFile.ts"],"mappings":";;;;;;;;
|
|
1
|
+
{"version":3,"file":"VirtualizedFile.d.ts","names":[],"sources":["../../src/components/VirtualizedFile.ts"],"mappings":";;;;;;;;cAiFa,gBACX,yBACA,2BACQ,KAAK,aAAa;UAwBhB;UACA;WAxBQ;WACF;EAET;EACA;UACC;UAUA;UACA;UACA;UACA;UACA;EAER,YACE,SAAS,YAAY,aAAa,oBAC1B,aAAa,cAAc,SAAS,aAAa,QACjD,UAAS,oBACjB,gBAAgB,mBAChB;EAKK,WACL,UAAU,QAAQ,qBAClB;EAWO,mBACP,iBAAiB,eAAe;UAS1B;YAiBW,qCACjB,iBAAiB,eAAe;UAS1B;UASA;EAYD,cAAc,mBAAmB;EAS/B,WACP,SAAS,YAAY,aAAa;EA4B3B,aAAa,WAAW;UAUzB;UAyBA;EAkCD;EAoHA,WAAQ;EAaR,qBACL,MAAM,cACN,aACA,QAAQ,4BACR,kBAAkB,eAAe;UA6C3B;UAKA;EAOD,gBACL;IACG;IAAa;;EAmDX,qBAAqB,cAAc;EAMnC,uBACL,2BACC;EAgFI;EAIA,uBACL,cAAc,eACb;EAyCM,QAAQ;UAiCT;EA0ED,cAAc;EAcZ;gBAsBc;EAUhB;EAYE,oBACP,cAAc,qBAAqB,cACnC,qBAAqB,eAAe,gBACpC;EAoCO,SACP,eACA,MACA,aACA,oBACG,SACF,gBAAgB;YA4FA;UAiBX;EA0BD;YAIY;YAMA;UAIX;UAIA;UAIA;UAWA;UAiCA;UAuCA;UASA;UAIA;UAIA;UAIA"}
|
|
@@ -29,10 +29,9 @@ var VirtualizedFile = class extends File {
|
|
|
29
29
|
isVisible = false;
|
|
30
30
|
isSetup = false;
|
|
31
31
|
layoutDirty = true;
|
|
32
|
-
forceRenderOverride;
|
|
33
32
|
currentCollapsed;
|
|
34
|
-
constructor(options, virtualizer, metrics = DEFAULT_VIRTUAL_FILE_METRICS, workerManager,
|
|
35
|
-
super(options, workerManager,
|
|
33
|
+
constructor(options, virtualizer, metrics = DEFAULT_VIRTUAL_FILE_METRICS, workerManager, requestOwnerRender) {
|
|
34
|
+
super(options, workerManager, requestOwnerRender);
|
|
36
35
|
this.virtualizer = virtualizer;
|
|
37
36
|
this.metrics = metrics;
|
|
38
37
|
}
|
|
@@ -59,7 +58,7 @@ var VirtualizedFile = class extends File {
|
|
|
59
58
|
return false;
|
|
60
59
|
}
|
|
61
60
|
hasLineAnnotations() {
|
|
62
|
-
return this.
|
|
61
|
+
return this.getLayoutAnnotations().some((annotation) => annotation.lineNumber > 0);
|
|
63
62
|
}
|
|
64
63
|
hasUniformLineHeights() {
|
|
65
64
|
const { overflow = "scroll" } = this.options;
|
|
@@ -123,7 +122,7 @@ var VirtualizedFile = class extends File {
|
|
|
123
122
|
this.top = this.getVirtualizedTop();
|
|
124
123
|
const ghostTextRows = this.editor?.__getGhostTextRows() ?? NO_GHOST_TEXT_ROWS;
|
|
125
124
|
hasHeightChange = this.applyGhostTextRows(ghostTextRows);
|
|
126
|
-
const measureAllRows = overflow !== "scroll" || this.
|
|
125
|
+
const measureAllRows = overflow !== "scroll" || this.lineAnnotations.length > 0 || this.isResizeDebuggingEnabled();
|
|
127
126
|
if (this.placeHolder != null || !measureAllRows && this.cache.heights.size === 0 && this.cache.fileAnnotationHeight === 0) {
|
|
128
127
|
if (hasHeightChange) {
|
|
129
128
|
this.computeApproximateSize(true);
|
|
@@ -166,13 +165,14 @@ var VirtualizedFile = class extends File {
|
|
|
166
165
|
return hasHeightChange;
|
|
167
166
|
}
|
|
168
167
|
onRender = (dirty) => {
|
|
169
|
-
|
|
168
|
+
const file = this.getInputFile();
|
|
169
|
+
if (this.fileContainer == null || file == null) return false;
|
|
170
170
|
if (dirty) this.top = this.getVirtualizedTop();
|
|
171
|
-
return this.render({ file
|
|
171
|
+
return this.render({ file });
|
|
172
172
|
};
|
|
173
173
|
updateCodeViewLayout(file, top, reset, lineAnnotations) {
|
|
174
|
-
const targetChanged = !areFileTargetsEqual(this.
|
|
175
|
-
if (targetChanged) this.
|
|
174
|
+
const targetChanged = !areFileTargetsEqual(this.getInputFile(), file);
|
|
175
|
+
if (targetChanged) this.updateInputFile(file, lineAnnotations);
|
|
176
176
|
const { pendingRenderFile, layoutFileChanged, renderedFileChanged, annotationsChanged } = this.updatePendingRender(file, lineAnnotations);
|
|
177
177
|
let shouldResetLayoutCache = reset?.resetFileLayoutCache === true || layoutFileChanged;
|
|
178
178
|
if (reset?.metrics != null) {
|
|
@@ -194,6 +194,10 @@ var VirtualizedFile = class extends File {
|
|
|
194
194
|
getLayoutFile() {
|
|
195
195
|
return this.pendingRender?.file ?? this.getRenderedFile();
|
|
196
196
|
}
|
|
197
|
+
getLayoutAnnotations() {
|
|
198
|
+
const { pendingRender } = this;
|
|
199
|
+
return pendingRender != null ? this.getAnnotationsForFile(pendingRender.file) : this.lineAnnotations;
|
|
200
|
+
}
|
|
197
201
|
getLinePosition(lineNumber) {
|
|
198
202
|
const file = this.getLayoutFile();
|
|
199
203
|
if (file == null || lineNumber < 1) return;
|
|
@@ -283,7 +287,7 @@ var VirtualizedFile = class extends File {
|
|
|
283
287
|
cleanUp(recycle = false) {
|
|
284
288
|
const hadGhostTextRows = this.cache.ghostTextRows.size > 0;
|
|
285
289
|
if (hadGhostTextRows) this.layoutDirty = true;
|
|
286
|
-
const shouldRecomputeLayout = recycle && this.isAdvancedMode() && this.fileContainer != null && (hadGhostTextRows || !areFileTargetsEqual(this.getRenderedFile(), this.
|
|
290
|
+
const shouldRecomputeLayout = recycle && this.isAdvancedMode() && this.fileContainer != null && (hadGhostTextRows || !areFileTargetsEqual(this.getRenderedFile(), this.getWorkingFile()));
|
|
287
291
|
if (this.fileContainer != null && this.isSimpleMode()) this.getSimpleVirtualizer()?.disconnect(this.fileContainer);
|
|
288
292
|
if (!recycle) this.resetLayoutCache();
|
|
289
293
|
this.pendingRender = void 0;
|
|
@@ -343,13 +347,17 @@ var VirtualizedFile = class extends File {
|
|
|
343
347
|
}
|
|
344
348
|
}
|
|
345
349
|
rerender() {
|
|
346
|
-
if (!this.enabled || this.
|
|
347
|
-
const
|
|
348
|
-
const nextRenderFile =
|
|
350
|
+
if (!this.enabled || this.getInputFile() == null) return;
|
|
351
|
+
const workingFile = this.getWorkingFile();
|
|
352
|
+
const nextRenderFile = workingFile == null ? void 0 : this.fileRenderer.getFileForNextRender(workingFile);
|
|
349
353
|
if (this.isSimpleMode()) this.pendingRender = void 0;
|
|
350
354
|
this.forceRenderOverride = true;
|
|
355
|
+
if (this.isSimpleMode() && this.requestRender()) return;
|
|
351
356
|
this.virtualizer.instanceChanged(this, !areFileTargetsEqual(this.getRenderedFile(), nextRenderFile));
|
|
352
357
|
}
|
|
358
|
+
get isComponentManaged() {
|
|
359
|
+
return this.getAdvancedVirtualizer()?.isComponentManaged ?? super.isComponentManaged;
|
|
360
|
+
}
|
|
353
361
|
syncGhostTextRows() {
|
|
354
362
|
const codeView = this.getAdvancedVirtualizer();
|
|
355
363
|
if (codeView != null) {
|
|
@@ -375,13 +383,13 @@ var VirtualizedFile = class extends File {
|
|
|
375
383
|
this.virtualizer.instanceChanged(this, true);
|
|
376
384
|
}
|
|
377
385
|
render({ fileContainer, file, forceRender = false, lineAnnotations, ...props }) {
|
|
378
|
-
const didFileChange = !areFileTargetsEqual(this.
|
|
386
|
+
const didFileChange = !areFileTargetsEqual(this.getInputFile(), file);
|
|
379
387
|
if (didFileChange) {
|
|
380
|
-
this.
|
|
388
|
+
this.updateInputFile(file, lineAnnotations);
|
|
381
389
|
this.cachedHeaderHTML = void 0;
|
|
382
390
|
}
|
|
383
391
|
const { pendingRenderFile, layoutFileChanged, renderedFileChanged, annotationsChanged } = (() => {
|
|
384
|
-
if (this.pendingRender != null && this.pendingRender.
|
|
392
|
+
if (this.pendingRender != null && this.pendingRender.workingFile === (this.getWorkingFile(file) ?? file)) return {
|
|
385
393
|
pendingRenderFile: this.pendingRender.file,
|
|
386
394
|
layoutFileChanged: false,
|
|
387
395
|
renderedFileChanged: false,
|
|
@@ -430,12 +438,12 @@ var VirtualizedFile = class extends File {
|
|
|
430
438
|
if (this.isSimpleMode()) this.getSimpleVirtualizer()?.requestHeightReconcile(this);
|
|
431
439
|
}
|
|
432
440
|
updatePendingRender(nextFile, lineAnnotations) {
|
|
433
|
-
const
|
|
441
|
+
const workingFile = this.getWorkingFile(nextFile) ?? nextFile;
|
|
434
442
|
const previousRenderedFile = this.getRenderedFile();
|
|
435
443
|
const previousLayoutFile = this.pendingRender?.file ?? previousRenderedFile;
|
|
436
|
-
const pendingRenderFile = this.fileRenderer.getFileForNextRender(
|
|
444
|
+
const pendingRenderFile = this.fileRenderer.getFileForNextRender(workingFile);
|
|
437
445
|
this.pendingRender = {
|
|
438
|
-
|
|
446
|
+
workingFile,
|
|
439
447
|
file: pendingRenderFile
|
|
440
448
|
};
|
|
441
449
|
return {
|
|
@@ -526,7 +534,7 @@ var VirtualizedFile = class extends File {
|
|
|
526
534
|
const { fileAnnotationHeight } = this.cache;
|
|
527
535
|
const codeRegionTop = headerRegion + fileAnnotationHeight;
|
|
528
536
|
const codeRowsHeight = Math.max(0, fileHeight - headerRegion - fileAnnotationHeight - paddingBottom);
|
|
529
|
-
const hasFileAnnotations = includesFileAnnotations(this.
|
|
537
|
+
const hasFileAnnotations = includesFileAnnotations(this.getLayoutAnnotations());
|
|
530
538
|
const fileAnnotationTop = fileTop + headerRegion;
|
|
531
539
|
const measuredFileAnnotationVisible = fileAnnotationHeight > 0 && hasFileAnnotations && fileAnnotationTop < bottom && fileAnnotationTop + fileAnnotationHeight > top;
|
|
532
540
|
if (fileTop < top - fileHeight || fileTop > bottom) return {
|