superdoc 2.0.0-next.27 → 2.0.0-next.29
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/chunks/{PdfViewer-XZg0nr8y.es.js → PdfViewer-CNOtyS-I.es.js} +1 -1
- package/dist/chunks/{PdfViewer-BtuYf2yM.cjs → PdfViewer-CoFiGAhm.cjs} +1 -1
- package/dist/chunks/{create-super-doc-ui-Dvl3EZsv.es.js → create-super-doc-ui-BKVf2uCM.es.js} +660 -159
- package/dist/chunks/{create-super-doc-ui-pYMthdDn.cjs → create-super-doc-ui-BXehf3i3.cjs} +660 -159
- package/dist/collaboration-upgrade-engine.cjs +1 -1
- package/dist/collaboration-upgrade-engine.es.js +1 -1
- package/dist/document-api/src/contract/operation-definitions.d.ts +1 -1
- package/dist/document-api/src/track-changes/track-changes.d.ts +6 -2
- package/dist/document-api/src/types/clipboard.d.ts +5 -1
- package/dist/document-api/src/types/table-operations.types.d.ts +6 -4
- package/dist/document-api/src/types/track-changes.types.d.ts +15 -0
- package/dist/layout-engine/contracts/src/incremental-dependency.d.ts +10 -0
- package/dist/layout-engine/contracts/src/index.d.ts +38 -0
- package/dist/layout-engine/layout-bridge/src/incrementalLayout.d.ts +40 -1
- package/dist/layout-engine/layout-engine/src/index.d.ts +17 -0
- package/dist/layout-engine/layout-engine/src/paginator.d.ts +16 -0
- package/dist/layout-engine/layout-engine/src/paragraph-layout-eligibility.d.ts +1 -4
- package/dist/public/ui-react.cjs +1 -1
- package/dist/public/ui-react.es.js +1 -1
- package/dist/public/ui.cjs +1 -1
- package/dist/public/ui.es.js +1 -1
- package/dist/style.css +130 -86
- package/dist/style.layered.css +130 -86
- package/dist/superdoc/src/components/CommentsLayer/floating-comment-positioning.d.ts +1 -2
- package/dist/superdoc/src/core/types/index.d.ts +7 -0
- package/dist/superdoc/src/helpers/v2-review-mutation-impact.d.ts +4 -1
- package/dist/superdoc/src/helpers/v2-review-mutation-reconciler.d.ts +6 -5
- package/dist/superdoc/src/public/ui/reasons.d.ts +8 -0
- package/dist/superdoc/src/stores/comments-store.d.ts +17 -11
- package/dist/superdoc/src/stores/helpers/floating-comment-instances.d.ts +2 -10
- package/dist/superdoc/src/stores/helpers/tracked-change-thread-index.d.ts +14 -0
- package/dist/superdoc/src/stores/superdoc-store.d.ts +51 -33
- package/dist/superdoc.cjs +531 -135
- package/dist/superdoc.es.js +531 -135
- package/dist-cdn/style.layered.css +1 -1
- package/dist-cdn/superdoc.min.css +1 -1
- package/dist-cdn/superdoc.min.js +37 -37
- package/package.json +2 -2
package/dist/superdoc.cjs
CHANGED
|
@@ -6,7 +6,7 @@ const require_uuid = require("./chunks/uuid-CFp0WGVU.cjs");
|
|
|
6
6
|
const require_jszip = require("./chunks/jszip-BdUBlUeG.cjs");
|
|
7
7
|
const require__plugin_vue_export_helper = require("./chunks/_plugin-vue_export-helper-BTwbGDKw.cjs");
|
|
8
8
|
const require_constants = require("./chunks/constants-sbCZ2O_A.cjs");
|
|
9
|
-
const require_create_super_doc_ui = require("./chunks/create-super-doc-ui-
|
|
9
|
+
const require_create_super_doc_ui = require("./chunks/create-super-doc-ui-BXehf3i3.cjs");
|
|
10
10
|
let vue = require("vue");
|
|
11
11
|
vue = require_rolldown_runtime.__toESM(vue);
|
|
12
12
|
require("y-websocket");
|
|
@@ -145,19 +145,50 @@ function compareVersions(version1, version2) {
|
|
|
145
145
|
}
|
|
146
146
|
return 0;
|
|
147
147
|
}
|
|
148
|
+
var registries = /* @__PURE__ */ new WeakMap();
|
|
149
|
+
function ownerDocumentFor(el) {
|
|
150
|
+
return el.ownerDocument ?? document;
|
|
151
|
+
}
|
|
152
|
+
function unregister(el, ownerDocument) {
|
|
153
|
+
const registry = registries.get(ownerDocument);
|
|
154
|
+
registry?.bindings.delete(el);
|
|
155
|
+
if (registry && registry.bindings.size === 0) {
|
|
156
|
+
ownerDocument.removeEventListener("click", registry.listener);
|
|
157
|
+
registries.delete(ownerDocument);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
function register(el, binding) {
|
|
161
|
+
const ownerDocument = ownerDocumentFor(el);
|
|
162
|
+
if (el.__clickOutsideDocument && el.__clickOutsideDocument !== ownerDocument) unregister(el, el.__clickOutsideDocument);
|
|
163
|
+
let registry = registries.get(ownerDocument);
|
|
164
|
+
if (!registry) {
|
|
165
|
+
const bindings = /* @__PURE__ */ new Map();
|
|
166
|
+
const listener = (event) => {
|
|
167
|
+
const path = typeof event.composedPath === "function" ? event.composedPath() : null;
|
|
168
|
+
for (const [element, currentBinding] of bindings) if (!(path?.includes(element) ?? element.contains(event.target))) currentBinding.value?.(event);
|
|
169
|
+
};
|
|
170
|
+
registry = {
|
|
171
|
+
bindings,
|
|
172
|
+
listener
|
|
173
|
+
};
|
|
174
|
+
registries.set(ownerDocument, registry);
|
|
175
|
+
ownerDocument.addEventListener("click", listener);
|
|
176
|
+
}
|
|
177
|
+
registry.bindings.set(el, binding);
|
|
178
|
+
el.__clickOutsideHandler = registry.listener;
|
|
179
|
+
el.__clickOutsideDocument = ownerDocument;
|
|
180
|
+
}
|
|
148
181
|
var v_click_outside_default = {
|
|
149
182
|
mounted(el, binding) {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
el.__clickOutsideHandler = clickOutsideHandler;
|
|
183
|
+
register(el, binding);
|
|
184
|
+
},
|
|
185
|
+
updated(el, binding) {
|
|
186
|
+
register(el, binding);
|
|
155
187
|
},
|
|
156
188
|
unmounted(el) {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
}
|
|
189
|
+
unregister(el, el.__clickOutsideDocument ?? ownerDocumentFor(el));
|
|
190
|
+
delete el.__clickOutsideHandler;
|
|
191
|
+
delete el.__clickOutsideDocument;
|
|
161
192
|
}
|
|
162
193
|
};
|
|
163
194
|
function hasUser(entry) {
|
|
@@ -2520,7 +2551,7 @@ var aggregateRectBounds = (rects) => {
|
|
|
2520
2551
|
};
|
|
2521
2552
|
var groupRectsByPage = (rects) => {
|
|
2522
2553
|
const groupedRects = /* @__PURE__ */ new Map();
|
|
2523
|
-
rects.forEach((rect) => {
|
|
2554
|
+
(Array.isArray(rects) ? rects : []).forEach((rect) => {
|
|
2524
2555
|
const pageIndex = toFinitePageIndex(rect?.pageIndex);
|
|
2525
2556
|
if (pageIndex == null) return;
|
|
2526
2557
|
const pageRects = groupedRects.get(pageIndex);
|
|
@@ -2547,31 +2578,40 @@ var resolveSelectionPageIndex = (comment) => {
|
|
|
2547
2578
|
};
|
|
2548
2579
|
var buildSingleFloatingCommentInstance = ({ id, threadId, comment, positionKey, positionEntry }) => {
|
|
2549
2580
|
const geometryPageIndex = toFinitePageIndex(positionEntry?.pageIndex);
|
|
2550
|
-
const
|
|
2581
|
+
const fallbackPageIndex = comment?.trackedChange ? null : resolveSelectionPageIndex(comment);
|
|
2551
2582
|
return {
|
|
2552
2583
|
id,
|
|
2553
2584
|
threadId,
|
|
2554
2585
|
comment,
|
|
2555
2586
|
positionKey,
|
|
2556
2587
|
positionEntry: positionEntry ?? null,
|
|
2557
|
-
pageIndex,
|
|
2588
|
+
pageIndex: geometryPageIndex ?? fallbackPageIndex,
|
|
2558
2589
|
isPrimary: true
|
|
2559
2590
|
};
|
|
2560
2591
|
};
|
|
2561
|
-
var buildRepeatedHeaderFooterInstances = ({ comment, positionKey, positionEntry }) => {
|
|
2592
|
+
var buildRepeatedHeaderFooterInstances = ({ comment, positionKey, positionEntry, primaryInstanceId }) => {
|
|
2562
2593
|
const rectGroups = groupRectsByPage(positionEntry?.rects);
|
|
2563
2594
|
if (rectGroups.length < 2) return [];
|
|
2564
|
-
const
|
|
2565
|
-
return rectGroups.map(({ pageIndex, rects }) => {
|
|
2595
|
+
const renderableGroups = rectGroups.map(({ pageIndex, rects }) => {
|
|
2566
2596
|
const bounds = aggregateRectBounds(rects);
|
|
2567
|
-
|
|
2597
|
+
return bounds ? {
|
|
2598
|
+
pageIndex,
|
|
2599
|
+
rects,
|
|
2600
|
+
bounds
|
|
2601
|
+
} : null;
|
|
2602
|
+
}).filter(Boolean);
|
|
2603
|
+
if (renderableGroups.length < 2) return [];
|
|
2604
|
+
const geometryPageIndex = toFinitePageIndex(positionEntry?.pageIndex);
|
|
2605
|
+
const primaryPageIndex = renderableGroups.some(({ pageIndex }) => pageIndex === geometryPageIndex) ? geometryPageIndex : renderableGroups[0]?.pageIndex ?? null;
|
|
2606
|
+
return renderableGroups.map(({ pageIndex, rects, bounds }) => {
|
|
2607
|
+
const isPrimary = pageIndex === primaryPageIndex;
|
|
2568
2608
|
return {
|
|
2569
|
-
id: buildPageScopedInstanceId(
|
|
2609
|
+
id: isPrimary ? primaryInstanceId : buildPageScopedInstanceId(primaryInstanceId, pageIndex),
|
|
2570
2610
|
threadId: comment?.commentId ?? positionKey,
|
|
2571
2611
|
comment,
|
|
2572
2612
|
positionKey,
|
|
2573
2613
|
pageIndex,
|
|
2574
|
-
isPrimary
|
|
2614
|
+
isPrimary,
|
|
2575
2615
|
positionEntry: {
|
|
2576
2616
|
...positionEntry,
|
|
2577
2617
|
pageIndex,
|
|
@@ -2579,7 +2619,7 @@ var buildRepeatedHeaderFooterInstances = ({ comment, positionKey, positionEntry
|
|
|
2579
2619
|
bounds
|
|
2580
2620
|
}
|
|
2581
2621
|
};
|
|
2582
|
-
})
|
|
2622
|
+
});
|
|
2583
2623
|
};
|
|
2584
2624
|
const buildFloatingCommentInstances = ({ comment, positionKey, positionEntry, fallbackId }) => {
|
|
2585
2625
|
const instanceId = comment?.trackedChange && comment?.trackedChangeCanonicalId && positionKey && fallbackId && String(positionKey) !== String(fallbackId) ? fallbackId : positionKey ?? fallbackId;
|
|
@@ -2588,7 +2628,8 @@ const buildFloatingCommentInstances = ({ comment, positionKey, positionEntry, fa
|
|
|
2588
2628
|
const repeatedInstances = buildRepeatedHeaderFooterInstances({
|
|
2589
2629
|
comment,
|
|
2590
2630
|
positionKey,
|
|
2591
|
-
positionEntry
|
|
2631
|
+
positionEntry,
|
|
2632
|
+
primaryInstanceId: instanceId
|
|
2592
2633
|
});
|
|
2593
2634
|
if (repeatedInstances.length > 0) return repeatedInstances;
|
|
2594
2635
|
}
|
|
@@ -2763,6 +2804,79 @@ const trackedChangeThreadParentIdForComment = (comment) => {
|
|
|
2763
2804
|
if (comment?.trackedChangeParentId != null && hasLegacyTrackedChangeThreadSignal(comment)) return comment.trackedChangeParentId;
|
|
2764
2805
|
return null;
|
|
2765
2806
|
};
|
|
2807
|
+
const buildTrackedChangeThreadIndex = (allComments, previous = /* @__PURE__ */ new Map()) => {
|
|
2808
|
+
const childrenByParentId = /* @__PURE__ */ new Map();
|
|
2809
|
+
const anchoredRootsByTrackedChangeId = /* @__PURE__ */ new Map();
|
|
2810
|
+
const commentsById = /* @__PURE__ */ new Map();
|
|
2811
|
+
const sourceIndex = /* @__PURE__ */ new Map();
|
|
2812
|
+
const append = (map, key, value) => {
|
|
2813
|
+
const existing = map.get(key);
|
|
2814
|
+
if (existing) existing.push(value);
|
|
2815
|
+
else map.set(key, [value]);
|
|
2816
|
+
};
|
|
2817
|
+
allComments.forEach((comment, index) => {
|
|
2818
|
+
sourceIndex.set(comment, index);
|
|
2819
|
+
append(commentsById, comment.commentId, comment);
|
|
2820
|
+
new Set([comment.parentCommentId, comment.threadingParentCommentId].filter((id) => id != null).map((id) => String(id))).forEach((parentId) => append(childrenByParentId, parentId, comment));
|
|
2821
|
+
const trackedChangeThreadParentId = trackedChangeThreadParentIdForComment(comment);
|
|
2822
|
+
if (trackedChangeThreadParentId != null && !comment.parentCommentId) append(anchoredRootsByTrackedChangeId, String(trackedChangeThreadParentId), comment);
|
|
2823
|
+
});
|
|
2824
|
+
const next = /* @__PURE__ */ new Map();
|
|
2825
|
+
for (const parentComment of allComments) {
|
|
2826
|
+
if (!parentComment?.trackedChange || parentComment.commentId == null) continue;
|
|
2827
|
+
const trackedChangeId = parentComment.commentId;
|
|
2828
|
+
const threadIds = new Set([trackedChangeId]);
|
|
2829
|
+
const queue = [];
|
|
2830
|
+
const seed = typeof trackedChangeId === "string" ? [...childrenByParentId.get(trackedChangeId) ?? [], ...anchoredRootsByTrackedChangeId.get(trackedChangeId) ?? []] : [];
|
|
2831
|
+
for (const comment of seed) {
|
|
2832
|
+
const id = comment.commentId;
|
|
2833
|
+
if (id === trackedChangeId || threadIds.has(id)) continue;
|
|
2834
|
+
threadIds.add(id);
|
|
2835
|
+
queue.push(id);
|
|
2836
|
+
}
|
|
2837
|
+
for (let index = 0; index < queue.length; index += 1) {
|
|
2838
|
+
const parentId = queue[index];
|
|
2839
|
+
for (const comment of typeof parentId === "string" ? childrenByParentId.get(parentId) ?? [] : []) {
|
|
2840
|
+
const id = comment.commentId;
|
|
2841
|
+
if (threadIds.has(id)) continue;
|
|
2842
|
+
threadIds.add(id);
|
|
2843
|
+
queue.push(id);
|
|
2844
|
+
}
|
|
2845
|
+
}
|
|
2846
|
+
const members = [...threadIds].flatMap((id) => commentsById.get(id) ?? []).sort((left, right) => (sourceIndex.get(left) ?? 0) - (sourceIndex.get(right) ?? 0));
|
|
2847
|
+
members.sort((left, right) => {
|
|
2848
|
+
if (left === parentComment) return -1;
|
|
2849
|
+
if (right === parentComment) return 1;
|
|
2850
|
+
return Number(left.createdTime) - Number(right.createdTime);
|
|
2851
|
+
});
|
|
2852
|
+
const prior = previous.get(trackedChangeId);
|
|
2853
|
+
const stable = prior?.length === members.length && members.every((comment, index) => prior[index] === comment) ? prior : members;
|
|
2854
|
+
next.set(trackedChangeId, stable);
|
|
2855
|
+
}
|
|
2856
|
+
return next;
|
|
2857
|
+
};
|
|
2858
|
+
const buildTrackedChangeDecisionLinkIndex = (allComments, previous = /* @__PURE__ */ new Map()) => {
|
|
2859
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
2860
|
+
for (const comment of allComments) {
|
|
2861
|
+
const ids = new Set([
|
|
2862
|
+
comment.parentCommentId,
|
|
2863
|
+
comment.threadingParentCommentId,
|
|
2864
|
+
comment.trackedChangeParentId,
|
|
2865
|
+
comment.trackedChangeThreadParentId
|
|
2866
|
+
].filter((id) => id != null).map((id) => String(id)));
|
|
2867
|
+
for (const id of ids) {
|
|
2868
|
+
const existing = grouped.get(id);
|
|
2869
|
+
if (existing) existing.push(comment);
|
|
2870
|
+
else grouped.set(id, [comment]);
|
|
2871
|
+
}
|
|
2872
|
+
}
|
|
2873
|
+
const next = /* @__PURE__ */ new Map();
|
|
2874
|
+
for (const [id, comments] of grouped) {
|
|
2875
|
+
const prior = previous.get(id);
|
|
2876
|
+
next.set(id, prior?.length === comments.length && comments.every((comment, index) => prior[index] === comment) ? prior : comments);
|
|
2877
|
+
}
|
|
2878
|
+
return next;
|
|
2879
|
+
};
|
|
2766
2880
|
var Editor = class {
|
|
2767
2881
|
constructor() {
|
|
2768
2882
|
throw new Error("SuperDoc v2 beta: v1 editor-backed comment import paths are not available.");
|
|
@@ -2923,6 +3037,22 @@ const useCommentsStore = defineStore("comments", () => {
|
|
|
2923
3037
|
const suppressInternalExternal = (0, vue.ref)(true);
|
|
2924
3038
|
const currentCommentText = (0, vue.ref)("");
|
|
2925
3039
|
const commentsList = (0, vue.ref)([]);
|
|
3040
|
+
let priorTrackedChangeThreadIndex = /* @__PURE__ */ new Map();
|
|
3041
|
+
const trackedChangeThreadIndex = (0, vue.computed)(() => {
|
|
3042
|
+
const next = buildTrackedChangeThreadIndex(commentsList.value, priorTrackedChangeThreadIndex);
|
|
3043
|
+
priorTrackedChangeThreadIndex = next;
|
|
3044
|
+
return next;
|
|
3045
|
+
});
|
|
3046
|
+
const getTrackedChangeThread = (parentComment) => {
|
|
3047
|
+
const id = parentComment?.commentId ?? null;
|
|
3048
|
+
return (id != null ? trackedChangeThreadIndex.value.get(id) : null) ?? [parentComment].filter(Boolean);
|
|
3049
|
+
};
|
|
3050
|
+
let priorTrackedChangeDecisionLinkIndex = /* @__PURE__ */ new Map();
|
|
3051
|
+
const trackedChangeDecisionLinkIndex = (0, vue.computed)(() => {
|
|
3052
|
+
const next = buildTrackedChangeDecisionLinkIndex(commentsList.value, priorTrackedChangeDecisionLinkIndex);
|
|
3053
|
+
priorTrackedChangeDecisionLinkIndex = next;
|
|
3054
|
+
return next;
|
|
3055
|
+
});
|
|
2926
3056
|
const isCommentsListVisible = (0, vue.ref)(false);
|
|
2927
3057
|
const editorCommentIds = (0, vue.ref)([]);
|
|
2928
3058
|
const editorCommentPositions = (0, vue.ref)({});
|
|
@@ -3709,6 +3839,7 @@ const useCommentsStore = defineStore("comments", () => {
|
|
|
3709
3839
|
};
|
|
3710
3840
|
};
|
|
3711
3841
|
const getGroupedComments = (0, vue.computed)(() => buildGroupedComments(compareByCreatedTime));
|
|
3842
|
+
const hasOpenTrackedChanges = (0, vue.computed)(() => getGroupedComments.value?.parentComments.some((comment) => comment.trackedChange && !comment.resolvedTime) ?? false);
|
|
3712
3843
|
const getCommentsByPosition = (0, vue.computed)(() => buildGroupedComments(compareByPosition));
|
|
3713
3844
|
const hasOverlapId = (id) => overlappedIds.includes(id);
|
|
3714
3845
|
const documentsWithConverations = (0, vue.computed)(() => {
|
|
@@ -4894,7 +5025,7 @@ const useCommentsStore = defineStore("comments", () => {
|
|
|
4894
5025
|
superdoc
|
|
4895
5026
|
};
|
|
4896
5027
|
let resolvedCount = 0;
|
|
4897
|
-
|
|
5028
|
+
getTrackedChangeDecisionLinks(comment).forEach((linkedComment) => {
|
|
4898
5029
|
if (!linkedComment || linkedComment === comment) return;
|
|
4899
5030
|
if (linkedComment.resolvedTime) return;
|
|
4900
5031
|
if (![
|
|
@@ -4922,6 +5053,16 @@ const useCommentsStore = defineStore("comments", () => {
|
|
|
4922
5053
|
}
|
|
4923
5054
|
return trackedChangeIds;
|
|
4924
5055
|
};
|
|
5056
|
+
const getTrackedChangeDecisionLinks = (comment) => {
|
|
5057
|
+
const linked = [];
|
|
5058
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5059
|
+
for (const id of collectTrackedChangeDecisionIds(comment)) for (const candidate of trackedChangeDecisionLinkIndex.value.get(String(id)) ?? []) {
|
|
5060
|
+
if (seen.has(candidate)) continue;
|
|
5061
|
+
seen.add(candidate);
|
|
5062
|
+
linked.push(candidate);
|
|
5063
|
+
}
|
|
5064
|
+
return linked;
|
|
5065
|
+
};
|
|
4925
5066
|
const collectTrackedChangeEntityIdsFromReceipt = (receipt) => {
|
|
4926
5067
|
const record = receipt && typeof receipt === "object" ? receipt : null;
|
|
4927
5068
|
if (!record?.success) return /* @__PURE__ */ new Set();
|
|
@@ -4953,7 +5094,7 @@ const useCommentsStore = defineStore("comments", () => {
|
|
|
4953
5094
|
const trackedChangeIds = collectTrackedChangeDecisionIds(comment);
|
|
4954
5095
|
if (!trackedChangeIds.size) return 0;
|
|
4955
5096
|
let detachedCount = 0;
|
|
4956
|
-
|
|
5097
|
+
getTrackedChangeDecisionLinks(comment).forEach((linkedComment) => {
|
|
4957
5098
|
if (!linkedComment || linkedComment === comment) return;
|
|
4958
5099
|
const trackedChangeParentId = normalizeCommentId(linkedComment.trackedChangeParentId);
|
|
4959
5100
|
const trackedChangeThreadParentId = normalizeCommentId(linkedComment.trackedChangeThreadParentId);
|
|
@@ -4969,7 +5110,7 @@ const useCommentsStore = defineStore("comments", () => {
|
|
|
4969
5110
|
});
|
|
4970
5111
|
return detachedCount;
|
|
4971
5112
|
};
|
|
4972
|
-
const pruneDecidedTrackedChangeRow = ({ superdoc, decidedId, decidedIds, documentId } = {}) => {
|
|
5113
|
+
const pruneDecidedTrackedChangeRow = ({ superdoc, comment: targetComment, decidedId, decidedIds, documentId } = {}) => {
|
|
4973
5114
|
const normalizedDecidedIds = new Set((Array.isArray(decidedIds) || decidedIds instanceof Set ? Array.from(decidedIds) : [decidedId]).map((id) => normalizeCommentId(id)).filter(Boolean));
|
|
4974
5115
|
const normalizedDocumentId = normalizeCommentId(documentId);
|
|
4975
5116
|
if (!normalizedDecidedIds.size || !normalizedDocumentId) return {
|
|
@@ -4978,7 +5119,13 @@ const useCommentsStore = defineStore("comments", () => {
|
|
|
4978
5119
|
};
|
|
4979
5120
|
const removedIds = /* @__PURE__ */ new Set();
|
|
4980
5121
|
let removed = false;
|
|
4981
|
-
|
|
5122
|
+
const targetIndex = targetComment ? commentsList.value.indexOf(targetComment) : -1;
|
|
5123
|
+
const targetIds = targetComment?.trackedChange ? collectTrackedChangeDecisionIds(targetComment) : /* @__PURE__ */ new Set();
|
|
5124
|
+
if (targetIndex >= 0 && belongsToTrackedChangeSyncDocument(targetComment, normalizedDocumentId) && Array.from(normalizedDecidedIds).some((id) => targetIds.has(id))) {
|
|
5125
|
+
targetIds.forEach((id) => removedIds.add(id));
|
|
5126
|
+
commentsList.value.splice(targetIndex, 1);
|
|
5127
|
+
removed = true;
|
|
5128
|
+
} else commentsList.value = commentsList.value.filter((comment) => {
|
|
4982
5129
|
if (!comment?.trackedChange) return true;
|
|
4983
5130
|
if (!belongsToTrackedChangeSyncDocument(comment, normalizedDocumentId)) return true;
|
|
4984
5131
|
const ids = collectTrackedChangeDecisionIds(comment);
|
|
@@ -5014,6 +5161,25 @@ const useCommentsStore = defineStore("comments", () => {
|
|
|
5014
5161
|
adapter.clearActiveTrackedChangeTargetIfMatches(decidedId);
|
|
5015
5162
|
} catch {}
|
|
5016
5163
|
};
|
|
5164
|
+
const waitForTrackedDecisionCanonicalPaint = async ({ superdoc, receipt } = {}) => {
|
|
5165
|
+
const readiness = superdoc?.activeEditor?.documentMutationReadiness;
|
|
5166
|
+
if (receipt?.success !== true || typeof receipt?.txId !== "string" || !receipt.txId || typeof readiness?.whenPainted !== "function") return;
|
|
5167
|
+
try {
|
|
5168
|
+
await readiness.whenPainted(receipt);
|
|
5169
|
+
const requestFrame = globalThis.requestAnimationFrame;
|
|
5170
|
+
if (typeof requestFrame === "function") await new Promise((resolve) => {
|
|
5171
|
+
let settled = false;
|
|
5172
|
+
const finish = () => {
|
|
5173
|
+
if (settled) return;
|
|
5174
|
+
settled = true;
|
|
5175
|
+
clearTimeout(fallback);
|
|
5176
|
+
resolve();
|
|
5177
|
+
};
|
|
5178
|
+
const fallback = setTimeout(finish, 250);
|
|
5179
|
+
requestFrame(() => requestFrame(() => setTimeout(finish, 0)));
|
|
5180
|
+
});
|
|
5181
|
+
} catch {}
|
|
5182
|
+
};
|
|
5017
5183
|
const tracePostDecisionBackgroundReconcile = (superdoc, event, payload = {}) => {
|
|
5018
5184
|
const record = {
|
|
5019
5185
|
event,
|
|
@@ -5165,7 +5331,7 @@ const useCommentsStore = defineStore("comments", () => {
|
|
|
5165
5331
|
adapter: v2Adapter,
|
|
5166
5332
|
documentId: effectiveDocumentId,
|
|
5167
5333
|
items: listResult.items ?? [],
|
|
5168
|
-
pruneStale: listResult.complete
|
|
5334
|
+
pruneStale: listResult.complete === true && listResult.sourceCoverageComplete === true
|
|
5169
5335
|
});
|
|
5170
5336
|
const liveIds = new Set((listResult.items ?? []).map((item) => item && item.id != null ? String(item.id) : null).filter(Boolean));
|
|
5171
5337
|
if (!(decidedId != null && liveIds.has(decidedId))) {
|
|
@@ -5209,6 +5375,17 @@ const useCommentsStore = defineStore("comments", () => {
|
|
|
5209
5375
|
};
|
|
5210
5376
|
};
|
|
5211
5377
|
if (!reliableDecidedIds.size || !effectiveDocumentId) return runBlockingPostDecisionReconcile();
|
|
5378
|
+
reliableDecidedIds.forEach((id$1) => clearV2ActiveTrackedChangeTarget(v2Adapter, id$1));
|
|
5379
|
+
schedulePostDecisionBackgroundReconcile({
|
|
5380
|
+
superdoc,
|
|
5381
|
+
trackedChangesAdapter: v2Adapter,
|
|
5382
|
+
commentsAdapter: getV2CommentsAdapter(superdoc),
|
|
5383
|
+
documentId: effectiveDocumentId
|
|
5384
|
+
});
|
|
5385
|
+
await waitForTrackedDecisionCanonicalPaint({
|
|
5386
|
+
superdoc,
|
|
5387
|
+
receipt: outcome.receipt
|
|
5388
|
+
});
|
|
5212
5389
|
resolveLinkedCommentsForTrackedChangeDecision({
|
|
5213
5390
|
superdoc,
|
|
5214
5391
|
comment,
|
|
@@ -5220,17 +5397,11 @@ const useCommentsStore = defineStore("comments", () => {
|
|
|
5220
5397
|
});
|
|
5221
5398
|
pruneDecidedTrackedChangeRow({
|
|
5222
5399
|
superdoc,
|
|
5400
|
+
comment,
|
|
5223
5401
|
decidedIds: reliableDecidedIds,
|
|
5224
5402
|
documentId: effectiveDocumentId
|
|
5225
5403
|
});
|
|
5226
5404
|
if (wasActiveBeforeDecide) clearActiveCommentSelection();
|
|
5227
|
-
reliableDecidedIds.forEach((id$1) => clearV2ActiveTrackedChangeTarget(v2Adapter, id$1));
|
|
5228
|
-
schedulePostDecisionBackgroundReconcile({
|
|
5229
|
-
superdoc,
|
|
5230
|
-
trackedChangesAdapter: v2Adapter,
|
|
5231
|
-
commentsAdapter: getV2CommentsAdapter(superdoc),
|
|
5232
|
-
documentId: effectiveDocumentId
|
|
5233
|
-
});
|
|
5234
5405
|
return {
|
|
5235
5406
|
ok: true,
|
|
5236
5407
|
success: true
|
|
@@ -5299,7 +5470,7 @@ const useCommentsStore = defineStore("comments", () => {
|
|
|
5299
5470
|
reason: "adapter-stale"
|
|
5300
5471
|
};
|
|
5301
5472
|
if (!result?.ok) return result;
|
|
5302
|
-
const pruneStale = !(trackedChangesListMode === "startup-page" || trackedChangesListMode === "interaction-prime" || trackedChangesListMode === "visible-window") && result.visibleWindowSource == null && result.complete
|
|
5473
|
+
const pruneStale = !(trackedChangesListMode === "startup-page" || trackedChangesListMode === "interaction-prime" || trackedChangesListMode === "visible-window") && result.visibleWindowSource == null && result.complete === true && result.sourceCoverageComplete === true;
|
|
5303
5474
|
reconcileTrackedChangesFromV2({
|
|
5304
5475
|
superdoc,
|
|
5305
5476
|
adapter: effectiveAdapter,
|
|
@@ -5336,12 +5507,12 @@ const useCommentsStore = defineStore("comments", () => {
|
|
|
5336
5507
|
};
|
|
5337
5508
|
const effectiveDocumentId = documentId ?? effectiveAdapter.documentId ?? superdoc?.activeEditor?.documentId ?? null;
|
|
5338
5509
|
const normalizedRemovedIds = new Set(Array.from(removedIds ?? []).map((id) => normalizeCommentId(id)).filter(Boolean));
|
|
5339
|
-
|
|
5510
|
+
const normalizedUpsertIds = [...new Set(Array.from(upsertIds ?? []).map((id) => normalizeCommentId(id)).filter(Boolean))];
|
|
5511
|
+
if (normalizedRemovedIds.size > 0 && normalizedUpsertIds.length === 0 && effectiveDocumentId != null) pruneDecidedTrackedChangeRow({
|
|
5340
5512
|
superdoc,
|
|
5341
5513
|
decidedIds: normalizedRemovedIds,
|
|
5342
5514
|
documentId: effectiveDocumentId
|
|
5343
5515
|
});
|
|
5344
|
-
const normalizedUpsertIds = [...new Set(Array.from(upsertIds ?? []).map((id) => normalizeCommentId(id)).filter(Boolean))];
|
|
5345
5516
|
if (normalizedUpsertIds.length === 0) return {
|
|
5346
5517
|
ok: true,
|
|
5347
5518
|
items: [],
|
|
@@ -5812,6 +5983,7 @@ const useCommentsStore = defineStore("comments", () => {
|
|
|
5812
5983
|
const getFloatingComments = (0, vue.computed)(() => {
|
|
5813
5984
|
return getGroupedComments.value?.parentComments.filter((c) => !c.resolvedTime).filter((c) => {
|
|
5814
5985
|
if (!isEditorBackedComment(c)) return true;
|
|
5986
|
+
if (isTrackedChangeThread(c)) return true;
|
|
5815
5987
|
return Boolean(resolveCommentPositionEntry(c).entry);
|
|
5816
5988
|
}).filter((c) => !isInlineTrackedChangeInsideTrackedTable(c));
|
|
5817
5989
|
});
|
|
@@ -5944,10 +6116,12 @@ const useCommentsStore = defineStore("comments", () => {
|
|
|
5944
6116
|
getConfig,
|
|
5945
6117
|
documentsWithConverations,
|
|
5946
6118
|
getGroupedComments,
|
|
6119
|
+
hasOpenTrackedChanges,
|
|
5947
6120
|
getCommentsByPosition,
|
|
5948
6121
|
getFloatingComments,
|
|
5949
6122
|
getFloatingCommentInstances,
|
|
5950
6123
|
getCommentAliasIds,
|
|
6124
|
+
getTrackedChangeThread,
|
|
5951
6125
|
getCommentPositionKey,
|
|
5952
6126
|
getCommentPosition,
|
|
5953
6127
|
getCommentAnchoredText,
|
|
@@ -6860,30 +7034,6 @@ var _sfc_main$33 = {
|
|
|
6860
7034
|
}
|
|
6861
7035
|
};
|
|
6862
7036
|
var CommentInput_default = /* @__PURE__ */ require__plugin_vue_export_helper.__plugin_vue_export_helper_default(_sfc_main$33, [["__scopeId", "data-v-cc54b489"]]);
|
|
6863
|
-
const collectTrackedChangeThread = (parentComment, allComments) => {
|
|
6864
|
-
const trackedChangeId = parentComment.commentId;
|
|
6865
|
-
const threadIds = new Set([trackedChangeId]);
|
|
6866
|
-
const queue = [];
|
|
6867
|
-
allComments.forEach((comment) => {
|
|
6868
|
-
if (comment.commentId === trackedChangeId) return;
|
|
6869
|
-
const isDirectChild = [comment.parentCommentId, comment.threadingParentCommentId].filter((id) => id != null).map((id) => String(id)).includes(trackedChangeId);
|
|
6870
|
-
const isTrackedChangeThreadRoot = String(trackedChangeThreadParentIdForComment(comment) ?? "") === trackedChangeId && !comment.parentCommentId;
|
|
6871
|
-
if (isDirectChild || isTrackedChangeThreadRoot) {
|
|
6872
|
-
threadIds.add(comment.commentId);
|
|
6873
|
-
queue.push(comment.commentId);
|
|
6874
|
-
}
|
|
6875
|
-
});
|
|
6876
|
-
for (let i = 0; i < queue.length; i += 1) {
|
|
6877
|
-
const parentId = queue[i];
|
|
6878
|
-
allComments.forEach((comment) => {
|
|
6879
|
-
if ([comment.parentCommentId, comment.threadingParentCommentId].filter((id) => id != null).map((id) => String(id)).includes(parentId) && !threadIds.has(comment.commentId)) {
|
|
6880
|
-
threadIds.add(comment.commentId);
|
|
6881
|
-
queue.push(comment.commentId);
|
|
6882
|
-
}
|
|
6883
|
-
});
|
|
6884
|
-
}
|
|
6885
|
-
return allComments.filter((comment) => threadIds.has(comment.commentId));
|
|
6886
|
-
};
|
|
6887
7037
|
var _hoisted_1$25 = [
|
|
6888
7038
|
"data-comment-instance-id",
|
|
6889
7039
|
"data-comment-thread-id",
|
|
@@ -6971,12 +7121,19 @@ var _hoisted_44 = {
|
|
|
6971
7121
|
class: "comment-separator"
|
|
6972
7122
|
};
|
|
6973
7123
|
var _hoisted_45 = {
|
|
7124
|
+
key: 2,
|
|
7125
|
+
class: "tracked-change-decision-alert",
|
|
7126
|
+
role: "alert"
|
|
7127
|
+
};
|
|
7128
|
+
var _hoisted_46 = { class: "tracked-change-decision-alert__message" };
|
|
7129
|
+
var _hoisted_47 = ["disabled", "data-disabled-reason"];
|
|
7130
|
+
var _hoisted_48 = {
|
|
6974
7131
|
key: 1,
|
|
6975
7132
|
class: "reply-expanded"
|
|
6976
7133
|
};
|
|
6977
|
-
var
|
|
6978
|
-
var
|
|
6979
|
-
var
|
|
7134
|
+
var _hoisted_49 = { class: "reply-input-wrapper" };
|
|
7135
|
+
var _hoisted_50 = { class: "reply-actions" };
|
|
7136
|
+
var _hoisted_51 = ["disabled", "data-disabled-reason"];
|
|
6980
7137
|
var CLICK_OUTSIDE_HIT_TOLERANCE_PX = 3;
|
|
6981
7138
|
var TRACKED_CHANGE_PREVIEW_MAX_PX = 90;
|
|
6982
7139
|
var _sfc_main$32 = {
|
|
@@ -7028,6 +7185,7 @@ var _sfc_main$32 = {
|
|
|
7028
7185
|
const isInternal = (0, vue.ref)(true);
|
|
7029
7186
|
const commentInput = (0, vue.ref)(null);
|
|
7030
7187
|
const editCommentInputs = (0, vue.ref)(/* @__PURE__ */ new Map());
|
|
7188
|
+
const trackedChangeDecisionFailure = (0, vue.ref)(null);
|
|
7031
7189
|
const CLICK_OUTSIDE_HIT_SAMPLE_OFFSETS = [
|
|
7032
7190
|
[0, 0],
|
|
7033
7191
|
[-CLICK_OUTSIDE_HIT_TOLERANCE_PX, 0],
|
|
@@ -7195,8 +7353,13 @@ var _sfc_main$32 = {
|
|
|
7195
7353
|
});
|
|
7196
7354
|
const commentsAreReadOnly$1 = () => getConfig.value?.readOnly === true;
|
|
7197
7355
|
const isReplying = (0, vue.ref)(false);
|
|
7356
|
+
const isSubmittingReply = (0, vue.ref)(false);
|
|
7198
7357
|
const startReply = () => {
|
|
7199
7358
|
if (commentsAreReadOnly$1()) return readOnlyMutationOutcome$1();
|
|
7359
|
+
if (isV2WriteDisabled.value) return {
|
|
7360
|
+
ok: false,
|
|
7361
|
+
reason: v2WriteCapability.value?.reason ?? "v2-write-unavailable"
|
|
7362
|
+
};
|
|
7200
7363
|
isReplying.value = true;
|
|
7201
7364
|
(0, vue.nextTick)(() => {
|
|
7202
7365
|
commentInput.value?.focus?.();
|
|
@@ -7205,12 +7368,12 @@ var _sfc_main$32 = {
|
|
|
7205
7368
|
};
|
|
7206
7369
|
const comments = (0, vue.computed)(() => {
|
|
7207
7370
|
const parentComment = props.comment;
|
|
7208
|
-
|
|
7209
|
-
return
|
|
7371
|
+
if (parentComment.trackedChange) return commentsStore.getTrackedChangeThread(parentComment);
|
|
7372
|
+
return commentsStore.commentsList.filter((comment) => {
|
|
7210
7373
|
const isThreadedComment = comment.parentCommentId === parentComment.commentId;
|
|
7211
7374
|
const isThisComment = comment.commentId === parentComment.commentId;
|
|
7212
7375
|
return isThreadedComment || isThisComment;
|
|
7213
|
-
})
|
|
7376
|
+
}).sort((a, b) => {
|
|
7214
7377
|
if (a.commentId === parentComment.commentId) return -1;
|
|
7215
7378
|
if (b.commentId === parentComment.commentId) return 1;
|
|
7216
7379
|
return a.createdTime - b.createdTime;
|
|
@@ -7388,20 +7551,33 @@ var _sfc_main$32 = {
|
|
|
7388
7551
|
};
|
|
7389
7552
|
const handleAddComment = async () => {
|
|
7390
7553
|
if (commentsAreReadOnly$1()) return readOnlyMutationOutcome$1();
|
|
7554
|
+
if (isV2WriteDisabled.value) return {
|
|
7555
|
+
ok: false,
|
|
7556
|
+
reason: v2WriteCapability.value?.reason ?? "v2-write-unavailable"
|
|
7557
|
+
};
|
|
7391
7558
|
if (isV2Mode.value && v2CommentsAdapter.value && !isPendingNewComment.value) {
|
|
7392
|
-
|
|
7393
|
-
|
|
7394
|
-
|
|
7395
|
-
|
|
7396
|
-
|
|
7397
|
-
|
|
7559
|
+
if (isSubmittingReply.value) return {
|
|
7560
|
+
ok: false,
|
|
7561
|
+
reason: "reply-submit-in-flight"
|
|
7562
|
+
};
|
|
7563
|
+
isSubmittingReply.value = true;
|
|
7564
|
+
try {
|
|
7565
|
+
const outcome = await commentsStore.replyCommentV2({
|
|
7566
|
+
superdoc: proxy.$superdoc,
|
|
7567
|
+
parentCommentId: getV2ExistingReplyParentId(props.comment),
|
|
7568
|
+
text: currentCommentText.value
|
|
7569
|
+
});
|
|
7570
|
+
if (!outcome?.ok) {
|
|
7571
|
+
(0, vue.nextTick)(() => emit("resize"));
|
|
7572
|
+
return outcome;
|
|
7573
|
+
}
|
|
7574
|
+
isReplying.value = false;
|
|
7575
|
+
currentCommentText.value = "";
|
|
7398
7576
|
(0, vue.nextTick)(() => emit("resize"));
|
|
7399
7577
|
return outcome;
|
|
7578
|
+
} finally {
|
|
7579
|
+
isSubmittingReply.value = false;
|
|
7400
7580
|
}
|
|
7401
|
-
isReplying.value = false;
|
|
7402
|
-
currentCommentText.value = "";
|
|
7403
|
-
(0, vue.nextTick)(() => emit("resize"));
|
|
7404
|
-
return outcome;
|
|
7405
7581
|
}
|
|
7406
7582
|
const options = {
|
|
7407
7583
|
documentId: props.comment.fileId,
|
|
@@ -7427,7 +7603,14 @@ var _sfc_main$32 = {
|
|
|
7427
7603
|
const v2TrackedChangesAdapter = (0, vue.computed)(() => isV2Mode.value ? proxy.$superdoc?.activeEditor?.v2TrackedChanges ?? null : null);
|
|
7428
7604
|
const v2WriteCapability = (0, vue.computed)(() => {
|
|
7429
7605
|
if (!v2CommentsAdapter.value) return null;
|
|
7430
|
-
|
|
7606
|
+
const documentMode = commentsStore.viewingVisibility.documentMode;
|
|
7607
|
+
const capability = v2CommentsAdapter.value.getCapabilityState?.() ?? null;
|
|
7608
|
+
if (documentMode === "viewing") return {
|
|
7609
|
+
...capability ?? {},
|
|
7610
|
+
canWrite: false,
|
|
7611
|
+
reason: "review-surface-read-only"
|
|
7612
|
+
};
|
|
7613
|
+
return capability;
|
|
7431
7614
|
});
|
|
7432
7615
|
const isV2WriteDisabled = (0, vue.computed)(() => {
|
|
7433
7616
|
if (!isV2Mode.value) return false;
|
|
@@ -7435,6 +7618,11 @@ var _sfc_main$32 = {
|
|
|
7435
7618
|
if (!cap) return false;
|
|
7436
7619
|
return cap.canWrite === false;
|
|
7437
7620
|
});
|
|
7621
|
+
const v2ReplyDisabledReason = (0, vue.computed)(() => {
|
|
7622
|
+
if (isSubmittingReply.value) return "reply-submit-in-flight";
|
|
7623
|
+
if (!isV2WriteDisabled.value) return null;
|
|
7624
|
+
return v2WriteCapability.value?.reason ?? "v2-write-unavailable";
|
|
7625
|
+
});
|
|
7438
7626
|
const v2TrackedChangeCapability = (0, vue.computed)(() => {
|
|
7439
7627
|
if (!v2TrackedChangesAdapter.value) return null;
|
|
7440
7628
|
const documentMode = commentsStore.viewingVisibility.documentMode;
|
|
@@ -7477,6 +7665,35 @@ var _sfc_main$32 = {
|
|
|
7477
7665
|
if (!isV2WriteDisabled.value) return null;
|
|
7478
7666
|
return v2WriteCapability.value?.reason ?? "v2-write-unavailable";
|
|
7479
7667
|
});
|
|
7668
|
+
const reportTrackedChangeDecisionFailure = (decision, outcome) => {
|
|
7669
|
+
trackedChangeDecisionFailure.value = {
|
|
7670
|
+
decision,
|
|
7671
|
+
reason: outcome?.reason ?? null
|
|
7672
|
+
};
|
|
7673
|
+
(0, vue.nextTick)(() => emit("resize"));
|
|
7674
|
+
};
|
|
7675
|
+
const clearTrackedChangeDecisionFailure = () => {
|
|
7676
|
+
if (!trackedChangeDecisionFailure.value) return;
|
|
7677
|
+
trackedChangeDecisionFailure.value = null;
|
|
7678
|
+
(0, vue.nextTick)(() => emit("resize"));
|
|
7679
|
+
};
|
|
7680
|
+
const trackedChangeDecisionFailureMessage = (0, vue.computed)(() => {
|
|
7681
|
+
const failure = trackedChangeDecisionFailure.value;
|
|
7682
|
+
if (!failure) return null;
|
|
7683
|
+
const action = failure.decision === "reject" ? "reject" : "accept";
|
|
7684
|
+
if (failure.reason === "stale-catalog") return `Couldn't ${action} this change because the review list is stale.`;
|
|
7685
|
+
return `Couldn't ${action} this change.`;
|
|
7686
|
+
});
|
|
7687
|
+
const retryTrackedChangeDecision = () => {
|
|
7688
|
+
const failure = trackedChangeDecisionFailure.value;
|
|
7689
|
+
if (!failure) return;
|
|
7690
|
+
trackedChangeDecisionFailure.value = null;
|
|
7691
|
+
if (failure.decision === "reject") {
|
|
7692
|
+
handleReject();
|
|
7693
|
+
return;
|
|
7694
|
+
}
|
|
7695
|
+
handleResolve();
|
|
7696
|
+
};
|
|
7480
7697
|
const handleReject = async () => {
|
|
7481
7698
|
if (commentsAreReadOnly$1()) return readOnlyMutationOutcome$1();
|
|
7482
7699
|
const customHandler = proxy.$superdoc.config.onTrackedChangeBubbleReject;
|
|
@@ -7487,7 +7704,11 @@ var _sfc_main$32 = {
|
|
|
7487
7704
|
comment: props.comment,
|
|
7488
7705
|
decision: "reject"
|
|
7489
7706
|
});
|
|
7490
|
-
if (!outcome?.ok || outcome.success === false)
|
|
7707
|
+
if (!outcome?.ok || outcome.success === false) {
|
|
7708
|
+
reportTrackedChangeDecisionFailure("reject", outcome);
|
|
7709
|
+
return;
|
|
7710
|
+
}
|
|
7711
|
+
clearTrackedChangeDecisionFailure();
|
|
7491
7712
|
if (typeof customHandler === "function") customHandler(props.comment, proxy.$superdoc.activeEditor);
|
|
7492
7713
|
(0, vue.nextTick)(() => {
|
|
7493
7714
|
commentsStore.lastUpdate = /* @__PURE__ */ new Date();
|
|
@@ -7543,7 +7764,11 @@ var _sfc_main$32 = {
|
|
|
7543
7764
|
comment: props.comment,
|
|
7544
7765
|
decision: "accept"
|
|
7545
7766
|
});
|
|
7546
|
-
if (!outcome?.ok || outcome.success === false)
|
|
7767
|
+
if (!outcome?.ok || outcome.success === false) {
|
|
7768
|
+
reportTrackedChangeDecisionFailure("accept", outcome);
|
|
7769
|
+
return;
|
|
7770
|
+
}
|
|
7771
|
+
clearTrackedChangeDecisionFailure();
|
|
7547
7772
|
if (typeof customHandler === "function") customHandler(props.comment, proxy.$superdoc.activeEditor);
|
|
7548
7773
|
(0, vue.nextTick)(() => {
|
|
7549
7774
|
commentsStore.lastUpdate = /* @__PURE__ */ new Date();
|
|
@@ -7707,6 +7932,11 @@ var _sfc_main$32 = {
|
|
|
7707
7932
|
if (isPendingNewComment.value) cancelComment(proxy.$superdoc);
|
|
7708
7933
|
(0, vue.nextTick)(() => emit("resize"));
|
|
7709
7934
|
}, { immediate: true });
|
|
7935
|
+
(0, vue.watch)(isV2WriteDisabled, (isDisabled) => {
|
|
7936
|
+
if (!isDisabled) return;
|
|
7937
|
+
isReplying.value = false;
|
|
7938
|
+
(0, vue.nextTick)(() => emit("resize"));
|
|
7939
|
+
});
|
|
7710
7940
|
return (_ctx, _cache) => {
|
|
7711
7941
|
const _directive_click_outside = (0, vue.resolveDirective)("click-outside");
|
|
7712
7942
|
return (0, vue.withDirectives)(((0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
|
|
@@ -7895,11 +8125,19 @@ var _sfc_main$32 = {
|
|
|
7895
8125
|
showSeparator.value(index) ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_44)) : (0, vue.createCommentVNode)("", true)
|
|
7896
8126
|
]);
|
|
7897
8127
|
}), 128)),
|
|
7898
|
-
|
|
8128
|
+
trackedChangeDecisionFailure.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_45, [(0, vue.createElementVNode)("span", _hoisted_46, (0, vue.toDisplayString)(trackedChangeDecisionFailureMessage.value), 1), (0, vue.createElementVNode)("button", {
|
|
8129
|
+
type: "button",
|
|
8130
|
+
class: "sd-button tracked-change-decision-alert__retry",
|
|
8131
|
+
onClick: (0, vue.withModifiers)(retryTrackedChangeDecision, ["stop", "prevent"])
|
|
8132
|
+
}, " Retry ")])) : (0, vue.createCommentVNode)("", true),
|
|
8133
|
+
showInputSection.value && !(0, vue.unref)(getConfig).readOnly ? ((0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key: 3 }, [!isReplying.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("button", {
|
|
7899
8134
|
key: 0,
|
|
7900
|
-
|
|
7901
|
-
|
|
7902
|
-
|
|
8135
|
+
type: "button",
|
|
8136
|
+
class: (0, vue.normalizeClass)(["reply-pill", { "sd-is-disabled": isV2WriteDisabled.value }]),
|
|
8137
|
+
onClick: (0, vue.withModifiers)(startReply, ["stop", "prevent"]),
|
|
8138
|
+
disabled: isV2WriteDisabled.value,
|
|
8139
|
+
"data-disabled-reason": isV2WriteDisabled.value ? v2WriteCapability.value?.reason ?? null : null
|
|
8140
|
+
}, " Reply or add others with @ ", 10, _hoisted_47)) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_48, [(0, vue.createElementVNode)("div", _hoisted_49, [(0, vue.createVNode)(CommentInput_default, {
|
|
7903
8141
|
ref_key: "commentInput",
|
|
7904
8142
|
ref: commentInput,
|
|
7905
8143
|
users: usersFiltered.value,
|
|
@@ -7910,20 +8148,20 @@ var _sfc_main$32 = {
|
|
|
7910
8148
|
"users",
|
|
7911
8149
|
"config",
|
|
7912
8150
|
"comment"
|
|
7913
|
-
])]), (0, vue.createElementVNode)("div",
|
|
8151
|
+
])]), (0, vue.createElementVNode)("div", _hoisted_50, [(0, vue.createElementVNode)("button", {
|
|
7914
8152
|
class: "sd-button reply-btn-cancel",
|
|
7915
8153
|
onClick: (0, vue.withModifiers)(handleCancel, ["stop", "prevent"])
|
|
7916
8154
|
}, "Cancel"), (0, vue.createElementVNode)("button", {
|
|
7917
|
-
class: (0, vue.normalizeClass)(["sd-button primary reply-btn-primary", { "sd-is-disabled": !hasTextContent.value || isV2WriteDisabled.value }]),
|
|
8155
|
+
class: (0, vue.normalizeClass)(["sd-button primary reply-btn-primary", { "sd-is-disabled": !hasTextContent.value || isV2WriteDisabled.value || isSubmittingReply.value }]),
|
|
7918
8156
|
onClick: (0, vue.withModifiers)(handleAddComment, ["stop", "prevent"]),
|
|
7919
|
-
disabled: !hasTextContent.value || isV2WriteDisabled.value,
|
|
7920
|
-
"data-disabled-reason":
|
|
7921
|
-
}, " Reply ", 10,
|
|
8157
|
+
disabled: !hasTextContent.value || isV2WriteDisabled.value || isSubmittingReply.value,
|
|
8158
|
+
"data-disabled-reason": v2ReplyDisabledReason.value
|
|
8159
|
+
}, " Reply ", 10, _hoisted_51)])]))], 64)) : (0, vue.createCommentVNode)("", true)
|
|
7922
8160
|
], 64))], 14, _hoisted_1$25)), [[_directive_click_outside, handleClickOutside]]);
|
|
7923
8161
|
};
|
|
7924
8162
|
}
|
|
7925
8163
|
};
|
|
7926
|
-
var CommentDialog_default = /* @__PURE__ */ require__plugin_vue_export_helper.__plugin_vue_export_helper_default(_sfc_main$32, [["__scopeId", "data-v-
|
|
8164
|
+
var CommentDialog_default = /* @__PURE__ */ require__plugin_vue_export_helper.__plugin_vue_export_helper_default(_sfc_main$32, [["__scopeId", "data-v-74340036"]]);
|
|
7927
8165
|
var _hoisted_1$24 = { class: "comments-list" };
|
|
7928
8166
|
var _hoisted_2$19 = { key: 0 };
|
|
7929
8167
|
var _hoisted_3$15 = [
|
|
@@ -8267,12 +8505,12 @@ const resolvePersistentReviewCardTop = ({ comment, anchorTop, anchorBottom, card
|
|
|
8267
8505
|
if ((Number.isFinite(anchorBottom) ? anchorBottom : anchorTop) < viewportTop) return Math.min(anchorTop, viewportTop - cardHeight - 1);
|
|
8268
8506
|
return anchorTop;
|
|
8269
8507
|
};
|
|
8270
|
-
const shouldMountFloatingCommentDialog = ({ id, visibleIds, activeCommentInstanceId
|
|
8508
|
+
const shouldMountFloatingCommentDialog = ({ id, visibleIds, activeCommentInstanceId }) => {
|
|
8271
8509
|
if (!id) return false;
|
|
8272
8510
|
if (id === "pending") return true;
|
|
8273
8511
|
if (activeCommentInstanceId != null && String(id) === String(activeCommentInstanceId)) return true;
|
|
8274
8512
|
if (visibleIds?.has?.(id)) return true;
|
|
8275
|
-
return
|
|
8513
|
+
return false;
|
|
8276
8514
|
};
|
|
8277
8515
|
const resolveRemovedReviewCardContinuityTarget = ({ previousIds, currentIds, removedId }) => {
|
|
8278
8516
|
if (!Array.isArray(previousIds) || !(currentIds instanceof Set) || !removedId) return null;
|
|
@@ -8353,6 +8591,7 @@ var _sfc_main$30 = {
|
|
|
8353
8591
|
const commentsRenderKey = (0, vue.ref)(0);
|
|
8354
8592
|
const sidebarOffsetY = (0, vue.ref)(0);
|
|
8355
8593
|
const disableInstantLayoutTransitions = (0, vue.ref)(false);
|
|
8594
|
+
const viewportRevision = (0, vue.ref)(0);
|
|
8356
8595
|
const isPendingThread = (commentOrId) => {
|
|
8357
8596
|
const pendingId = pendingComment.value?.commentId;
|
|
8358
8597
|
if (!pendingId) return false;
|
|
@@ -8362,10 +8601,27 @@ var _sfc_main$30 = {
|
|
|
8362
8601
|
const getThreadId = (comment) => {
|
|
8363
8602
|
return comment?.commentId ?? comment?.importedId ?? null;
|
|
8364
8603
|
};
|
|
8604
|
+
const floatingInstanceIndex = (0, vue.computed)(() => {
|
|
8605
|
+
const byId = /* @__PURE__ */ new Map();
|
|
8606
|
+
const byThreadId = /* @__PURE__ */ new Map();
|
|
8607
|
+
for (const instance of floatingCommentInstances.value) {
|
|
8608
|
+
if (instance?.id != null) byId.set(String(instance.id), instance);
|
|
8609
|
+
const threadId = getThreadId(instance?.comment);
|
|
8610
|
+
if (threadId == null) continue;
|
|
8611
|
+
const key = String(threadId);
|
|
8612
|
+
const threadInstances = byThreadId.get(key) ?? [];
|
|
8613
|
+
threadInstances.push(instance);
|
|
8614
|
+
byThreadId.set(key, threadInstances);
|
|
8615
|
+
}
|
|
8616
|
+
return {
|
|
8617
|
+
byId,
|
|
8618
|
+
byThreadId
|
|
8619
|
+
};
|
|
8620
|
+
});
|
|
8365
8621
|
const resolveFloatingInstanceId = (threadId, preferredInstanceId = null) => {
|
|
8366
8622
|
if (threadId == null) return null;
|
|
8367
8623
|
const normalizedThreadId = String(threadId);
|
|
8368
|
-
const matchingInstances =
|
|
8624
|
+
const matchingInstances = floatingInstanceIndex.value.byThreadId.get(normalizedThreadId) ?? [];
|
|
8369
8625
|
if (!matchingInstances.length) return null;
|
|
8370
8626
|
if (preferredInstanceId != null) {
|
|
8371
8627
|
const preferredInstance = matchingInstances.find((instance) => String(instance.id) === String(preferredInstanceId));
|
|
@@ -8388,6 +8644,14 @@ var _sfc_main$30 = {
|
|
|
8388
8644
|
const placeholderRefs = (0, vue.ref)({});
|
|
8389
8645
|
let observer = null;
|
|
8390
8646
|
const observedElements = /* @__PURE__ */ new Set();
|
|
8647
|
+
let viewportFrame = null;
|
|
8648
|
+
const refreshViewportWindow = () => {
|
|
8649
|
+
if (viewportFrame != null) return;
|
|
8650
|
+
viewportFrame = requestAnimationFrame(() => {
|
|
8651
|
+
viewportFrame = null;
|
|
8652
|
+
viewportRevision.value += 1;
|
|
8653
|
+
});
|
|
8654
|
+
};
|
|
8391
8655
|
const getAnchorTop = (instance) => {
|
|
8392
8656
|
if (props.currentDocument.type === "application/pdf") {
|
|
8393
8657
|
const zoom = (activeZoom.value ?? 100) / 100;
|
|
@@ -8405,6 +8669,24 @@ var _sfc_main$30 = {
|
|
|
8405
8669
|
const bottom = instance?.positionEntry?.bounds?.bottom;
|
|
8406
8670
|
return Number.isFinite(bottom) ? bottom : anchorTop;
|
|
8407
8671
|
};
|
|
8672
|
+
const geometryBearingInstances = (0, vue.computed)(() => {
|
|
8673
|
+
const positioned = [];
|
|
8674
|
+
for (const instance of floatingCommentInstances.value) {
|
|
8675
|
+
const id = instance?.id;
|
|
8676
|
+
const threadId = getThreadId(instance?.comment);
|
|
8677
|
+
const anchorTop = getAnchorTop(instance);
|
|
8678
|
+
if (id == null || threadId == null || !Number.isFinite(anchorTop)) continue;
|
|
8679
|
+
const top = normalizeFloatingAnchorTop(anchorTop, instance.comment);
|
|
8680
|
+
positioned.push({
|
|
8681
|
+
id,
|
|
8682
|
+
threadId,
|
|
8683
|
+
instance,
|
|
8684
|
+
top,
|
|
8685
|
+
anchorBottom: getAnchorBottom(instance, top)
|
|
8686
|
+
});
|
|
8687
|
+
}
|
|
8688
|
+
return positioned;
|
|
8689
|
+
});
|
|
8408
8690
|
const getPendingAnchorTop = () => {
|
|
8409
8691
|
const positionEntry = editorCommentPositions.value["pending"];
|
|
8410
8692
|
if (typeof positionEntry?.bounds?.top === "number" && !isNaN(positionEntry.bounds.top)) return positionEntry.bounds.top;
|
|
@@ -8438,27 +8720,72 @@ var _sfc_main$30 = {
|
|
|
8438
8720
|
return resolveFloatingInstanceId(instantSidebarAlignmentThreadId.value, instantSidebarAlignmentInstanceId.value);
|
|
8439
8721
|
});
|
|
8440
8722
|
const allPositions = (0, vue.computed)(() => {
|
|
8441
|
-
|
|
8723
|
+
viewportRevision.value;
|
|
8724
|
+
const positionedInstances = geometryBearingInstances.value;
|
|
8442
8725
|
const hasPending = pendingComment.value && pendingComment.value.fileId === props.currentDocument.id;
|
|
8443
|
-
if (!
|
|
8726
|
+
if (!positionedInstances.length && !floatingCommentInstances.value.length && !hasPending) return [];
|
|
8444
8727
|
const positions = [];
|
|
8445
|
-
|
|
8446
|
-
|
|
8447
|
-
|
|
8448
|
-
|
|
8449
|
-
|
|
8450
|
-
|
|
8728
|
+
const viewportRange = getFloatingViewportRange() ?? {
|
|
8729
|
+
top: 0,
|
|
8730
|
+
bottom: Math.max(0, props.parent?.clientHeight || window.innerHeight || 0)
|
|
8731
|
+
};
|
|
8732
|
+
const renderTop = viewportRange.top - OBSERVER_MARGIN;
|
|
8733
|
+
const renderBottom = viewportRange.bottom + OBSERVER_MARGIN;
|
|
8734
|
+
const activeKey = hasPending ? "pending" : activeCommentInstanceId.value;
|
|
8735
|
+
const positionIds = /* @__PURE__ */ new Set();
|
|
8736
|
+
const pushPosition = ({ id, threadId, instance, top, anchorBottom, hasAnchorGeometry }) => {
|
|
8737
|
+
const key = String(id);
|
|
8738
|
+
if (positionIds.has(key)) return;
|
|
8739
|
+
positionIds.add(key);
|
|
8451
8740
|
positions.push({
|
|
8452
|
-
id
|
|
8741
|
+
id,
|
|
8453
8742
|
threadId,
|
|
8454
8743
|
pageIndex: instance?.pageIndex ?? null,
|
|
8455
8744
|
anchorTop: top,
|
|
8456
|
-
anchorBottom
|
|
8745
|
+
anchorBottom,
|
|
8746
|
+
hasAnchorGeometry,
|
|
8457
8747
|
top,
|
|
8458
|
-
height: measuredHeights.value[
|
|
8748
|
+
height: measuredHeights.value[id] || ESTIMATED_HEIGHT,
|
|
8459
8749
|
commentRef: instance.comment,
|
|
8460
8750
|
instanceRef: instance
|
|
8461
8751
|
});
|
|
8752
|
+
};
|
|
8753
|
+
for (const positioned of positionedInstances) {
|
|
8754
|
+
const { id, threadId, instance, top, anchorBottom } = positioned;
|
|
8755
|
+
const isActive = activeKey != null && String(id) === String(activeKey);
|
|
8756
|
+
const isEditing = editingCommentId.value != null && String(threadId) === String(editingCommentId.value);
|
|
8757
|
+
if (!isActive && !isEditing && (anchorBottom < renderTop || top > renderBottom)) continue;
|
|
8758
|
+
pushPosition({
|
|
8759
|
+
id,
|
|
8760
|
+
threadId,
|
|
8761
|
+
instance,
|
|
8762
|
+
top,
|
|
8763
|
+
anchorBottom,
|
|
8764
|
+
hasAnchorGeometry: true
|
|
8765
|
+
});
|
|
8766
|
+
}
|
|
8767
|
+
const transitionalInstances = [];
|
|
8768
|
+
if (activeKey && activeKey !== "pending") {
|
|
8769
|
+
const activeInstance = floatingInstanceIndex.value.byId.get(String(activeKey));
|
|
8770
|
+
if (activeInstance) transitionalInstances.push(activeInstance);
|
|
8771
|
+
}
|
|
8772
|
+
if (editingCommentId.value != null) {
|
|
8773
|
+
const editingInstances = floatingInstanceIndex.value.byThreadId.get(String(editingCommentId.value)) ?? [];
|
|
8774
|
+
const editingInstance = editingInstances.find((instance) => instance.isPrimary) ?? editingInstances[0];
|
|
8775
|
+
if (editingInstance) transitionalInstances.push(editingInstance);
|
|
8776
|
+
}
|
|
8777
|
+
for (const instance of transitionalInstances) {
|
|
8778
|
+
const id = instance.id;
|
|
8779
|
+
const threadId = getThreadId(instance.comment);
|
|
8780
|
+
if (id == null || threadId == null || positionIds.has(String(id))) continue;
|
|
8781
|
+
pushPosition({
|
|
8782
|
+
id,
|
|
8783
|
+
threadId,
|
|
8784
|
+
instance,
|
|
8785
|
+
top: viewportRange.top,
|
|
8786
|
+
anchorBottom: viewportRange.top,
|
|
8787
|
+
hasAnchorGeometry: false
|
|
8788
|
+
});
|
|
8462
8789
|
}
|
|
8463
8790
|
if (hasPending) {
|
|
8464
8791
|
const pendingTop = getPendingAnchorTop();
|
|
@@ -8466,17 +8793,17 @@ var _sfc_main$30 = {
|
|
|
8466
8793
|
id: "pending",
|
|
8467
8794
|
anchorTop: pendingTop,
|
|
8468
8795
|
anchorBottom: pendingTop,
|
|
8796
|
+
hasAnchorGeometry: true,
|
|
8469
8797
|
top: pendingTop,
|
|
8470
8798
|
height: measuredHeights.value["pending"] || ESTIMATED_HEIGHT,
|
|
8471
8799
|
commentRef: pendingComment.value
|
|
8472
8800
|
});
|
|
8473
8801
|
}
|
|
8474
8802
|
positions.sort((a, b) => a.anchorTop - b.anchorTop);
|
|
8475
|
-
const activeKey = hasPending ? "pending" : activeCommentInstanceId.value;
|
|
8476
8803
|
resolveCollisions(positions, activeKey ? positions.findIndex((p) => p.id === activeKey) : -1, 15);
|
|
8477
|
-
const
|
|
8478
|
-
|
|
8479
|
-
const
|
|
8804
|
+
for (const position of positions) {
|
|
8805
|
+
if (!position.hasAnchorGeometry) continue;
|
|
8806
|
+
const offscreenTop = resolvePersistentReviewCardTop({
|
|
8480
8807
|
comment: position.commentRef,
|
|
8481
8808
|
anchorTop: position.anchorTop,
|
|
8482
8809
|
anchorBottom: position.anchorBottom,
|
|
@@ -8484,21 +8811,13 @@ var _sfc_main$30 = {
|
|
|
8484
8811
|
viewportTop: viewportRange.top,
|
|
8485
8812
|
viewportBottom: viewportRange.bottom
|
|
8486
8813
|
});
|
|
8487
|
-
if (
|
|
8814
|
+
if (offscreenTop != null) position.top = offscreenTop;
|
|
8488
8815
|
}
|
|
8489
8816
|
return positions;
|
|
8490
8817
|
});
|
|
8491
|
-
const totalHeight = (0, vue.computed)(() => {
|
|
8492
|
-
if (!allPositions.value.length) return 0;
|
|
8493
|
-
let max = 0;
|
|
8494
|
-
for (const p of allPositions.value) {
|
|
8495
|
-
const bottom = p.top + p.height;
|
|
8496
|
-
if (bottom > max) max = bottom;
|
|
8497
|
-
}
|
|
8498
|
-
return max + 50;
|
|
8499
|
-
});
|
|
8500
8818
|
const wrapperMinHeight = (0, vue.computed)(() => {
|
|
8501
|
-
|
|
8819
|
+
viewportRevision.value;
|
|
8820
|
+
return Math.max(0, props.parent?.clientHeight || 0, props.parent?.scrollHeight || 0);
|
|
8502
8821
|
});
|
|
8503
8822
|
const setupObserver = () => {
|
|
8504
8823
|
if (observer) observer.disconnect();
|
|
@@ -8605,6 +8924,7 @@ var _sfc_main$30 = {
|
|
|
8605
8924
|
let continuityAlignmentScheduled = false;
|
|
8606
8925
|
let continuityAlignmentGeneration = 0;
|
|
8607
8926
|
let continuityTransitionFrame = null;
|
|
8927
|
+
let activeLayoutContinuityFrame = null;
|
|
8608
8928
|
const clearDeferredRemeasureTimers = () => {
|
|
8609
8929
|
remeasureTimers.forEach(clearTimeout);
|
|
8610
8930
|
remeasureTimers = [];
|
|
@@ -8776,14 +9096,27 @@ var _sfc_main$30 = {
|
|
|
8776
9096
|
});
|
|
8777
9097
|
let prevPositionIds = /* @__PURE__ */ new Set();
|
|
8778
9098
|
let prevActiveAnchorTop = null;
|
|
9099
|
+
let prevActiveLayoutTop = null;
|
|
8779
9100
|
(0, vue.watch)(allPositions, (positions) => {
|
|
8780
9101
|
const activePosition = activeCommentInstanceId.value ? positions.find((position) => position.id === activeCommentInstanceId.value) : null;
|
|
8781
9102
|
const activeAnchorTop = typeof activePosition?.anchorTop === "number" && Number.isFinite(activePosition.anchorTop) ? activePosition.anchorTop : null;
|
|
8782
|
-
|
|
9103
|
+
const activeAnchorMoved = activeAnchorTop != null && prevActiveAnchorTop != null && Math.abs(activeAnchorTop - prevActiveAnchorTop) > 1;
|
|
9104
|
+
const activeLayoutTop = typeof activePosition?.top === "number" && Number.isFinite(activePosition.top) ? activePosition.top : null;
|
|
9105
|
+
const activeLayoutMoved = activeLayoutTop != null && prevActiveLayoutTop != null && Math.abs(activeLayoutTop - prevActiveLayoutTop) > 1;
|
|
9106
|
+
if (activeAnchorMoved && sidebarOffsetY.value !== 0 && !Number.isFinite(instantSidebarAlignmentTargetY.value)) {
|
|
8783
9107
|
sidebarOffsetY.value = 0;
|
|
8784
9108
|
setInstantLayoutTransitionsDisabled(false);
|
|
9109
|
+
} else if (activeLayoutMoved && sidebarOffsetY.value !== 0 && !Number.isFinite(instantSidebarAlignmentTargetY.value) && !sidebarContinuityAnchor) {
|
|
9110
|
+
setInstantLayoutTransitionsDisabled(true);
|
|
9111
|
+
sidebarOffsetY.value += prevActiveLayoutTop - activeLayoutTop;
|
|
9112
|
+
if (activeLayoutContinuityFrame != null) cancelAnimationFrame(activeLayoutContinuityFrame);
|
|
9113
|
+
activeLayoutContinuityFrame = requestAnimationFrame(() => {
|
|
9114
|
+
activeLayoutContinuityFrame = null;
|
|
9115
|
+
if (!sidebarContinuityAnchor && !Number.isFinite(instantSidebarAlignmentTargetY.value)) setInstantLayoutTransitionsDisabled(false);
|
|
9116
|
+
});
|
|
8785
9117
|
}
|
|
8786
9118
|
prevActiveAnchorTop = activeAnchorTop;
|
|
9119
|
+
prevActiveLayoutTop = activeLayoutTop;
|
|
8787
9120
|
const positionOrder = positions.map((position) => position.id);
|
|
8788
9121
|
const currentIds = new Set(positionOrder);
|
|
8789
9122
|
if (sidebarContinuityAnchor && !currentIds.has(sidebarContinuityAnchor.key)) {
|
|
@@ -8842,12 +9175,24 @@ var _sfc_main$30 = {
|
|
|
8842
9175
|
});
|
|
8843
9176
|
(0, vue.onMounted)(() => {
|
|
8844
9177
|
setupObserver();
|
|
9178
|
+
props.parent?.addEventListener?.("scroll", refreshViewportWindow, { passive: true });
|
|
9179
|
+
window.addEventListener("resize", refreshViewportWindow, { passive: true });
|
|
8845
9180
|
(0, vue.nextTick)(observePlaceholders);
|
|
8846
9181
|
});
|
|
8847
9182
|
(0, vue.onBeforeUnmount)(() => {
|
|
8848
9183
|
clearDeferredRemeasureTimers();
|
|
8849
9184
|
if (scrollTimer) clearTimeout(scrollTimer);
|
|
8850
9185
|
clearSidebarContinuityAnchor();
|
|
9186
|
+
if (activeLayoutContinuityFrame != null) {
|
|
9187
|
+
cancelAnimationFrame(activeLayoutContinuityFrame);
|
|
9188
|
+
activeLayoutContinuityFrame = null;
|
|
9189
|
+
}
|
|
9190
|
+
props.parent?.removeEventListener?.("scroll", refreshViewportWindow);
|
|
9191
|
+
window.removeEventListener("resize", refreshViewportWindow);
|
|
9192
|
+
if (viewportFrame != null) {
|
|
9193
|
+
cancelAnimationFrame(viewportFrame);
|
|
9194
|
+
viewportFrame = null;
|
|
9195
|
+
}
|
|
8851
9196
|
if (observer) {
|
|
8852
9197
|
observer.disconnect();
|
|
8853
9198
|
observer = null;
|
|
@@ -8909,7 +9254,7 @@ var _sfc_main$30 = {
|
|
|
8909
9254
|
};
|
|
8910
9255
|
}
|
|
8911
9256
|
};
|
|
8912
|
-
var FloatingComments_default = /* @__PURE__ */ require__plugin_vue_export_helper.__plugin_vue_export_helper_default(_sfc_main$30, [["__scopeId", "data-v-
|
|
9257
|
+
var FloatingComments_default = /* @__PURE__ */ require__plugin_vue_export_helper.__plugin_vue_export_helper_default(_sfc_main$30, [["__scopeId", "data-v-e699ceb8"]]);
|
|
8913
9258
|
var _hoisted_1$22 = {
|
|
8914
9259
|
class: "superdoc__pdf-comments-layer pdf-comments-layer",
|
|
8915
9260
|
"aria-hidden": "false"
|
|
@@ -9655,6 +10000,17 @@ const DRAWING_SUPPORT_TAXONOMY = {
|
|
|
9655
10000
|
}
|
|
9656
10001
|
};
|
|
9657
10002
|
const DRAWING_FAMILIES = Object.keys(DRAWING_SUPPORT_TAXONOMY);
|
|
10003
|
+
const PAGE_CHECKPOINT_DEPENDENCY_CLASSES = Object.freeze([
|
|
10004
|
+
"multiple-sections",
|
|
10005
|
+
"furniture-page-tokens",
|
|
10006
|
+
"non-balanceable-multi-column-sections",
|
|
10007
|
+
"body-anchored-objects",
|
|
10008
|
+
"footnotes",
|
|
10009
|
+
"page-references",
|
|
10010
|
+
"keep-constraints",
|
|
10011
|
+
"tables",
|
|
10012
|
+
"furniture-anchored-objects"
|
|
10013
|
+
]);
|
|
9658
10014
|
var _hoisted_1$20 = { class: "superdoc-html-viewer" };
|
|
9659
10015
|
var _hoisted_2$17 = { class: "superdoc-html-viewer__document" };
|
|
9660
10016
|
var _hoisted_3$14 = ["innerHTML"];
|
|
@@ -11511,8 +11867,11 @@ function scrollToElement(targetElement, options = {
|
|
|
11511
11867
|
const container = getScrollableParent(targetElement);
|
|
11512
11868
|
const containerRect = container.getBoundingClientRect();
|
|
11513
11869
|
const offsetTop = targetElement.getBoundingClientRect().top - containerRect.top + container.scrollTop;
|
|
11870
|
+
const scrollPaddingTopValue = window.getComputedStyle(container).scrollPaddingTop?.trim();
|
|
11871
|
+
const resolvedScrollPaddingTop = scrollPaddingTopValue?.endsWith("px") ? Number(scrollPaddingTopValue.slice(0, -2)) : 0;
|
|
11872
|
+
const scrollPaddingTop = Number.isFinite(resolvedScrollPaddingTop) && resolvedScrollPaddingTop >= 0 ? resolvedScrollPaddingTop : 0;
|
|
11514
11873
|
container.scrollTo({
|
|
11515
|
-
top: options.block === "start" ? offsetTop : offsetTop - container.clientHeight + targetElement.offsetHeight,
|
|
11874
|
+
top: options.block === "start" ? offsetTop - scrollPaddingTop : offsetTop - container.clientHeight + targetElement.offsetHeight,
|
|
11516
11875
|
behavior: options.behavior
|
|
11517
11876
|
});
|
|
11518
11877
|
}
|
|
@@ -11758,7 +12117,34 @@ function useLinkPopover({ getSurfaceManager, getActiveEditor, getUi, getResolver
|
|
|
11758
12117
|
tick();
|
|
11759
12118
|
});
|
|
11760
12119
|
}
|
|
11761
|
-
async function
|
|
12120
|
+
async function placeCaretAtHeadingStart(blockId) {
|
|
12121
|
+
const setSelectionTarget = getActiveEditor()?.authoring?.setSelectionTarget;
|
|
12122
|
+
if (typeof setSelectionTarget !== "function") return;
|
|
12123
|
+
const story = {
|
|
12124
|
+
kind: "story",
|
|
12125
|
+
storyType: "body"
|
|
12126
|
+
};
|
|
12127
|
+
const anchor = {
|
|
12128
|
+
kind: "text",
|
|
12129
|
+
blockId,
|
|
12130
|
+
offset: 0,
|
|
12131
|
+
story
|
|
12132
|
+
};
|
|
12133
|
+
const target = {
|
|
12134
|
+
kind: "selection",
|
|
12135
|
+
start: anchor,
|
|
12136
|
+
end: anchor,
|
|
12137
|
+
story
|
|
12138
|
+
};
|
|
12139
|
+
try {
|
|
12140
|
+
await Promise.resolve(setSelectionTarget({
|
|
12141
|
+
target,
|
|
12142
|
+
collapse: "start",
|
|
12143
|
+
focus: true
|
|
12144
|
+
}));
|
|
12145
|
+
} catch {}
|
|
12146
|
+
}
|
|
12147
|
+
async function navigateToAnchor(anchorUrl, { placeCaret = false } = {}) {
|
|
11762
12148
|
if (typeof anchorUrl !== "string" || !anchorUrl.startsWith("#")) return;
|
|
11763
12149
|
const anchorName = anchorUrl.slice(1);
|
|
11764
12150
|
const escapedAnchorName = cssEscape(anchorName);
|
|
@@ -11783,6 +12169,7 @@ function useLinkPopover({ getSurfaceManager, getActiveEditor, getUi, getResolver
|
|
|
11783
12169
|
if (story && story.storyType !== "body") return;
|
|
11784
12170
|
const blockId = bookmark?.range?.from?.blockId;
|
|
11785
12171
|
if (typeof blockId !== "string") return;
|
|
12172
|
+
if (placeCaret) await placeCaretAtHeadingStart(blockId);
|
|
11786
12173
|
const mountedParagraph = findPaintedParagraphByParaId(getUi()?.viewport?.getHost?.() ?? null, blockId);
|
|
11787
12174
|
if (mountedParagraph) {
|
|
11788
12175
|
scrollToElement(mountedParagraph);
|
|
@@ -11892,7 +12279,7 @@ function useLinkPopover({ getSurfaceManager, getActiveEditor, getUi, getResolver
|
|
|
11892
12279
|
function openDefaultPopover(ctx) {
|
|
11893
12280
|
closeCurrentPopover("replace");
|
|
11894
12281
|
if (ctx.isAnchorLink && isTocEntryLinkElement(ctx.element)) {
|
|
11895
|
-
navigateToAnchor(ctx.href);
|
|
12282
|
+
navigateToAnchor(ctx.href, { placeCaret: ctx.documentMode !== "viewing" });
|
|
11896
12283
|
return;
|
|
11897
12284
|
}
|
|
11898
12285
|
if (ctx.documentMode === "viewing") {
|
|
@@ -11908,7 +12295,7 @@ function useLinkPopover({ getSurfaceManager, getActiveEditor, getUi, getResolver
|
|
|
11908
12295
|
const closePopover = () => closeCurrentPopover("closed");
|
|
11909
12296
|
const goToAnchor = (anchorUrl) => {
|
|
11910
12297
|
closePopover();
|
|
11911
|
-
navigateToAnchor(anchorUrl);
|
|
12298
|
+
navigateToAnchor(anchorUrl, { placeCaret: true });
|
|
11912
12299
|
};
|
|
11913
12300
|
const generation = openGeneration;
|
|
11914
12301
|
const openWithHyperlinkTarget = (hyperlinkTarget) => {
|
|
@@ -13671,7 +14058,7 @@ var _sfc_main$20 = {
|
|
|
13671
14058
|
__name: "SuperDoc",
|
|
13672
14059
|
emits: ["selection-update"],
|
|
13673
14060
|
setup(__props, { emit: __emit }) {
|
|
13674
|
-
const PdfViewer = (0, vue.defineAsyncComponent)(() => Promise.resolve().then(() => require("./chunks/PdfViewer-
|
|
14061
|
+
const PdfViewer = (0, vue.defineAsyncComponent)(() => Promise.resolve().then(() => require("./chunks/PdfViewer-CoFiGAhm.cjs")));
|
|
13675
14062
|
const getDocumentLoadPassword = (doc) => doc.password ?? proxy.$superdoc.config.password;
|
|
13676
14063
|
const resolveDocumentV2Collaboration = (doc) => {
|
|
13677
14064
|
const rawConfig = doc?.v2Collaboration;
|
|
@@ -13716,7 +14103,7 @@ var _sfc_main$20 = {
|
|
|
13716
14103
|
});
|
|
13717
14104
|
}
|
|
13718
14105
|
});
|
|
13719
|
-
const { getConfig, documentsWithConverations, commentsList, pendingComment, activeComment, skipSelectionUpdate, commentsByDocument, isCommentsListVisible, isFloatingCommentsReady, generalCommentIds, hasSyncedCollaborationComments, editorCommentPositions, hasInitializedLocations, isCommentHighlighted } = storeToRefs(commentsStore);
|
|
14106
|
+
const { getConfig, documentsWithConverations, commentsList, pendingComment, activeComment, skipSelectionUpdate, commentsByDocument, isCommentsListVisible, isFloatingCommentsReady, generalCommentIds, hasSyncedCollaborationComments, editorCommentPositions, hasInitializedLocations, isCommentHighlighted, hasOpenTrackedChanges } = storeToRefs(commentsStore);
|
|
13720
14107
|
const { showAddComment, handleEditorLocationsUpdate, handleTrackedChangeUpdate, refreshTrackedChangeCommentsByIds, syncTrackedChangePositionsWithDocument, syncTrackedChangeComments, addComment, addHydratedComment, getComment, resolveCommentPositionEntry, belongsToDocument, COMMENT_EVENTS, requestInstantSidebarAlignment, peekInstantSidebarAlignment, clearInstantSidebarAlignment } = commentsStore;
|
|
13721
14108
|
const { proxy } = (0, vue.getCurrentInstance)();
|
|
13722
14109
|
commentsStore.proxy = proxy;
|
|
@@ -13896,18 +14283,19 @@ var _sfc_main$20 = {
|
|
|
13896
14283
|
if (!documentId) return;
|
|
13897
14284
|
clearV2CommandShortcutBinding(documentId);
|
|
13898
14285
|
if (typeof bindEditShortcuts !== "function") return;
|
|
13899
|
-
const
|
|
14286
|
+
const fallbackUi = require_create_super_doc_ui.createSuperDocUI({ superdoc: proxy.$superdoc });
|
|
14287
|
+
const resolveUi = () => proxy.$superdoc?.toolbar?.ui ?? fallbackUi;
|
|
13900
14288
|
const openLinkWorkflow = resolveV2LinkWorkflowOpener();
|
|
13901
14289
|
const unbind = bindEditShortcuts({
|
|
13902
14290
|
commandRoute: {
|
|
13903
|
-
executeAsync: (commandId, payload) =>
|
|
13904
|
-
getState: (commandId) =>
|
|
14291
|
+
executeAsync: (commandId, payload) => resolveUi().commands.executeAsync(commandId, payload),
|
|
14292
|
+
getState: (commandId) => resolveUi().commands.get(commandId).getState()
|
|
13905
14293
|
},
|
|
13906
14294
|
...openLinkWorkflow ? { openLinkWorkflow } : {}
|
|
13907
14295
|
});
|
|
13908
14296
|
v2CommandShortcutBindings.set(documentId, {
|
|
13909
14297
|
unbind,
|
|
13910
|
-
ui
|
|
14298
|
+
ui: fallbackUi
|
|
13911
14299
|
});
|
|
13912
14300
|
};
|
|
13913
14301
|
const clearV2SessionShortcutBinding = (documentId) => {
|
|
@@ -14731,13 +15119,17 @@ var _sfc_main$20 = {
|
|
|
14731
15119
|
v2RulerReady.value = false;
|
|
14732
15120
|
};
|
|
14733
15121
|
let v2TypingReviewHydrationTimer = 0;
|
|
14734
|
-
const
|
|
15122
|
+
const hydrateV2CommentRowsFromHost = () => {
|
|
14735
15123
|
const commentsAdapter = proxy.$superdoc?.activeEditor?.v2Comments ?? null;
|
|
14736
|
-
if (commentsAdapter)
|
|
15124
|
+
if (!commentsAdapter) return;
|
|
15125
|
+
commentsStore.hydrateCommentsFromV2?.({
|
|
14737
15126
|
superdoc: proxy.$superdoc,
|
|
14738
15127
|
adapter: commentsAdapter,
|
|
14739
15128
|
documentId: proxy.$superdoc?.activeEditor?.documentId ?? null
|
|
14740
15129
|
});
|
|
15130
|
+
};
|
|
15131
|
+
const hydrateV2ReviewRowsFromHost = (options = {}) => {
|
|
15132
|
+
hydrateV2CommentRowsFromHost();
|
|
14741
15133
|
const trackedChangesAdapter = proxy.$superdoc?.activeEditor?.v2TrackedChanges ?? null;
|
|
14742
15134
|
if (!trackedChangesAdapter) return;
|
|
14743
15135
|
commentsStore.hydrateTrackedChangesFromV2?.({
|
|
@@ -14840,6 +15232,10 @@ var _sfc_main$20 = {
|
|
|
14840
15232
|
const receipt = event.origin === "history" ? null : event.receipt;
|
|
14841
15233
|
const canWaitForExactPaint = reviewImpact && typeof receipt?.txId === "string" && receipt.txId.length > 0 && typeof readiness?.whenPainted === "function";
|
|
14842
15234
|
v2ReviewMutationReconciler.enqueueAfterPaint(reviewImpact, canWaitForExactPaint ? () => readiness.whenPainted.call(readiness, receipt) : null);
|
|
15235
|
+
if (reviewImpact?.reconcileMode === "authoritative" && reviewImpact.upsertIds.size > 0) {
|
|
15236
|
+
hydrateV2CommentRowsFromHost();
|
|
15237
|
+
return;
|
|
15238
|
+
}
|
|
14843
15239
|
if (require_create_super_doc_ui.isV2EditableTextMutationEvent(event)) {
|
|
14844
15240
|
scheduleV2TypingReviewHydration();
|
|
14845
15241
|
return;
|
|
@@ -15301,7 +15697,7 @@ var _sfc_main$20 = {
|
|
|
15301
15697
|
if (isV2Mode.value && !v2GeometryAvailable.value && !hasPdfFloatingComments.value) return false;
|
|
15302
15698
|
if (!shouldRenderCommentsInViewing.value) return false;
|
|
15303
15699
|
if (!shouldUseSidebarComments.value) return false;
|
|
15304
|
-
return pendingComment.value || floatingComments.value.length > 0 && isReady.value && layers.value && isCommentsEnabled.value && !isCommentsListVisible.value;
|
|
15700
|
+
return pendingComment.value || (floatingComments.value.length > 0 || hasOpenTrackedChanges.value) && isReady.value && layers.value && isCommentsEnabled.value && !isCommentsListVisible.value;
|
|
15305
15701
|
});
|
|
15306
15702
|
const activeCompactComment = (0, vue.computed)(() => {
|
|
15307
15703
|
if (showCommentsSidebar.value) return null;
|
|
@@ -15970,7 +16366,7 @@ var _sfc_main$20 = {
|
|
|
15970
16366
|
};
|
|
15971
16367
|
}
|
|
15972
16368
|
};
|
|
15973
|
-
var SuperDoc_default = /* @__PURE__ */ require__plugin_vue_export_helper.__plugin_vue_export_helper_default(_sfc_main$20, [["__scopeId", "data-v-
|
|
16369
|
+
var SuperDoc_default = /* @__PURE__ */ require__plugin_vue_export_helper.__plugin_vue_export_helper_default(_sfc_main$20, [["__scopeId", "data-v-4084bf1b"]]);
|
|
15974
16370
|
var PINIA_DEVTOOLS_SETUP_EVENT = "devtools-plugin:setup";
|
|
15975
16371
|
var PINIA_DEVTOOLS_PLUGIN_ID = "dev.esm.pinia";
|
|
15976
16372
|
var piniaDevtoolsSuppressionState = {
|
|
@@ -34539,7 +34935,7 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
|
|
|
34539
34935
|
this.config.colors = shuffleArray(this.config.colors);
|
|
34540
34936
|
this.userColorMap = /* @__PURE__ */ new Map();
|
|
34541
34937
|
this.colorIndex = 0;
|
|
34542
|
-
this.version = "2.0.0-next.
|
|
34938
|
+
this.version = "2.0.0-next.29";
|
|
34543
34939
|
this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
|
|
34544
34940
|
this.superdocId = config.superdocId || require_uuid.v4_default();
|
|
34545
34941
|
this.colors = this.config.colors ?? [];
|