superdoc 2.0.0-next.28 → 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-BlnUCtrx.es.js → create-super-doc-ui-BKVf2uCM.es.js} +489 -108
- package/dist/chunks/{create-super-doc-ui-CZBUMdjl.cjs → create-super-doc-ui-BXehf3i3.cjs} +489 -108
- package/dist/collaboration-upgrade-engine.cjs +1 -1
- package/dist/collaboration-upgrade-engine.es.js +1 -1
- package/dist/layout-engine/layout-bridge/src/incrementalLayout.d.ts +18 -1
- 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 +113 -88
- package/dist/style.layered.css +113 -88
- package/dist/superdoc/src/components/CommentsLayer/floating-comment-positioning.d.ts +1 -2
- 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/stores/comments-store.d.ts +8 -2
- package/dist/superdoc/src/stores/helpers/tracked-change-thread-index.d.ts +14 -0
- package/dist/superdoc/src/stores/superdoc-store.d.ts +24 -6
- package/dist/superdoc.cjs +422 -134
- package/dist/superdoc.es.js +422 -134
- 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) {
|
|
@@ -2773,6 +2804,79 @@ const trackedChangeThreadParentIdForComment = (comment) => {
|
|
|
2773
2804
|
if (comment?.trackedChangeParentId != null && hasLegacyTrackedChangeThreadSignal(comment)) return comment.trackedChangeParentId;
|
|
2774
2805
|
return null;
|
|
2775
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
|
+
};
|
|
2776
2880
|
var Editor = class {
|
|
2777
2881
|
constructor() {
|
|
2778
2882
|
throw new Error("SuperDoc v2 beta: v1 editor-backed comment import paths are not available.");
|
|
@@ -2933,6 +3037,22 @@ const useCommentsStore = defineStore("comments", () => {
|
|
|
2933
3037
|
const suppressInternalExternal = (0, vue.ref)(true);
|
|
2934
3038
|
const currentCommentText = (0, vue.ref)("");
|
|
2935
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
|
+
});
|
|
2936
3056
|
const isCommentsListVisible = (0, vue.ref)(false);
|
|
2937
3057
|
const editorCommentIds = (0, vue.ref)([]);
|
|
2938
3058
|
const editorCommentPositions = (0, vue.ref)({});
|
|
@@ -3719,6 +3839,7 @@ const useCommentsStore = defineStore("comments", () => {
|
|
|
3719
3839
|
};
|
|
3720
3840
|
};
|
|
3721
3841
|
const getGroupedComments = (0, vue.computed)(() => buildGroupedComments(compareByCreatedTime));
|
|
3842
|
+
const hasOpenTrackedChanges = (0, vue.computed)(() => getGroupedComments.value?.parentComments.some((comment) => comment.trackedChange && !comment.resolvedTime) ?? false);
|
|
3722
3843
|
const getCommentsByPosition = (0, vue.computed)(() => buildGroupedComments(compareByPosition));
|
|
3723
3844
|
const hasOverlapId = (id) => overlappedIds.includes(id);
|
|
3724
3845
|
const documentsWithConverations = (0, vue.computed)(() => {
|
|
@@ -4904,7 +5025,7 @@ const useCommentsStore = defineStore("comments", () => {
|
|
|
4904
5025
|
superdoc
|
|
4905
5026
|
};
|
|
4906
5027
|
let resolvedCount = 0;
|
|
4907
|
-
|
|
5028
|
+
getTrackedChangeDecisionLinks(comment).forEach((linkedComment) => {
|
|
4908
5029
|
if (!linkedComment || linkedComment === comment) return;
|
|
4909
5030
|
if (linkedComment.resolvedTime) return;
|
|
4910
5031
|
if (![
|
|
@@ -4932,6 +5053,16 @@ const useCommentsStore = defineStore("comments", () => {
|
|
|
4932
5053
|
}
|
|
4933
5054
|
return trackedChangeIds;
|
|
4934
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
|
+
};
|
|
4935
5066
|
const collectTrackedChangeEntityIdsFromReceipt = (receipt) => {
|
|
4936
5067
|
const record = receipt && typeof receipt === "object" ? receipt : null;
|
|
4937
5068
|
if (!record?.success) return /* @__PURE__ */ new Set();
|
|
@@ -4963,7 +5094,7 @@ const useCommentsStore = defineStore("comments", () => {
|
|
|
4963
5094
|
const trackedChangeIds = collectTrackedChangeDecisionIds(comment);
|
|
4964
5095
|
if (!trackedChangeIds.size) return 0;
|
|
4965
5096
|
let detachedCount = 0;
|
|
4966
|
-
|
|
5097
|
+
getTrackedChangeDecisionLinks(comment).forEach((linkedComment) => {
|
|
4967
5098
|
if (!linkedComment || linkedComment === comment) return;
|
|
4968
5099
|
const trackedChangeParentId = normalizeCommentId(linkedComment.trackedChangeParentId);
|
|
4969
5100
|
const trackedChangeThreadParentId = normalizeCommentId(linkedComment.trackedChangeThreadParentId);
|
|
@@ -4979,7 +5110,7 @@ const useCommentsStore = defineStore("comments", () => {
|
|
|
4979
5110
|
});
|
|
4980
5111
|
return detachedCount;
|
|
4981
5112
|
};
|
|
4982
|
-
const pruneDecidedTrackedChangeRow = ({ superdoc, decidedId, decidedIds, documentId } = {}) => {
|
|
5113
|
+
const pruneDecidedTrackedChangeRow = ({ superdoc, comment: targetComment, decidedId, decidedIds, documentId } = {}) => {
|
|
4983
5114
|
const normalizedDecidedIds = new Set((Array.isArray(decidedIds) || decidedIds instanceof Set ? Array.from(decidedIds) : [decidedId]).map((id) => normalizeCommentId(id)).filter(Boolean));
|
|
4984
5115
|
const normalizedDocumentId = normalizeCommentId(documentId);
|
|
4985
5116
|
if (!normalizedDecidedIds.size || !normalizedDocumentId) return {
|
|
@@ -4988,7 +5119,13 @@ const useCommentsStore = defineStore("comments", () => {
|
|
|
4988
5119
|
};
|
|
4989
5120
|
const removedIds = /* @__PURE__ */ new Set();
|
|
4990
5121
|
let removed = false;
|
|
4991
|
-
|
|
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) => {
|
|
4992
5129
|
if (!comment?.trackedChange) return true;
|
|
4993
5130
|
if (!belongsToTrackedChangeSyncDocument(comment, normalizedDocumentId)) return true;
|
|
4994
5131
|
const ids = collectTrackedChangeDecisionIds(comment);
|
|
@@ -5024,6 +5161,25 @@ const useCommentsStore = defineStore("comments", () => {
|
|
|
5024
5161
|
adapter.clearActiveTrackedChangeTargetIfMatches(decidedId);
|
|
5025
5162
|
} catch {}
|
|
5026
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
|
+
};
|
|
5027
5183
|
const tracePostDecisionBackgroundReconcile = (superdoc, event, payload = {}) => {
|
|
5028
5184
|
const record = {
|
|
5029
5185
|
event,
|
|
@@ -5175,7 +5331,7 @@ const useCommentsStore = defineStore("comments", () => {
|
|
|
5175
5331
|
adapter: v2Adapter,
|
|
5176
5332
|
documentId: effectiveDocumentId,
|
|
5177
5333
|
items: listResult.items ?? [],
|
|
5178
|
-
pruneStale: listResult.complete
|
|
5334
|
+
pruneStale: listResult.complete === true && listResult.sourceCoverageComplete === true
|
|
5179
5335
|
});
|
|
5180
5336
|
const liveIds = new Set((listResult.items ?? []).map((item) => item && item.id != null ? String(item.id) : null).filter(Boolean));
|
|
5181
5337
|
if (!(decidedId != null && liveIds.has(decidedId))) {
|
|
@@ -5219,6 +5375,17 @@ const useCommentsStore = defineStore("comments", () => {
|
|
|
5219
5375
|
};
|
|
5220
5376
|
};
|
|
5221
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
|
+
});
|
|
5222
5389
|
resolveLinkedCommentsForTrackedChangeDecision({
|
|
5223
5390
|
superdoc,
|
|
5224
5391
|
comment,
|
|
@@ -5230,17 +5397,11 @@ const useCommentsStore = defineStore("comments", () => {
|
|
|
5230
5397
|
});
|
|
5231
5398
|
pruneDecidedTrackedChangeRow({
|
|
5232
5399
|
superdoc,
|
|
5400
|
+
comment,
|
|
5233
5401
|
decidedIds: reliableDecidedIds,
|
|
5234
5402
|
documentId: effectiveDocumentId
|
|
5235
5403
|
});
|
|
5236
5404
|
if (wasActiveBeforeDecide) clearActiveCommentSelection();
|
|
5237
|
-
reliableDecidedIds.forEach((id$1) => clearV2ActiveTrackedChangeTarget(v2Adapter, id$1));
|
|
5238
|
-
schedulePostDecisionBackgroundReconcile({
|
|
5239
|
-
superdoc,
|
|
5240
|
-
trackedChangesAdapter: v2Adapter,
|
|
5241
|
-
commentsAdapter: getV2CommentsAdapter(superdoc),
|
|
5242
|
-
documentId: effectiveDocumentId
|
|
5243
|
-
});
|
|
5244
5405
|
return {
|
|
5245
5406
|
ok: true,
|
|
5246
5407
|
success: true
|
|
@@ -5309,7 +5470,7 @@ const useCommentsStore = defineStore("comments", () => {
|
|
|
5309
5470
|
reason: "adapter-stale"
|
|
5310
5471
|
};
|
|
5311
5472
|
if (!result?.ok) return result;
|
|
5312
|
-
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;
|
|
5313
5474
|
reconcileTrackedChangesFromV2({
|
|
5314
5475
|
superdoc,
|
|
5315
5476
|
adapter: effectiveAdapter,
|
|
@@ -5346,12 +5507,12 @@ const useCommentsStore = defineStore("comments", () => {
|
|
|
5346
5507
|
};
|
|
5347
5508
|
const effectiveDocumentId = documentId ?? effectiveAdapter.documentId ?? superdoc?.activeEditor?.documentId ?? null;
|
|
5348
5509
|
const normalizedRemovedIds = new Set(Array.from(removedIds ?? []).map((id) => normalizeCommentId(id)).filter(Boolean));
|
|
5349
|
-
|
|
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({
|
|
5350
5512
|
superdoc,
|
|
5351
5513
|
decidedIds: normalizedRemovedIds,
|
|
5352
5514
|
documentId: effectiveDocumentId
|
|
5353
5515
|
});
|
|
5354
|
-
const normalizedUpsertIds = [...new Set(Array.from(upsertIds ?? []).map((id) => normalizeCommentId(id)).filter(Boolean))];
|
|
5355
5516
|
if (normalizedUpsertIds.length === 0) return {
|
|
5356
5517
|
ok: true,
|
|
5357
5518
|
items: [],
|
|
@@ -5955,10 +6116,12 @@ const useCommentsStore = defineStore("comments", () => {
|
|
|
5955
6116
|
getConfig,
|
|
5956
6117
|
documentsWithConverations,
|
|
5957
6118
|
getGroupedComments,
|
|
6119
|
+
hasOpenTrackedChanges,
|
|
5958
6120
|
getCommentsByPosition,
|
|
5959
6121
|
getFloatingComments,
|
|
5960
6122
|
getFloatingCommentInstances,
|
|
5961
6123
|
getCommentAliasIds,
|
|
6124
|
+
getTrackedChangeThread,
|
|
5962
6125
|
getCommentPositionKey,
|
|
5963
6126
|
getCommentPosition,
|
|
5964
6127
|
getCommentAnchoredText,
|
|
@@ -6871,30 +7034,6 @@ var _sfc_main$33 = {
|
|
|
6871
7034
|
}
|
|
6872
7035
|
};
|
|
6873
7036
|
var CommentInput_default = /* @__PURE__ */ require__plugin_vue_export_helper.__plugin_vue_export_helper_default(_sfc_main$33, [["__scopeId", "data-v-cc54b489"]]);
|
|
6874
|
-
const collectTrackedChangeThread = (parentComment, allComments) => {
|
|
6875
|
-
const trackedChangeId = parentComment.commentId;
|
|
6876
|
-
const threadIds = new Set([trackedChangeId]);
|
|
6877
|
-
const queue = [];
|
|
6878
|
-
allComments.forEach((comment) => {
|
|
6879
|
-
if (comment.commentId === trackedChangeId) return;
|
|
6880
|
-
const isDirectChild = [comment.parentCommentId, comment.threadingParentCommentId].filter((id) => id != null).map((id) => String(id)).includes(trackedChangeId);
|
|
6881
|
-
const isTrackedChangeThreadRoot = String(trackedChangeThreadParentIdForComment(comment) ?? "") === trackedChangeId && !comment.parentCommentId;
|
|
6882
|
-
if (isDirectChild || isTrackedChangeThreadRoot) {
|
|
6883
|
-
threadIds.add(comment.commentId);
|
|
6884
|
-
queue.push(comment.commentId);
|
|
6885
|
-
}
|
|
6886
|
-
});
|
|
6887
|
-
for (let i = 0; i < queue.length; i += 1) {
|
|
6888
|
-
const parentId = queue[i];
|
|
6889
|
-
allComments.forEach((comment) => {
|
|
6890
|
-
if ([comment.parentCommentId, comment.threadingParentCommentId].filter((id) => id != null).map((id) => String(id)).includes(parentId) && !threadIds.has(comment.commentId)) {
|
|
6891
|
-
threadIds.add(comment.commentId);
|
|
6892
|
-
queue.push(comment.commentId);
|
|
6893
|
-
}
|
|
6894
|
-
});
|
|
6895
|
-
}
|
|
6896
|
-
return allComments.filter((comment) => threadIds.has(comment.commentId));
|
|
6897
|
-
};
|
|
6898
7037
|
var _hoisted_1$25 = [
|
|
6899
7038
|
"data-comment-instance-id",
|
|
6900
7039
|
"data-comment-thread-id",
|
|
@@ -6987,13 +7126,14 @@ var _hoisted_45 = {
|
|
|
6987
7126
|
role: "alert"
|
|
6988
7127
|
};
|
|
6989
7128
|
var _hoisted_46 = { class: "tracked-change-decision-alert__message" };
|
|
6990
|
-
var _hoisted_47 =
|
|
7129
|
+
var _hoisted_47 = ["disabled", "data-disabled-reason"];
|
|
7130
|
+
var _hoisted_48 = {
|
|
6991
7131
|
key: 1,
|
|
6992
7132
|
class: "reply-expanded"
|
|
6993
7133
|
};
|
|
6994
|
-
var
|
|
6995
|
-
var
|
|
6996
|
-
var
|
|
7134
|
+
var _hoisted_49 = { class: "reply-input-wrapper" };
|
|
7135
|
+
var _hoisted_50 = { class: "reply-actions" };
|
|
7136
|
+
var _hoisted_51 = ["disabled", "data-disabled-reason"];
|
|
6997
7137
|
var CLICK_OUTSIDE_HIT_TOLERANCE_PX = 3;
|
|
6998
7138
|
var TRACKED_CHANGE_PREVIEW_MAX_PX = 90;
|
|
6999
7139
|
var _sfc_main$32 = {
|
|
@@ -7213,8 +7353,13 @@ var _sfc_main$32 = {
|
|
|
7213
7353
|
});
|
|
7214
7354
|
const commentsAreReadOnly$1 = () => getConfig.value?.readOnly === true;
|
|
7215
7355
|
const isReplying = (0, vue.ref)(false);
|
|
7356
|
+
const isSubmittingReply = (0, vue.ref)(false);
|
|
7216
7357
|
const startReply = () => {
|
|
7217
7358
|
if (commentsAreReadOnly$1()) return readOnlyMutationOutcome$1();
|
|
7359
|
+
if (isV2WriteDisabled.value) return {
|
|
7360
|
+
ok: false,
|
|
7361
|
+
reason: v2WriteCapability.value?.reason ?? "v2-write-unavailable"
|
|
7362
|
+
};
|
|
7218
7363
|
isReplying.value = true;
|
|
7219
7364
|
(0, vue.nextTick)(() => {
|
|
7220
7365
|
commentInput.value?.focus?.();
|
|
@@ -7223,12 +7368,12 @@ var _sfc_main$32 = {
|
|
|
7223
7368
|
};
|
|
7224
7369
|
const comments = (0, vue.computed)(() => {
|
|
7225
7370
|
const parentComment = props.comment;
|
|
7226
|
-
|
|
7227
|
-
return
|
|
7371
|
+
if (parentComment.trackedChange) return commentsStore.getTrackedChangeThread(parentComment);
|
|
7372
|
+
return commentsStore.commentsList.filter((comment) => {
|
|
7228
7373
|
const isThreadedComment = comment.parentCommentId === parentComment.commentId;
|
|
7229
7374
|
const isThisComment = comment.commentId === parentComment.commentId;
|
|
7230
7375
|
return isThreadedComment || isThisComment;
|
|
7231
|
-
})
|
|
7376
|
+
}).sort((a, b) => {
|
|
7232
7377
|
if (a.commentId === parentComment.commentId) return -1;
|
|
7233
7378
|
if (b.commentId === parentComment.commentId) return 1;
|
|
7234
7379
|
return a.createdTime - b.createdTime;
|
|
@@ -7406,20 +7551,33 @@ var _sfc_main$32 = {
|
|
|
7406
7551
|
};
|
|
7407
7552
|
const handleAddComment = async () => {
|
|
7408
7553
|
if (commentsAreReadOnly$1()) return readOnlyMutationOutcome$1();
|
|
7554
|
+
if (isV2WriteDisabled.value) return {
|
|
7555
|
+
ok: false,
|
|
7556
|
+
reason: v2WriteCapability.value?.reason ?? "v2-write-unavailable"
|
|
7557
|
+
};
|
|
7409
7558
|
if (isV2Mode.value && v2CommentsAdapter.value && !isPendingNewComment.value) {
|
|
7410
|
-
|
|
7411
|
-
|
|
7412
|
-
|
|
7413
|
-
|
|
7414
|
-
|
|
7415
|
-
|
|
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 = "";
|
|
7416
7576
|
(0, vue.nextTick)(() => emit("resize"));
|
|
7417
7577
|
return outcome;
|
|
7578
|
+
} finally {
|
|
7579
|
+
isSubmittingReply.value = false;
|
|
7418
7580
|
}
|
|
7419
|
-
isReplying.value = false;
|
|
7420
|
-
currentCommentText.value = "";
|
|
7421
|
-
(0, vue.nextTick)(() => emit("resize"));
|
|
7422
|
-
return outcome;
|
|
7423
7581
|
}
|
|
7424
7582
|
const options = {
|
|
7425
7583
|
documentId: props.comment.fileId,
|
|
@@ -7445,7 +7603,14 @@ var _sfc_main$32 = {
|
|
|
7445
7603
|
const v2TrackedChangesAdapter = (0, vue.computed)(() => isV2Mode.value ? proxy.$superdoc?.activeEditor?.v2TrackedChanges ?? null : null);
|
|
7446
7604
|
const v2WriteCapability = (0, vue.computed)(() => {
|
|
7447
7605
|
if (!v2CommentsAdapter.value) return null;
|
|
7448
|
-
|
|
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;
|
|
7449
7614
|
});
|
|
7450
7615
|
const isV2WriteDisabled = (0, vue.computed)(() => {
|
|
7451
7616
|
if (!isV2Mode.value) return false;
|
|
@@ -7453,6 +7618,11 @@ var _sfc_main$32 = {
|
|
|
7453
7618
|
if (!cap) return false;
|
|
7454
7619
|
return cap.canWrite === false;
|
|
7455
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
|
+
});
|
|
7456
7626
|
const v2TrackedChangeCapability = (0, vue.computed)(() => {
|
|
7457
7627
|
if (!v2TrackedChangesAdapter.value) return null;
|
|
7458
7628
|
const documentMode = commentsStore.viewingVisibility.documentMode;
|
|
@@ -7762,6 +7932,11 @@ var _sfc_main$32 = {
|
|
|
7762
7932
|
if (isPendingNewComment.value) cancelComment(proxy.$superdoc);
|
|
7763
7933
|
(0, vue.nextTick)(() => emit("resize"));
|
|
7764
7934
|
}, { immediate: true });
|
|
7935
|
+
(0, vue.watch)(isV2WriteDisabled, (isDisabled) => {
|
|
7936
|
+
if (!isDisabled) return;
|
|
7937
|
+
isReplying.value = false;
|
|
7938
|
+
(0, vue.nextTick)(() => emit("resize"));
|
|
7939
|
+
});
|
|
7765
7940
|
return (_ctx, _cache) => {
|
|
7766
7941
|
const _directive_click_outside = (0, vue.resolveDirective)("click-outside");
|
|
7767
7942
|
return (0, vue.withDirectives)(((0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
|
|
@@ -7955,11 +8130,14 @@ var _sfc_main$32 = {
|
|
|
7955
8130
|
class: "sd-button tracked-change-decision-alert__retry",
|
|
7956
8131
|
onClick: (0, vue.withModifiers)(retryTrackedChangeDecision, ["stop", "prevent"])
|
|
7957
8132
|
}, " Retry ")])) : (0, vue.createCommentVNode)("", true),
|
|
7958
|
-
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)("
|
|
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", {
|
|
7959
8134
|
key: 0,
|
|
7960
|
-
|
|
7961
|
-
|
|
7962
|
-
|
|
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, {
|
|
7963
8141
|
ref_key: "commentInput",
|
|
7964
8142
|
ref: commentInput,
|
|
7965
8143
|
users: usersFiltered.value,
|
|
@@ -7970,20 +8148,20 @@ var _sfc_main$32 = {
|
|
|
7970
8148
|
"users",
|
|
7971
8149
|
"config",
|
|
7972
8150
|
"comment"
|
|
7973
|
-
])]), (0, vue.createElementVNode)("div",
|
|
8151
|
+
])]), (0, vue.createElementVNode)("div", _hoisted_50, [(0, vue.createElementVNode)("button", {
|
|
7974
8152
|
class: "sd-button reply-btn-cancel",
|
|
7975
8153
|
onClick: (0, vue.withModifiers)(handleCancel, ["stop", "prevent"])
|
|
7976
8154
|
}, "Cancel"), (0, vue.createElementVNode)("button", {
|
|
7977
|
-
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 }]),
|
|
7978
8156
|
onClick: (0, vue.withModifiers)(handleAddComment, ["stop", "prevent"]),
|
|
7979
|
-
disabled: !hasTextContent.value || isV2WriteDisabled.value,
|
|
7980
|
-
"data-disabled-reason":
|
|
7981
|
-
}, " 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)
|
|
7982
8160
|
], 64))], 14, _hoisted_1$25)), [[_directive_click_outside, handleClickOutside]]);
|
|
7983
8161
|
};
|
|
7984
8162
|
}
|
|
7985
8163
|
};
|
|
7986
|
-
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"]]);
|
|
7987
8165
|
var _hoisted_1$24 = { class: "comments-list" };
|
|
7988
8166
|
var _hoisted_2$19 = { key: 0 };
|
|
7989
8167
|
var _hoisted_3$15 = [
|
|
@@ -8327,12 +8505,12 @@ const resolvePersistentReviewCardTop = ({ comment, anchorTop, anchorBottom, card
|
|
|
8327
8505
|
if ((Number.isFinite(anchorBottom) ? anchorBottom : anchorTop) < viewportTop) return Math.min(anchorTop, viewportTop - cardHeight - 1);
|
|
8328
8506
|
return anchorTop;
|
|
8329
8507
|
};
|
|
8330
|
-
const shouldMountFloatingCommentDialog = ({ id, visibleIds, activeCommentInstanceId
|
|
8508
|
+
const shouldMountFloatingCommentDialog = ({ id, visibleIds, activeCommentInstanceId }) => {
|
|
8331
8509
|
if (!id) return false;
|
|
8332
8510
|
if (id === "pending") return true;
|
|
8333
8511
|
if (activeCommentInstanceId != null && String(id) === String(activeCommentInstanceId)) return true;
|
|
8334
8512
|
if (visibleIds?.has?.(id)) return true;
|
|
8335
|
-
return
|
|
8513
|
+
return false;
|
|
8336
8514
|
};
|
|
8337
8515
|
const resolveRemovedReviewCardContinuityTarget = ({ previousIds, currentIds, removedId }) => {
|
|
8338
8516
|
if (!Array.isArray(previousIds) || !(currentIds instanceof Set) || !removedId) return null;
|
|
@@ -8371,7 +8549,6 @@ var _sfc_main$30 = {
|
|
|
8371
8549
|
setup(__props) {
|
|
8372
8550
|
const ESTIMATED_HEIGHT = 110;
|
|
8373
8551
|
const OBSERVER_MARGIN = 600;
|
|
8374
|
-
const FALLBACK_ANCHOR_STEP = .001;
|
|
8375
8552
|
const resolveCollisions = (positions, activeIndex, gap) => {
|
|
8376
8553
|
if (activeIndex >= 0) {
|
|
8377
8554
|
positions[activeIndex].top = positions[activeIndex].anchorTop;
|
|
@@ -8414,6 +8591,7 @@ var _sfc_main$30 = {
|
|
|
8414
8591
|
const commentsRenderKey = (0, vue.ref)(0);
|
|
8415
8592
|
const sidebarOffsetY = (0, vue.ref)(0);
|
|
8416
8593
|
const disableInstantLayoutTransitions = (0, vue.ref)(false);
|
|
8594
|
+
const viewportRevision = (0, vue.ref)(0);
|
|
8417
8595
|
const isPendingThread = (commentOrId) => {
|
|
8418
8596
|
const pendingId = pendingComment.value?.commentId;
|
|
8419
8597
|
if (!pendingId) return false;
|
|
@@ -8423,10 +8601,27 @@ var _sfc_main$30 = {
|
|
|
8423
8601
|
const getThreadId = (comment) => {
|
|
8424
8602
|
return comment?.commentId ?? comment?.importedId ?? null;
|
|
8425
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
|
+
});
|
|
8426
8621
|
const resolveFloatingInstanceId = (threadId, preferredInstanceId = null) => {
|
|
8427
8622
|
if (threadId == null) return null;
|
|
8428
8623
|
const normalizedThreadId = String(threadId);
|
|
8429
|
-
const matchingInstances =
|
|
8624
|
+
const matchingInstances = floatingInstanceIndex.value.byThreadId.get(normalizedThreadId) ?? [];
|
|
8430
8625
|
if (!matchingInstances.length) return null;
|
|
8431
8626
|
if (preferredInstanceId != null) {
|
|
8432
8627
|
const preferredInstance = matchingInstances.find((instance) => String(instance.id) === String(preferredInstanceId));
|
|
@@ -8449,6 +8644,14 @@ var _sfc_main$30 = {
|
|
|
8449
8644
|
const placeholderRefs = (0, vue.ref)({});
|
|
8450
8645
|
let observer = null;
|
|
8451
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
|
+
};
|
|
8452
8655
|
const getAnchorTop = (instance) => {
|
|
8453
8656
|
if (props.currentDocument.type === "application/pdf") {
|
|
8454
8657
|
const zoom = (activeZoom.value ?? 100) / 100;
|
|
@@ -8466,6 +8669,24 @@ var _sfc_main$30 = {
|
|
|
8466
8669
|
const bottom = instance?.positionEntry?.bounds?.bottom;
|
|
8467
8670
|
return Number.isFinite(bottom) ? bottom : anchorTop;
|
|
8468
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
|
+
});
|
|
8469
8690
|
const getPendingAnchorTop = () => {
|
|
8470
8691
|
const positionEntry = editorCommentPositions.value["pending"];
|
|
8471
8692
|
if (typeof positionEntry?.bounds?.top === "number" && !isNaN(positionEntry.bounds.top)) return positionEntry.bounds.top;
|
|
@@ -8499,40 +8720,72 @@ var _sfc_main$30 = {
|
|
|
8499
8720
|
return resolveFloatingInstanceId(instantSidebarAlignmentThreadId.value, instantSidebarAlignmentInstanceId.value);
|
|
8500
8721
|
});
|
|
8501
8722
|
const allPositions = (0, vue.computed)(() => {
|
|
8502
|
-
|
|
8723
|
+
viewportRevision.value;
|
|
8724
|
+
const positionedInstances = geometryBearingInstances.value;
|
|
8503
8725
|
const hasPending = pendingComment.value && pendingComment.value.fileId === props.currentDocument.id;
|
|
8504
|
-
if (!
|
|
8726
|
+
if (!positionedInstances.length && !floatingCommentInstances.value.length && !hasPending) return [];
|
|
8505
8727
|
const positions = [];
|
|
8506
|
-
|
|
8507
|
-
|
|
8508
|
-
|
|
8509
|
-
|
|
8510
|
-
|
|
8511
|
-
|
|
8512
|
-
|
|
8513
|
-
|
|
8514
|
-
|
|
8515
|
-
|
|
8516
|
-
if (
|
|
8517
|
-
|
|
8518
|
-
lastAnchoredTop = top;
|
|
8519
|
-
fallbackAnchorCount = 0;
|
|
8520
|
-
} else {
|
|
8521
|
-
fallbackAnchorCount += 1;
|
|
8522
|
-
top = lastAnchoredTop + fallbackAnchorCount * FALLBACK_ANCHOR_STEP;
|
|
8523
|
-
}
|
|
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);
|
|
8524
8740
|
positions.push({
|
|
8525
|
-
id
|
|
8741
|
+
id,
|
|
8526
8742
|
threadId,
|
|
8527
8743
|
pageIndex: instance?.pageIndex ?? null,
|
|
8528
8744
|
anchorTop: top,
|
|
8529
|
-
anchorBottom
|
|
8745
|
+
anchorBottom,
|
|
8530
8746
|
hasAnchorGeometry,
|
|
8531
8747
|
top,
|
|
8532
|
-
height: measuredHeights.value[
|
|
8748
|
+
height: measuredHeights.value[id] || ESTIMATED_HEIGHT,
|
|
8533
8749
|
commentRef: instance.comment,
|
|
8534
8750
|
instanceRef: instance
|
|
8535
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
|
+
});
|
|
8536
8789
|
}
|
|
8537
8790
|
if (hasPending) {
|
|
8538
8791
|
const pendingTop = getPendingAnchorTop();
|
|
@@ -8547,12 +8800,10 @@ var _sfc_main$30 = {
|
|
|
8547
8800
|
});
|
|
8548
8801
|
}
|
|
8549
8802
|
positions.sort((a, b) => a.anchorTop - b.anchorTop);
|
|
8550
|
-
const activeKey = hasPending ? "pending" : activeCommentInstanceId.value;
|
|
8551
8803
|
resolveCollisions(positions, activeKey ? positions.findIndex((p) => p.id === activeKey) : -1, 15);
|
|
8552
|
-
const
|
|
8553
|
-
if (viewportRange) for (const position of positions) {
|
|
8804
|
+
for (const position of positions) {
|
|
8554
8805
|
if (!position.hasAnchorGeometry) continue;
|
|
8555
|
-
const
|
|
8806
|
+
const offscreenTop = resolvePersistentReviewCardTop({
|
|
8556
8807
|
comment: position.commentRef,
|
|
8557
8808
|
anchorTop: position.anchorTop,
|
|
8558
8809
|
anchorBottom: position.anchorBottom,
|
|
@@ -8560,21 +8811,13 @@ var _sfc_main$30 = {
|
|
|
8560
8811
|
viewportTop: viewportRange.top,
|
|
8561
8812
|
viewportBottom: viewportRange.bottom
|
|
8562
8813
|
});
|
|
8563
|
-
if (
|
|
8814
|
+
if (offscreenTop != null) position.top = offscreenTop;
|
|
8564
8815
|
}
|
|
8565
8816
|
return positions;
|
|
8566
8817
|
});
|
|
8567
|
-
const totalHeight = (0, vue.computed)(() => {
|
|
8568
|
-
if (!allPositions.value.length) return 0;
|
|
8569
|
-
let max = 0;
|
|
8570
|
-
for (const p of allPositions.value) {
|
|
8571
|
-
const bottom = p.top + p.height;
|
|
8572
|
-
if (bottom > max) max = bottom;
|
|
8573
|
-
}
|
|
8574
|
-
return max + 50;
|
|
8575
|
-
});
|
|
8576
8818
|
const wrapperMinHeight = (0, vue.computed)(() => {
|
|
8577
|
-
|
|
8819
|
+
viewportRevision.value;
|
|
8820
|
+
return Math.max(0, props.parent?.clientHeight || 0, props.parent?.scrollHeight || 0);
|
|
8578
8821
|
});
|
|
8579
8822
|
const setupObserver = () => {
|
|
8580
8823
|
if (observer) observer.disconnect();
|
|
@@ -8932,6 +9175,8 @@ var _sfc_main$30 = {
|
|
|
8932
9175
|
});
|
|
8933
9176
|
(0, vue.onMounted)(() => {
|
|
8934
9177
|
setupObserver();
|
|
9178
|
+
props.parent?.addEventListener?.("scroll", refreshViewportWindow, { passive: true });
|
|
9179
|
+
window.addEventListener("resize", refreshViewportWindow, { passive: true });
|
|
8935
9180
|
(0, vue.nextTick)(observePlaceholders);
|
|
8936
9181
|
});
|
|
8937
9182
|
(0, vue.onBeforeUnmount)(() => {
|
|
@@ -8942,6 +9187,12 @@ var _sfc_main$30 = {
|
|
|
8942
9187
|
cancelAnimationFrame(activeLayoutContinuityFrame);
|
|
8943
9188
|
activeLayoutContinuityFrame = null;
|
|
8944
9189
|
}
|
|
9190
|
+
props.parent?.removeEventListener?.("scroll", refreshViewportWindow);
|
|
9191
|
+
window.removeEventListener("resize", refreshViewportWindow);
|
|
9192
|
+
if (viewportFrame != null) {
|
|
9193
|
+
cancelAnimationFrame(viewportFrame);
|
|
9194
|
+
viewportFrame = null;
|
|
9195
|
+
}
|
|
8945
9196
|
if (observer) {
|
|
8946
9197
|
observer.disconnect();
|
|
8947
9198
|
observer = null;
|
|
@@ -9003,7 +9254,7 @@ var _sfc_main$30 = {
|
|
|
9003
9254
|
};
|
|
9004
9255
|
}
|
|
9005
9256
|
};
|
|
9006
|
-
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"]]);
|
|
9007
9258
|
var _hoisted_1$22 = {
|
|
9008
9259
|
class: "superdoc__pdf-comments-layer pdf-comments-layer",
|
|
9009
9260
|
"aria-hidden": "false"
|
|
@@ -11866,7 +12117,34 @@ function useLinkPopover({ getSurfaceManager, getActiveEditor, getUi, getResolver
|
|
|
11866
12117
|
tick();
|
|
11867
12118
|
});
|
|
11868
12119
|
}
|
|
11869
|
-
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 } = {}) {
|
|
11870
12148
|
if (typeof anchorUrl !== "string" || !anchorUrl.startsWith("#")) return;
|
|
11871
12149
|
const anchorName = anchorUrl.slice(1);
|
|
11872
12150
|
const escapedAnchorName = cssEscape(anchorName);
|
|
@@ -11891,6 +12169,7 @@ function useLinkPopover({ getSurfaceManager, getActiveEditor, getUi, getResolver
|
|
|
11891
12169
|
if (story && story.storyType !== "body") return;
|
|
11892
12170
|
const blockId = bookmark?.range?.from?.blockId;
|
|
11893
12171
|
if (typeof blockId !== "string") return;
|
|
12172
|
+
if (placeCaret) await placeCaretAtHeadingStart(blockId);
|
|
11894
12173
|
const mountedParagraph = findPaintedParagraphByParaId(getUi()?.viewport?.getHost?.() ?? null, blockId);
|
|
11895
12174
|
if (mountedParagraph) {
|
|
11896
12175
|
scrollToElement(mountedParagraph);
|
|
@@ -12000,7 +12279,7 @@ function useLinkPopover({ getSurfaceManager, getActiveEditor, getUi, getResolver
|
|
|
12000
12279
|
function openDefaultPopover(ctx) {
|
|
12001
12280
|
closeCurrentPopover("replace");
|
|
12002
12281
|
if (ctx.isAnchorLink && isTocEntryLinkElement(ctx.element)) {
|
|
12003
|
-
navigateToAnchor(ctx.href);
|
|
12282
|
+
navigateToAnchor(ctx.href, { placeCaret: ctx.documentMode !== "viewing" });
|
|
12004
12283
|
return;
|
|
12005
12284
|
}
|
|
12006
12285
|
if (ctx.documentMode === "viewing") {
|
|
@@ -12016,7 +12295,7 @@ function useLinkPopover({ getSurfaceManager, getActiveEditor, getUi, getResolver
|
|
|
12016
12295
|
const closePopover = () => closeCurrentPopover("closed");
|
|
12017
12296
|
const goToAnchor = (anchorUrl) => {
|
|
12018
12297
|
closePopover();
|
|
12019
|
-
navigateToAnchor(anchorUrl);
|
|
12298
|
+
navigateToAnchor(anchorUrl, { placeCaret: true });
|
|
12020
12299
|
};
|
|
12021
12300
|
const generation = openGeneration;
|
|
12022
12301
|
const openWithHyperlinkTarget = (hyperlinkTarget) => {
|
|
@@ -13779,7 +14058,7 @@ var _sfc_main$20 = {
|
|
|
13779
14058
|
__name: "SuperDoc",
|
|
13780
14059
|
emits: ["selection-update"],
|
|
13781
14060
|
setup(__props, { emit: __emit }) {
|
|
13782
|
-
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")));
|
|
13783
14062
|
const getDocumentLoadPassword = (doc) => doc.password ?? proxy.$superdoc.config.password;
|
|
13784
14063
|
const resolveDocumentV2Collaboration = (doc) => {
|
|
13785
14064
|
const rawConfig = doc?.v2Collaboration;
|
|
@@ -13824,7 +14103,7 @@ var _sfc_main$20 = {
|
|
|
13824
14103
|
});
|
|
13825
14104
|
}
|
|
13826
14105
|
});
|
|
13827
|
-
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);
|
|
13828
14107
|
const { showAddComment, handleEditorLocationsUpdate, handleTrackedChangeUpdate, refreshTrackedChangeCommentsByIds, syncTrackedChangePositionsWithDocument, syncTrackedChangeComments, addComment, addHydratedComment, getComment, resolveCommentPositionEntry, belongsToDocument, COMMENT_EVENTS, requestInstantSidebarAlignment, peekInstantSidebarAlignment, clearInstantSidebarAlignment } = commentsStore;
|
|
13829
14108
|
const { proxy } = (0, vue.getCurrentInstance)();
|
|
13830
14109
|
commentsStore.proxy = proxy;
|
|
@@ -14004,18 +14283,19 @@ var _sfc_main$20 = {
|
|
|
14004
14283
|
if (!documentId) return;
|
|
14005
14284
|
clearV2CommandShortcutBinding(documentId);
|
|
14006
14285
|
if (typeof bindEditShortcuts !== "function") return;
|
|
14007
|
-
const
|
|
14286
|
+
const fallbackUi = require_create_super_doc_ui.createSuperDocUI({ superdoc: proxy.$superdoc });
|
|
14287
|
+
const resolveUi = () => proxy.$superdoc?.toolbar?.ui ?? fallbackUi;
|
|
14008
14288
|
const openLinkWorkflow = resolveV2LinkWorkflowOpener();
|
|
14009
14289
|
const unbind = bindEditShortcuts({
|
|
14010
14290
|
commandRoute: {
|
|
14011
|
-
executeAsync: (commandId, payload) =>
|
|
14012
|
-
getState: (commandId) =>
|
|
14291
|
+
executeAsync: (commandId, payload) => resolveUi().commands.executeAsync(commandId, payload),
|
|
14292
|
+
getState: (commandId) => resolveUi().commands.get(commandId).getState()
|
|
14013
14293
|
},
|
|
14014
14294
|
...openLinkWorkflow ? { openLinkWorkflow } : {}
|
|
14015
14295
|
});
|
|
14016
14296
|
v2CommandShortcutBindings.set(documentId, {
|
|
14017
14297
|
unbind,
|
|
14018
|
-
ui
|
|
14298
|
+
ui: fallbackUi
|
|
14019
14299
|
});
|
|
14020
14300
|
};
|
|
14021
14301
|
const clearV2SessionShortcutBinding = (documentId) => {
|
|
@@ -14839,13 +15119,17 @@ var _sfc_main$20 = {
|
|
|
14839
15119
|
v2RulerReady.value = false;
|
|
14840
15120
|
};
|
|
14841
15121
|
let v2TypingReviewHydrationTimer = 0;
|
|
14842
|
-
const
|
|
15122
|
+
const hydrateV2CommentRowsFromHost = () => {
|
|
14843
15123
|
const commentsAdapter = proxy.$superdoc?.activeEditor?.v2Comments ?? null;
|
|
14844
|
-
if (commentsAdapter)
|
|
15124
|
+
if (!commentsAdapter) return;
|
|
15125
|
+
commentsStore.hydrateCommentsFromV2?.({
|
|
14845
15126
|
superdoc: proxy.$superdoc,
|
|
14846
15127
|
adapter: commentsAdapter,
|
|
14847
15128
|
documentId: proxy.$superdoc?.activeEditor?.documentId ?? null
|
|
14848
15129
|
});
|
|
15130
|
+
};
|
|
15131
|
+
const hydrateV2ReviewRowsFromHost = (options = {}) => {
|
|
15132
|
+
hydrateV2CommentRowsFromHost();
|
|
14849
15133
|
const trackedChangesAdapter = proxy.$superdoc?.activeEditor?.v2TrackedChanges ?? null;
|
|
14850
15134
|
if (!trackedChangesAdapter) return;
|
|
14851
15135
|
commentsStore.hydrateTrackedChangesFromV2?.({
|
|
@@ -14948,6 +15232,10 @@ var _sfc_main$20 = {
|
|
|
14948
15232
|
const receipt = event.origin === "history" ? null : event.receipt;
|
|
14949
15233
|
const canWaitForExactPaint = reviewImpact && typeof receipt?.txId === "string" && receipt.txId.length > 0 && typeof readiness?.whenPainted === "function";
|
|
14950
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
|
+
}
|
|
14951
15239
|
if (require_create_super_doc_ui.isV2EditableTextMutationEvent(event)) {
|
|
14952
15240
|
scheduleV2TypingReviewHydration();
|
|
14953
15241
|
return;
|
|
@@ -15409,7 +15697,7 @@ var _sfc_main$20 = {
|
|
|
15409
15697
|
if (isV2Mode.value && !v2GeometryAvailable.value && !hasPdfFloatingComments.value) return false;
|
|
15410
15698
|
if (!shouldRenderCommentsInViewing.value) return false;
|
|
15411
15699
|
if (!shouldUseSidebarComments.value) return false;
|
|
15412
|
-
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;
|
|
15413
15701
|
});
|
|
15414
15702
|
const activeCompactComment = (0, vue.computed)(() => {
|
|
15415
15703
|
if (showCommentsSidebar.value) return null;
|
|
@@ -16078,7 +16366,7 @@ var _sfc_main$20 = {
|
|
|
16078
16366
|
};
|
|
16079
16367
|
}
|
|
16080
16368
|
};
|
|
16081
|
-
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"]]);
|
|
16082
16370
|
var PINIA_DEVTOOLS_SETUP_EVENT = "devtools-plugin:setup";
|
|
16083
16371
|
var PINIA_DEVTOOLS_PLUGIN_ID = "dev.esm.pinia";
|
|
16084
16372
|
var piniaDevtoolsSuppressionState = {
|
|
@@ -34647,7 +34935,7 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
|
|
|
34647
34935
|
this.config.colors = shuffleArray(this.config.colors);
|
|
34648
34936
|
this.userColorMap = /* @__PURE__ */ new Map();
|
|
34649
34937
|
this.colorIndex = 0;
|
|
34650
|
-
this.version = "2.0.0-next.
|
|
34938
|
+
this.version = "2.0.0-next.29";
|
|
34651
34939
|
this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
|
|
34652
34940
|
this.superdocId = config.superdocId || require_uuid.v4_default();
|
|
34653
34941
|
this.colors = this.config.colors ?? [];
|