superdoc 2.29.0-next.9 → 2.30.0-next.13
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-Bm5kmx0W.es.js → create-super-doc-ui--o8TcYYv.es.js} +3322 -2729
- package/dist/chunks/{create-super-doc-ui-DN70aatf.cjs → create-super-doc-ui-CvK1JdZv.cjs} +3447 -2854
- 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/comments/comment-create-attribution.d.ts +4 -0
- package/dist/document-api/src/comments/comments.types.d.ts +4 -0
- package/dist/document-api/src/contract/command-catalog.d.ts +1 -1
- package/dist/document-api/src/contract/operation-definitions.d.ts +76 -8
- package/dist/document-api/src/contract/operation-registry.d.ts +2 -2
- package/dist/document-api/src/contract/schemas.d.ts +7 -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 +13 -1
- 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/document-api/src/paragraphs/paragraphs.d.ts +8 -3
- package/dist/document-api/src/paragraphs/paragraphs.types.d.ts +49 -5
- package/dist/document-api/src/tables/data/table-preset-appearance.generated.d.ts +2 -0
- package/dist/document-api/src/tables/table-style-presets.d.ts +73 -0
- package/dist/document-api/src/tables/tables.d.ts +4 -1
- package/dist/document-api/src/types/sd-props.d.ts +7 -0
- package/dist/document-api/src/types/table-operations.types.d.ts +12 -15
- package/dist/layout-engine/contracts/src/index.d.ts +4 -1
- package/dist/layout-engine/contracts/src/table-cell-vector-overlay.d.ts +2 -0
- 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/index.d.ts +2 -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-sidebar.d.ts +6 -0
- 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/config/normalize-interaction-config.d.ts +10 -1
- package/dist/superdoc/src/core/document-open-telemetry.d.ts +1 -1
- package/dist/superdoc/src/core/editor-runtime/types.d.ts +4 -0
- 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 +147 -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 +20 -0
- package/dist/superdoc/src/public/index.d.ts +4 -1
- 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/commands.d.ts +5 -1
- 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-paragraph.d.ts +7 -0
- package/dist/superdoc/src/public/ui/format-painter-state.d.ts +29 -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 +80 -0
- package/dist/superdoc/src/public/ui/loose-record.d.ts +4 -0
- package/dist/superdoc/src/public/ui/reasons.d.ts +1 -0
- package/dist/superdoc/src/public/ui/selection-targets.d.ts +53 -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 +25 -2
- package/dist/superdoc/src/public/ui/ui-bench-timing.d.ts +9 -0
- package/dist/superdoc/src/public/ui.d.cts +18 -0
- package/dist/superdoc/src/public/ui.d.ts +1 -1
- package/dist/superdoc/src/stores/comments-store.d.ts +23028 -552
- 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 +91 -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 +1330 -972
- package/dist/superdoc.es.js +1242 -884
- 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--o8TcYYv.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.13";
|
|
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,136 @@ 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
|
+
new TextEncoder();
|
|
6832
|
+
function normalizeCommentIdentity(value) {
|
|
6833
|
+
if (value === null) return null;
|
|
6834
|
+
if (typeof value !== "object" || Array.isArray(value) || !("providerId" in value) || !("userId" in value) || !xmlIdentityString(value.providerId) || !xmlIdentityString(value.userId)) throw new TypeError("commentIdentity requires XML-safe non-empty providerId and userId strings.");
|
|
6835
|
+
return {
|
|
6836
|
+
providerId: value.providerId,
|
|
6837
|
+
userId: value.userId
|
|
6838
|
+
};
|
|
6839
|
+
}
|
|
6840
|
+
function xmlIdentityString(value) {
|
|
6841
|
+
return typeof value === "string" && value.trim().length > 0 && !/[^\u0009\u000A\u000D\u0020-\uD7FF\uE000-\uFFFD\u{10000}-\u{10FFFF}]/u.test(value);
|
|
6842
|
+
}
|
|
6843
|
+
//#endregion
|
|
6844
|
+
//#region ../document-api/src/permission-ranges/permission-ranges.ts
|
|
6845
|
+
function editorKey(editor) {
|
|
6846
|
+
return editor.id?.trim() ? editor.id : editor.email?.trim() || void 0;
|
|
6847
|
+
}
|
|
6848
|
+
function editorMatches(editor, id) {
|
|
6849
|
+
return Boolean(id.trim()) && (editor.id === id || Boolean(editor.email?.trim() && editor.email.trim().toLowerCase() === id.toLowerCase()));
|
|
6850
|
+
}
|
|
6851
|
+
/**
|
|
6852
|
+
* Resolve a host ID or imported Word email against an explicitly supplied roster.
|
|
6853
|
+
* Word receives the email when available; opaque IDs remain host-specific.
|
|
6854
|
+
* Duplicate IDs/emails are ambiguous. This does not authenticate a user.
|
|
6855
|
+
*/
|
|
6856
|
+
function resolvePermissionRangeEditor(editors, id) {
|
|
6857
|
+
const matches = editors.filter((editor) => editorMatches(editor, id));
|
|
6858
|
+
if (matches.length === 0) return {
|
|
6859
|
+
status: "unknown",
|
|
6860
|
+
id
|
|
6861
|
+
};
|
|
6862
|
+
if (matches.length !== 1) return {
|
|
6863
|
+
status: "ambiguous",
|
|
6864
|
+
id
|
|
6865
|
+
};
|
|
6866
|
+
const editor = matches[0];
|
|
6867
|
+
const wordId = editor.email?.trim() || editor.id;
|
|
6868
|
+
if (editors.filter((candidate) => editorMatches(candidate, wordId)).length !== 1) return {
|
|
6869
|
+
status: "ambiguous",
|
|
6870
|
+
id
|
|
6871
|
+
};
|
|
6872
|
+
return {
|
|
6873
|
+
status: "resolved",
|
|
6874
|
+
id,
|
|
6875
|
+
editor: { ...editor },
|
|
6876
|
+
principal: {
|
|
6877
|
+
kind: "editor",
|
|
6878
|
+
id: wordId
|
|
6879
|
+
}
|
|
6880
|
+
};
|
|
6881
|
+
}
|
|
6882
|
+
/** Enumerate the host roster for an editor picker, including ambiguous entries. */
|
|
6883
|
+
function listPermissionRangeEditors(editors) {
|
|
6884
|
+
const ids = new Set(editors.map(editorKey).filter((id) => id !== void 0));
|
|
6885
|
+
return Array.from(ids, (id) => resolvePermissionRangeEditor(editors, id));
|
|
6886
|
+
}
|
|
6887
|
+
//#endregion
|
|
6753
6888
|
//#region src/stores/helpers/floating-comment-instances.ts
|
|
6754
6889
|
var HEADER_FOOTER_TRACKED_CHANGE_STORY_TYPE = "headerFooterPart";
|
|
6755
6890
|
var toFinitePageIndex = (value) => {
|
|
@@ -6890,23 +7025,76 @@ var buildFloatingCommentInstances = ({ comment, positionKey, positionEntry, fall
|
|
|
6890
7025
|
})];
|
|
6891
7026
|
};
|
|
6892
7027
|
//#endregion
|
|
6893
|
-
//#region src/
|
|
7028
|
+
//#region src/stores/helpers/comment-document-scope.ts
|
|
7029
|
+
var getCommentDocumentId = (comment) => {
|
|
7030
|
+
if (!comment) return null;
|
|
7031
|
+
if (comment.fileId != null) return String(comment.fileId);
|
|
7032
|
+
if (comment.documentId != null) return String(comment.documentId);
|
|
7033
|
+
if (comment.selection?.documentId != null) return String(comment.selection.documentId);
|
|
7034
|
+
return null;
|
|
7035
|
+
};
|
|
7036
|
+
var createCommentDocumentScope = (readOpenDocuments) => {
|
|
7037
|
+
const getOpenDocuments = () => {
|
|
7038
|
+
const source = readOpenDocuments();
|
|
7039
|
+
const docs = Array.isArray(source) ? source : source?.value;
|
|
7040
|
+
return Array.isArray(docs) ? docs : [];
|
|
7041
|
+
};
|
|
7042
|
+
const getSingleOpenDocumentId = () => {
|
|
7043
|
+
const docs = getOpenDocuments();
|
|
7044
|
+
if (docs.length !== 1) return null;
|
|
7045
|
+
return docs[0]?.id != null ? String(docs[0].id) : null;
|
|
7046
|
+
};
|
|
7047
|
+
const belongsToDocument = (comment, activeDocumentId, options = {}) => {
|
|
7048
|
+
const { allowSingleDocumentMismatch = false } = options;
|
|
7049
|
+
if (!activeDocumentId) return false;
|
|
7050
|
+
const commentDocumentId = getCommentDocumentId(comment);
|
|
7051
|
+
if (commentDocumentId) {
|
|
7052
|
+
if (commentDocumentId === activeDocumentId) return true;
|
|
7053
|
+
const singleOpenDocumentId = getSingleOpenDocumentId();
|
|
7054
|
+
return allowSingleDocumentMismatch && singleOpenDocumentId === activeDocumentId;
|
|
7055
|
+
}
|
|
7056
|
+
return getSingleOpenDocumentId() === activeDocumentId;
|
|
7057
|
+
};
|
|
7058
|
+
const belongsToTrackedChangeSyncDocument = (comment, activeDocumentId) => belongsToDocument(comment, activeDocumentId, { allowSingleDocumentMismatch: true });
|
|
7059
|
+
return {
|
|
7060
|
+
belongsToDocument,
|
|
7061
|
+
belongsToTrackedChangeSyncDocument
|
|
7062
|
+
};
|
|
7063
|
+
};
|
|
7064
|
+
//#endregion
|
|
7065
|
+
//#region src/stores/helpers/pending-selection-snapshot.ts
|
|
7066
|
+
var isThenable = (value) => (typeof value === "object" || typeof value === "function") && value !== null && "then" in value && typeof value.then === "function";
|
|
7067
|
+
var getPendingSelectionSnapshot = (superdoc, activeSelection) => {
|
|
7068
|
+
if (activeSelection?.source !== "document-editor") return null;
|
|
7069
|
+
const selectionDocumentId = activeSelection?.documentId ?? null;
|
|
7070
|
+
const editorDocumentId = superdoc?.activeEditor?.options?.documentId ?? null;
|
|
7071
|
+
if (!selectionDocumentId || !editorDocumentId || selectionDocumentId !== editorDocumentId) return null;
|
|
7072
|
+
let currentSelection;
|
|
7073
|
+
try {
|
|
7074
|
+
currentSelection = superdoc?.activeEditor?.doc?.selection?.current;
|
|
7075
|
+
} catch {
|
|
7076
|
+
return null;
|
|
7077
|
+
}
|
|
7078
|
+
if (typeof currentSelection !== "function") return null;
|
|
7079
|
+
try {
|
|
7080
|
+
const snapshot = currentSelection();
|
|
7081
|
+
return isThenable(snapshot) ? Promise.resolve(snapshot).catch(() => null) : snapshot;
|
|
7082
|
+
} catch {
|
|
7083
|
+
return null;
|
|
7084
|
+
}
|
|
7085
|
+
};
|
|
7086
|
+
//#endregion
|
|
7087
|
+
//#region src/components/CommentsLayer/tracked-change-threading.ts
|
|
6894
7088
|
/**
|
|
6895
7089
|
* Legacy comment payloads predate explicit tracked-change thread provenance.
|
|
6896
7090
|
* These fields distinguish a true legacy review child from a v2 comment whose
|
|
6897
7091
|
* anchor merely overlaps tracked content.
|
|
6898
|
-
*
|
|
6899
|
-
* @param {Record<string, any> | null | undefined} comment
|
|
6900
|
-
* @returns {boolean}
|
|
6901
7092
|
*/
|
|
6902
7093
|
var hasLegacyTrackedChangeThreadSignal = (comment) => Boolean(comment?.trackedChangeLink) || Boolean(comment?.trackedChangeType) || Boolean(comment?.trackedChangeDisplayType) || Boolean(comment?.trackedChangeText) || Boolean(comment?.deletedText) || comment?.trackedChange === true;
|
|
6903
7094
|
/**
|
|
6904
7095
|
* Resolve explicit thread provenance first, then the guarded legacy fallback.
|
|
6905
7096
|
* Spatial-only v2 comments carry neither the explicit field nor a legacy
|
|
6906
7097
|
* review signal and therefore remain standalone.
|
|
6907
|
-
*
|
|
6908
|
-
* @param {Record<string, any> | null | undefined} comment
|
|
6909
|
-
* @returns {string | number | null}
|
|
6910
7098
|
*/
|
|
6911
7099
|
var trackedChangeThreadParentIdForComment$1 = (comment) => {
|
|
6912
7100
|
if (comment?.trackedChangeThreadParentId != null) return comment.trackedChangeThreadParentId;
|
|
@@ -7058,6 +7246,7 @@ var groupCommittedComments = (comments, presentations, isVisible) => {
|
|
|
7058
7246
|
});
|
|
7059
7247
|
const grouped = groupComments(comments.filter((row) => !presentations[String(row.fileId)]), isVisible);
|
|
7060
7248
|
for (const [documentId, presentation] of Object.entries(presentations)) {
|
|
7249
|
+
if (!presentation) continue;
|
|
7061
7250
|
grouped.parentComments.push(...visibleRowsInOrder(documentId, presentation.groupOrder.open));
|
|
7062
7251
|
grouped.resolvedComments.push(...visibleRowsInOrder(documentId, presentation.groupOrder.resolved));
|
|
7063
7252
|
}
|
|
@@ -7185,7 +7374,6 @@ function createDefaultV2Integration() {
|
|
|
7185
7374
|
//#region src/helpers/interaction-trace.ts
|
|
7186
7375
|
var isStartSpan = (value) => typeof value === "function";
|
|
7187
7376
|
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
7377
|
function safeTraceCollector() {
|
|
7190
7378
|
try {
|
|
7191
7379
|
const collector = Reflect.get(globalThis, "__superdocInteractionTrace");
|
|
@@ -7216,7 +7404,7 @@ function withInteractionSpan(stage, branch, meta, fn) {
|
|
|
7216
7404
|
if (!span) return fn();
|
|
7217
7405
|
try {
|
|
7218
7406
|
const result = fn();
|
|
7219
|
-
if (isThenable$
|
|
7407
|
+
if (isThenable$1(result)) return result.then((value) => {
|
|
7220
7408
|
endInteractionSpan(span);
|
|
7221
7409
|
return value;
|
|
7222
7410
|
}, (error) => {
|
|
@@ -7231,6 +7419,81 @@ function withInteractionSpan(stage, branch, meta, fn) {
|
|
|
7231
7419
|
}
|
|
7232
7420
|
}
|
|
7233
7421
|
//#endregion
|
|
7422
|
+
//#region src/stores/helpers/tracked-change-decision.ts
|
|
7423
|
+
var normalizeTrackedChangeDecisionType = (value) => {
|
|
7424
|
+
const lower = typeof value === "string" ? value.toLowerCase() : "";
|
|
7425
|
+
if (!lower) return null;
|
|
7426
|
+
if (lower === "insert" || lower === "insertion" || lower === "trackinsert" || lower === "tableinsert" || lower === "paragraphsplit") return "insertion";
|
|
7427
|
+
if (lower === "delete" || lower === "deletion" || lower === "trackdelete" || lower === "tabledelete") return "deletion";
|
|
7428
|
+
return lower;
|
|
7429
|
+
};
|
|
7430
|
+
var trackedChangeDecisionKeepsCommentAnchor = ({ comment, decision } = {}) => {
|
|
7431
|
+
const normalizedDecision = decision === "accept" || decision === "reject" ? decision : null;
|
|
7432
|
+
if (!normalizedDecision) return false;
|
|
7433
|
+
const type = normalizeTrackedChangeDecisionType(comment?.trackedChangeDisplayType) ?? normalizeTrackedChangeDecisionType(comment?.trackedChangeType);
|
|
7434
|
+
return normalizedDecision === "accept" && type === "insertion" || normalizedDecision === "reject" && type === "deletion";
|
|
7435
|
+
};
|
|
7436
|
+
var collectTrackedChangeDecisionIdsWithAliases = (comment, aliasIds) => {
|
|
7437
|
+
const trackedChangeIds = new Set(aliasIds);
|
|
7438
|
+
if (comment?.trackedChangeCanonicalId != null) trackedChangeIds.add(String(comment.trackedChangeCanonicalId));
|
|
7439
|
+
const anchorKey = comment?.trackedChangeAnchorKey != null ? String(comment.trackedChangeAnchorKey) : null;
|
|
7440
|
+
if (anchorKey) {
|
|
7441
|
+
trackedChangeIds.add(anchorKey);
|
|
7442
|
+
if (anchorKey.startsWith("tc::")) {
|
|
7443
|
+
const rawId = anchorKey.slice(anchorKey.lastIndexOf("::") + 2);
|
|
7444
|
+
if (rawId) trackedChangeIds.add(rawId);
|
|
7445
|
+
}
|
|
7446
|
+
}
|
|
7447
|
+
return trackedChangeIds;
|
|
7448
|
+
};
|
|
7449
|
+
var collectTrackedChangeEntityIdsFromReceipt = (receipt) => {
|
|
7450
|
+
const record = receipt && typeof receipt === "object" ? receipt : null;
|
|
7451
|
+
if (!record?.success) return /* @__PURE__ */ new Set();
|
|
7452
|
+
const ids = /* @__PURE__ */ new Set();
|
|
7453
|
+
const collect = (entry) => {
|
|
7454
|
+
const ref = entry && typeof entry === "object" ? entry : null;
|
|
7455
|
+
if (ref?.kind !== "entity" || ref.entityType !== "trackedChange") return;
|
|
7456
|
+
if (ref.entityId != null && String(ref.entityId).length > 0) ids.add(String(ref.entityId));
|
|
7457
|
+
};
|
|
7458
|
+
if (Array.isArray(record.removed)) record.removed.forEach(collect);
|
|
7459
|
+
if (Array.isArray(record.invalidatedRefs)) record.invalidatedRefs.forEach(collect);
|
|
7460
|
+
return ids;
|
|
7461
|
+
};
|
|
7462
|
+
var collectReliableDecidedTrackedChangeIds = (outcome) => {
|
|
7463
|
+
const ids = /* @__PURE__ */ new Set();
|
|
7464
|
+
if (outcome?.decidedId != null && String(outcome.decidedId).length > 0) ids.add(String(outcome.decidedId));
|
|
7465
|
+
if (Array.isArray(outcome?.decidedIds)) outcome.decidedIds.forEach((id) => {
|
|
7466
|
+
if (id != null && String(id).length > 0) ids.add(String(id));
|
|
7467
|
+
});
|
|
7468
|
+
collectTrackedChangeEntityIdsFromReceipt(outcome?.receipt).forEach((id) => ids.add(id));
|
|
7469
|
+
return ids;
|
|
7470
|
+
};
|
|
7471
|
+
var clearV2ActiveTrackedChangeTarget = (adapter, decidedId) => {
|
|
7472
|
+
if (!decidedId || typeof adapter?.clearActiveTrackedChangeTargetIfMatches !== "function") return;
|
|
7473
|
+
try {
|
|
7474
|
+
adapter.clearActiveTrackedChangeTargetIfMatches(decidedId);
|
|
7475
|
+
} catch {}
|
|
7476
|
+
};
|
|
7477
|
+
var waitForTrackedDecisionCanonicalPaint = async ({ superdoc, receipt } = {}) => {
|
|
7478
|
+
const readiness = superdoc?.activeEditor?.documentMutationReadiness;
|
|
7479
|
+
if (receipt?.success !== true || typeof receipt?.txId !== "string" || !receipt.txId || typeof readiness?.whenPainted !== "function") return;
|
|
7480
|
+
try {
|
|
7481
|
+
await readiness.whenPainted(receipt);
|
|
7482
|
+
const requestFrame = globalThis.requestAnimationFrame;
|
|
7483
|
+
if (typeof requestFrame === "function") await new Promise((resolve) => {
|
|
7484
|
+
let settled = false;
|
|
7485
|
+
const finish = () => {
|
|
7486
|
+
if (settled) return;
|
|
7487
|
+
settled = true;
|
|
7488
|
+
clearTimeout(fallback);
|
|
7489
|
+
resolve();
|
|
7490
|
+
};
|
|
7491
|
+
const fallback = setTimeout(finish, 250);
|
|
7492
|
+
requestFrame(() => requestFrame(() => setTimeout(finish, 0)));
|
|
7493
|
+
});
|
|
7494
|
+
} catch {}
|
|
7495
|
+
};
|
|
7496
|
+
//#endregion
|
|
7234
7497
|
//#region src/stores/helpers/comment-draft-text.ts
|
|
7235
7498
|
var COMMENT_DRAFT_BR_TAG = /<br(?:\s[^>]*)?\s*\/?>/gi;
|
|
7236
7499
|
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 +7866,131 @@ var cloneV2TrackedChangeStory = (story) => {
|
|
|
7603
7866
|
};
|
|
7604
7867
|
};
|
|
7605
7868
|
//#endregion
|
|
7606
|
-
//#region src/stores/
|
|
7869
|
+
//#region src/stores/helpers/tracked-change-compaction.ts
|
|
7870
|
+
var isPresentId = (id) => Boolean(id);
|
|
7871
|
+
var getBodyTrackedChangeIdentityIds = (comment) => {
|
|
7872
|
+
return [normalizeCommentId(comment.commentId), ...!normalizeCommentId(comment.trackedChangeCanonicalId) ? [
|
|
7873
|
+
comment.importedId,
|
|
7874
|
+
comment.trackedChangeAnchorKey,
|
|
7875
|
+
...normalizeTrackedChangePositionAliases(comment.trackedChangePositionAliases)
|
|
7876
|
+
] : []].map((id) => normalizeCommentId(id)).filter(isPresentId);
|
|
7877
|
+
};
|
|
7878
|
+
var groupBodyTrackedChangeCommentsByIdentity = (comments) => {
|
|
7879
|
+
const parents = comments.map((_, index) => index);
|
|
7880
|
+
const findRoot = (index) => {
|
|
7881
|
+
let root = index;
|
|
7882
|
+
while (parents[root] !== root) root = parents[root];
|
|
7883
|
+
while (parents[index] !== index) {
|
|
7884
|
+
const next = parents[index];
|
|
7885
|
+
parents[index] = root;
|
|
7886
|
+
index = next;
|
|
7887
|
+
}
|
|
7888
|
+
return root;
|
|
7889
|
+
};
|
|
7890
|
+
const join = (left, right) => {
|
|
7891
|
+
const leftRoot = findRoot(left);
|
|
7892
|
+
const rightRoot = findRoot(right);
|
|
7893
|
+
if (leftRoot === rightRoot) return;
|
|
7894
|
+
parents[Math.max(leftRoot, rightRoot)] = Math.min(leftRoot, rightRoot);
|
|
7895
|
+
};
|
|
7896
|
+
const identityOwner = /* @__PURE__ */ new Map();
|
|
7897
|
+
comments.forEach((comment, index) => {
|
|
7898
|
+
getBodyTrackedChangeIdentityIds(comment).forEach((identityId) => {
|
|
7899
|
+
const owner = identityOwner.get(identityId);
|
|
7900
|
+
if (owner === void 0) identityOwner.set(identityId, index);
|
|
7901
|
+
else join(index, owner);
|
|
7902
|
+
});
|
|
7903
|
+
});
|
|
7904
|
+
const groups = /* @__PURE__ */ new Map();
|
|
7905
|
+
comments.forEach((comment, index) => {
|
|
7906
|
+
const root = findRoot(index);
|
|
7907
|
+
const group = groups.get(root) ?? [];
|
|
7908
|
+
group.push(comment);
|
|
7909
|
+
groups.set(root, group);
|
|
7910
|
+
});
|
|
7911
|
+
return groups;
|
|
7912
|
+
};
|
|
7913
|
+
var mergeDuplicateBodyTrackedChangeComments = (groups) => {
|
|
7914
|
+
const duplicates = /* @__PURE__ */ new Map();
|
|
7915
|
+
groups.forEach(([survivor, ...duplicateRows]) => {
|
|
7916
|
+
if (!survivor || duplicateRows.length === 0) return;
|
|
7917
|
+
const resolvedDuplicate = duplicateRows.find((comment) => comment.resolvedTime != null);
|
|
7918
|
+
if (survivor.resolvedTime == null && resolvedDuplicate) {
|
|
7919
|
+
survivor.resolvedTime = resolvedDuplicate.resolvedTime;
|
|
7920
|
+
survivor.resolvedById = resolvedDuplicate.resolvedById;
|
|
7921
|
+
survivor.resolvedByEmail = resolvedDuplicate.resolvedByEmail;
|
|
7922
|
+
survivor.resolvedByName = resolvedDuplicate.resolvedByName;
|
|
7923
|
+
survivor.trackedChangeDecision = resolvedDuplicate.trackedChangeDecision;
|
|
7924
|
+
}
|
|
7925
|
+
survivor.trackedChangePositionAliases = normalizeTrackedChangePositionAliases([...normalizeTrackedChangePositionAliases(survivor.trackedChangePositionAliases), ...duplicateRows.flatMap((comment) => [
|
|
7926
|
+
comment.commentId,
|
|
7927
|
+
comment.importedId,
|
|
7928
|
+
comment.trackedChangeCanonicalId,
|
|
7929
|
+
...normalizeTrackedChangePositionAliases(comment.trackedChangePositionAliases)
|
|
7930
|
+
])]);
|
|
7931
|
+
duplicateRows.forEach((comment) => duplicates.set(comment, survivor));
|
|
7932
|
+
});
|
|
7933
|
+
return duplicates;
|
|
7934
|
+
};
|
|
7935
|
+
var createDroppedCommentIdMap = (duplicates) => {
|
|
7936
|
+
const droppedCommentIds = /* @__PURE__ */ new Map();
|
|
7937
|
+
duplicates.forEach((survivor, duplicate) => {
|
|
7938
|
+
const fromId = normalizeCommentId(duplicate.commentId);
|
|
7939
|
+
const toId = normalizeCommentId(survivor.commentId);
|
|
7940
|
+
if (fromId && toId) droppedCommentIds.set(fromId, toId);
|
|
7941
|
+
});
|
|
7942
|
+
return droppedCommentIds;
|
|
7943
|
+
};
|
|
7944
|
+
//#endregion
|
|
7945
|
+
//#region src/stores/helpers/v2-review-adapters.ts
|
|
7946
|
+
var COMMENTS_ADAPTER_METHODS = [
|
|
7947
|
+
"setActiveComment",
|
|
7948
|
+
"commitPendingComment",
|
|
7949
|
+
"reply",
|
|
7950
|
+
"edit",
|
|
7951
|
+
"resolve",
|
|
7952
|
+
"reopen",
|
|
7953
|
+
"delete",
|
|
7954
|
+
"mapV2CommentToUseCommentInput"
|
|
7955
|
+
];
|
|
7956
|
+
var COMMENTS_ADAPTER_OPTIONAL_METHODS = [
|
|
7957
|
+
"getCapabilityState",
|
|
7958
|
+
"captureCurrentSelection",
|
|
7959
|
+
"isPendingCommentCreation",
|
|
7960
|
+
"seedReviewCatalog",
|
|
7961
|
+
"selectVisibleReviewComments"
|
|
7962
|
+
];
|
|
7963
|
+
var TRACKED_CHANGES_ADAPTER_METHODS = [
|
|
7964
|
+
"accept",
|
|
7965
|
+
"reject",
|
|
7966
|
+
"mapV2TrackedChangeToCommentParams"
|
|
7967
|
+
];
|
|
7968
|
+
var TRACKED_CHANGES_ADAPTER_OPTIONAL_METHODS = ["clearActiveTrackedChangeTargetIfMatches"];
|
|
7969
|
+
var isAdapterDocumentId = (value) => value === void 0 || value === null || typeof value === "string" || typeof value === "number";
|
|
7970
|
+
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");
|
|
7971
|
+
function isV2CommentsAdapter(value) {
|
|
7972
|
+
return hasAdapterShape(value, COMMENTS_ADAPTER_METHODS, COMMENTS_ADAPTER_OPTIONAL_METHODS);
|
|
7973
|
+
}
|
|
7974
|
+
function isV2TrackedChangesAdapter(value) {
|
|
7975
|
+
return hasAdapterShape(value, TRACKED_CHANGES_ADAPTER_METHODS, TRACKED_CHANGES_ADAPTER_OPTIONAL_METHODS);
|
|
7976
|
+
}
|
|
7977
|
+
//#endregion
|
|
7978
|
+
//#region src/stores/comments-store.ts
|
|
7979
|
+
var requireHost = (superdoc, action) => {
|
|
7980
|
+
if (!superdoc) throw new TypeError(`${action} requires superdoc`);
|
|
7981
|
+
return superdoc;
|
|
7982
|
+
};
|
|
7983
|
+
var PARENT_LINK_FIELDS = [
|
|
7984
|
+
"trackedChangeThreadParentId",
|
|
7985
|
+
"trackedChangeParentId",
|
|
7986
|
+
"threadingParentCommentId",
|
|
7987
|
+
"parentCommentId"
|
|
7988
|
+
];
|
|
7989
|
+
var isPresent = (value) => Boolean(value);
|
|
7990
|
+
var errorDetail = (error) => (error == null ? void 0 : Reflect.get(Object(error), "message")) ?? String(error);
|
|
7607
7991
|
var useCommentsStore = defineStore("comments", () => {
|
|
7608
7992
|
const superdocStore = useSuperdocStore();
|
|
7993
|
+
const findDocument = (documentId) => typeof documentId === "string" ? superdocStore.getDocument(documentId) : void 0;
|
|
7609
7994
|
const commentsConfig = reactive({
|
|
7610
7995
|
name: "comments",
|
|
7611
7996
|
readOnly: false,
|
|
@@ -7635,6 +8020,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
7635
8020
|
});
|
|
7636
8021
|
const debounceTimers = {};
|
|
7637
8022
|
const trackedChangeResolutionSnapshots = /* @__PURE__ */ new WeakMap();
|
|
8023
|
+
let cachedTrackedChangeBatchIdentityIndex = null;
|
|
7638
8024
|
const isBenchmarkCommentsDebugEnabled = () => {
|
|
7639
8025
|
if (typeof window === "undefined") return false;
|
|
7640
8026
|
return "__labsSuperDocV2BenchmarkDebug" in window;
|
|
@@ -7672,7 +8058,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
7672
8058
|
});
|
|
7673
8059
|
const getTrackedChangeThread = (parentComment) => {
|
|
7674
8060
|
const id = parentComment?.commentId ?? null;
|
|
7675
|
-
return (id != null ? trackedChangeThreadIndex.value.get(id) : null) ?? [parentComment]
|
|
8061
|
+
return (id != null ? trackedChangeThreadIndex.value.get(id) : null) ?? (parentComment ? [parentComment] : []);
|
|
7676
8062
|
};
|
|
7677
8063
|
let priorTrackedChangeDecisionLinkIndex = /* @__PURE__ */ new Map();
|
|
7678
8064
|
const trackedChangeDecisionLinkIndex = computed$1(() => {
|
|
@@ -7704,29 +8090,28 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
7704
8090
|
});
|
|
7705
8091
|
const v2CommentsAdapter = shallowRef$1(null);
|
|
7706
8092
|
const setV2CommentsAdapter = (adapter) => {
|
|
7707
|
-
|
|
7708
|
-
v2CommentsAdapter.value
|
|
8093
|
+
const next = isV2CommentsAdapter(adapter) ? adapter : null;
|
|
8094
|
+
if (v2CommentsAdapter.value !== next) pendingCommentRequest += 1;
|
|
8095
|
+
v2CommentsAdapter.value = next;
|
|
7709
8096
|
};
|
|
7710
8097
|
const getV2CommentsAdapter = (superdoc) => {
|
|
7711
|
-
const fromFacade = superdoc?.activeEditor?.v2Comments
|
|
7712
|
-
if (fromFacade) return fromFacade;
|
|
8098
|
+
const fromFacade = superdoc?.activeEditor?.v2Comments;
|
|
8099
|
+
if (isV2CommentsAdapter(fromFacade)) return fromFacade;
|
|
7713
8100
|
return v2CommentsAdapter.value;
|
|
7714
8101
|
};
|
|
7715
8102
|
const isV2EditorActive = (superdoc) => superdoc?.activeEditor?.editorVersion === 2 || v2CommentsAdapter.value !== null;
|
|
7716
8103
|
const v2TrackedChangesAdapter = shallowRef$1(null);
|
|
7717
8104
|
const setV2TrackedChangesAdapter = (adapter) => {
|
|
7718
|
-
|
|
8105
|
+
cachedTrackedChangeBatchIdentityIndex = null;
|
|
8106
|
+
v2TrackedChangesAdapter.value = isV2TrackedChangesAdapter(adapter) ? adapter : null;
|
|
7719
8107
|
};
|
|
7720
8108
|
const getV2TrackedChangesAdapter = (superdoc) => {
|
|
7721
|
-
const fromFacade = superdoc?.activeEditor?.v2TrackedChanges
|
|
7722
|
-
if (fromFacade) return fromFacade;
|
|
8109
|
+
const fromFacade = superdoc?.activeEditor?.v2TrackedChanges;
|
|
8110
|
+
if (isV2TrackedChangesAdapter(fromFacade)) return fromFacade;
|
|
7723
8111
|
return v2TrackedChangesAdapter.value;
|
|
7724
8112
|
};
|
|
7725
8113
|
/**
|
|
7726
8114
|
* Initialize the store
|
|
7727
|
-
*
|
|
7728
|
-
* @param {Object} config The comments module config from SuperDoc
|
|
7729
|
-
* @returns {void}
|
|
7730
8115
|
*/
|
|
7731
8116
|
const init = (config = {}) => {
|
|
7732
8117
|
const updatedConfig = {
|
|
@@ -7758,12 +8143,17 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
7758
8143
|
comment.trackedChangeDecision = null;
|
|
7759
8144
|
};
|
|
7760
8145
|
const getCommentEventPayload = (comment) => typeof comment?.getValues === "function" ? comment.getValues() : { ...comment };
|
|
8146
|
+
const getDeletedCommentChanges = (sources, fileId) => {
|
|
8147
|
+
const commentId = [...sources.map((source) => source?.commentId), ...sources.map((source) => source?.importedId)].map(normalizeCommentId).find(Boolean);
|
|
8148
|
+
return commentId ? [{
|
|
8149
|
+
key: "deleted",
|
|
8150
|
+
commentId,
|
|
8151
|
+
fileId
|
|
8152
|
+
}] : [];
|
|
8153
|
+
};
|
|
7761
8154
|
/**
|
|
7762
8155
|
* Check if a comment originated from the document editor (or has no explicit source).
|
|
7763
8156
|
* 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
8157
|
*/
|
|
7768
8158
|
const isEditorBackedComment = (comment) => {
|
|
7769
8159
|
const source = comment?.selection?.source;
|
|
@@ -7797,9 +8187,6 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
7797
8187
|
}, { deep: false });
|
|
7798
8188
|
/**
|
|
7799
8189
|
* 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
8190
|
*/
|
|
7804
8191
|
const getCommentPosition = (commentOrId) => {
|
|
7805
8192
|
return resolveCommentPositionEntry(commentOrId).entry ?? null;
|
|
@@ -7812,10 +8199,6 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
7812
8199
|
};
|
|
7813
8200
|
/**
|
|
7814
8201
|
* 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
8202
|
*/
|
|
7820
8203
|
const setActiveComment = (superdoc, id) => {
|
|
7821
8204
|
const activeEditor = superdoc?.activeEditor;
|
|
@@ -7826,7 +8209,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
7826
8209
|
v2Adapter.setActiveComment(null);
|
|
7827
8210
|
return;
|
|
7828
8211
|
}
|
|
7829
|
-
activeEditor?.commands?.setActiveComment({ commentId: null });
|
|
8212
|
+
activeEditor?.commands?.setActiveComment?.({ commentId: null });
|
|
7830
8213
|
return;
|
|
7831
8214
|
}
|
|
7832
8215
|
const comment = getComment(id);
|
|
@@ -7837,18 +8220,13 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
7837
8220
|
v2Adapter.setActiveComment(comment.commentId);
|
|
7838
8221
|
return;
|
|
7839
8222
|
}
|
|
7840
|
-
activeEditor?.commands?.setActiveComment({ commentId: activeComment.value });
|
|
8223
|
+
activeEditor?.commands?.setActiveComment?.({ commentId: activeComment.value });
|
|
7841
8224
|
};
|
|
7842
8225
|
/**
|
|
7843
8226
|
* Called when a tracked change is updated. Creates a new comment if necessary,
|
|
7844
8227
|
* 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
8228
|
*/
|
|
7851
|
-
const handleTrackedChangeUpdate = ({ superdoc, params, broadcastChanges = true, trackedChangeIdentityIndex = null }) => {
|
|
8229
|
+
const handleTrackedChangeUpdate = ({ superdoc, params, broadcastChanges = true, trackedChangeIdentityIndex = null, preserveDraft = false }) => {
|
|
7852
8230
|
const span = startInteractionSpan("store.trackedChanges.handleUpdate", "store-reconciliation", {
|
|
7853
8231
|
event: params?.event ?? null,
|
|
7854
8232
|
changeId: params?.changeId ?? null,
|
|
@@ -7873,9 +8251,11 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
7873
8251
|
const normalizedTrackedChangeLabel = typeof trackedChangeLabel === "string" && trackedChangeLabel.length > 0 ? trackedChangeLabel : null;
|
|
7874
8252
|
const normalizedTrackedChangeDetailLines = normalizeTrackedChangeDetailLines(trackedChangeDetailLines);
|
|
7875
8253
|
const normalizedTrackedChangeImagePreview = normalizeTrackedChangeImagePreview(trackedChangeImagePreview);
|
|
8254
|
+
const hasDraft = preserveDraft && (pendingComment.value !== null || currentCommentText.value !== "" || currentCommentMentions.value.length > 0);
|
|
7876
8255
|
const comment = getPendingComment({
|
|
7877
8256
|
documentId,
|
|
7878
|
-
|
|
8257
|
+
...hasDraft ? { commentText: "" } : {},
|
|
8258
|
+
commentId: normalizedChangeId ?? void 0,
|
|
7879
8259
|
trackedChange: true,
|
|
7880
8260
|
trackedChangeText,
|
|
7881
8261
|
trackedChangeType,
|
|
@@ -7927,7 +8307,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
7927
8307
|
commentCanonicalId,
|
|
7928
8308
|
commentAnchorKey,
|
|
7929
8309
|
...commentAliasIds
|
|
7930
|
-
].
|
|
8310
|
+
].some((id) => id != null && incomingAliasIds.has(id))) return true;
|
|
7931
8311
|
const hasSyntheticSideIdentity = normalizedTrackedChangeCanonicalId && normalizedTrackedChangeCanonicalId !== normalizedChangeId || commentCanonicalId && commentCanonicalId !== commentId;
|
|
7932
8312
|
if (hasCompatibleStory && commentId === normalizedChangeId) return true;
|
|
7933
8313
|
if (hasCompatibleStory && !hasSyntheticSideIdentity && (importedId === normalizedChangeId || normalizedImportedId !== void 0 && normalizedImportedId != null && importedId === normalizedImportedId)) return true;
|
|
@@ -7951,7 +8331,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
7951
8331
|
};
|
|
7952
8332
|
const emitTrackedChangeEvent = (event) => {
|
|
7953
8333
|
if (!broadcastChanges) return;
|
|
7954
|
-
syncCommentsToClients(superdoc, event);
|
|
8334
|
+
syncCommentsToClients(requireHost(superdoc, "handleTrackedChangeUpdate"), event);
|
|
7955
8335
|
debounceEmit(changeId, event, superdoc);
|
|
7956
8336
|
};
|
|
7957
8337
|
const setIfChanged = (target, key, value) => {
|
|
@@ -7994,8 +8374,9 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
7994
8374
|
target?.trackedChangeCanonicalId,
|
|
7995
8375
|
target?.trackedChangeAnchorKey,
|
|
7996
8376
|
...getCommentAliasIds(target)
|
|
7997
|
-
].map((id) => normalizeCommentId(id)).filter(
|
|
7998
|
-
|
|
8377
|
+
].map((id) => normalizeCommentId(id)).filter(isPresent));
|
|
8378
|
+
const incomingAliases = normalizedTrackedChangePositionAliases ?? [];
|
|
8379
|
+
fields.trackedChangePositionAliases = incomingAliases.some((alias) => targetIdentityIds.has(alias)) ? normalizeTrackedChangePositionAliases([...Array.isArray(target?.trackedChangePositionAliases) ? target.trackedChangePositionAliases : [], ...incomingAliases]) : incomingAliases;
|
|
7999
8380
|
}
|
|
8000
8381
|
let didChange = false;
|
|
8001
8382
|
for (const [key, value] of Object.entries(fields)) didChange = setIfChanged(target, key, value) || didChange;
|
|
@@ -8004,7 +8385,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8004
8385
|
didChange = true;
|
|
8005
8386
|
}
|
|
8006
8387
|
if (hasCustomAttributes && target && !trackedChangeCustomAttributesEqual(target.customAttributes, normalizedCustomAttributes)) {
|
|
8007
|
-
target.customAttributes = normalizedCustomAttributes;
|
|
8388
|
+
target.customAttributes = normalizedCustomAttributes ?? null;
|
|
8008
8389
|
didChange = true;
|
|
8009
8390
|
}
|
|
8010
8391
|
return applyStoryMetadata(target) || didChange;
|
|
@@ -8026,9 +8407,10 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8026
8407
|
return;
|
|
8027
8408
|
}
|
|
8028
8409
|
addHydratedComment({
|
|
8029
|
-
superdoc,
|
|
8410
|
+
superdoc: requireHost(superdoc, "handleTrackedChangeUpdate"),
|
|
8030
8411
|
comment,
|
|
8031
|
-
broadcastChanges
|
|
8412
|
+
broadcastChanges,
|
|
8413
|
+
preserveDraft: hasDraft
|
|
8032
8414
|
});
|
|
8033
8415
|
trackedChangeIdentityIndex?.add(comment);
|
|
8034
8416
|
} else if (event === "update") {
|
|
@@ -8046,11 +8428,12 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8046
8428
|
id: params.resolvedById ?? superdoc?.user?.id ?? null,
|
|
8047
8429
|
email: params.resolvedByEmail ?? superdoc?.user?.email ?? null,
|
|
8048
8430
|
name: params.resolvedByName ?? superdoc?.user?.name ?? null,
|
|
8049
|
-
decision: params.decision ??
|
|
8431
|
+
decision: params.decision ?? void 0,
|
|
8050
8432
|
superdoc
|
|
8051
8433
|
};
|
|
8052
8434
|
if (existingTrackedChange && !existingTrackedChange.resolvedTime) existingTrackedChange.resolveComment({
|
|
8053
8435
|
...resolveArgs,
|
|
8436
|
+
superdoc: requireHost(superdoc, "handleTrackedChangeUpdate"),
|
|
8054
8437
|
reconciliationToken: COMMENT_RECONCILIATION_TOKEN
|
|
8055
8438
|
});
|
|
8056
8439
|
}
|
|
@@ -8075,31 +8458,13 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8075
8458
|
instantSidebarAlignmentInstanceId.value = null;
|
|
8076
8459
|
};
|
|
8077
8460
|
const debounceEmit = (commentId, event, superdoc, delay = 1e3) => {
|
|
8078
|
-
|
|
8079
|
-
debounceTimers[
|
|
8461
|
+
const timerKey = String(commentId);
|
|
8462
|
+
if (debounceTimers[timerKey]) clearTimeout(debounceTimers[timerKey]);
|
|
8463
|
+
debounceTimers[timerKey] = setTimeout(() => {
|
|
8080
8464
|
if (superdoc) superdoc.emit("comments-update", event);
|
|
8081
|
-
delete debounceTimers[
|
|
8465
|
+
delete debounceTimers[timerKey];
|
|
8082
8466
|
}, delay);
|
|
8083
8467
|
};
|
|
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
8468
|
const showAddComment = (superdoc, targetClientY = null) => {
|
|
8104
8469
|
const request = ++pendingCommentRequest;
|
|
8105
8470
|
const editor = superdoc?.activeEditor;
|
|
@@ -8109,7 +8474,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8109
8474
|
if (!ownsRequest()) return;
|
|
8110
8475
|
superdoc.emit("comments-update", {
|
|
8111
8476
|
type: COMMENT_EVENTS.PENDING,
|
|
8112
|
-
pendingSelection: superdoc?.activeEditor === editor ? snapshot : null
|
|
8477
|
+
pendingSelection: superdoc?.activeEditor === editor && isPlainObject$1(snapshot) ? snapshot : null
|
|
8113
8478
|
});
|
|
8114
8479
|
};
|
|
8115
8480
|
if (v2Adapter) {
|
|
@@ -8154,12 +8519,11 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8154
8519
|
}).catch((err) => ({
|
|
8155
8520
|
ok: false,
|
|
8156
8521
|
reason: "selection-capture-failed",
|
|
8157
|
-
detail:
|
|
8522
|
+
detail: errorDetail(err)
|
|
8158
8523
|
}));
|
|
8159
8524
|
}
|
|
8160
8525
|
const pendingSelection = getPendingSelectionSnapshot(superdoc, superdocStore.activeSelection);
|
|
8161
|
-
|
|
8162
|
-
if (!asyncSnapshot) emitPending(pendingSelection);
|
|
8526
|
+
if (!isThenable$1(pendingSelection)) emitPending(pendingSelection);
|
|
8163
8527
|
const showLegacyPending = (selection) => {
|
|
8164
8528
|
selection.selectionBounds = { ...selection.selectionBounds };
|
|
8165
8529
|
if (superdocStore.selectionPosition?.source && superdocStore.selectionPosition.source !== "pdf") superdocStore.selectionPosition.source = null;
|
|
@@ -8169,7 +8533,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8169
8533
|
parentCommentId: null
|
|
8170
8534
|
});
|
|
8171
8535
|
if (!superdoc.config.isInternal) pendingComment.value.isInternal = false;
|
|
8172
|
-
if (superdoc.activeEditor?.commands) superdoc.activeEditor.commands.insertComment({
|
|
8536
|
+
if (superdoc.activeEditor?.commands) superdoc.activeEditor.commands.insertComment?.({
|
|
8173
8537
|
...pendingComment.value.getValues(),
|
|
8174
8538
|
commentId: "pending",
|
|
8175
8539
|
skipEmit: true
|
|
@@ -8180,10 +8544,10 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8180
8544
|
activeComment.value = pendingComment.value.commentId;
|
|
8181
8545
|
return { ok: true };
|
|
8182
8546
|
};
|
|
8183
|
-
if (
|
|
8547
|
+
if (isThenable$1(pendingSelection)) {
|
|
8184
8548
|
const selection = { ...superdocStore.activeSelection };
|
|
8185
8549
|
selection.selectionBounds = { ...selection.selectionBounds };
|
|
8186
|
-
return pendingSelection.then((snapshot) => {
|
|
8550
|
+
return Promise.resolve(pendingSelection).then((snapshot) => {
|
|
8187
8551
|
if (!ownsRequest()) return {
|
|
8188
8552
|
ok: false,
|
|
8189
8553
|
reason: "pending-comment-superseded"
|
|
@@ -8215,12 +8579,6 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8215
8579
|
});
|
|
8216
8580
|
/**
|
|
8217
8581
|
* 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
8582
|
*/
|
|
8225
8583
|
const getPendingComment = ({ selection, documentId, parentCommentId, ...options }) => {
|
|
8226
8584
|
return _getNewcomment({
|
|
@@ -8232,17 +8590,11 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8232
8590
|
};
|
|
8233
8591
|
/**
|
|
8234
8592
|
* 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
8593
|
*/
|
|
8242
8594
|
const _getNewcomment = ({ selection, documentId, parentCommentId, ...options }) => {
|
|
8243
8595
|
let activeDocument;
|
|
8244
|
-
if (documentId) activeDocument =
|
|
8245
|
-
else if (selection) activeDocument =
|
|
8596
|
+
if (documentId) activeDocument = findDocument(documentId);
|
|
8597
|
+
else if (selection) activeDocument = findDocument(selection.documentId);
|
|
8246
8598
|
if (!activeDocument) activeDocument = superdocStore.documents[0];
|
|
8247
8599
|
return useComment({
|
|
8248
8600
|
fileId: activeDocument.id,
|
|
@@ -8259,8 +8611,6 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8259
8611
|
};
|
|
8260
8612
|
/**
|
|
8261
8613
|
* Remove the pending comment
|
|
8262
|
-
*
|
|
8263
|
-
* @returns {void}
|
|
8264
8614
|
*/
|
|
8265
8615
|
const resetPendingCommentState = (superdoc, clearViewingSelection = true) => {
|
|
8266
8616
|
const hadPending = !!pendingComment.value;
|
|
@@ -8276,7 +8626,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8276
8626
|
} catch {}
|
|
8277
8627
|
return;
|
|
8278
8628
|
}
|
|
8279
|
-
superdoc?.activeEditor?.commands?.removeComment({ commentId: "pending" });
|
|
8629
|
+
superdoc?.activeEditor?.commands?.removeComment?.({ commentId: "pending" });
|
|
8280
8630
|
};
|
|
8281
8631
|
const removePendingComment = (superdoc) => {
|
|
8282
8632
|
pendingCommentRequest += 1;
|
|
@@ -8289,16 +8639,8 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8289
8639
|
};
|
|
8290
8640
|
/**
|
|
8291
8641
|
* 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
8642
|
*/
|
|
8301
|
-
const addCommentInternal = ({ superdoc, comment, skipEditorUpdate = false, broadcastChanges = true, isHydration = false }) => {
|
|
8643
|
+
const addCommentInternal = ({ superdoc, comment, skipEditorUpdate = false, broadcastChanges = true, isHydration = false, preserveDraft = false }) => {
|
|
8302
8644
|
if (commentsAreReadOnly() && !isHydration) return readOnlyMutationOutcome();
|
|
8303
8645
|
const v2Adapter = !skipEditorUpdate && !isHydration ? getV2CommentsAdapter(superdoc) : null;
|
|
8304
8646
|
if (v2Adapter && !comment.trackedChange) {
|
|
@@ -8326,7 +8668,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8326
8668
|
return {
|
|
8327
8669
|
ok: false,
|
|
8328
8670
|
reason: "adapter-threw",
|
|
8329
|
-
detail:
|
|
8671
|
+
detail: errorDetail(err)
|
|
8330
8672
|
};
|
|
8331
8673
|
}
|
|
8332
8674
|
})().then((outcome) => {
|
|
@@ -8377,28 +8719,30 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8377
8719
|
};
|
|
8378
8720
|
});
|
|
8379
8721
|
}
|
|
8380
|
-
|
|
8722
|
+
const activeId = activeComment.value;
|
|
8723
|
+
const parent = toRaw$2(commentsList.value).find((c) => unref(c.commentId) === activeId);
|
|
8724
|
+
let parentComment = parent ? reactive(parent) : void 0;
|
|
8381
8725
|
if (!parentComment) parentComment = comment;
|
|
8382
8726
|
const newComment = useComment(comment.getValues());
|
|
8383
|
-
|
|
8384
|
-
|
|
8727
|
+
const text = pendingComment.value && !preserveDraft ? currentCommentText.value : comment.commentText;
|
|
8728
|
+
if (text === "") {
|
|
8729
|
+
newComment.commentText = "";
|
|
8730
|
+
newComment.mentions = [];
|
|
8731
|
+
} else newComment.setText({
|
|
8732
|
+
text,
|
|
8385
8733
|
suppressUpdate: true
|
|
8386
8734
|
});
|
|
8387
|
-
|
|
8388
|
-
text: comment.commentText,
|
|
8389
|
-
suppressUpdate: true
|
|
8390
|
-
});
|
|
8391
|
-
newComment.selection.source = pendingComment.value?.selection?.source ?? newComment.selection.source;
|
|
8735
|
+
if (!preserveDraft) newComment.selection.source = pendingComment.value?.selection?.source ?? newComment.selection.source;
|
|
8392
8736
|
if (parentComment) newComment.isInternal = parentComment.isInternal;
|
|
8393
8737
|
if (!superdoc.config.isInternal) newComment.isInternal = false;
|
|
8394
8738
|
commentsList.value.push(newComment);
|
|
8395
|
-
const hadPendingComment = !!pendingComment.value;
|
|
8396
|
-
removePendingComment(superdoc);
|
|
8739
|
+
const hadPendingComment = !preserveDraft && !!pendingComment.value;
|
|
8740
|
+
if (!preserveDraft) removePendingComment(superdoc);
|
|
8397
8741
|
if (hadPendingComment) {
|
|
8398
8742
|
activeComment.value = newComment.commentId;
|
|
8399
8743
|
setActiveFloatingCommentInstance(newComment.commentId);
|
|
8400
8744
|
}
|
|
8401
|
-
if (!skipEditorUpdate && !comment.trackedChange && superdoc.activeEditor?.commands && !comment.parentCommentId) superdoc.activeEditor.commands.insertComment({
|
|
8745
|
+
if (!skipEditorUpdate && !comment.trackedChange && superdoc.activeEditor?.commands && !comment.parentCommentId) superdoc.activeEditor.commands.insertComment?.({
|
|
8402
8746
|
...newComment.getValues(),
|
|
8403
8747
|
skipEmit: true
|
|
8404
8748
|
});
|
|
@@ -8421,12 +8765,13 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8421
8765
|
skipEditorUpdate,
|
|
8422
8766
|
broadcastChanges
|
|
8423
8767
|
});
|
|
8424
|
-
const addHydratedComment = ({ superdoc, comment, skipEditorUpdate = false, broadcastChanges = true }) => addCommentInternal({
|
|
8768
|
+
const addHydratedComment = ({ superdoc, comment, skipEditorUpdate = false, broadcastChanges = true, preserveDraft = false }) => addCommentInternal({
|
|
8425
8769
|
superdoc,
|
|
8426
8770
|
comment,
|
|
8427
8771
|
skipEditorUpdate,
|
|
8428
8772
|
broadcastChanges,
|
|
8429
|
-
isHydration: true
|
|
8773
|
+
isHydration: true,
|
|
8774
|
+
preserveDraft
|
|
8430
8775
|
});
|
|
8431
8776
|
const deleteComment = ({ commentId: commentIdToDelete, superdoc }) => {
|
|
8432
8777
|
if (commentsAreReadOnly()) return Promise.resolve(readOnlyMutationOutcome());
|
|
@@ -8446,7 +8791,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8446
8791
|
return {
|
|
8447
8792
|
ok: false,
|
|
8448
8793
|
reason: "adapter-threw",
|
|
8449
|
-
detail:
|
|
8794
|
+
detail: errorDetail(err)
|
|
8450
8795
|
};
|
|
8451
8796
|
}
|
|
8452
8797
|
})().then((outcome) => {
|
|
@@ -8466,16 +8811,16 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8466
8811
|
});
|
|
8467
8812
|
return outcome;
|
|
8468
8813
|
}
|
|
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(
|
|
8814
|
+
const removedIds = new Set((Array.isArray(outcome.removedCommentIds) ? outcome.removedCommentIds : []).map(normalizeCommentId).filter(isPresent));
|
|
8815
|
+
if (removedIds.has(normalizeCommentId(commentId) ?? "")) {
|
|
8816
|
+
if (importedId != null) removedIds.add(String(importedId));
|
|
8472
8817
|
let addedChild = true;
|
|
8473
8818
|
while (addedChild) {
|
|
8474
8819
|
addedChild = false;
|
|
8475
8820
|
for (const row of commentsList.value) {
|
|
8476
8821
|
const parentId = normalizeCommentId(row?.parentCommentId);
|
|
8477
8822
|
if (!parentId || !removedIds.has(parentId)) continue;
|
|
8478
|
-
for (const alias of [row?.commentId, row?.importedId].map(normalizeCommentId).filter(
|
|
8823
|
+
for (const alias of [row?.commentId, row?.importedId].map(normalizeCommentId).filter(isPresent)) {
|
|
8479
8824
|
if (removedIds.has(alias)) continue;
|
|
8480
8825
|
removedIds.add(alias);
|
|
8481
8826
|
addedChild = true;
|
|
@@ -8483,9 +8828,9 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8483
8828
|
}
|
|
8484
8829
|
}
|
|
8485
8830
|
commentsList.value = commentsList.value.filter((row) => {
|
|
8486
|
-
return ![row?.commentId, row?.importedId].map(normalizeCommentId).filter(
|
|
8831
|
+
return ![row?.commentId, row?.importedId].map(normalizeCommentId).filter(isPresent).some((alias) => removedIds.has(alias));
|
|
8487
8832
|
});
|
|
8488
|
-
if (removedIds.has(normalizeCommentId(activeComment.value))) clearActiveCommentSelection();
|
|
8833
|
+
if (removedIds.has(normalizeCommentId(activeComment.value) ?? "")) clearActiveCommentSelection();
|
|
8489
8834
|
} else reconcileCommentsFromV2({
|
|
8490
8835
|
superdoc,
|
|
8491
8836
|
adapter: v2Adapter,
|
|
@@ -8493,18 +8838,18 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8493
8838
|
items: outcome.items ?? [],
|
|
8494
8839
|
pruneStale: outcome.complete !== false
|
|
8495
8840
|
});
|
|
8841
|
+
const payload = comment.getValues();
|
|
8496
8842
|
superdoc.emit("comments-update", {
|
|
8497
8843
|
type: COMMENT_EVENTS.DELETED,
|
|
8498
|
-
comment:
|
|
8499
|
-
changes: [{
|
|
8500
|
-
key: "deleted",
|
|
8844
|
+
comment: payload,
|
|
8845
|
+
changes: getDeletedCommentChanges([{
|
|
8501
8846
|
commentId,
|
|
8502
|
-
|
|
8503
|
-
}]
|
|
8847
|
+
importedId
|
|
8848
|
+
}, payload], fileId)
|
|
8504
8849
|
});
|
|
8505
8850
|
return { ok: true };
|
|
8506
8851
|
});
|
|
8507
|
-
superdoc.activeEditor?.commands?.removeComment({
|
|
8852
|
+
superdoc.activeEditor?.commands?.removeComment?.({
|
|
8508
8853
|
commentId,
|
|
8509
8854
|
importedId
|
|
8510
8855
|
});
|
|
@@ -8512,14 +8857,14 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8512
8857
|
const childCommentIds = commentsList.value.filter((c) => c.parentCommentId === commentId).map((c) => c.commentId || c.importedId);
|
|
8513
8858
|
commentsList.value = commentsList.value.filter((c) => !childCommentIds.includes(c.commentId));
|
|
8514
8859
|
if (activeComment.value === commentId || childCommentIds.includes(activeComment.value)) clearActiveCommentSelection();
|
|
8860
|
+
const payload = comment.getValues();
|
|
8515
8861
|
const event = {
|
|
8516
8862
|
type: COMMENT_EVENTS.DELETED,
|
|
8517
|
-
comment:
|
|
8518
|
-
changes: [{
|
|
8519
|
-
key: "deleted",
|
|
8863
|
+
comment: payload,
|
|
8864
|
+
changes: getDeletedCommentChanges([{
|
|
8520
8865
|
commentId,
|
|
8521
|
-
|
|
8522
|
-
}]
|
|
8866
|
+
importedId
|
|
8867
|
+
}, payload], fileId)
|
|
8523
8868
|
};
|
|
8524
8869
|
superdoc.emit("comments-update", event);
|
|
8525
8870
|
syncCommentsToClients(superdoc, event);
|
|
@@ -8531,7 +8876,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8531
8876
|
* otherwise keep the source bubble after the document comment is gone.
|
|
8532
8877
|
*/
|
|
8533
8878
|
const dropCommentsFromMutationImpact = ({ superdoc, documentId, removedIds } = {}) => {
|
|
8534
|
-
const seedIds = new Set([...removedIds instanceof Set ? removedIds : removedIds ?? []].map((id) => normalizeCommentId(id)).filter(
|
|
8879
|
+
const seedIds = new Set([...removedIds instanceof Set ? removedIds : removedIds ?? []].map((id) => normalizeCommentId(id)).filter(isPresent));
|
|
8535
8880
|
if (!seedIds.size) return {
|
|
8536
8881
|
ok: true,
|
|
8537
8882
|
removedIds: []
|
|
@@ -8555,7 +8900,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8555
8900
|
if (!isDroppableCommentRow(row)) continue;
|
|
8556
8901
|
const aliases = getCommentAliasIds(row);
|
|
8557
8902
|
const alreadyDropped = aliases.some((alias) => droppedIds.has(alias));
|
|
8558
|
-
const parentDropped = droppedIds.has(normalizeCommentId(row?.parentCommentId)) || droppedIds.has(normalizeCommentId(row?.threadingParentCommentId));
|
|
8903
|
+
const parentDropped = droppedIds.has(normalizeCommentId(row?.parentCommentId) ?? "") || droppedIds.has(normalizeCommentId(row?.threadingParentCommentId) ?? "");
|
|
8559
8904
|
if (!alreadyDropped && !parentDropped) continue;
|
|
8560
8905
|
for (const alias of aliases) {
|
|
8561
8906
|
if (droppedIds.has(alias)) continue;
|
|
@@ -8583,11 +8928,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8583
8928
|
const event = {
|
|
8584
8929
|
type: COMMENT_EVENTS.DELETED,
|
|
8585
8930
|
comment: payload,
|
|
8586
|
-
changes: [
|
|
8587
|
-
key: "deleted",
|
|
8588
|
-
commentId: payload?.commentId,
|
|
8589
|
-
fileId: payload?.fileId
|
|
8590
|
-
}]
|
|
8931
|
+
changes: getDeletedCommentChanges([payload, comment], payload?.fileId)
|
|
8591
8932
|
};
|
|
8592
8933
|
superdoc?.emit?.("comments-update", event);
|
|
8593
8934
|
});
|
|
@@ -8609,7 +8950,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8609
8950
|
const byAlias = /* @__PURE__ */ new Map();
|
|
8610
8951
|
const childrenByParentAlias = /* @__PURE__ */ new Map();
|
|
8611
8952
|
for (const row of rows) {
|
|
8612
|
-
for (const alias of [row.commentId, row.importedId].map(normalizeCommentId).filter(
|
|
8953
|
+
for (const alias of [row.commentId, row.importedId].map(normalizeCommentId).filter(isPresent)) if (!byAlias.has(alias)) byAlias.set(alias, row);
|
|
8613
8954
|
const parentId = normalizeCommentId(row.parentCommentId);
|
|
8614
8955
|
if (parentId) {
|
|
8615
8956
|
const children = childrenByParentAlias.get(parentId) ?? [];
|
|
@@ -8636,7 +8977,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8636
8977
|
if (!row || visited.has(row)) continue;
|
|
8637
8978
|
visited.add(row);
|
|
8638
8979
|
family.push(row);
|
|
8639
|
-
for (const alias of [row.commentId, row.importedId].map(normalizeCommentId).filter(
|
|
8980
|
+
for (const alias of [row.commentId, row.importedId].map(normalizeCommentId).filter(isPresent)) queue.push(...childrenByParentAlias.get(alias) ?? []);
|
|
8640
8981
|
}
|
|
8641
8982
|
const isResolved = status === "resolved";
|
|
8642
8983
|
const resolvedAt = Date.now();
|
|
@@ -8659,7 +9000,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8659
9000
|
outcome = {
|
|
8660
9001
|
ok: false,
|
|
8661
9002
|
reason: "adapter-threw",
|
|
8662
|
-
detail:
|
|
9003
|
+
detail: errorDetail(err)
|
|
8663
9004
|
};
|
|
8664
9005
|
}
|
|
8665
9006
|
if (!isCurrentV2CommentsAdapter(adapter)) return {
|
|
@@ -8731,14 +9072,14 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8731
9072
|
return (outcome.items ?? []).map((item) => adapter.mapV2CommentToUseCommentInput(item, {
|
|
8732
9073
|
fileId,
|
|
8733
9074
|
fileType: null
|
|
8734
|
-
})).filter(
|
|
9075
|
+
})).filter(isPresent);
|
|
8735
9076
|
};
|
|
8736
9077
|
const isBlankDirectoryCommentText = (value) => typeof value !== "string" || value.replace(/<[^>]*>/g, "").replace(/ /gi, " ").trim().length === 0;
|
|
8737
9078
|
const trackedChangeDirectoryComment = (params) => {
|
|
8738
9079
|
if (!params || params.event === "omit" || params.changeId == null) return null;
|
|
8739
9080
|
return getPendingComment({
|
|
8740
9081
|
documentId: params.documentId,
|
|
8741
|
-
commentId: params.changeId,
|
|
9082
|
+
commentId: String(params.changeId),
|
|
8742
9083
|
trackedChange: true,
|
|
8743
9084
|
trackedChangeText: params.trackedChangeText,
|
|
8744
9085
|
trackedChangeType: params.trackedChangeType,
|
|
@@ -8785,7 +9126,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8785
9126
|
const mappedCommentInputs = commentItems.filter((item) => !isSyntheticTrackedChangeCommentLaneItem(item)).map((item) => commentsAdapter.mapV2CommentToUseCommentInput(item, {
|
|
8786
9127
|
fileId: documentId,
|
|
8787
9128
|
fileType: document?.type ?? null
|
|
8788
|
-
})).filter(
|
|
9129
|
+
})).filter(isPresent);
|
|
8789
9130
|
const trackedParentBySidecarId = /* @__PURE__ */ new Map();
|
|
8790
9131
|
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
9132
|
const commentRows = mappedCommentInputs.filter((input) => !trackedParentBySidecarId.has(String(input.commentId))).map((input) => {
|
|
@@ -8796,7 +9137,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8796
9137
|
}
|
|
8797
9138
|
return useComment(input);
|
|
8798
9139
|
});
|
|
8799
|
-
const trackedRows = trackedChangeItems.map((item) => trackedChangesAdapter.mapV2TrackedChangeToCommentParams(item)).map((params) => trackedChangeDirectoryComment(params)).filter(
|
|
9140
|
+
const trackedRows = trackedChangeItems.map((item) => trackedChangesAdapter.mapV2TrackedChangeToCommentParams(item)).map((params) => trackedChangeDirectoryComment(params)).filter(isPresent);
|
|
8800
9141
|
reviewDirectoryList.value = [...commentRows, ...trackedRows];
|
|
8801
9142
|
return {
|
|
8802
9143
|
ok: true,
|
|
@@ -8877,13 +9218,6 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
8877
9218
|
* - successful mutation refreshes from v2 list and reconciles
|
|
8878
9219
|
* - rejection preserves rows and emits a rejected `comments-update` event
|
|
8879
9220
|
* - 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
9221
|
*/
|
|
8888
9222
|
const replyCommentV2 = async ({ superdoc, parentCommentId, text, mentions = [], trackedChangeTarget } = {}) => {
|
|
8889
9223
|
if (commentsAreReadOnly()) return readOnlyMutationOutcome();
|
|
@@ -9158,10 +9492,15 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9158
9492
|
row?.threadingParentCommentId,
|
|
9159
9493
|
row?.trackedChangeParentId,
|
|
9160
9494
|
row?.trackedChangeThreadParentId
|
|
9161
|
-
].map((value) => normalizeCommentId(value)).filter(
|
|
9495
|
+
].map((value) => normalizeCommentId(value)).filter(isPresent));
|
|
9162
9496
|
/** Keep one mounted review window plus rows whose interaction is still live. */
|
|
9163
9497
|
const boundReviewPresentationRows = ({ documentId, visibleIds }) => {
|
|
9164
9498
|
const currentRows = commentsList.value;
|
|
9499
|
+
if (currentRows.every((row) => {
|
|
9500
|
+
if (!belongsToTrackedChangeSyncDocument(row, documentId)) return true;
|
|
9501
|
+
const id = normalizeCommentId(row.commentId);
|
|
9502
|
+
return Boolean(id && visibleIds.has(id));
|
|
9503
|
+
})) return;
|
|
9165
9504
|
const identityIdsByRow = /* @__PURE__ */ new Map();
|
|
9166
9505
|
const identityIdsFor = (row) => {
|
|
9167
9506
|
let ids = identityIdsByRow.get(row);
|
|
@@ -9179,7 +9518,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9179
9518
|
pendingComment.value?.commentId,
|
|
9180
9519
|
instantSidebarAlignmentThreadId.value,
|
|
9181
9520
|
instantSidebarAlignmentInstanceId.value
|
|
9182
|
-
].map((value) => normalizeCommentId(value)).filter(
|
|
9521
|
+
].map((value) => normalizeCommentId(value)).filter(isPresent));
|
|
9183
9522
|
let changed = true;
|
|
9184
9523
|
while (changed) {
|
|
9185
9524
|
changed = false;
|
|
@@ -9247,7 +9586,8 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9247
9586
|
if (preparedReview?.reuseCatalog === true && committedReviewPresentations.value[normalizedDocumentId]) {
|
|
9248
9587
|
const previous = committedReviewPresentations.value[normalizedDocumentId];
|
|
9249
9588
|
const next = preparedReview.presentation;
|
|
9250
|
-
|
|
9589
|
+
const catalogVersion = preparedReview.catalogVersion ?? NaN;
|
|
9590
|
+
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
9591
|
ok: false,
|
|
9252
9592
|
reason: "review-catalog-stale"
|
|
9253
9593
|
};
|
|
@@ -9293,8 +9633,8 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9293
9633
|
previousPresentation.updateContext = presentation.updateContext;
|
|
9294
9634
|
return {
|
|
9295
9635
|
ok: true,
|
|
9296
|
-
commentItems: preparedReview
|
|
9297
|
-
trackedItems: preparedReview
|
|
9636
|
+
commentItems: preparedReview?.comments.length,
|
|
9637
|
+
trackedItems: preparedReview?.trackedChanges.length
|
|
9298
9638
|
};
|
|
9299
9639
|
}
|
|
9300
9640
|
let effectiveCommentItems = commentItems;
|
|
@@ -9308,7 +9648,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9308
9648
|
reason: seeded?.reason ?? "comment-catalog-seed-failed"
|
|
9309
9649
|
};
|
|
9310
9650
|
const selected = commentsAdapter.selectVisibleReviewComments?.();
|
|
9311
|
-
if (selected?.ok === true && Array.isArray(selected.items) && (!Array.isArray(selected.unresolvedIds) || selected.unresolvedIds.length === 0)) effectiveCommentItems = selected.items;
|
|
9651
|
+
if (!isThenable$1(selected) && selected?.ok === true && Array.isArray(selected.items) && (!Array.isArray(selected.unresolvedIds) || selected.unresolvedIds.length === 0)) effectiveCommentItems = selected.items;
|
|
9312
9652
|
}
|
|
9313
9653
|
const fileType = (normalizedDocumentId ? superdocStore.getDocument(normalizedDocumentId) : null)?.type ?? null;
|
|
9314
9654
|
let preparedInputs;
|
|
@@ -9325,16 +9665,16 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9325
9665
|
})) : effectiveCommentItems.filter((item) => !isSyntheticTrackedChangeCommentLaneItem(item)).map((item) => commentsAdapter.mapV2CommentToUseCommentInput(item, {
|
|
9326
9666
|
fileId: normalizedDocumentId,
|
|
9327
9667
|
fileType
|
|
9328
|
-
})).filter(
|
|
9668
|
+
})).filter(isPresent);
|
|
9329
9669
|
preparedParams = preparedReview ? preparedReview.trackedChanges.map((params) => ({
|
|
9330
9670
|
...params,
|
|
9331
9671
|
documentId: normalizedDocumentId
|
|
9332
|
-
})) : trackedChangeItems.map((item) => trackedChangesAdapter.mapV2TrackedChangeToCommentParams(item)).filter(
|
|
9672
|
+
})) : trackedChangeItems.map((item) => trackedChangesAdapter.mapV2TrackedChangeToCommentParams(item)).filter(isPresent);
|
|
9333
9673
|
} catch (error) {
|
|
9334
9674
|
return {
|
|
9335
9675
|
ok: false,
|
|
9336
9676
|
reason: "mapper-failed",
|
|
9337
|
-
detail:
|
|
9677
|
+
detail: errorDetail(error)
|
|
9338
9678
|
};
|
|
9339
9679
|
}
|
|
9340
9680
|
if (typeof patch !== "function") return {
|
|
@@ -9362,7 +9702,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9362
9702
|
params?.trackedChangeCanonicalId,
|
|
9363
9703
|
params?.trackedChangeAnchorKey
|
|
9364
9704
|
])
|
|
9365
|
-
].map((value) => normalizeCommentId(value)).filter(
|
|
9705
|
+
].map((value) => normalizeCommentId(value)).filter(isPresent));
|
|
9366
9706
|
patch(() => {
|
|
9367
9707
|
const previousPreparedPresentation = committedReviewPresentations.value[normalizedDocumentId] ?? null;
|
|
9368
9708
|
if (preparedReview?.presentation) committedReviewPresentations.value = {
|
|
@@ -9377,7 +9717,8 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9377
9717
|
preparedParams,
|
|
9378
9718
|
preparedPresentation: preparedReview?.presentation ?? null,
|
|
9379
9719
|
previousPreparedPresentation,
|
|
9380
|
-
pruneStale: false
|
|
9720
|
+
pruneStale: false,
|
|
9721
|
+
preserveDraft: true
|
|
9381
9722
|
});
|
|
9382
9723
|
reconcileCommentsFromV2({
|
|
9383
9724
|
superdoc,
|
|
@@ -9410,7 +9751,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9410
9751
|
};
|
|
9411
9752
|
const effectiveDocumentId = documentId ?? adapter.documentId ?? null;
|
|
9412
9753
|
const normalizedEffectiveDocumentId = effectiveDocumentId != null ? String(effectiveDocumentId) : null;
|
|
9413
|
-
const fileType = (effectiveDocumentId ?
|
|
9754
|
+
const fileType = (effectiveDocumentId ? findDocument(effectiveDocumentId) : null)?.type ?? null;
|
|
9414
9755
|
const isBlankV2CommentText = (value) => {
|
|
9415
9756
|
if (typeof value !== "string") return true;
|
|
9416
9757
|
return value.replace(/<[^>]*>/g, "").replace(/ /gi, " ").trim().length === 0;
|
|
@@ -9430,7 +9771,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9430
9771
|
const candidateInputs = Array.isArray(preparedInputs) ? preparedInputs : items.filter((item) => !isSyntheticTrackedChangeCommentLaneItem(item)).map((item) => adapter.mapV2CommentToUseCommentInput(item, {
|
|
9431
9772
|
fileId: effectiveDocumentId,
|
|
9432
9773
|
fileType
|
|
9433
|
-
})).filter(
|
|
9774
|
+
})).filter(isPresent);
|
|
9434
9775
|
for (const input of candidateInputs) {
|
|
9435
9776
|
if (isV2TrackedChangeSidecarCommentInput(input)) {
|
|
9436
9777
|
trackedChangeSidecarParentByCommentId.set(String(input.commentId), String(input.trackedChangeThreadParentId));
|
|
@@ -9483,7 +9824,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9483
9824
|
existing.mentions = Array.isArray(input.mentions) ? input.mentions : [];
|
|
9484
9825
|
existing.isInternal = typeof input.isInternal === "boolean" ? input.isInternal : existing.isInternal;
|
|
9485
9826
|
if (typeof input.resolvedTime === "number") {
|
|
9486
|
-
existing.resolvedTime = input.resolvedTimeWasSynthesized === true && typeof existing.resolvedTime === "number" ? existing.resolvedTime : input.resolvedTime;
|
|
9827
|
+
existing.resolvedTime = input.resolvedTimeWasSynthesized === true && typeof existing.resolvedTime === "number" ? existing.resolvedTime : input.resolvedTime ?? null;
|
|
9487
9828
|
existing.resolvedByEmail = input.resolvedByEmail ?? null;
|
|
9488
9829
|
existing.resolvedByName = input.resolvedByName ?? null;
|
|
9489
9830
|
} else {
|
|
@@ -9557,7 +9898,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9557
9898
|
return {
|
|
9558
9899
|
ok: false,
|
|
9559
9900
|
reason: "comment-read-failed",
|
|
9560
|
-
detail:
|
|
9901
|
+
detail: errorDetail(err)
|
|
9561
9902
|
};
|
|
9562
9903
|
}
|
|
9563
9904
|
if (!isCurrentV2CommentsAdapter(adapter)) return {
|
|
@@ -9583,8 +9924,6 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9583
9924
|
};
|
|
9584
9925
|
/**
|
|
9585
9926
|
* Cancel the pending comment
|
|
9586
|
-
*
|
|
9587
|
-
* @returns {void}
|
|
9588
9927
|
*/
|
|
9589
9928
|
const cancelComment = (superdoc) => {
|
|
9590
9929
|
removePendingComment(superdoc);
|
|
@@ -9594,9 +9933,6 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9594
9933
|
*
|
|
9595
9934
|
* Replace-file swaps call this before hydrating the replacement so stale
|
|
9596
9935
|
* comments never survive long enough to render beside the new content.
|
|
9597
|
-
*
|
|
9598
|
-
* @param {string | null | undefined} documentId
|
|
9599
|
-
* @returns {void}
|
|
9600
9936
|
*/
|
|
9601
9937
|
function removeCommentsForDocument(documentId) {
|
|
9602
9938
|
const activeDocumentId = documentId != null ? String(documentId) : null;
|
|
@@ -9623,139 +9959,20 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9623
9959
|
const activeCommentId = activeComment.value != null ? String(activeComment.value) : null;
|
|
9624
9960
|
if (activeCommentId && removedAliasIds.has(activeCommentId)) clearActiveCommentSelection();
|
|
9625
9961
|
}
|
|
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
|
-
};
|
|
9962
|
+
const { belongsToDocument, belongsToTrackedChangeSyncDocument } = createCommentDocumentScope(() => superdocStore.documents);
|
|
9742
9963
|
const remapTrackedChangeReferences = (droppedCommentIds, activeDocumentId) => {
|
|
9743
9964
|
const remapSelection = (selection) => {
|
|
9744
9965
|
const selectedId = normalizeCommentId(selection.value);
|
|
9745
|
-
|
|
9966
|
+
const replacementId = selectedId ? droppedCommentIds.get(selectedId) : void 0;
|
|
9967
|
+
if (replacementId) selection.value = replacementId;
|
|
9746
9968
|
};
|
|
9747
9969
|
remapSelection(activeComment);
|
|
9748
9970
|
remapSelection(activeFloatingCommentInstanceId);
|
|
9749
9971
|
commentsList.value.forEach((row) => {
|
|
9750
9972
|
if (!belongsToTrackedChangeSyncDocument(row, activeDocumentId)) return;
|
|
9751
9973
|
const rowIdentityUpdates = {};
|
|
9752
|
-
for (const field of
|
|
9753
|
-
"
|
|
9754
|
-
"trackedChangeParentId",
|
|
9755
|
-
"threadingParentCommentId",
|
|
9756
|
-
"parentCommentId"
|
|
9757
|
-
]) {
|
|
9758
|
-
const replacementId = droppedCommentIds.get(normalizeCommentId(row?.[field]));
|
|
9974
|
+
for (const field of PARENT_LINK_FIELDS) {
|
|
9975
|
+
const replacementId = droppedCommentIds.get(normalizeCommentId(row?.[field]) ?? "");
|
|
9759
9976
|
if (!replacementId) continue;
|
|
9760
9977
|
row[field] = replacementId;
|
|
9761
9978
|
rowIdentityUpdates[field] = replacementId;
|
|
@@ -9764,9 +9981,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9764
9981
|
});
|
|
9765
9982
|
};
|
|
9766
9983
|
const compactDuplicateBodyTrackedChangeComments = (activeDocumentId) => {
|
|
9767
|
-
const
|
|
9768
|
-
const groups = groupBodyTrackedChangeCommentsByIdentity(candidates);
|
|
9769
|
-
const duplicates = mergeDuplicateBodyTrackedChangeComments(groups);
|
|
9984
|
+
const duplicates = mergeDuplicateBodyTrackedChangeComments(groupBodyTrackedChangeCommentsByIdentity(commentsList.value.filter((comment) => isBodyTrackedChangeComment(comment) && belongsToTrackedChangeSyncDocument(comment, activeDocumentId))));
|
|
9770
9985
|
if (!duplicates.size) return 0;
|
|
9771
9986
|
commentsList.value = commentsList.value.filter((comment) => !duplicates.has(comment));
|
|
9772
9987
|
remapTrackedChangeReferences(createDroppedCommentIdMap(duplicates), activeDocumentId);
|
|
@@ -9778,10 +9993,6 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9778
9993
|
*
|
|
9779
9994
|
* Pruning is scoped to the active editor document so replay in one document does not
|
|
9780
9995
|
* 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
9996
|
*/
|
|
9786
9997
|
const pruneStaleTrackedChangeComments = (liveTrackedChangeIds, liveTrackedChangeAnchorKeys, activeDocumentId, superdoc = null, { broadcastChanges = true } = {}) => withInteractionSpan("store.trackedChanges.pruneStaleComments", "store-reconciliation", {
|
|
9787
9998
|
activeDocumentId: activeDocumentId ?? null,
|
|
@@ -9826,7 +10037,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9826
10037
|
comment: payload
|
|
9827
10038
|
};
|
|
9828
10039
|
if (broadcastChanges) {
|
|
9829
|
-
syncCommentsToClients(superdoc, event);
|
|
10040
|
+
syncCommentsToClients(requireHost(superdoc, "pruneStaleTrackedChangeComments"), event);
|
|
9830
10041
|
superdoc?.emit?.("comments-update", event);
|
|
9831
10042
|
}
|
|
9832
10043
|
});
|
|
@@ -9858,14 +10069,10 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9858
10069
|
const event = {
|
|
9859
10070
|
type: COMMENT_EVENTS.DELETED,
|
|
9860
10071
|
comment: payload,
|
|
9861
|
-
changes: [
|
|
9862
|
-
key: "deleted",
|
|
9863
|
-
commentId: payload.commentId,
|
|
9864
|
-
fileId: payload.fileId
|
|
9865
|
-
}]
|
|
10072
|
+
changes: getDeletedCommentChanges([payload, comment], payload.fileId)
|
|
9866
10073
|
};
|
|
9867
10074
|
if (broadcastChanges) {
|
|
9868
|
-
syncCommentsToClients(superdoc, event);
|
|
10075
|
+
syncCommentsToClients(requireHost(superdoc, "pruneStaleTrackedChangeComments"), event);
|
|
9869
10076
|
superdoc?.emit?.("comments-update", event);
|
|
9870
10077
|
}
|
|
9871
10078
|
});
|
|
@@ -9888,7 +10095,6 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9888
10095
|
const resolveArgs = {
|
|
9889
10096
|
email: superdoc?.user?.email ?? null,
|
|
9890
10097
|
name: superdoc?.user?.name ?? null,
|
|
9891
|
-
superdoc,
|
|
9892
10098
|
reconciliationToken: COMMENT_RECONCILIATION_TOKEN
|
|
9893
10099
|
};
|
|
9894
10100
|
let resolvedCount = 0;
|
|
@@ -9899,27 +10105,18 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9899
10105
|
trackedChangeThreadParentIdForComment(linkedComment),
|
|
9900
10106
|
linkedComment.threadingParentCommentId,
|
|
9901
10107
|
linkedComment.parentCommentId
|
|
9902
|
-
].map((id) => normalizeCommentId(id)).filter(
|
|
10108
|
+
].map((id) => normalizeCommentId(id)).filter(isPresent).some((id) => trackedChangeIds.has(id))) return;
|
|
9903
10109
|
if (typeof linkedComment.resolveComment === "function") {
|
|
9904
|
-
linkedComment.resolveComment(
|
|
10110
|
+
linkedComment.resolveComment({
|
|
10111
|
+
...resolveArgs,
|
|
10112
|
+
superdoc: requireHost(superdoc, "resolveLinkedCommentsForTrackedChangeDecision")
|
|
10113
|
+
});
|
|
9905
10114
|
resolvedCount += 1;
|
|
9906
10115
|
}
|
|
9907
10116
|
});
|
|
9908
10117
|
return resolvedCount;
|
|
9909
10118
|
};
|
|
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
|
-
};
|
|
10119
|
+
const collectTrackedChangeDecisionIds = (comment) => collectTrackedChangeDecisionIdsWithAliases(comment, getCommentAliasIds(comment));
|
|
9923
10120
|
const getTrackedChangeDecisionLinks = (comment) => {
|
|
9924
10121
|
const linked = [];
|
|
9925
10122
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -9930,28 +10127,6 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
9930
10127
|
}
|
|
9931
10128
|
return linked;
|
|
9932
10129
|
};
|
|
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
10130
|
const detachLinkedCommentsForTrackedChangeDecision = ({ comment, decision } = {}) => {
|
|
9956
10131
|
if (!comment?.trackedChange) return 0;
|
|
9957
10132
|
if (!trackedChangeDecisionKeepsCommentAnchor({
|
|
@@ -10032,7 +10207,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
10032
10207
|
if (previousCommentId) anchorSourceIds.add(previousCommentId);
|
|
10033
10208
|
if (previousCanonicalId) anchorSourceIds.add(previousCanonicalId);
|
|
10034
10209
|
}
|
|
10035
|
-
if (comment.trackedChangeAnchorKey == null || anchorSourceIds.has(currentAnchorParts?.rawId)) comment.trackedChangeAnchorKey = toAnchor;
|
|
10210
|
+
if (comment.trackedChangeAnchorKey == null || anchorSourceIds.has(currentAnchorParts?.rawId ?? "")) comment.trackedChangeAnchorKey = toAnchor;
|
|
10036
10211
|
comment.trackedChangePositionAliases = normalizeTrackedChangePositionAliases([...Array.isArray(comment.trackedChangePositionAliases) ? comment.trackedChangePositionAliases : [], fromId]);
|
|
10037
10212
|
const identitySourceIds = /* @__PURE__ */ new Set([fromId]);
|
|
10038
10213
|
if (advancesRemapLineage) {
|
|
@@ -10043,33 +10218,28 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
10043
10218
|
if (row === comment) return;
|
|
10044
10219
|
if (!belongsToTrackedChangeSyncDocument(row, normalizedDocumentId)) return;
|
|
10045
10220
|
const rowIdentityUpdates = {};
|
|
10046
|
-
for (const field of
|
|
10047
|
-
"
|
|
10048
|
-
"trackedChangeParentId",
|
|
10049
|
-
"threadingParentCommentId",
|
|
10050
|
-
"parentCommentId"
|
|
10051
|
-
]) {
|
|
10052
|
-
if (!identitySourceIds.has(normalizeCommentId(row?.[field]))) continue;
|
|
10221
|
+
for (const field of PARENT_LINK_FIELDS) {
|
|
10222
|
+
if (!identitySourceIds.has(normalizeCommentId(row?.[field]) ?? "")) continue;
|
|
10053
10223
|
row[field] = toId;
|
|
10054
10224
|
rowIdentityUpdates[field] = toId;
|
|
10055
10225
|
}
|
|
10056
10226
|
if (Object.keys(rowIdentityUpdates).length && typeof row.updateIdentityValues === "function") row.updateIdentityValues(rowIdentityUpdates);
|
|
10057
10227
|
});
|
|
10058
10228
|
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));
|
|
10229
|
+
const previousEntry = previousPositionEntry ?? [positions[fromId], positions[String(buildBodyTrackedChangeAnchorKey(fromId))]].find((entry) => entry && positionEntryMatchesTrackedChangeStory(entry, comment));
|
|
10060
10230
|
if (previousEntry) {
|
|
10061
|
-
for (const key of [toId, toAnchor]) if (positions[key] === void 0) {
|
|
10231
|
+
for (const key of [toId, String(toAnchor)]) if (positions[key] === void 0) {
|
|
10062
10232
|
positions[key] = previousEntry;
|
|
10063
10233
|
positionsChanged = true;
|
|
10064
10234
|
}
|
|
10065
10235
|
}
|
|
10066
|
-
if (identitySourceIds.has(normalizeCommentId(activeComment.value))) activeComment.value = toId;
|
|
10067
|
-
if (identitySourceIds.has(normalizeCommentId(activeFloatingCommentInstanceId.value))) activeFloatingCommentInstanceId.value = toId;
|
|
10236
|
+
if (identitySourceIds.has(normalizeCommentId(activeComment.value) ?? "")) activeComment.value = toId;
|
|
10237
|
+
if (identitySourceIds.has(normalizeCommentId(activeFloatingCommentInstanceId.value) ?? "")) activeFloatingCommentInstanceId.value = toId;
|
|
10068
10238
|
}
|
|
10069
10239
|
if (positionsChanged) editorCommentPositions.value = { ...positions };
|
|
10070
10240
|
};
|
|
10071
10241
|
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(
|
|
10242
|
+
const normalizedDecidedIds = new Set((Array.isArray(decidedIds) || decidedIds instanceof Set ? Array.from(decidedIds) : [decidedId]).map((id) => normalizeCommentId(id)).filter(isPresent));
|
|
10073
10243
|
const normalizedDocumentId = normalizeCommentId(documentId);
|
|
10074
10244
|
if (!normalizedDecidedIds.size || !normalizedDocumentId) return {
|
|
10075
10245
|
removed: false,
|
|
@@ -10127,39 +10297,8 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
10127
10297
|
removedIds
|
|
10128
10298
|
};
|
|
10129
10299
|
};
|
|
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
10300
|
/**
|
|
10156
10301
|
* 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
10302
|
*/
|
|
10164
10303
|
const decideTrackedChangeFromSidebar = ({ superdoc, comment, decision }) => {
|
|
10165
10304
|
const disabledReason = trackedChangeDecisionDisabledReason(superdoc);
|
|
@@ -10187,7 +10326,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
10187
10326
|
return {
|
|
10188
10327
|
ok: false,
|
|
10189
10328
|
reason: "adapter-threw",
|
|
10190
|
-
detail:
|
|
10329
|
+
detail: errorDetail(err)
|
|
10191
10330
|
};
|
|
10192
10331
|
}
|
|
10193
10332
|
})().then(async (outcome) => {
|
|
@@ -10240,9 +10379,11 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
10240
10379
|
if (!activeEditor) return { ok: false };
|
|
10241
10380
|
const id = comment.commentId ?? comment.importedId;
|
|
10242
10381
|
if (!id) return { ok: false };
|
|
10243
|
-
const
|
|
10382
|
+
const rawStory = comment.trackedChangeStory ?? void 0;
|
|
10383
|
+
const story = isStoryLocator(rawStory) ? rawStory : void 0;
|
|
10244
10384
|
const documentApi = typeof activeEditor.doc === "object" ? activeEditor.doc : null;
|
|
10245
10385
|
if (documentApi?.trackChanges?.decide) try {
|
|
10386
|
+
if (rawStory && !story) throw new TypeError("trackedChangeStory must be a valid StoryLocator");
|
|
10246
10387
|
const target = story ? {
|
|
10247
10388
|
id,
|
|
10248
10389
|
story
|
|
@@ -10255,7 +10396,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
10255
10396
|
success: Boolean(receipt?.success)
|
|
10256
10397
|
}));
|
|
10257
10398
|
} catch (error) {
|
|
10258
|
-
if (
|
|
10399
|
+
if (rawStory) return {
|
|
10259
10400
|
ok: false,
|
|
10260
10401
|
error
|
|
10261
10402
|
};
|
|
@@ -10302,9 +10443,9 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
10302
10443
|
documentId: effectiveDocumentId
|
|
10303
10444
|
})).removed
|
|
10304
10445
|
};
|
|
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(
|
|
10446
|
+
const normalizedRemovedIds = new Set(Array.from(removedIds ?? []).map((id) => normalizeCommentId(id)).filter(isPresent));
|
|
10447
|
+
const normalizedUpsertIds = [...new Set(Array.from(upsertIds ?? []).map((id) => normalizeCommentId(id)).filter(isPresent))];
|
|
10448
|
+
const remappedSourceIds = new Set((Array.isArray(remappedPairs) ? remappedPairs : []).map((pair) => normalizeCommentId(pair?.from)).filter(isPresent));
|
|
10308
10449
|
const locallyRemovedIds = new Set([...normalizedRemovedIds].filter((id) => !remappedSourceIds.has(id)));
|
|
10309
10450
|
if (locallyRemovedIds.size > 0 && effectiveDocumentId != null) pruneDecidedTrackedChangeRow({
|
|
10310
10451
|
superdoc,
|
|
@@ -10323,6 +10464,10 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
10323
10464
|
const byIdentityAlias = /* @__PURE__ */ new Map();
|
|
10324
10465
|
const aliasesByRow = /* @__PURE__ */ new Map();
|
|
10325
10466
|
const indexedRows = /* @__PURE__ */ new Set();
|
|
10467
|
+
const indexedIdentities = [];
|
|
10468
|
+
let building = true;
|
|
10469
|
+
let reusable = true;
|
|
10470
|
+
let reused = false;
|
|
10326
10471
|
let aliasLookups = 0;
|
|
10327
10472
|
let candidateVisits = 0;
|
|
10328
10473
|
let rowAliasBuilds = 0;
|
|
@@ -10346,6 +10491,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
10346
10491
|
index.set(alias, bucket);
|
|
10347
10492
|
};
|
|
10348
10493
|
const add = (comment) => {
|
|
10494
|
+
if (!building) reusable = false;
|
|
10349
10495
|
if (!comment?.trackedChange) return;
|
|
10350
10496
|
if (documentId && !belongsToTrackedChangeSyncDocument(comment, documentId)) return;
|
|
10351
10497
|
indexedRows.add(comment);
|
|
@@ -10357,19 +10503,49 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
10357
10503
|
rowAliasBuilds += 1;
|
|
10358
10504
|
aliasesByRow.set(comment, aliases);
|
|
10359
10505
|
aliases.forEach((alias) => addAlias(byIdentityAlias, alias, comment));
|
|
10506
|
+
if (building) indexedIdentities.push({
|
|
10507
|
+
row: comment,
|
|
10508
|
+
aliases,
|
|
10509
|
+
canonicalId: normalizeCommentId(comment.trackedChangeCanonicalId)
|
|
10510
|
+
});
|
|
10360
10511
|
};
|
|
10361
10512
|
commentsList.value.forEach(add);
|
|
10513
|
+
building = false;
|
|
10362
10514
|
return {
|
|
10515
|
+
inUse: false,
|
|
10363
10516
|
add,
|
|
10364
10517
|
aliasesFor,
|
|
10365
|
-
|
|
10366
|
-
|
|
10367
|
-
|
|
10368
|
-
|
|
10369
|
-
|
|
10370
|
-
|
|
10371
|
-
|
|
10372
|
-
|
|
10518
|
+
isCurrent: () => {
|
|
10519
|
+
if (!reusable) return false;
|
|
10520
|
+
let index = 0;
|
|
10521
|
+
for (const row of commentsList.value) {
|
|
10522
|
+
if (!row?.trackedChange || documentId && !belongsToTrackedChangeSyncDocument(row, documentId)) continue;
|
|
10523
|
+
const previous = indexedIdentities[index++];
|
|
10524
|
+
if (!previous || previous.row !== row || previous.canonicalId !== normalizeCommentId(row.trackedChangeCanonicalId)) return false;
|
|
10525
|
+
const aliases = getCommentAliasIds(row);
|
|
10526
|
+
rowAliasBuilds += 1;
|
|
10527
|
+
if (aliases.length !== previous.aliases.length || aliases.some((alias, i) => alias !== previous.aliases[i])) return false;
|
|
10528
|
+
}
|
|
10529
|
+
reused = index === indexedIdentities.length;
|
|
10530
|
+
return reused;
|
|
10531
|
+
},
|
|
10532
|
+
work: () => {
|
|
10533
|
+
const result = {
|
|
10534
|
+
trackedRowsIndexed: indexedRows.size,
|
|
10535
|
+
invalidatedIdMembershipChecks: 0,
|
|
10536
|
+
incomingAliasLookups: aliasLookups,
|
|
10537
|
+
candidateVisits,
|
|
10538
|
+
rowAliasBuilds,
|
|
10539
|
+
rowAliasCacheHits,
|
|
10540
|
+
indexReused: Number(reused)
|
|
10541
|
+
};
|
|
10542
|
+
aliasLookups = 0;
|
|
10543
|
+
candidateVisits = 0;
|
|
10544
|
+
rowAliasBuilds = 0;
|
|
10545
|
+
rowAliasCacheHits = 0;
|
|
10546
|
+
reused = false;
|
|
10547
|
+
return result;
|
|
10548
|
+
},
|
|
10373
10549
|
candidates({ changeId, importedId, anchorKey, canonicalId, positionAliases = [] } = {}) {
|
|
10374
10550
|
const out = /* @__PURE__ */ new Set();
|
|
10375
10551
|
const include = (value) => {
|
|
@@ -10392,7 +10568,30 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
10392
10568
|
}
|
|
10393
10569
|
};
|
|
10394
10570
|
};
|
|
10395
|
-
const
|
|
10571
|
+
const getTrackedChangeBatchIdentityIndex = (documentId) => {
|
|
10572
|
+
const cached = cachedTrackedChangeBatchIdentityIndex;
|
|
10573
|
+
if (cached?.documentId === documentId && !cached.index.inUse) {
|
|
10574
|
+
cached.index.inUse = true;
|
|
10575
|
+
let current = false;
|
|
10576
|
+
try {
|
|
10577
|
+
current = cached.index.isCurrent() && cachedTrackedChangeBatchIdentityIndex === cached;
|
|
10578
|
+
} finally {
|
|
10579
|
+
if (!current) {
|
|
10580
|
+
cached.index.inUse = false;
|
|
10581
|
+
if (cachedTrackedChangeBatchIdentityIndex === cached) cachedTrackedChangeBatchIdentityIndex = null;
|
|
10582
|
+
}
|
|
10583
|
+
}
|
|
10584
|
+
if (current) return cached.index;
|
|
10585
|
+
}
|
|
10586
|
+
const index = createTrackedChangeBatchIdentityIndex(documentId);
|
|
10587
|
+
index.inUse = true;
|
|
10588
|
+
cachedTrackedChangeBatchIdentityIndex = {
|
|
10589
|
+
documentId,
|
|
10590
|
+
index
|
|
10591
|
+
};
|
|
10592
|
+
return index;
|
|
10593
|
+
};
|
|
10594
|
+
const reconcileTrackedChangesFromV2 = ({ superdoc, adapter, documentId, items, pruneStale = true, preparedParams = null, preserveDraft = false, preparedPresentation = null, previousPreparedPresentation = null, liveIds: suppliedLiveIds = null, liveAnchorKeys: suppliedLiveAnchorKeys = null, hydrationGeneration } = {}) => withInteractionSpan("store.trackedChanges.reconcile", "store-reconciliation", {
|
|
10396
10595
|
documentId: documentId ?? null,
|
|
10397
10596
|
itemCount: Array.isArray(items) ? items.length : null,
|
|
10398
10597
|
pruneStale,
|
|
@@ -10404,33 +10603,36 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
10404
10603
|
const liveAnchorKeys = suppliedLiveAnchorKeys instanceof Set ? suppliedLiveAnchorKeys : /* @__PURE__ */ new Set();
|
|
10405
10604
|
const liveIds = suppliedLiveIds instanceof Set ? suppliedLiveIds : /* @__PURE__ */ new Set();
|
|
10406
10605
|
let appliedCount = 0;
|
|
10407
|
-
const trackedChangeIdentityIndex =
|
|
10606
|
+
const trackedChangeIdentityIndex = getTrackedChangeBatchIdentityIndex(effectiveDocumentId == null ? null : String(effectiveDocumentId));
|
|
10408
10607
|
const identitySpan = startInteractionSpan("store.trackedChanges.batchIdentity", "store-reconciliation", { itemCount: items.length });
|
|
10409
|
-
|
|
10410
|
-
const previousCoordinate = previousPreparedPresentation?.coordinate;
|
|
10411
|
-
const coordinate = preparedPresentation?.coordinate;
|
|
10412
|
-
const retainUnchangedRows = !pruneStale && previousCoordinate && coordinate && coordinate.documentEpoch === preparedPresentation.epoch && coordinate.documentEpoch === previousPreparedPresentation.epoch && coordinate.documentEpoch === previousCoordinate.documentEpoch && typeof coordinate.mountId === "string" && coordinate.mountId.length > 0 && coordinate.mountId === previousCoordinate.mountId && preparedPresentation.baseVersion === previousPreparedPresentation.version && preparedPresentation.version === preparedPresentation.baseVersion + 1 && coordinate.reviewVersion === preparedPresentation.version && previousCoordinate.reviewVersion === previousPreparedPresentation.version && Number.isSafeInteger(coordinate.commitSequence) && Number.isSafeInteger(previousCoordinate.commitSequence) && coordinate.commitSequence >= previousCoordinate.commitSequence;
|
|
10608
|
+
let enteredBatch = false;
|
|
10413
10609
|
try {
|
|
10610
|
+
const paramsList = Array.isArray(preparedParams) ? preparedParams : items.map((item) => adapter.mapV2TrackedChangeToCommentParams(item));
|
|
10611
|
+
const previousCoordinate = previousPreparedPresentation?.coordinate;
|
|
10612
|
+
const coordinate = preparedPresentation?.coordinate;
|
|
10613
|
+
const retainUnchangedRows = !pruneStale && previousCoordinate && coordinate && coordinate.documentEpoch === preparedPresentation.epoch && coordinate.documentEpoch === previousPreparedPresentation.epoch && coordinate.documentEpoch === previousCoordinate.documentEpoch && typeof coordinate.mountId === "string" && coordinate.mountId.length > 0 && coordinate.mountId === previousCoordinate.mountId && preparedPresentation.baseVersion === previousPreparedPresentation.version && preparedPresentation.version === preparedPresentation.baseVersion + 1 && coordinate.reviewVersion === preparedPresentation.version && previousCoordinate.reviewVersion === previousPreparedPresentation.version && Number.isSafeInteger(coordinate.commitSequence) && Number.isSafeInteger(previousCoordinate.commitSequence) && coordinate.commitSequence >= previousCoordinate.commitSequence;
|
|
10614
|
+
enteredBatch = true;
|
|
10414
10615
|
for (const params of paramsList) {
|
|
10415
10616
|
if (!params) continue;
|
|
10416
10617
|
let retainUnchangedRow = false;
|
|
10618
|
+
const anchorParts = parseTrackedChangeAnchorKey(params.trackedChangeAnchorKey);
|
|
10619
|
+
const anchorStoryKey = anchorParts ? normalizeTrackedChangeStoryKey(anchorParts.storyKey) : void 0;
|
|
10417
10620
|
if (preparedPresentation) {
|
|
10418
10621
|
if (preparedPresentation !== committedReviewPresentations.value[String(effectiveDocumentId)]) continue;
|
|
10419
10622
|
if (params.documentId != null && String(params.documentId) !== String(effectiveDocumentId)) continue;
|
|
10420
10623
|
const id = normalizeCommentId(params.changeId);
|
|
10421
|
-
const version = preparedPresentation.rowVersions?.[id];
|
|
10624
|
+
const version = preparedPresentation.rowVersions?.[String(id)] ?? NaN;
|
|
10422
10625
|
if (!id || !Number.isSafeInteger(version) || version < 1) continue;
|
|
10423
10626
|
const existing = [...trackedChangeIdentityIndex.candidates({ changeId: id })].filter((row) => String(row.fileId) === String(effectiveDocumentId) && String(row.commentId) === id);
|
|
10424
10627
|
if (existing.length > 1) continue;
|
|
10425
10628
|
const row = existing[0];
|
|
10426
10629
|
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)) !==
|
|
10630
|
+
const previousVersion = previousPreparedPresentation?.rowVersions?.[id] ?? NaN;
|
|
10631
|
+
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
10632
|
row.trackedChangeCanonicalId = params.trackedChangeCanonicalId;
|
|
10430
|
-
row.updateIdentityValues?.({ trackedChangeCanonicalId: params.trackedChangeCanonicalId });
|
|
10431
10633
|
trackedChangeIdentityIndex.add(row);
|
|
10432
10634
|
}
|
|
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)) ===
|
|
10635
|
+
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
10636
|
}
|
|
10435
10637
|
if (params.event === "omit") {
|
|
10436
10638
|
if (params.changeId != null) liveIds.add(String(params.changeId));
|
|
@@ -10444,12 +10646,15 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
10444
10646
|
superdoc,
|
|
10445
10647
|
params,
|
|
10446
10648
|
broadcastChanges: false,
|
|
10447
|
-
trackedChangeIdentityIndex
|
|
10649
|
+
trackedChangeIdentityIndex,
|
|
10650
|
+
preserveDraft
|
|
10448
10651
|
});
|
|
10449
10652
|
appliedCount += 1;
|
|
10450
10653
|
}
|
|
10451
10654
|
} finally {
|
|
10452
|
-
|
|
10655
|
+
const work = trackedChangeIdentityIndex.work();
|
|
10656
|
+
trackedChangeIdentityIndex.inUse = false;
|
|
10657
|
+
if (enteredBatch) endInteractionSpan(identitySpan, work);
|
|
10453
10658
|
}
|
|
10454
10659
|
if (!effectiveDocumentId || !pruneStale) {
|
|
10455
10660
|
if (effectiveDocumentId) compactDuplicateBodyTrackedChangeComments(String(effectiveDocumentId));
|
|
@@ -10471,22 +10676,18 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
10471
10676
|
return commentsList.value.filter((comment) => {
|
|
10472
10677
|
if (comment?.trackedChange !== true) return false;
|
|
10473
10678
|
if (normalizedDocumentId == null) return true;
|
|
10474
|
-
const rowDocumentId = comment
|
|
10679
|
+
const rowDocumentId = Reflect.get(comment, "documentId") ?? comment?.fileId ?? null;
|
|
10475
10680
|
return rowDocumentId != null && String(rowDocumentId) === normalizedDocumentId;
|
|
10476
10681
|
}).length;
|
|
10477
10682
|
};
|
|
10478
10683
|
/**
|
|
10479
10684
|
* Triggered when the editor locations are updated
|
|
10480
10685
|
* 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
10686
|
*/
|
|
10486
10687
|
const handleEditorLocationsUpdate = (allCommentPositions, options = {}) => {
|
|
10487
10688
|
if (allCommentPositions == null) return;
|
|
10488
10689
|
const retainMissingTrackedChangeGeometry = options?.retainMissingTrackedChangeGeometry === true;
|
|
10489
|
-
const retainedTrackedChangeIds = retainMissingTrackedChangeGeometry && options?.retainedTrackedChangeIds != null ? new Set(Array.from(options.retainedTrackedChangeIds, (id) => normalizeCommentId(id)).filter(
|
|
10690
|
+
const retainedTrackedChangeIds = retainMissingTrackedChangeGeometry && options?.retainedTrackedChangeIds != null ? new Set(Array.from(options.retainedTrackedChangeIds, (id) => normalizeCommentId(id)).filter(isPresent)) : null;
|
|
10490
10691
|
const previousPositions = editorCommentPositions.value || {};
|
|
10491
10692
|
const normalizedPositions = {};
|
|
10492
10693
|
Object.entries(allCommentPositions).forEach(([key, entry]) => {
|
|
@@ -10513,7 +10714,7 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
10513
10714
|
return null;
|
|
10514
10715
|
};
|
|
10515
10716
|
const writeTrackedChangeAliases = (entry, comment, extraKeys = []) => {
|
|
10516
|
-
const keys = [...aliasesFor(comment), ...extraKeys.map((id) => normalizeCommentId(id)).filter(
|
|
10717
|
+
const keys = [...aliasesFor(comment), ...extraKeys.map((id) => normalizeCommentId(id)).filter(isPresent)];
|
|
10517
10718
|
for (const key of new Set(keys)) if (normalizedPositions[key] === void 0) normalizedPositions[key] = entry;
|
|
10518
10719
|
};
|
|
10519
10720
|
commentsList.value.forEach((comment) => {
|
|
@@ -10712,7 +10913,7 @@ var ellipsis_vertical_solid_default = "<svg xmlns=\"http://www.w3.org/2000/svg\"
|
|
|
10712
10913
|
//#region ../../shared/common/icons/rotate-left-solid.svg?raw
|
|
10713
10914
|
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
10915
|
//#endregion
|
|
10715
|
-
//#region src/icons.
|
|
10916
|
+
//#region src/icons.ts
|
|
10716
10917
|
var superdocIcons = {
|
|
10717
10918
|
comment: comment_solid_default,
|
|
10718
10919
|
caretDown: caret_down_solid_default,
|
|
@@ -11074,12 +11275,9 @@ var InternalDropdown_default = /* @__PURE__ */ _plugin_vue_export_helper_default
|
|
|
11074
11275
|
}
|
|
11075
11276
|
}), [["__scopeId", "data-v-026f5d66"]]);
|
|
11076
11277
|
//#endregion
|
|
11077
|
-
//#region src/components/CommentsLayer/helpers.
|
|
11278
|
+
//#region src/components/CommentsLayer/helpers.ts
|
|
11078
11279
|
/**
|
|
11079
11280
|
* Comments helper to format dates from timestamp
|
|
11080
|
-
*
|
|
11081
|
-
* @param {Number} timestamp The timestamp to format
|
|
11082
|
-
* @returns {String} The formatted date
|
|
11083
11281
|
*/
|
|
11084
11282
|
function formatDate(timestamp) {
|
|
11085
11283
|
const date = new Date(timestamp);
|
|
@@ -11677,7 +11875,7 @@ var CommentInput_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/*
|
|
|
11677
11875
|
}
|
|
11678
11876
|
}), [["__scopeId", "data-v-aa97de44"]]);
|
|
11679
11877
|
//#endregion
|
|
11680
|
-
//#region src/internal/toolbar/built-in/url-safety.
|
|
11878
|
+
//#region src/internal/toolbar/built-in/url-safety.ts
|
|
11681
11879
|
/**
|
|
11682
11880
|
* Minimal href sanitizer for the built-in link popover.
|
|
11683
11881
|
*
|
|
@@ -11693,8 +11891,6 @@ var DANGEROUS_SCHEME = /^(javascript|data|vbscript):/i;
|
|
|
11693
11891
|
var HAS_SCHEME = /^[a-z][a-z0-9+.-]*:/i;
|
|
11694
11892
|
/**
|
|
11695
11893
|
* Validate and normalize an href. Returns `{ href }` for safe values, or `null`.
|
|
11696
|
-
* @param {string} value
|
|
11697
|
-
* @returns {{ href: string }|null}
|
|
11698
11894
|
*/
|
|
11699
11895
|
function sanitizeHref(value) {
|
|
11700
11896
|
if (typeof value !== "string") return null;
|
|
@@ -11706,7 +11902,7 @@ function sanitizeHref(value) {
|
|
|
11706
11902
|
return { href: trimmed };
|
|
11707
11903
|
}
|
|
11708
11904
|
//#endregion
|
|
11709
|
-
//#region src/components/CommentsLayer/comment-urls.
|
|
11905
|
+
//#region src/components/CommentsLayer/comment-urls.ts
|
|
11710
11906
|
function isAbsoluteWebUrl(value) {
|
|
11711
11907
|
if (!/^https?:\/\/[^\s/?#\\]+/i.test(value) || /[\s\\]/u.test(value)) return false;
|
|
11712
11908
|
try {
|
|
@@ -11730,7 +11926,7 @@ function trimUrlPunctuation(value) {
|
|
|
11730
11926
|
for (const character of value) {
|
|
11731
11927
|
const close = closingDelimiter[character];
|
|
11732
11928
|
if (close) balance[close] += 1;
|
|
11733
|
-
else if (Object.
|
|
11929
|
+
else if (Object.prototype.hasOwnProperty.call(balance, character)) balance[character] -= 1;
|
|
11734
11930
|
}
|
|
11735
11931
|
let end = value.length;
|
|
11736
11932
|
while (end > 0) {
|
|
@@ -11754,17 +11950,18 @@ function renderCommentHtml(value) {
|
|
|
11754
11950
|
if (typeof document === "undefined") return value;
|
|
11755
11951
|
const template = document.createElement("template");
|
|
11756
11952
|
template.innerHTML = value;
|
|
11757
|
-
for (const link of template.content.querySelectorAll("a")) {
|
|
11758
|
-
const
|
|
11953
|
+
for (const link of Array.from(template.content.querySelectorAll("a"))) {
|
|
11954
|
+
const rawHref = link.getAttribute("href");
|
|
11955
|
+
const safe = rawHref === null ? null : sanitizeHref(rawHref);
|
|
11759
11956
|
if (safe && (isAbsoluteWebUrl(safe.href) || /^(mailto|tel):\S+$/i.test(safe.href))) configureLink(link, safe.href);
|
|
11760
|
-
else link.replaceWith(...link.childNodes);
|
|
11957
|
+
else link.replaceWith(...Array.from(link.childNodes));
|
|
11761
11958
|
}
|
|
11762
11959
|
const walker = document.createTreeWalker(template.content, NodeFilter.SHOW_TEXT);
|
|
11763
11960
|
const textNodes = [];
|
|
11764
|
-
while (walker.nextNode()) textNodes.push(walker.currentNode);
|
|
11961
|
+
while (walker.nextNode()) if (walker.currentNode instanceof Text) textNodes.push(walker.currentNode);
|
|
11765
11962
|
for (const node of textNodes) {
|
|
11766
11963
|
if (node.parentElement?.closest("a, script, style, textarea, code, pre")) continue;
|
|
11767
|
-
const text = node.
|
|
11964
|
+
const text = node.data;
|
|
11768
11965
|
const fragment = document.createDocumentFragment();
|
|
11769
11966
|
let end = 0;
|
|
11770
11967
|
for (const match of text.matchAll(/(^|[\s([{])(https?:\/\/[^\s<>"']+)/gi)) {
|
|
@@ -11823,8 +12020,8 @@ var _hoisted_11$3 = {
|
|
|
11823
12020
|
key: 0,
|
|
11824
12021
|
class: "card-section comment-body"
|
|
11825
12022
|
};
|
|
11826
|
-
var _hoisted_12$
|
|
11827
|
-
var _hoisted_13$
|
|
12023
|
+
var _hoisted_12$3 = ["data-track-change-semantic-color-key"];
|
|
12024
|
+
var _hoisted_13$3 = { key: 0 };
|
|
11828
12025
|
var _hoisted_14$2 = { class: "change-type tracked-change-label" };
|
|
11829
12026
|
var _hoisted_15$2 = {
|
|
11830
12027
|
key: 0,
|
|
@@ -12609,6 +12806,16 @@ var CommentDialog_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/*
|
|
|
12609
12806
|
}
|
|
12610
12807
|
handleResolve();
|
|
12611
12808
|
};
|
|
12809
|
+
const ownsTrackedChangeDecision = (superdoc, editor) => editor !== null && proxy.$superdoc === superdoc && superdoc.activeEditor === editor;
|
|
12810
|
+
const restoreTrackedChangeDecisionFocus = (superdoc, editor) => {
|
|
12811
|
+
nextTick(() => {
|
|
12812
|
+
if (!ownsTrackedChangeDecision(superdoc, editor)) return;
|
|
12813
|
+
commentsStore.lastUpdate = /* @__PURE__ */ new Date();
|
|
12814
|
+
activeComment.value = null;
|
|
12815
|
+
commentsStore.setActiveComment(superdoc, activeComment.value);
|
|
12816
|
+
if (ownsTrackedChangeDecision(superdoc, editor)) superdoc.focus?.({ preventScroll: true });
|
|
12817
|
+
});
|
|
12818
|
+
};
|
|
12612
12819
|
const handleReject = async () => {
|
|
12613
12820
|
if (props.comment.trackedChange) {
|
|
12614
12821
|
if (trackedChangeDecisionsAreDisabled()) return trackedChangeDecisionDisabledOutcome();
|
|
@@ -12616,23 +12823,21 @@ var CommentDialog_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/*
|
|
|
12616
12823
|
const customHandler = proxy.$superdoc.config.onTrackedChangeBubbleReject;
|
|
12617
12824
|
if (props.comment.trackedChange) {
|
|
12618
12825
|
if (isV2Mode.value) {
|
|
12826
|
+
const superdoc = proxy.$superdoc;
|
|
12827
|
+
const editor = superdoc.activeEditor;
|
|
12619
12828
|
const outcome = await commentsStore.decideTrackedChangeFromSidebar({
|
|
12620
|
-
superdoc
|
|
12829
|
+
superdoc,
|
|
12621
12830
|
comment: props.comment,
|
|
12622
12831
|
decision: "reject"
|
|
12623
12832
|
});
|
|
12833
|
+
if (!ownsTrackedChangeDecision(superdoc, editor)) return;
|
|
12624
12834
|
if (!outcome?.ok || outcome.success === false) {
|
|
12625
12835
|
reportTrackedChangeDecisionFailure("reject", outcome);
|
|
12626
12836
|
return;
|
|
12627
12837
|
}
|
|
12628
12838
|
clearTrackedChangeDecisionFailure();
|
|
12629
|
-
if (typeof customHandler === "function") customHandler(props.comment,
|
|
12630
|
-
|
|
12631
|
-
commentsStore.lastUpdate = /* @__PURE__ */ new Date();
|
|
12632
|
-
activeComment.value = null;
|
|
12633
|
-
commentsStore.setActiveComment(proxy.$superdoc, activeComment.value);
|
|
12634
|
-
proxy.$superdoc.focus?.({ preventScroll: true });
|
|
12635
|
-
});
|
|
12839
|
+
if (typeof customHandler === "function") customHandler(props.comment, editor);
|
|
12840
|
+
restoreTrackedChangeDecisionFocus(superdoc, editor);
|
|
12636
12841
|
return;
|
|
12637
12842
|
}
|
|
12638
12843
|
let decisionApplied = true;
|
|
@@ -12678,23 +12883,21 @@ var CommentDialog_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/*
|
|
|
12678
12883
|
}
|
|
12679
12884
|
const customHandler = proxy.$superdoc.config.onTrackedChangeBubbleAccept;
|
|
12680
12885
|
if (props.comment.trackedChange && isV2Mode.value) {
|
|
12886
|
+
const superdoc = proxy.$superdoc;
|
|
12887
|
+
const editor = superdoc.activeEditor;
|
|
12681
12888
|
const outcome = await commentsStore.decideTrackedChangeFromSidebar({
|
|
12682
|
-
superdoc
|
|
12889
|
+
superdoc,
|
|
12683
12890
|
comment: props.comment,
|
|
12684
12891
|
decision: "accept"
|
|
12685
12892
|
});
|
|
12893
|
+
if (!ownsTrackedChangeDecision(superdoc, editor)) return;
|
|
12686
12894
|
if (!outcome?.ok || outcome.success === false) {
|
|
12687
12895
|
reportTrackedChangeDecisionFailure("accept", outcome);
|
|
12688
12896
|
return;
|
|
12689
12897
|
}
|
|
12690
12898
|
clearTrackedChangeDecisionFailure();
|
|
12691
|
-
if (typeof customHandler === "function") customHandler(props.comment,
|
|
12692
|
-
|
|
12693
|
-
commentsStore.lastUpdate = /* @__PURE__ */ new Date();
|
|
12694
|
-
activeComment.value = null;
|
|
12695
|
-
commentsStore.setActiveComment(proxy.$superdoc, activeComment.value);
|
|
12696
|
-
proxy.$superdoc.focus?.({ preventScroll: true });
|
|
12697
|
-
});
|
|
12899
|
+
if (typeof customHandler === "function") customHandler(props.comment, editor);
|
|
12900
|
+
restoreTrackedChangeDecisionFocus(superdoc, editor);
|
|
12698
12901
|
return;
|
|
12699
12902
|
}
|
|
12700
12903
|
let v1TrackedChangeDecisionApplied = true;
|
|
@@ -12998,7 +13201,7 @@ var CommentDialog_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/*
|
|
|
12998
13201
|
"data-track-change-semantic-color-key": comment.semanticColorKey ?? void 0,
|
|
12999
13202
|
ref_for: true,
|
|
13000
13203
|
ref: index === 0 ? setParentBodyRef : void 0
|
|
13001
|
-
}, [comment.trackedChangeLabel ? (openBlock(), createElementBlock("div", _hoisted_13$
|
|
13204
|
+
}, [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
13205
|
return openBlock(), createElementBlock("div", {
|
|
13003
13206
|
key: lineIndex,
|
|
13004
13207
|
class: "tracked-change-detail-line"
|
|
@@ -13023,7 +13226,7 @@ var CommentDialog_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/*
|
|
|
13023
13226
|
style: normalizeStyle(trackedChangeImagePreviewStyle(comment.trackedChangeImagePreview)),
|
|
13024
13227
|
loading: "lazy",
|
|
13025
13228
|
decoding: "async"
|
|
13026
|
-
}, null, 12, _hoisted_38)], 8, _hoisted_37)) : createCommentVNode("", true)], 10, _hoisted_12$
|
|
13229
|
+
}, null, 12, _hoisted_38)], 8, _hoisted_37)) : createCommentVNode("", true)], 10, _hoisted_12$3),
|
|
13027
13230
|
shouldTruncate.value && isTextOverflowing.value && index === 0 ? (openBlock(), createElementBlock("div", {
|
|
13028
13231
|
key: 0,
|
|
13029
13232
|
class: "show-more-toggle",
|
|
@@ -13117,7 +13320,7 @@ var CommentDialog_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/*
|
|
|
13117
13320
|
], 64))], 14, _hoisted_1$26)), [[_directive_click_outside, handleClickOutside]]);
|
|
13118
13321
|
};
|
|
13119
13322
|
}
|
|
13120
|
-
}), [["__scopeId", "data-v-
|
|
13323
|
+
}), [["__scopeId", "data-v-04c17a1a"]]);
|
|
13121
13324
|
//#endregion
|
|
13122
13325
|
//#region src/components/CommentsLayer/commentsList/ReviewDirectoryListItem.vue?vue&type=script&setup=true&lang.ts
|
|
13123
13326
|
var _hoisted_1$25 = [
|
|
@@ -13445,21 +13648,25 @@ var commentsList_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/*
|
|
|
13445
13648
|
}
|
|
13446
13649
|
}), [["__scopeId", "data-v-8eca48e1"]]);
|
|
13447
13650
|
//#endregion
|
|
13448
|
-
//#region src/components/CommentsLayer/commentsList/super-comments-list.
|
|
13651
|
+
//#region src/components/CommentsLayer/commentsList/super-comments-list.ts
|
|
13652
|
+
var isReviewDirectoryStore = (value) => isPlainObject$1(value) && typeof value.setReviewDirectoryFromV2 === "function" && typeof value.clearReviewDirectory === "function";
|
|
13653
|
+
var readCommentsStore = (superdoc) => {
|
|
13654
|
+
const store = superdoc?.["commentsStore"];
|
|
13655
|
+
return isReviewDirectoryStore(store) ? store : void 0;
|
|
13656
|
+
};
|
|
13449
13657
|
/**
|
|
13450
13658
|
* Comments list renderer (not floating comments)
|
|
13451
13659
|
*
|
|
13452
13660
|
* This renders a list of comments into an element, connected to main SuperDoc instance
|
|
13453
13661
|
*/
|
|
13454
13662
|
var SuperComments = class extends import_eventemitter3.default {
|
|
13455
|
-
element;
|
|
13456
|
-
config = {
|
|
13457
|
-
comments: [],
|
|
13458
|
-
element: null,
|
|
13459
|
-
commentsStore: null
|
|
13460
|
-
};
|
|
13461
13663
|
constructor(options, superdoc) {
|
|
13462
13664
|
super();
|
|
13665
|
+
this.config = {
|
|
13666
|
+
comments: [],
|
|
13667
|
+
element: null,
|
|
13668
|
+
commentsStore: null
|
|
13669
|
+
};
|
|
13463
13670
|
this.config = {
|
|
13464
13671
|
...this.config,
|
|
13465
13672
|
...options
|
|
@@ -13480,7 +13687,7 @@ var SuperComments = class extends import_eventemitter3.default {
|
|
|
13480
13687
|
this.open();
|
|
13481
13688
|
}
|
|
13482
13689
|
syncDirectory() {
|
|
13483
|
-
const store = this.superdoc
|
|
13690
|
+
const store = readCommentsStore(this.superdoc);
|
|
13484
13691
|
if (!store) return;
|
|
13485
13692
|
const comments = this.directorySnapshots.comments;
|
|
13486
13693
|
const trackChanges = this.directorySnapshots.trackChanges;
|
|
@@ -13498,12 +13705,14 @@ var SuperComments = class extends import_eventemitter3.default {
|
|
|
13498
13705
|
const acceptDirectorySnapshot = (snapshot) => {
|
|
13499
13706
|
if (generation !== this.directoryGeneration) return;
|
|
13500
13707
|
if ((snapshot?.listStatus ?? snapshot?.status) !== "ready") {
|
|
13501
|
-
|
|
13708
|
+
const store = readCommentsStore(this.superdoc);
|
|
13709
|
+
if (store) store.isReviewDirectoryLoading = true;
|
|
13502
13710
|
return;
|
|
13503
13711
|
}
|
|
13504
13712
|
const items = Array.isArray(snapshot.items) ? snapshot.items : [];
|
|
13505
13713
|
if (this.directoryItemRefs[family] === items) {
|
|
13506
|
-
|
|
13714
|
+
const store = readCommentsStore(this.superdoc);
|
|
13715
|
+
if (store) store.isReviewDirectoryLoading = this.directorySnapshots.comments == null || this.directorySnapshots.trackChanges == null;
|
|
13507
13716
|
return;
|
|
13508
13717
|
}
|
|
13509
13718
|
this.directoryItemRefs[family] = items;
|
|
@@ -13520,15 +13729,16 @@ var SuperComments = class extends import_eventemitter3.default {
|
|
|
13520
13729
|
};
|
|
13521
13730
|
const ui = this.superdoc?.ui;
|
|
13522
13731
|
if (!ui) return;
|
|
13523
|
-
|
|
13524
|
-
|
|
13525
|
-
|
|
13732
|
+
const store = readCommentsStore(this.superdoc);
|
|
13733
|
+
if (store) {
|
|
13734
|
+
store.isReviewDirectoryActive = true;
|
|
13735
|
+
store.isReviewDirectoryLoading = true;
|
|
13526
13736
|
}
|
|
13527
13737
|
this.stopDirectoryObservers = [subscribe(ui.comments, "comments"), subscribe(ui.trackChanges, "trackChanges")];
|
|
13528
13738
|
}
|
|
13529
13739
|
createVueApp() {
|
|
13530
13740
|
this.app = createApp(commentsList_default);
|
|
13531
|
-
const parentProvides = this.superdoc?.app?._context?.provides;
|
|
13741
|
+
const parentProvides = this.superdoc?.["app"]?._context?.provides;
|
|
13532
13742
|
if (parentProvides && this.app?._context?.provides) Object.setPrototypeOf(this.app._context.provides, parentProvides);
|
|
13533
13743
|
if (this.superdoc?.pinia) {
|
|
13534
13744
|
setActivePinia(this.superdoc.pinia);
|
|
@@ -13552,10 +13762,11 @@ var SuperComments = class extends import_eventemitter3.default {
|
|
|
13552
13762
|
comments: null,
|
|
13553
13763
|
trackChanges: null
|
|
13554
13764
|
};
|
|
13555
|
-
|
|
13556
|
-
|
|
13557
|
-
|
|
13558
|
-
|
|
13765
|
+
const store = readCommentsStore(this.superdoc);
|
|
13766
|
+
if (store) {
|
|
13767
|
+
store.clearReviewDirectory();
|
|
13768
|
+
store.isReviewDirectoryActive = false;
|
|
13769
|
+
store.isReviewDirectoryLoading = false;
|
|
13559
13770
|
}
|
|
13560
13771
|
if (this.app) {
|
|
13561
13772
|
this.app.unmount();
|
|
@@ -13569,7 +13780,7 @@ var SuperComments = class extends import_eventemitter3.default {
|
|
|
13569
13780
|
}
|
|
13570
13781
|
};
|
|
13571
13782
|
//#endregion
|
|
13572
|
-
//#region src/composables/use-viewport-fit.
|
|
13783
|
+
//#region src/composables/use-viewport-fit.ts
|
|
13573
13784
|
var CSS_PX_PER_INCH = 96;
|
|
13574
13785
|
var SIDEBAR_SELECTOR = ".superdoc__right-sidebar";
|
|
13575
13786
|
var PDF_PAGE_SELECTOR = ".sd-pdf-viewer-page";
|
|
@@ -13674,7 +13885,7 @@ function useViewportFit({ getSuperdoc, superdocContainerWidth, isReady, activeZo
|
|
|
13674
13885
|
const root = superdocRoot.value;
|
|
13675
13886
|
if (!root?.querySelectorAll) return null;
|
|
13676
13887
|
let widest = 0;
|
|
13677
|
-
for (const page of root.querySelectorAll(PDF_PAGE_SELECTOR)) {
|
|
13888
|
+
for (const page of Array.from(root.querySelectorAll(PDF_PAGE_SELECTOR))) {
|
|
13678
13889
|
const measured = Number(page.clientWidth) || Number(page.getBoundingClientRect?.().width) || 0;
|
|
13679
13890
|
let scaleFactor = NaN;
|
|
13680
13891
|
if (typeof window !== "undefined" && typeof window.getComputedStyle === "function") scaleFactor = Number.parseFloat(window.getComputedStyle(page).getPropertyValue("--scale-factor"));
|
|
@@ -13876,124 +14087,6 @@ var composeAuthorColorResolver = (config) => {
|
|
|
13876
14087
|
};
|
|
13877
14088
|
};
|
|
13878
14089
|
//#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
14090
|
//#region src/core/superdoc-ui-owner.ts
|
|
13998
14091
|
var ownerIds = /* @__PURE__ */ new WeakMap();
|
|
13999
14092
|
function getSuperDocUiOwnerId(superdoc) {
|
|
@@ -14106,18 +14199,42 @@ var FloatingComments_default = /* @__PURE__ */ _plugin_vue_export_helper_default
|
|
|
14106
14199
|
const { activeComment, activeFloatingCommentInstanceId, editorCommentPositions, pendingComment, editingCommentId, instantSidebarAlignmentTargetY, instantSidebarAlignmentThreadId, instantSidebarAlignmentInstanceId } = storeToRefs(piniaCommentsStore);
|
|
14107
14200
|
const { activeZoom } = storeToRefs(superdocStore);
|
|
14108
14201
|
const committedPresentation = computed$1(() => commentsStore.committedReviewPresentations?.[String(props.currentDocument?.id)] ?? null);
|
|
14202
|
+
const committedInstanceCache = /* @__PURE__ */ new Map();
|
|
14203
|
+
let committedInstanceCacheOwner = "";
|
|
14204
|
+
const sameReviewInstance = (cached, next) => {
|
|
14205
|
+
const before = Object.entries(cached).filter(([key]) => key !== "comment" && key !== "rowVersion");
|
|
14206
|
+
const after = Object.entries(next);
|
|
14207
|
+
if (before.length !== after.length) return false;
|
|
14208
|
+
const previous = new Map(before);
|
|
14209
|
+
return after.every(([key, value]) => previous.has(key) && (key === "positionEntry" ? JSON.stringify(previous.get(key)) === JSON.stringify(value) : Object.is(previous.get(key), value)));
|
|
14210
|
+
};
|
|
14109
14211
|
const committedInstances = computed$1(() => {
|
|
14110
14212
|
const presentation = committedPresentation.value;
|
|
14111
14213
|
if (!presentation) return null;
|
|
14112
14214
|
const rows = new Map(commentsStore.commentsList.filter((row) => String(row.fileId) === String(props.currentDocument?.id)).map((row) => [String(row.commentId), row]));
|
|
14113
|
-
|
|
14215
|
+
const owner = `${presentation.epoch}\u0000${presentation.coordinate?.mountId ?? ""}`;
|
|
14216
|
+
if (owner !== committedInstanceCacheOwner) {
|
|
14217
|
+
committedInstanceCache.clear();
|
|
14218
|
+
committedInstanceCacheOwner = owner;
|
|
14219
|
+
}
|
|
14220
|
+
const live = /* @__PURE__ */ new Set();
|
|
14221
|
+
const instances = presentation.instances.flatMap((instance) => {
|
|
14114
14222
|
const comment = instance.rowId === "pending" ? pendingComment.value : rows.get(instance.rowId);
|
|
14115
|
-
|
|
14223
|
+
if (!comment) return [];
|
|
14224
|
+
const rowVersion = presentation.rowVersions[instance.rowId] ?? 0;
|
|
14225
|
+
live.add(instance.id);
|
|
14226
|
+
const cached = committedInstanceCache.get(instance.id);
|
|
14227
|
+
if (cached && cached.comment === comment && cached.rowVersion === rowVersion && sameReviewInstance(cached, instance)) return [cached];
|
|
14228
|
+
const merged = {
|
|
14116
14229
|
...instance,
|
|
14117
14230
|
comment,
|
|
14118
|
-
rowVersion
|
|
14119
|
-
}
|
|
14231
|
+
rowVersion
|
|
14232
|
+
};
|
|
14233
|
+
committedInstanceCache.set(instance.id, merged);
|
|
14234
|
+
return [merged];
|
|
14120
14235
|
});
|
|
14236
|
+
for (const id of committedInstanceCache.keys()) if (!live.has(id)) committedInstanceCache.delete(id);
|
|
14237
|
+
return instances;
|
|
14121
14238
|
});
|
|
14122
14239
|
const floatingCommentInstances = computed$1(() => {
|
|
14123
14240
|
if (committedInstances.value) return committedInstances.value.filter((instance) => instance.rowId !== "pending");
|
|
@@ -14533,6 +14650,18 @@ var FloatingComments_default = /* @__PURE__ */ _plugin_vue_export_helper_default
|
|
|
14533
14650
|
scheduleDeferredRemeasure(() => allPositions.value.map((pos) => pos.id));
|
|
14534
14651
|
});
|
|
14535
14652
|
};
|
|
14653
|
+
const resizeHandlers = /* @__PURE__ */ new Map();
|
|
14654
|
+
const resizeHandlerFor = (id) => {
|
|
14655
|
+
let handler = resizeHandlers.get(id);
|
|
14656
|
+
if (!handler) {
|
|
14657
|
+
handler = () => {
|
|
14658
|
+
const position = allPositions.value.find((candidate) => candidate.id === id);
|
|
14659
|
+
if (position) handleResize(position);
|
|
14660
|
+
};
|
|
14661
|
+
resizeHandlers.set(id, handler);
|
|
14662
|
+
}
|
|
14663
|
+
return handler;
|
|
14664
|
+
};
|
|
14536
14665
|
const setInstantLayoutTransitionsDisabled = (disabled) => {
|
|
14537
14666
|
if (!disabled && directDecisionContinuityTargetId.value != null) return;
|
|
14538
14667
|
disableInstantLayoutTransitions.value = disabled;
|
|
@@ -14937,6 +15066,7 @@ var FloatingComments_default = /* @__PURE__ */ _plugin_vue_export_helper_default
|
|
|
14937
15066
|
visibilityChanged = true;
|
|
14938
15067
|
}
|
|
14939
15068
|
if (visibilityChanged) visibleIds.value = newVisible;
|
|
15069
|
+
for (const id of resizeHandlers.keys()) if (!currentIds.has(id)) resizeHandlers.delete(id);
|
|
14940
15070
|
for (const id of prevPositionIds) if (!currentIds.has(id)) delete _heightsCache[id];
|
|
14941
15071
|
const setChanged = prevPositionIds.size !== currentIds.size || [...prevPositionIds].some((id) => !currentIds.has(id));
|
|
14942
15072
|
const orderChanged = renderedPositionOrder.length !== positionOrder.length || renderedPositionOrder.some((id, index) => id !== positionOrder[index]);
|
|
@@ -15029,12 +15159,13 @@ var FloatingComments_default = /* @__PURE__ */ _plugin_vue_export_helper_default
|
|
|
15029
15159
|
style: normalizeStyle({
|
|
15030
15160
|
top: (pos.isOffscreenReviewCard && !committedPresentation.value ? pos.top - sidebarOffsetY.value : pos.top) + "px",
|
|
15031
15161
|
height: pos.height + "px",
|
|
15032
|
-
transition: committedPresentation.value || disableInstantLayoutTransitions.value ? "none" : void 0
|
|
15162
|
+
transition: committedPresentation.value || disableInstantLayoutTransitions.value ? "none" : void 0,
|
|
15163
|
+
visibility: pos.instanceRef?.provisional ? "hidden" : void 0
|
|
15033
15164
|
})
|
|
15034
15165
|
}, [shouldRenderDialog(pos) ? (openBlock(), createBlock(CommentDialog_default, {
|
|
15035
15166
|
key: pos.id + commentsRenderKey.value,
|
|
15036
15167
|
onReady: handleDialog,
|
|
15037
|
-
onResize: (
|
|
15168
|
+
onResize: resizeHandlerFor(pos.id),
|
|
15038
15169
|
class: "floating-comment",
|
|
15039
15170
|
parent: __props.parent,
|
|
15040
15171
|
comment: pos.commentRef,
|
|
@@ -15054,7 +15185,7 @@ var FloatingComments_default = /* @__PURE__ */ _plugin_vue_export_helper_default
|
|
|
15054
15185
|
}), 128))], 4)], 36);
|
|
15055
15186
|
};
|
|
15056
15187
|
}
|
|
15057
|
-
}), [["__scopeId", "data-v-
|
|
15188
|
+
}), [["__scopeId", "data-v-1070f5a1"]]);
|
|
15058
15189
|
//#endregion
|
|
15059
15190
|
//#region src/components/CommentsLayer/PdfCommentsLayer.vue?vue&type=script&setup=true&lang.ts
|
|
15060
15191
|
var _hoisted_1$22 = {
|
|
@@ -15187,7 +15318,7 @@ var PdfCommentsLayer_default = /* @__PURE__ */ _plugin_vue_export_helper_default
|
|
|
15187
15318
|
}), 128))]);
|
|
15188
15319
|
};
|
|
15189
15320
|
}
|
|
15190
|
-
}), [["__scopeId", "data-v-
|
|
15321
|
+
}), [["__scopeId", "data-v-e3ae65fa"]]);
|
|
15191
15322
|
//#endregion
|
|
15192
15323
|
//#region src/components/Whiteboard/use-whiteboard.ts
|
|
15193
15324
|
var useWhiteboard = ({ proxy, layers, documents, modules }) => {
|
|
@@ -15481,7 +15612,7 @@ var WhiteboardPage_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/
|
|
|
15481
15612
|
}, null, 44, _hoisted_1$21);
|
|
15482
15613
|
};
|
|
15483
15614
|
}
|
|
15484
|
-
}), [["__scopeId", "data-v-
|
|
15615
|
+
}), [["__scopeId", "data-v-fdae8749"]]);
|
|
15485
15616
|
//#endregion
|
|
15486
15617
|
//#region src/components/Whiteboard/WhiteboardLayer.vue
|
|
15487
15618
|
var WhiteboardLayer_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
|
|
@@ -15552,16 +15683,11 @@ var WhiteboardLayer_default = /* @__PURE__ */ _plugin_vue_export_helper_default(
|
|
|
15552
15683
|
}), 128))], 4);
|
|
15553
15684
|
};
|
|
15554
15685
|
}
|
|
15555
|
-
}), [["__scopeId", "data-v-
|
|
15686
|
+
}), [["__scopeId", "data-v-800e1970"]]);
|
|
15556
15687
|
//#endregion
|
|
15557
|
-
//#region src/components/CommentsLayer/collect-removed-comment-ids.
|
|
15688
|
+
//#region src/components/CommentsLayer/collect-removed-comment-ids.ts
|
|
15558
15689
|
/**
|
|
15559
15690
|
* 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
15691
|
*/
|
|
15566
15692
|
var collectRemovedCommentIds = (comments, targetIds, isInScope = () => true) => {
|
|
15567
15693
|
const targets = new Set(targetIds.map(String));
|
|
@@ -15644,7 +15770,7 @@ function normalizeCommentsUiConfig(commentsConfig) {
|
|
|
15644
15770
|
return normalized;
|
|
15645
15771
|
}
|
|
15646
15772
|
//#endregion
|
|
15647
|
-
//#region src/composables/use-comment-small-screen.
|
|
15773
|
+
//#region src/composables/use-comment-small-screen.ts
|
|
15648
15774
|
var SUPERDOC_DOCUMENT_SELECTOR = ".superdoc__document";
|
|
15649
15775
|
var isValidCompactBreakpoint = (value) => {
|
|
15650
15776
|
return isFiniteNumber(value) && value >= 0;
|
|
@@ -15724,10 +15850,11 @@ function useCommentSmallScreen({ commentsModuleConfig, superdocRoot, layers }) {
|
|
|
15724
15850
|
}
|
|
15725
15851
|
documentWidthTargets = nextTargets;
|
|
15726
15852
|
if (!nextTargets.length) return;
|
|
15727
|
-
|
|
15853
|
+
const observer = new ResizeObserverClass(() => {
|
|
15728
15854
|
recalculateCompactCommentsMode();
|
|
15729
15855
|
});
|
|
15730
|
-
|
|
15856
|
+
documentWidthResizeObserver = observer;
|
|
15857
|
+
nextTargets.forEach((el) => observer.observe(el));
|
|
15731
15858
|
};
|
|
15732
15859
|
const getMeasuredDocumentWidth = () => {
|
|
15733
15860
|
ensureDocumentWidthObserver();
|
|
@@ -15783,7 +15910,22 @@ function useCommentSmallScreen({ commentsModuleConfig, superdocRoot, layers }) {
|
|
|
15783
15910
|
};
|
|
15784
15911
|
}
|
|
15785
15912
|
//#endregion
|
|
15786
|
-
//#region src/composables/use-
|
|
15913
|
+
//#region src/composables/use-comment-sidebar.ts
|
|
15914
|
+
function useCommentSidebar({ documentKey, enabled, hasContent }) {
|
|
15915
|
+
const reserved = ref(false);
|
|
15916
|
+
watch$1(documentKey, () => {
|
|
15917
|
+
reserved.value = false;
|
|
15918
|
+
}, { flush: "sync" });
|
|
15919
|
+
watch$1(() => enabled.value && hasContent.value, (visible) => {
|
|
15920
|
+
if (visible) reserved.value = true;
|
|
15921
|
+
}, {
|
|
15922
|
+
immediate: true,
|
|
15923
|
+
flush: "sync"
|
|
15924
|
+
});
|
|
15925
|
+
return computed$1(() => enabled.value && (hasContent.value || reserved.value));
|
|
15926
|
+
}
|
|
15927
|
+
//#endregion
|
|
15928
|
+
//#region src/composables/use-compact-comment-popover.ts
|
|
15787
15929
|
var POPOVER_WIDTH_PX = 320;
|
|
15788
15930
|
var SAFE_MARGIN_PX = 12;
|
|
15789
15931
|
var MIN_BOTTOM_SPACE_PX = 220;
|
|
@@ -15813,7 +15955,7 @@ var resolveInteractionAnchor = (lastClickAnchor) => {
|
|
|
15813
15955
|
var resolveInlineHighlightAnchorRect = ({ rootEl, comment, pendingComment }) => {
|
|
15814
15956
|
if (Boolean(pendingComment?.value && comment?.commentId === pendingComment.value?.commentId)) {
|
|
15815
15957
|
const nodes = rootEl.querySelectorAll(COMMENT_HIGHLIGHT_SELECTOR);
|
|
15816
|
-
for (const node of nodes) {
|
|
15958
|
+
for (const node of Array.from(nodes)) {
|
|
15817
15959
|
if (!parseCommentIds(node.getAttribute(COMMENT_HIGHLIGHT_DATA_ATTR)).includes("pending")) continue;
|
|
15818
15960
|
if (typeof node.getBoundingClientRect !== "function") continue;
|
|
15819
15961
|
return node.getBoundingClientRect();
|
|
@@ -15823,7 +15965,7 @@ var resolveInlineHighlightAnchorRect = ({ rootEl, comment, pendingComment }) =>
|
|
|
15823
15965
|
if (!anchorId) return null;
|
|
15824
15966
|
const safeId = String(anchorId);
|
|
15825
15967
|
const highlightNodes = rootEl.querySelectorAll(COMMENT_HIGHLIGHT_SELECTOR);
|
|
15826
|
-
for (const node of highlightNodes) {
|
|
15968
|
+
for (const node of Array.from(highlightNodes)) {
|
|
15827
15969
|
if (!parseCommentIds(node.getAttribute(COMMENT_HIGHLIGHT_DATA_ATTR)).includes(safeId)) continue;
|
|
15828
15970
|
if (typeof node.getBoundingClientRect !== "function") continue;
|
|
15829
15971
|
return node.getBoundingClientRect();
|
|
@@ -15908,9 +16050,10 @@ function useCompactCommentPopover({ activeComment, pendingComment, activeCompact
|
|
|
15908
16050
|
};
|
|
15909
16051
|
const trackCompactPopoverClickAnchor = (e) => {
|
|
15910
16052
|
const root = superdocRoot.value;
|
|
15911
|
-
|
|
15912
|
-
|
|
15913
|
-
|
|
16053
|
+
const target = e.target instanceof Node ? e.target : null;
|
|
16054
|
+
if (!root || !layers.value?.contains(target)) return;
|
|
16055
|
+
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);
|
|
16056
|
+
if (clearCompactPopoverIfPdfClickedOutside(root, target, anchorElement)) return;
|
|
15914
16057
|
if (e.button !== 0 || e.pointerType !== "mouse") return;
|
|
15915
16058
|
const anchorRect = anchorElement && typeof anchorElement.getBoundingClientRect === "function" ? anchorElement.getBoundingClientRect() : null;
|
|
15916
16059
|
if (!anchorRect) return;
|
|
@@ -16144,7 +16287,7 @@ function normalizeHyperlinksConfig(config = {}) {
|
|
|
16144
16287
|
};
|
|
16145
16288
|
}
|
|
16146
16289
|
//#endregion
|
|
16147
|
-
//#region src/helpers/v2-review-target.
|
|
16290
|
+
//#region src/helpers/v2-review-target.ts
|
|
16148
16291
|
/**
|
|
16149
16292
|
* Resolve the comments-store identity for a document-origin v2 review target.
|
|
16150
16293
|
* Painted review carriers can become interactive before the asynchronous row
|
|
@@ -16160,15 +16303,126 @@ function resolveV2ReviewTargetCommentId(target, getComment) {
|
|
|
16160
16303
|
return commentId != null ? String(commentId) : null;
|
|
16161
16304
|
}
|
|
16162
16305
|
//#endregion
|
|
16163
|
-
//#region src/helpers/v2-
|
|
16306
|
+
//#region src/helpers/v2-review-geometry-delivery.ts
|
|
16307
|
+
function createReviewGeometryDelivery(deliver) {
|
|
16308
|
+
const packets = /* @__PURE__ */ new Map();
|
|
16309
|
+
let stageOwners = /* @__PURE__ */ new WeakMap();
|
|
16310
|
+
let active = null;
|
|
16311
|
+
const documentOf = (current) => current.documentId != null ? String(current.documentId) : current.mountContainer?.dataset.superdocV2DocumentId ?? null;
|
|
16312
|
+
const matches = (documentId, current) => current.mountContainer?.dataset.superdocV2DocumentId === documentId && (current.documentId == null || String(current.documentId) === documentId);
|
|
16313
|
+
const matchesPaint = (packet, current) => typeof packet.payload.paintEpoch !== "number" || packet.payload.paintEpoch === current.epoch;
|
|
16314
|
+
const observe = (current) => {
|
|
16315
|
+
const stage = current.mountContainer;
|
|
16316
|
+
const documentId = documentOf(current);
|
|
16317
|
+
if (!stage || !documentId || !matches(documentId, current)) return;
|
|
16318
|
+
const previousOwner = stageOwners.get(stage);
|
|
16319
|
+
if (previousOwner && previousOwner !== documentId) packets.delete(previousOwner);
|
|
16320
|
+
stageOwners.set(stage, documentId);
|
|
16321
|
+
const packet = packets.get(documentId);
|
|
16322
|
+
if (packet?.stage && packet.stage !== stage) packets.delete(documentId);
|
|
16323
|
+
else if (packet && (!active || active.stage !== stage || active.documentId !== documentId || active.epoch !== current.epoch)) packet.delivered = false;
|
|
16324
|
+
active = {
|
|
16325
|
+
documentId,
|
|
16326
|
+
stage,
|
|
16327
|
+
epoch: current.epoch
|
|
16328
|
+
};
|
|
16329
|
+
};
|
|
16330
|
+
const dispatch = (documentId, packet, current, replay = false) => {
|
|
16331
|
+
if (!current.mountContainer || !matches(documentId, current) || !matchesPaint(packet, current)) return false;
|
|
16332
|
+
if (packet.stage && packet.stage !== current.mountContainer || packet.delivering || packet.delivered && !replay) return false;
|
|
16333
|
+
const wasDelivered = packet.delivered;
|
|
16334
|
+
const previousStage = packet.stage;
|
|
16335
|
+
packet.stage = current.mountContainer;
|
|
16336
|
+
packet.delivered = true;
|
|
16337
|
+
packet.delivering = true;
|
|
16338
|
+
try {
|
|
16339
|
+
deliver(current, packet.payload);
|
|
16340
|
+
} catch (error) {
|
|
16341
|
+
packet.delivered = wasDelivered;
|
|
16342
|
+
packet.stage = previousStage;
|
|
16343
|
+
throw error;
|
|
16344
|
+
} finally {
|
|
16345
|
+
packet.delivering = false;
|
|
16346
|
+
}
|
|
16347
|
+
return true;
|
|
16348
|
+
};
|
|
16349
|
+
const notify = (documentId, payload, current, ready = true) => {
|
|
16350
|
+
if (!payload.reviewGeometry || !Array.isArray(payload.pageIndices)) return false;
|
|
16351
|
+
let key;
|
|
16352
|
+
try {
|
|
16353
|
+
key = JSON.stringify([
|
|
16354
|
+
documentId,
|
|
16355
|
+
payload.documentEpoch,
|
|
16356
|
+
payload.paintEpoch,
|
|
16357
|
+
payload.commitSequence,
|
|
16358
|
+
payload.pageIndices,
|
|
16359
|
+
payload.zoomScale,
|
|
16360
|
+
payload.reviewGeometry
|
|
16361
|
+
]);
|
|
16362
|
+
} catch {
|
|
16363
|
+
return false;
|
|
16364
|
+
}
|
|
16365
|
+
const isCurrent = current != null && matches(documentId, current);
|
|
16366
|
+
if (isCurrent) observe(current);
|
|
16367
|
+
const previous = packets.get(documentId);
|
|
16368
|
+
if (previous && previous.payload.documentEpoch === payload.documentEpoch && typeof previous.payload.paintEpoch === "number" && typeof payload.paintEpoch === "number" && payload.paintEpoch < previous.payload.paintEpoch) return false;
|
|
16369
|
+
if (previous && previous.payload.documentEpoch === payload.documentEpoch && typeof previous.payload.commitSequence === "number" && typeof payload.commitSequence === "number" && payload.commitSequence < previous.payload.commitSequence) return false;
|
|
16370
|
+
if (previous && previous.payload.documentEpoch === payload.documentEpoch && typeof previous.payload.generation === "number" && typeof payload.generation === "number" && payload.generation < previous.payload.generation) return false;
|
|
16371
|
+
if (isCurrent && typeof payload.paintEpoch === "number" && typeof current.epoch === "number" && payload.paintEpoch < current.epoch) return false;
|
|
16372
|
+
if (previous?.key === key) {
|
|
16373
|
+
previous.payload = payload;
|
|
16374
|
+
return isCurrent && ready ? dispatch(documentId, previous, current) : false;
|
|
16375
|
+
}
|
|
16376
|
+
const packet = {
|
|
16377
|
+
payload,
|
|
16378
|
+
key,
|
|
16379
|
+
stage: isCurrent ? current.mountContainer : previous && previous.payload.documentEpoch === payload.documentEpoch ? previous.stage : null,
|
|
16380
|
+
delivered: false,
|
|
16381
|
+
delivering: false
|
|
16382
|
+
};
|
|
16383
|
+
packets.set(documentId, packet);
|
|
16384
|
+
if (!isCurrent || !ready) return false;
|
|
16385
|
+
try {
|
|
16386
|
+
return dispatch(documentId, packet, current);
|
|
16387
|
+
} catch (error) {
|
|
16388
|
+
if (previous) packets.set(documentId, previous);
|
|
16389
|
+
else packets.delete(documentId);
|
|
16390
|
+
throw error;
|
|
16391
|
+
}
|
|
16392
|
+
};
|
|
16393
|
+
return {
|
|
16394
|
+
notify,
|
|
16395
|
+
observe,
|
|
16396
|
+
flush(current) {
|
|
16397
|
+
observe(current);
|
|
16398
|
+
const documentId = documentOf(current);
|
|
16399
|
+
const packet = documentId == null ? null : packets.get(documentId);
|
|
16400
|
+
return documentId && packet ? dispatch(documentId, packet, current) : false;
|
|
16401
|
+
},
|
|
16402
|
+
replay(current) {
|
|
16403
|
+
observe(current);
|
|
16404
|
+
const documentId = documentOf(current);
|
|
16405
|
+
const packet = documentId == null ? null : packets.get(documentId);
|
|
16406
|
+
return documentId && packet ? dispatch(documentId, packet, current, true) : false;
|
|
16407
|
+
},
|
|
16408
|
+
reset() {
|
|
16409
|
+
packets.clear();
|
|
16410
|
+
stageOwners = /* @__PURE__ */ new WeakMap();
|
|
16411
|
+
active = null;
|
|
16412
|
+
}
|
|
16413
|
+
};
|
|
16414
|
+
}
|
|
16415
|
+
//#endregion
|
|
16416
|
+
//#region src/helpers/v2-mutation-exception.ts
|
|
16164
16417
|
var FAILURE_SOURCES = /* @__PURE__ */ new Set(["shell", "receipt"]);
|
|
16165
16418
|
var DIAGNOSTIC_CODE = /^[a-zA-Z][a-zA-Z0-9_-]{0,127}$/;
|
|
16166
16419
|
var COMMAND_KIND = /^[a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?$/;
|
|
16167
16420
|
function createV2MutationRejectionCause(event) {
|
|
16168
|
-
if (!event
|
|
16169
|
-
const
|
|
16421
|
+
if (!isPlainObject$1(event)) return {};
|
|
16422
|
+
const failure = isPlainObject$1(event.failure) ? event.failure : void 0;
|
|
16423
|
+
const reason = event.reason ?? (event.failureSource === "receipt" ? failure?.code : void 0);
|
|
16170
16424
|
return {
|
|
16171
|
-
...FAILURE_SOURCES.has(event.failureSource) ? { failureSource: event.failureSource } : {},
|
|
16425
|
+
...typeof event.failureSource === "string" && FAILURE_SOURCES.has(event.failureSource) ? { failureSource: event.failureSource } : {},
|
|
16172
16426
|
...typeof reason === "string" && DIAGNOSTIC_CODE.test(reason) ? { reason } : {},
|
|
16173
16427
|
...typeof event.inputKind === "string" && DIAGNOSTIC_CODE.test(event.inputKind) ? { inputKind: event.inputKind } : {},
|
|
16174
16428
|
...typeof event.editableCommandKind === "string" && event.editableCommandKind.length <= 128 && COMMAND_KIND.test(event.editableCommandKind) ? { editableCommandKind: event.editableCommandKind } : {}
|
|
@@ -16196,7 +16450,7 @@ function createV2MutationRejectionNotificationGate(matches) {
|
|
|
16196
16450
|
};
|
|
16197
16451
|
}
|
|
16198
16452
|
//#endregion
|
|
16199
|
-
//#region src/helpers/v2-author-required-rejection.
|
|
16453
|
+
//#region src/helpers/v2-author-required-rejection.ts
|
|
16200
16454
|
var NO_AUTHOR_SIGNAL = "no-author-configured";
|
|
16201
16455
|
/** Stable, non-terminal exception code surfaced to consumers. */
|
|
16202
16456
|
var V2_AUTHOR_REQUIRED_CODE = "author-required";
|
|
@@ -16208,15 +16462,11 @@ var V2_AUTHOR_REQUIRED_MESSAGE = "This edit needs an author identity. Set `user.
|
|
|
16208
16462
|
function messageHasNoAuthorSignal(message) {
|
|
16209
16463
|
return typeof message === "string" && message.includes(NO_AUTHOR_SIGNAL);
|
|
16210
16464
|
}
|
|
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
16465
|
function isV2AuthorRequiredRejection(event) {
|
|
16216
|
-
if (!event || event.type !== "mutation:rejected") return false;
|
|
16466
|
+
if (!isPlainObject$1(event) || event.type !== "mutation:rejected") return false;
|
|
16217
16467
|
if (event.failureSource === "receipt") {
|
|
16218
16468
|
const failure = event.failure;
|
|
16219
|
-
if (!failure) return false;
|
|
16469
|
+
if (!isPlainObject$1(failure)) return false;
|
|
16220
16470
|
return failure.code === "PRECONDITION_FAILED" && messageHasNoAuthorSignal(failure.message);
|
|
16221
16471
|
}
|
|
16222
16472
|
if (event.failureSource === "shell") {
|
|
@@ -16229,7 +16479,7 @@ function createV2AuthorRequiredNotificationGate() {
|
|
|
16229
16479
|
return createV2MutationRejectionNotificationGate(isV2AuthorRequiredRejection);
|
|
16230
16480
|
}
|
|
16231
16481
|
//#endregion
|
|
16232
|
-
//#region src/helpers/v2-bulk-decision-event.
|
|
16482
|
+
//#region src/helpers/v2-bulk-decision-event.ts
|
|
16233
16483
|
function toV2BulkDecisionEvent(documentId, fact) {
|
|
16234
16484
|
if (fact?.schemaVersion !== 1 || fact.decision !== "accept" && fact.decision !== "reject") return null;
|
|
16235
16485
|
return {
|
|
@@ -16241,7 +16491,7 @@ function toV2BulkDecisionEvent(documentId, fact) {
|
|
|
16241
16491
|
};
|
|
16242
16492
|
}
|
|
16243
16493
|
//#endregion
|
|
16244
|
-
//#region src/helpers/v2-keyboard-edit-rejection.
|
|
16494
|
+
//#region src/helpers/v2-keyboard-edit-rejection.ts
|
|
16245
16495
|
var EDIT_INPUT_KINDS = /* @__PURE__ */ new Set([
|
|
16246
16496
|
"keydown",
|
|
16247
16497
|
"beforeinput",
|
|
@@ -16291,7 +16541,7 @@ var EDIT_FAILURE_SOURCES = /* @__PURE__ */ new Set(["shell", "receipt"]);
|
|
|
16291
16541
|
var V2_EDIT_REJECTED_CODE = "edit-rejected";
|
|
16292
16542
|
var V2_EDIT_REJECTED_MESSAGE = "This edit couldn’t be completed. Adjust the selection and try again.";
|
|
16293
16543
|
function isV2KeyboardEditRejection(event) {
|
|
16294
|
-
return
|
|
16544
|
+
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
16545
|
}
|
|
16296
16546
|
function createV2KeyboardEditRejectionException(documentId, event) {
|
|
16297
16547
|
return {
|
|
@@ -16305,24 +16555,17 @@ function createV2KeyboardEditRejectionNotificationGate() {
|
|
|
16305
16555
|
return createV2MutationRejectionNotificationGate(isV2KeyboardEditRejection);
|
|
16306
16556
|
}
|
|
16307
16557
|
//#endregion
|
|
16308
|
-
//#region src/helpers/v2-selection-sync.
|
|
16558
|
+
//#region src/helpers/v2-selection-sync.ts
|
|
16309
16559
|
/**
|
|
16310
16560
|
* A logical v2 selection snapshot represents a non-empty range when its anchor
|
|
16311
16561
|
* and focus point at different block positions. Mirrors the range check the v2
|
|
16312
16562
|
* 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
16563
|
*/
|
|
16317
16564
|
var isV2RangeSnapshot = (snapshot) => Boolean(snapshot?.anchor && snapshot?.focus && (snapshot.anchor.blockId !== snapshot.focus.blockId || snapshot.anchor.blockOffset !== snapshot.focus.blockOffset));
|
|
16318
16565
|
/**
|
|
16319
16566
|
* Detect a real browser text selection whose endpoints are outside the active
|
|
16320
16567
|
* v2 mount. Editable host selections can have no native DOM range, so an
|
|
16321
16568
|
* 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
16569
|
*/
|
|
16327
16570
|
var hasOutsideV2DomRangeSelection = (selection, root) => {
|
|
16328
16571
|
if (!selection || selection.rangeCount < 1 || selection.isCollapsed || !root) return false;
|
|
@@ -16338,10 +16581,6 @@ var hasOutsideV2DomRangeSelection = (selection, root) => {
|
|
|
16338
16581
|
* host snapshot rather than clobber the selection the host just published.
|
|
16339
16582
|
* Only editable modes use the host snapshot. Viewing mode keeps native DOM
|
|
16340
16583
|
* 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
16584
|
*/
|
|
16346
16585
|
var shouldPreserveHostV2Selection = (documentMode, hostSnapshot) => {
|
|
16347
16586
|
if (documentMode !== "editing" && documentMode !== "suggesting") return false;
|
|
@@ -16352,10 +16591,6 @@ var shouldPreserveHostV2Selection = (documentMode, hostSnapshot) => {
|
|
|
16352
16591
|
* rebuilt. Keep an already-positioned comment affordance during that gap when
|
|
16353
16592
|
* the host still owns a range; otherwise the button unmounts and remounts on
|
|
16354
16593
|
* 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
16594
|
*/
|
|
16360
16595
|
var shouldRetainV2FloatingSelection = (hasHostRange, selectionPosition) => hasHostRange === true && selectionPosition?.source === "document-editor";
|
|
16361
16596
|
//#endregion
|
|
@@ -16547,7 +16782,7 @@ function usePasswordPrompt({ getSurfaceManager, getPasswordPromptConfig, onUnhan
|
|
|
16547
16782
|
})
|
|
16548
16783
|
});
|
|
16549
16784
|
} else {
|
|
16550
|
-
const mod = await import("./chunks/PasswordPromptSurface-
|
|
16785
|
+
const mod = await import("./chunks/PasswordPromptSurface-DjV1JgjD.es.js");
|
|
16551
16786
|
const surfaceId = `password-prompt-${doc.id}`;
|
|
16552
16787
|
handle = manager.open({
|
|
16553
16788
|
id: surfaceId,
|
|
@@ -16649,9 +16884,6 @@ function createReplaceContinuation(session, { getCurrentSession, applySlice, onS
|
|
|
16649
16884
|
}
|
|
16650
16885
|
//#endregion
|
|
16651
16886
|
//#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
16887
|
var DEFAULT_TEXTS = {
|
|
16656
16888
|
findPlaceholder: "Find",
|
|
16657
16889
|
findAriaLabel: "Find text",
|
|
@@ -16826,7 +17058,7 @@ function useFindReplace({ getSurfaceManager, getActiveEditor, activeEditorRef, g
|
|
|
16826
17058
|
try {
|
|
16827
17059
|
result = search.replace(replaceText.value);
|
|
16828
17060
|
} catch {}
|
|
16829
|
-
if (isThenable$
|
|
17061
|
+
if (isThenable$1(result)) Promise.resolve(result).then(finish, finish);
|
|
16830
17062
|
else finish();
|
|
16831
17063
|
}
|
|
16832
17064
|
function replaceAll() {
|
|
@@ -16848,7 +17080,7 @@ function useFindReplace({ getSurfaceManager, getActiveEditor, activeEditorRef, g
|
|
|
16848
17080
|
try {
|
|
16849
17081
|
result = search.replaceAll(replaceText.value);
|
|
16850
17082
|
} catch {}
|
|
16851
|
-
if (isThenable$
|
|
17083
|
+
if (isThenable$1(result)) Promise.resolve(result).then(finish, finish);
|
|
16852
17084
|
else finish();
|
|
16853
17085
|
}
|
|
16854
17086
|
function syncFromSearchSession() {
|
|
@@ -17210,7 +17442,7 @@ function useFindReplace({ getSurfaceManager, getActiveEditor, activeEditorRef, g
|
|
|
17210
17442
|
} else {
|
|
17211
17443
|
let FindReplaceSurface;
|
|
17212
17444
|
try {
|
|
17213
|
-
FindReplaceSurface = (await import("./chunks/FindReplaceSurface-
|
|
17445
|
+
FindReplaceSurface = (await import("./chunks/FindReplaceSurface-BEnRLpD9.es.js")).default;
|
|
17214
17446
|
} catch {
|
|
17215
17447
|
opening = false;
|
|
17216
17448
|
return;
|
|
@@ -17477,7 +17709,7 @@ var plus_solid_default = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0
|
|
|
17477
17709
|
//#region ../../shared/common/icons/trash-can-solid.svg?raw
|
|
17478
17710
|
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
17711
|
//#endregion
|
|
17480
|
-
//#region src/internal/toolbar/built-in/toolbarIcons.
|
|
17712
|
+
//#region src/internal/toolbar/built-in/toolbarIcons.ts
|
|
17481
17713
|
var toolbarIcons = {
|
|
17482
17714
|
undo: rotate_left_solid_default,
|
|
17483
17715
|
redo: rotate_right_solid_default,
|
|
@@ -17584,11 +17816,11 @@ var _hoisted_8$3 = { class: "input-row url-input-row" };
|
|
|
17584
17816
|
var _hoisted_9$2 = ["innerHTML"];
|
|
17585
17817
|
var _hoisted_10$2 = ["readonly", "onKeydown"];
|
|
17586
17818
|
var _hoisted_11$2 = ["innerHTML"];
|
|
17587
|
-
var _hoisted_12$
|
|
17819
|
+
var _hoisted_12$2 = {
|
|
17588
17820
|
key: 0,
|
|
17589
17821
|
class: "input-row link-buttons"
|
|
17590
17822
|
};
|
|
17591
|
-
var _hoisted_13$
|
|
17823
|
+
var _hoisted_13$2 = ["disabled"];
|
|
17592
17824
|
var _hoisted_14$1 = ["innerHTML"];
|
|
17593
17825
|
var _hoisted_15$1 = ["disabled"];
|
|
17594
17826
|
var _hoisted_16$1 = {
|
|
@@ -17847,7 +18079,7 @@ var LinkInput_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__
|
|
|
17847
18079
|
"data-item": "btn-link-open"
|
|
17848
18080
|
}, null, 10, _hoisted_11$2)
|
|
17849
18081
|
]),
|
|
17850
|
-
!isViewingMode.value ? (openBlock(), createElementBlock("div", _hoisted_12$
|
|
18082
|
+
!isViewingMode.value ? (openBlock(), createElementBlock("div", _hoisted_12$2, [isEditing.value ? (openBlock(), createElementBlock("button", {
|
|
17851
18083
|
key: 0,
|
|
17852
18084
|
class: "remove-btn",
|
|
17853
18085
|
onClick: handleRemove,
|
|
@@ -17856,7 +18088,7 @@ var LinkInput_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__
|
|
|
17856
18088
|
}, [createElementVNode("div", {
|
|
17857
18089
|
class: "remove-btn__icon",
|
|
17858
18090
|
innerHTML: unref(toolbarIcons).removeLink
|
|
17859
|
-
}, null, 8, _hoisted_14$1), _cache[6] || (_cache[6] = createTextVNode(" Remove ", -1))], 8, _hoisted_13$
|
|
18091
|
+
}, null, 8, _hoisted_14$1), _cache[6] || (_cache[6] = createTextVNode(" Remove ", -1))], 8, _hoisted_13$2)) : createCommentVNode("", true), createElementVNode("button", {
|
|
17860
18092
|
class: normalizeClass(["sd-submit-btn", { "disable-btn": isDisabled.value }]),
|
|
17861
18093
|
onClick: handleSubmit,
|
|
17862
18094
|
disabled: isSubmitting.value,
|
|
@@ -17870,7 +18102,7 @@ var LinkInput_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__
|
|
|
17870
18102
|
}
|
|
17871
18103
|
}), [["__scopeId", "data-v-172107e4"]]);
|
|
17872
18104
|
//#endregion
|
|
17873
|
-
//#region src/internal/toolbar/built-in/scroll-helpers.
|
|
18105
|
+
//#region src/internal/toolbar/built-in/scroll-helpers.ts
|
|
17874
18106
|
function getScrollableParent(element) {
|
|
17875
18107
|
let currentElement = element;
|
|
17876
18108
|
while (currentElement) {
|
|
@@ -17903,7 +18135,6 @@ function scrollToElement(targetElement, options = {
|
|
|
17903
18135
|
var FLOATING_SURFACE_ID = "link-popover";
|
|
17904
18136
|
var RECENT_OUTSIDE_CLOSE_MS = 500;
|
|
17905
18137
|
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
18138
|
function isLinkPopoverDocumentApi(value) {
|
|
17908
18139
|
return isPlainObject$1(value) || typeof value === "function";
|
|
17909
18140
|
}
|
|
@@ -18767,6 +18998,7 @@ function createV2EditorRuntimeAdapter(options) {
|
|
|
18767
18998
|
const { id, documentId, root, host, getLegacyEditorProjection, onUnregister } = options;
|
|
18768
18999
|
let snapshot = host.getSnapshot();
|
|
18769
19000
|
let didDispose = false;
|
|
19001
|
+
let detached = false;
|
|
18770
19002
|
let unregistered = false;
|
|
18771
19003
|
let mountedFocusHandle = null;
|
|
18772
19004
|
let tokenRevision = 0;
|
|
@@ -19063,7 +19295,17 @@ function createV2EditorRuntimeAdapter(options) {
|
|
|
19063
19295
|
};
|
|
19064
19296
|
}
|
|
19065
19297
|
}
|
|
19298
|
+
function releaseHostSubscriptions() {
|
|
19299
|
+
hostUnsubscribe?.();
|
|
19300
|
+
hostUnsubscribe = null;
|
|
19301
|
+
pageMetricsUnsubscribe?.();
|
|
19302
|
+
pageMetricsUnsubscribe = null;
|
|
19303
|
+
selectionUnsubscribe?.();
|
|
19304
|
+
selectionUnsubscribe = null;
|
|
19305
|
+
activeSelectionController = null;
|
|
19306
|
+
}
|
|
19066
19307
|
function handleHostSnapshot(next) {
|
|
19308
|
+
if (detached || didDispose) return;
|
|
19067
19309
|
snapshot = next;
|
|
19068
19310
|
invalidatePositionTokens();
|
|
19069
19311
|
syncSelectionSubscription();
|
|
@@ -19077,10 +19319,7 @@ function createV2EditorRuntimeAdapter(options) {
|
|
|
19077
19319
|
});
|
|
19078
19320
|
if (next.state === "disposed" && !didDispose) {
|
|
19079
19321
|
didDispose = true;
|
|
19080
|
-
|
|
19081
|
-
pageMetricsUnsubscribe?.();
|
|
19082
|
-
selectionUnsubscribe?.();
|
|
19083
|
-
selectionUnsubscribe = null;
|
|
19322
|
+
releaseHostSubscriptions();
|
|
19084
19323
|
emit({ type: "disposed" });
|
|
19085
19324
|
listeners.clear();
|
|
19086
19325
|
if (!unregistered) {
|
|
@@ -19227,10 +19466,7 @@ function createV2EditorRuntimeAdapter(options) {
|
|
|
19227
19466
|
await host.dispose();
|
|
19228
19467
|
if (!didDispose) {
|
|
19229
19468
|
didDispose = true;
|
|
19230
|
-
|
|
19231
|
-
pageMetricsUnsubscribe?.();
|
|
19232
|
-
selectionUnsubscribe?.();
|
|
19233
|
-
selectionUnsubscribe = null;
|
|
19469
|
+
releaseHostSubscriptions();
|
|
19234
19470
|
emit({ type: "disposed" });
|
|
19235
19471
|
listeners.clear();
|
|
19236
19472
|
if (!unregistered) {
|
|
@@ -19309,8 +19545,17 @@ function createV2EditorRuntimeAdapter(options) {
|
|
|
19309
19545
|
}
|
|
19310
19546
|
},
|
|
19311
19547
|
attachMountHandle(handle) {
|
|
19548
|
+
if (detached || didDispose) return;
|
|
19312
19549
|
mountedFocusHandle = handle;
|
|
19313
19550
|
syncSelectionSubscription();
|
|
19551
|
+
},
|
|
19552
|
+
detach() {
|
|
19553
|
+
if (detached) return;
|
|
19554
|
+
detached = true;
|
|
19555
|
+
unregistered = true;
|
|
19556
|
+
releaseHostSubscriptions();
|
|
19557
|
+
mountedFocusHandle = null;
|
|
19558
|
+
listeners.clear();
|
|
19314
19559
|
}
|
|
19315
19560
|
};
|
|
19316
19561
|
}
|
|
@@ -20473,7 +20718,7 @@ var SuperDoc_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
|
|
|
20473
20718
|
__name: "SuperDoc",
|
|
20474
20719
|
emits: ["selection-update"],
|
|
20475
20720
|
setup(__props, { emit: __emit }) {
|
|
20476
|
-
const PdfViewer = defineAsyncComponent(() => import("./chunks/PdfViewer-
|
|
20721
|
+
const PdfViewer = defineAsyncComponent(() => import("./chunks/PdfViewer-C2r-K8zC.es.js"));
|
|
20477
20722
|
const getDocumentLoadPassword = (doc) => doc.password ?? proxy.$superdoc.config.password;
|
|
20478
20723
|
const resolveDocumentV2Collaboration = (doc) => {
|
|
20479
20724
|
const rawConfig = doc?.v2Collaboration;
|
|
@@ -20558,7 +20803,7 @@ var SuperDoc_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
|
|
|
20558
20803
|
if (commentsConfig.highlightHoverColor) vars["--sd-comments-highlight-hover"] = commentsConfig.highlightHoverColor;
|
|
20559
20804
|
const activeTrackChangeColors = {
|
|
20560
20805
|
...commentsConfig.trackChangeHighlightColors || {},
|
|
20561
|
-
...commentsConfig.trackChangeActiveHighlightColors
|
|
20806
|
+
...commentsConfig.trackChangeActiveHighlightColors
|
|
20562
20807
|
};
|
|
20563
20808
|
if (activeTrackChangeColors.insertBorder) vars["--sd-tracked-changes-insert-border"] = activeTrackChangeColors.insertBorder;
|
|
20564
20809
|
if (activeTrackChangeColors.insertBackground) vars["--sd-tracked-changes-insert-background"] = activeTrackChangeColors.insertBackground;
|
|
@@ -20587,6 +20832,8 @@ var SuperDoc_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
|
|
|
20587
20832
|
const v2ReviewSidebarUnlocked = ref(false);
|
|
20588
20833
|
const v2GeometryEpoch = ref(null);
|
|
20589
20834
|
let v2GeometryRafHandle = 0;
|
|
20835
|
+
let v2GeometryReplayRafHandle = 0;
|
|
20836
|
+
let v2GeometryReplayGeneration = 0;
|
|
20590
20837
|
let v2TrackedChangeRestampRetainPaints = 0;
|
|
20591
20838
|
let v2TrackedChangeRestampRetentionReason = null;
|
|
20592
20839
|
const activeEditorRef = computed$1(() => proxy.$superdoc.activeEditor);
|
|
@@ -20770,6 +21017,7 @@ var SuperDoc_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
|
|
|
20770
21017
|
if (document && provider?.sendStateless) document.provider = null;
|
|
20771
21018
|
const entry = v2Runtimes.get(documentId);
|
|
20772
21019
|
if (!entry) return;
|
|
21020
|
+
entry.adapter.detach();
|
|
20773
21021
|
proxy.$superdoc["unregisterEditorRuntime"](entry.runtimeId);
|
|
20774
21022
|
v2Runtimes.delete(documentId);
|
|
20775
21023
|
const hostRoot = subDocumentRoots.get(documentId);
|
|
@@ -20923,7 +21171,7 @@ var SuperDoc_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
|
|
|
20923
21171
|
if (loadingDocument?.loadScope && !loadingDocument.loadScope.finish()) return;
|
|
20924
21172
|
clearV2EditorFailure(payload.documentId ?? null);
|
|
20925
21173
|
clearV2MutationRejectionNotifications(payload.documentId ?? null);
|
|
20926
|
-
const { host, firstPartyCommandMutation, mount, documentId, capabilities, editCommands, bindEditShortcuts, bindSessionShortcuts, commentsAdapter, trackedChangesAdapter, contextMenu, documentApi, documentMutationReadiness, documentApiUnavailableReason, pageMetrics, pageLayout, pageFurniture, presence, lock, connection, collaborationProvider, fonts, replaceFile, upgradeToCollaboration, documentOpenToken } = payload;
|
|
21174
|
+
const { host, firstPartyCommandMutation, mount, documentId, capabilities, editCommands, bindEditShortcuts, bindSessionShortcuts, commentsAdapter, trackedChangesAdapter, contextMenu, viewportQuery, documentApi, documentMutationReadiness, documentApiUnavailableReason, pageMetrics, pageLayout, pageFurniture, presence, lock, connection, collaborationProvider, fonts, replaceFile, upgradeToCollaboration, documentOpenToken } = payload;
|
|
20927
21175
|
documentOpenTelemetry?.trackDocumentOpen(documentOpenToken ?? null, documentId ?? null);
|
|
20928
21176
|
const saveV2Bytes = createV2SaveQueue(async (saveOptions = {}) => {
|
|
20929
21177
|
if (!host || typeof host.save !== "function") throw new Error("v2-editor: save unavailable");
|
|
@@ -21019,21 +21267,21 @@ var SuperDoc_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
|
|
|
21019
21267
|
};
|
|
21020
21268
|
};
|
|
21021
21269
|
const currentV2AuthoringMode = () => proxy.$superdoc.config.documentMode === "suggesting" ? "tracked" : "direct";
|
|
21022
|
-
const
|
|
21023
|
-
const
|
|
21024
|
-
if (typeof
|
|
21025
|
-
|
|
21026
|
-
|
|
21027
|
-
|
|
21028
|
-
return
|
|
21270
|
+
const confirmedV2SelectionTarget = async () => {
|
|
21271
|
+
const selectionTargets = host?.getHandles?.()?.editing?.selectionTargets;
|
|
21272
|
+
if (typeof selectionTargets?.confirmedSelectionTarget !== "function") return createV2AuthoringFailure("selection-confirmation-unavailable");
|
|
21273
|
+
try {
|
|
21274
|
+
const result = await selectionTargets.confirmedSelectionTarget();
|
|
21275
|
+
if (!result?.ok || !result.target) return createV2AuthoringFailure(result?.reason ?? "selection-unconfirmed");
|
|
21276
|
+
return {
|
|
21277
|
+
ok: true,
|
|
21278
|
+
target: result.target,
|
|
21279
|
+
mode: result.mode,
|
|
21280
|
+
story: result.story
|
|
21281
|
+
};
|
|
21282
|
+
} catch (error) {
|
|
21283
|
+
return createV2AuthoringFailure("selection-unconfirmed", error instanceof Error ? error.message : String(error));
|
|
21029
21284
|
}
|
|
21030
|
-
if (!result.target || typeof result.target !== "object") return createV2AuthoringFailure("selection-target-rejected", "selection target was not produced");
|
|
21031
|
-
return {
|
|
21032
|
-
ok: true,
|
|
21033
|
-
target: result.target,
|
|
21034
|
-
mode: result.mode ?? "range",
|
|
21035
|
-
story: result.story
|
|
21036
|
-
};
|
|
21037
21285
|
};
|
|
21038
21286
|
const failureFromV2Receipt = (receipt, fallbackReason) => {
|
|
21039
21287
|
const failure = receipt?.failure ?? receipt;
|
|
@@ -21107,7 +21355,7 @@ var SuperDoc_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
|
|
|
21107
21355
|
},
|
|
21108
21356
|
serializeSelectionToClipboard: async ({ includeHtml = true } = {}) => {
|
|
21109
21357
|
if (!documentApi?.clipboard || typeof documentApi.clipboard.serializeSelection !== "function") return createV2AuthoringFailure("clipboard-serialize-unavailable", "activeEditor.doc.clipboard.serializeSelection is not available");
|
|
21110
|
-
const selected =
|
|
21358
|
+
const selected = await confirmedV2SelectionTarget();
|
|
21111
21359
|
if (!selected.ok) return selected;
|
|
21112
21360
|
let serialized;
|
|
21113
21361
|
try {
|
|
@@ -21133,7 +21381,7 @@ var SuperDoc_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
|
|
|
21133
21381
|
let pasteTarget = target;
|
|
21134
21382
|
let selectionMode = null;
|
|
21135
21383
|
if (!pasteTarget) {
|
|
21136
|
-
const selected =
|
|
21384
|
+
const selected = await confirmedV2SelectionTarget();
|
|
21137
21385
|
if (!selected.ok) return selected;
|
|
21138
21386
|
pasteTarget = selected.target;
|
|
21139
21387
|
selectionMode = selected.mode;
|
|
@@ -21194,6 +21442,7 @@ var SuperDoc_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
|
|
|
21194
21442
|
v2Comments: commentsAdapter ?? null,
|
|
21195
21443
|
v2TrackedChanges: trackedChangesAdapter ?? null,
|
|
21196
21444
|
contextMenu: contextMenu ?? null,
|
|
21445
|
+
viewportQuery: viewportQuery ?? null,
|
|
21197
21446
|
pageMetrics: pageMetrics ?? null,
|
|
21198
21447
|
pageLayout: pageLayout ?? null,
|
|
21199
21448
|
pageFurniture: pageFurniture ?? null,
|
|
@@ -21276,7 +21525,7 @@ var SuperDoc_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
|
|
|
21276
21525
|
let v2SelectionToolbarRafHandle = 0;
|
|
21277
21526
|
let v2SelectionToolbarTimeoutHandle = 0;
|
|
21278
21527
|
let v2DomSelectionRafHandle = 0;
|
|
21279
|
-
const buildV2EditorUpdatePayload = ({ editor, sourceEditor, surface = "body", headerId = null, sectionType = null } = {}) => {
|
|
21528
|
+
const buildV2EditorUpdatePayload = ({ editor, sourceEditor, surface = "body", headerId = null, sectionType = null, isRemote = false } = {}) => {
|
|
21280
21529
|
const activeEditor = proxy.$superdoc?.activeEditor ?? null;
|
|
21281
21530
|
const effectiveEditor = editor ?? sourceEditor ?? activeEditor ?? void 0;
|
|
21282
21531
|
return {
|
|
@@ -21284,7 +21533,8 @@ var SuperDoc_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
|
|
|
21284
21533
|
sourceEditor: sourceEditor ?? effectiveEditor,
|
|
21285
21534
|
surface,
|
|
21286
21535
|
headerId,
|
|
21287
|
-
sectionType
|
|
21536
|
+
sectionType,
|
|
21537
|
+
isRemote
|
|
21288
21538
|
};
|
|
21289
21539
|
};
|
|
21290
21540
|
const emitV2EditorUpdate = (payload = {}) => {
|
|
@@ -21534,10 +21784,11 @@ var SuperDoc_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
|
|
|
21534
21784
|
const publishV2PendingPositionEntry = (entry) => {
|
|
21535
21785
|
if (!entry) return;
|
|
21536
21786
|
handleEditorLocationsUpdate({
|
|
21537
|
-
...editorCommentPositions.value
|
|
21787
|
+
...editorCommentPositions.value,
|
|
21538
21788
|
pending: entry
|
|
21539
21789
|
});
|
|
21540
21790
|
};
|
|
21791
|
+
let scheduleV2GeometryReplay = () => {};
|
|
21541
21792
|
const v2GeometryPublisher = resolvedEditorIntegration.createGeometryPublisher({
|
|
21542
21793
|
getLayersContainer: () => layers.value ?? null,
|
|
21543
21794
|
isCommentsEnabled: () => Boolean(commentsModuleConfig.value) && shouldRenderCommentsInViewing.value,
|
|
@@ -21553,7 +21804,8 @@ var SuperDoc_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
|
|
|
21553
21804
|
v2ReviewSidebarUnlocked.value = true;
|
|
21554
21805
|
v2GeometryEpoch.value = v2GeometryPublisher.getLastEpoch();
|
|
21555
21806
|
}
|
|
21556
|
-
}
|
|
21807
|
+
},
|
|
21808
|
+
onCommittedPagePaint: ({ payload }) => scheduleV2GeometryReplay(payload)
|
|
21557
21809
|
});
|
|
21558
21810
|
const armV2TrackedChangeRestampGeometryRetention = (reason = "tracked-change-restamp") => {
|
|
21559
21811
|
v2TrackedChangeRestampRetainPaints = Math.max(v2TrackedChangeRestampRetainPaints, 3);
|
|
@@ -21573,20 +21825,53 @@ var SuperDoc_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
|
|
|
21573
21825
|
v2TrackedChangeRestampRetentionReason = null;
|
|
21574
21826
|
};
|
|
21575
21827
|
const resolveV2GeometryPublishOptions = (options) => typeof options === "function" ? options() : options;
|
|
21828
|
+
const isV2GeometryReady = (current) => {
|
|
21829
|
+
if (!current?.mountContainer || !commentsModuleConfig.value || !shouldRenderCommentsInViewing.value) return false;
|
|
21830
|
+
const mount = current.mount;
|
|
21831
|
+
let liveEpoch;
|
|
21832
|
+
try {
|
|
21833
|
+
liveEpoch = mount?.getRenderEpoch?.();
|
|
21834
|
+
} catch {
|
|
21835
|
+
return false;
|
|
21836
|
+
}
|
|
21837
|
+
return v2GeometryPublisher.getLastPayload() === current && v2GeometryPublisher.getLastEpoch() != null && v2GeometryPublisher.getLastEpoch() === current.epoch && (liveEpoch == null || liveEpoch === current.epoch);
|
|
21838
|
+
};
|
|
21576
21839
|
const scheduleV2GeometryPublish = (payload, options = void 0) => {
|
|
21577
21840
|
v2GeometryRender.value = payload;
|
|
21578
21841
|
if (v2GeometryRafHandle && typeof cancelAnimationFrame === "function") cancelAnimationFrame(v2GeometryRafHandle);
|
|
21842
|
+
const publish = () => {
|
|
21843
|
+
const current = v2GeometryRender.value;
|
|
21844
|
+
Promise.resolve(v2GeometryPublisher.publish(current, resolveV2GeometryPublishOptions(options))).then(() => {
|
|
21845
|
+
if (current === v2GeometryRender.value && isV2GeometryReady(current)) v2ReviewGeometryDelivery.flush(current);
|
|
21846
|
+
});
|
|
21847
|
+
};
|
|
21579
21848
|
if (typeof requestAnimationFrame !== "function") {
|
|
21580
|
-
|
|
21849
|
+
publish();
|
|
21581
21850
|
return;
|
|
21582
21851
|
}
|
|
21583
21852
|
v2GeometryRafHandle = requestAnimationFrame(() => {
|
|
21584
21853
|
v2GeometryRafHandle = 0;
|
|
21585
|
-
|
|
21854
|
+
publish();
|
|
21586
21855
|
});
|
|
21587
21856
|
};
|
|
21857
|
+
const v2ReviewGeometryDelivery = createReviewGeometryDelivery((current, packet) => {
|
|
21858
|
+
v2GeometryPublisher.noteCommittedPageWindow?.(packet);
|
|
21859
|
+
scheduleV2GeometryPublish(current);
|
|
21860
|
+
});
|
|
21861
|
+
scheduleV2GeometryReplay = (payload) => {
|
|
21862
|
+
if (!payload || payload !== v2GeometryRender.value) return;
|
|
21863
|
+
const generation = ++v2GeometryReplayGeneration;
|
|
21864
|
+
if (v2GeometryReplayRafHandle && typeof cancelAnimationFrame === "function") cancelAnimationFrame(v2GeometryReplayRafHandle);
|
|
21865
|
+
const replay = () => {
|
|
21866
|
+
v2GeometryReplayRafHandle = 0;
|
|
21867
|
+
if (generation === v2GeometryReplayGeneration && payload === v2GeometryRender.value && isV2GeometryReady(payload)) v2ReviewGeometryDelivery.replay(payload);
|
|
21868
|
+
};
|
|
21869
|
+
if (typeof requestAnimationFrame === "function") v2GeometryReplayRafHandle = requestAnimationFrame(replay);
|
|
21870
|
+
else queueMicrotask(replay);
|
|
21871
|
+
};
|
|
21588
21872
|
const onV2Render = (payload) => {
|
|
21589
21873
|
if (!payload) return;
|
|
21874
|
+
v2ReviewGeometryDelivery.observe(payload);
|
|
21590
21875
|
scheduleV2GeometryPublish(payload, () => takeV2TrackedChangeRestampGeometryRetention());
|
|
21591
21876
|
if (v2HasRangeSelection.value) scheduleV2SelectionToolbarStateSync();
|
|
21592
21877
|
};
|
|
@@ -21619,7 +21904,11 @@ var SuperDoc_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
|
|
|
21619
21904
|
cancelScheduledV2SelectionToolbarSync();
|
|
21620
21905
|
if (v2GeometryRafHandle && typeof cancelAnimationFrame === "function") cancelAnimationFrame(v2GeometryRafHandle);
|
|
21621
21906
|
v2GeometryRafHandle = 0;
|
|
21907
|
+
if (v2GeometryReplayRafHandle && typeof cancelAnimationFrame === "function") cancelAnimationFrame(v2GeometryReplayRafHandle);
|
|
21908
|
+
v2GeometryReplayRafHandle = 0;
|
|
21909
|
+
v2GeometryReplayGeneration++;
|
|
21622
21910
|
v2GeometryRender.value = null;
|
|
21911
|
+
v2ReviewGeometryDelivery.reset();
|
|
21623
21912
|
v2GeometryEpoch.value = null;
|
|
21624
21913
|
v2GeometryAvailable.value = false;
|
|
21625
21914
|
v2ReviewSidebarUnlocked.value = false;
|
|
@@ -21678,6 +21967,7 @@ var SuperDoc_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
|
|
|
21678
21967
|
v2ReviewWindowController.invalidate("collaboration:remote-review-changed");
|
|
21679
21968
|
v2ReviewWindowController.refreshCommittedWindow("collaboration:remote-review-changed");
|
|
21680
21969
|
}
|
|
21970
|
+
emitV2EditorUpdate({ isRemote: true });
|
|
21681
21971
|
return;
|
|
21682
21972
|
}
|
|
21683
21973
|
if (event.type === "source:complete") {
|
|
@@ -21766,14 +22056,15 @@ var SuperDoc_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
|
|
|
21766
22056
|
if (!isV2Mode.value) return;
|
|
21767
22057
|
if (!v2GeometryPublisher.getLastPayload()) return;
|
|
21768
22058
|
if (v2GeometryRafHandle && typeof cancelAnimationFrame === "function") cancelAnimationFrame(v2GeometryRafHandle);
|
|
21769
|
-
|
|
21770
|
-
v2GeometryPublisher.recollect(resolveV2GeometryPublishOptions(options));
|
|
21771
|
-
return;
|
|
21772
|
-
}
|
|
21773
|
-
v2GeometryRafHandle = requestAnimationFrame(() => {
|
|
22059
|
+
const recollect = () => {
|
|
21774
22060
|
v2GeometryRafHandle = 0;
|
|
21775
|
-
|
|
21776
|
-
|
|
22061
|
+
const current = v2GeometryRender.value;
|
|
22062
|
+
Promise.resolve(v2GeometryPublisher.recollect(resolveV2GeometryPublishOptions(options))).then(() => {
|
|
22063
|
+
if (current === v2GeometryRender.value && isV2GeometryReady(current)) v2ReviewGeometryDelivery.replay(current);
|
|
22064
|
+
});
|
|
22065
|
+
};
|
|
22066
|
+
if (typeof requestAnimationFrame !== "function") recollect();
|
|
22067
|
+
else v2GeometryRafHandle = requestAnimationFrame(recollect);
|
|
21777
22068
|
};
|
|
21778
22069
|
const handleV2DocumentModeChange = () => {
|
|
21779
22070
|
if (!isV2Mode.value) return;
|
|
@@ -22001,13 +22292,17 @@ var SuperDoc_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
|
|
|
22001
22292
|
...payload,
|
|
22002
22293
|
documentId: doc.id
|
|
22003
22294
|
});
|
|
22004
|
-
|
|
22295
|
+
if (payload.reviewGeometry && Array.isArray(payload.pageIndices)) {
|
|
22296
|
+
const current = v2GeometryRender.value;
|
|
22297
|
+
v2ReviewGeometryDelivery.notify(String(doc.id), payload, current, isV2GeometryReady(current));
|
|
22298
|
+
} else v2GeometryPublisher.noteCommittedPageWindow?.(payload);
|
|
22005
22299
|
},
|
|
22006
22300
|
fontAssets: proxy.$superdoc.config.fonts,
|
|
22007
22301
|
workerUrls: proxy.$superdoc.config.workerUrls,
|
|
22008
22302
|
fieldContext: doc.fieldContext,
|
|
22009
22303
|
fieldUpdatePolicy: proxy.$superdoc.config.fieldUpdatePolicy,
|
|
22010
22304
|
workerStartupTimeoutMs: proxy.$superdoc.config.workerStartupTimeoutMs,
|
|
22305
|
+
...proxy.$superdoc.config.changes ? { changes: proxy.$superdoc.config.changes } : {},
|
|
22011
22306
|
proofing: resolvedProofingConfig.value,
|
|
22012
22307
|
isNewFile,
|
|
22013
22308
|
password: getDocumentLoadPassword(doc),
|
|
@@ -22028,7 +22323,7 @@ var SuperDoc_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
|
|
|
22028
22323
|
documentLoading: proxy.$superdoc.uiConfig.loading.enabled,
|
|
22029
22324
|
linkPopoverResolver: getHyperlinkActivationHandler(),
|
|
22030
22325
|
layoutEngineOptions: useLayoutEngine ? {
|
|
22031
|
-
...proxy.$superdoc.config.layoutEngineOptions
|
|
22326
|
+
...proxy.$superdoc.config.layoutEngineOptions,
|
|
22032
22327
|
proofing: resolvedProofingConfig.value,
|
|
22033
22328
|
debugLabel: proxy.$superdoc.config.layoutEngineOptions?.debugLabel ?? doc.name ?? doc.id,
|
|
22034
22329
|
zoom: (activeZoom.value ?? 100) / 100,
|
|
@@ -22291,11 +22586,16 @@ var SuperDoc_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
|
|
|
22291
22586
|
if (layout !== "auto") return true;
|
|
22292
22587
|
return !isCompactCommentsMode.value;
|
|
22293
22588
|
});
|
|
22294
|
-
const
|
|
22589
|
+
const sidebarEnabled = computed$1(() => {
|
|
22295
22590
|
if (isV2Mode.value && !v2GeometryAvailable.value && !v2ReviewSidebarUnlocked.value && !hasPdfFloatingComments.value) return false;
|
|
22296
22591
|
if (!shouldRenderCommentsInViewing.value) return false;
|
|
22297
22592
|
if (!shouldUseSidebarComments.value) return false;
|
|
22298
|
-
return pendingComment.value ||
|
|
22593
|
+
return Boolean(pendingComment.value || isReady.value && layers.value && isCommentsEnabled.value && !isCommentsListVisible.value);
|
|
22594
|
+
});
|
|
22595
|
+
const showCommentsSidebar = useCommentSidebar({
|
|
22596
|
+
documentKey: computed$1(() => JSON.stringify(documents.value.map((document) => document.id))),
|
|
22597
|
+
enabled: sidebarEnabled,
|
|
22598
|
+
hasContent: computed$1(() => Boolean(pendingComment.value || floatingComments.value.length || hasOpenTrackedChanges.value))
|
|
22299
22599
|
});
|
|
22300
22600
|
const activeCompactComment = computed$1(() => {
|
|
22301
22601
|
if (showCommentsSidebar.value) return null;
|
|
@@ -22919,7 +23219,7 @@ var SuperDoc_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
|
|
|
22919
23219
|
ref_key: "superdocRoot",
|
|
22920
23220
|
ref: superdocRoot,
|
|
22921
23221
|
class: normalizeClass(["superdoc", {
|
|
22922
|
-
"superdoc--with-sidebar": showCommentsSidebar
|
|
23222
|
+
"superdoc--with-sidebar": unref(showCommentsSidebar),
|
|
22923
23223
|
"superdoc--web-layout": unref(proxy).$superdoc.config.viewOptions?.layout === "web",
|
|
22924
23224
|
"superdoc--contained": unref(proxy).$superdoc.config.contained,
|
|
22925
23225
|
"high-contrast": unref(isHighContrastMode)
|
|
@@ -23067,7 +23367,7 @@ var SuperDoc_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
|
|
|
23067
23367
|
onAnchorActivate: handleHighlightClick
|
|
23068
23368
|
})) : createCommentVNode("", true)
|
|
23069
23369
|
])], 512),
|
|
23070
|
-
showCommentsSidebar
|
|
23370
|
+
unref(showCommentsSidebar) ? (openBlock(), createElementBlock("div", {
|
|
23071
23371
|
key: 0,
|
|
23072
23372
|
ref_key: "rightSidebarRef",
|
|
23073
23373
|
ref: rightSidebarRef,
|
|
@@ -23090,7 +23390,7 @@ var SuperDoc_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
|
|
|
23090
23390
|
], 46, _hoisted_1$17);
|
|
23091
23391
|
};
|
|
23092
23392
|
}
|
|
23093
|
-
}), [["__scopeId", "data-v-
|
|
23393
|
+
}), [["__scopeId", "data-v-b5da778c"]]);
|
|
23094
23394
|
//#endregion
|
|
23095
23395
|
//#region src/core/create-app.ts
|
|
23096
23396
|
var PINIA_DEVTOOLS_SETUP_EVENT = "devtools-plugin:setup";
|
|
@@ -24571,6 +24871,16 @@ var SurfaceManager = class {
|
|
|
24571
24871
|
};
|
|
24572
24872
|
//#endregion
|
|
24573
24873
|
//#region src/helpers/deprecation.ts
|
|
24874
|
+
/**
|
|
24875
|
+
* Deprecation utilities for steering consumers toward the Document API.
|
|
24876
|
+
*
|
|
24877
|
+
* ProseMirror will be removed in a future major version. These helpers emit
|
|
24878
|
+
* one-time console warnings when deprecated properties are accessed on an
|
|
24879
|
+
* editor instance handed to consumer callbacks (onEditorCreate, etc.).
|
|
24880
|
+
*
|
|
24881
|
+
* Internal code continues to use the raw Editor — only the consumer-facing
|
|
24882
|
+
* boundary wraps the editor with a Proxy.
|
|
24883
|
+
*/
|
|
24574
24884
|
var MIGRATION_URL = "https://docs.superdoc.dev/guides/migration/document-api";
|
|
24575
24885
|
var _warned = /* @__PURE__ */ new Set();
|
|
24576
24886
|
/**
|
|
@@ -24759,7 +25069,8 @@ function normalizeSuperDocUser(user) {
|
|
|
24759
25069
|
if (!user || typeof user !== "object") return { ...DEFAULT_SUPERDOC_USER };
|
|
24760
25070
|
return {
|
|
24761
25071
|
...DEFAULT_SUPERDOC_USER,
|
|
24762
|
-
...user
|
|
25072
|
+
...user,
|
|
25073
|
+
...user.commentIdentity !== void 0 ? { commentIdentity: normalizeCommentIdentity(user.commentIdentity) } : {}
|
|
24763
25074
|
};
|
|
24764
25075
|
}
|
|
24765
25076
|
//#endregion
|
|
@@ -25278,6 +25589,7 @@ function normalizeUiConfig(config = {}) {
|
|
|
25278
25589
|
* Keeping policy separate means an application can disable the built-in
|
|
25279
25590
|
* comments UI without losing the rules enforced by its custom UI.
|
|
25280
25591
|
*/
|
|
25592
|
+
var isAutocapitalize = (value) => value === "off" || value === "sentences" || value === "words" || value === "characters";
|
|
25281
25593
|
var isCommentInteractionLevel = (value) => value === "read" || value === "write" || value === "resolve";
|
|
25282
25594
|
/**
|
|
25283
25595
|
* Resolve the effective interaction policy.
|
|
@@ -25297,14 +25609,26 @@ function normalizeInteractionConfig(config = {}) {
|
|
|
25297
25609
|
const canonicalLevel = interactionComments.level;
|
|
25298
25610
|
const hasCanonicalLevel = isCommentInteractionLevel(canonicalLevel);
|
|
25299
25611
|
const level = hasCanonicalLevel ? canonicalLevel : legacyReadOnly ? "read" : legacyAllowResolve ? "resolve" : "write";
|
|
25612
|
+
const interactionWritingAssistance = isPlainObject$1(interaction.writingAssistance) ? interaction.writingAssistance : {};
|
|
25613
|
+
const autocorrect = interactionWritingAssistance.autocorrect === true;
|
|
25614
|
+
const autocapitalize = isAutocapitalize(interactionWritingAssistance.autocapitalize) ? interactionWritingAssistance.autocapitalize : "off";
|
|
25615
|
+
const spellcheck = interactionWritingAssistance.spellcheck === true;
|
|
25300
25616
|
const canonicalAllowDecisions = interactionTrackedChanges.allowDecisions;
|
|
25617
|
+
const interactionTouch = isPlainObject$1(interaction.touch) ? interaction.touch : {};
|
|
25301
25618
|
return {
|
|
25302
25619
|
comments: {
|
|
25303
25620
|
level,
|
|
25304
25621
|
readOnly: hasCanonicalLevel ? level === "read" : legacyReadOnly,
|
|
25305
25622
|
allowResolve: hasCanonicalLevel ? level === "resolve" : legacyAllowResolve
|
|
25306
25623
|
},
|
|
25307
|
-
trackedChanges: { allowDecisions: typeof canonicalAllowDecisions === "boolean" ? canonicalAllowDecisions : !legacyReadOnly }
|
|
25624
|
+
trackedChanges: { allowDecisions: typeof canonicalAllowDecisions === "boolean" ? canonicalAllowDecisions : !legacyReadOnly },
|
|
25625
|
+
touch: { gestures: interactionTouch.gestures === true },
|
|
25626
|
+
writingAssistance: {
|
|
25627
|
+
enabled: autocorrect || autocapitalize !== "off" || spellcheck,
|
|
25628
|
+
autocorrect,
|
|
25629
|
+
autocapitalize,
|
|
25630
|
+
spellcheck
|
|
25631
|
+
}
|
|
25308
25632
|
};
|
|
25309
25633
|
}
|
|
25310
25634
|
//#endregion
|
|
@@ -25873,23 +26197,21 @@ function resolveBuiltInItemCommandId(name) {
|
|
|
25873
26197
|
return resolveToolbarCommandId(name) ?? UNCATALOGED_ITEM_COMMAND_IDS[name] ?? null;
|
|
25874
26198
|
}
|
|
25875
26199
|
//#endregion
|
|
25876
|
-
//#region src/internal/toolbar/built-in/helpers.
|
|
26200
|
+
//#region src/internal/toolbar/built-in/helpers.ts
|
|
25877
26201
|
var sanitizeNumber = (value, defaultNumber) => {
|
|
25878
|
-
|
|
25879
|
-
|
|
25880
|
-
|
|
25881
|
-
|
|
25882
|
-
|
|
25883
|
-
|
|
25884
|
-
|
|
25885
|
-
let timeout, args, result;
|
|
26202
|
+
const parsed = parseFloat(String(value ?? "").replace(/[^0-9.]/g, ""));
|
|
26203
|
+
return isNaN(parsed) ? defaultNumber : parsed;
|
|
26204
|
+
};
|
|
26205
|
+
var throttle = (func, wait, options = {}) => {
|
|
26206
|
+
let timeout;
|
|
26207
|
+
let args;
|
|
26208
|
+
let result;
|
|
25886
26209
|
let previous = 0;
|
|
25887
|
-
if (!options) options = {};
|
|
25888
26210
|
const later = () => {
|
|
25889
26211
|
previous = options.leading === false ? 0 : Date.now();
|
|
25890
|
-
timeout =
|
|
25891
|
-
result = func(...args);
|
|
25892
|
-
if (!timeout) args =
|
|
26212
|
+
timeout = void 0;
|
|
26213
|
+
if (args) result = func(...args);
|
|
26214
|
+
if (!timeout) args = void 0;
|
|
25893
26215
|
};
|
|
25894
26216
|
const throttled = (...callArgs) => {
|
|
25895
26217
|
const _now = Date.now();
|
|
@@ -25899,18 +26221,18 @@ var throttle = (func, wait, options) => {
|
|
|
25899
26221
|
if (remaining <= 0 || remaining > wait) {
|
|
25900
26222
|
if (timeout) {
|
|
25901
26223
|
clearTimeout(timeout);
|
|
25902
|
-
timeout =
|
|
26224
|
+
timeout = void 0;
|
|
25903
26225
|
}
|
|
25904
26226
|
previous = _now;
|
|
25905
26227
|
result = func(...callArgs);
|
|
25906
|
-
if (!timeout) args =
|
|
26228
|
+
if (!timeout) args = void 0;
|
|
25907
26229
|
} else if (!timeout && options.trailing !== false) timeout = setTimeout(later, remaining);
|
|
25908
26230
|
return result;
|
|
25909
26231
|
};
|
|
25910
26232
|
throttled.cancel = function() {
|
|
25911
26233
|
clearTimeout(timeout);
|
|
25912
26234
|
previous = 0;
|
|
25913
|
-
timeout = args =
|
|
26235
|
+
timeout = args = void 0;
|
|
25914
26236
|
};
|
|
25915
26237
|
return throttled;
|
|
25916
26238
|
};
|
|
@@ -25962,26 +26284,39 @@ var ToolbarButtonIcon_default = /* @__PURE__ */ _plugin_vue_export_helper_defaul
|
|
|
25962
26284
|
var _hoisted_1$15 = [
|
|
25963
26285
|
"role",
|
|
25964
26286
|
"aria-label",
|
|
25965
|
-
"aria-disabled"
|
|
26287
|
+
"aria-disabled",
|
|
26288
|
+
"aria-busy"
|
|
25966
26289
|
];
|
|
25967
26290
|
var _hoisted_2$11 = ["data-item"];
|
|
25968
26291
|
var _hoisted_3$10 = ["data-item"];
|
|
25969
26292
|
var _hoisted_4$8 = {
|
|
25970
|
-
key:
|
|
26293
|
+
key: 0,
|
|
26294
|
+
role: "status",
|
|
26295
|
+
"aria-label": "Applying list",
|
|
26296
|
+
style: { "font-weight": "700" }
|
|
26297
|
+
};
|
|
26298
|
+
var _hoisted_5$6 = {
|
|
26299
|
+
key: 2,
|
|
25971
26300
|
class: "sd-button-label"
|
|
25972
26301
|
};
|
|
25973
|
-
var
|
|
25974
|
-
var
|
|
25975
|
-
var
|
|
25976
|
-
|
|
25977
|
-
|
|
26302
|
+
var _hoisted_6$4 = ["data-item", "aria-label"];
|
|
26303
|
+
var _hoisted_7$2 = ["innerHTML"];
|
|
26304
|
+
var _hoisted_8$2 = {
|
|
26305
|
+
key: 0,
|
|
26306
|
+
role: "status",
|
|
26307
|
+
"aria-label": "Applying list",
|
|
26308
|
+
style: { "font-weight": "700" }
|
|
26309
|
+
};
|
|
26310
|
+
var _hoisted_9$1 = { key: 3 };
|
|
26311
|
+
var _hoisted_10$1 = ["onKeydown", "id"];
|
|
26312
|
+
var _hoisted_11$1 = [
|
|
25978
26313
|
"placeholder",
|
|
25979
26314
|
"onKeydown",
|
|
25980
26315
|
"id",
|
|
25981
26316
|
"data-item"
|
|
25982
26317
|
];
|
|
25983
|
-
var
|
|
25984
|
-
var
|
|
26318
|
+
var _hoisted_12$1 = ["data-item", "innerHTML"];
|
|
26319
|
+
var _hoisted_13$1 = {
|
|
25985
26320
|
"aria-live": "polite",
|
|
25986
26321
|
class: "sd-visually-hidden"
|
|
25987
26322
|
};
|
|
@@ -26154,6 +26489,7 @@ var ToolbarButton_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/*
|
|
|
26154
26489
|
role: __props.isOverflowItem ? "menuitem" : "button",
|
|
26155
26490
|
"aria-label": unref(attributes).ariaLabel,
|
|
26156
26491
|
"aria-disabled": unref(disabled) ? "true" : void 0,
|
|
26492
|
+
"aria-busy": unref(attributes).ariaBusy || void 0,
|
|
26157
26493
|
"data-sd-part": "toolbar-item",
|
|
26158
26494
|
onClick: handleOuterClick,
|
|
26159
26495
|
onKeydown: _cache[9] || (_cache[9] = withKeys(($event) => onEnterKeydown($event), ["enter"])),
|
|
@@ -26175,17 +26511,21 @@ var ToolbarButton_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/*
|
|
|
26175
26511
|
class: "sd-toolbar-button__main",
|
|
26176
26512
|
"data-item": `btn-${unref(name) || ""}-main`,
|
|
26177
26513
|
onClick: _cache[0] || (_cache[0] = ($event) => handleSplitMainClick($event))
|
|
26178
|
-
}, [
|
|
26179
|
-
|
|
26180
|
-
|
|
26181
|
-
|
|
26182
|
-
|
|
26183
|
-
|
|
26184
|
-
|
|
26185
|
-
|
|
26186
|
-
|
|
26187
|
-
|
|
26188
|
-
|
|
26514
|
+
}, [
|
|
26515
|
+
unref(attributes).ariaBusy && isSplit.value ? (openBlock(), createElementBlock("span", _hoisted_4$8, "…")) : createCommentVNode("", true),
|
|
26516
|
+
unref(icon) ? (openBlock(), createBlock(ToolbarButtonIcon_default, {
|
|
26517
|
+
key: 1,
|
|
26518
|
+
color: unref(iconColor),
|
|
26519
|
+
class: "sd-toolbar-icon",
|
|
26520
|
+
icon: unref(icon),
|
|
26521
|
+
name: unref(name)
|
|
26522
|
+
}, null, 8, [
|
|
26523
|
+
"color",
|
|
26524
|
+
"icon",
|
|
26525
|
+
"name"
|
|
26526
|
+
])) : createCommentVNode("", true),
|
|
26527
|
+
unref(label) && !unref(hideLabel) && !unref(inlineTextInputVisible) ? (openBlock(), createElementBlock("div", _hoisted_5$6, toDisplayString(unref(label)), 1)) : createCommentVNode("", true)
|
|
26528
|
+
], 8, _hoisted_3$10)) : createCommentVNode("", true),
|
|
26189
26529
|
isSplit.value ? (openBlock(), createElementBlock("div", {
|
|
26190
26530
|
key: 1,
|
|
26191
26531
|
class: "sd-toolbar-button__caret",
|
|
@@ -26196,9 +26536,10 @@ var ToolbarButton_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/*
|
|
|
26196
26536
|
class: "sd-dropdown-caret",
|
|
26197
26537
|
innerHTML: caretIcon.value,
|
|
26198
26538
|
style: normalizeStyle({ opacity: unref(disabled) ? .6 : 1 })
|
|
26199
|
-
}, null, 12,
|
|
26539
|
+
}, null, 12, _hoisted_7$2)], 8, _hoisted_6$4)) : (openBlock(), createElementBlock(Fragment, { key: 2 }, [
|
|
26540
|
+
unref(attributes).ariaBusy ? (openBlock(), createElementBlock("span", _hoisted_8$2, "…")) : createCommentVNode("", true),
|
|
26200
26541
|
unref(icon) ? (openBlock(), createBlock(ToolbarButtonIcon_default, {
|
|
26201
|
-
key:
|
|
26542
|
+
key: 1,
|
|
26202
26543
|
color: unref(iconColor),
|
|
26203
26544
|
class: "sd-toolbar-icon",
|
|
26204
26545
|
icon: unref(icon),
|
|
@@ -26209,10 +26550,10 @@ var ToolbarButton_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/*
|
|
|
26209
26550
|
"name"
|
|
26210
26551
|
])) : createCommentVNode("", true),
|
|
26211
26552
|
unref(label) && !unref(hideLabel) && (!unref(inlineTextInputVisible) || itemName.value === "fontFamily") ? (openBlock(), createElementBlock("div", {
|
|
26212
|
-
key:
|
|
26553
|
+
key: 2,
|
|
26213
26554
|
class: normalizeClass(["sd-button-label", { "sd-visually-hidden": unref(inlineTextInputVisible) && itemName.value === "fontFamily" }])
|
|
26214
26555
|
}, toDisplayString(unref(label)), 3)) : createCommentVNode("", true),
|
|
26215
|
-
unref(inlineTextInputVisible) ? (openBlock(), createElementBlock("span",
|
|
26556
|
+
unref(inlineTextInputVisible) ? (openBlock(), createElementBlock("span", _hoisted_9$1, [unref(name) === "fontSize" ? withDirectives((openBlock(), createElementBlock("input", {
|
|
26216
26557
|
key: 0,
|
|
26217
26558
|
"onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => inlineTextInput.value = $event),
|
|
26218
26559
|
onKeydown: [withKeys(withModifiers(handleInlineInputEnter, ["stop", "prevent"]), ["enter"]), _cache[2] || (_cache[2] = withKeys(($event) => handleInlineInputTab($event), ["tab"]))],
|
|
@@ -26224,7 +26565,7 @@ var ToolbarButton_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/*
|
|
|
26224
26565
|
autocomplete: "off",
|
|
26225
26566
|
ref_key: "inlineInput",
|
|
26226
26567
|
ref: inlineInput
|
|
26227
|
-
}, null, 42,
|
|
26568
|
+
}, null, 42, _hoisted_10$1)), [[vModelText, inlineTextInput.value]]) : withDirectives((openBlock(), createElementBlock("input", {
|
|
26228
26569
|
key: 1,
|
|
26229
26570
|
"onUpdate:modelValue": _cache[5] || (_cache[5] = ($event) => inlineTextInput.value = $event),
|
|
26230
26571
|
placeholder: unref(label),
|
|
@@ -26241,20 +26582,20 @@ var ToolbarButton_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/*
|
|
|
26241
26582
|
autocomplete: "off",
|
|
26242
26583
|
ref_key: "inlineInput",
|
|
26243
26584
|
ref: inlineInput
|
|
26244
|
-
}, null, 42,
|
|
26585
|
+
}, null, 42, _hoisted_11$1)), [[vModelText, inlineTextInput.value]])])) : createCommentVNode("", true),
|
|
26245
26586
|
unref(hasCaret) ? (openBlock(), createElementBlock("div", {
|
|
26246
|
-
key:
|
|
26587
|
+
key: 4,
|
|
26247
26588
|
class: "sd-dropdown-caret",
|
|
26248
26589
|
"data-item": `btn-${unref(name) || ""}-toggle`,
|
|
26249
26590
|
innerHTML: caretIcon.value,
|
|
26250
26591
|
style: normalizeStyle({ opacity: unref(disabled) ? .6 : 1 })
|
|
26251
|
-
}, null, 12,
|
|
26592
|
+
}, null, 12, _hoisted_12$1)) : createCommentVNode("", true)
|
|
26252
26593
|
], 64)),
|
|
26253
|
-
createElementVNode("div",
|
|
26594
|
+
createElementVNode("div", _hoisted_13$1, toDisplayString(`${unref(attributes).ariaLabel} ${unref(active) ? "selected" : "unset"}`), 1)
|
|
26254
26595
|
], 10, _hoisted_2$11)], 46, _hoisted_1$15);
|
|
26255
26596
|
};
|
|
26256
26597
|
}
|
|
26257
|
-
}), [["__scopeId", "data-v-
|
|
26598
|
+
}), [["__scopeId", "data-v-b49ede12"]]);
|
|
26258
26599
|
//#endregion
|
|
26259
26600
|
//#region src/internal/toolbar/built-in/ToolbarSeparator.vue?vue&type=script&setup=true&lang.ts
|
|
26260
26601
|
var _hoisted_1$14 = {
|
|
@@ -26809,24 +27150,11 @@ var OverflowMenu_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/*
|
|
|
26809
27150
|
}
|
|
26810
27151
|
}), [["__scopeId", "data-v-d2e189fd"]]);
|
|
26811
27152
|
//#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
|
-
*/
|
|
27153
|
+
//#region src/internal/toolbar/built-in/font-typeahead.ts
|
|
26822
27154
|
var normalize = (value) => String(value ?? "").trim().toLowerCase();
|
|
26823
27155
|
/**
|
|
26824
27156
|
* 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
|
|
27157
|
+
* An empty/whitespace query never matches. Returns the matching index or -1.
|
|
26830
27158
|
*/
|
|
26831
27159
|
var findPrefixMatchIndex = (query, labels) => {
|
|
26832
27160
|
const q = normalize(query);
|
|
@@ -26840,12 +27168,7 @@ var findPrefixMatchIndex = (query, labels) => {
|
|
|
26840
27168
|
* When `autocomplete` is true and a prefix match exists that is longer than the
|
|
26841
27169
|
* typed query, the completion is shown with the suffix selected so the next
|
|
26842
27170
|
* 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 }}
|
|
27171
|
+
* query is shown with the caret at its end. `query` is the user-typed portion.
|
|
26849
27172
|
*/
|
|
26850
27173
|
var computeTypeahead = (query, labels, { autocomplete = true } = {}) => {
|
|
26851
27174
|
const typed = String(query ?? "");
|
|
@@ -26897,9 +27220,6 @@ var MAX_FONT_SIZE = 1638;
|
|
|
26897
27220
|
* the nearest half point (DOCX/Word support half points such as 10.5), and clamps
|
|
26898
27221
|
* to the supported range. Returns '' when nothing usable was typed, including
|
|
26899
27222
|
* negative or sub-minimum values.
|
|
26900
|
-
*
|
|
26901
|
-
* @param {string} value
|
|
26902
|
-
* @returns {string} point size (whole or half), or '' when empty/invalid
|
|
26903
27223
|
*/
|
|
26904
27224
|
var normalizeCustomFontSize = (value) => {
|
|
26905
27225
|
const cleaned = String(value ?? "").replace(/[^0-9.-]/g, "");
|
|
@@ -27567,7 +27887,7 @@ var SdTooltip_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__
|
|
|
27567
27887
|
]);
|
|
27568
27888
|
const contentStyle = computed$1(() => ({
|
|
27569
27889
|
...props.contentStyle,
|
|
27570
|
-
...attrs.style
|
|
27890
|
+
...attrs.style,
|
|
27571
27891
|
position: "fixed",
|
|
27572
27892
|
top: position.value.top,
|
|
27573
27893
|
left: position.value.left,
|
|
@@ -27736,7 +28056,7 @@ var SdTooltip_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__
|
|
|
27736
28056
|
}, 8, ["css"])]))], 64);
|
|
27737
28057
|
};
|
|
27738
28058
|
}
|
|
27739
|
-
}), [["__scopeId", "data-v-
|
|
28059
|
+
}), [["__scopeId", "data-v-87967ab1"]]);
|
|
27740
28060
|
//#endregion
|
|
27741
28061
|
//#region src/internal/toolbar/built-in/ButtonGroup.vue?vue&type=script&setup=true&lang.ts
|
|
27742
28062
|
var _hoisted_1$11 = [
|
|
@@ -28590,7 +28910,7 @@ var Toolbar_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__PU
|
|
|
28590
28910
|
}
|
|
28591
28911
|
}), [["__scopeId", "data-v-bce7c04a"]]);
|
|
28592
28912
|
//#endregion
|
|
28593
|
-
//#region src/internal/toolbar/built-in/font-options.
|
|
28913
|
+
//#region src/internal/toolbar/built-in/font-options.ts
|
|
28594
28914
|
/**
|
|
28595
28915
|
* Normalize a font dropdown option so each row renders in its own typeface.
|
|
28596
28916
|
*
|
|
@@ -28946,7 +29266,7 @@ var StyleButtonsList_default = /* @__PURE__ */ _plugin_vue_export_helper_default
|
|
|
28946
29266
|
}
|
|
28947
29267
|
}), [["__scopeId", "data-v-539d0995"]]);
|
|
28948
29268
|
//#endregion
|
|
28949
|
-
//#region src/internal/toolbar/built-in/list-style-buttons.
|
|
29269
|
+
//#region src/internal/toolbar/built-in/list-style-buttons.ts
|
|
28950
29270
|
var bulletStyleButtons = [
|
|
28951
29271
|
{
|
|
28952
29272
|
key: "disc",
|
|
@@ -30257,7 +30577,7 @@ var PageNumberMenu_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/
|
|
|
30257
30577
|
onClick: ($event) => selectTile(tile),
|
|
30258
30578
|
onDblclick: applyPageNumbers,
|
|
30259
30579
|
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-
|
|
30580
|
+
}, [(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
30581
|
class: "sd-page-number-menu__chip",
|
|
30262
30582
|
x: CHIP_X[tile.alignment],
|
|
30263
30583
|
y: CHIP_Y[tile.position],
|
|
@@ -30337,23 +30657,21 @@ var PageNumberMenu_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/
|
|
|
30337
30657
|
], 10, _hoisted_1);
|
|
30338
30658
|
};
|
|
30339
30659
|
}
|
|
30340
|
-
}), [["__scopeId", "data-v-
|
|
30660
|
+
}), [["__scopeId", "data-v-e3105afd"]]);
|
|
30341
30661
|
//#endregion
|
|
30342
|
-
//#region src/internal/toolbar/built-in/page-number-feedback.
|
|
30662
|
+
//#region src/internal/toolbar/built-in/page-number-feedback.ts
|
|
30343
30663
|
var FLASH_CLASS = "sd-page-number-flash";
|
|
30344
30664
|
var FLASH_MS = 1400;
|
|
30345
30665
|
var nextFrame = (view) => new Promise((resolve) => {
|
|
30346
|
-
if (typeof view
|
|
30666
|
+
if (typeof view.requestAnimationFrame === "function") view.requestAnimationFrame(() => resolve());
|
|
30347
30667
|
else setTimeout(resolve, 16);
|
|
30348
30668
|
});
|
|
30349
30669
|
/**
|
|
30350
30670
|
* Briefly highlight the painted header or footer regions that are on screen,
|
|
30351
30671
|
* so the user sees where page numbers landed without the caret leaving the
|
|
30352
30672
|
* 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
|
|
30673
|
+
* happens when none is visible or the host is unavailable. `host` is the
|
|
30674
|
+
* document viewport host element.
|
|
30357
30675
|
*/
|
|
30358
30676
|
async function flashPageNumberRegions(host, kind) {
|
|
30359
30677
|
const view = host?.ownerDocument?.defaultView;
|
|
@@ -30361,7 +30679,7 @@ async function flashPageNumberRegions(host, kind) {
|
|
|
30361
30679
|
await nextFrame(view);
|
|
30362
30680
|
await nextFrame(view);
|
|
30363
30681
|
const viewportHeight = view.innerHeight;
|
|
30364
|
-
const regions =
|
|
30682
|
+
const regions = Array.from(host.querySelectorAll(`[data-sd-headerfooter-kind="${kind}"]`)).filter((region) => {
|
|
30365
30683
|
const rect = region.getBoundingClientRect();
|
|
30366
30684
|
return rect.height > 0 && rect.bottom > 0 && rect.top < viewportHeight;
|
|
30367
30685
|
});
|
|
@@ -30562,6 +30880,8 @@ var makeDefaultItems = ({ superToolbar, toolbarIcons: configuredIcons, toolbarTe
|
|
|
30562
30880
|
attributes: { ariaLabel: "Bold" }
|
|
30563
30881
|
});
|
|
30564
30882
|
const fontOptions = (toolbarFonts ?? TOOLBAR_FONTS).map(normalizeFontOption);
|
|
30883
|
+
const isFontOption = (option) => typeof option.label === "string" && typeof option.key === "string";
|
|
30884
|
+
const currentFontOptions = () => fontButton.nestedOptions.value.filter(isFontOption);
|
|
30565
30885
|
const fontButton = useToolbarItem({
|
|
30566
30886
|
type: "dropdown",
|
|
30567
30887
|
name: "fontFamily",
|
|
@@ -30588,8 +30908,9 @@ var makeDefaultItems = ({ superToolbar, toolbarIcons: configuredIcons, toolbarTe
|
|
|
30588
30908
|
if (typeof fontFamily !== "string" || !fontFamily) return;
|
|
30589
30909
|
const family = fontFamily.split(",")[0];
|
|
30590
30910
|
const optionValue = (option) => option.value ?? option.label;
|
|
30591
|
-
const
|
|
30592
|
-
const
|
|
30911
|
+
const options = currentFontOptions();
|
|
30912
|
+
const defaultFont = options.find((option) => optionValue(option) === fontButton.defaultLabel.value);
|
|
30913
|
+
const foundFont = options.find((option) => optionValue(option) === family);
|
|
30593
30914
|
if (foundFont) {
|
|
30594
30915
|
fontButton.label.value = foundFont.label;
|
|
30595
30916
|
fontButton.selectedValue.value = foundFont.key;
|
|
@@ -30602,7 +30923,7 @@ var makeDefaultItems = ({ superToolbar, toolbarIcons: configuredIcons, toolbarTe
|
|
|
30602
30923
|
}
|
|
30603
30924
|
},
|
|
30604
30925
|
onDeactivate: () => {
|
|
30605
|
-
const defaultFont =
|
|
30926
|
+
const defaultFont = currentFontOptions().find((option) => (option.value ?? option.label) === fontButton.defaultLabel.value);
|
|
30606
30927
|
fontButton.label.value = defaultFont?.label ?? fontButton.defaultLabel.value;
|
|
30607
30928
|
fontButton.selectedValue.value = defaultFont?.key ?? "";
|
|
30608
30929
|
}
|
|
@@ -31709,7 +32030,7 @@ var makeDefaultItems = ({ superToolbar, toolbarIcons: configuredIcons, toolbarTe
|
|
|
31709
32030
|
};
|
|
31710
32031
|
};
|
|
31711
32032
|
//#endregion
|
|
31712
|
-
//#region src/internal/toolbar/built-in/general.
|
|
32033
|
+
//#region src/internal/toolbar/built-in/general.ts
|
|
31713
32034
|
/**
|
|
31714
32035
|
* Minimal DOM helpers for the built-in toolbar shell.
|
|
31715
32036
|
*
|
|
@@ -31720,8 +32041,6 @@ var makeDefaultItems = ({ superToolbar, toolbarIcons: configuredIcons, toolbarTe
|
|
|
31720
32041
|
*/
|
|
31721
32042
|
/**
|
|
31722
32043
|
* Resolve a toolbar mount target from a selector string or element id.
|
|
31723
|
-
* @param {string|HTMLElement|null|undefined} selector
|
|
31724
|
-
* @returns {HTMLElement|null}
|
|
31725
32044
|
*/
|
|
31726
32045
|
var findElementBySelector = (selector) => {
|
|
31727
32046
|
if (!selector) return null;
|
|
@@ -31761,9 +32080,6 @@ function toSelectedValue(value) {
|
|
|
31761
32080
|
function nonEmptyString(value) {
|
|
31762
32081
|
return typeof value === "string" && value ? value : void 0;
|
|
31763
32082
|
}
|
|
31764
|
-
function isThenable(value) {
|
|
31765
|
-
return (typeof value === "object" || typeof value === "function") && value !== null && "then" in value && typeof value.then === "function";
|
|
31766
|
-
}
|
|
31767
32083
|
function isToolbarCommandCallback(value) {
|
|
31768
32084
|
return typeof value === "function";
|
|
31769
32085
|
}
|
|
@@ -31786,7 +32102,7 @@ function executeCommand(ui, commandId, argument, options = {}) {
|
|
|
31786
32102
|
if (!options.reportUnhandled || settled !== false) return;
|
|
31787
32103
|
options.onError?.(/* @__PURE__ */ new Error(`[superdoc toolbar] Command "${commandId}" did not run. Check that it is enabled and has the required input.`));
|
|
31788
32104
|
};
|
|
31789
|
-
if (isThenable(result)) Promise.resolve(result).then((settled) => {
|
|
32105
|
+
if (isThenable$1(result)) Promise.resolve(result).then((settled) => {
|
|
31790
32106
|
reportFailure(settled);
|
|
31791
32107
|
options.onSettled?.();
|
|
31792
32108
|
}, (error) => {
|
|
@@ -31819,7 +32135,7 @@ var V1_ENABLED_ON_SELECTION_REASON = /* @__PURE__ */ new Set([
|
|
|
31819
32135
|
]);
|
|
31820
32136
|
var V1_ENABLED_ON_EMPTY_REASON = /* @__PURE__ */ new Set(["list", "numberedlist"]);
|
|
31821
32137
|
function shouldKeepEnabledForV1ToolbarParity(name, commandState) {
|
|
31822
|
-
if (name === "fontFamily" || name === "fontSize") return
|
|
32138
|
+
if (name === "fontFamily" || name === "fontSize") return commandState?.reason !== "document-readonly" && commandState?.reason !== "deleted-text-formatting-unsupported";
|
|
31823
32139
|
if (V1_ENABLED_ON_EMPTY_REASON.has(name) && commandState?.disabled && commandState?.supported !== false && commandState?.reason == null) return true;
|
|
31824
32140
|
if (!V1_ENABLED_ON_SELECTION_REASON.has(name)) return false;
|
|
31825
32141
|
const reason = commandState?.reason;
|
|
@@ -31853,6 +32169,7 @@ var RESERVED_TOOLBAR_ITEM_NAMES = /* @__PURE__ */ new Set([
|
|
|
31853
32169
|
* proof lane, and behavior tests resolve against a real object.
|
|
31854
32170
|
*/
|
|
31855
32171
|
var BuiltInToolbar = class extends import_eventemitter3.default {
|
|
32172
|
+
#formattingRefusalTooltips;
|
|
31856
32173
|
#imagePicker;
|
|
31857
32174
|
#groupItems;
|
|
31858
32175
|
#highlightOptions;
|
|
@@ -31884,6 +32201,7 @@ var BuiltInToolbar = class extends import_eventemitter3.default {
|
|
|
31884
32201
|
showPageNumberButton: false
|
|
31885
32202
|
};
|
|
31886
32203
|
this.toolbarItems = [];
|
|
32204
|
+
this.#formattingRefusalTooltips = /* @__PURE__ */ new WeakMap();
|
|
31887
32205
|
this.overflowItems = [];
|
|
31888
32206
|
this.pendingSelectionCapture = void 0;
|
|
31889
32207
|
this.#imagePicker = null;
|
|
@@ -32010,7 +32328,7 @@ var BuiltInToolbar = class extends import_eventemitter3.default {
|
|
|
32010
32328
|
const signature = this.#fontOptionsSignature();
|
|
32011
32329
|
if (signature !== this._lastFontOptionsSignature) {
|
|
32012
32330
|
this._lastFontOptionsSignature = signature;
|
|
32013
|
-
this.#rebuildToolbarItems();
|
|
32331
|
+
if (!this.#refreshFontFamilyOptions()) this.#rebuildToolbarItems();
|
|
32014
32332
|
}
|
|
32015
32333
|
this.updateToolbarState();
|
|
32016
32334
|
};
|
|
@@ -32138,7 +32456,7 @@ var BuiltInToolbar = class extends import_eventemitter3.default {
|
|
|
32138
32456
|
argument: payload.argument,
|
|
32139
32457
|
option: payload.option
|
|
32140
32458
|
});
|
|
32141
|
-
if (isThenable(result)) return Promise.resolve(result).catch((error) => {
|
|
32459
|
+
if (isThenable$1(result)) return Promise.resolve(result).catch((error) => {
|
|
32142
32460
|
this.#emitCommandException(error, config.name);
|
|
32143
32461
|
return false;
|
|
32144
32462
|
});
|
|
@@ -32158,6 +32476,13 @@ var BuiltInToolbar = class extends import_eventemitter3.default {
|
|
|
32158
32476
|
this.#makeToolbarItems();
|
|
32159
32477
|
this.emit("toolbar-items-changed");
|
|
32160
32478
|
}
|
|
32479
|
+
#refreshFontFamilyOptions() {
|
|
32480
|
+
const items = this.#getAllToolbarItems().filter((item) => item.name.value === "fontFamily");
|
|
32481
|
+
if (!items.length) return false;
|
|
32482
|
+
const options = (this.#resolveToolbarFonts(this.config.fonts) ?? TOOLBAR_FONTS).map(normalizeFontOption);
|
|
32483
|
+
for (const item of items) item.nestedOptions.value = options.map((option) => ({ ...option }));
|
|
32484
|
+
return true;
|
|
32485
|
+
}
|
|
32161
32486
|
#fontOptionsSignature() {
|
|
32162
32487
|
if (this.config.fonts) return "custom-fonts";
|
|
32163
32488
|
const options = this.superdoc?.fonts?.getFontFamilyOptions?.() ?? [];
|
|
@@ -32337,6 +32662,17 @@ var BuiltInToolbar = class extends import_eventemitter3.default {
|
|
|
32337
32662
|
const commandId = resolveBuiltInItemCommandId(name);
|
|
32338
32663
|
if (!commandId) return false;
|
|
32339
32664
|
const commandState = this.snapshot?.commands?.[commandId];
|
|
32665
|
+
if (commandState?.reason === "deleted-text-formatting-unsupported") {
|
|
32666
|
+
if (!this.#formattingRefusalTooltips.has(item)) this.#formattingRefusalTooltips.set(item, item.tooltip.value);
|
|
32667
|
+
item.tooltip.value = "Select kept text, or accept or reject the deletion before formatting.";
|
|
32668
|
+
} else if (this.#formattingRefusalTooltips.has(item)) {
|
|
32669
|
+
item.tooltip.value = this.#formattingRefusalTooltips.get(item);
|
|
32670
|
+
this.#formattingRefusalTooltips.delete(item);
|
|
32671
|
+
}
|
|
32672
|
+
if ((name === "list" || name === "numberedlist") && item.attributes.value.ariaBusy !== Boolean(commandState?.pending)) item.attributes.value = {
|
|
32673
|
+
...item.attributes.value,
|
|
32674
|
+
ariaBusy: Boolean(commandState?.pending)
|
|
32675
|
+
};
|
|
32340
32676
|
if (shouldKeepEnabledForV1ToolbarParity(name, commandState)) item.setDisabled(false);
|
|
32341
32677
|
else item.setDisabled(Boolean(commandState?.disabled));
|
|
32342
32678
|
const handlers = {
|
|
@@ -32615,7 +32951,7 @@ var BuiltInToolbar = class extends import_eventemitter3.default {
|
|
|
32615
32951
|
ui: this.ui,
|
|
32616
32952
|
superdoc: this.superdoc
|
|
32617
32953
|
});
|
|
32618
|
-
if (isThenable(result)) Promise.resolve(result).catch((error) => this.#emitCommandException(error, name));
|
|
32954
|
+
if (isThenable$1(result)) Promise.resolve(result).catch((error) => this.#emitCommandException(error, name));
|
|
32619
32955
|
}
|
|
32620
32956
|
this.updateToolbarState();
|
|
32621
32957
|
return;
|
|
@@ -32804,6 +33140,9 @@ function deriveCollaborationConnectionKind(snapshot, hasSyncedBefore) {
|
|
|
32804
33140
|
default: return hasSyncedBefore ? "reconnecting" : "initial";
|
|
32805
33141
|
}
|
|
32806
33142
|
}
|
|
33143
|
+
function destroyedDuringUpgradeError() {
|
|
33144
|
+
return /* @__PURE__ */ new Error("SuperDoc: instance was destroyed during upgrade");
|
|
33145
|
+
}
|
|
32807
33146
|
function isV2ActiveEditorFacade(editor) {
|
|
32808
33147
|
return Boolean(editor && typeof editor === "object" && editor.editorVersion === 2);
|
|
32809
33148
|
}
|
|
@@ -32853,6 +33192,7 @@ function runtimeUserOf(user) {
|
|
|
32853
33192
|
const text = (value) => typeof value === "string" && value ? value : void 0;
|
|
32854
33193
|
return {
|
|
32855
33194
|
name: text(user.name) ?? "",
|
|
33195
|
+
...user.commentIdentity !== void 0 ? { commentIdentity: user.commentIdentity ? { ...user.commentIdentity } : null } : {},
|
|
32856
33196
|
...text(user.id) ? { id: text(user.id) } : {},
|
|
32857
33197
|
...text(user.email) ? { email: text(user.email) } : {},
|
|
32858
33198
|
...text(user.initials) ? { initials: text(user.initials) } : {}
|
|
@@ -32864,10 +33204,7 @@ var SuperDoc = class extends import_eventemitter3.default {
|
|
|
32864
33204
|
}
|
|
32865
33205
|
#destroyed;
|
|
32866
33206
|
#diagnostics;
|
|
32867
|
-
#isUpgrading;
|
|
32868
33207
|
#pendingUpgrade;
|
|
32869
|
-
/** Aborts an in-flight upgrade (sync wait or ready wait). */
|
|
32870
|
-
#abortUpgrade;
|
|
32871
33208
|
/**
|
|
32872
33209
|
* Unsubscribe handle for the v2 presence → `awareness-update` bridge. Set
|
|
32873
33210
|
* while a v2 collaborative editor is mounted and torn down on remount,
|
|
@@ -32881,6 +33218,7 @@ var SuperDoc = class extends import_eventemitter3.default {
|
|
|
32881
33218
|
#v2ConnectionUnsub;
|
|
32882
33219
|
/** Latest `collaboration-connection-change` payload, for late readers. */
|
|
32883
33220
|
#v2ConnectionState;
|
|
33221
|
+
#v2ConnectionFailureReported;
|
|
32884
33222
|
/** Whether the current collaboration room has completed a sync at least once. */
|
|
32885
33223
|
#v2ConnectionHasSynced;
|
|
32886
33224
|
/** Lock state captured before a local → v2 collaboration promotion remount. */
|
|
@@ -32976,13 +33314,12 @@ var SuperDoc = class extends import_eventemitter3.default {
|
|
|
32976
33314
|
constructor(config) {
|
|
32977
33315
|
super();
|
|
32978
33316
|
this.#destroyed = false;
|
|
32979
|
-
this.#isUpgrading = false;
|
|
32980
33317
|
this.#pendingUpgrade = null;
|
|
32981
|
-
this.#abortUpgrade = null;
|
|
32982
33318
|
this.#v2AwarenessUnsub = null;
|
|
32983
33319
|
this.#v2LockUnsub = null;
|
|
32984
33320
|
this.#v2ConnectionUnsub = null;
|
|
32985
33321
|
this.#v2ConnectionState = null;
|
|
33322
|
+
this.#v2ConnectionFailureReported = false;
|
|
32986
33323
|
this.#v2ConnectionHasSynced = false;
|
|
32987
33324
|
this.#pendingV2LockSeed = null;
|
|
32988
33325
|
this.#mountWrapper = null;
|
|
@@ -33097,6 +33434,7 @@ var SuperDoc = class extends import_eventemitter3.default {
|
|
|
33097
33434
|
if (!config.selector) throw new Error("SuperDoc: selector is required");
|
|
33098
33435
|
const container = typeof config.selector === "string" ? document.querySelector(config.selector) : config.selector;
|
|
33099
33436
|
if (!(container instanceof HTMLElement)) throw new Error("SuperDoc: selector must be a valid CSS selector string or DOM element");
|
|
33437
|
+
const user = normalizeSuperDocUser(config.user);
|
|
33100
33438
|
this.#diagnostics = createInteractionHistory(this, config, () => this.version, container);
|
|
33101
33439
|
this.#surfaceManager = new SurfaceManager({ getModuleConfig: () => this.#surfacesConfig });
|
|
33102
33440
|
this.#contentControlClickRoot = container;
|
|
@@ -33106,7 +33444,10 @@ var SuperDoc = class extends import_eventemitter3.default {
|
|
|
33106
33444
|
container.addEventListener("keydown", this.#handleContentControlKeyDown, true);
|
|
33107
33445
|
container.addEventListener("click", this.#handleContentControlClick, true);
|
|
33108
33446
|
this.#onConfig("content-control:active-change", config.onContentControlActiveChange);
|
|
33109
|
-
this.#init(
|
|
33447
|
+
this.#init({
|
|
33448
|
+
...config,
|
|
33449
|
+
user
|
|
33450
|
+
}, container);
|
|
33110
33451
|
this.#contentControlEventBridgeReady = true;
|
|
33111
33452
|
if (this.listenerCount("content-control:active-change") > 0) this.ui;
|
|
33112
33453
|
}
|
|
@@ -33159,7 +33500,6 @@ var SuperDoc = class extends import_eventemitter3.default {
|
|
|
33159
33500
|
}
|
|
33160
33501
|
this.editorVersion = 2;
|
|
33161
33502
|
this.#validateLegacyConfig();
|
|
33162
|
-
this.config.user = normalizeSuperDocUser(this.config.user);
|
|
33163
33503
|
if (!this.config.layoutEngineOptions.virtualization) this.config.layoutEngineOptions.virtualization = {
|
|
33164
33504
|
enabled: true,
|
|
33165
33505
|
window: 5,
|
|
@@ -33185,7 +33525,7 @@ var SuperDoc = class extends import_eventemitter3.default {
|
|
|
33185
33525
|
}
|
|
33186
33526
|
this.userColorMap = /* @__PURE__ */ new Map();
|
|
33187
33527
|
this.colorIndex = 0;
|
|
33188
|
-
this.version = "2.
|
|
33528
|
+
this.version = "2.30.0-next.13";
|
|
33189
33529
|
this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
|
|
33190
33530
|
this.superdocId = config.superdocId || v4();
|
|
33191
33531
|
this.colors = this.config.colors ?? [];
|
|
@@ -33604,6 +33944,7 @@ var SuperDoc = class extends import_eventemitter3.default {
|
|
|
33604
33944
|
if (this.#v2ConnectionState?.documentId !== documentId) {
|
|
33605
33945
|
this.#v2ConnectionState = null;
|
|
33606
33946
|
this.#v2ConnectionHasSynced = false;
|
|
33947
|
+
this.#v2ConnectionFailureReported = false;
|
|
33607
33948
|
}
|
|
33608
33949
|
const publish = (snapshot) => {
|
|
33609
33950
|
if (this.#destroyed) return;
|
|
@@ -33618,8 +33959,21 @@ var SuperDoc = class extends import_eventemitter3.default {
|
|
|
33618
33959
|
superdoc: this
|
|
33619
33960
|
};
|
|
33620
33961
|
this.#v2ConnectionState = payload;
|
|
33621
|
-
if (snapshot.state === "synced")
|
|
33622
|
-
|
|
33962
|
+
if (snapshot.state === "synced") {
|
|
33963
|
+
this.#v2ConnectionHasSynced = true;
|
|
33964
|
+
this.#v2ConnectionFailureReported = false;
|
|
33965
|
+
}
|
|
33966
|
+
const firstFailure = snapshot.state === "failed" && !this.#v2ConnectionFailureReported;
|
|
33967
|
+
if (firstFailure) this.#v2ConnectionFailureReported = true;
|
|
33968
|
+
const reportFailure = firstFailure && snapshot.detail !== "worker-transport-failed";
|
|
33969
|
+
try {
|
|
33970
|
+
this.emit("collaboration-connection-change", payload);
|
|
33971
|
+
} finally {
|
|
33972
|
+
if (reportFailure) {
|
|
33973
|
+
const exception = createCollaborationException("collaboration-connection-failed", documentId);
|
|
33974
|
+
if (exception) this.emit("exception", exception);
|
|
33975
|
+
}
|
|
33976
|
+
}
|
|
33623
33977
|
};
|
|
33624
33978
|
try {
|
|
33625
33979
|
const initialSnapshot = connection.getSnapshot?.();
|
|
@@ -33732,41 +34086,43 @@ var SuperDoc = class extends import_eventemitter3.default {
|
|
|
33732
34086
|
throw Object.assign(/* @__PURE__ */ new Error("SuperDoc: a different collaboration target is already upgrading"), { code: "collaboration-upgrade-target-conflict" });
|
|
33733
34087
|
}
|
|
33734
34088
|
const { target } = this.#validateUpgradePrerequisites(options);
|
|
33735
|
-
|
|
33736
|
-
const
|
|
33737
|
-
|
|
33738
|
-
|
|
33739
|
-
|
|
33740
|
-
|
|
33741
|
-
|
|
33742
|
-
try {
|
|
33743
|
-
this.#pendingV2LockSeed = lockSeed;
|
|
33744
|
-
const promotion = await this.#promoteSingleDocumentToV2Collaboration(target, localSource);
|
|
33745
|
-
this.#finalizeSingleDocumentV2Collaboration(promotion, target);
|
|
33746
|
-
this.#pendingV2LockSeed = null;
|
|
33747
|
-
const attachedDocumentId = this.activeEditor?.options?.documentId;
|
|
33748
|
-
const attachedRoomId = promotion.configDoc.v2Collaboration?.documentId;
|
|
33749
|
-
if (typeof attachedDocumentId !== "string" || attachedDocumentId !== promotion.configDoc.id || typeof attachedRoomId !== "string" || attachedRoomId !== target.documentId) throw new Error("SuperDoc: collaboration upgrade did not attach the expected room and document");
|
|
33750
|
-
return {
|
|
33751
|
-
roomId: attachedRoomId,
|
|
33752
|
-
documentId: attachedDocumentId
|
|
33753
|
-
};
|
|
33754
|
-
} catch (err) {
|
|
33755
|
-
this.#rollbackV2UpgradeState(rollback);
|
|
33756
|
-
throw err;
|
|
33757
|
-
}
|
|
33758
|
-
} finally {
|
|
33759
|
-
this.#abortUpgrade = null;
|
|
33760
|
-
this.#isUpgrading = false;
|
|
33761
|
-
this.#pendingUpgrade = null;
|
|
33762
|
-
}
|
|
33763
|
-
})();
|
|
34089
|
+
let rejectOnDestroy = () => {};
|
|
34090
|
+
const destroyed = new Promise((_resolve, reject) => {
|
|
34091
|
+
rejectOnDestroy = reject;
|
|
34092
|
+
});
|
|
34093
|
+
const operation = Promise.race([this.#runUpgrade(target), destroyed]).finally(() => {
|
|
34094
|
+
this.#pendingUpgrade = null;
|
|
34095
|
+
});
|
|
33764
34096
|
this.#pendingUpgrade = {
|
|
33765
34097
|
target,
|
|
33766
|
-
promise: operation
|
|
34098
|
+
promise: operation,
|
|
34099
|
+
rejectOnDestroy
|
|
33767
34100
|
};
|
|
33768
34101
|
return operation;
|
|
33769
34102
|
}
|
|
34103
|
+
async #runUpgrade(target) {
|
|
34104
|
+
const localSource = await this.#captureCurrentDocxSourceForUpgrade();
|
|
34105
|
+
const rollback = this.#snapshotV2UpgradeState();
|
|
34106
|
+
const lockSeed = this.#snapshotV2LockSeed();
|
|
34107
|
+
this.#assertNotDestroyed();
|
|
34108
|
+
try {
|
|
34109
|
+
this.#pendingV2LockSeed = lockSeed;
|
|
34110
|
+
const promotion = await this.#promoteSingleDocumentToV2Collaboration(target, localSource);
|
|
34111
|
+
this.#assertNotDestroyed();
|
|
34112
|
+
this.#finalizeSingleDocumentV2Collaboration(promotion, target);
|
|
34113
|
+
this.#pendingV2LockSeed = null;
|
|
34114
|
+
const attachedDocumentId = this.activeEditor?.options?.documentId;
|
|
34115
|
+
const attachedRoomId = promotion.configDoc.v2Collaboration?.documentId;
|
|
34116
|
+
if (typeof attachedDocumentId !== "string" || attachedDocumentId !== promotion.configDoc.id || typeof attachedRoomId !== "string" || attachedRoomId !== target.documentId) throw new Error("SuperDoc: collaboration upgrade did not attach the expected room and document");
|
|
34117
|
+
return {
|
|
34118
|
+
roomId: attachedRoomId,
|
|
34119
|
+
documentId: attachedDocumentId
|
|
34120
|
+
};
|
|
34121
|
+
} catch (err) {
|
|
34122
|
+
if (!this.#destroyed) this.#rollbackV2UpgradeState(rollback);
|
|
34123
|
+
throw err;
|
|
34124
|
+
}
|
|
34125
|
+
}
|
|
33770
34126
|
#sameUpgradeTarget(left, right) {
|
|
33771
34127
|
if (left.token !== right.token) return false;
|
|
33772
34128
|
const seen = /* @__PURE__ */ new WeakMap();
|
|
@@ -33831,7 +34187,7 @@ var SuperDoc = class extends import_eventemitter3.default {
|
|
|
33831
34187
|
* async waits inside upgradeToCollaboration().
|
|
33832
34188
|
*/
|
|
33833
34189
|
#assertNotDestroyed() {
|
|
33834
|
-
if (this.#destroyed) throw
|
|
34190
|
+
if (this.#destroyed) throw destroyedDuringUpgradeError();
|
|
33835
34191
|
}
|
|
33836
34192
|
/**
|
|
33837
34193
|
* Return the superdoc store, throwing a clear lifecycle error if
|
|
@@ -33930,6 +34286,7 @@ var SuperDoc = class extends import_eventemitter3.default {
|
|
|
33930
34286
|
this.#writeStoreDocV2Collaboration(storeDoc, v2Collaboration);
|
|
33931
34287
|
this.isCollaborative = true;
|
|
33932
34288
|
await editor.upgradeToCollaboration(localSource, v2Collaboration);
|
|
34289
|
+
this.#assertNotDestroyed();
|
|
33933
34290
|
configDoc.data = localSource;
|
|
33934
34291
|
storeDoc.data = localSource;
|
|
33935
34292
|
return {
|
|
@@ -33989,7 +34346,6 @@ var SuperDoc = class extends import_eventemitter3.default {
|
|
|
33989
34346
|
*/
|
|
33990
34347
|
#validateUpgradePrerequisites(options) {
|
|
33991
34348
|
if (this.#destroyed) throw new Error("SuperDoc: cannot upgrade a destroyed instance");
|
|
33992
|
-
if (this.#isUpgrading) throw new Error("SuperDoc: upgrade already in progress");
|
|
33993
34349
|
if (this.isCollaborative) throw new Error("SuperDoc: instance is already collaborative");
|
|
33994
34350
|
const cfg = this.config;
|
|
33995
34351
|
const docxDocs = cfg.documents.filter((d) => d.type === DOCX);
|
|
@@ -34044,10 +34400,15 @@ var SuperDoc = class extends import_eventemitter3.default {
|
|
|
34044
34400
|
this.#requireReady("setUser");
|
|
34045
34401
|
const name = typeof user?.name === "string" ? user.name.trim() : "";
|
|
34046
34402
|
if (!name) return Promise.reject(/* @__PURE__ */ new TypeError("SuperDoc.setUser requires a non-empty user name."));
|
|
34047
|
-
|
|
34048
|
-
|
|
34049
|
-
|
|
34050
|
-
|
|
34403
|
+
let next;
|
|
34404
|
+
try {
|
|
34405
|
+
next = normalizeSuperDocUser({
|
|
34406
|
+
...user,
|
|
34407
|
+
name
|
|
34408
|
+
});
|
|
34409
|
+
} catch (error) {
|
|
34410
|
+
return Promise.reject(error);
|
|
34411
|
+
}
|
|
34051
34412
|
const applied = this.#userSwitch.then(() => this.#applyUser(next));
|
|
34052
34413
|
this.#userSwitch = applied.catch(() => {});
|
|
34053
34414
|
return applied;
|
|
@@ -34061,7 +34422,7 @@ var SuperDoc = class extends import_eventemitter3.default {
|
|
|
34061
34422
|
"email",
|
|
34062
34423
|
"image",
|
|
34063
34424
|
"initials"
|
|
34064
|
-
].every((key) => (current[key] ?? null) === (next[key] ?? null))) return;
|
|
34425
|
+
].every((key) => (current[key] ?? null) === (next[key] ?? null)) && current.commentIdentity === void 0 === (next.commentIdentity === void 0) && (current.commentIdentity?.providerId ?? null) === (next.commentIdentity?.providerId ?? null) && (current.commentIdentity?.userId ?? null) === (next.commentIdentity?.userId ?? null)) return;
|
|
34065
34426
|
const runtimes = this.#editorRuntimeRegistry.getAll();
|
|
34066
34427
|
const results = await Promise.allSettled(runtimes.map((runtime) => runtime.setUser?.(runtimeUserOf(next))));
|
|
34067
34428
|
const failure = results.find((result) => result.status === "rejected");
|
|
@@ -35396,10 +35757,7 @@ var SuperDoc = class extends import_eventemitter3.default {
|
|
|
35396
35757
|
this.#contentControlClickRoot = null;
|
|
35397
35758
|
this.#contentControlActiveChangeUnsub?.();
|
|
35398
35759
|
this.#contentControlActiveChangeUnsub = null;
|
|
35399
|
-
|
|
35400
|
-
this.#abortUpgrade();
|
|
35401
|
-
this.#abortUpgrade = null;
|
|
35402
|
-
}
|
|
35760
|
+
this.#pendingUpgrade?.rejectOnDestroy(destroyedDuringUpgradeError());
|
|
35403
35761
|
if (this.#surfaceManager) this.#surfaceManager.destroy();
|
|
35404
35762
|
this.toolbar?.destroy?.();
|
|
35405
35763
|
this.commentsList?.close();
|