superdoc 2.29.0-next.9 → 2.30.0-next.4
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/README.md +127 -25
- package/dist/chunks/{FindReplaceSurface-BKVHzhQ4.es.js → FindReplaceSurface-BEnRLpD9.es.js} +1 -1
- package/dist/chunks/{FindReplaceSurface-BNDrJ6VS.cjs → FindReplaceSurface-DWXgWgg7.cjs} +1 -1
- package/dist/chunks/{PasswordPromptSurface-6mF6Azda.es.js → PasswordPromptSurface-DjV1JgjD.es.js} +1 -1
- package/dist/chunks/{PasswordPromptSurface-BNkaztaP.cjs → PasswordPromptSurface-VFPnQOML.cjs} +1 -1
- package/dist/chunks/{PdfViewer-aOWhUVI7.es.js → PdfViewer-C2r-K8zC.es.js} +4 -10
- package/dist/chunks/{PdfViewer-DmSkZehl.cjs → PdfViewer-DYTbPVUr.cjs} +4 -10
- package/dist/chunks/{_plugin-vue_export-helper-6MBoygIY.cjs → _plugin-vue_export-helper-BzM2_tVU.cjs} +40 -7
- package/dist/chunks/{_plugin-vue_export-helper-CsJQtMvr.es.js → _plugin-vue_export-helper-CmkaJDnr.es.js} +23 -8
- package/dist/chunks/{create-super-doc-ui-DN70aatf.cjs → create-super-doc-ui--kQBNTyt.cjs} +2424 -2302
- package/dist/chunks/{create-super-doc-ui-Bm5kmx0W.es.js → create-super-doc-ui-CbEDXtpm.es.js} +2350 -2228
- package/dist/collaboration-upgrade-engine.cjs +1 -1
- package/dist/collaboration-upgrade-engine.es.js +1 -1
- package/dist/document-api/src/changes/changes.d.ts +26 -0
- package/dist/document-api/src/changes/changes.types.d.ts +156 -0
- package/dist/document-api/src/contract/command-catalog.d.ts +1 -1
- package/dist/document-api/src/contract/operation-definitions.d.ts +51 -1
- package/dist/document-api/src/create/create.d.ts +0 -4
- package/dist/document-api/src/diff/diff.types.d.ts +6 -6
- package/dist/document-api/src/header-footers/header-footers.d.ts +1 -3
- package/dist/document-api/src/index.d.ts +6 -0
- package/dist/document-api/src/inline-semantics/token-sets.d.ts +0 -2
- package/dist/document-api/src/insert/insert.d.ts +0 -1
- package/dist/layout-engine/contracts/src/index.d.ts +3 -1
- package/dist/layout-engine/dom-contract/src/data-attrs.d.ts +4 -0
- package/dist/layout-engine/layout-bridge/src/coupled-footnote-pagination.d.ts +1 -0
- package/dist/layout-engine/layout-bridge/src/footnote-page-certificate.d.ts +1 -0
- package/dist/layout-engine/layout-bridge/src/footnote-page-planner.d.ts +5 -0
- package/dist/layout-engine/layout-bridge/src/incrementalLayout.d.ts +1 -0
- package/dist/layout-engine/layout-engine/src/footnote-page-flow.d.ts +3 -0
- package/dist/layout-engine/layout-engine/src/index.d.ts +7 -0
- package/dist/layout-engine/layout-engine/src/layout-paragraph.d.ts +5 -0
- package/dist/layout-engine/layout-engine/src/layout-table.d.ts +3 -1
- package/dist/layout-engine/layout-engine/src/layout-utils.d.ts +0 -4
- package/dist/layout-engine/layout-engine/src/paginator.d.ts +4 -0
- package/dist/layout-engine/painters/dom/src/paragraph/list-marker.d.ts +1 -1
- package/dist/layout-engine/painters/dom/src/paragraph/renderParagraphContent.d.ts +1 -1
- package/dist/layout-engine/painters/dom/src/styles.d.ts +0 -10
- package/dist/layout-engine/painters/dom/src/svg-utils.d.ts +1 -13
- package/dist/public/ui-react.cjs +1 -1
- package/dist/public/ui-react.es.js +1 -1
- package/dist/public/ui-vue.cjs +1 -1
- package/dist/public/ui-vue.es.js +1 -1
- package/dist/public/ui.cjs +1 -1
- package/dist/public/ui.es.js +1 -1
- package/dist/shared/common/Telemetry.d.ts +50 -0
- package/dist/shared/common/event-types.d.ts +13 -0
- package/dist/shared/font-system/src/bundled-face-names.d.ts +1 -0
- package/dist/shared/font-system/src/resolver.d.ts +1 -0
- package/dist/style.css +1 -1
- package/dist/style.layered.css +1 -1
- package/dist/superdoc/src/components/CommentsLayer/CommentDialog.vue.d.ts +17 -33
- package/dist/superdoc/src/components/CommentsLayer/collect-removed-comment-ids.d.ts +11 -1
- package/dist/superdoc/src/components/CommentsLayer/collect-tracked-change-thread.d.ts +25 -6
- package/dist/superdoc/src/components/CommentsLayer/comment-params.d.ts +84 -0
- package/dist/superdoc/src/components/CommentsLayer/comment-urls.d.ts +1 -1
- package/dist/superdoc/src/components/CommentsLayer/commentsList/super-comments-list.d.ts +23 -20
- package/dist/superdoc/src/components/CommentsLayer/helpers.d.ts +1 -4
- package/dist/superdoc/src/components/CommentsLayer/tracked-change-threading.d.ts +16 -1
- package/dist/superdoc/src/components/CommentsLayer/use-comment.d.ts +15 -95
- package/dist/superdoc/src/components/Whiteboard/WhiteboardLayer.vue.d.ts +4 -5
- package/dist/superdoc/src/components/Whiteboard/WhiteboardPage.vue.d.ts +3 -4
- package/dist/superdoc/src/components/Whiteboard/use-whiteboard.d.ts +30 -9
- package/dist/superdoc/src/components/Whiteboard/whiteboard-types.d.ts +2 -0
- package/dist/superdoc/src/components/surfaces/watermark-surface-runtime.d.ts +7 -7
- package/dist/superdoc/src/composables/use-comment-small-screen.d.ts +11 -7
- package/dist/superdoc/src/composables/use-compact-comment-popover.d.ts +44 -18
- package/dist/superdoc/src/composables/use-document.d.ts +51 -99
- package/dist/superdoc/src/composables/use-find-replace.d.ts +13 -3
- package/dist/superdoc/src/composables/use-password-prompt.d.ts +1 -1
- package/dist/superdoc/src/composables/use-viewport-fit.d.ts +62 -26
- package/dist/superdoc/src/core/SuperDoc.d.ts +15 -6
- package/dist/superdoc/src/core/collaboration/cdn-collaboration-comment-map.d.ts +1 -0
- package/dist/superdoc/src/core/collaboration/collaboration-comment-map.d.ts +2 -0
- package/dist/superdoc/src/core/collaboration/helpers.d.ts +1 -1
- package/dist/superdoc/src/core/document-open-telemetry.d.ts +1 -1
- package/dist/superdoc/src/core/editor-runtime/v2/v2-editor-runtime-adapter.d.ts +1 -0
- package/dist/superdoc/src/core/pdf/pdf-adapter.d.ts +6 -2
- package/dist/superdoc/src/core/types/index.d.ts +108 -43
- package/dist/superdoc/src/core/v2-integration/browser-peer-runtime.d.ts +5 -3
- package/dist/superdoc/src/core/v2-integration/cdn-engine-loader.d.ts +3 -13
- package/dist/superdoc/src/core/v2-integration/internal-vue-runtime.d.ts +64 -59
- package/dist/superdoc/src/helpers/deprecation.d.ts +12 -3
- package/dist/superdoc/src/helpers/object-guards.d.ts +2 -0
- package/dist/superdoc/src/helpers/v2-author-required-rejection.d.ts +8 -11
- package/dist/superdoc/src/helpers/v2-bulk-decision-event.d.ts +9 -7
- package/dist/superdoc/src/helpers/v2-keyboard-edit-rejection.d.ts +8 -7
- package/dist/superdoc/src/helpers/v2-mutation-exception.d.ts +12 -8
- package/dist/superdoc/src/helpers/v2-review-geometry-delivery.d.ts +22 -0
- package/dist/superdoc/src/helpers/v2-review-target.d.ts +11 -1
- package/dist/superdoc/src/helpers/v2-selection-sync.d.ts +40 -14
- package/dist/superdoc/src/helpers/v2-typing-mutation-event.d.ts +14 -5
- package/dist/superdoc/src/icons.d.ts +11 -19
- package/dist/superdoc/src/internal/diagnostics/translate-diagnostic.d.ts +6 -4
- package/dist/superdoc/src/internal/toolbar/built-in/PageNumberMenu.vue.d.ts +25 -15
- package/dist/superdoc/src/internal/toolbar/built-in/ToolbarButton.vue.d.ts +1 -0
- package/dist/superdoc/src/internal/toolbar/built-in/constants.d.ts +3 -1
- package/dist/superdoc/src/internal/toolbar/built-in/font-options.d.ts +15 -1
- package/dist/superdoc/src/internal/toolbar/built-in/font-typeahead.d.ts +37 -7
- package/dist/superdoc/src/internal/toolbar/built-in/general.d.ts +12 -1
- package/dist/superdoc/src/internal/toolbar/built-in/helpers.d.ts +9 -4
- package/dist/superdoc/src/internal/toolbar/built-in/list-style-buttons.d.ts +2 -2
- package/dist/superdoc/src/internal/toolbar/built-in/page-number-feedback.d.ts +4 -5
- package/dist/superdoc/src/internal/toolbar/built-in/scroll-helpers.d.ts +3 -4
- package/dist/superdoc/src/internal/toolbar/built-in/toolbarIcons.d.ts +78 -145
- package/dist/superdoc/src/internal/toolbar/built-in/url-safety.d.ts +11 -3
- package/dist/superdoc/src/internal/toolbar/built-in-toolbar.d.ts +4 -3
- package/dist/superdoc/src/internal/toolbar/image-upload.d.ts +29 -39
- package/dist/superdoc/src/public/content-control-ref.d.ts +12 -0
- package/dist/superdoc/src/public/index.d.cts +16 -0
- package/dist/superdoc/src/public/index.d.ts +3 -0
- package/dist/superdoc/src/public/ui/async-read-cache.d.ts +32 -0
- package/dist/superdoc/src/public/ui/block-commands.d.ts +39 -0
- package/dist/superdoc/src/public/ui/command-results.d.ts +39 -0
- package/dist/superdoc/src/public/ui/create-super-doc-ui.d.ts +1 -17
- package/dist/superdoc/src/public/ui/document-change-records.d.ts +7 -0
- package/dist/superdoc/src/public/ui/entity-rows.d.ts +14 -0
- package/dist/superdoc/src/public/ui/font-options.d.ts +7 -0
- package/dist/superdoc/src/public/ui/format-painter-helpers.d.ts +2 -8
- package/dist/superdoc/src/public/ui/format-painter-state.d.ts +33 -0
- package/dist/superdoc/src/public/ui/heavy-read-policy.d.ts +11 -0
- package/dist/superdoc/src/public/ui/host-events.d.ts +3 -0
- package/dist/superdoc/src/public/ui/inline-values.d.ts +79 -0
- package/dist/superdoc/src/public/ui/loose-record.d.ts +4 -0
- package/dist/superdoc/src/public/ui/selection-targets.d.ts +45 -0
- package/dist/superdoc/src/public/ui/shared-tracked-changes-catalog.d.ts +16 -0
- package/dist/superdoc/src/public/ui/tracked-change-ids.d.ts +51 -0
- package/dist/superdoc/src/public/ui/types.d.ts +12 -2
- package/dist/superdoc/src/public/ui/ui-bench-timing.d.ts +9 -0
- package/dist/superdoc/src/public/ui.d.cts +14 -0
- package/dist/superdoc/src/public/ui.d.ts +1 -1
- package/dist/superdoc/src/stores/comments-store.d.ts +23006 -542
- package/dist/superdoc/src/stores/helpers/comment-document-scope.d.ts +22 -0
- package/dist/superdoc/src/stores/helpers/comment-grouping.d.ts +1 -1
- package/dist/superdoc/src/stores/helpers/comment-identity.d.ts +10 -10
- package/dist/superdoc/src/stores/helpers/pending-selection-snapshot.d.ts +17 -0
- package/dist/superdoc/src/stores/helpers/review-presentation.d.ts +90 -0
- package/dist/superdoc/src/stores/helpers/tracked-change-compaction.d.ts +16 -0
- package/dist/superdoc/src/stores/helpers/tracked-change-decision.d.ts +45 -0
- package/dist/superdoc/src/stores/helpers/tracked-change-identity.d.ts +4 -2
- package/dist/superdoc/src/stores/helpers/tracked-change-row-values.d.ts +1 -8
- package/dist/superdoc/src/stores/helpers/tracked-change-thread-index.d.ts +1 -1
- package/dist/superdoc/src/stores/helpers/v2-review-adapters.d.ts +147 -0
- package/dist/superdoc/src/stores/superdoc-store.d.ts +12 -2895
- package/dist/superdoc.cjs +1019 -844
- package/dist/superdoc.es.js +931 -756
- package/dist/word-layout/src/marker-utils.d.ts +0 -5
- package/dist/word-layout/src/unit-conversions.d.ts +0 -1
- package/dist-cdn/style.layered.css +1 -1
- package/dist-cdn/superdoc.min.css +1 -1
- package/dist-cdn/superdoc.min.js +38 -42
- package/package.json +13 -3
- package/dist/document-api/src/diff/index.d.ts +0 -3
- package/dist/document-api/src/write/locator.d.ts +0 -24
- package/dist/layout-engine/painters/dom/src/features/feature-registry.d.ts +0 -41
- package/dist/superdoc/src/internal/toolbar/built-in/format-negation.d.ts +0 -5
- package/dist/superdoc/src/main.d.ts +0 -1
- package/dist/word-layout/src/tab-layout.d.ts +0 -193
package/dist/superdoc.es.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import { i as __toESM$2 } from "./chunks/rolldown-runtime-0pSA04fp.es.js";
|
|
2
|
+
import { $ as vModelSelect, A as onActivated, B as renderList, C as isRef$1, D as normalizeClass, E as nextTick, F as openBlock, G as toDisplayString, H as resolveDirective, I as provide$1, J as toRefs, K as toRaw$2, L as reactive, M as onDeactivated, N as onMounted, O as normalizeProps, P as onScopeDispose$1, Q as vModelCheckbox, R as readonly, S as isReactive$1, T as mergeProps, U as resolveDynamicComponent, V as renderSlot, W as shallowRef$1, X as useAttrs, Y as unref, Z as useSlots, _ as getCurrentInstance, a as computed$1, at as withModifiers, b as hasInjectionContext, c as createCommentVNode, ct as isThenable$1, d as createStaticVNode, et as vModelText, f as createTextVNode, g as effectScope, h as defineComponent, i as Transition, it as withKeys, j as onBeforeUnmount, k as normalizeStyle, l as createElementBlock, m as defineAsyncComponent, n as Fragment, nt as withCtx, o as createApp, p as createVNode, q as toRef, r as Teleport, rt as withDirectives, s as createBlock, st as isPlainObject$1, t as _plugin_vue_export_helper_default, tt as watch$1, u as createElementVNode, v as getCurrentScope, w as markRaw, x as inject$1, y as h, z as ref } from "./chunks/_plugin-vue_export-helper-CmkaJDnr.es.js";
|
|
2
3
|
import { t as blank_default } from "./chunks/blank-docx-DzQccOlW.es.js";
|
|
3
|
-
import { C as createInteractionHistory, E as recordInteraction, S as closeInteractionHistory, T as isWorkflowRecordingEnabled, _ as
|
|
4
|
+
import { C as createInteractionHistory, E as recordInteraction, S as closeInteractionHistory, T as isWorkflowRecordingEnabled, _ as isAllowed, a as registerFirstPartyCommandMutation, b as isRecord, c as applyV2CommentInvalidationFromMutation, d as createImageFilePicker, f as resolveImageSrc, g as createTrackedChangePermissionResolver, h as PERMISSIONS, i as readFirstPartyPageNumbers, l as getV2TrackedChangeMutationImpact, m as BUILT_IN_PERMISSION_METHOD, n as executeFirstPartyCommandAsync, r as executeFirstPartyShortcutAsync, s as getCommandDescriptor, t as createSuperDocUI, u as mutationCommittedEventChangedDocument, v as isSyntheticTrackedChangeCommentLaneItem, w as getWorkflowRecording, x as DOM_CLASS_NAMES, y as isStoryLocator } from "./chunks/create-super-doc-ui-CbEDXtpm.es.js";
|
|
4
5
|
import { t as import_eventemitter3 } from "./chunks/eventemitter3-DEIiXiH2.es.js";
|
|
5
6
|
import { t as v4 } from "./chunks/uuid-H0Xcmmhy.es.js";
|
|
6
|
-
import { $ as vModelSelect, A as onActivated, B as renderList, C as isRef$1, D as normalizeClass, E as nextTick, F as openBlock, G as toDisplayString, H as resolveDirective, I as provide$1, J as toRefs, K as toRaw$2, L as reactive, M as onDeactivated, N as onMounted, O as normalizeProps, P as onScopeDispose$1, Q as vModelCheckbox, R as readonly, S as isReactive$1, T as mergeProps, U as resolveDynamicComponent, V as renderSlot, W as shallowRef$1, X as useAttrs, Y as unref, Z as useSlots, _ as getCurrentInstance, a as computed$1, at as withModifiers, b as hasInjectionContext, c as createCommentVNode, d as createStaticVNode, et as vModelText, f as createTextVNode, g as effectScope, h as defineComponent, i as Transition, it as withKeys, j as onBeforeUnmount, k as normalizeStyle, l as createElementBlock, m as defineAsyncComponent, n as Fragment, nt as withCtx, o as createApp, p as createVNode, q as toRef, r as Teleport, rt as withDirectives, s as createBlock, t as _plugin_vue_export_helper_default, tt as watch$1, u as createElementVNode, v as getCurrentScope, w as markRaw, x as inject$1, y as h, z as ref } from "./chunks/_plugin-vue_export-helper-CsJQtMvr.es.js";
|
|
7
7
|
import { a as init_dist$1, i as global, n as init_dist$2, o as Buffer, r as process$1, s as init_dist, t as require_jszip_min } from "./chunks/jszip-BzJ3CyxR.es.js";
|
|
8
8
|
import { t as isFiniteNumber } from "./chunks/is-finite-number-BpL4F38c.es.js";
|
|
9
9
|
import { t as PDF_TO_CSS_UNITS } from "./chunks/constants-BvNs_ybI.es.js";
|
|
10
10
|
import * as Vue from "vue";
|
|
11
11
|
import { Map as Map$1 } from "yjs";
|
|
12
12
|
import Konva from "konva";
|
|
13
|
-
//#region src/core/v2-integration/browser-peer-runtime.
|
|
13
|
+
//#region src/core/v2-integration/browser-peer-runtime.ts
|
|
14
14
|
var SUPERDOC_V2_BROWSER_RUNTIME_GLOBAL_KEY = "__SUPERDOC_V2_BROWSER_RUNTIME__";
|
|
15
15
|
function readInstalledRuntime(globalObject = globalThis) {
|
|
16
|
-
const installed = globalObject
|
|
17
|
-
return installed
|
|
16
|
+
const installed = Reflect.get(globalObject, SUPERDOC_V2_BROWSER_RUNTIME_GLOBAL_KEY);
|
|
17
|
+
return isPlainObject$1(installed) ? installed : null;
|
|
18
18
|
}
|
|
19
19
|
function installSuperDocV2BrowserRuntime(runtime = {}, globalObject = globalThis) {
|
|
20
20
|
const installed = readInstalledRuntime(globalObject) ?? {};
|
|
@@ -23,7 +23,7 @@ function installSuperDocV2BrowserRuntime(runtime = {}, globalObject = globalThis
|
|
|
23
23
|
...runtime,
|
|
24
24
|
vue: runtime.vue ?? installed.vue ?? Vue
|
|
25
25
|
};
|
|
26
|
-
globalObject
|
|
26
|
+
Reflect.set(globalObject, SUPERDOC_V2_BROWSER_RUNTIME_GLOBAL_KEY, nextRuntime);
|
|
27
27
|
return nextRuntime;
|
|
28
28
|
}
|
|
29
29
|
installSuperDocV2BrowserRuntime();
|
|
@@ -258,7 +258,7 @@ var v_click_outside_default = {
|
|
|
258
258
|
var DEFAULT_ENDPOINT = "https://ingest.superdoc.dev/v1/collect";
|
|
259
259
|
function getSuperdocVersion() {
|
|
260
260
|
try {
|
|
261
|
-
return "2.
|
|
261
|
+
return "2.30.0-next.4";
|
|
262
262
|
} catch {
|
|
263
263
|
return "unknown";
|
|
264
264
|
}
|
|
@@ -5838,6 +5838,11 @@ function useCheckboxField(field) {
|
|
|
5838
5838
|
}) : itemoptions) };
|
|
5839
5839
|
}
|
|
5840
5840
|
//#endregion
|
|
5841
|
+
//#region src/core/collaboration/collaboration-comment-map.ts
|
|
5842
|
+
function createCollaborationCommentMap(entries) {
|
|
5843
|
+
return new Map$1(entries);
|
|
5844
|
+
}
|
|
5845
|
+
//#endregion
|
|
5841
5846
|
//#region src/core/collaboration/collaboration-comments.ts
|
|
5842
5847
|
var readComment = (event) => {
|
|
5843
5848
|
const { comment } = event;
|
|
@@ -5846,14 +5851,14 @@ var readComment = (event) => {
|
|
|
5846
5851
|
};
|
|
5847
5852
|
var addYComment = (yArray, ydoc, event, user) => {
|
|
5848
5853
|
const comment = readComment(event);
|
|
5849
|
-
const yComment =
|
|
5854
|
+
const yComment = createCollaborationCommentMap(Object.entries(comment));
|
|
5850
5855
|
ydoc.transact(() => {
|
|
5851
5856
|
yArray.push([yComment]);
|
|
5852
5857
|
}, { user });
|
|
5853
5858
|
};
|
|
5854
5859
|
var updateYComment = (yArray, ydoc, event, user) => {
|
|
5855
5860
|
const comment = readComment(event);
|
|
5856
|
-
const yComment =
|
|
5861
|
+
const yComment = createCollaborationCommentMap(Object.entries(comment));
|
|
5857
5862
|
const commentIndex = getCommentIndex(yArray, comment);
|
|
5858
5863
|
if (commentIndex === -1) return;
|
|
5859
5864
|
ydoc.transact(() => {
|
|
@@ -5874,7 +5879,7 @@ var getCommentIndex = (yArray, comment) => {
|
|
|
5874
5879
|
//#endregion
|
|
5875
5880
|
//#region src/core/collaboration/helpers.ts
|
|
5876
5881
|
var isPropertyBag = (value) => typeof value === "object" && value !== null || typeof value === "function";
|
|
5877
|
-
var readCommentsStore = (superdoc) => superdoc["commentsStore"];
|
|
5882
|
+
var readCommentsStore$1 = (superdoc) => superdoc["commentsStore"];
|
|
5878
5883
|
var isV2ReviewRuntimeActive = (superdoc) => superdoc.activeEditor?.editorVersion === 2 || superdoc.editorVersion === 2;
|
|
5879
5884
|
var commentKey = (comment) => {
|
|
5880
5885
|
const key = comment.commentId ?? comment.importedId;
|
|
@@ -5893,7 +5898,7 @@ var preserveLocalV2TrackedChangeRows = (superdoc, commentsStore, incomingComment
|
|
|
5893
5898
|
};
|
|
5894
5899
|
var loadCommentsFromYdoc = (superdoc) => {
|
|
5895
5900
|
if (!superdoc?.ydoc) return false;
|
|
5896
|
-
const commentsStore = readCommentsStore(superdoc);
|
|
5901
|
+
const commentsStore = readCommentsStore$1(superdoc);
|
|
5897
5902
|
if (!commentsStore) return false;
|
|
5898
5903
|
const comments = superdoc.ydoc.getArray("comments").toJSON();
|
|
5899
5904
|
const seenCommentIdByKey = /* @__PURE__ */ new Map();
|
|
@@ -5939,7 +5944,7 @@ var initCollaborationComments = (superdoc) => {
|
|
|
5939
5944
|
const updateCommentsStore = () => loadCommentsFromYdoc(superdoc);
|
|
5940
5945
|
const onSuperDocYdocSynced = () => {
|
|
5941
5946
|
if (!updateCommentsStore()) setTimeout(updateCommentsStore, 0);
|
|
5942
|
-
const commentsStore = readCommentsStore(superdoc);
|
|
5947
|
+
const commentsStore = readCommentsStore$1(superdoc);
|
|
5943
5948
|
if (commentsStore) commentsStore.hasSyncedCollaborationComments = true;
|
|
5944
5949
|
const currentProvider = superdoc.provider;
|
|
5945
5950
|
if (!currentProvider) throw new TypeError("initCollaborationComments requires superdoc.provider");
|
|
@@ -5951,7 +5956,7 @@ var initCollaborationComments = (superdoc) => {
|
|
|
5951
5956
|
provider.on("synced", onSuperDocYdocSynced);
|
|
5952
5957
|
if (!updateCommentsStore()) setTimeout(updateCommentsStore, 0);
|
|
5953
5958
|
commentsArray.observe((event) => {
|
|
5954
|
-
if (!readCommentsStore(superdoc)) return;
|
|
5959
|
+
if (!readCommentsStore$1(superdoc)) return;
|
|
5955
5960
|
const currentUser = superdoc.config.user;
|
|
5956
5961
|
const origin = event?.transaction?.origin;
|
|
5957
5962
|
const originUser = isPropertyBag(origin) ? origin.user : null;
|
|
@@ -6750,6 +6755,124 @@ var useSuperdocStore = defineStore("superdoc", () => {
|
|
|
6750
6755
|
};
|
|
6751
6756
|
});
|
|
6752
6757
|
//#endregion
|
|
6758
|
+
//#region ../document-api/src/errors.ts
|
|
6759
|
+
/**
|
|
6760
|
+
* Structured validation error thrown by document-api execute* functions.
|
|
6761
|
+
*
|
|
6762
|
+
* Consumers should prefer checking `error.code` over `instanceof` for resilience
|
|
6763
|
+
* across package boundaries and bundling scenarios.
|
|
6764
|
+
*/
|
|
6765
|
+
var DocumentApiValidationError = class DocumentApiValidationError extends Error {
|
|
6766
|
+
constructor(code, message, details) {
|
|
6767
|
+
super(message);
|
|
6768
|
+
this.name = "DocumentApiValidationError";
|
|
6769
|
+
this.code = code;
|
|
6770
|
+
this.details = details;
|
|
6771
|
+
Object.setPrototypeOf(this, DocumentApiValidationError.prototype);
|
|
6772
|
+
}
|
|
6773
|
+
};
|
|
6774
|
+
//#endregion
|
|
6775
|
+
//#region ../document-api/src/export/export.types.ts
|
|
6776
|
+
/** Canonical tracked-change export modes accepted by every public export surface. */
|
|
6777
|
+
var SD_EXPORT_MODES = [
|
|
6778
|
+
"review-preserving",
|
|
6779
|
+
"final",
|
|
6780
|
+
"original"
|
|
6781
|
+
];
|
|
6782
|
+
/** Default mode for modeful DOCX export. */
|
|
6783
|
+
var DEFAULT_SD_EXPORT_MODE = "review-preserving";
|
|
6784
|
+
var SD_COMMENT_EXPORT_POLICIES = [
|
|
6785
|
+
"preserve",
|
|
6786
|
+
"resolve",
|
|
6787
|
+
"remove"
|
|
6788
|
+
];
|
|
6789
|
+
var SD_CONTENT_CONTROL_EXPORT_POLICIES = ["preserve", "flatten"];
|
|
6790
|
+
//#endregion
|
|
6791
|
+
//#region ../document-api/src/export/export.ts
|
|
6792
|
+
/**
|
|
6793
|
+
* Export namespace: engine-agnostic public API and adapter contract.
|
|
6794
|
+
*
|
|
6795
|
+
* Validates the requested mode at the public boundary so an invalid mode fails
|
|
6796
|
+
* closed with `INVALID_INPUT` before any document work happens, then delegates
|
|
6797
|
+
* byte production and degradation reporting to the engine adapter.
|
|
6798
|
+
*/
|
|
6799
|
+
function resolveMode$1(input) {
|
|
6800
|
+
if (input != null && !isRecord(input)) throw new DocumentApiValidationError("INVALID_INPUT", "export.toDocx input must be an object.");
|
|
6801
|
+
const raw = input?.mode;
|
|
6802
|
+
if (raw === void 0) return DEFAULT_SD_EXPORT_MODE;
|
|
6803
|
+
if (typeof raw !== "string" || !SD_EXPORT_MODES.includes(raw)) throw new DocumentApiValidationError("INVALID_INPUT", `export.toDocx mode must be one of: ${SD_EXPORT_MODES.join(", ")}.`, {
|
|
6804
|
+
mode: raw,
|
|
6805
|
+
allowedModes: [...SD_EXPORT_MODES]
|
|
6806
|
+
});
|
|
6807
|
+
return raw;
|
|
6808
|
+
}
|
|
6809
|
+
function resolveDocxExportPolicies(input = {}) {
|
|
6810
|
+
if (!isRecord(input)) throw new DocumentApiValidationError("INVALID_INPUT", "DOCX export input must be an object.");
|
|
6811
|
+
const mode = resolveMode$1(input);
|
|
6812
|
+
const policies = input.policies;
|
|
6813
|
+
if (policies !== void 0 && !isRecord(policies)) throw new DocumentApiValidationError("INVALID_INPUT", "DOCX export policies must be an object.");
|
|
6814
|
+
const allowed = {
|
|
6815
|
+
trackedChanges: SD_EXPORT_MODES,
|
|
6816
|
+
comments: SD_COMMENT_EXPORT_POLICIES,
|
|
6817
|
+
contentControls: SD_CONTENT_CONTROL_EXPORT_POLICIES
|
|
6818
|
+
};
|
|
6819
|
+
for (const [key, value] of Object.entries(policies ?? {})) if (!Object.prototype.hasOwnProperty.call(allowed, key) || value !== void 0 && !allowed[key].includes(value)) throw new DocumentApiValidationError("INVALID_INPUT", `Unsupported DOCX export policy: ${key}.`, {
|
|
6820
|
+
policy: key,
|
|
6821
|
+
value
|
|
6822
|
+
});
|
|
6823
|
+
const requested = policies;
|
|
6824
|
+
if (input.mode !== void 0 && requested?.trackedChanges !== void 0 && mode !== requested.trackedChanges) throw new DocumentApiValidationError("INVALID_INPUT", "mode conflicts with policies.trackedChanges.");
|
|
6825
|
+
return {
|
|
6826
|
+
trackedChanges: requested?.trackedChanges ?? mode,
|
|
6827
|
+
comments: requested?.comments ?? "preserve",
|
|
6828
|
+
contentControls: requested?.contentControls ?? "preserve"
|
|
6829
|
+
};
|
|
6830
|
+
}
|
|
6831
|
+
//#endregion
|
|
6832
|
+
//#region ../document-api/src/permission-ranges/permission-ranges.ts
|
|
6833
|
+
function editorKey(editor) {
|
|
6834
|
+
return editor.id?.trim() ? editor.id : editor.email?.trim() || void 0;
|
|
6835
|
+
}
|
|
6836
|
+
function editorMatches(editor, id) {
|
|
6837
|
+
return Boolean(id.trim()) && (editor.id === id || Boolean(editor.email?.trim() && editor.email.trim().toLowerCase() === id.toLowerCase()));
|
|
6838
|
+
}
|
|
6839
|
+
/**
|
|
6840
|
+
* Resolve a host ID or imported Word email against an explicitly supplied roster.
|
|
6841
|
+
* Word receives the email when available; opaque IDs remain host-specific.
|
|
6842
|
+
* Duplicate IDs/emails are ambiguous. This does not authenticate a user.
|
|
6843
|
+
*/
|
|
6844
|
+
function resolvePermissionRangeEditor(editors, id) {
|
|
6845
|
+
const matches = editors.filter((editor) => editorMatches(editor, id));
|
|
6846
|
+
if (matches.length === 0) return {
|
|
6847
|
+
status: "unknown",
|
|
6848
|
+
id
|
|
6849
|
+
};
|
|
6850
|
+
if (matches.length !== 1) return {
|
|
6851
|
+
status: "ambiguous",
|
|
6852
|
+
id
|
|
6853
|
+
};
|
|
6854
|
+
const editor = matches[0];
|
|
6855
|
+
const wordId = editor.email?.trim() || editor.id;
|
|
6856
|
+
if (editors.filter((candidate) => editorMatches(candidate, wordId)).length !== 1) return {
|
|
6857
|
+
status: "ambiguous",
|
|
6858
|
+
id
|
|
6859
|
+
};
|
|
6860
|
+
return {
|
|
6861
|
+
status: "resolved",
|
|
6862
|
+
id,
|
|
6863
|
+
editor: { ...editor },
|
|
6864
|
+
principal: {
|
|
6865
|
+
kind: "editor",
|
|
6866
|
+
id: wordId
|
|
6867
|
+
}
|
|
6868
|
+
};
|
|
6869
|
+
}
|
|
6870
|
+
/** Enumerate the host roster for an editor picker, including ambiguous entries. */
|
|
6871
|
+
function listPermissionRangeEditors(editors) {
|
|
6872
|
+
const ids = new Set(editors.map(editorKey).filter((id) => id !== void 0));
|
|
6873
|
+
return Array.from(ids, (id) => resolvePermissionRangeEditor(editors, id));
|
|
6874
|
+
}
|
|
6875
|
+
//#endregion
|
|
6753
6876
|
//#region src/stores/helpers/floating-comment-instances.ts
|
|
6754
6877
|
var HEADER_FOOTER_TRACKED_CHANGE_STORY_TYPE = "headerFooterPart";
|
|
6755
6878
|
var toFinitePageIndex = (value) => {
|
|
@@ -6890,23 +7013,76 @@ var buildFloatingCommentInstances = ({ comment, positionKey, positionEntry, fall
|
|
|
6890
7013
|
})];
|
|
6891
7014
|
};
|
|
6892
7015
|
//#endregion
|
|
6893
|
-
//#region src/
|
|
7016
|
+
//#region src/stores/helpers/comment-document-scope.ts
|
|
7017
|
+
var getCommentDocumentId = (comment) => {
|
|
7018
|
+
if (!comment) return null;
|
|
7019
|
+
if (comment.fileId != null) return String(comment.fileId);
|
|
7020
|
+
if (comment.documentId != null) return String(comment.documentId);
|
|
7021
|
+
if (comment.selection?.documentId != null) return String(comment.selection.documentId);
|
|
7022
|
+
return null;
|
|
7023
|
+
};
|
|
7024
|
+
var createCommentDocumentScope = (readOpenDocuments) => {
|
|
7025
|
+
const getOpenDocuments = () => {
|
|
7026
|
+
const source = readOpenDocuments();
|
|
7027
|
+
const docs = Array.isArray(source) ? source : source?.value;
|
|
7028
|
+
return Array.isArray(docs) ? docs : [];
|
|
7029
|
+
};
|
|
7030
|
+
const getSingleOpenDocumentId = () => {
|
|
7031
|
+
const docs = getOpenDocuments();
|
|
7032
|
+
if (docs.length !== 1) return null;
|
|
7033
|
+
return docs[0]?.id != null ? String(docs[0].id) : null;
|
|
7034
|
+
};
|
|
7035
|
+
const belongsToDocument = (comment, activeDocumentId, options = {}) => {
|
|
7036
|
+
const { allowSingleDocumentMismatch = false } = options;
|
|
7037
|
+
if (!activeDocumentId) return false;
|
|
7038
|
+
const commentDocumentId = getCommentDocumentId(comment);
|
|
7039
|
+
if (commentDocumentId) {
|
|
7040
|
+
if (commentDocumentId === activeDocumentId) return true;
|
|
7041
|
+
const singleOpenDocumentId = getSingleOpenDocumentId();
|
|
7042
|
+
return allowSingleDocumentMismatch && singleOpenDocumentId === activeDocumentId;
|
|
7043
|
+
}
|
|
7044
|
+
return getSingleOpenDocumentId() === activeDocumentId;
|
|
7045
|
+
};
|
|
7046
|
+
const belongsToTrackedChangeSyncDocument = (comment, activeDocumentId) => belongsToDocument(comment, activeDocumentId, { allowSingleDocumentMismatch: true });
|
|
7047
|
+
return {
|
|
7048
|
+
belongsToDocument,
|
|
7049
|
+
belongsToTrackedChangeSyncDocument
|
|
7050
|
+
};
|
|
7051
|
+
};
|
|
7052
|
+
//#endregion
|
|
7053
|
+
//#region src/stores/helpers/pending-selection-snapshot.ts
|
|
7054
|
+
var isThenable = (value) => (typeof value === "object" || typeof value === "function") && value !== null && "then" in value && typeof value.then === "function";
|
|
7055
|
+
var getPendingSelectionSnapshot = (superdoc, activeSelection) => {
|
|
7056
|
+
if (activeSelection?.source !== "document-editor") return null;
|
|
7057
|
+
const selectionDocumentId = activeSelection?.documentId ?? null;
|
|
7058
|
+
const editorDocumentId = superdoc?.activeEditor?.options?.documentId ?? null;
|
|
7059
|
+
if (!selectionDocumentId || !editorDocumentId || selectionDocumentId !== editorDocumentId) return null;
|
|
7060
|
+
let currentSelection;
|
|
7061
|
+
try {
|
|
7062
|
+
currentSelection = superdoc?.activeEditor?.doc?.selection?.current;
|
|
7063
|
+
} catch {
|
|
7064
|
+
return null;
|
|
7065
|
+
}
|
|
7066
|
+
if (typeof currentSelection !== "function") return null;
|
|
7067
|
+
try {
|
|
7068
|
+
const snapshot = currentSelection();
|
|
7069
|
+
return isThenable(snapshot) ? Promise.resolve(snapshot).catch(() => null) : snapshot;
|
|
7070
|
+
} catch {
|
|
7071
|
+
return null;
|
|
7072
|
+
}
|
|
7073
|
+
};
|
|
7074
|
+
//#endregion
|
|
7075
|
+
//#region src/components/CommentsLayer/tracked-change-threading.ts
|
|
6894
7076
|
/**
|
|
6895
7077
|
* Legacy comment payloads predate explicit tracked-change thread provenance.
|
|
6896
7078
|
* These fields distinguish a true legacy review child from a v2 comment whose
|
|
6897
7079
|
* anchor merely overlaps tracked content.
|
|
6898
|
-
*
|
|
6899
|
-
* @param {Record<string, any> | null | undefined} comment
|
|
6900
|
-
* @returns {boolean}
|
|
6901
7080
|
*/
|
|
6902
7081
|
var hasLegacyTrackedChangeThreadSignal = (comment) => Boolean(comment?.trackedChangeLink) || Boolean(comment?.trackedChangeType) || Boolean(comment?.trackedChangeDisplayType) || Boolean(comment?.trackedChangeText) || Boolean(comment?.deletedText) || comment?.trackedChange === true;
|
|
6903
7082
|
/**
|
|
6904
7083
|
* Resolve explicit thread provenance first, then the guarded legacy fallback.
|
|
6905
7084
|
* Spatial-only v2 comments carry neither the explicit field nor a legacy
|
|
6906
7085
|
* review signal and therefore remain standalone.
|
|
6907
|
-
*
|
|
6908
|
-
* @param {Record<string, any> | null | undefined} comment
|
|
6909
|
-
* @returns {string | number | null}
|
|
6910
7086
|
*/
|
|
6911
7087
|
var trackedChangeThreadParentIdForComment$1 = (comment) => {
|
|
6912
7088
|
if (comment?.trackedChangeThreadParentId != null) return comment.trackedChangeThreadParentId;
|
|
@@ -7058,6 +7234,7 @@ var groupCommittedComments = (comments, presentations, isVisible) => {
|
|
|
7058
7234
|
});
|
|
7059
7235
|
const grouped = groupComments(comments.filter((row) => !presentations[String(row.fileId)]), isVisible);
|
|
7060
7236
|
for (const [documentId, presentation] of Object.entries(presentations)) {
|
|
7237
|
+
if (!presentation) continue;
|
|
7061
7238
|
grouped.parentComments.push(...visibleRowsInOrder(documentId, presentation.groupOrder.open));
|
|
7062
7239
|
grouped.resolvedComments.push(...visibleRowsInOrder(documentId, presentation.groupOrder.resolved));
|
|
7063
7240
|
}
|
|
@@ -7185,7 +7362,6 @@ function createDefaultV2Integration() {
|
|
|
7185
7362
|
//#region src/helpers/interaction-trace.ts
|
|
7186
7363
|
var isStartSpan = (value) => typeof value === "function";
|
|
7187
7364
|
var isEndSpan = (value) => typeof value === "function";
|
|
7188
|
-
var isThenable$3 = (value) => (typeof value === "object" || typeof value === "function") && value !== null && "then" in value && typeof value.then === "function";
|
|
7189
7365
|
function safeTraceCollector() {
|
|
7190
7366
|
try {
|
|
7191
7367
|
const collector = Reflect.get(globalThis, "__superdocInteractionTrace");
|
|
@@ -7216,7 +7392,7 @@ function withInteractionSpan(stage, branch, meta, fn) {
|
|
|
7216
7392
|
if (!span) return fn();
|
|
7217
7393
|
try {
|
|
7218
7394
|
const result = fn();
|
|
7219
|
-
if (isThenable$
|
|
7395
|
+
if (isThenable$1(result)) return result.then((value) => {
|
|
7220
7396
|
endInteractionSpan(span);
|
|
7221
7397
|
return value;
|
|
7222
7398
|
}, (error) => {
|
|
@@ -7231,6 +7407,81 @@ function withInteractionSpan(stage, branch, meta, fn) {
|
|
|
7231
7407
|
}
|
|
7232
7408
|
}
|
|
7233
7409
|
//#endregion
|
|
7410
|
+
//#region src/stores/helpers/tracked-change-decision.ts
|
|
7411
|
+
var normalizeTrackedChangeDecisionType = (value) => {
|
|
7412
|
+
const lower = typeof value === "string" ? value.toLowerCase() : "";
|
|
7413
|
+
if (!lower) return null;
|
|
7414
|
+
if (lower === "insert" || lower === "insertion" || lower === "trackinsert" || lower === "tableinsert" || lower === "paragraphsplit") return "insertion";
|
|
7415
|
+
if (lower === "delete" || lower === "deletion" || lower === "trackdelete" || lower === "tabledelete") return "deletion";
|
|
7416
|
+
return lower;
|
|
7417
|
+
};
|
|
7418
|
+
var trackedChangeDecisionKeepsCommentAnchor = ({ comment, decision } = {}) => {
|
|
7419
|
+
const normalizedDecision = decision === "accept" || decision === "reject" ? decision : null;
|
|
7420
|
+
if (!normalizedDecision) return false;
|
|
7421
|
+
const type = normalizeTrackedChangeDecisionType(comment?.trackedChangeDisplayType) ?? normalizeTrackedChangeDecisionType(comment?.trackedChangeType);
|
|
7422
|
+
return normalizedDecision === "accept" && type === "insertion" || normalizedDecision === "reject" && type === "deletion";
|
|
7423
|
+
};
|
|
7424
|
+
var collectTrackedChangeDecisionIdsWithAliases = (comment, aliasIds) => {
|
|
7425
|
+
const trackedChangeIds = new Set(aliasIds);
|
|
7426
|
+
if (comment?.trackedChangeCanonicalId != null) trackedChangeIds.add(String(comment.trackedChangeCanonicalId));
|
|
7427
|
+
const anchorKey = comment?.trackedChangeAnchorKey != null ? String(comment.trackedChangeAnchorKey) : null;
|
|
7428
|
+
if (anchorKey) {
|
|
7429
|
+
trackedChangeIds.add(anchorKey);
|
|
7430
|
+
if (anchorKey.startsWith("tc::")) {
|
|
7431
|
+
const rawId = anchorKey.slice(anchorKey.lastIndexOf("::") + 2);
|
|
7432
|
+
if (rawId) trackedChangeIds.add(rawId);
|
|
7433
|
+
}
|
|
7434
|
+
}
|
|
7435
|
+
return trackedChangeIds;
|
|
7436
|
+
};
|
|
7437
|
+
var collectTrackedChangeEntityIdsFromReceipt = (receipt) => {
|
|
7438
|
+
const record = receipt && typeof receipt === "object" ? receipt : null;
|
|
7439
|
+
if (!record?.success) return /* @__PURE__ */ new Set();
|
|
7440
|
+
const ids = /* @__PURE__ */ new Set();
|
|
7441
|
+
const collect = (entry) => {
|
|
7442
|
+
const ref = entry && typeof entry === "object" ? entry : null;
|
|
7443
|
+
if (ref?.kind !== "entity" || ref.entityType !== "trackedChange") return;
|
|
7444
|
+
if (ref.entityId != null && String(ref.entityId).length > 0) ids.add(String(ref.entityId));
|
|
7445
|
+
};
|
|
7446
|
+
if (Array.isArray(record.removed)) record.removed.forEach(collect);
|
|
7447
|
+
if (Array.isArray(record.invalidatedRefs)) record.invalidatedRefs.forEach(collect);
|
|
7448
|
+
return ids;
|
|
7449
|
+
};
|
|
7450
|
+
var collectReliableDecidedTrackedChangeIds = (outcome) => {
|
|
7451
|
+
const ids = /* @__PURE__ */ new Set();
|
|
7452
|
+
if (outcome?.decidedId != null && String(outcome.decidedId).length > 0) ids.add(String(outcome.decidedId));
|
|
7453
|
+
if (Array.isArray(outcome?.decidedIds)) outcome.decidedIds.forEach((id) => {
|
|
7454
|
+
if (id != null && String(id).length > 0) ids.add(String(id));
|
|
7455
|
+
});
|
|
7456
|
+
collectTrackedChangeEntityIdsFromReceipt(outcome?.receipt).forEach((id) => ids.add(id));
|
|
7457
|
+
return ids;
|
|
7458
|
+
};
|
|
7459
|
+
var clearV2ActiveTrackedChangeTarget = (adapter, decidedId) => {
|
|
7460
|
+
if (!decidedId || typeof adapter?.clearActiveTrackedChangeTargetIfMatches !== "function") return;
|
|
7461
|
+
try {
|
|
7462
|
+
adapter.clearActiveTrackedChangeTargetIfMatches(decidedId);
|
|
7463
|
+
} catch {}
|
|
7464
|
+
};
|
|
7465
|
+
var waitForTrackedDecisionCanonicalPaint = async ({ superdoc, receipt } = {}) => {
|
|
7466
|
+
const readiness = superdoc?.activeEditor?.documentMutationReadiness;
|
|
7467
|
+
if (receipt?.success !== true || typeof receipt?.txId !== "string" || !receipt.txId || typeof readiness?.whenPainted !== "function") return;
|
|
7468
|
+
try {
|
|
7469
|
+
await readiness.whenPainted(receipt);
|
|
7470
|
+
const requestFrame = globalThis.requestAnimationFrame;
|
|
7471
|
+
if (typeof requestFrame === "function") await new Promise((resolve) => {
|
|
7472
|
+
let settled = false;
|
|
7473
|
+
const finish = () => {
|
|
7474
|
+
if (settled) return;
|
|
7475
|
+
settled = true;
|
|
7476
|
+
clearTimeout(fallback);
|
|
7477
|
+
resolve();
|
|
7478
|
+
};
|
|
7479
|
+
const fallback = setTimeout(finish, 250);
|
|
7480
|
+
requestFrame(() => requestFrame(() => setTimeout(finish, 0)));
|
|
7481
|
+
});
|
|
7482
|
+
} catch {}
|
|
7483
|
+
};
|
|
7484
|
+
//#endregion
|
|
7234
7485
|
//#region src/stores/helpers/comment-draft-text.ts
|
|
7235
7486
|
var COMMENT_DRAFT_BR_TAG = /<br(?:\s[^>]*)?\s*\/?>/gi;
|
|
7236
7487
|
var COMMENT_DRAFT_BLOCK_BOUNDARY = /(?:<\/(?:p|div|li|blockquote|pre|h[1-6])\s*>\s*)+(?:<(?:p|div|li|blockquote|pre|h[1-6])(?:\s[^>]*)?\s*\/?>)+/gi;
|
|
@@ -7603,9 +7854,131 @@ var cloneV2TrackedChangeStory = (story) => {
|
|
|
7603
7854
|
};
|
|
7604
7855
|
};
|
|
7605
7856
|
//#endregion
|
|
7606
|
-
//#region src/stores/
|
|
7857
|
+
//#region src/stores/helpers/tracked-change-compaction.ts
|
|
7858
|
+
var isPresentId = (id) => Boolean(id);
|
|
7859
|
+
var getBodyTrackedChangeIdentityIds = (comment) => {
|
|
7860
|
+
return [normalizeCommentId(comment.commentId), ...!normalizeCommentId(comment.trackedChangeCanonicalId) ? [
|
|
7861
|
+
comment.importedId,
|
|
7862
|
+
comment.trackedChangeAnchorKey,
|
|
7863
|
+
...normalizeTrackedChangePositionAliases(comment.trackedChangePositionAliases)
|
|
7864
|
+
] : []].map((id) => normalizeCommentId(id)).filter(isPresentId);
|
|
7865
|
+
};
|
|
7866
|
+
var groupBodyTrackedChangeCommentsByIdentity = (comments) => {
|
|
7867
|
+
const parents = comments.map((_, index) => index);
|
|
7868
|
+
const findRoot = (index) => {
|
|
7869
|
+
let root = index;
|
|
7870
|
+
while (parents[root] !== root) root = parents[root];
|
|
7871
|
+
while (parents[index] !== index) {
|
|
7872
|
+
const next = parents[index];
|
|
7873
|
+
parents[index] = root;
|
|
7874
|
+
index = next;
|
|
7875
|
+
}
|
|
7876
|
+
return root;
|
|
7877
|
+
};
|
|
7878
|
+
const join = (left, right) => {
|
|
7879
|
+
const leftRoot = findRoot(left);
|
|
7880
|
+
const rightRoot = findRoot(right);
|
|
7881
|
+
if (leftRoot === rightRoot) return;
|
|
7882
|
+
parents[Math.max(leftRoot, rightRoot)] = Math.min(leftRoot, rightRoot);
|
|
7883
|
+
};
|
|
7884
|
+
const identityOwner = /* @__PURE__ */ new Map();
|
|
7885
|
+
comments.forEach((comment, index) => {
|
|
7886
|
+
getBodyTrackedChangeIdentityIds(comment).forEach((identityId) => {
|
|
7887
|
+
const owner = identityOwner.get(identityId);
|
|
7888
|
+
if (owner === void 0) identityOwner.set(identityId, index);
|
|
7889
|
+
else join(index, owner);
|
|
7890
|
+
});
|
|
7891
|
+
});
|
|
7892
|
+
const groups = /* @__PURE__ */ new Map();
|
|
7893
|
+
comments.forEach((comment, index) => {
|
|
7894
|
+
const root = findRoot(index);
|
|
7895
|
+
const group = groups.get(root) ?? [];
|
|
7896
|
+
group.push(comment);
|
|
7897
|
+
groups.set(root, group);
|
|
7898
|
+
});
|
|
7899
|
+
return groups;
|
|
7900
|
+
};
|
|
7901
|
+
var mergeDuplicateBodyTrackedChangeComments = (groups) => {
|
|
7902
|
+
const duplicates = /* @__PURE__ */ new Map();
|
|
7903
|
+
groups.forEach(([survivor, ...duplicateRows]) => {
|
|
7904
|
+
if (!survivor || duplicateRows.length === 0) return;
|
|
7905
|
+
const resolvedDuplicate = duplicateRows.find((comment) => comment.resolvedTime != null);
|
|
7906
|
+
if (survivor.resolvedTime == null && resolvedDuplicate) {
|
|
7907
|
+
survivor.resolvedTime = resolvedDuplicate.resolvedTime;
|
|
7908
|
+
survivor.resolvedById = resolvedDuplicate.resolvedById;
|
|
7909
|
+
survivor.resolvedByEmail = resolvedDuplicate.resolvedByEmail;
|
|
7910
|
+
survivor.resolvedByName = resolvedDuplicate.resolvedByName;
|
|
7911
|
+
survivor.trackedChangeDecision = resolvedDuplicate.trackedChangeDecision;
|
|
7912
|
+
}
|
|
7913
|
+
survivor.trackedChangePositionAliases = normalizeTrackedChangePositionAliases([...normalizeTrackedChangePositionAliases(survivor.trackedChangePositionAliases), ...duplicateRows.flatMap((comment) => [
|
|
7914
|
+
comment.commentId,
|
|
7915
|
+
comment.importedId,
|
|
7916
|
+
comment.trackedChangeCanonicalId,
|
|
7917
|
+
...normalizeTrackedChangePositionAliases(comment.trackedChangePositionAliases)
|
|
7918
|
+
])]);
|
|
7919
|
+
duplicateRows.forEach((comment) => duplicates.set(comment, survivor));
|
|
7920
|
+
});
|
|
7921
|
+
return duplicates;
|
|
7922
|
+
};
|
|
7923
|
+
var createDroppedCommentIdMap = (duplicates) => {
|
|
7924
|
+
const droppedCommentIds = /* @__PURE__ */ new Map();
|
|
7925
|
+
duplicates.forEach((survivor, duplicate) => {
|
|
7926
|
+
const fromId = normalizeCommentId(duplicate.commentId);
|
|
7927
|
+
const toId = normalizeCommentId(survivor.commentId);
|
|
7928
|
+
if (fromId && toId) droppedCommentIds.set(fromId, toId);
|
|
7929
|
+
});
|
|
7930
|
+
return droppedCommentIds;
|
|
7931
|
+
};
|
|
7932
|
+
//#endregion
|
|
7933
|
+
//#region src/stores/helpers/v2-review-adapters.ts
|
|
7934
|
+
var COMMENTS_ADAPTER_METHODS = [
|
|
7935
|
+
"setActiveComment",
|
|
7936
|
+
"commitPendingComment",
|
|
7937
|
+
"reply",
|
|
7938
|
+
"edit",
|
|
7939
|
+
"resolve",
|
|
7940
|
+
"reopen",
|
|
7941
|
+
"delete",
|
|
7942
|
+
"mapV2CommentToUseCommentInput"
|
|
7943
|
+
];
|
|
7944
|
+
var COMMENTS_ADAPTER_OPTIONAL_METHODS = [
|
|
7945
|
+
"getCapabilityState",
|
|
7946
|
+
"captureCurrentSelection",
|
|
7947
|
+
"isPendingCommentCreation",
|
|
7948
|
+
"seedReviewCatalog",
|
|
7949
|
+
"selectVisibleReviewComments"
|
|
7950
|
+
];
|
|
7951
|
+
var TRACKED_CHANGES_ADAPTER_METHODS = [
|
|
7952
|
+
"accept",
|
|
7953
|
+
"reject",
|
|
7954
|
+
"mapV2TrackedChangeToCommentParams"
|
|
7955
|
+
];
|
|
7956
|
+
var TRACKED_CHANGES_ADAPTER_OPTIONAL_METHODS = ["clearActiveTrackedChangeTargetIfMatches"];
|
|
7957
|
+
var isAdapterDocumentId = (value) => value === void 0 || value === null || typeof value === "string" || typeof value === "number";
|
|
7958
|
+
var hasAdapterShape = (value, required, optional) => isPlainObject$1(value) && isAdapterDocumentId(value.documentId) && required.every((member) => typeof value[member] === "function") && optional.every((member) => value[member] === void 0 || typeof value[member] === "function");
|
|
7959
|
+
function isV2CommentsAdapter(value) {
|
|
7960
|
+
return hasAdapterShape(value, COMMENTS_ADAPTER_METHODS, COMMENTS_ADAPTER_OPTIONAL_METHODS);
|
|
7961
|
+
}
|
|
7962
|
+
function isV2TrackedChangesAdapter(value) {
|
|
7963
|
+
return hasAdapterShape(value, TRACKED_CHANGES_ADAPTER_METHODS, TRACKED_CHANGES_ADAPTER_OPTIONAL_METHODS);
|
|
7964
|
+
}
|
|
7965
|
+
//#endregion
|
|
7966
|
+
//#region src/stores/comments-store.ts
|
|
7967
|
+
var requireHost = (superdoc, action) => {
|
|
7968
|
+
if (!superdoc) throw new TypeError(`${action} requires superdoc`);
|
|
7969
|
+
return superdoc;
|
|
7970
|
+
};
|
|
7971
|
+
var PARENT_LINK_FIELDS = [
|
|
7972
|
+
"trackedChangeThreadParentId",
|
|
7973
|
+
"trackedChangeParentId",
|
|
7974
|
+
"threadingParentCommentId",
|
|
7975
|
+
"parentCommentId"
|
|
7976
|
+
];
|
|
7977
|
+
var isPresent = (value) => Boolean(value);
|
|
7978
|
+
var errorDetail = (error) => (error == null ? void 0 : Reflect.get(Object(error), "message")) ?? String(error);
|
|
7607
7979
|
var useCommentsStore = defineStore("comments", () => {
|
|
7608
7980
|
const superdocStore = useSuperdocStore();
|
|
7981
|
+
const findDocument = (documentId) => typeof documentId === "string" ? superdocStore.getDocument(documentId) : void 0;
|
|
7609
7982
|
const commentsConfig = reactive({
|
|
7610
7983
|
name: "comments",
|
|
7611
7984
|
readOnly: false,
|
|
@@ -7672,7 +8045,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
7672
8045
|
});
|
|
7673
8046
|
const getTrackedChangeThread = (parentComment) => {
|
|
7674
8047
|
const id = parentComment?.commentId ?? null;
|
|
7675
|
-
return (id != null ? trackedChangeThreadIndex.value.get(id) : null) ?? [parentComment]
|
|
8048
|
+
return (id != null ? trackedChangeThreadIndex.value.get(id) : null) ?? (parentComment ? [parentComment] : []);
|
|
7676
8049
|
};
|
|
7677
8050
|
let priorTrackedChangeDecisionLinkIndex = /* @__PURE__ */ new Map();
|
|
7678
8051
|
const trackedChangeDecisionLinkIndex = computed$1(() => {
|
|
@@ -7704,29 +8077,27 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
7704
8077
|
});
|
|
7705
8078
|
const v2CommentsAdapter = shallowRef$1(null);
|
|
7706
8079
|
const setV2CommentsAdapter = (adapter) => {
|
|
7707
|
-
|
|
7708
|
-
v2CommentsAdapter.value
|
|
8080
|
+
const next = isV2CommentsAdapter(adapter) ? adapter : null;
|
|
8081
|
+
if (v2CommentsAdapter.value !== next) pendingCommentRequest += 1;
|
|
8082
|
+
v2CommentsAdapter.value = next;
|
|
7709
8083
|
};
|
|
7710
8084
|
const getV2CommentsAdapter = (superdoc) => {
|
|
7711
|
-
const fromFacade = superdoc?.activeEditor?.v2Comments
|
|
7712
|
-
if (fromFacade) return fromFacade;
|
|
8085
|
+
const fromFacade = superdoc?.activeEditor?.v2Comments;
|
|
8086
|
+
if (isV2CommentsAdapter(fromFacade)) return fromFacade;
|
|
7713
8087
|
return v2CommentsAdapter.value;
|
|
7714
8088
|
};
|
|
7715
8089
|
const isV2EditorActive = (superdoc) => superdoc?.activeEditor?.editorVersion === 2 || v2CommentsAdapter.value !== null;
|
|
7716
8090
|
const v2TrackedChangesAdapter = shallowRef$1(null);
|
|
7717
8091
|
const setV2TrackedChangesAdapter = (adapter) => {
|
|
7718
|
-
v2TrackedChangesAdapter.value = adapter
|
|
8092
|
+
v2TrackedChangesAdapter.value = isV2TrackedChangesAdapter(adapter) ? adapter : null;
|
|
7719
8093
|
};
|
|
7720
8094
|
const getV2TrackedChangesAdapter = (superdoc) => {
|
|
7721
|
-
const fromFacade = superdoc?.activeEditor?.v2TrackedChanges
|
|
7722
|
-
if (fromFacade) return fromFacade;
|
|
8095
|
+
const fromFacade = superdoc?.activeEditor?.v2TrackedChanges;
|
|
8096
|
+
if (isV2TrackedChangesAdapter(fromFacade)) return fromFacade;
|
|
7723
8097
|
return v2TrackedChangesAdapter.value;
|
|
7724
8098
|
};
|
|
7725
8099
|
/**
|
|
7726
8100
|
* Initialize the store
|
|
7727
|
-
*
|
|
7728
|
-
* @param {Object} config The comments module config from SuperDoc
|
|
7729
|
-
* @returns {void}
|
|
7730
8101
|
*/
|
|
7731
8102
|
const init = (config = {}) => {
|
|
7732
8103
|
const updatedConfig = {
|
|
@@ -7758,12 +8129,17 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
7758
8129
|
comment.trackedChangeDecision = null;
|
|
7759
8130
|
};
|
|
7760
8131
|
const getCommentEventPayload = (comment) => typeof comment?.getValues === "function" ? comment.getValues() : { ...comment };
|
|
8132
|
+
const getDeletedCommentChanges = (sources, fileId) => {
|
|
8133
|
+
const commentId = [...sources.map((source) => source?.commentId), ...sources.map((source) => source?.importedId)].map(normalizeCommentId).find(Boolean);
|
|
8134
|
+
return commentId ? [{
|
|
8135
|
+
key: "deleted",
|
|
8136
|
+
commentId,
|
|
8137
|
+
fileId
|
|
8138
|
+
}] : [];
|
|
8139
|
+
};
|
|
7761
8140
|
/**
|
|
7762
8141
|
* Check if a comment originated from the document editor (or has no explicit source).
|
|
7763
8142
|
* Comments without a source are assumed to be editor-backed for backward compatibility.
|
|
7764
|
-
*
|
|
7765
|
-
* @param {Object} comment - The comment to check
|
|
7766
|
-
* @returns {boolean} True if the comment is editor-backed
|
|
7767
8143
|
*/
|
|
7768
8144
|
const isEditorBackedComment = (comment) => {
|
|
7769
8145
|
const source = comment?.selection?.source;
|
|
@@ -7797,9 +8173,6 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
7797
8173
|
}, { deep: false });
|
|
7798
8174
|
/**
|
|
7799
8175
|
* Get the editor position data for a comment.
|
|
7800
|
-
*
|
|
7801
|
-
* @param {Object | string} commentOrId The comment object or comment ID
|
|
7802
|
-
* @returns {Object | null} The position data from editorCommentPositions
|
|
7803
8176
|
*/
|
|
7804
8177
|
const getCommentPosition = (commentOrId) => {
|
|
7805
8178
|
return resolveCommentPositionEntry(commentOrId).entry ?? null;
|
|
@@ -7812,10 +8185,6 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
7812
8185
|
};
|
|
7813
8186
|
/**
|
|
7814
8187
|
* Set the active comment or clear all active comments
|
|
7815
|
-
*
|
|
7816
|
-
* @param {Object | undefined | null} superdoc The SuperDoc instance holding the active editor
|
|
7817
|
-
* @param {string | undefined | null} id The comment ID
|
|
7818
|
-
* @returns {void}
|
|
7819
8188
|
*/
|
|
7820
8189
|
const setActiveComment = (superdoc, id) => {
|
|
7821
8190
|
const activeEditor = superdoc?.activeEditor;
|
|
@@ -7826,7 +8195,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
7826
8195
|
v2Adapter.setActiveComment(null);
|
|
7827
8196
|
return;
|
|
7828
8197
|
}
|
|
7829
|
-
activeEditor?.commands?.setActiveComment({ commentId: null });
|
|
8198
|
+
activeEditor?.commands?.setActiveComment?.({ commentId: null });
|
|
7830
8199
|
return;
|
|
7831
8200
|
}
|
|
7832
8201
|
const comment = getComment(id);
|
|
@@ -7837,16 +8206,11 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
7837
8206
|
v2Adapter.setActiveComment(comment.commentId);
|
|
7838
8207
|
return;
|
|
7839
8208
|
}
|
|
7840
|
-
activeEditor?.commands?.setActiveComment({ commentId: activeComment.value });
|
|
8209
|
+
activeEditor?.commands?.setActiveComment?.({ commentId: activeComment.value });
|
|
7841
8210
|
};
|
|
7842
8211
|
/**
|
|
7843
8212
|
* Called when a tracked change is updated. Creates a new comment if necessary,
|
|
7844
8213
|
* or updates an existing tracked-change comment.
|
|
7845
|
-
*
|
|
7846
|
-
* @param {Object} param0
|
|
7847
|
-
* @param {Object} param0.superdoc The SuperDoc instance
|
|
7848
|
-
* @param {Object} param0.params The tracked change params
|
|
7849
|
-
* @returns {void}
|
|
7850
8214
|
*/
|
|
7851
8215
|
const handleTrackedChangeUpdate = ({ superdoc, params, broadcastChanges = true, trackedChangeIdentityIndex = null }) => {
|
|
7852
8216
|
const span = startInteractionSpan("store.trackedChanges.handleUpdate", "store-reconciliation", {
|
|
@@ -7875,7 +8239,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
7875
8239
|
const normalizedTrackedChangeImagePreview = normalizeTrackedChangeImagePreview(trackedChangeImagePreview);
|
|
7876
8240
|
const comment = getPendingComment({
|
|
7877
8241
|
documentId,
|
|
7878
|
-
commentId:
|
|
8242
|
+
commentId: normalizedChangeId ?? void 0,
|
|
7879
8243
|
trackedChange: true,
|
|
7880
8244
|
trackedChangeText,
|
|
7881
8245
|
trackedChangeType,
|
|
@@ -7927,7 +8291,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
7927
8291
|
commentCanonicalId,
|
|
7928
8292
|
commentAnchorKey,
|
|
7929
8293
|
...commentAliasIds
|
|
7930
|
-
].
|
|
8294
|
+
].some((id) => id != null && incomingAliasIds.has(id))) return true;
|
|
7931
8295
|
const hasSyntheticSideIdentity = normalizedTrackedChangeCanonicalId && normalizedTrackedChangeCanonicalId !== normalizedChangeId || commentCanonicalId && commentCanonicalId !== commentId;
|
|
7932
8296
|
if (hasCompatibleStory && commentId === normalizedChangeId) return true;
|
|
7933
8297
|
if (hasCompatibleStory && !hasSyntheticSideIdentity && (importedId === normalizedChangeId || normalizedImportedId !== void 0 && normalizedImportedId != null && importedId === normalizedImportedId)) return true;
|
|
@@ -7951,7 +8315,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
7951
8315
|
};
|
|
7952
8316
|
const emitTrackedChangeEvent = (event) => {
|
|
7953
8317
|
if (!broadcastChanges) return;
|
|
7954
|
-
syncCommentsToClients(superdoc, event);
|
|
8318
|
+
syncCommentsToClients(requireHost(superdoc, "handleTrackedChangeUpdate"), event);
|
|
7955
8319
|
debounceEmit(changeId, event, superdoc);
|
|
7956
8320
|
};
|
|
7957
8321
|
const setIfChanged = (target, key, value) => {
|
|
@@ -7994,8 +8358,9 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
7994
8358
|
target?.trackedChangeCanonicalId,
|
|
7995
8359
|
target?.trackedChangeAnchorKey,
|
|
7996
8360
|
...getCommentAliasIds(target)
|
|
7997
|
-
].map((id) => normalizeCommentId(id)).filter(
|
|
7998
|
-
|
|
8361
|
+
].map((id) => normalizeCommentId(id)).filter(isPresent));
|
|
8362
|
+
const incomingAliases = normalizedTrackedChangePositionAliases ?? [];
|
|
8363
|
+
fields.trackedChangePositionAliases = incomingAliases.some((alias) => targetIdentityIds.has(alias)) ? normalizeTrackedChangePositionAliases([...Array.isArray(target?.trackedChangePositionAliases) ? target.trackedChangePositionAliases : [], ...incomingAliases]) : incomingAliases;
|
|
7999
8364
|
}
|
|
8000
8365
|
let didChange = false;
|
|
8001
8366
|
for (const [key, value] of Object.entries(fields)) didChange = setIfChanged(target, key, value) || didChange;
|
|
@@ -8004,7 +8369,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8004
8369
|
didChange = true;
|
|
8005
8370
|
}
|
|
8006
8371
|
if (hasCustomAttributes && target && !trackedChangeCustomAttributesEqual(target.customAttributes, normalizedCustomAttributes)) {
|
|
8007
|
-
target.customAttributes = normalizedCustomAttributes;
|
|
8372
|
+
target.customAttributes = normalizedCustomAttributes ?? null;
|
|
8008
8373
|
didChange = true;
|
|
8009
8374
|
}
|
|
8010
8375
|
return applyStoryMetadata(target) || didChange;
|
|
@@ -8026,7 +8391,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8026
8391
|
return;
|
|
8027
8392
|
}
|
|
8028
8393
|
addHydratedComment({
|
|
8029
|
-
superdoc,
|
|
8394
|
+
superdoc: requireHost(superdoc, "handleTrackedChangeUpdate"),
|
|
8030
8395
|
comment,
|
|
8031
8396
|
broadcastChanges
|
|
8032
8397
|
});
|
|
@@ -8046,11 +8411,12 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8046
8411
|
id: params.resolvedById ?? superdoc?.user?.id ?? null,
|
|
8047
8412
|
email: params.resolvedByEmail ?? superdoc?.user?.email ?? null,
|
|
8048
8413
|
name: params.resolvedByName ?? superdoc?.user?.name ?? null,
|
|
8049
|
-
decision: params.decision ??
|
|
8414
|
+
decision: params.decision ?? void 0,
|
|
8050
8415
|
superdoc
|
|
8051
8416
|
};
|
|
8052
8417
|
if (existingTrackedChange && !existingTrackedChange.resolvedTime) existingTrackedChange.resolveComment({
|
|
8053
8418
|
...resolveArgs,
|
|
8419
|
+
superdoc: requireHost(superdoc, "handleTrackedChangeUpdate"),
|
|
8054
8420
|
reconciliationToken: COMMENT_RECONCILIATION_TOKEN
|
|
8055
8421
|
});
|
|
8056
8422
|
}
|
|
@@ -8075,31 +8441,13 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8075
8441
|
instantSidebarAlignmentInstanceId.value = null;
|
|
8076
8442
|
};
|
|
8077
8443
|
const debounceEmit = (commentId, event, superdoc, delay = 1e3) => {
|
|
8078
|
-
|
|
8079
|
-
debounceTimers[
|
|
8444
|
+
const timerKey = String(commentId);
|
|
8445
|
+
if (debounceTimers[timerKey]) clearTimeout(debounceTimers[timerKey]);
|
|
8446
|
+
debounceTimers[timerKey] = setTimeout(() => {
|
|
8080
8447
|
if (superdoc) superdoc.emit("comments-update", event);
|
|
8081
|
-
delete debounceTimers[
|
|
8448
|
+
delete debounceTimers[timerKey];
|
|
8082
8449
|
}, delay);
|
|
8083
8450
|
};
|
|
8084
|
-
const getPendingSelectionSnapshot = (superdoc, activeSelection) => {
|
|
8085
|
-
if (activeSelection?.source !== "document-editor") return null;
|
|
8086
|
-
const selectionDocumentId = activeSelection?.documentId ?? null;
|
|
8087
|
-
const editorDocumentId = superdoc?.activeEditor?.options?.documentId ?? null;
|
|
8088
|
-
if (!selectionDocumentId || !editorDocumentId || selectionDocumentId !== editorDocumentId) return null;
|
|
8089
|
-
let currentSelection;
|
|
8090
|
-
try {
|
|
8091
|
-
currentSelection = superdoc?.activeEditor?.doc?.selection?.current;
|
|
8092
|
-
} catch {
|
|
8093
|
-
return null;
|
|
8094
|
-
}
|
|
8095
|
-
if (typeof currentSelection !== "function") return null;
|
|
8096
|
-
try {
|
|
8097
|
-
const snapshot = currentSelection();
|
|
8098
|
-
return typeof snapshot?.then === "function" ? Promise.resolve(snapshot).catch(() => null) : snapshot;
|
|
8099
|
-
} catch {
|
|
8100
|
-
return null;
|
|
8101
|
-
}
|
|
8102
|
-
};
|
|
8103
8451
|
const showAddComment = (superdoc, targetClientY = null) => {
|
|
8104
8452
|
const request = ++pendingCommentRequest;
|
|
8105
8453
|
const editor = superdoc?.activeEditor;
|
|
@@ -8109,7 +8457,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8109
8457
|
if (!ownsRequest()) return;
|
|
8110
8458
|
superdoc.emit("comments-update", {
|
|
8111
8459
|
type: COMMENT_EVENTS.PENDING,
|
|
8112
|
-
pendingSelection: superdoc?.activeEditor === editor ? snapshot : null
|
|
8460
|
+
pendingSelection: superdoc?.activeEditor === editor && isPlainObject$1(snapshot) ? snapshot : null
|
|
8113
8461
|
});
|
|
8114
8462
|
};
|
|
8115
8463
|
if (v2Adapter) {
|
|
@@ -8154,12 +8502,11 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8154
8502
|
}).catch((err) => ({
|
|
8155
8503
|
ok: false,
|
|
8156
8504
|
reason: "selection-capture-failed",
|
|
8157
|
-
detail:
|
|
8505
|
+
detail: errorDetail(err)
|
|
8158
8506
|
}));
|
|
8159
8507
|
}
|
|
8160
8508
|
const pendingSelection = getPendingSelectionSnapshot(superdoc, superdocStore.activeSelection);
|
|
8161
|
-
|
|
8162
|
-
if (!asyncSnapshot) emitPending(pendingSelection);
|
|
8509
|
+
if (!isThenable$1(pendingSelection)) emitPending(pendingSelection);
|
|
8163
8510
|
const showLegacyPending = (selection) => {
|
|
8164
8511
|
selection.selectionBounds = { ...selection.selectionBounds };
|
|
8165
8512
|
if (superdocStore.selectionPosition?.source && superdocStore.selectionPosition.source !== "pdf") superdocStore.selectionPosition.source = null;
|
|
@@ -8169,7 +8516,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8169
8516
|
parentCommentId: null
|
|
8170
8517
|
});
|
|
8171
8518
|
if (!superdoc.config.isInternal) pendingComment.value.isInternal = false;
|
|
8172
|
-
if (superdoc.activeEditor?.commands) superdoc.activeEditor.commands.insertComment({
|
|
8519
|
+
if (superdoc.activeEditor?.commands) superdoc.activeEditor.commands.insertComment?.({
|
|
8173
8520
|
...pendingComment.value.getValues(),
|
|
8174
8521
|
commentId: "pending",
|
|
8175
8522
|
skipEmit: true
|
|
@@ -8180,10 +8527,10 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8180
8527
|
activeComment.value = pendingComment.value.commentId;
|
|
8181
8528
|
return { ok: true };
|
|
8182
8529
|
};
|
|
8183
|
-
if (
|
|
8530
|
+
if (isThenable$1(pendingSelection)) {
|
|
8184
8531
|
const selection = { ...superdocStore.activeSelection };
|
|
8185
8532
|
selection.selectionBounds = { ...selection.selectionBounds };
|
|
8186
|
-
return pendingSelection.then((snapshot) => {
|
|
8533
|
+
return Promise.resolve(pendingSelection).then((snapshot) => {
|
|
8187
8534
|
if (!ownsRequest()) return {
|
|
8188
8535
|
ok: false,
|
|
8189
8536
|
reason: "pending-comment-superseded"
|
|
@@ -8215,12 +8562,6 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8215
8562
|
});
|
|
8216
8563
|
/**
|
|
8217
8564
|
* Get a new pending comment
|
|
8218
|
-
*
|
|
8219
|
-
* @param {Object} param0
|
|
8220
|
-
* @param {Object} [param0.selection] The selection object
|
|
8221
|
-
* @param {string | null} [param0.documentId] The document ID
|
|
8222
|
-
* @param {string | null} [param0.parentCommentId] The parent comment
|
|
8223
|
-
* @returns {ReturnType<typeof useComment>} The new comment object
|
|
8224
8565
|
*/
|
|
8225
8566
|
const getPendingComment = ({ selection, documentId, parentCommentId, ...options }) => {
|
|
8226
8567
|
return _getNewcomment({
|
|
@@ -8232,17 +8573,11 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8232
8573
|
};
|
|
8233
8574
|
/**
|
|
8234
8575
|
* Get the new comment object
|
|
8235
|
-
*
|
|
8236
|
-
* @param {Object} param0
|
|
8237
|
-
* @param {Object} param0.selection The selection object
|
|
8238
|
-
* @param {String} param0.documentId The document ID
|
|
8239
|
-
* @param {String} param0.parentCommentId The parent comment ID
|
|
8240
|
-
* @returns {Object} The new comment object
|
|
8241
8576
|
*/
|
|
8242
8577
|
const _getNewcomment = ({ selection, documentId, parentCommentId, ...options }) => {
|
|
8243
8578
|
let activeDocument;
|
|
8244
|
-
if (documentId) activeDocument =
|
|
8245
|
-
else if (selection) activeDocument =
|
|
8579
|
+
if (documentId) activeDocument = findDocument(documentId);
|
|
8580
|
+
else if (selection) activeDocument = findDocument(selection.documentId);
|
|
8246
8581
|
if (!activeDocument) activeDocument = superdocStore.documents[0];
|
|
8247
8582
|
return useComment({
|
|
8248
8583
|
fileId: activeDocument.id,
|
|
@@ -8259,8 +8594,6 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8259
8594
|
};
|
|
8260
8595
|
/**
|
|
8261
8596
|
* Remove the pending comment
|
|
8262
|
-
*
|
|
8263
|
-
* @returns {void}
|
|
8264
8597
|
*/
|
|
8265
8598
|
const resetPendingCommentState = (superdoc, clearViewingSelection = true) => {
|
|
8266
8599
|
const hadPending = !!pendingComment.value;
|
|
@@ -8276,7 +8609,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8276
8609
|
} catch {}
|
|
8277
8610
|
return;
|
|
8278
8611
|
}
|
|
8279
|
-
superdoc?.activeEditor?.commands?.removeComment({ commentId: "pending" });
|
|
8612
|
+
superdoc?.activeEditor?.commands?.removeComment?.({ commentId: "pending" });
|
|
8280
8613
|
};
|
|
8281
8614
|
const removePendingComment = (superdoc) => {
|
|
8282
8615
|
pendingCommentRequest += 1;
|
|
@@ -8289,14 +8622,6 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8289
8622
|
};
|
|
8290
8623
|
/**
|
|
8291
8624
|
* Add a new comment to the document
|
|
8292
|
-
*
|
|
8293
|
-
* @param {Object} param0
|
|
8294
|
-
* @param {Object} param0.superdoc The SuperDoc instance
|
|
8295
|
-
* @param {ReturnType<typeof useComment>} param0.comment The comment to add
|
|
8296
|
-
* @param {boolean} [param0.skipEditorUpdate] Skip writing the comment into the editor
|
|
8297
|
-
* @param {boolean} [param0.broadcastChanges] Emit and sync the change
|
|
8298
|
-
* @param {boolean} [param0.isHydration] The comment comes from import or collaboration
|
|
8299
|
-
* @returns {{ ok: boolean, reason?: string, detail?: string, code?: string } | Promise<{ ok: boolean, reason?: string, detail?: string, code?: string }>} The mutation outcome
|
|
8300
8625
|
*/
|
|
8301
8626
|
const addCommentInternal = ({ superdoc, comment, skipEditorUpdate = false, broadcastChanges = true, isHydration = false }) => {
|
|
8302
8627
|
if (commentsAreReadOnly() && !isHydration) return readOnlyMutationOutcome();
|
|
@@ -8326,7 +8651,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8326
8651
|
return {
|
|
8327
8652
|
ok: false,
|
|
8328
8653
|
reason: "adapter-threw",
|
|
8329
|
-
detail:
|
|
8654
|
+
detail: errorDetail(err)
|
|
8330
8655
|
};
|
|
8331
8656
|
}
|
|
8332
8657
|
})().then((outcome) => {
|
|
@@ -8398,7 +8723,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8398
8723
|
activeComment.value = newComment.commentId;
|
|
8399
8724
|
setActiveFloatingCommentInstance(newComment.commentId);
|
|
8400
8725
|
}
|
|
8401
|
-
if (!skipEditorUpdate && !comment.trackedChange && superdoc.activeEditor?.commands && !comment.parentCommentId) superdoc.activeEditor.commands.insertComment({
|
|
8726
|
+
if (!skipEditorUpdate && !comment.trackedChange && superdoc.activeEditor?.commands && !comment.parentCommentId) superdoc.activeEditor.commands.insertComment?.({
|
|
8402
8727
|
...newComment.getValues(),
|
|
8403
8728
|
skipEmit: true
|
|
8404
8729
|
});
|
|
@@ -8446,7 +8771,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8446
8771
|
return {
|
|
8447
8772
|
ok: false,
|
|
8448
8773
|
reason: "adapter-threw",
|
|
8449
|
-
detail:
|
|
8774
|
+
detail: errorDetail(err)
|
|
8450
8775
|
};
|
|
8451
8776
|
}
|
|
8452
8777
|
})().then((outcome) => {
|
|
@@ -8466,16 +8791,16 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8466
8791
|
});
|
|
8467
8792
|
return outcome;
|
|
8468
8793
|
}
|
|
8469
|
-
const removedIds = new Set((Array.isArray(outcome.removedCommentIds) ? outcome.removedCommentIds : []).map(normalizeCommentId).filter(
|
|
8470
|
-
if (removedIds.has(normalizeCommentId(commentId))) {
|
|
8471
|
-
if (importedId != null) removedIds.add(
|
|
8794
|
+
const removedIds = new Set((Array.isArray(outcome.removedCommentIds) ? outcome.removedCommentIds : []).map(normalizeCommentId).filter(isPresent));
|
|
8795
|
+
if (removedIds.has(normalizeCommentId(commentId) ?? "")) {
|
|
8796
|
+
if (importedId != null) removedIds.add(String(importedId));
|
|
8472
8797
|
let addedChild = true;
|
|
8473
8798
|
while (addedChild) {
|
|
8474
8799
|
addedChild = false;
|
|
8475
8800
|
for (const row of commentsList.value) {
|
|
8476
8801
|
const parentId = normalizeCommentId(row?.parentCommentId);
|
|
8477
8802
|
if (!parentId || !removedIds.has(parentId)) continue;
|
|
8478
|
-
for (const alias of [row?.commentId, row?.importedId].map(normalizeCommentId).filter(
|
|
8803
|
+
for (const alias of [row?.commentId, row?.importedId].map(normalizeCommentId).filter(isPresent)) {
|
|
8479
8804
|
if (removedIds.has(alias)) continue;
|
|
8480
8805
|
removedIds.add(alias);
|
|
8481
8806
|
addedChild = true;
|
|
@@ -8483,9 +8808,9 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8483
8808
|
}
|
|
8484
8809
|
}
|
|
8485
8810
|
commentsList.value = commentsList.value.filter((row) => {
|
|
8486
|
-
return ![row?.commentId, row?.importedId].map(normalizeCommentId).filter(
|
|
8811
|
+
return ![row?.commentId, row?.importedId].map(normalizeCommentId).filter(isPresent).some((alias) => removedIds.has(alias));
|
|
8487
8812
|
});
|
|
8488
|
-
if (removedIds.has(normalizeCommentId(activeComment.value))) clearActiveCommentSelection();
|
|
8813
|
+
if (removedIds.has(normalizeCommentId(activeComment.value) ?? "")) clearActiveCommentSelection();
|
|
8489
8814
|
} else reconcileCommentsFromV2({
|
|
8490
8815
|
superdoc,
|
|
8491
8816
|
adapter: v2Adapter,
|
|
@@ -8493,18 +8818,18 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8493
8818
|
items: outcome.items ?? [],
|
|
8494
8819
|
pruneStale: outcome.complete !== false
|
|
8495
8820
|
});
|
|
8821
|
+
const payload = comment.getValues();
|
|
8496
8822
|
superdoc.emit("comments-update", {
|
|
8497
8823
|
type: COMMENT_EVENTS.DELETED,
|
|
8498
|
-
comment:
|
|
8499
|
-
changes: [{
|
|
8500
|
-
key: "deleted",
|
|
8824
|
+
comment: payload,
|
|
8825
|
+
changes: getDeletedCommentChanges([{
|
|
8501
8826
|
commentId,
|
|
8502
|
-
|
|
8503
|
-
}]
|
|
8827
|
+
importedId
|
|
8828
|
+
}, payload], fileId)
|
|
8504
8829
|
});
|
|
8505
8830
|
return { ok: true };
|
|
8506
8831
|
});
|
|
8507
|
-
superdoc.activeEditor?.commands?.removeComment({
|
|
8832
|
+
superdoc.activeEditor?.commands?.removeComment?.({
|
|
8508
8833
|
commentId,
|
|
8509
8834
|
importedId
|
|
8510
8835
|
});
|
|
@@ -8512,14 +8837,14 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8512
8837
|
const childCommentIds = commentsList.value.filter((c) => c.parentCommentId === commentId).map((c) => c.commentId || c.importedId);
|
|
8513
8838
|
commentsList.value = commentsList.value.filter((c) => !childCommentIds.includes(c.commentId));
|
|
8514
8839
|
if (activeComment.value === commentId || childCommentIds.includes(activeComment.value)) clearActiveCommentSelection();
|
|
8840
|
+
const payload = comment.getValues();
|
|
8515
8841
|
const event = {
|
|
8516
8842
|
type: COMMENT_EVENTS.DELETED,
|
|
8517
|
-
comment:
|
|
8518
|
-
changes: [{
|
|
8519
|
-
key: "deleted",
|
|
8843
|
+
comment: payload,
|
|
8844
|
+
changes: getDeletedCommentChanges([{
|
|
8520
8845
|
commentId,
|
|
8521
|
-
|
|
8522
|
-
}]
|
|
8846
|
+
importedId
|
|
8847
|
+
}, payload], fileId)
|
|
8523
8848
|
};
|
|
8524
8849
|
superdoc.emit("comments-update", event);
|
|
8525
8850
|
syncCommentsToClients(superdoc, event);
|
|
@@ -8531,7 +8856,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8531
8856
|
* otherwise keep the source bubble after the document comment is gone.
|
|
8532
8857
|
*/
|
|
8533
8858
|
const dropCommentsFromMutationImpact = ({ superdoc, documentId, removedIds } = {}) => {
|
|
8534
|
-
const seedIds = new Set([...removedIds instanceof Set ? removedIds : removedIds ?? []].map((id) => normalizeCommentId(id)).filter(
|
|
8859
|
+
const seedIds = new Set([...removedIds instanceof Set ? removedIds : removedIds ?? []].map((id) => normalizeCommentId(id)).filter(isPresent));
|
|
8535
8860
|
if (!seedIds.size) return {
|
|
8536
8861
|
ok: true,
|
|
8537
8862
|
removedIds: []
|
|
@@ -8555,7 +8880,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8555
8880
|
if (!isDroppableCommentRow(row)) continue;
|
|
8556
8881
|
const aliases = getCommentAliasIds(row);
|
|
8557
8882
|
const alreadyDropped = aliases.some((alias) => droppedIds.has(alias));
|
|
8558
|
-
const parentDropped = droppedIds.has(normalizeCommentId(row?.parentCommentId)) || droppedIds.has(normalizeCommentId(row?.threadingParentCommentId));
|
|
8883
|
+
const parentDropped = droppedIds.has(normalizeCommentId(row?.parentCommentId) ?? "") || droppedIds.has(normalizeCommentId(row?.threadingParentCommentId) ?? "");
|
|
8559
8884
|
if (!alreadyDropped && !parentDropped) continue;
|
|
8560
8885
|
for (const alias of aliases) {
|
|
8561
8886
|
if (droppedIds.has(alias)) continue;
|
|
@@ -8583,11 +8908,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8583
8908
|
const event = {
|
|
8584
8909
|
type: COMMENT_EVENTS.DELETED,
|
|
8585
8910
|
comment: payload,
|
|
8586
|
-
changes: [
|
|
8587
|
-
key: "deleted",
|
|
8588
|
-
commentId: payload?.commentId,
|
|
8589
|
-
fileId: payload?.fileId
|
|
8590
|
-
}]
|
|
8911
|
+
changes: getDeletedCommentChanges([payload, comment], payload?.fileId)
|
|
8591
8912
|
};
|
|
8592
8913
|
superdoc?.emit?.("comments-update", event);
|
|
8593
8914
|
});
|
|
@@ -8609,7 +8930,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8609
8930
|
const byAlias = /* @__PURE__ */ new Map();
|
|
8610
8931
|
const childrenByParentAlias = /* @__PURE__ */ new Map();
|
|
8611
8932
|
for (const row of rows) {
|
|
8612
|
-
for (const alias of [row.commentId, row.importedId].map(normalizeCommentId).filter(
|
|
8933
|
+
for (const alias of [row.commentId, row.importedId].map(normalizeCommentId).filter(isPresent)) if (!byAlias.has(alias)) byAlias.set(alias, row);
|
|
8613
8934
|
const parentId = normalizeCommentId(row.parentCommentId);
|
|
8614
8935
|
if (parentId) {
|
|
8615
8936
|
const children = childrenByParentAlias.get(parentId) ?? [];
|
|
@@ -8636,7 +8957,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8636
8957
|
if (!row || visited.has(row)) continue;
|
|
8637
8958
|
visited.add(row);
|
|
8638
8959
|
family.push(row);
|
|
8639
|
-
for (const alias of [row.commentId, row.importedId].map(normalizeCommentId).filter(
|
|
8960
|
+
for (const alias of [row.commentId, row.importedId].map(normalizeCommentId).filter(isPresent)) queue.push(...childrenByParentAlias.get(alias) ?? []);
|
|
8640
8961
|
}
|
|
8641
8962
|
const isResolved = status === "resolved";
|
|
8642
8963
|
const resolvedAt = Date.now();
|
|
@@ -8659,7 +8980,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8659
8980
|
outcome = {
|
|
8660
8981
|
ok: false,
|
|
8661
8982
|
reason: "adapter-threw",
|
|
8662
|
-
detail:
|
|
8983
|
+
detail: errorDetail(err)
|
|
8663
8984
|
};
|
|
8664
8985
|
}
|
|
8665
8986
|
if (!isCurrentV2CommentsAdapter(adapter)) return {
|
|
@@ -8731,14 +9052,14 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8731
9052
|
return (outcome.items ?? []).map((item) => adapter.mapV2CommentToUseCommentInput(item, {
|
|
8732
9053
|
fileId,
|
|
8733
9054
|
fileType: null
|
|
8734
|
-
})).filter(
|
|
9055
|
+
})).filter(isPresent);
|
|
8735
9056
|
};
|
|
8736
9057
|
const isBlankDirectoryCommentText = (value) => typeof value !== "string" || value.replace(/<[^>]*>/g, "").replace(/ /gi, " ").trim().length === 0;
|
|
8737
9058
|
const trackedChangeDirectoryComment = (params) => {
|
|
8738
9059
|
if (!params || params.event === "omit" || params.changeId == null) return null;
|
|
8739
9060
|
return getPendingComment({
|
|
8740
9061
|
documentId: params.documentId,
|
|
8741
|
-
commentId: params.changeId,
|
|
9062
|
+
commentId: String(params.changeId),
|
|
8742
9063
|
trackedChange: true,
|
|
8743
9064
|
trackedChangeText: params.trackedChangeText,
|
|
8744
9065
|
trackedChangeType: params.trackedChangeType,
|
|
@@ -8785,7 +9106,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8785
9106
|
const mappedCommentInputs = commentItems.filter((item) => !isSyntheticTrackedChangeCommentLaneItem(item)).map((item) => commentsAdapter.mapV2CommentToUseCommentInput(item, {
|
|
8786
9107
|
fileId: documentId,
|
|
8787
9108
|
fileType: document?.type ?? null
|
|
8788
|
-
})).filter(
|
|
9109
|
+
})).filter(isPresent);
|
|
8789
9110
|
const trackedParentBySidecarId = /* @__PURE__ */ new Map();
|
|
8790
9111
|
for (const input of mappedCommentInputs) if (input.trackedChange !== true && input.trackedChangeThreadParentId && !input.parentCommentId && isBlankDirectoryCommentText(input.commentText)) trackedParentBySidecarId.set(String(input.commentId), String(input.trackedChangeThreadParentId));
|
|
8791
9112
|
const commentRows = mappedCommentInputs.filter((input) => !trackedParentBySidecarId.has(String(input.commentId))).map((input) => {
|
|
@@ -8796,7 +9117,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8796
9117
|
}
|
|
8797
9118
|
return useComment(input);
|
|
8798
9119
|
});
|
|
8799
|
-
const trackedRows = trackedChangeItems.map((item) => trackedChangesAdapter.mapV2TrackedChangeToCommentParams(item)).map((params) => trackedChangeDirectoryComment(params)).filter(
|
|
9120
|
+
const trackedRows = trackedChangeItems.map((item) => trackedChangesAdapter.mapV2TrackedChangeToCommentParams(item)).map((params) => trackedChangeDirectoryComment(params)).filter(isPresent);
|
|
8800
9121
|
reviewDirectoryList.value = [...commentRows, ...trackedRows];
|
|
8801
9122
|
return {
|
|
8802
9123
|
ok: true,
|
|
@@ -8877,13 +9198,6 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8877
9198
|
* - successful mutation refreshes from v2 list and reconciles
|
|
8878
9199
|
* - rejection preserves rows and emits a rejected `comments-update` event
|
|
8879
9200
|
* - committed-but-refresh-failed surfaces honestly (no reconcile with `[]`)
|
|
8880
|
-
*
|
|
8881
|
-
* @param {Object} [param0]
|
|
8882
|
-
* @param {Object} [param0.superdoc] The SuperDoc instance.
|
|
8883
|
-
* @param {string | null} [param0.parentCommentId] The comment or tracked-change row being replied to.
|
|
8884
|
-
* @param {string} [param0.text] The reply text.
|
|
8885
|
-
* @param {Array<{ name?: string | null, email?: string | null }>} [param0.mentions] Users mentioned in the reply.
|
|
8886
|
-
* @param {{ kind: 'trackedChange', trackedChangeId: string, story?: unknown, side?: import('./helpers/tracked-change-thread-index.js').TrackedChangeSideGroup }} [param0.trackedChangeTarget] The tracked change a first reply anchors to.
|
|
8887
9201
|
*/
|
|
8888
9202
|
const replyCommentV2 = async ({ superdoc, parentCommentId, text, mentions = [], trackedChangeTarget } = {}) => {
|
|
8889
9203
|
if (commentsAreReadOnly()) return readOnlyMutationOutcome();
|
|
@@ -9158,7 +9472,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9158
9472
|
row?.threadingParentCommentId,
|
|
9159
9473
|
row?.trackedChangeParentId,
|
|
9160
9474
|
row?.trackedChangeThreadParentId
|
|
9161
|
-
].map((value) => normalizeCommentId(value)).filter(
|
|
9475
|
+
].map((value) => normalizeCommentId(value)).filter(isPresent));
|
|
9162
9476
|
/** Keep one mounted review window plus rows whose interaction is still live. */
|
|
9163
9477
|
const boundReviewPresentationRows = ({ documentId, visibleIds }) => {
|
|
9164
9478
|
const currentRows = commentsList.value;
|
|
@@ -9179,7 +9493,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9179
9493
|
pendingComment.value?.commentId,
|
|
9180
9494
|
instantSidebarAlignmentThreadId.value,
|
|
9181
9495
|
instantSidebarAlignmentInstanceId.value
|
|
9182
|
-
].map((value) => normalizeCommentId(value)).filter(
|
|
9496
|
+
].map((value) => normalizeCommentId(value)).filter(isPresent));
|
|
9183
9497
|
let changed = true;
|
|
9184
9498
|
while (changed) {
|
|
9185
9499
|
changed = false;
|
|
@@ -9247,7 +9561,8 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9247
9561
|
if (preparedReview?.reuseCatalog === true && committedReviewPresentations.value[normalizedDocumentId]) {
|
|
9248
9562
|
const previous = committedReviewPresentations.value[normalizedDocumentId];
|
|
9249
9563
|
const next = preparedReview.presentation;
|
|
9250
|
-
|
|
9564
|
+
const catalogVersion = preparedReview.catalogVersion ?? NaN;
|
|
9565
|
+
if (!next || !Number.isSafeInteger(catalogVersion) || catalogVersion < 1 || (previous.catalogVersion ?? 0) > catalogVersion || next.catalogVersion !== preparedReview.catalogVersion || previous.coordinate?.documentEpoch !== next.coordinate?.documentEpoch || previous.coordinate?.mountId !== next.coordinate?.mountId || next.coordinate?.reviewVersion <= previous.coordinate?.reviewVersion || next.coordinate?.commitSequence < previous.coordinate?.commitSequence) return {
|
|
9251
9566
|
ok: false,
|
|
9252
9567
|
reason: "review-catalog-stale"
|
|
9253
9568
|
};
|
|
@@ -9293,8 +9608,8 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9293
9608
|
previousPresentation.updateContext = presentation.updateContext;
|
|
9294
9609
|
return {
|
|
9295
9610
|
ok: true,
|
|
9296
|
-
commentItems: preparedReview
|
|
9297
|
-
trackedItems: preparedReview
|
|
9611
|
+
commentItems: preparedReview?.comments.length,
|
|
9612
|
+
trackedItems: preparedReview?.trackedChanges.length
|
|
9298
9613
|
};
|
|
9299
9614
|
}
|
|
9300
9615
|
let effectiveCommentItems = commentItems;
|
|
@@ -9308,7 +9623,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9308
9623
|
reason: seeded?.reason ?? "comment-catalog-seed-failed"
|
|
9309
9624
|
};
|
|
9310
9625
|
const selected = commentsAdapter.selectVisibleReviewComments?.();
|
|
9311
|
-
if (selected?.ok === true && Array.isArray(selected.items) && (!Array.isArray(selected.unresolvedIds) || selected.unresolvedIds.length === 0)) effectiveCommentItems = selected.items;
|
|
9626
|
+
if (!isThenable$1(selected) && selected?.ok === true && Array.isArray(selected.items) && (!Array.isArray(selected.unresolvedIds) || selected.unresolvedIds.length === 0)) effectiveCommentItems = selected.items;
|
|
9312
9627
|
}
|
|
9313
9628
|
const fileType = (normalizedDocumentId ? superdocStore.getDocument(normalizedDocumentId) : null)?.type ?? null;
|
|
9314
9629
|
let preparedInputs;
|
|
@@ -9325,16 +9640,16 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9325
9640
|
})) : effectiveCommentItems.filter((item) => !isSyntheticTrackedChangeCommentLaneItem(item)).map((item) => commentsAdapter.mapV2CommentToUseCommentInput(item, {
|
|
9326
9641
|
fileId: normalizedDocumentId,
|
|
9327
9642
|
fileType
|
|
9328
|
-
})).filter(
|
|
9643
|
+
})).filter(isPresent);
|
|
9329
9644
|
preparedParams = preparedReview ? preparedReview.trackedChanges.map((params) => ({
|
|
9330
9645
|
...params,
|
|
9331
9646
|
documentId: normalizedDocumentId
|
|
9332
|
-
})) : trackedChangeItems.map((item) => trackedChangesAdapter.mapV2TrackedChangeToCommentParams(item)).filter(
|
|
9647
|
+
})) : trackedChangeItems.map((item) => trackedChangesAdapter.mapV2TrackedChangeToCommentParams(item)).filter(isPresent);
|
|
9333
9648
|
} catch (error) {
|
|
9334
9649
|
return {
|
|
9335
9650
|
ok: false,
|
|
9336
9651
|
reason: "mapper-failed",
|
|
9337
|
-
detail:
|
|
9652
|
+
detail: errorDetail(error)
|
|
9338
9653
|
};
|
|
9339
9654
|
}
|
|
9340
9655
|
if (typeof patch !== "function") return {
|
|
@@ -9362,7 +9677,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9362
9677
|
params?.trackedChangeCanonicalId,
|
|
9363
9678
|
params?.trackedChangeAnchorKey
|
|
9364
9679
|
])
|
|
9365
|
-
].map((value) => normalizeCommentId(value)).filter(
|
|
9680
|
+
].map((value) => normalizeCommentId(value)).filter(isPresent));
|
|
9366
9681
|
patch(() => {
|
|
9367
9682
|
const previousPreparedPresentation = committedReviewPresentations.value[normalizedDocumentId] ?? null;
|
|
9368
9683
|
if (preparedReview?.presentation) committedReviewPresentations.value = {
|
|
@@ -9410,7 +9725,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9410
9725
|
};
|
|
9411
9726
|
const effectiveDocumentId = documentId ?? adapter.documentId ?? null;
|
|
9412
9727
|
const normalizedEffectiveDocumentId = effectiveDocumentId != null ? String(effectiveDocumentId) : null;
|
|
9413
|
-
const fileType = (effectiveDocumentId ?
|
|
9728
|
+
const fileType = (effectiveDocumentId ? findDocument(effectiveDocumentId) : null)?.type ?? null;
|
|
9414
9729
|
const isBlankV2CommentText = (value) => {
|
|
9415
9730
|
if (typeof value !== "string") return true;
|
|
9416
9731
|
return value.replace(/<[^>]*>/g, "").replace(/ /gi, " ").trim().length === 0;
|
|
@@ -9430,7 +9745,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9430
9745
|
const candidateInputs = Array.isArray(preparedInputs) ? preparedInputs : items.filter((item) => !isSyntheticTrackedChangeCommentLaneItem(item)).map((item) => adapter.mapV2CommentToUseCommentInput(item, {
|
|
9431
9746
|
fileId: effectiveDocumentId,
|
|
9432
9747
|
fileType
|
|
9433
|
-
})).filter(
|
|
9748
|
+
})).filter(isPresent);
|
|
9434
9749
|
for (const input of candidateInputs) {
|
|
9435
9750
|
if (isV2TrackedChangeSidecarCommentInput(input)) {
|
|
9436
9751
|
trackedChangeSidecarParentByCommentId.set(String(input.commentId), String(input.trackedChangeThreadParentId));
|
|
@@ -9483,7 +9798,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9483
9798
|
existing.mentions = Array.isArray(input.mentions) ? input.mentions : [];
|
|
9484
9799
|
existing.isInternal = typeof input.isInternal === "boolean" ? input.isInternal : existing.isInternal;
|
|
9485
9800
|
if (typeof input.resolvedTime === "number") {
|
|
9486
|
-
existing.resolvedTime = input.resolvedTimeWasSynthesized === true && typeof existing.resolvedTime === "number" ? existing.resolvedTime : input.resolvedTime;
|
|
9801
|
+
existing.resolvedTime = input.resolvedTimeWasSynthesized === true && typeof existing.resolvedTime === "number" ? existing.resolvedTime : input.resolvedTime ?? null;
|
|
9487
9802
|
existing.resolvedByEmail = input.resolvedByEmail ?? null;
|
|
9488
9803
|
existing.resolvedByName = input.resolvedByName ?? null;
|
|
9489
9804
|
} else {
|
|
@@ -9557,7 +9872,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9557
9872
|
return {
|
|
9558
9873
|
ok: false,
|
|
9559
9874
|
reason: "comment-read-failed",
|
|
9560
|
-
detail:
|
|
9875
|
+
detail: errorDetail(err)
|
|
9561
9876
|
};
|
|
9562
9877
|
}
|
|
9563
9878
|
if (!isCurrentV2CommentsAdapter(adapter)) return {
|
|
@@ -9583,8 +9898,6 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9583
9898
|
};
|
|
9584
9899
|
/**
|
|
9585
9900
|
* Cancel the pending comment
|
|
9586
|
-
*
|
|
9587
|
-
* @returns {void}
|
|
9588
9901
|
*/
|
|
9589
9902
|
const cancelComment = (superdoc) => {
|
|
9590
9903
|
removePendingComment(superdoc);
|
|
@@ -9594,9 +9907,6 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9594
9907
|
*
|
|
9595
9908
|
* Replace-file swaps call this before hydrating the replacement so stale
|
|
9596
9909
|
* comments never survive long enough to render beside the new content.
|
|
9597
|
-
*
|
|
9598
|
-
* @param {string | null | undefined} documentId
|
|
9599
|
-
* @returns {void}
|
|
9600
9910
|
*/
|
|
9601
9911
|
function removeCommentsForDocument(documentId) {
|
|
9602
9912
|
const activeDocumentId = documentId != null ? String(documentId) : null;
|
|
@@ -9623,139 +9933,20 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9623
9933
|
const activeCommentId = activeComment.value != null ? String(activeComment.value) : null;
|
|
9624
9934
|
if (activeCommentId && removedAliasIds.has(activeCommentId)) clearActiveCommentSelection();
|
|
9625
9935
|
}
|
|
9626
|
-
const
|
|
9627
|
-
if (!comment) return null;
|
|
9628
|
-
if (comment.fileId != null) return String(comment.fileId);
|
|
9629
|
-
if (comment.documentId != null) return String(comment.documentId);
|
|
9630
|
-
if (comment.selection?.documentId != null) return String(comment.selection.documentId);
|
|
9631
|
-
return null;
|
|
9632
|
-
};
|
|
9633
|
-
const getOpenDocuments = () => {
|
|
9634
|
-
const docs = Array.isArray(superdocStore.documents) ? superdocStore.documents : superdocStore.documents?.value;
|
|
9635
|
-
return Array.isArray(docs) ? docs : [];
|
|
9636
|
-
};
|
|
9637
|
-
const getSingleOpenDocumentId = () => {
|
|
9638
|
-
const docs = getOpenDocuments();
|
|
9639
|
-
if (docs.length !== 1) return null;
|
|
9640
|
-
return docs[0]?.id != null ? String(docs[0].id) : null;
|
|
9641
|
-
};
|
|
9642
|
-
const belongsToDocument = (comment, activeDocumentId, options = {}) => {
|
|
9643
|
-
const { allowSingleDocumentMismatch = false } = options;
|
|
9644
|
-
if (!activeDocumentId) return false;
|
|
9645
|
-
const commentDocumentId = getCommentDocumentId(comment);
|
|
9646
|
-
if (commentDocumentId) {
|
|
9647
|
-
if (commentDocumentId === activeDocumentId) return true;
|
|
9648
|
-
const singleOpenDocumentId = getSingleOpenDocumentId();
|
|
9649
|
-
return allowSingleDocumentMismatch && singleOpenDocumentId === activeDocumentId;
|
|
9650
|
-
}
|
|
9651
|
-
return getSingleOpenDocumentId() === activeDocumentId;
|
|
9652
|
-
};
|
|
9653
|
-
const belongsToTrackedChangeSyncDocument = (comment, activeDocumentId) => {
|
|
9654
|
-
return belongsToDocument(comment, activeDocumentId, { allowSingleDocumentMismatch: true });
|
|
9655
|
-
};
|
|
9656
|
-
const normalizeTrackedChangeDecisionType = (value) => {
|
|
9657
|
-
const lower = typeof value === "string" ? value.toLowerCase() : "";
|
|
9658
|
-
if (!lower) return null;
|
|
9659
|
-
if (lower === "insert" || lower === "insertion" || lower === "trackinsert" || lower === "tableinsert" || lower === "paragraphsplit") return "insertion";
|
|
9660
|
-
if (lower === "delete" || lower === "deletion" || lower === "trackdelete" || lower === "tabledelete") return "deletion";
|
|
9661
|
-
return lower;
|
|
9662
|
-
};
|
|
9663
|
-
const trackedChangeDecisionKeepsCommentAnchor = ({ comment, decision } = {}) => {
|
|
9664
|
-
const normalizedDecision = decision === "accept" || decision === "reject" ? decision : null;
|
|
9665
|
-
if (!normalizedDecision) return false;
|
|
9666
|
-
const type = normalizeTrackedChangeDecisionType(comment?.trackedChangeDisplayType) ?? normalizeTrackedChangeDecisionType(comment?.trackedChangeType);
|
|
9667
|
-
return normalizedDecision === "accept" && type === "insertion" || normalizedDecision === "reject" && type === "deletion";
|
|
9668
|
-
};
|
|
9669
|
-
const getBodyTrackedChangeIdentityIds = (comment) => {
|
|
9670
|
-
return [normalizeCommentId(comment.commentId), ...!normalizeCommentId(comment.trackedChangeCanonicalId) ? [
|
|
9671
|
-
comment.importedId,
|
|
9672
|
-
comment.trackedChangeAnchorKey,
|
|
9673
|
-
...normalizeTrackedChangePositionAliases(comment.trackedChangePositionAliases)
|
|
9674
|
-
] : []].map((id) => normalizeCommentId(id)).filter(Boolean);
|
|
9675
|
-
};
|
|
9676
|
-
const groupBodyTrackedChangeCommentsByIdentity = (comments) => {
|
|
9677
|
-
const parents = comments.map((_, index) => index);
|
|
9678
|
-
const findRoot = (index) => {
|
|
9679
|
-
let root = index;
|
|
9680
|
-
while (parents[root] !== root) root = parents[root];
|
|
9681
|
-
while (parents[index] !== index) {
|
|
9682
|
-
const next = parents[index];
|
|
9683
|
-
parents[index] = root;
|
|
9684
|
-
index = next;
|
|
9685
|
-
}
|
|
9686
|
-
return root;
|
|
9687
|
-
};
|
|
9688
|
-
const join = (left, right) => {
|
|
9689
|
-
const leftRoot = findRoot(left);
|
|
9690
|
-
const rightRoot = findRoot(right);
|
|
9691
|
-
if (leftRoot === rightRoot) return;
|
|
9692
|
-
parents[Math.max(leftRoot, rightRoot)] = Math.min(leftRoot, rightRoot);
|
|
9693
|
-
};
|
|
9694
|
-
const identityOwner = /* @__PURE__ */ new Map();
|
|
9695
|
-
comments.forEach((comment, index) => {
|
|
9696
|
-
getBodyTrackedChangeIdentityIds(comment).forEach((identityId) => {
|
|
9697
|
-
const owner = identityOwner.get(identityId);
|
|
9698
|
-
if (owner === void 0) identityOwner.set(identityId, index);
|
|
9699
|
-
else join(index, owner);
|
|
9700
|
-
});
|
|
9701
|
-
});
|
|
9702
|
-
const groups = /* @__PURE__ */ new Map();
|
|
9703
|
-
comments.forEach((comment, index) => {
|
|
9704
|
-
const root = findRoot(index);
|
|
9705
|
-
const group = groups.get(root) ?? [];
|
|
9706
|
-
group.push(comment);
|
|
9707
|
-
groups.set(root, group);
|
|
9708
|
-
});
|
|
9709
|
-
return groups;
|
|
9710
|
-
};
|
|
9711
|
-
const mergeDuplicateBodyTrackedChangeComments = (groups) => {
|
|
9712
|
-
const duplicates = /* @__PURE__ */ new Map();
|
|
9713
|
-
groups.forEach(([survivor, ...duplicateRows]) => {
|
|
9714
|
-
if (!survivor || duplicateRows.length === 0) return;
|
|
9715
|
-
const resolvedDuplicate = duplicateRows.find((comment) => comment.resolvedTime != null);
|
|
9716
|
-
if (survivor.resolvedTime == null && resolvedDuplicate) {
|
|
9717
|
-
survivor.resolvedTime = resolvedDuplicate.resolvedTime;
|
|
9718
|
-
survivor.resolvedById = resolvedDuplicate.resolvedById;
|
|
9719
|
-
survivor.resolvedByEmail = resolvedDuplicate.resolvedByEmail;
|
|
9720
|
-
survivor.resolvedByName = resolvedDuplicate.resolvedByName;
|
|
9721
|
-
survivor.trackedChangeDecision = resolvedDuplicate.trackedChangeDecision;
|
|
9722
|
-
}
|
|
9723
|
-
survivor.trackedChangePositionAliases = normalizeTrackedChangePositionAliases([...normalizeTrackedChangePositionAliases(survivor.trackedChangePositionAliases), ...duplicateRows.flatMap((comment) => [
|
|
9724
|
-
comment.commentId,
|
|
9725
|
-
comment.importedId,
|
|
9726
|
-
comment.trackedChangeCanonicalId,
|
|
9727
|
-
...normalizeTrackedChangePositionAliases(comment.trackedChangePositionAliases)
|
|
9728
|
-
])]);
|
|
9729
|
-
duplicateRows.forEach((comment) => duplicates.set(comment, survivor));
|
|
9730
|
-
});
|
|
9731
|
-
return duplicates;
|
|
9732
|
-
};
|
|
9733
|
-
const createDroppedCommentIdMap = (duplicates) => {
|
|
9734
|
-
const droppedCommentIds = /* @__PURE__ */ new Map();
|
|
9735
|
-
duplicates.forEach((survivor, duplicate) => {
|
|
9736
|
-
const fromId = normalizeCommentId(duplicate.commentId);
|
|
9737
|
-
const toId = normalizeCommentId(survivor.commentId);
|
|
9738
|
-
if (fromId && toId) droppedCommentIds.set(fromId, toId);
|
|
9739
|
-
});
|
|
9740
|
-
return droppedCommentIds;
|
|
9741
|
-
};
|
|
9936
|
+
const { belongsToDocument, belongsToTrackedChangeSyncDocument } = createCommentDocumentScope(() => superdocStore.documents);
|
|
9742
9937
|
const remapTrackedChangeReferences = (droppedCommentIds, activeDocumentId) => {
|
|
9743
9938
|
const remapSelection = (selection) => {
|
|
9744
9939
|
const selectedId = normalizeCommentId(selection.value);
|
|
9745
|
-
|
|
9940
|
+
const replacementId = selectedId ? droppedCommentIds.get(selectedId) : void 0;
|
|
9941
|
+
if (replacementId) selection.value = replacementId;
|
|
9746
9942
|
};
|
|
9747
9943
|
remapSelection(activeComment);
|
|
9748
9944
|
remapSelection(activeFloatingCommentInstanceId);
|
|
9749
9945
|
commentsList.value.forEach((row) => {
|
|
9750
9946
|
if (!belongsToTrackedChangeSyncDocument(row, activeDocumentId)) return;
|
|
9751
9947
|
const rowIdentityUpdates = {};
|
|
9752
|
-
for (const field of
|
|
9753
|
-
"
|
|
9754
|
-
"trackedChangeParentId",
|
|
9755
|
-
"threadingParentCommentId",
|
|
9756
|
-
"parentCommentId"
|
|
9757
|
-
]) {
|
|
9758
|
-
const replacementId = droppedCommentIds.get(normalizeCommentId(row?.[field]));
|
|
9948
|
+
for (const field of PARENT_LINK_FIELDS) {
|
|
9949
|
+
const replacementId = droppedCommentIds.get(normalizeCommentId(row?.[field]) ?? "");
|
|
9759
9950
|
if (!replacementId) continue;
|
|
9760
9951
|
row[field] = replacementId;
|
|
9761
9952
|
rowIdentityUpdates[field] = replacementId;
|
|
@@ -9764,9 +9955,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9764
9955
|
});
|
|
9765
9956
|
};
|
|
9766
9957
|
const compactDuplicateBodyTrackedChangeComments = (activeDocumentId) => {
|
|
9767
|
-
const
|
|
9768
|
-
const groups = groupBodyTrackedChangeCommentsByIdentity(candidates);
|
|
9769
|
-
const duplicates = mergeDuplicateBodyTrackedChangeComments(groups);
|
|
9958
|
+
const duplicates = mergeDuplicateBodyTrackedChangeComments(groupBodyTrackedChangeCommentsByIdentity(commentsList.value.filter((comment) => isBodyTrackedChangeComment(comment) && belongsToTrackedChangeSyncDocument(comment, activeDocumentId))));
|
|
9770
9959
|
if (!duplicates.size) return 0;
|
|
9771
9960
|
commentsList.value = commentsList.value.filter((comment) => !duplicates.has(comment));
|
|
9772
9961
|
remapTrackedChangeReferences(createDroppedCommentIdMap(duplicates), activeDocumentId);
|
|
@@ -9778,10 +9967,6 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9778
9967
|
*
|
|
9779
9968
|
* Pruning is scoped to the active editor document so replay in one document does not
|
|
9780
9969
|
* delete tracked-change comments from other open documents.
|
|
9781
|
-
*
|
|
9782
|
-
* @param {Set<string>} liveTrackedChangeIds IDs currently present in editor marks.
|
|
9783
|
-
* @param {string | null} activeDocumentId Document currently being synced.
|
|
9784
|
-
* @returns {void}
|
|
9785
9970
|
*/
|
|
9786
9971
|
const pruneStaleTrackedChangeComments = (liveTrackedChangeIds, liveTrackedChangeAnchorKeys, activeDocumentId, superdoc = null, { broadcastChanges = true } = {}) => withInteractionSpan("store.trackedChanges.pruneStaleComments", "store-reconciliation", {
|
|
9787
9972
|
activeDocumentId: activeDocumentId ?? null,
|
|
@@ -9826,7 +10011,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9826
10011
|
comment: payload
|
|
9827
10012
|
};
|
|
9828
10013
|
if (broadcastChanges) {
|
|
9829
|
-
syncCommentsToClients(superdoc, event);
|
|
10014
|
+
syncCommentsToClients(requireHost(superdoc, "pruneStaleTrackedChangeComments"), event);
|
|
9830
10015
|
superdoc?.emit?.("comments-update", event);
|
|
9831
10016
|
}
|
|
9832
10017
|
});
|
|
@@ -9858,14 +10043,10 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9858
10043
|
const event = {
|
|
9859
10044
|
type: COMMENT_EVENTS.DELETED,
|
|
9860
10045
|
comment: payload,
|
|
9861
|
-
changes: [
|
|
9862
|
-
key: "deleted",
|
|
9863
|
-
commentId: payload.commentId,
|
|
9864
|
-
fileId: payload.fileId
|
|
9865
|
-
}]
|
|
10046
|
+
changes: getDeletedCommentChanges([payload, comment], payload.fileId)
|
|
9866
10047
|
};
|
|
9867
10048
|
if (broadcastChanges) {
|
|
9868
|
-
syncCommentsToClients(superdoc, event);
|
|
10049
|
+
syncCommentsToClients(requireHost(superdoc, "pruneStaleTrackedChangeComments"), event);
|
|
9869
10050
|
superdoc?.emit?.("comments-update", event);
|
|
9870
10051
|
}
|
|
9871
10052
|
});
|
|
@@ -9888,7 +10069,6 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9888
10069
|
const resolveArgs = {
|
|
9889
10070
|
email: superdoc?.user?.email ?? null,
|
|
9890
10071
|
name: superdoc?.user?.name ?? null,
|
|
9891
|
-
superdoc,
|
|
9892
10072
|
reconciliationToken: COMMENT_RECONCILIATION_TOKEN
|
|
9893
10073
|
};
|
|
9894
10074
|
let resolvedCount = 0;
|
|
@@ -9899,27 +10079,18 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9899
10079
|
trackedChangeThreadParentIdForComment(linkedComment),
|
|
9900
10080
|
linkedComment.threadingParentCommentId,
|
|
9901
10081
|
linkedComment.parentCommentId
|
|
9902
|
-
].map((id) => normalizeCommentId(id)).filter(
|
|
10082
|
+
].map((id) => normalizeCommentId(id)).filter(isPresent).some((id) => trackedChangeIds.has(id))) return;
|
|
9903
10083
|
if (typeof linkedComment.resolveComment === "function") {
|
|
9904
|
-
linkedComment.resolveComment(
|
|
10084
|
+
linkedComment.resolveComment({
|
|
10085
|
+
...resolveArgs,
|
|
10086
|
+
superdoc: requireHost(superdoc, "resolveLinkedCommentsForTrackedChangeDecision")
|
|
10087
|
+
});
|
|
9905
10088
|
resolvedCount += 1;
|
|
9906
10089
|
}
|
|
9907
10090
|
});
|
|
9908
10091
|
return resolvedCount;
|
|
9909
10092
|
};
|
|
9910
|
-
const collectTrackedChangeDecisionIds = (comment) =>
|
|
9911
|
-
const trackedChangeIds = new Set(getCommentAliasIds(comment));
|
|
9912
|
-
if (comment?.trackedChangeCanonicalId != null) trackedChangeIds.add(String(comment.trackedChangeCanonicalId));
|
|
9913
|
-
const anchorKey = comment?.trackedChangeAnchorKey != null ? String(comment.trackedChangeAnchorKey) : null;
|
|
9914
|
-
if (anchorKey) {
|
|
9915
|
-
trackedChangeIds.add(anchorKey);
|
|
9916
|
-
if (anchorKey.startsWith("tc::")) {
|
|
9917
|
-
const rawId = anchorKey.slice(anchorKey.lastIndexOf("::") + 2);
|
|
9918
|
-
if (rawId) trackedChangeIds.add(rawId);
|
|
9919
|
-
}
|
|
9920
|
-
}
|
|
9921
|
-
return trackedChangeIds;
|
|
9922
|
-
};
|
|
10093
|
+
const collectTrackedChangeDecisionIds = (comment) => collectTrackedChangeDecisionIdsWithAliases(comment, getCommentAliasIds(comment));
|
|
9923
10094
|
const getTrackedChangeDecisionLinks = (comment) => {
|
|
9924
10095
|
const linked = [];
|
|
9925
10096
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -9930,28 +10101,6 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9930
10101
|
}
|
|
9931
10102
|
return linked;
|
|
9932
10103
|
};
|
|
9933
|
-
const collectTrackedChangeEntityIdsFromReceipt = (receipt) => {
|
|
9934
|
-
const record = receipt && typeof receipt === "object" ? receipt : null;
|
|
9935
|
-
if (!record?.success) return /* @__PURE__ */ new Set();
|
|
9936
|
-
const ids = /* @__PURE__ */ new Set();
|
|
9937
|
-
const collect = (entry) => {
|
|
9938
|
-
const ref = entry && typeof entry === "object" ? entry : null;
|
|
9939
|
-
if (ref?.kind !== "entity" || ref.entityType !== "trackedChange") return;
|
|
9940
|
-
if (ref.entityId != null && String(ref.entityId).length > 0) ids.add(String(ref.entityId));
|
|
9941
|
-
};
|
|
9942
|
-
if (Array.isArray(record.removed)) record.removed.forEach(collect);
|
|
9943
|
-
if (Array.isArray(record.invalidatedRefs)) record.invalidatedRefs.forEach(collect);
|
|
9944
|
-
return ids;
|
|
9945
|
-
};
|
|
9946
|
-
const collectReliableDecidedTrackedChangeIds = (outcome) => {
|
|
9947
|
-
const ids = /* @__PURE__ */ new Set();
|
|
9948
|
-
if (outcome?.decidedId != null && String(outcome.decidedId).length > 0) ids.add(String(outcome.decidedId));
|
|
9949
|
-
if (Array.isArray(outcome?.decidedIds)) outcome.decidedIds.forEach((id) => {
|
|
9950
|
-
if (id != null && String(id).length > 0) ids.add(String(id));
|
|
9951
|
-
});
|
|
9952
|
-
collectTrackedChangeEntityIdsFromReceipt(outcome?.receipt).forEach((id) => ids.add(id));
|
|
9953
|
-
return ids;
|
|
9954
|
-
};
|
|
9955
10104
|
const detachLinkedCommentsForTrackedChangeDecision = ({ comment, decision } = {}) => {
|
|
9956
10105
|
if (!comment?.trackedChange) return 0;
|
|
9957
10106
|
if (!trackedChangeDecisionKeepsCommentAnchor({
|
|
@@ -10032,7 +10181,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
10032
10181
|
if (previousCommentId) anchorSourceIds.add(previousCommentId);
|
|
10033
10182
|
if (previousCanonicalId) anchorSourceIds.add(previousCanonicalId);
|
|
10034
10183
|
}
|
|
10035
|
-
if (comment.trackedChangeAnchorKey == null || anchorSourceIds.has(currentAnchorParts?.rawId)) comment.trackedChangeAnchorKey = toAnchor;
|
|
10184
|
+
if (comment.trackedChangeAnchorKey == null || anchorSourceIds.has(currentAnchorParts?.rawId ?? "")) comment.trackedChangeAnchorKey = toAnchor;
|
|
10036
10185
|
comment.trackedChangePositionAliases = normalizeTrackedChangePositionAliases([...Array.isArray(comment.trackedChangePositionAliases) ? comment.trackedChangePositionAliases : [], fromId]);
|
|
10037
10186
|
const identitySourceIds = /* @__PURE__ */ new Set([fromId]);
|
|
10038
10187
|
if (advancesRemapLineage) {
|
|
@@ -10043,33 +10192,28 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
10043
10192
|
if (row === comment) return;
|
|
10044
10193
|
if (!belongsToTrackedChangeSyncDocument(row, normalizedDocumentId)) return;
|
|
10045
10194
|
const rowIdentityUpdates = {};
|
|
10046
|
-
for (const field of
|
|
10047
|
-
"
|
|
10048
|
-
"trackedChangeParentId",
|
|
10049
|
-
"threadingParentCommentId",
|
|
10050
|
-
"parentCommentId"
|
|
10051
|
-
]) {
|
|
10052
|
-
if (!identitySourceIds.has(normalizeCommentId(row?.[field]))) continue;
|
|
10195
|
+
for (const field of PARENT_LINK_FIELDS) {
|
|
10196
|
+
if (!identitySourceIds.has(normalizeCommentId(row?.[field]) ?? "")) continue;
|
|
10053
10197
|
row[field] = toId;
|
|
10054
10198
|
rowIdentityUpdates[field] = toId;
|
|
10055
10199
|
}
|
|
10056
10200
|
if (Object.keys(rowIdentityUpdates).length && typeof row.updateIdentityValues === "function") row.updateIdentityValues(rowIdentityUpdates);
|
|
10057
10201
|
});
|
|
10058
10202
|
if (Object.keys(commentIdentityUpdates).length && typeof comment.updateIdentityValues === "function") comment.updateIdentityValues(commentIdentityUpdates);
|
|
10059
|
-
const previousEntry = previousPositionEntry ?? [positions[fromId], positions[buildBodyTrackedChangeAnchorKey(fromId)]].find((entry) => entry && positionEntryMatchesTrackedChangeStory(entry, comment));
|
|
10203
|
+
const previousEntry = previousPositionEntry ?? [positions[fromId], positions[String(buildBodyTrackedChangeAnchorKey(fromId))]].find((entry) => entry && positionEntryMatchesTrackedChangeStory(entry, comment));
|
|
10060
10204
|
if (previousEntry) {
|
|
10061
|
-
for (const key of [toId, toAnchor]) if (positions[key] === void 0) {
|
|
10205
|
+
for (const key of [toId, String(toAnchor)]) if (positions[key] === void 0) {
|
|
10062
10206
|
positions[key] = previousEntry;
|
|
10063
10207
|
positionsChanged = true;
|
|
10064
10208
|
}
|
|
10065
10209
|
}
|
|
10066
|
-
if (identitySourceIds.has(normalizeCommentId(activeComment.value))) activeComment.value = toId;
|
|
10067
|
-
if (identitySourceIds.has(normalizeCommentId(activeFloatingCommentInstanceId.value))) activeFloatingCommentInstanceId.value = toId;
|
|
10210
|
+
if (identitySourceIds.has(normalizeCommentId(activeComment.value) ?? "")) activeComment.value = toId;
|
|
10211
|
+
if (identitySourceIds.has(normalizeCommentId(activeFloatingCommentInstanceId.value) ?? "")) activeFloatingCommentInstanceId.value = toId;
|
|
10068
10212
|
}
|
|
10069
10213
|
if (positionsChanged) editorCommentPositions.value = { ...positions };
|
|
10070
10214
|
};
|
|
10071
10215
|
const pruneDecidedTrackedChangeRow = ({ superdoc, comment: targetComment, decidedId, decidedIds, documentId } = {}) => {
|
|
10072
|
-
const normalizedDecidedIds = new Set((Array.isArray(decidedIds) || decidedIds instanceof Set ? Array.from(decidedIds) : [decidedId]).map((id) => normalizeCommentId(id)).filter(
|
|
10216
|
+
const normalizedDecidedIds = new Set((Array.isArray(decidedIds) || decidedIds instanceof Set ? Array.from(decidedIds) : [decidedId]).map((id) => normalizeCommentId(id)).filter(isPresent));
|
|
10073
10217
|
const normalizedDocumentId = normalizeCommentId(documentId);
|
|
10074
10218
|
if (!normalizedDecidedIds.size || !normalizedDocumentId) return {
|
|
10075
10219
|
removed: false,
|
|
@@ -10127,39 +10271,8 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
10127
10271
|
removedIds
|
|
10128
10272
|
};
|
|
10129
10273
|
};
|
|
10130
|
-
const clearV2ActiveTrackedChangeTarget = (adapter, decidedId) => {
|
|
10131
|
-
if (!decidedId || typeof adapter?.clearActiveTrackedChangeTargetIfMatches !== "function") return;
|
|
10132
|
-
try {
|
|
10133
|
-
adapter.clearActiveTrackedChangeTargetIfMatches(decidedId);
|
|
10134
|
-
} catch {}
|
|
10135
|
-
};
|
|
10136
|
-
const waitForTrackedDecisionCanonicalPaint = async ({ superdoc, receipt } = {}) => {
|
|
10137
|
-
const readiness = superdoc?.activeEditor?.documentMutationReadiness;
|
|
10138
|
-
if (receipt?.success !== true || typeof receipt?.txId !== "string" || !receipt.txId || typeof readiness?.whenPainted !== "function") return;
|
|
10139
|
-
try {
|
|
10140
|
-
await readiness.whenPainted(receipt);
|
|
10141
|
-
const requestFrame = globalThis.requestAnimationFrame;
|
|
10142
|
-
if (typeof requestFrame === "function") await new Promise((resolve) => {
|
|
10143
|
-
let settled = false;
|
|
10144
|
-
const finish = () => {
|
|
10145
|
-
if (settled) return;
|
|
10146
|
-
settled = true;
|
|
10147
|
-
clearTimeout(fallback);
|
|
10148
|
-
resolve();
|
|
10149
|
-
};
|
|
10150
|
-
const fallback = setTimeout(finish, 250);
|
|
10151
|
-
requestFrame(() => requestFrame(() => setTimeout(finish, 0)));
|
|
10152
|
-
});
|
|
10153
|
-
} catch {}
|
|
10154
|
-
};
|
|
10155
10274
|
/**
|
|
10156
10275
|
* Accept or reject the tracked change behind a sidebar row.
|
|
10157
|
-
*
|
|
10158
|
-
* @param {Object} param0
|
|
10159
|
-
* @param {Object} param0.superdoc The SuperDoc instance.
|
|
10160
|
-
* @param {Object} param0.comment The tracked-change row.
|
|
10161
|
-
* @param {string} param0.decision `'accept'` or `'reject'`.
|
|
10162
|
-
* @returns {{ ok: boolean, success?: boolean, reason?: string } | Promise<{ ok: boolean, success?: boolean, reason?: string }>} The decision outcome.
|
|
10163
10276
|
*/
|
|
10164
10277
|
const decideTrackedChangeFromSidebar = ({ superdoc, comment, decision }) => {
|
|
10165
10278
|
const disabledReason = trackedChangeDecisionDisabledReason(superdoc);
|
|
@@ -10187,7 +10300,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
10187
10300
|
return {
|
|
10188
10301
|
ok: false,
|
|
10189
10302
|
reason: "adapter-threw",
|
|
10190
|
-
detail:
|
|
10303
|
+
detail: errorDetail(err)
|
|
10191
10304
|
};
|
|
10192
10305
|
}
|
|
10193
10306
|
})().then(async (outcome) => {
|
|
@@ -10240,9 +10353,11 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
10240
10353
|
if (!activeEditor) return { ok: false };
|
|
10241
10354
|
const id = comment.commentId ?? comment.importedId;
|
|
10242
10355
|
if (!id) return { ok: false };
|
|
10243
|
-
const
|
|
10356
|
+
const rawStory = comment.trackedChangeStory ?? void 0;
|
|
10357
|
+
const story = isStoryLocator(rawStory) ? rawStory : void 0;
|
|
10244
10358
|
const documentApi = typeof activeEditor.doc === "object" ? activeEditor.doc : null;
|
|
10245
10359
|
if (documentApi?.trackChanges?.decide) try {
|
|
10360
|
+
if (rawStory && !story) throw new TypeError("trackedChangeStory must be a valid StoryLocator");
|
|
10246
10361
|
const target = story ? {
|
|
10247
10362
|
id,
|
|
10248
10363
|
story
|
|
@@ -10255,7 +10370,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
10255
10370
|
success: Boolean(receipt?.success)
|
|
10256
10371
|
}));
|
|
10257
10372
|
} catch (error) {
|
|
10258
|
-
if (
|
|
10373
|
+
if (rawStory) return {
|
|
10259
10374
|
ok: false,
|
|
10260
10375
|
error
|
|
10261
10376
|
};
|
|
@@ -10302,9 +10417,9 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
10302
10417
|
documentId: effectiveDocumentId
|
|
10303
10418
|
})).removed
|
|
10304
10419
|
};
|
|
10305
|
-
const normalizedRemovedIds = new Set(Array.from(removedIds ?? []).map((id) => normalizeCommentId(id)).filter(
|
|
10306
|
-
const normalizedUpsertIds = [...new Set(Array.from(upsertIds ?? []).map((id) => normalizeCommentId(id)).filter(
|
|
10307
|
-
const remappedSourceIds = new Set((Array.isArray(remappedPairs) ? remappedPairs : []).map((pair) => normalizeCommentId(pair?.from)).filter(
|
|
10420
|
+
const normalizedRemovedIds = new Set(Array.from(removedIds ?? []).map((id) => normalizeCommentId(id)).filter(isPresent));
|
|
10421
|
+
const normalizedUpsertIds = [...new Set(Array.from(upsertIds ?? []).map((id) => normalizeCommentId(id)).filter(isPresent))];
|
|
10422
|
+
const remappedSourceIds = new Set((Array.isArray(remappedPairs) ? remappedPairs : []).map((pair) => normalizeCommentId(pair?.from)).filter(isPresent));
|
|
10308
10423
|
const locallyRemovedIds = new Set([...normalizedRemovedIds].filter((id) => !remappedSourceIds.has(id)));
|
|
10309
10424
|
if (locallyRemovedIds.size > 0 && effectiveDocumentId != null) pruneDecidedTrackedChangeRow({
|
|
10310
10425
|
superdoc,
|
|
@@ -10414,23 +10529,24 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
10414
10529
|
for (const params of paramsList) {
|
|
10415
10530
|
if (!params) continue;
|
|
10416
10531
|
let retainUnchangedRow = false;
|
|
10532
|
+
const anchorParts = parseTrackedChangeAnchorKey(params.trackedChangeAnchorKey);
|
|
10533
|
+
const anchorStoryKey = anchorParts ? normalizeTrackedChangeStoryKey(anchorParts.storyKey) : void 0;
|
|
10417
10534
|
if (preparedPresentation) {
|
|
10418
10535
|
if (preparedPresentation !== committedReviewPresentations.value[String(effectiveDocumentId)]) continue;
|
|
10419
10536
|
if (params.documentId != null && String(params.documentId) !== String(effectiveDocumentId)) continue;
|
|
10420
10537
|
const id = normalizeCommentId(params.changeId);
|
|
10421
|
-
const version = preparedPresentation.rowVersions?.[id];
|
|
10538
|
+
const version = preparedPresentation.rowVersions?.[String(id)] ?? NaN;
|
|
10422
10539
|
if (!id || !Number.isSafeInteger(version) || version < 1) continue;
|
|
10423
10540
|
const existing = [...trackedChangeIdentityIndex.candidates({ changeId: id })].filter((row) => String(row.fileId) === String(effectiveDocumentId) && String(row.commentId) === id);
|
|
10424
10541
|
if (existing.length > 1) continue;
|
|
10425
10542
|
const row = existing[0];
|
|
10426
10543
|
if (row && row.trackedChangeCanonicalId !== params.trackedChangeCanonicalId) {
|
|
10427
|
-
const previousVersion = previousPreparedPresentation?.rowVersions?.[id];
|
|
10428
|
-
if (!row.trackedChange || params.event !== "add" || typeof params.trackedChangeCanonicalId !== "string" || !params.trackedChangeCanonicalId || !Number.isSafeInteger(previousVersion) || previousVersion < 1 || version <= previousVersion || normalizeTrackedChangeStoryKey(getTrackedChangeStoryKey(row)) !==
|
|
10544
|
+
const previousVersion = previousPreparedPresentation?.rowVersions?.[id] ?? NaN;
|
|
10545
|
+
if (!row.trackedChange || params.event !== "add" || typeof params.trackedChangeCanonicalId !== "string" || !params.trackedChangeCanonicalId || !Number.isSafeInteger(previousVersion) || previousVersion < 1 || version <= previousVersion || normalizeTrackedChangeStoryKey(getTrackedChangeStoryKey(row)) !== anchorStoryKey || row.trackedChangeType !== params.trackedChangeType || row.trackedChangeDisplayType !== params.trackedChangeDisplayType) continue;
|
|
10429
10546
|
row.trackedChangeCanonicalId = params.trackedChangeCanonicalId;
|
|
10430
|
-
row.updateIdentityValues?.({ trackedChangeCanonicalId: params.trackedChangeCanonicalId });
|
|
10431
10547
|
trackedChangeIdentityIndex.add(row);
|
|
10432
10548
|
}
|
|
10433
|
-
retainUnchangedRow = retainUnchangedRows && row?.trackedChange === true && previousPreparedPresentation.rowVersions?.[id] === version && row.trackedChangeCanonicalId === params.trackedChangeCanonicalId && row.trackedChangeType === params.trackedChangeType && row.trackedChangeDisplayType === params.trackedChangeDisplayType && normalizeTrackedChangeStoryKey(getTrackedChangeStoryKey(row)) ===
|
|
10549
|
+
retainUnchangedRow = retainUnchangedRows === true && row?.trackedChange === true && previousPreparedPresentation.rowVersions?.[id] === version && row.trackedChangeCanonicalId === params.trackedChangeCanonicalId && row.trackedChangeType === params.trackedChangeType && row.trackedChangeDisplayType === params.trackedChangeDisplayType && normalizeTrackedChangeStoryKey(getTrackedChangeStoryKey(row)) === anchorStoryKey && !row.resolvedTime && !row.resolvedById && !row.resolvedByEmail && !row.resolvedByName;
|
|
10434
10550
|
}
|
|
10435
10551
|
if (params.event === "omit") {
|
|
10436
10552
|
if (params.changeId != null) liveIds.add(String(params.changeId));
|
|
@@ -10471,22 +10587,18 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
10471
10587
|
return commentsList.value.filter((comment) => {
|
|
10472
10588
|
if (comment?.trackedChange !== true) return false;
|
|
10473
10589
|
if (normalizedDocumentId == null) return true;
|
|
10474
|
-
const rowDocumentId = comment
|
|
10590
|
+
const rowDocumentId = Reflect.get(comment, "documentId") ?? comment?.fileId ?? null;
|
|
10475
10591
|
return rowDocumentId != null && String(rowDocumentId) === normalizedDocumentId;
|
|
10476
10592
|
}).length;
|
|
10477
10593
|
};
|
|
10478
10594
|
/**
|
|
10479
10595
|
* Triggered when the editor locations are updated
|
|
10480
10596
|
* Updates floating comment locations from the editor
|
|
10481
|
-
*
|
|
10482
|
-
* @param {Object} allCommentPositions The collected geometry keyed by comment / tracked-change id
|
|
10483
|
-
* @param {{ retainMissingTrackedChangeGeometry?: boolean, retainedTrackedChangeIds?: Iterable<string> }} options Geometry reconciliation options
|
|
10484
|
-
* @returns {void}
|
|
10485
10597
|
*/
|
|
10486
10598
|
const handleEditorLocationsUpdate = (allCommentPositions, options = {}) => {
|
|
10487
10599
|
if (allCommentPositions == null) return;
|
|
10488
10600
|
const retainMissingTrackedChangeGeometry = options?.retainMissingTrackedChangeGeometry === true;
|
|
10489
|
-
const retainedTrackedChangeIds = retainMissingTrackedChangeGeometry && options?.retainedTrackedChangeIds != null ? new Set(Array.from(options.retainedTrackedChangeIds, (id) => normalizeCommentId(id)).filter(
|
|
10601
|
+
const retainedTrackedChangeIds = retainMissingTrackedChangeGeometry && options?.retainedTrackedChangeIds != null ? new Set(Array.from(options.retainedTrackedChangeIds, (id) => normalizeCommentId(id)).filter(isPresent)) : null;
|
|
10490
10602
|
const previousPositions = editorCommentPositions.value || {};
|
|
10491
10603
|
const normalizedPositions = {};
|
|
10492
10604
|
Object.entries(allCommentPositions).forEach(([key, entry]) => {
|
|
@@ -10513,7 +10625,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
10513
10625
|
return null;
|
|
10514
10626
|
};
|
|
10515
10627
|
const writeTrackedChangeAliases = (entry, comment, extraKeys = []) => {
|
|
10516
|
-
const keys = [...aliasesFor(comment), ...extraKeys.map((id) => normalizeCommentId(id)).filter(
|
|
10628
|
+
const keys = [...aliasesFor(comment), ...extraKeys.map((id) => normalizeCommentId(id)).filter(isPresent)];
|
|
10517
10629
|
for (const key of new Set(keys)) if (normalizedPositions[key] === void 0) normalizedPositions[key] = entry;
|
|
10518
10630
|
};
|
|
10519
10631
|
commentsList.value.forEach((comment) => {
|
|
@@ -10712,7 +10824,7 @@ var ellipsis_vertical_solid_default = "<svg xmlns=\"http://www.w3.org/2000/svg\"
|
|
|
10712
10824
|
//#region ../../shared/common/icons/rotate-left-solid.svg?raw
|
|
10713
10825
|
var rotate_left_solid_default = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d=\"M48.5 224L40 224c-13.3 0-24-10.7-24-24L16 72c0-9.7 5.8-18.5 14.8-22.2s19.3-1.7 26.2 5.2L98.6 96.6c87.6-86.5 228.7-86.2 315.8 1c87.5 87.5 87.5 229.3 0 316.8s-229.3 87.5-316.8 0c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0c62.5 62.5 163.8 62.5 226.3 0s62.5-163.8 0-226.3c-62.2-62.2-162.7-62.5-225.3-1L185 183c6.9 6.9 8.9 17.2 5.2 26.2s-12.5 14.8-22.2 14.8L48.5 224z\"/></svg>";
|
|
10714
10826
|
//#endregion
|
|
10715
|
-
//#region src/icons.
|
|
10827
|
+
//#region src/icons.ts
|
|
10716
10828
|
var superdocIcons = {
|
|
10717
10829
|
comment: comment_solid_default,
|
|
10718
10830
|
caretDown: caret_down_solid_default,
|
|
@@ -11074,12 +11186,9 @@ var InternalDropdown_default = /* @__PURE__ */ _plugin_vue_export_helper_default
|
|
|
11074
11186
|
}
|
|
11075
11187
|
}), [["__scopeId", "data-v-026f5d66"]]);
|
|
11076
11188
|
//#endregion
|
|
11077
|
-
//#region src/components/CommentsLayer/helpers.
|
|
11189
|
+
//#region src/components/CommentsLayer/helpers.ts
|
|
11078
11190
|
/**
|
|
11079
11191
|
* Comments helper to format dates from timestamp
|
|
11080
|
-
*
|
|
11081
|
-
* @param {Number} timestamp The timestamp to format
|
|
11082
|
-
* @returns {String} The formatted date
|
|
11083
11192
|
*/
|
|
11084
11193
|
function formatDate(timestamp) {
|
|
11085
11194
|
const date = new Date(timestamp);
|
|
@@ -11677,7 +11786,7 @@ var CommentInput_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/*
|
|
|
11677
11786
|
}
|
|
11678
11787
|
}), [["__scopeId", "data-v-aa97de44"]]);
|
|
11679
11788
|
//#endregion
|
|
11680
|
-
//#region src/internal/toolbar/built-in/url-safety.
|
|
11789
|
+
//#region src/internal/toolbar/built-in/url-safety.ts
|
|
11681
11790
|
/**
|
|
11682
11791
|
* Minimal href sanitizer for the built-in link popover.
|
|
11683
11792
|
*
|
|
@@ -11693,8 +11802,6 @@ var DANGEROUS_SCHEME = /^(javascript|data|vbscript):/i;
|
|
|
11693
11802
|
var HAS_SCHEME = /^[a-z][a-z0-9+.-]*:/i;
|
|
11694
11803
|
/**
|
|
11695
11804
|
* Validate and normalize an href. Returns `{ href }` for safe values, or `null`.
|
|
11696
|
-
* @param {string} value
|
|
11697
|
-
* @returns {{ href: string }|null}
|
|
11698
11805
|
*/
|
|
11699
11806
|
function sanitizeHref(value) {
|
|
11700
11807
|
if (typeof value !== "string") return null;
|
|
@@ -11706,7 +11813,7 @@ function sanitizeHref(value) {
|
|
|
11706
11813
|
return { href: trimmed };
|
|
11707
11814
|
}
|
|
11708
11815
|
//#endregion
|
|
11709
|
-
//#region src/components/CommentsLayer/comment-urls.
|
|
11816
|
+
//#region src/components/CommentsLayer/comment-urls.ts
|
|
11710
11817
|
function isAbsoluteWebUrl(value) {
|
|
11711
11818
|
if (!/^https?:\/\/[^\s/?#\\]+/i.test(value) || /[\s\\]/u.test(value)) return false;
|
|
11712
11819
|
try {
|
|
@@ -11730,7 +11837,7 @@ function trimUrlPunctuation(value) {
|
|
|
11730
11837
|
for (const character of value) {
|
|
11731
11838
|
const close = closingDelimiter[character];
|
|
11732
11839
|
if (close) balance[close] += 1;
|
|
11733
|
-
else if (Object.
|
|
11840
|
+
else if (Object.prototype.hasOwnProperty.call(balance, character)) balance[character] -= 1;
|
|
11734
11841
|
}
|
|
11735
11842
|
let end = value.length;
|
|
11736
11843
|
while (end > 0) {
|
|
@@ -11754,17 +11861,18 @@ function renderCommentHtml(value) {
|
|
|
11754
11861
|
if (typeof document === "undefined") return value;
|
|
11755
11862
|
const template = document.createElement("template");
|
|
11756
11863
|
template.innerHTML = value;
|
|
11757
|
-
for (const link of template.content.querySelectorAll("a")) {
|
|
11758
|
-
const
|
|
11864
|
+
for (const link of Array.from(template.content.querySelectorAll("a"))) {
|
|
11865
|
+
const rawHref = link.getAttribute("href");
|
|
11866
|
+
const safe = rawHref === null ? null : sanitizeHref(rawHref);
|
|
11759
11867
|
if (safe && (isAbsoluteWebUrl(safe.href) || /^(mailto|tel):\S+$/i.test(safe.href))) configureLink(link, safe.href);
|
|
11760
|
-
else link.replaceWith(...link.childNodes);
|
|
11868
|
+
else link.replaceWith(...Array.from(link.childNodes));
|
|
11761
11869
|
}
|
|
11762
11870
|
const walker = document.createTreeWalker(template.content, NodeFilter.SHOW_TEXT);
|
|
11763
11871
|
const textNodes = [];
|
|
11764
|
-
while (walker.nextNode()) textNodes.push(walker.currentNode);
|
|
11872
|
+
while (walker.nextNode()) if (walker.currentNode instanceof Text) textNodes.push(walker.currentNode);
|
|
11765
11873
|
for (const node of textNodes) {
|
|
11766
11874
|
if (node.parentElement?.closest("a, script, style, textarea, code, pre")) continue;
|
|
11767
|
-
const text = node.
|
|
11875
|
+
const text = node.data;
|
|
11768
11876
|
const fragment = document.createDocumentFragment();
|
|
11769
11877
|
let end = 0;
|
|
11770
11878
|
for (const match of text.matchAll(/(^|[\s([{])(https?:\/\/[^\s<>"']+)/gi)) {
|
|
@@ -11823,8 +11931,8 @@ var _hoisted_11$3 = {
|
|
|
11823
11931
|
key: 0,
|
|
11824
11932
|
class: "card-section comment-body"
|
|
11825
11933
|
};
|
|
11826
|
-
var _hoisted_12$
|
|
11827
|
-
var _hoisted_13$
|
|
11934
|
+
var _hoisted_12$3 = ["data-track-change-semantic-color-key"];
|
|
11935
|
+
var _hoisted_13$3 = { key: 0 };
|
|
11828
11936
|
var _hoisted_14$2 = { class: "change-type tracked-change-label" };
|
|
11829
11937
|
var _hoisted_15$2 = {
|
|
11830
11938
|
key: 0,
|
|
@@ -12998,7 +13106,7 @@ var CommentDialog_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/*
|
|
|
12998
13106
|
"data-track-change-semantic-color-key": comment.semanticColorKey ?? void 0,
|
|
12999
13107
|
ref_for: true,
|
|
13000
13108
|
ref: index === 0 ? setParentBodyRef : void 0
|
|
13001
|
-
}, [comment.trackedChangeLabel ? (openBlock(), createElementBlock("div", _hoisted_13$
|
|
13109
|
+
}, [comment.trackedChangeLabel ? (openBlock(), createElementBlock("div", _hoisted_13$3, [createElementVNode("span", _hoisted_14$2, toDisplayString(comment.trackedChangeLabel), 1), comment.trackedChangeDetailLines && comment.trackedChangeDetailLines.length ? (openBlock(), createElementBlock("div", _hoisted_15$2, [(openBlock(true), createElementBlock(Fragment, null, renderList(comment.trackedChangeDetailLines, (line, lineIndex) => {
|
|
13002
13110
|
return openBlock(), createElementBlock("div", {
|
|
13003
13111
|
key: lineIndex,
|
|
13004
13112
|
class: "tracked-change-detail-line"
|
|
@@ -13023,7 +13131,7 @@ var CommentDialog_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/*
|
|
|
13023
13131
|
style: normalizeStyle(trackedChangeImagePreviewStyle(comment.trackedChangeImagePreview)),
|
|
13024
13132
|
loading: "lazy",
|
|
13025
13133
|
decoding: "async"
|
|
13026
|
-
}, null, 12, _hoisted_38)], 8, _hoisted_37)) : createCommentVNode("", true)], 10, _hoisted_12$
|
|
13134
|
+
}, null, 12, _hoisted_38)], 8, _hoisted_37)) : createCommentVNode("", true)], 10, _hoisted_12$3),
|
|
13027
13135
|
shouldTruncate.value && isTextOverflowing.value && index === 0 ? (openBlock(), createElementBlock("div", {
|
|
13028
13136
|
key: 0,
|
|
13029
13137
|
class: "show-more-toggle",
|
|
@@ -13117,7 +13225,7 @@ var CommentDialog_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/*
|
|
|
13117
13225
|
], 64))], 14, _hoisted_1$26)), [[_directive_click_outside, handleClickOutside]]);
|
|
13118
13226
|
};
|
|
13119
13227
|
}
|
|
13120
|
-
}), [["__scopeId", "data-v-
|
|
13228
|
+
}), [["__scopeId", "data-v-c0cc448b"]]);
|
|
13121
13229
|
//#endregion
|
|
13122
13230
|
//#region src/components/CommentsLayer/commentsList/ReviewDirectoryListItem.vue?vue&type=script&setup=true&lang.ts
|
|
13123
13231
|
var _hoisted_1$25 = [
|
|
@@ -13445,21 +13553,25 @@ var commentsList_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/*
|
|
|
13445
13553
|
}
|
|
13446
13554
|
}), [["__scopeId", "data-v-8eca48e1"]]);
|
|
13447
13555
|
//#endregion
|
|
13448
|
-
//#region src/components/CommentsLayer/commentsList/super-comments-list.
|
|
13556
|
+
//#region src/components/CommentsLayer/commentsList/super-comments-list.ts
|
|
13557
|
+
var isReviewDirectoryStore = (value) => isPlainObject$1(value) && typeof value.setReviewDirectoryFromV2 === "function" && typeof value.clearReviewDirectory === "function";
|
|
13558
|
+
var readCommentsStore = (superdoc) => {
|
|
13559
|
+
const store = superdoc?.["commentsStore"];
|
|
13560
|
+
return isReviewDirectoryStore(store) ? store : void 0;
|
|
13561
|
+
};
|
|
13449
13562
|
/**
|
|
13450
13563
|
* Comments list renderer (not floating comments)
|
|
13451
13564
|
*
|
|
13452
13565
|
* This renders a list of comments into an element, connected to main SuperDoc instance
|
|
13453
13566
|
*/
|
|
13454
13567
|
var SuperComments = class extends import_eventemitter3.default {
|
|
13455
|
-
element;
|
|
13456
|
-
config = {
|
|
13457
|
-
comments: [],
|
|
13458
|
-
element: null,
|
|
13459
|
-
commentsStore: null
|
|
13460
|
-
};
|
|
13461
13568
|
constructor(options, superdoc) {
|
|
13462
13569
|
super();
|
|
13570
|
+
this.config = {
|
|
13571
|
+
comments: [],
|
|
13572
|
+
element: null,
|
|
13573
|
+
commentsStore: null
|
|
13574
|
+
};
|
|
13463
13575
|
this.config = {
|
|
13464
13576
|
...this.config,
|
|
13465
13577
|
...options
|
|
@@ -13480,7 +13592,7 @@ var SuperComments = class extends import_eventemitter3.default {
|
|
|
13480
13592
|
this.open();
|
|
13481
13593
|
}
|
|
13482
13594
|
syncDirectory() {
|
|
13483
|
-
const store = this.superdoc
|
|
13595
|
+
const store = readCommentsStore(this.superdoc);
|
|
13484
13596
|
if (!store) return;
|
|
13485
13597
|
const comments = this.directorySnapshots.comments;
|
|
13486
13598
|
const trackChanges = this.directorySnapshots.trackChanges;
|
|
@@ -13498,12 +13610,14 @@ var SuperComments = class extends import_eventemitter3.default {
|
|
|
13498
13610
|
const acceptDirectorySnapshot = (snapshot) => {
|
|
13499
13611
|
if (generation !== this.directoryGeneration) return;
|
|
13500
13612
|
if ((snapshot?.listStatus ?? snapshot?.status) !== "ready") {
|
|
13501
|
-
|
|
13613
|
+
const store = readCommentsStore(this.superdoc);
|
|
13614
|
+
if (store) store.isReviewDirectoryLoading = true;
|
|
13502
13615
|
return;
|
|
13503
13616
|
}
|
|
13504
13617
|
const items = Array.isArray(snapshot.items) ? snapshot.items : [];
|
|
13505
13618
|
if (this.directoryItemRefs[family] === items) {
|
|
13506
|
-
|
|
13619
|
+
const store = readCommentsStore(this.superdoc);
|
|
13620
|
+
if (store) store.isReviewDirectoryLoading = this.directorySnapshots.comments == null || this.directorySnapshots.trackChanges == null;
|
|
13507
13621
|
return;
|
|
13508
13622
|
}
|
|
13509
13623
|
this.directoryItemRefs[family] = items;
|
|
@@ -13520,15 +13634,16 @@ var SuperComments = class extends import_eventemitter3.default {
|
|
|
13520
13634
|
};
|
|
13521
13635
|
const ui = this.superdoc?.ui;
|
|
13522
13636
|
if (!ui) return;
|
|
13523
|
-
|
|
13524
|
-
|
|
13525
|
-
|
|
13637
|
+
const store = readCommentsStore(this.superdoc);
|
|
13638
|
+
if (store) {
|
|
13639
|
+
store.isReviewDirectoryActive = true;
|
|
13640
|
+
store.isReviewDirectoryLoading = true;
|
|
13526
13641
|
}
|
|
13527
13642
|
this.stopDirectoryObservers = [subscribe(ui.comments, "comments"), subscribe(ui.trackChanges, "trackChanges")];
|
|
13528
13643
|
}
|
|
13529
13644
|
createVueApp() {
|
|
13530
13645
|
this.app = createApp(commentsList_default);
|
|
13531
|
-
const parentProvides = this.superdoc?.app?._context?.provides;
|
|
13646
|
+
const parentProvides = this.superdoc?.["app"]?._context?.provides;
|
|
13532
13647
|
if (parentProvides && this.app?._context?.provides) Object.setPrototypeOf(this.app._context.provides, parentProvides);
|
|
13533
13648
|
if (this.superdoc?.pinia) {
|
|
13534
13649
|
setActivePinia(this.superdoc.pinia);
|
|
@@ -13552,10 +13667,11 @@ var SuperComments = class extends import_eventemitter3.default {
|
|
|
13552
13667
|
comments: null,
|
|
13553
13668
|
trackChanges: null
|
|
13554
13669
|
};
|
|
13555
|
-
|
|
13556
|
-
|
|
13557
|
-
|
|
13558
|
-
|
|
13670
|
+
const store = readCommentsStore(this.superdoc);
|
|
13671
|
+
if (store) {
|
|
13672
|
+
store.clearReviewDirectory();
|
|
13673
|
+
store.isReviewDirectoryActive = false;
|
|
13674
|
+
store.isReviewDirectoryLoading = false;
|
|
13559
13675
|
}
|
|
13560
13676
|
if (this.app) {
|
|
13561
13677
|
this.app.unmount();
|
|
@@ -13569,7 +13685,7 @@ var SuperComments = class extends import_eventemitter3.default {
|
|
|
13569
13685
|
}
|
|
13570
13686
|
};
|
|
13571
13687
|
//#endregion
|
|
13572
|
-
//#region src/composables/use-viewport-fit.
|
|
13688
|
+
//#region src/composables/use-viewport-fit.ts
|
|
13573
13689
|
var CSS_PX_PER_INCH = 96;
|
|
13574
13690
|
var SIDEBAR_SELECTOR = ".superdoc__right-sidebar";
|
|
13575
13691
|
var PDF_PAGE_SELECTOR = ".sd-pdf-viewer-page";
|
|
@@ -13674,7 +13790,7 @@ function useViewportFit({ getSuperdoc, superdocContainerWidth, isReady, activeZo
|
|
|
13674
13790
|
const root = superdocRoot.value;
|
|
13675
13791
|
if (!root?.querySelectorAll) return null;
|
|
13676
13792
|
let widest = 0;
|
|
13677
|
-
for (const page of root.querySelectorAll(PDF_PAGE_SELECTOR)) {
|
|
13793
|
+
for (const page of Array.from(root.querySelectorAll(PDF_PAGE_SELECTOR))) {
|
|
13678
13794
|
const measured = Number(page.clientWidth) || Number(page.getBoundingClientRect?.().width) || 0;
|
|
13679
13795
|
let scaleFactor = NaN;
|
|
13680
13796
|
if (typeof window !== "undefined" && typeof window.getComputedStyle === "function") scaleFactor = Number.parseFloat(window.getComputedStyle(page).getPropertyValue("--scale-factor"));
|
|
@@ -13876,124 +13992,6 @@ var composeAuthorColorResolver = (config) => {
|
|
|
13876
13992
|
};
|
|
13877
13993
|
};
|
|
13878
13994
|
//#endregion
|
|
13879
|
-
//#region ../document-api/src/errors.ts
|
|
13880
|
-
/**
|
|
13881
|
-
* Structured validation error thrown by document-api execute* functions.
|
|
13882
|
-
*
|
|
13883
|
-
* Consumers should prefer checking `error.code` over `instanceof` for resilience
|
|
13884
|
-
* across package boundaries and bundling scenarios.
|
|
13885
|
-
*/
|
|
13886
|
-
var DocumentApiValidationError = class DocumentApiValidationError extends Error {
|
|
13887
|
-
constructor(code, message, details) {
|
|
13888
|
-
super(message);
|
|
13889
|
-
this.name = "DocumentApiValidationError";
|
|
13890
|
-
this.code = code;
|
|
13891
|
-
this.details = details;
|
|
13892
|
-
Object.setPrototypeOf(this, DocumentApiValidationError.prototype);
|
|
13893
|
-
}
|
|
13894
|
-
};
|
|
13895
|
-
//#endregion
|
|
13896
|
-
//#region ../document-api/src/export/export.types.ts
|
|
13897
|
-
/** Canonical tracked-change export modes accepted by every public export surface. */
|
|
13898
|
-
var SD_EXPORT_MODES = [
|
|
13899
|
-
"review-preserving",
|
|
13900
|
-
"final",
|
|
13901
|
-
"original"
|
|
13902
|
-
];
|
|
13903
|
-
/** Default mode for modeful DOCX export. */
|
|
13904
|
-
var DEFAULT_SD_EXPORT_MODE = "review-preserving";
|
|
13905
|
-
var SD_COMMENT_EXPORT_POLICIES = [
|
|
13906
|
-
"preserve",
|
|
13907
|
-
"resolve",
|
|
13908
|
-
"remove"
|
|
13909
|
-
];
|
|
13910
|
-
var SD_CONTENT_CONTROL_EXPORT_POLICIES = ["preserve", "flatten"];
|
|
13911
|
-
//#endregion
|
|
13912
|
-
//#region ../document-api/src/export/export.ts
|
|
13913
|
-
/**
|
|
13914
|
-
* Export namespace: engine-agnostic public API and adapter contract.
|
|
13915
|
-
*
|
|
13916
|
-
* Validates the requested mode at the public boundary so an invalid mode fails
|
|
13917
|
-
* closed with `INVALID_INPUT` before any document work happens, then delegates
|
|
13918
|
-
* byte production and degradation reporting to the engine adapter.
|
|
13919
|
-
*/
|
|
13920
|
-
function resolveMode$1(input) {
|
|
13921
|
-
if (input != null && !isRecord(input)) throw new DocumentApiValidationError("INVALID_INPUT", "export.toDocx input must be an object.");
|
|
13922
|
-
const raw = input?.mode;
|
|
13923
|
-
if (raw === void 0) return DEFAULT_SD_EXPORT_MODE;
|
|
13924
|
-
if (typeof raw !== "string" || !SD_EXPORT_MODES.includes(raw)) throw new DocumentApiValidationError("INVALID_INPUT", `export.toDocx mode must be one of: ${SD_EXPORT_MODES.join(", ")}.`, {
|
|
13925
|
-
mode: raw,
|
|
13926
|
-
allowedModes: [...SD_EXPORT_MODES]
|
|
13927
|
-
});
|
|
13928
|
-
return raw;
|
|
13929
|
-
}
|
|
13930
|
-
function resolveDocxExportPolicies(input = {}) {
|
|
13931
|
-
if (!isRecord(input)) throw new DocumentApiValidationError("INVALID_INPUT", "DOCX export input must be an object.");
|
|
13932
|
-
const mode = resolveMode$1(input);
|
|
13933
|
-
const policies = input.policies;
|
|
13934
|
-
if (policies !== void 0 && !isRecord(policies)) throw new DocumentApiValidationError("INVALID_INPUT", "DOCX export policies must be an object.");
|
|
13935
|
-
const allowed = {
|
|
13936
|
-
trackedChanges: SD_EXPORT_MODES,
|
|
13937
|
-
comments: SD_COMMENT_EXPORT_POLICIES,
|
|
13938
|
-
contentControls: SD_CONTENT_CONTROL_EXPORT_POLICIES
|
|
13939
|
-
};
|
|
13940
|
-
for (const [key, value] of Object.entries(policies ?? {})) if (!Object.prototype.hasOwnProperty.call(allowed, key) || value !== void 0 && !allowed[key].includes(value)) throw new DocumentApiValidationError("INVALID_INPUT", `Unsupported DOCX export policy: ${key}.`, {
|
|
13941
|
-
policy: key,
|
|
13942
|
-
value
|
|
13943
|
-
});
|
|
13944
|
-
const requested = policies;
|
|
13945
|
-
if (input.mode !== void 0 && requested?.trackedChanges !== void 0 && mode !== requested.trackedChanges) throw new DocumentApiValidationError("INVALID_INPUT", "mode conflicts with policies.trackedChanges.");
|
|
13946
|
-
return {
|
|
13947
|
-
trackedChanges: requested?.trackedChanges ?? mode,
|
|
13948
|
-
comments: requested?.comments ?? "preserve",
|
|
13949
|
-
contentControls: requested?.contentControls ?? "preserve"
|
|
13950
|
-
};
|
|
13951
|
-
}
|
|
13952
|
-
//#endregion
|
|
13953
|
-
//#region ../document-api/src/permission-ranges/permission-ranges.ts
|
|
13954
|
-
function editorKey(editor) {
|
|
13955
|
-
return editor.id?.trim() ? editor.id : editor.email?.trim() || void 0;
|
|
13956
|
-
}
|
|
13957
|
-
function editorMatches(editor, id) {
|
|
13958
|
-
return Boolean(id.trim()) && (editor.id === id || Boolean(editor.email?.trim() && editor.email.trim().toLowerCase() === id.toLowerCase()));
|
|
13959
|
-
}
|
|
13960
|
-
/**
|
|
13961
|
-
* Resolve a host ID or imported Word email against an explicitly supplied roster.
|
|
13962
|
-
* Word receives the email when available; opaque IDs remain host-specific.
|
|
13963
|
-
* Duplicate IDs/emails are ambiguous. This does not authenticate a user.
|
|
13964
|
-
*/
|
|
13965
|
-
function resolvePermissionRangeEditor(editors, id) {
|
|
13966
|
-
const matches = editors.filter((editor) => editorMatches(editor, id));
|
|
13967
|
-
if (matches.length === 0) return {
|
|
13968
|
-
status: "unknown",
|
|
13969
|
-
id
|
|
13970
|
-
};
|
|
13971
|
-
if (matches.length !== 1) return {
|
|
13972
|
-
status: "ambiguous",
|
|
13973
|
-
id
|
|
13974
|
-
};
|
|
13975
|
-
const editor = matches[0];
|
|
13976
|
-
const wordId = editor.email?.trim() || editor.id;
|
|
13977
|
-
if (editors.filter((candidate) => editorMatches(candidate, wordId)).length !== 1) return {
|
|
13978
|
-
status: "ambiguous",
|
|
13979
|
-
id
|
|
13980
|
-
};
|
|
13981
|
-
return {
|
|
13982
|
-
status: "resolved",
|
|
13983
|
-
id,
|
|
13984
|
-
editor: { ...editor },
|
|
13985
|
-
principal: {
|
|
13986
|
-
kind: "editor",
|
|
13987
|
-
id: wordId
|
|
13988
|
-
}
|
|
13989
|
-
};
|
|
13990
|
-
}
|
|
13991
|
-
/** Enumerate the host roster for an editor picker, including ambiguous entries. */
|
|
13992
|
-
function listPermissionRangeEditors(editors) {
|
|
13993
|
-
const ids = new Set(editors.map(editorKey).filter((id) => id !== void 0));
|
|
13994
|
-
return Array.from(ids, (id) => resolvePermissionRangeEditor(editors, id));
|
|
13995
|
-
}
|
|
13996
|
-
//#endregion
|
|
13997
13995
|
//#region src/core/superdoc-ui-owner.ts
|
|
13998
13996
|
var ownerIds = /* @__PURE__ */ new WeakMap();
|
|
13999
13997
|
function getSuperDocUiOwnerId(superdoc) {
|
|
@@ -15054,7 +15052,7 @@ var FloatingComments_default = /* @__PURE__ */ _plugin_vue_export_helper_default
|
|
|
15054
15052
|
}), 128))], 4)], 36);
|
|
15055
15053
|
};
|
|
15056
15054
|
}
|
|
15057
|
-
}), [["__scopeId", "data-v-
|
|
15055
|
+
}), [["__scopeId", "data-v-df897b8d"]]);
|
|
15058
15056
|
//#endregion
|
|
15059
15057
|
//#region src/components/CommentsLayer/PdfCommentsLayer.vue?vue&type=script&setup=true&lang.ts
|
|
15060
15058
|
var _hoisted_1$22 = {
|
|
@@ -15187,7 +15185,7 @@ var PdfCommentsLayer_default = /* @__PURE__ */ _plugin_vue_export_helper_default
|
|
|
15187
15185
|
}), 128))]);
|
|
15188
15186
|
};
|
|
15189
15187
|
}
|
|
15190
|
-
}), [["__scopeId", "data-v-
|
|
15188
|
+
}), [["__scopeId", "data-v-e3ae65fa"]]);
|
|
15191
15189
|
//#endregion
|
|
15192
15190
|
//#region src/components/Whiteboard/use-whiteboard.ts
|
|
15193
15191
|
var useWhiteboard = ({ proxy, layers, documents, modules }) => {
|
|
@@ -15481,7 +15479,7 @@ var WhiteboardPage_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/
|
|
|
15481
15479
|
}, null, 44, _hoisted_1$21);
|
|
15482
15480
|
};
|
|
15483
15481
|
}
|
|
15484
|
-
}), [["__scopeId", "data-v-
|
|
15482
|
+
}), [["__scopeId", "data-v-fdae8749"]]);
|
|
15485
15483
|
//#endregion
|
|
15486
15484
|
//#region src/components/Whiteboard/WhiteboardLayer.vue
|
|
15487
15485
|
var WhiteboardLayer_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
|
|
@@ -15552,16 +15550,11 @@ var WhiteboardLayer_default = /* @__PURE__ */ _plugin_vue_export_helper_default(
|
|
|
15552
15550
|
}), 128))], 4);
|
|
15553
15551
|
};
|
|
15554
15552
|
}
|
|
15555
|
-
}), [["__scopeId", "data-v-
|
|
15553
|
+
}), [["__scopeId", "data-v-800e1970"]]);
|
|
15556
15554
|
//#endregion
|
|
15557
|
-
//#region src/components/CommentsLayer/collect-removed-comment-ids.
|
|
15555
|
+
//#region src/components/CommentsLayer/collect-removed-comment-ids.ts
|
|
15558
15556
|
/**
|
|
15559
15557
|
* Expand deleted comment ids through comment and tracked-change descendants.
|
|
15560
|
-
*
|
|
15561
|
-
* @param {ReadonlyArray<Record<string, any>>} comments
|
|
15562
|
-
* @param {ReadonlyArray<string>} targetIds
|
|
15563
|
-
* @param {(comment: Record<string, any>) => boolean} [isInScope]
|
|
15564
|
-
* @returns {Set<string>}
|
|
15565
15558
|
*/
|
|
15566
15559
|
var collectRemovedCommentIds = (comments, targetIds, isInScope = () => true) => {
|
|
15567
15560
|
const targets = new Set(targetIds.map(String));
|
|
@@ -15644,7 +15637,7 @@ function normalizeCommentsUiConfig(commentsConfig) {
|
|
|
15644
15637
|
return normalized;
|
|
15645
15638
|
}
|
|
15646
15639
|
//#endregion
|
|
15647
|
-
//#region src/composables/use-comment-small-screen.
|
|
15640
|
+
//#region src/composables/use-comment-small-screen.ts
|
|
15648
15641
|
var SUPERDOC_DOCUMENT_SELECTOR = ".superdoc__document";
|
|
15649
15642
|
var isValidCompactBreakpoint = (value) => {
|
|
15650
15643
|
return isFiniteNumber(value) && value >= 0;
|
|
@@ -15724,10 +15717,11 @@ function useCommentSmallScreen({ commentsModuleConfig, superdocRoot, layers }) {
|
|
|
15724
15717
|
}
|
|
15725
15718
|
documentWidthTargets = nextTargets;
|
|
15726
15719
|
if (!nextTargets.length) return;
|
|
15727
|
-
|
|
15720
|
+
const observer = new ResizeObserverClass(() => {
|
|
15728
15721
|
recalculateCompactCommentsMode();
|
|
15729
15722
|
});
|
|
15730
|
-
|
|
15723
|
+
documentWidthResizeObserver = observer;
|
|
15724
|
+
nextTargets.forEach((el) => observer.observe(el));
|
|
15731
15725
|
};
|
|
15732
15726
|
const getMeasuredDocumentWidth = () => {
|
|
15733
15727
|
ensureDocumentWidthObserver();
|
|
@@ -15783,7 +15777,7 @@ function useCommentSmallScreen({ commentsModuleConfig, superdocRoot, layers }) {
|
|
|
15783
15777
|
};
|
|
15784
15778
|
}
|
|
15785
15779
|
//#endregion
|
|
15786
|
-
//#region src/composables/use-compact-comment-popover.
|
|
15780
|
+
//#region src/composables/use-compact-comment-popover.ts
|
|
15787
15781
|
var POPOVER_WIDTH_PX = 320;
|
|
15788
15782
|
var SAFE_MARGIN_PX = 12;
|
|
15789
15783
|
var MIN_BOTTOM_SPACE_PX = 220;
|
|
@@ -15813,7 +15807,7 @@ var resolveInteractionAnchor = (lastClickAnchor) => {
|
|
|
15813
15807
|
var resolveInlineHighlightAnchorRect = ({ rootEl, comment, pendingComment }) => {
|
|
15814
15808
|
if (Boolean(pendingComment?.value && comment?.commentId === pendingComment.value?.commentId)) {
|
|
15815
15809
|
const nodes = rootEl.querySelectorAll(COMMENT_HIGHLIGHT_SELECTOR);
|
|
15816
|
-
for (const node of nodes) {
|
|
15810
|
+
for (const node of Array.from(nodes)) {
|
|
15817
15811
|
if (!parseCommentIds(node.getAttribute(COMMENT_HIGHLIGHT_DATA_ATTR)).includes("pending")) continue;
|
|
15818
15812
|
if (typeof node.getBoundingClientRect !== "function") continue;
|
|
15819
15813
|
return node.getBoundingClientRect();
|
|
@@ -15823,7 +15817,7 @@ var resolveInlineHighlightAnchorRect = ({ rootEl, comment, pendingComment }) =>
|
|
|
15823
15817
|
if (!anchorId) return null;
|
|
15824
15818
|
const safeId = String(anchorId);
|
|
15825
15819
|
const highlightNodes = rootEl.querySelectorAll(COMMENT_HIGHLIGHT_SELECTOR);
|
|
15826
|
-
for (const node of highlightNodes) {
|
|
15820
|
+
for (const node of Array.from(highlightNodes)) {
|
|
15827
15821
|
if (!parseCommentIds(node.getAttribute(COMMENT_HIGHLIGHT_DATA_ATTR)).includes(safeId)) continue;
|
|
15828
15822
|
if (typeof node.getBoundingClientRect !== "function") continue;
|
|
15829
15823
|
return node.getBoundingClientRect();
|
|
@@ -15908,9 +15902,10 @@ function useCompactCommentPopover({ activeComment, pendingComment, activeCompact
|
|
|
15908
15902
|
};
|
|
15909
15903
|
const trackCompactPopoverClickAnchor = (e) => {
|
|
15910
15904
|
const root = superdocRoot.value;
|
|
15911
|
-
|
|
15912
|
-
|
|
15913
|
-
|
|
15905
|
+
const target = e.target instanceof Node ? e.target : null;
|
|
15906
|
+
if (!root || !layers.value?.contains(target)) return;
|
|
15907
|
+
const anchorElement = (typeof document.elementsFromPoint === "function" ? document.elementsFromPoint(e.clientX, e.clientY) : []).find((node) => node?.nodeType === 1 && root.contains(node) && node.closest("[data-track-change-id], .superdoc-comment-highlight, .sd-comment-anchor"))?.closest("[data-track-change-id], .superdoc-comment-highlight, .sd-comment-anchor") ?? (target instanceof Element ? target.closest("[data-track-change-id], .superdoc-comment-highlight, .sd-comment-anchor") : null);
|
|
15908
|
+
if (clearCompactPopoverIfPdfClickedOutside(root, target, anchorElement)) return;
|
|
15914
15909
|
if (e.button !== 0 || e.pointerType !== "mouse") return;
|
|
15915
15910
|
const anchorRect = anchorElement && typeof anchorElement.getBoundingClientRect === "function" ? anchorElement.getBoundingClientRect() : null;
|
|
15916
15911
|
if (!anchorRect) return;
|
|
@@ -16144,7 +16139,7 @@ function normalizeHyperlinksConfig(config = {}) {
|
|
|
16144
16139
|
};
|
|
16145
16140
|
}
|
|
16146
16141
|
//#endregion
|
|
16147
|
-
//#region src/helpers/v2-review-target.
|
|
16142
|
+
//#region src/helpers/v2-review-target.ts
|
|
16148
16143
|
/**
|
|
16149
16144
|
* Resolve the comments-store identity for a document-origin v2 review target.
|
|
16150
16145
|
* Painted review carriers can become interactive before the asynchronous row
|
|
@@ -16160,15 +16155,126 @@ function resolveV2ReviewTargetCommentId(target, getComment) {
|
|
|
16160
16155
|
return commentId != null ? String(commentId) : null;
|
|
16161
16156
|
}
|
|
16162
16157
|
//#endregion
|
|
16163
|
-
//#region src/helpers/v2-
|
|
16158
|
+
//#region src/helpers/v2-review-geometry-delivery.ts
|
|
16159
|
+
function createReviewGeometryDelivery(deliver) {
|
|
16160
|
+
const packets = /* @__PURE__ */ new Map();
|
|
16161
|
+
let stageOwners = /* @__PURE__ */ new WeakMap();
|
|
16162
|
+
let active = null;
|
|
16163
|
+
const documentOf = (current) => current.documentId != null ? String(current.documentId) : current.mountContainer?.dataset.superdocV2DocumentId ?? null;
|
|
16164
|
+
const matches = (documentId, current) => current.mountContainer?.dataset.superdocV2DocumentId === documentId && (current.documentId == null || String(current.documentId) === documentId);
|
|
16165
|
+
const matchesPaint = (packet, current) => typeof packet.payload.paintEpoch !== "number" || packet.payload.paintEpoch === current.epoch;
|
|
16166
|
+
const observe = (current) => {
|
|
16167
|
+
const stage = current.mountContainer;
|
|
16168
|
+
const documentId = documentOf(current);
|
|
16169
|
+
if (!stage || !documentId || !matches(documentId, current)) return;
|
|
16170
|
+
const previousOwner = stageOwners.get(stage);
|
|
16171
|
+
if (previousOwner && previousOwner !== documentId) packets.delete(previousOwner);
|
|
16172
|
+
stageOwners.set(stage, documentId);
|
|
16173
|
+
const packet = packets.get(documentId);
|
|
16174
|
+
if (packet?.stage && packet.stage !== stage) packets.delete(documentId);
|
|
16175
|
+
else if (packet && (!active || active.stage !== stage || active.documentId !== documentId || active.epoch !== current.epoch)) packet.delivered = false;
|
|
16176
|
+
active = {
|
|
16177
|
+
documentId,
|
|
16178
|
+
stage,
|
|
16179
|
+
epoch: current.epoch
|
|
16180
|
+
};
|
|
16181
|
+
};
|
|
16182
|
+
const dispatch = (documentId, packet, current, replay = false) => {
|
|
16183
|
+
if (!current.mountContainer || !matches(documentId, current) || !matchesPaint(packet, current)) return false;
|
|
16184
|
+
if (packet.stage && packet.stage !== current.mountContainer || packet.delivering || packet.delivered && !replay) return false;
|
|
16185
|
+
const wasDelivered = packet.delivered;
|
|
16186
|
+
const previousStage = packet.stage;
|
|
16187
|
+
packet.stage = current.mountContainer;
|
|
16188
|
+
packet.delivered = true;
|
|
16189
|
+
packet.delivering = true;
|
|
16190
|
+
try {
|
|
16191
|
+
deliver(current, packet.payload);
|
|
16192
|
+
} catch (error) {
|
|
16193
|
+
packet.delivered = wasDelivered;
|
|
16194
|
+
packet.stage = previousStage;
|
|
16195
|
+
throw error;
|
|
16196
|
+
} finally {
|
|
16197
|
+
packet.delivering = false;
|
|
16198
|
+
}
|
|
16199
|
+
return true;
|
|
16200
|
+
};
|
|
16201
|
+
const notify = (documentId, payload, current, ready = true) => {
|
|
16202
|
+
if (!payload.reviewGeometry || !Array.isArray(payload.pageIndices)) return false;
|
|
16203
|
+
let key;
|
|
16204
|
+
try {
|
|
16205
|
+
key = JSON.stringify([
|
|
16206
|
+
documentId,
|
|
16207
|
+
payload.documentEpoch,
|
|
16208
|
+
payload.paintEpoch,
|
|
16209
|
+
payload.commitSequence,
|
|
16210
|
+
payload.pageIndices,
|
|
16211
|
+
payload.zoomScale,
|
|
16212
|
+
payload.reviewGeometry
|
|
16213
|
+
]);
|
|
16214
|
+
} catch {
|
|
16215
|
+
return false;
|
|
16216
|
+
}
|
|
16217
|
+
const isCurrent = current != null && matches(documentId, current);
|
|
16218
|
+
if (isCurrent) observe(current);
|
|
16219
|
+
const previous = packets.get(documentId);
|
|
16220
|
+
if (previous && previous.payload.documentEpoch === payload.documentEpoch && typeof previous.payload.paintEpoch === "number" && typeof payload.paintEpoch === "number" && payload.paintEpoch < previous.payload.paintEpoch) return false;
|
|
16221
|
+
if (previous && previous.payload.documentEpoch === payload.documentEpoch && typeof previous.payload.commitSequence === "number" && typeof payload.commitSequence === "number" && payload.commitSequence < previous.payload.commitSequence) return false;
|
|
16222
|
+
if (previous && previous.payload.documentEpoch === payload.documentEpoch && typeof previous.payload.generation === "number" && typeof payload.generation === "number" && payload.generation < previous.payload.generation) return false;
|
|
16223
|
+
if (isCurrent && typeof payload.paintEpoch === "number" && typeof current.epoch === "number" && payload.paintEpoch < current.epoch) return false;
|
|
16224
|
+
if (previous?.key === key) {
|
|
16225
|
+
previous.payload = payload;
|
|
16226
|
+
return isCurrent && ready ? dispatch(documentId, previous, current) : false;
|
|
16227
|
+
}
|
|
16228
|
+
const packet = {
|
|
16229
|
+
payload,
|
|
16230
|
+
key,
|
|
16231
|
+
stage: isCurrent ? current.mountContainer : previous && previous.payload.documentEpoch === payload.documentEpoch ? previous.stage : null,
|
|
16232
|
+
delivered: false,
|
|
16233
|
+
delivering: false
|
|
16234
|
+
};
|
|
16235
|
+
packets.set(documentId, packet);
|
|
16236
|
+
if (!isCurrent || !ready) return false;
|
|
16237
|
+
try {
|
|
16238
|
+
return dispatch(documentId, packet, current);
|
|
16239
|
+
} catch (error) {
|
|
16240
|
+
if (previous) packets.set(documentId, previous);
|
|
16241
|
+
else packets.delete(documentId);
|
|
16242
|
+
throw error;
|
|
16243
|
+
}
|
|
16244
|
+
};
|
|
16245
|
+
return {
|
|
16246
|
+
notify,
|
|
16247
|
+
observe,
|
|
16248
|
+
flush(current) {
|
|
16249
|
+
observe(current);
|
|
16250
|
+
const documentId = documentOf(current);
|
|
16251
|
+
const packet = documentId == null ? null : packets.get(documentId);
|
|
16252
|
+
return documentId && packet ? dispatch(documentId, packet, current) : false;
|
|
16253
|
+
},
|
|
16254
|
+
replay(current) {
|
|
16255
|
+
observe(current);
|
|
16256
|
+
const documentId = documentOf(current);
|
|
16257
|
+
const packet = documentId == null ? null : packets.get(documentId);
|
|
16258
|
+
return documentId && packet ? dispatch(documentId, packet, current, true) : false;
|
|
16259
|
+
},
|
|
16260
|
+
reset() {
|
|
16261
|
+
packets.clear();
|
|
16262
|
+
stageOwners = /* @__PURE__ */ new WeakMap();
|
|
16263
|
+
active = null;
|
|
16264
|
+
}
|
|
16265
|
+
};
|
|
16266
|
+
}
|
|
16267
|
+
//#endregion
|
|
16268
|
+
//#region src/helpers/v2-mutation-exception.ts
|
|
16164
16269
|
var FAILURE_SOURCES = /* @__PURE__ */ new Set(["shell", "receipt"]);
|
|
16165
16270
|
var DIAGNOSTIC_CODE = /^[a-zA-Z][a-zA-Z0-9_-]{0,127}$/;
|
|
16166
16271
|
var COMMAND_KIND = /^[a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?$/;
|
|
16167
16272
|
function createV2MutationRejectionCause(event) {
|
|
16168
|
-
if (!event
|
|
16169
|
-
const
|
|
16273
|
+
if (!isPlainObject$1(event)) return {};
|
|
16274
|
+
const failure = isPlainObject$1(event.failure) ? event.failure : void 0;
|
|
16275
|
+
const reason = event.reason ?? (event.failureSource === "receipt" ? failure?.code : void 0);
|
|
16170
16276
|
return {
|
|
16171
|
-
...FAILURE_SOURCES.has(event.failureSource) ? { failureSource: event.failureSource } : {},
|
|
16277
|
+
...typeof event.failureSource === "string" && FAILURE_SOURCES.has(event.failureSource) ? { failureSource: event.failureSource } : {},
|
|
16172
16278
|
...typeof reason === "string" && DIAGNOSTIC_CODE.test(reason) ? { reason } : {},
|
|
16173
16279
|
...typeof event.inputKind === "string" && DIAGNOSTIC_CODE.test(event.inputKind) ? { inputKind: event.inputKind } : {},
|
|
16174
16280
|
...typeof event.editableCommandKind === "string" && event.editableCommandKind.length <= 128 && COMMAND_KIND.test(event.editableCommandKind) ? { editableCommandKind: event.editableCommandKind } : {}
|
|
@@ -16196,7 +16302,7 @@ function createV2MutationRejectionNotificationGate(matches) {
|
|
|
16196
16302
|
};
|
|
16197
16303
|
}
|
|
16198
16304
|
//#endregion
|
|
16199
|
-
//#region src/helpers/v2-author-required-rejection.
|
|
16305
|
+
//#region src/helpers/v2-author-required-rejection.ts
|
|
16200
16306
|
var NO_AUTHOR_SIGNAL = "no-author-configured";
|
|
16201
16307
|
/** Stable, non-terminal exception code surfaced to consumers. */
|
|
16202
16308
|
var V2_AUTHOR_REQUIRED_CODE = "author-required";
|
|
@@ -16208,15 +16314,11 @@ var V2_AUTHOR_REQUIRED_MESSAGE = "This edit needs an author identity. Set `user.
|
|
|
16208
16314
|
function messageHasNoAuthorSignal(message) {
|
|
16209
16315
|
return typeof message === "string" && message.includes(NO_AUTHOR_SIGNAL);
|
|
16210
16316
|
}
|
|
16211
|
-
/**
|
|
16212
|
-
* @param {any} event - a `v2-host-event` payload.
|
|
16213
|
-
* @returns {boolean} true when the rejection means the session needs an author.
|
|
16214
|
-
*/
|
|
16215
16317
|
function isV2AuthorRequiredRejection(event) {
|
|
16216
|
-
if (!event || event.type !== "mutation:rejected") return false;
|
|
16318
|
+
if (!isPlainObject$1(event) || event.type !== "mutation:rejected") return false;
|
|
16217
16319
|
if (event.failureSource === "receipt") {
|
|
16218
16320
|
const failure = event.failure;
|
|
16219
|
-
if (!failure) return false;
|
|
16321
|
+
if (!isPlainObject$1(failure)) return false;
|
|
16220
16322
|
return failure.code === "PRECONDITION_FAILED" && messageHasNoAuthorSignal(failure.message);
|
|
16221
16323
|
}
|
|
16222
16324
|
if (event.failureSource === "shell") {
|
|
@@ -16229,7 +16331,7 @@ function createV2AuthorRequiredNotificationGate() {
|
|
|
16229
16331
|
return createV2MutationRejectionNotificationGate(isV2AuthorRequiredRejection);
|
|
16230
16332
|
}
|
|
16231
16333
|
//#endregion
|
|
16232
|
-
//#region src/helpers/v2-bulk-decision-event.
|
|
16334
|
+
//#region src/helpers/v2-bulk-decision-event.ts
|
|
16233
16335
|
function toV2BulkDecisionEvent(documentId, fact) {
|
|
16234
16336
|
if (fact?.schemaVersion !== 1 || fact.decision !== "accept" && fact.decision !== "reject") return null;
|
|
16235
16337
|
return {
|
|
@@ -16241,7 +16343,7 @@ function toV2BulkDecisionEvent(documentId, fact) {
|
|
|
16241
16343
|
};
|
|
16242
16344
|
}
|
|
16243
16345
|
//#endregion
|
|
16244
|
-
//#region src/helpers/v2-keyboard-edit-rejection.
|
|
16346
|
+
//#region src/helpers/v2-keyboard-edit-rejection.ts
|
|
16245
16347
|
var EDIT_INPUT_KINDS = /* @__PURE__ */ new Set([
|
|
16246
16348
|
"keydown",
|
|
16247
16349
|
"beforeinput",
|
|
@@ -16291,7 +16393,7 @@ var EDIT_FAILURE_SOURCES = /* @__PURE__ */ new Set(["shell", "receipt"]);
|
|
|
16291
16393
|
var V2_EDIT_REJECTED_CODE = "edit-rejected";
|
|
16292
16394
|
var V2_EDIT_REJECTED_MESSAGE = "This edit couldn’t be completed. Adjust the selection and try again.";
|
|
16293
16395
|
function isV2KeyboardEditRejection(event) {
|
|
16294
|
-
return
|
|
16396
|
+
return isPlainObject$1(event) && event.type === "mutation:rejected" && event.origin === "document-surface" && EDIT_FAILURE_SOURCES.has(event.failureSource) && EDIT_INPUT_KINDS.has(event.inputKind) && (EDIT_COMMAND_KINDS.has(event.editableCommandKind) || event.editableCommandKind == null && EDIT_INPUT_WITHOUT_COMMAND_KINDS.has(event.inputKind));
|
|
16295
16397
|
}
|
|
16296
16398
|
function createV2KeyboardEditRejectionException(documentId, event) {
|
|
16297
16399
|
return {
|
|
@@ -16305,24 +16407,17 @@ function createV2KeyboardEditRejectionNotificationGate() {
|
|
|
16305
16407
|
return createV2MutationRejectionNotificationGate(isV2KeyboardEditRejection);
|
|
16306
16408
|
}
|
|
16307
16409
|
//#endregion
|
|
16308
|
-
//#region src/helpers/v2-selection-sync.
|
|
16410
|
+
//#region src/helpers/v2-selection-sync.ts
|
|
16309
16411
|
/**
|
|
16310
16412
|
* A logical v2 selection snapshot represents a non-empty range when its anchor
|
|
16311
16413
|
* and focus point at different block positions. Mirrors the range check the v2
|
|
16312
16414
|
* shell uses when it emits `v2-selection-changed`.
|
|
16313
|
-
*
|
|
16314
|
-
* @param {{ anchor?: { blockId?: unknown, blockOffset?: unknown }, focus?: { blockId?: unknown, blockOffset?: unknown } } | null | undefined} snapshot
|
|
16315
|
-
* @returns {boolean}
|
|
16316
16415
|
*/
|
|
16317
16416
|
var isV2RangeSnapshot = (snapshot) => Boolean(snapshot?.anchor && snapshot?.focus && (snapshot.anchor.blockId !== snapshot.focus.blockId || snapshot.anchor.blockOffset !== snapshot.focus.blockOffset));
|
|
16318
16417
|
/**
|
|
16319
16418
|
* Detect a real browser text selection whose endpoints are outside the active
|
|
16320
16419
|
* v2 mount. Editable host selections can have no native DOM range, so an
|
|
16321
16420
|
* absent range must not count as an outside selection.
|
|
16322
|
-
*
|
|
16323
|
-
* @param {Selection | null | undefined} selection
|
|
16324
|
-
* @param {Node | null | undefined} root
|
|
16325
|
-
* @returns {boolean}
|
|
16326
16421
|
*/
|
|
16327
16422
|
var hasOutsideV2DomRangeSelection = (selection, root) => {
|
|
16328
16423
|
if (!selection || selection.rangeCount < 1 || selection.isCollapsed || !root) return false;
|
|
@@ -16338,10 +16433,6 @@ var hasOutsideV2DomRangeSelection = (selection, root) => {
|
|
|
16338
16433
|
* host snapshot rather than clobber the selection the host just published.
|
|
16339
16434
|
* Only editable modes use the host snapshot. Viewing mode keeps native DOM
|
|
16340
16435
|
* selection, and unknown modes should not preserve stale host state.
|
|
16341
|
-
*
|
|
16342
|
-
* @param {string | null | undefined} documentMode
|
|
16343
|
-
* @param {unknown} hostSnapshot
|
|
16344
|
-
* @returns {boolean}
|
|
16345
16436
|
*/
|
|
16346
16437
|
var shouldPreserveHostV2Selection = (documentMode, hostSnapshot) => {
|
|
16347
16438
|
if (documentMode !== "editing" && documentMode !== "suggesting") return false;
|
|
@@ -16352,10 +16443,6 @@ var shouldPreserveHostV2Selection = (documentMode, hostSnapshot) => {
|
|
|
16352
16443
|
* rebuilt. Keep an already-positioned comment affordance during that gap when
|
|
16353
16444
|
* the host still owns a range; otherwise the button unmounts and remounts on
|
|
16354
16445
|
* consecutive paint frames, making it blink and intercepting its own click.
|
|
16355
|
-
*
|
|
16356
|
-
* @param {boolean} hasHostRange
|
|
16357
|
-
* @param {{ source?: unknown } | null | undefined} selectionPosition
|
|
16358
|
-
* @returns {boolean}
|
|
16359
16446
|
*/
|
|
16360
16447
|
var shouldRetainV2FloatingSelection = (hasHostRange, selectionPosition) => hasHostRange === true && selectionPosition?.source === "document-editor";
|
|
16361
16448
|
//#endregion
|
|
@@ -16547,7 +16634,7 @@ function usePasswordPrompt({ getSurfaceManager, getPasswordPromptConfig, onUnhan
|
|
|
16547
16634
|
})
|
|
16548
16635
|
});
|
|
16549
16636
|
} else {
|
|
16550
|
-
const mod = await import("./chunks/PasswordPromptSurface-
|
|
16637
|
+
const mod = await import("./chunks/PasswordPromptSurface-DjV1JgjD.es.js");
|
|
16551
16638
|
const surfaceId = `password-prompt-${doc.id}`;
|
|
16552
16639
|
handle = manager.open({
|
|
16553
16640
|
id: surfaceId,
|
|
@@ -16649,9 +16736,6 @@ function createReplaceContinuation(session, { getCurrentSession, applySlice, onS
|
|
|
16649
16736
|
}
|
|
16650
16737
|
//#endregion
|
|
16651
16738
|
//#region src/composables/use-find-replace.ts
|
|
16652
|
-
function isThenable$2(value) {
|
|
16653
|
-
return (typeof value === "object" || typeof value === "function") && value !== null && "then" in value && typeof value.then === "function";
|
|
16654
|
-
}
|
|
16655
16739
|
var DEFAULT_TEXTS = {
|
|
16656
16740
|
findPlaceholder: "Find",
|
|
16657
16741
|
findAriaLabel: "Find text",
|
|
@@ -16826,7 +16910,7 @@ function useFindReplace({ getSurfaceManager, getActiveEditor, activeEditorRef, g
|
|
|
16826
16910
|
try {
|
|
16827
16911
|
result = search.replace(replaceText.value);
|
|
16828
16912
|
} catch {}
|
|
16829
|
-
if (isThenable$
|
|
16913
|
+
if (isThenable$1(result)) Promise.resolve(result).then(finish, finish);
|
|
16830
16914
|
else finish();
|
|
16831
16915
|
}
|
|
16832
16916
|
function replaceAll() {
|
|
@@ -16848,7 +16932,7 @@ function useFindReplace({ getSurfaceManager, getActiveEditor, activeEditorRef, g
|
|
|
16848
16932
|
try {
|
|
16849
16933
|
result = search.replaceAll(replaceText.value);
|
|
16850
16934
|
} catch {}
|
|
16851
|
-
if (isThenable$
|
|
16935
|
+
if (isThenable$1(result)) Promise.resolve(result).then(finish, finish);
|
|
16852
16936
|
else finish();
|
|
16853
16937
|
}
|
|
16854
16938
|
function syncFromSearchSession() {
|
|
@@ -17210,7 +17294,7 @@ function useFindReplace({ getSurfaceManager, getActiveEditor, activeEditorRef, g
|
|
|
17210
17294
|
} else {
|
|
17211
17295
|
let FindReplaceSurface;
|
|
17212
17296
|
try {
|
|
17213
|
-
FindReplaceSurface = (await import("./chunks/FindReplaceSurface-
|
|
17297
|
+
FindReplaceSurface = (await import("./chunks/FindReplaceSurface-BEnRLpD9.es.js")).default;
|
|
17214
17298
|
} catch {
|
|
17215
17299
|
opening = false;
|
|
17216
17300
|
return;
|
|
@@ -17477,7 +17561,7 @@ var plus_solid_default = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0
|
|
|
17477
17561
|
//#region ../../shared/common/icons/trash-can-solid.svg?raw
|
|
17478
17562
|
var trash_can_solid_default = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 448 512\"><!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d=\"M135.2 17.7C140.6 6.8 151.7 0 163.8 0L284.2 0c12.1 0 23.2 6.8 28.6 17.7L320 32l96 0c17.7 0 32 14.3 32 32s-14.3 32-32 32L32 96C14.3 96 0 81.7 0 64S14.3 32 32 32l96 0 7.2-14.3zM32 128l384 0 0 320c0 35.3-28.7 64-64 64L96 512c-35.3 0-64-28.7-64-64l0-320zm96 64c-8.8 0-16 7.2-16 16l0 224c0 8.8 7.2 16 16 16s16-7.2 16-16l0-224c0-8.8-7.2-16-16-16zm96 0c-8.8 0-16 7.2-16 16l0 224c0 8.8 7.2 16 16 16s16-7.2 16-16l0-224c0-8.8-7.2-16-16-16zm96 0c-8.8 0-16 7.2-16 16l0 224c0 8.8 7.2 16 16 16s16-7.2 16-16l0-224c0-8.8-7.2-16-16-16z\"/></svg>";
|
|
17479
17563
|
//#endregion
|
|
17480
|
-
//#region src/internal/toolbar/built-in/toolbarIcons.
|
|
17564
|
+
//#region src/internal/toolbar/built-in/toolbarIcons.ts
|
|
17481
17565
|
var toolbarIcons = {
|
|
17482
17566
|
undo: rotate_left_solid_default,
|
|
17483
17567
|
redo: rotate_right_solid_default,
|
|
@@ -17584,11 +17668,11 @@ var _hoisted_8$3 = { class: "input-row url-input-row" };
|
|
|
17584
17668
|
var _hoisted_9$2 = ["innerHTML"];
|
|
17585
17669
|
var _hoisted_10$2 = ["readonly", "onKeydown"];
|
|
17586
17670
|
var _hoisted_11$2 = ["innerHTML"];
|
|
17587
|
-
var _hoisted_12$
|
|
17671
|
+
var _hoisted_12$2 = {
|
|
17588
17672
|
key: 0,
|
|
17589
17673
|
class: "input-row link-buttons"
|
|
17590
17674
|
};
|
|
17591
|
-
var _hoisted_13$
|
|
17675
|
+
var _hoisted_13$2 = ["disabled"];
|
|
17592
17676
|
var _hoisted_14$1 = ["innerHTML"];
|
|
17593
17677
|
var _hoisted_15$1 = ["disabled"];
|
|
17594
17678
|
var _hoisted_16$1 = {
|
|
@@ -17847,7 +17931,7 @@ var LinkInput_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__
|
|
|
17847
17931
|
"data-item": "btn-link-open"
|
|
17848
17932
|
}, null, 10, _hoisted_11$2)
|
|
17849
17933
|
]),
|
|
17850
|
-
!isViewingMode.value ? (openBlock(), createElementBlock("div", _hoisted_12$
|
|
17934
|
+
!isViewingMode.value ? (openBlock(), createElementBlock("div", _hoisted_12$2, [isEditing.value ? (openBlock(), createElementBlock("button", {
|
|
17851
17935
|
key: 0,
|
|
17852
17936
|
class: "remove-btn",
|
|
17853
17937
|
onClick: handleRemove,
|
|
@@ -17856,7 +17940,7 @@ var LinkInput_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__
|
|
|
17856
17940
|
}, [createElementVNode("div", {
|
|
17857
17941
|
class: "remove-btn__icon",
|
|
17858
17942
|
innerHTML: unref(toolbarIcons).removeLink
|
|
17859
|
-
}, null, 8, _hoisted_14$1), _cache[6] || (_cache[6] = createTextVNode(" Remove ", -1))], 8, _hoisted_13$
|
|
17943
|
+
}, null, 8, _hoisted_14$1), _cache[6] || (_cache[6] = createTextVNode(" Remove ", -1))], 8, _hoisted_13$2)) : createCommentVNode("", true), createElementVNode("button", {
|
|
17860
17944
|
class: normalizeClass(["sd-submit-btn", { "disable-btn": isDisabled.value }]),
|
|
17861
17945
|
onClick: handleSubmit,
|
|
17862
17946
|
disabled: isSubmitting.value,
|
|
@@ -17870,7 +17954,7 @@ var LinkInput_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__
|
|
|
17870
17954
|
}
|
|
17871
17955
|
}), [["__scopeId", "data-v-172107e4"]]);
|
|
17872
17956
|
//#endregion
|
|
17873
|
-
//#region src/internal/toolbar/built-in/scroll-helpers.
|
|
17957
|
+
//#region src/internal/toolbar/built-in/scroll-helpers.ts
|
|
17874
17958
|
function getScrollableParent(element) {
|
|
17875
17959
|
let currentElement = element;
|
|
17876
17960
|
while (currentElement) {
|
|
@@ -17903,7 +17987,6 @@ function scrollToElement(targetElement, options = {
|
|
|
17903
17987
|
var FLOATING_SURFACE_ID = "link-popover";
|
|
17904
17988
|
var RECENT_OUTSIDE_CLOSE_MS = 500;
|
|
17905
17989
|
var MAX_ANCHOR_NAVIGATION_STEPS = 4;
|
|
17906
|
-
var isThenable$1 = (value) => Boolean(value && (typeof value === "object" || typeof value === "function") && "then" in value && typeof value.then === "function");
|
|
17907
17990
|
function isLinkPopoverDocumentApi(value) {
|
|
17908
17991
|
return isPlainObject$1(value) || typeof value === "function";
|
|
17909
17992
|
}
|
|
@@ -18767,6 +18850,7 @@ function createV2EditorRuntimeAdapter(options) {
|
|
|
18767
18850
|
const { id, documentId, root, host, getLegacyEditorProjection, onUnregister } = options;
|
|
18768
18851
|
let snapshot = host.getSnapshot();
|
|
18769
18852
|
let didDispose = false;
|
|
18853
|
+
let detached = false;
|
|
18770
18854
|
let unregistered = false;
|
|
18771
18855
|
let mountedFocusHandle = null;
|
|
18772
18856
|
let tokenRevision = 0;
|
|
@@ -19063,7 +19147,17 @@ function createV2EditorRuntimeAdapter(options) {
|
|
|
19063
19147
|
};
|
|
19064
19148
|
}
|
|
19065
19149
|
}
|
|
19150
|
+
function releaseHostSubscriptions() {
|
|
19151
|
+
hostUnsubscribe?.();
|
|
19152
|
+
hostUnsubscribe = null;
|
|
19153
|
+
pageMetricsUnsubscribe?.();
|
|
19154
|
+
pageMetricsUnsubscribe = null;
|
|
19155
|
+
selectionUnsubscribe?.();
|
|
19156
|
+
selectionUnsubscribe = null;
|
|
19157
|
+
activeSelectionController = null;
|
|
19158
|
+
}
|
|
19066
19159
|
function handleHostSnapshot(next) {
|
|
19160
|
+
if (detached || didDispose) return;
|
|
19067
19161
|
snapshot = next;
|
|
19068
19162
|
invalidatePositionTokens();
|
|
19069
19163
|
syncSelectionSubscription();
|
|
@@ -19077,10 +19171,7 @@ function createV2EditorRuntimeAdapter(options) {
|
|
|
19077
19171
|
});
|
|
19078
19172
|
if (next.state === "disposed" && !didDispose) {
|
|
19079
19173
|
didDispose = true;
|
|
19080
|
-
|
|
19081
|
-
pageMetricsUnsubscribe?.();
|
|
19082
|
-
selectionUnsubscribe?.();
|
|
19083
|
-
selectionUnsubscribe = null;
|
|
19174
|
+
releaseHostSubscriptions();
|
|
19084
19175
|
emit({ type: "disposed" });
|
|
19085
19176
|
listeners.clear();
|
|
19086
19177
|
if (!unregistered) {
|
|
@@ -19227,10 +19318,7 @@ function createV2EditorRuntimeAdapter(options) {
|
|
|
19227
19318
|
await host.dispose();
|
|
19228
19319
|
if (!didDispose) {
|
|
19229
19320
|
didDispose = true;
|
|
19230
|
-
|
|
19231
|
-
pageMetricsUnsubscribe?.();
|
|
19232
|
-
selectionUnsubscribe?.();
|
|
19233
|
-
selectionUnsubscribe = null;
|
|
19321
|
+
releaseHostSubscriptions();
|
|
19234
19322
|
emit({ type: "disposed" });
|
|
19235
19323
|
listeners.clear();
|
|
19236
19324
|
if (!unregistered) {
|
|
@@ -19309,8 +19397,17 @@ function createV2EditorRuntimeAdapter(options) {
|
|
|
19309
19397
|
}
|
|
19310
19398
|
},
|
|
19311
19399
|
attachMountHandle(handle) {
|
|
19400
|
+
if (detached || didDispose) return;
|
|
19312
19401
|
mountedFocusHandle = handle;
|
|
19313
19402
|
syncSelectionSubscription();
|
|
19403
|
+
},
|
|
19404
|
+
detach() {
|
|
19405
|
+
if (detached) return;
|
|
19406
|
+
detached = true;
|
|
19407
|
+
unregistered = true;
|
|
19408
|
+
releaseHostSubscriptions();
|
|
19409
|
+
mountedFocusHandle = null;
|
|
19410
|
+
listeners.clear();
|
|
19314
19411
|
}
|
|
19315
19412
|
};
|
|
19316
19413
|
}
|
|
@@ -20473,7 +20570,7 @@ var SuperDoc_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
|
|
|
20473
20570
|
__name: "SuperDoc",
|
|
20474
20571
|
emits: ["selection-update"],
|
|
20475
20572
|
setup(__props, { emit: __emit }) {
|
|
20476
|
-
const PdfViewer = defineAsyncComponent(() => import("./chunks/PdfViewer-
|
|
20573
|
+
const PdfViewer = defineAsyncComponent(() => import("./chunks/PdfViewer-C2r-K8zC.es.js"));
|
|
20477
20574
|
const getDocumentLoadPassword = (doc) => doc.password ?? proxy.$superdoc.config.password;
|
|
20478
20575
|
const resolveDocumentV2Collaboration = (doc) => {
|
|
20479
20576
|
const rawConfig = doc?.v2Collaboration;
|
|
@@ -20587,6 +20684,8 @@ var SuperDoc_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
|
|
|
20587
20684
|
const v2ReviewSidebarUnlocked = ref(false);
|
|
20588
20685
|
const v2GeometryEpoch = ref(null);
|
|
20589
20686
|
let v2GeometryRafHandle = 0;
|
|
20687
|
+
let v2GeometryReplayRafHandle = 0;
|
|
20688
|
+
let v2GeometryReplayGeneration = 0;
|
|
20590
20689
|
let v2TrackedChangeRestampRetainPaints = 0;
|
|
20591
20690
|
let v2TrackedChangeRestampRetentionReason = null;
|
|
20592
20691
|
const activeEditorRef = computed$1(() => proxy.$superdoc.activeEditor);
|
|
@@ -20770,6 +20869,7 @@ var SuperDoc_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
|
|
|
20770
20869
|
if (document && provider?.sendStateless) document.provider = null;
|
|
20771
20870
|
const entry = v2Runtimes.get(documentId);
|
|
20772
20871
|
if (!entry) return;
|
|
20872
|
+
entry.adapter.detach();
|
|
20773
20873
|
proxy.$superdoc["unregisterEditorRuntime"](entry.runtimeId);
|
|
20774
20874
|
v2Runtimes.delete(documentId);
|
|
20775
20875
|
const hostRoot = subDocumentRoots.get(documentId);
|
|
@@ -21276,7 +21376,7 @@ var SuperDoc_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
|
|
|
21276
21376
|
let v2SelectionToolbarRafHandle = 0;
|
|
21277
21377
|
let v2SelectionToolbarTimeoutHandle = 0;
|
|
21278
21378
|
let v2DomSelectionRafHandle = 0;
|
|
21279
|
-
const buildV2EditorUpdatePayload = ({ editor, sourceEditor, surface = "body", headerId = null, sectionType = null } = {}) => {
|
|
21379
|
+
const buildV2EditorUpdatePayload = ({ editor, sourceEditor, surface = "body", headerId = null, sectionType = null, isRemote = false } = {}) => {
|
|
21280
21380
|
const activeEditor = proxy.$superdoc?.activeEditor ?? null;
|
|
21281
21381
|
const effectiveEditor = editor ?? sourceEditor ?? activeEditor ?? void 0;
|
|
21282
21382
|
return {
|
|
@@ -21284,7 +21384,8 @@ var SuperDoc_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
|
|
|
21284
21384
|
sourceEditor: sourceEditor ?? effectiveEditor,
|
|
21285
21385
|
surface,
|
|
21286
21386
|
headerId,
|
|
21287
|
-
sectionType
|
|
21387
|
+
sectionType,
|
|
21388
|
+
isRemote
|
|
21288
21389
|
};
|
|
21289
21390
|
};
|
|
21290
21391
|
const emitV2EditorUpdate = (payload = {}) => {
|
|
@@ -21538,6 +21639,7 @@ var SuperDoc_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
|
|
|
21538
21639
|
pending: entry
|
|
21539
21640
|
});
|
|
21540
21641
|
};
|
|
21642
|
+
let scheduleV2GeometryReplay = () => {};
|
|
21541
21643
|
const v2GeometryPublisher = resolvedEditorIntegration.createGeometryPublisher({
|
|
21542
21644
|
getLayersContainer: () => layers.value ?? null,
|
|
21543
21645
|
isCommentsEnabled: () => Boolean(commentsModuleConfig.value) && shouldRenderCommentsInViewing.value,
|
|
@@ -21553,7 +21655,8 @@ var SuperDoc_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
|
|
|
21553
21655
|
v2ReviewSidebarUnlocked.value = true;
|
|
21554
21656
|
v2GeometryEpoch.value = v2GeometryPublisher.getLastEpoch();
|
|
21555
21657
|
}
|
|
21556
|
-
}
|
|
21658
|
+
},
|
|
21659
|
+
onCommittedPagePaint: ({ payload }) => scheduleV2GeometryReplay(payload)
|
|
21557
21660
|
});
|
|
21558
21661
|
const armV2TrackedChangeRestampGeometryRetention = (reason = "tracked-change-restamp") => {
|
|
21559
21662
|
v2TrackedChangeRestampRetainPaints = Math.max(v2TrackedChangeRestampRetainPaints, 3);
|
|
@@ -21573,20 +21676,53 @@ var SuperDoc_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
|
|
|
21573
21676
|
v2TrackedChangeRestampRetentionReason = null;
|
|
21574
21677
|
};
|
|
21575
21678
|
const resolveV2GeometryPublishOptions = (options) => typeof options === "function" ? options() : options;
|
|
21679
|
+
const isV2GeometryReady = (current) => {
|
|
21680
|
+
if (!current?.mountContainer || !commentsModuleConfig.value || !shouldRenderCommentsInViewing.value) return false;
|
|
21681
|
+
const mount = current.mount;
|
|
21682
|
+
let liveEpoch;
|
|
21683
|
+
try {
|
|
21684
|
+
liveEpoch = mount?.getRenderEpoch?.();
|
|
21685
|
+
} catch {
|
|
21686
|
+
return false;
|
|
21687
|
+
}
|
|
21688
|
+
return v2GeometryPublisher.getLastPayload() === current && v2GeometryPublisher.getLastEpoch() != null && v2GeometryPublisher.getLastEpoch() === current.epoch && (liveEpoch == null || liveEpoch === current.epoch);
|
|
21689
|
+
};
|
|
21576
21690
|
const scheduleV2GeometryPublish = (payload, options = void 0) => {
|
|
21577
21691
|
v2GeometryRender.value = payload;
|
|
21578
21692
|
if (v2GeometryRafHandle && typeof cancelAnimationFrame === "function") cancelAnimationFrame(v2GeometryRafHandle);
|
|
21693
|
+
const publish = () => {
|
|
21694
|
+
const current = v2GeometryRender.value;
|
|
21695
|
+
Promise.resolve(v2GeometryPublisher.publish(current, resolveV2GeometryPublishOptions(options))).then(() => {
|
|
21696
|
+
if (current === v2GeometryRender.value && isV2GeometryReady(current)) v2ReviewGeometryDelivery.flush(current);
|
|
21697
|
+
});
|
|
21698
|
+
};
|
|
21579
21699
|
if (typeof requestAnimationFrame !== "function") {
|
|
21580
|
-
|
|
21700
|
+
publish();
|
|
21581
21701
|
return;
|
|
21582
21702
|
}
|
|
21583
21703
|
v2GeometryRafHandle = requestAnimationFrame(() => {
|
|
21584
21704
|
v2GeometryRafHandle = 0;
|
|
21585
|
-
|
|
21705
|
+
publish();
|
|
21586
21706
|
});
|
|
21587
21707
|
};
|
|
21708
|
+
const v2ReviewGeometryDelivery = createReviewGeometryDelivery((current, packet) => {
|
|
21709
|
+
v2GeometryPublisher.noteCommittedPageWindow?.(packet);
|
|
21710
|
+
scheduleV2GeometryPublish(current);
|
|
21711
|
+
});
|
|
21712
|
+
scheduleV2GeometryReplay = (payload) => {
|
|
21713
|
+
if (!payload || payload !== v2GeometryRender.value) return;
|
|
21714
|
+
const generation = ++v2GeometryReplayGeneration;
|
|
21715
|
+
if (v2GeometryReplayRafHandle && typeof cancelAnimationFrame === "function") cancelAnimationFrame(v2GeometryReplayRafHandle);
|
|
21716
|
+
const replay = () => {
|
|
21717
|
+
v2GeometryReplayRafHandle = 0;
|
|
21718
|
+
if (generation === v2GeometryReplayGeneration && payload === v2GeometryRender.value && isV2GeometryReady(payload)) v2ReviewGeometryDelivery.replay(payload);
|
|
21719
|
+
};
|
|
21720
|
+
if (typeof requestAnimationFrame === "function") v2GeometryReplayRafHandle = requestAnimationFrame(replay);
|
|
21721
|
+
else queueMicrotask(replay);
|
|
21722
|
+
};
|
|
21588
21723
|
const onV2Render = (payload) => {
|
|
21589
21724
|
if (!payload) return;
|
|
21725
|
+
v2ReviewGeometryDelivery.observe(payload);
|
|
21590
21726
|
scheduleV2GeometryPublish(payload, () => takeV2TrackedChangeRestampGeometryRetention());
|
|
21591
21727
|
if (v2HasRangeSelection.value) scheduleV2SelectionToolbarStateSync();
|
|
21592
21728
|
};
|
|
@@ -21619,7 +21755,11 @@ var SuperDoc_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
|
|
|
21619
21755
|
cancelScheduledV2SelectionToolbarSync();
|
|
21620
21756
|
if (v2GeometryRafHandle && typeof cancelAnimationFrame === "function") cancelAnimationFrame(v2GeometryRafHandle);
|
|
21621
21757
|
v2GeometryRafHandle = 0;
|
|
21758
|
+
if (v2GeometryReplayRafHandle && typeof cancelAnimationFrame === "function") cancelAnimationFrame(v2GeometryReplayRafHandle);
|
|
21759
|
+
v2GeometryReplayRafHandle = 0;
|
|
21760
|
+
v2GeometryReplayGeneration++;
|
|
21622
21761
|
v2GeometryRender.value = null;
|
|
21762
|
+
v2ReviewGeometryDelivery.reset();
|
|
21623
21763
|
v2GeometryEpoch.value = null;
|
|
21624
21764
|
v2GeometryAvailable.value = false;
|
|
21625
21765
|
v2ReviewSidebarUnlocked.value = false;
|
|
@@ -21678,6 +21818,7 @@ var SuperDoc_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
|
|
|
21678
21818
|
v2ReviewWindowController.invalidate("collaboration:remote-review-changed");
|
|
21679
21819
|
v2ReviewWindowController.refreshCommittedWindow("collaboration:remote-review-changed");
|
|
21680
21820
|
}
|
|
21821
|
+
emitV2EditorUpdate({ isRemote: true });
|
|
21681
21822
|
return;
|
|
21682
21823
|
}
|
|
21683
21824
|
if (event.type === "source:complete") {
|
|
@@ -21766,14 +21907,15 @@ var SuperDoc_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
|
|
|
21766
21907
|
if (!isV2Mode.value) return;
|
|
21767
21908
|
if (!v2GeometryPublisher.getLastPayload()) return;
|
|
21768
21909
|
if (v2GeometryRafHandle && typeof cancelAnimationFrame === "function") cancelAnimationFrame(v2GeometryRafHandle);
|
|
21769
|
-
|
|
21770
|
-
v2GeometryPublisher.recollect(resolveV2GeometryPublishOptions(options));
|
|
21771
|
-
return;
|
|
21772
|
-
}
|
|
21773
|
-
v2GeometryRafHandle = requestAnimationFrame(() => {
|
|
21910
|
+
const recollect = () => {
|
|
21774
21911
|
v2GeometryRafHandle = 0;
|
|
21775
|
-
|
|
21776
|
-
|
|
21912
|
+
const current = v2GeometryRender.value;
|
|
21913
|
+
Promise.resolve(v2GeometryPublisher.recollect(resolveV2GeometryPublishOptions(options))).then(() => {
|
|
21914
|
+
if (current === v2GeometryRender.value && isV2GeometryReady(current)) v2ReviewGeometryDelivery.replay(current);
|
|
21915
|
+
});
|
|
21916
|
+
};
|
|
21917
|
+
if (typeof requestAnimationFrame !== "function") recollect();
|
|
21918
|
+
else v2GeometryRafHandle = requestAnimationFrame(recollect);
|
|
21777
21919
|
};
|
|
21778
21920
|
const handleV2DocumentModeChange = () => {
|
|
21779
21921
|
if (!isV2Mode.value) return;
|
|
@@ -22001,13 +22143,17 @@ var SuperDoc_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
|
|
|
22001
22143
|
...payload,
|
|
22002
22144
|
documentId: doc.id
|
|
22003
22145
|
});
|
|
22004
|
-
|
|
22146
|
+
if (payload.reviewGeometry && Array.isArray(payload.pageIndices)) {
|
|
22147
|
+
const current = v2GeometryRender.value;
|
|
22148
|
+
v2ReviewGeometryDelivery.notify(String(doc.id), payload, current, isV2GeometryReady(current));
|
|
22149
|
+
} else v2GeometryPublisher.noteCommittedPageWindow?.(payload);
|
|
22005
22150
|
},
|
|
22006
22151
|
fontAssets: proxy.$superdoc.config.fonts,
|
|
22007
22152
|
workerUrls: proxy.$superdoc.config.workerUrls,
|
|
22008
22153
|
fieldContext: doc.fieldContext,
|
|
22009
22154
|
fieldUpdatePolicy: proxy.$superdoc.config.fieldUpdatePolicy,
|
|
22010
22155
|
workerStartupTimeoutMs: proxy.$superdoc.config.workerStartupTimeoutMs,
|
|
22156
|
+
...proxy.$superdoc.config.changes ? { changes: proxy.$superdoc.config.changes } : {},
|
|
22011
22157
|
proofing: resolvedProofingConfig.value,
|
|
22012
22158
|
isNewFile,
|
|
22013
22159
|
password: getDocumentLoadPassword(doc),
|
|
@@ -23090,7 +23236,7 @@ var SuperDoc_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
|
|
|
23090
23236
|
], 46, _hoisted_1$17);
|
|
23091
23237
|
};
|
|
23092
23238
|
}
|
|
23093
|
-
}), [["__scopeId", "data-v-
|
|
23239
|
+
}), [["__scopeId", "data-v-7c932add"]]);
|
|
23094
23240
|
//#endregion
|
|
23095
23241
|
//#region src/core/create-app.ts
|
|
23096
23242
|
var PINIA_DEVTOOLS_SETUP_EVENT = "devtools-plugin:setup";
|
|
@@ -24571,6 +24717,16 @@ var SurfaceManager = class {
|
|
|
24571
24717
|
};
|
|
24572
24718
|
//#endregion
|
|
24573
24719
|
//#region src/helpers/deprecation.ts
|
|
24720
|
+
/**
|
|
24721
|
+
* Deprecation utilities for steering consumers toward the Document API.
|
|
24722
|
+
*
|
|
24723
|
+
* ProseMirror will be removed in a future major version. These helpers emit
|
|
24724
|
+
* one-time console warnings when deprecated properties are accessed on an
|
|
24725
|
+
* editor instance handed to consumer callbacks (onEditorCreate, etc.).
|
|
24726
|
+
*
|
|
24727
|
+
* Internal code continues to use the raw Editor — only the consumer-facing
|
|
24728
|
+
* boundary wraps the editor with a Proxy.
|
|
24729
|
+
*/
|
|
24574
24730
|
var MIGRATION_URL = "https://docs.superdoc.dev/guides/migration/document-api";
|
|
24575
24731
|
var _warned = /* @__PURE__ */ new Set();
|
|
24576
24732
|
/**
|
|
@@ -25873,23 +26029,21 @@ function resolveBuiltInItemCommandId(name) {
|
|
|
25873
26029
|
return resolveToolbarCommandId(name) ?? UNCATALOGED_ITEM_COMMAND_IDS[name] ?? null;
|
|
25874
26030
|
}
|
|
25875
26031
|
//#endregion
|
|
25876
|
-
//#region src/internal/toolbar/built-in/helpers.
|
|
26032
|
+
//#region src/internal/toolbar/built-in/helpers.ts
|
|
25877
26033
|
var sanitizeNumber = (value, defaultNumber) => {
|
|
25878
|
-
|
|
25879
|
-
|
|
25880
|
-
|
|
25881
|
-
|
|
25882
|
-
|
|
25883
|
-
|
|
25884
|
-
|
|
25885
|
-
let timeout, args, result;
|
|
26034
|
+
const parsed = parseFloat(String(value ?? "").replace(/[^0-9.]/g, ""));
|
|
26035
|
+
return isNaN(parsed) ? defaultNumber : parsed;
|
|
26036
|
+
};
|
|
26037
|
+
var throttle = (func, wait, options = {}) => {
|
|
26038
|
+
let timeout;
|
|
26039
|
+
let args;
|
|
26040
|
+
let result;
|
|
25886
26041
|
let previous = 0;
|
|
25887
|
-
if (!options) options = {};
|
|
25888
26042
|
const later = () => {
|
|
25889
26043
|
previous = options.leading === false ? 0 : Date.now();
|
|
25890
|
-
timeout =
|
|
25891
|
-
result = func(...args);
|
|
25892
|
-
if (!timeout) args =
|
|
26044
|
+
timeout = void 0;
|
|
26045
|
+
if (args) result = func(...args);
|
|
26046
|
+
if (!timeout) args = void 0;
|
|
25893
26047
|
};
|
|
25894
26048
|
const throttled = (...callArgs) => {
|
|
25895
26049
|
const _now = Date.now();
|
|
@@ -25899,18 +26053,18 @@ var throttle = (func, wait, options) => {
|
|
|
25899
26053
|
if (remaining <= 0 || remaining > wait) {
|
|
25900
26054
|
if (timeout) {
|
|
25901
26055
|
clearTimeout(timeout);
|
|
25902
|
-
timeout =
|
|
26056
|
+
timeout = void 0;
|
|
25903
26057
|
}
|
|
25904
26058
|
previous = _now;
|
|
25905
26059
|
result = func(...callArgs);
|
|
25906
|
-
if (!timeout) args =
|
|
26060
|
+
if (!timeout) args = void 0;
|
|
25907
26061
|
} else if (!timeout && options.trailing !== false) timeout = setTimeout(later, remaining);
|
|
25908
26062
|
return result;
|
|
25909
26063
|
};
|
|
25910
26064
|
throttled.cancel = function() {
|
|
25911
26065
|
clearTimeout(timeout);
|
|
25912
26066
|
previous = 0;
|
|
25913
|
-
timeout = args =
|
|
26067
|
+
timeout = args = void 0;
|
|
25914
26068
|
};
|
|
25915
26069
|
return throttled;
|
|
25916
26070
|
};
|
|
@@ -25962,26 +26116,39 @@ var ToolbarButtonIcon_default = /* @__PURE__ */ _plugin_vue_export_helper_defaul
|
|
|
25962
26116
|
var _hoisted_1$15 = [
|
|
25963
26117
|
"role",
|
|
25964
26118
|
"aria-label",
|
|
25965
|
-
"aria-disabled"
|
|
26119
|
+
"aria-disabled",
|
|
26120
|
+
"aria-busy"
|
|
25966
26121
|
];
|
|
25967
26122
|
var _hoisted_2$11 = ["data-item"];
|
|
25968
26123
|
var _hoisted_3$10 = ["data-item"];
|
|
25969
26124
|
var _hoisted_4$8 = {
|
|
25970
|
-
key:
|
|
26125
|
+
key: 0,
|
|
26126
|
+
role: "status",
|
|
26127
|
+
"aria-label": "Applying list",
|
|
26128
|
+
style: { "font-weight": "700" }
|
|
26129
|
+
};
|
|
26130
|
+
var _hoisted_5$6 = {
|
|
26131
|
+
key: 2,
|
|
25971
26132
|
class: "sd-button-label"
|
|
25972
26133
|
};
|
|
25973
|
-
var
|
|
25974
|
-
var
|
|
25975
|
-
var
|
|
25976
|
-
|
|
25977
|
-
|
|
26134
|
+
var _hoisted_6$4 = ["data-item", "aria-label"];
|
|
26135
|
+
var _hoisted_7$2 = ["innerHTML"];
|
|
26136
|
+
var _hoisted_8$2 = {
|
|
26137
|
+
key: 0,
|
|
26138
|
+
role: "status",
|
|
26139
|
+
"aria-label": "Applying list",
|
|
26140
|
+
style: { "font-weight": "700" }
|
|
26141
|
+
};
|
|
26142
|
+
var _hoisted_9$1 = { key: 3 };
|
|
26143
|
+
var _hoisted_10$1 = ["onKeydown", "id"];
|
|
26144
|
+
var _hoisted_11$1 = [
|
|
25978
26145
|
"placeholder",
|
|
25979
26146
|
"onKeydown",
|
|
25980
26147
|
"id",
|
|
25981
26148
|
"data-item"
|
|
25982
26149
|
];
|
|
25983
|
-
var
|
|
25984
|
-
var
|
|
26150
|
+
var _hoisted_12$1 = ["data-item", "innerHTML"];
|
|
26151
|
+
var _hoisted_13$1 = {
|
|
25985
26152
|
"aria-live": "polite",
|
|
25986
26153
|
class: "sd-visually-hidden"
|
|
25987
26154
|
};
|
|
@@ -26154,6 +26321,7 @@ var ToolbarButton_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/*
|
|
|
26154
26321
|
role: __props.isOverflowItem ? "menuitem" : "button",
|
|
26155
26322
|
"aria-label": unref(attributes).ariaLabel,
|
|
26156
26323
|
"aria-disabled": unref(disabled) ? "true" : void 0,
|
|
26324
|
+
"aria-busy": unref(attributes).ariaBusy || void 0,
|
|
26157
26325
|
"data-sd-part": "toolbar-item",
|
|
26158
26326
|
onClick: handleOuterClick,
|
|
26159
26327
|
onKeydown: _cache[9] || (_cache[9] = withKeys(($event) => onEnterKeydown($event), ["enter"])),
|
|
@@ -26175,17 +26343,21 @@ var ToolbarButton_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/*
|
|
|
26175
26343
|
class: "sd-toolbar-button__main",
|
|
26176
26344
|
"data-item": `btn-${unref(name) || ""}-main`,
|
|
26177
26345
|
onClick: _cache[0] || (_cache[0] = ($event) => handleSplitMainClick($event))
|
|
26178
|
-
}, [
|
|
26179
|
-
|
|
26180
|
-
|
|
26181
|
-
|
|
26182
|
-
|
|
26183
|
-
|
|
26184
|
-
|
|
26185
|
-
|
|
26186
|
-
|
|
26187
|
-
|
|
26188
|
-
|
|
26346
|
+
}, [
|
|
26347
|
+
unref(attributes).ariaBusy && isSplit.value ? (openBlock(), createElementBlock("span", _hoisted_4$8, "…")) : createCommentVNode("", true),
|
|
26348
|
+
unref(icon) ? (openBlock(), createBlock(ToolbarButtonIcon_default, {
|
|
26349
|
+
key: 1,
|
|
26350
|
+
color: unref(iconColor),
|
|
26351
|
+
class: "sd-toolbar-icon",
|
|
26352
|
+
icon: unref(icon),
|
|
26353
|
+
name: unref(name)
|
|
26354
|
+
}, null, 8, [
|
|
26355
|
+
"color",
|
|
26356
|
+
"icon",
|
|
26357
|
+
"name"
|
|
26358
|
+
])) : createCommentVNode("", true),
|
|
26359
|
+
unref(label) && !unref(hideLabel) && !unref(inlineTextInputVisible) ? (openBlock(), createElementBlock("div", _hoisted_5$6, toDisplayString(unref(label)), 1)) : createCommentVNode("", true)
|
|
26360
|
+
], 8, _hoisted_3$10)) : createCommentVNode("", true),
|
|
26189
26361
|
isSplit.value ? (openBlock(), createElementBlock("div", {
|
|
26190
26362
|
key: 1,
|
|
26191
26363
|
class: "sd-toolbar-button__caret",
|
|
@@ -26196,9 +26368,10 @@ var ToolbarButton_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/*
|
|
|
26196
26368
|
class: "sd-dropdown-caret",
|
|
26197
26369
|
innerHTML: caretIcon.value,
|
|
26198
26370
|
style: normalizeStyle({ opacity: unref(disabled) ? .6 : 1 })
|
|
26199
|
-
}, null, 12,
|
|
26371
|
+
}, null, 12, _hoisted_7$2)], 8, _hoisted_6$4)) : (openBlock(), createElementBlock(Fragment, { key: 2 }, [
|
|
26372
|
+
unref(attributes).ariaBusy ? (openBlock(), createElementBlock("span", _hoisted_8$2, "…")) : createCommentVNode("", true),
|
|
26200
26373
|
unref(icon) ? (openBlock(), createBlock(ToolbarButtonIcon_default, {
|
|
26201
|
-
key:
|
|
26374
|
+
key: 1,
|
|
26202
26375
|
color: unref(iconColor),
|
|
26203
26376
|
class: "sd-toolbar-icon",
|
|
26204
26377
|
icon: unref(icon),
|
|
@@ -26209,10 +26382,10 @@ var ToolbarButton_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/*
|
|
|
26209
26382
|
"name"
|
|
26210
26383
|
])) : createCommentVNode("", true),
|
|
26211
26384
|
unref(label) && !unref(hideLabel) && (!unref(inlineTextInputVisible) || itemName.value === "fontFamily") ? (openBlock(), createElementBlock("div", {
|
|
26212
|
-
key:
|
|
26385
|
+
key: 2,
|
|
26213
26386
|
class: normalizeClass(["sd-button-label", { "sd-visually-hidden": unref(inlineTextInputVisible) && itemName.value === "fontFamily" }])
|
|
26214
26387
|
}, toDisplayString(unref(label)), 3)) : createCommentVNode("", true),
|
|
26215
|
-
unref(inlineTextInputVisible) ? (openBlock(), createElementBlock("span",
|
|
26388
|
+
unref(inlineTextInputVisible) ? (openBlock(), createElementBlock("span", _hoisted_9$1, [unref(name) === "fontSize" ? withDirectives((openBlock(), createElementBlock("input", {
|
|
26216
26389
|
key: 0,
|
|
26217
26390
|
"onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => inlineTextInput.value = $event),
|
|
26218
26391
|
onKeydown: [withKeys(withModifiers(handleInlineInputEnter, ["stop", "prevent"]), ["enter"]), _cache[2] || (_cache[2] = withKeys(($event) => handleInlineInputTab($event), ["tab"]))],
|
|
@@ -26224,7 +26397,7 @@ var ToolbarButton_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/*
|
|
|
26224
26397
|
autocomplete: "off",
|
|
26225
26398
|
ref_key: "inlineInput",
|
|
26226
26399
|
ref: inlineInput
|
|
26227
|
-
}, null, 42,
|
|
26400
|
+
}, null, 42, _hoisted_10$1)), [[vModelText, inlineTextInput.value]]) : withDirectives((openBlock(), createElementBlock("input", {
|
|
26228
26401
|
key: 1,
|
|
26229
26402
|
"onUpdate:modelValue": _cache[5] || (_cache[5] = ($event) => inlineTextInput.value = $event),
|
|
26230
26403
|
placeholder: unref(label),
|
|
@@ -26241,20 +26414,20 @@ var ToolbarButton_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/*
|
|
|
26241
26414
|
autocomplete: "off",
|
|
26242
26415
|
ref_key: "inlineInput",
|
|
26243
26416
|
ref: inlineInput
|
|
26244
|
-
}, null, 42,
|
|
26417
|
+
}, null, 42, _hoisted_11$1)), [[vModelText, inlineTextInput.value]])])) : createCommentVNode("", true),
|
|
26245
26418
|
unref(hasCaret) ? (openBlock(), createElementBlock("div", {
|
|
26246
|
-
key:
|
|
26419
|
+
key: 4,
|
|
26247
26420
|
class: "sd-dropdown-caret",
|
|
26248
26421
|
"data-item": `btn-${unref(name) || ""}-toggle`,
|
|
26249
26422
|
innerHTML: caretIcon.value,
|
|
26250
26423
|
style: normalizeStyle({ opacity: unref(disabled) ? .6 : 1 })
|
|
26251
|
-
}, null, 12,
|
|
26424
|
+
}, null, 12, _hoisted_12$1)) : createCommentVNode("", true)
|
|
26252
26425
|
], 64)),
|
|
26253
|
-
createElementVNode("div",
|
|
26426
|
+
createElementVNode("div", _hoisted_13$1, toDisplayString(`${unref(attributes).ariaLabel} ${unref(active) ? "selected" : "unset"}`), 1)
|
|
26254
26427
|
], 10, _hoisted_2$11)], 46, _hoisted_1$15);
|
|
26255
26428
|
};
|
|
26256
26429
|
}
|
|
26257
|
-
}), [["__scopeId", "data-v-
|
|
26430
|
+
}), [["__scopeId", "data-v-b49ede12"]]);
|
|
26258
26431
|
//#endregion
|
|
26259
26432
|
//#region src/internal/toolbar/built-in/ToolbarSeparator.vue?vue&type=script&setup=true&lang.ts
|
|
26260
26433
|
var _hoisted_1$14 = {
|
|
@@ -26809,24 +26982,11 @@ var OverflowMenu_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/*
|
|
|
26809
26982
|
}
|
|
26810
26983
|
}), [["__scopeId", "data-v-d2e189fd"]]);
|
|
26811
26984
|
//#endregion
|
|
26812
|
-
//#region src/internal/toolbar/built-in/font-typeahead.
|
|
26813
|
-
/**
|
|
26814
|
-
* Pure typeahead/autocomplete helpers for the font comboboxes (family + size).
|
|
26815
|
-
*
|
|
26816
|
-
* Matching is case-insensitive prefix matching on the logical font labels.
|
|
26817
|
-
* Space is a normal query character, so the query is never split on spaces;
|
|
26818
|
-
* only the outer whitespace is ignored when comparing.
|
|
26819
|
-
*
|
|
26820
|
-
* These functions hold no Vue or DOM state so CI can unit-test them in isolation.
|
|
26821
|
-
*/
|
|
26985
|
+
//#region src/internal/toolbar/built-in/font-typeahead.ts
|
|
26822
26986
|
var normalize = (value) => String(value ?? "").trim().toLowerCase();
|
|
26823
26987
|
/**
|
|
26824
26988
|
* Index of the first label that starts with `query` (case-insensitive).
|
|
26825
|
-
* An empty/whitespace query never matches.
|
|
26826
|
-
*
|
|
26827
|
-
* @param {string} query
|
|
26828
|
-
* @param {ReadonlyArray<string>} labels
|
|
26829
|
-
* @returns {number} matching index or -1
|
|
26989
|
+
* An empty/whitespace query never matches. Returns the matching index or -1.
|
|
26830
26990
|
*/
|
|
26831
26991
|
var findPrefixMatchIndex = (query, labels) => {
|
|
26832
26992
|
const q = normalize(query);
|
|
@@ -26840,12 +27000,7 @@ var findPrefixMatchIndex = (query, labels) => {
|
|
|
26840
27000
|
* When `autocomplete` is true and a prefix match exists that is longer than the
|
|
26841
27001
|
* typed query, the completion is shown with the suffix selected so the next
|
|
26842
27002
|
* keystroke replaces it. When false (deletion) or no match exists, the raw
|
|
26843
|
-
* query is shown with the caret at its end.
|
|
26844
|
-
*
|
|
26845
|
-
* @param {string} query - the user-typed portion
|
|
26846
|
-
* @param {ReadonlyArray<string>} labels
|
|
26847
|
-
* @param {{ autocomplete?: boolean }} [options]
|
|
26848
|
-
* @returns {{ matchIndex: number, display: string, selectionStart: number, selectionEnd: number }}
|
|
27003
|
+
* query is shown with the caret at its end. `query` is the user-typed portion.
|
|
26849
27004
|
*/
|
|
26850
27005
|
var computeTypeahead = (query, labels, { autocomplete = true } = {}) => {
|
|
26851
27006
|
const typed = String(query ?? "");
|
|
@@ -26897,9 +27052,6 @@ var MAX_FONT_SIZE = 1638;
|
|
|
26897
27052
|
* the nearest half point (DOCX/Word support half points such as 10.5), and clamps
|
|
26898
27053
|
* to the supported range. Returns '' when nothing usable was typed, including
|
|
26899
27054
|
* negative or sub-minimum values.
|
|
26900
|
-
*
|
|
26901
|
-
* @param {string} value
|
|
26902
|
-
* @returns {string} point size (whole or half), or '' when empty/invalid
|
|
26903
27055
|
*/
|
|
26904
27056
|
var normalizeCustomFontSize = (value) => {
|
|
26905
27057
|
const cleaned = String(value ?? "").replace(/[^0-9.-]/g, "");
|
|
@@ -27567,7 +27719,7 @@ var SdTooltip_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__
|
|
|
27567
27719
|
]);
|
|
27568
27720
|
const contentStyle = computed$1(() => ({
|
|
27569
27721
|
...props.contentStyle,
|
|
27570
|
-
...attrs.style
|
|
27722
|
+
...attrs.style,
|
|
27571
27723
|
position: "fixed",
|
|
27572
27724
|
top: position.value.top,
|
|
27573
27725
|
left: position.value.left,
|
|
@@ -27736,7 +27888,7 @@ var SdTooltip_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__
|
|
|
27736
27888
|
}, 8, ["css"])]))], 64);
|
|
27737
27889
|
};
|
|
27738
27890
|
}
|
|
27739
|
-
}), [["__scopeId", "data-v-
|
|
27891
|
+
}), [["__scopeId", "data-v-87967ab1"]]);
|
|
27740
27892
|
//#endregion
|
|
27741
27893
|
//#region src/internal/toolbar/built-in/ButtonGroup.vue?vue&type=script&setup=true&lang.ts
|
|
27742
27894
|
var _hoisted_1$11 = [
|
|
@@ -28590,7 +28742,7 @@ var Toolbar_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__PU
|
|
|
28590
28742
|
}
|
|
28591
28743
|
}), [["__scopeId", "data-v-bce7c04a"]]);
|
|
28592
28744
|
//#endregion
|
|
28593
|
-
//#region src/internal/toolbar/built-in/font-options.
|
|
28745
|
+
//#region src/internal/toolbar/built-in/font-options.ts
|
|
28594
28746
|
/**
|
|
28595
28747
|
* Normalize a font dropdown option so each row renders in its own typeface.
|
|
28596
28748
|
*
|
|
@@ -28946,7 +29098,7 @@ var StyleButtonsList_default = /* @__PURE__ */ _plugin_vue_export_helper_default
|
|
|
28946
29098
|
}
|
|
28947
29099
|
}), [["__scopeId", "data-v-539d0995"]]);
|
|
28948
29100
|
//#endregion
|
|
28949
|
-
//#region src/internal/toolbar/built-in/list-style-buttons.
|
|
29101
|
+
//#region src/internal/toolbar/built-in/list-style-buttons.ts
|
|
28950
29102
|
var bulletStyleButtons = [
|
|
28951
29103
|
{
|
|
28952
29104
|
key: "disc",
|
|
@@ -30257,7 +30409,7 @@ var PageNumberMenu_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/
|
|
|
30257
30409
|
onClick: ($event) => selectTile(tile),
|
|
30258
30410
|
onDblclick: applyPageNumbers,
|
|
30259
30411
|
onKeydown: onTileKeydown
|
|
30260
|
-
}, [(openBlock(), createElementBlock("svg", _hoisted_5, [_cache[4] || (_cache[4] = createStaticVNode("<rect class=\"sd-page-number-menu__sheet\" x=\"0.75\" y=\"0.75\" width=\"34.5\" height=\"44.5\" rx=\"2.5\" data-v-
|
|
30412
|
+
}, [(openBlock(), createElementBlock("svg", _hoisted_5, [_cache[4] || (_cache[4] = createStaticVNode("<rect class=\"sd-page-number-menu__sheet\" x=\"0.75\" y=\"0.75\" width=\"34.5\" height=\"44.5\" rx=\"2.5\" data-v-e3105afd></rect><rect class=\"sd-page-number-menu__line\" x=\"7\" y=\"14\" width=\"22\" height=\"2\" rx=\"1\" data-v-e3105afd></rect><rect class=\"sd-page-number-menu__line\" x=\"7\" y=\"19\" width=\"18\" height=\"2\" rx=\"1\" data-v-e3105afd></rect><rect class=\"sd-page-number-menu__line\" x=\"7\" y=\"24\" width=\"22\" height=\"2\" rx=\"1\" data-v-e3105afd></rect><rect class=\"sd-page-number-menu__line\" x=\"7\" y=\"29\" width=\"14\" height=\"2\" rx=\"1\" data-v-e3105afd></rect>", 5)), createElementVNode("rect", {
|
|
30261
30413
|
class: "sd-page-number-menu__chip",
|
|
30262
30414
|
x: CHIP_X[tile.alignment],
|
|
30263
30415
|
y: CHIP_Y[tile.position],
|
|
@@ -30337,23 +30489,21 @@ var PageNumberMenu_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/
|
|
|
30337
30489
|
], 10, _hoisted_1);
|
|
30338
30490
|
};
|
|
30339
30491
|
}
|
|
30340
|
-
}), [["__scopeId", "data-v-
|
|
30492
|
+
}), [["__scopeId", "data-v-e3105afd"]]);
|
|
30341
30493
|
//#endregion
|
|
30342
|
-
//#region src/internal/toolbar/built-in/page-number-feedback.
|
|
30494
|
+
//#region src/internal/toolbar/built-in/page-number-feedback.ts
|
|
30343
30495
|
var FLASH_CLASS = "sd-page-number-flash";
|
|
30344
30496
|
var FLASH_MS = 1400;
|
|
30345
30497
|
var nextFrame = (view) => new Promise((resolve) => {
|
|
30346
|
-
if (typeof view
|
|
30498
|
+
if (typeof view.requestAnimationFrame === "function") view.requestAnimationFrame(() => resolve());
|
|
30347
30499
|
else setTimeout(resolve, 16);
|
|
30348
30500
|
});
|
|
30349
30501
|
/**
|
|
30350
30502
|
* Briefly highlight the painted header or footer regions that are on screen,
|
|
30351
30503
|
* so the user sees where page numbers landed without the caret leaving the
|
|
30352
30504
|
* body. Regions are read after the repaint that follows the mutation; nothing
|
|
30353
|
-
* happens when none is visible or the host is unavailable.
|
|
30354
|
-
*
|
|
30355
|
-
* @param {HTMLElement | null | undefined} host Document viewport host element.
|
|
30356
|
-
* @param {'header' | 'footer'} kind
|
|
30505
|
+
* happens when none is visible or the host is unavailable. `host` is the
|
|
30506
|
+
* document viewport host element.
|
|
30357
30507
|
*/
|
|
30358
30508
|
async function flashPageNumberRegions(host, kind) {
|
|
30359
30509
|
const view = host?.ownerDocument?.defaultView;
|
|
@@ -30361,7 +30511,7 @@ async function flashPageNumberRegions(host, kind) {
|
|
|
30361
30511
|
await nextFrame(view);
|
|
30362
30512
|
await nextFrame(view);
|
|
30363
30513
|
const viewportHeight = view.innerHeight;
|
|
30364
|
-
const regions =
|
|
30514
|
+
const regions = Array.from(host.querySelectorAll(`[data-sd-headerfooter-kind="${kind}"]`)).filter((region) => {
|
|
30365
30515
|
const rect = region.getBoundingClientRect();
|
|
30366
30516
|
return rect.height > 0 && rect.bottom > 0 && rect.top < viewportHeight;
|
|
30367
30517
|
});
|
|
@@ -30562,6 +30712,8 @@ var makeDefaultItems = ({ superToolbar, toolbarIcons: configuredIcons, toolbarTe
|
|
|
30562
30712
|
attributes: { ariaLabel: "Bold" }
|
|
30563
30713
|
});
|
|
30564
30714
|
const fontOptions = (toolbarFonts ?? TOOLBAR_FONTS).map(normalizeFontOption);
|
|
30715
|
+
const isFontOption = (option) => typeof option.label === "string" && typeof option.key === "string";
|
|
30716
|
+
const currentFontOptions = () => fontButton.nestedOptions.value.filter(isFontOption);
|
|
30565
30717
|
const fontButton = useToolbarItem({
|
|
30566
30718
|
type: "dropdown",
|
|
30567
30719
|
name: "fontFamily",
|
|
@@ -30588,8 +30740,9 @@ var makeDefaultItems = ({ superToolbar, toolbarIcons: configuredIcons, toolbarTe
|
|
|
30588
30740
|
if (typeof fontFamily !== "string" || !fontFamily) return;
|
|
30589
30741
|
const family = fontFamily.split(",")[0];
|
|
30590
30742
|
const optionValue = (option) => option.value ?? option.label;
|
|
30591
|
-
const
|
|
30592
|
-
const
|
|
30743
|
+
const options = currentFontOptions();
|
|
30744
|
+
const defaultFont = options.find((option) => optionValue(option) === fontButton.defaultLabel.value);
|
|
30745
|
+
const foundFont = options.find((option) => optionValue(option) === family);
|
|
30593
30746
|
if (foundFont) {
|
|
30594
30747
|
fontButton.label.value = foundFont.label;
|
|
30595
30748
|
fontButton.selectedValue.value = foundFont.key;
|
|
@@ -30602,7 +30755,7 @@ var makeDefaultItems = ({ superToolbar, toolbarIcons: configuredIcons, toolbarTe
|
|
|
30602
30755
|
}
|
|
30603
30756
|
},
|
|
30604
30757
|
onDeactivate: () => {
|
|
30605
|
-
const defaultFont =
|
|
30758
|
+
const defaultFont = currentFontOptions().find((option) => (option.value ?? option.label) === fontButton.defaultLabel.value);
|
|
30606
30759
|
fontButton.label.value = defaultFont?.label ?? fontButton.defaultLabel.value;
|
|
30607
30760
|
fontButton.selectedValue.value = defaultFont?.key ?? "";
|
|
30608
30761
|
}
|
|
@@ -31709,7 +31862,7 @@ var makeDefaultItems = ({ superToolbar, toolbarIcons: configuredIcons, toolbarTe
|
|
|
31709
31862
|
};
|
|
31710
31863
|
};
|
|
31711
31864
|
//#endregion
|
|
31712
|
-
//#region src/internal/toolbar/built-in/general.
|
|
31865
|
+
//#region src/internal/toolbar/built-in/general.ts
|
|
31713
31866
|
/**
|
|
31714
31867
|
* Minimal DOM helpers for the built-in toolbar shell.
|
|
31715
31868
|
*
|
|
@@ -31720,8 +31873,6 @@ var makeDefaultItems = ({ superToolbar, toolbarIcons: configuredIcons, toolbarTe
|
|
|
31720
31873
|
*/
|
|
31721
31874
|
/**
|
|
31722
31875
|
* Resolve a toolbar mount target from a selector string or element id.
|
|
31723
|
-
* @param {string|HTMLElement|null|undefined} selector
|
|
31724
|
-
* @returns {HTMLElement|null}
|
|
31725
31876
|
*/
|
|
31726
31877
|
var findElementBySelector = (selector) => {
|
|
31727
31878
|
if (!selector) return null;
|
|
@@ -31761,9 +31912,6 @@ function toSelectedValue(value) {
|
|
|
31761
31912
|
function nonEmptyString(value) {
|
|
31762
31913
|
return typeof value === "string" && value ? value : void 0;
|
|
31763
31914
|
}
|
|
31764
|
-
function isThenable(value) {
|
|
31765
|
-
return (typeof value === "object" || typeof value === "function") && value !== null && "then" in value && typeof value.then === "function";
|
|
31766
|
-
}
|
|
31767
31915
|
function isToolbarCommandCallback(value) {
|
|
31768
31916
|
return typeof value === "function";
|
|
31769
31917
|
}
|
|
@@ -31786,7 +31934,7 @@ function executeCommand(ui, commandId, argument, options = {}) {
|
|
|
31786
31934
|
if (!options.reportUnhandled || settled !== false) return;
|
|
31787
31935
|
options.onError?.(/* @__PURE__ */ new Error(`[superdoc toolbar] Command "${commandId}" did not run. Check that it is enabled and has the required input.`));
|
|
31788
31936
|
};
|
|
31789
|
-
if (isThenable(result)) Promise.resolve(result).then((settled) => {
|
|
31937
|
+
if (isThenable$1(result)) Promise.resolve(result).then((settled) => {
|
|
31790
31938
|
reportFailure(settled);
|
|
31791
31939
|
options.onSettled?.();
|
|
31792
31940
|
}, (error) => {
|
|
@@ -31819,7 +31967,7 @@ var V1_ENABLED_ON_SELECTION_REASON = /* @__PURE__ */ new Set([
|
|
|
31819
31967
|
]);
|
|
31820
31968
|
var V1_ENABLED_ON_EMPTY_REASON = /* @__PURE__ */ new Set(["list", "numberedlist"]);
|
|
31821
31969
|
function shouldKeepEnabledForV1ToolbarParity(name, commandState) {
|
|
31822
|
-
if (name === "fontFamily" || name === "fontSize") return
|
|
31970
|
+
if (name === "fontFamily" || name === "fontSize") return commandState?.reason !== "document-readonly";
|
|
31823
31971
|
if (V1_ENABLED_ON_EMPTY_REASON.has(name) && commandState?.disabled && commandState?.supported !== false && commandState?.reason == null) return true;
|
|
31824
31972
|
if (!V1_ENABLED_ON_SELECTION_REASON.has(name)) return false;
|
|
31825
31973
|
const reason = commandState?.reason;
|
|
@@ -32010,7 +32158,7 @@ var BuiltInToolbar = class extends import_eventemitter3.default {
|
|
|
32010
32158
|
const signature = this.#fontOptionsSignature();
|
|
32011
32159
|
if (signature !== this._lastFontOptionsSignature) {
|
|
32012
32160
|
this._lastFontOptionsSignature = signature;
|
|
32013
|
-
this.#rebuildToolbarItems();
|
|
32161
|
+
if (!this.#refreshFontFamilyOptions()) this.#rebuildToolbarItems();
|
|
32014
32162
|
}
|
|
32015
32163
|
this.updateToolbarState();
|
|
32016
32164
|
};
|
|
@@ -32138,7 +32286,7 @@ var BuiltInToolbar = class extends import_eventemitter3.default {
|
|
|
32138
32286
|
argument: payload.argument,
|
|
32139
32287
|
option: payload.option
|
|
32140
32288
|
});
|
|
32141
|
-
if (isThenable(result)) return Promise.resolve(result).catch((error) => {
|
|
32289
|
+
if (isThenable$1(result)) return Promise.resolve(result).catch((error) => {
|
|
32142
32290
|
this.#emitCommandException(error, config.name);
|
|
32143
32291
|
return false;
|
|
32144
32292
|
});
|
|
@@ -32158,6 +32306,13 @@ var BuiltInToolbar = class extends import_eventemitter3.default {
|
|
|
32158
32306
|
this.#makeToolbarItems();
|
|
32159
32307
|
this.emit("toolbar-items-changed");
|
|
32160
32308
|
}
|
|
32309
|
+
#refreshFontFamilyOptions() {
|
|
32310
|
+
const items = this.#getAllToolbarItems().filter((item) => item.name.value === "fontFamily");
|
|
32311
|
+
if (!items.length) return false;
|
|
32312
|
+
const options = (this.#resolveToolbarFonts(this.config.fonts) ?? TOOLBAR_FONTS).map(normalizeFontOption);
|
|
32313
|
+
for (const item of items) item.nestedOptions.value = options.map((option) => ({ ...option }));
|
|
32314
|
+
return true;
|
|
32315
|
+
}
|
|
32161
32316
|
#fontOptionsSignature() {
|
|
32162
32317
|
if (this.config.fonts) return "custom-fonts";
|
|
32163
32318
|
const options = this.superdoc?.fonts?.getFontFamilyOptions?.() ?? [];
|
|
@@ -32337,6 +32492,10 @@ var BuiltInToolbar = class extends import_eventemitter3.default {
|
|
|
32337
32492
|
const commandId = resolveBuiltInItemCommandId(name);
|
|
32338
32493
|
if (!commandId) return false;
|
|
32339
32494
|
const commandState = this.snapshot?.commands?.[commandId];
|
|
32495
|
+
if ((name === "list" || name === "numberedlist") && item.attributes.value.ariaBusy !== Boolean(commandState?.pending)) item.attributes.value = {
|
|
32496
|
+
...item.attributes.value,
|
|
32497
|
+
ariaBusy: Boolean(commandState?.pending)
|
|
32498
|
+
};
|
|
32340
32499
|
if (shouldKeepEnabledForV1ToolbarParity(name, commandState)) item.setDisabled(false);
|
|
32341
32500
|
else item.setDisabled(Boolean(commandState?.disabled));
|
|
32342
32501
|
const handlers = {
|
|
@@ -32615,7 +32774,7 @@ var BuiltInToolbar = class extends import_eventemitter3.default {
|
|
|
32615
32774
|
ui: this.ui,
|
|
32616
32775
|
superdoc: this.superdoc
|
|
32617
32776
|
});
|
|
32618
|
-
if (isThenable(result)) Promise.resolve(result).catch((error) => this.#emitCommandException(error, name));
|
|
32777
|
+
if (isThenable$1(result)) Promise.resolve(result).catch((error) => this.#emitCommandException(error, name));
|
|
32619
32778
|
}
|
|
32620
32779
|
this.updateToolbarState();
|
|
32621
32780
|
return;
|
|
@@ -32881,6 +33040,7 @@ var SuperDoc = class extends import_eventemitter3.default {
|
|
|
32881
33040
|
#v2ConnectionUnsub;
|
|
32882
33041
|
/** Latest `collaboration-connection-change` payload, for late readers. */
|
|
32883
33042
|
#v2ConnectionState;
|
|
33043
|
+
#v2ConnectionFailureReported;
|
|
32884
33044
|
/** Whether the current collaboration room has completed a sync at least once. */
|
|
32885
33045
|
#v2ConnectionHasSynced;
|
|
32886
33046
|
/** Lock state captured before a local → v2 collaboration promotion remount. */
|
|
@@ -32983,6 +33143,7 @@ var SuperDoc = class extends import_eventemitter3.default {
|
|
|
32983
33143
|
this.#v2LockUnsub = null;
|
|
32984
33144
|
this.#v2ConnectionUnsub = null;
|
|
32985
33145
|
this.#v2ConnectionState = null;
|
|
33146
|
+
this.#v2ConnectionFailureReported = false;
|
|
32986
33147
|
this.#v2ConnectionHasSynced = false;
|
|
32987
33148
|
this.#pendingV2LockSeed = null;
|
|
32988
33149
|
this.#mountWrapper = null;
|
|
@@ -33185,7 +33346,7 @@ var SuperDoc = class extends import_eventemitter3.default {
|
|
|
33185
33346
|
}
|
|
33186
33347
|
this.userColorMap = /* @__PURE__ */ new Map();
|
|
33187
33348
|
this.colorIndex = 0;
|
|
33188
|
-
this.version = "2.
|
|
33349
|
+
this.version = "2.30.0-next.4";
|
|
33189
33350
|
this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
|
|
33190
33351
|
this.superdocId = config.superdocId || v4();
|
|
33191
33352
|
this.colors = this.config.colors ?? [];
|
|
@@ -33604,6 +33765,7 @@ var SuperDoc = class extends import_eventemitter3.default {
|
|
|
33604
33765
|
if (this.#v2ConnectionState?.documentId !== documentId) {
|
|
33605
33766
|
this.#v2ConnectionState = null;
|
|
33606
33767
|
this.#v2ConnectionHasSynced = false;
|
|
33768
|
+
this.#v2ConnectionFailureReported = false;
|
|
33607
33769
|
}
|
|
33608
33770
|
const publish = (snapshot) => {
|
|
33609
33771
|
if (this.#destroyed) return;
|
|
@@ -33618,8 +33780,21 @@ var SuperDoc = class extends import_eventemitter3.default {
|
|
|
33618
33780
|
superdoc: this
|
|
33619
33781
|
};
|
|
33620
33782
|
this.#v2ConnectionState = payload;
|
|
33621
|
-
if (snapshot.state === "synced")
|
|
33622
|
-
|
|
33783
|
+
if (snapshot.state === "synced") {
|
|
33784
|
+
this.#v2ConnectionHasSynced = true;
|
|
33785
|
+
this.#v2ConnectionFailureReported = false;
|
|
33786
|
+
}
|
|
33787
|
+
const firstFailure = snapshot.state === "failed" && !this.#v2ConnectionFailureReported;
|
|
33788
|
+
if (firstFailure) this.#v2ConnectionFailureReported = true;
|
|
33789
|
+
const reportFailure = firstFailure && snapshot.detail !== "worker-transport-failed";
|
|
33790
|
+
try {
|
|
33791
|
+
this.emit("collaboration-connection-change", payload);
|
|
33792
|
+
} finally {
|
|
33793
|
+
if (reportFailure) {
|
|
33794
|
+
const exception = createCollaborationException("collaboration-connection-failed", documentId);
|
|
33795
|
+
if (exception) this.emit("exception", exception);
|
|
33796
|
+
}
|
|
33797
|
+
}
|
|
33623
33798
|
};
|
|
33624
33799
|
try {
|
|
33625
33800
|
const initialSnapshot = connection.getSnapshot?.();
|