superdoc 2.28.0-next.6 → 2.28.0-next.7

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.
Files changed (41) hide show
  1. package/dist/chunks/{create-super-doc-ui-D1eOhAjv.cjs → create-super-doc-ui-B4c55pFy.cjs} +420 -84
  2. package/dist/chunks/{create-super-doc-ui-B29zw5qD.es.js → create-super-doc-ui-C4Ka5Ph3.es.js} +415 -85
  3. package/dist/collaboration-upgrade-engine.cjs +1 -1
  4. package/dist/collaboration-upgrade-engine.es.js +1 -1
  5. package/dist/document-api/src/content-controls/content-controls.types.d.ts +11 -0
  6. package/dist/document-api/src/contract/command-catalog.d.ts +1 -1
  7. package/dist/document-api/src/contract/operation-definitions.d.ts +30 -30
  8. package/dist/document-api/src/contract/operation-registry.d.ts +4 -0
  9. package/dist/document-api/src/export/export.d.ts +3 -1
  10. package/dist/document-api/src/export/export.types.d.ts +8 -0
  11. package/dist/document-api/src/get-node/get-node.d.ts +10 -4
  12. package/dist/document-api/src/index.d.ts +1 -0
  13. package/dist/document-api/src/types/track-changes.types.d.ts +10 -2
  14. package/dist/layout-engine/contracts/src/index.d.ts +1 -0
  15. package/dist/public/ui-react.cjs +1 -1
  16. package/dist/public/ui-react.es.js +1 -1
  17. package/dist/public/ui-vue.cjs +1 -1
  18. package/dist/public/ui-vue.es.js +1 -1
  19. package/dist/public/ui.cjs +1 -1
  20. package/dist/public/ui.es.js +1 -1
  21. package/dist/style.css +1 -1
  22. package/dist/style.layered.css +1 -1
  23. package/dist/superdoc/src/core/SuperDoc.d.ts +2 -6
  24. package/dist/superdoc/src/core/editor-runtime/types.d.ts +1 -0
  25. package/dist/superdoc/src/core/editor-runtime/v2/v2-editor-runtime-adapter.d.ts +2 -2
  26. package/dist/superdoc/src/core/helpers/resolve-docx-export.d.ts +6 -0
  27. package/dist/superdoc/src/public/export-types.d.ts +3 -0
  28. package/dist/superdoc/src/public/ui/entity-at.d.ts +1 -0
  29. package/dist/superdoc/src/public/ui/types.d.ts +16 -2
  30. package/dist/superdoc/src/public/ui.d.cts +14 -0
  31. package/dist/superdoc/src/public/ui.d.ts +1 -1
  32. package/dist/superdoc/src/stores/comments-store.d.ts +3 -57
  33. package/dist/superdoc/src/stores/superdoc-store.d.ts +9 -171
  34. package/dist/superdoc.cjs +214 -43
  35. package/dist/superdoc.es.js +214 -43
  36. package/dist-cdn/style.layered.css +1 -1
  37. package/dist-cdn/superdoc.min.css +1 -1
  38. package/dist-cdn/superdoc.min.js +42 -42
  39. package/package.json +2 -2
  40. package/dist/superdoc/src/index.d.cts +0 -18
  41. package/dist/superdoc/src/index.d.ts +0 -14
@@ -1,6 +1,6 @@
1
1
  import { i as __toESM$2 } from "./chunks/rolldown-runtime-0pSA04fp.es.js";
2
2
  import { t as blank_default } from "./chunks/blank-docx-DzQccOlW.es.js";
3
- import { _ as getWorkflowRecording, a as registerFirstPartyCommandMutation, c as getV2TrackedChangeMutationImpact, d as resolveImageSrc, g as createInteractionHistory, h as closeInteractionHistory, i as readFirstPartyPageNumbers, l as isPlainObject$1, m as DOM_CLASS_NAMES, n as executeFirstPartyCommandAsync, p as isSyntheticTrackedChangeCommentLaneItem, r as executeFirstPartyShortcutAsync, s as applyV2CommentInvalidationFromMutation, t as createSuperDocUI, u as createImageFilePicker, v as isWorkflowRecordingEnabled, y as recordInteraction } from "./chunks/create-super-doc-ui-B29zw5qD.es.js";
3
+ import { _ as createInteractionHistory, a as registerFirstPartyCommandMutation, b as recordInteraction, c as applyV2CommentInvalidationFromMutation, d as createImageFilePicker, f as resolveImageSrc, g as closeInteractionHistory, h as DOM_CLASS_NAMES, i as readFirstPartyPageNumbers, l as getV2TrackedChangeMutationImpact, m as isSyntheticTrackedChangeCommentLaneItem, n as executeFirstPartyCommandAsync, o as isRecord, r as executeFirstPartyShortcutAsync, t as createSuperDocUI, u as isPlainObject$1, v as getWorkflowRecording, y as isWorkflowRecordingEnabled } from "./chunks/create-super-doc-ui-C4Ka5Ph3.es.js";
4
4
  import { t as import_eventemitter3 } from "./chunks/eventemitter3-DEIiXiH2.es.js";
5
5
  import { t as v4 } from "./chunks/uuid-H0Xcmmhy.es.js";
6
6
  import { $ as vModelText, A as onActivated, B as renderSlot, C as isRef$1, D as normalizeClass, E as nextTick, F as openBlock, G as toRaw$2, H as resolveDynamicComponent, I as provide$1, J as unref, K as toRef, L as reactive, M as onDeactivated, N as onMounted, O as normalizeProps, P as onScopeDispose$1, Q as vModelSelect, R as ref, S as isReactive$1, T as mergeProps, U as shallowRef$1, V as resolveDirective, W as toDisplayString, X as useSlots, Y as useAttrs, Z as vModelCheckbox, _ as getCurrentInstance, a as computed$1, b as hasInjectionContext, c as createCommentVNode, d as createStaticVNode, et as watch$1, f as createTextVNode, g as effectScope, h as defineComponent, i as Transition, it as withModifiers, j as onBeforeUnmount, k as normalizeStyle, l as createElementBlock, m as defineAsyncComponent, n as Fragment, nt as withDirectives, o as createApp, p as createVNode, q as toRefs, r as Teleport, rt as withKeys, s as createBlock, t as _plugin_vue_export_helper_default, tt as withCtx, u as createElementVNode, v as getCurrentScope, w as markRaw, x as inject$1, y as h, z as renderList } from "./chunks/_plugin-vue_export-helper-7ZiLY07t.es.js";
@@ -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.28.0-next.6";
261
+ return "2.28.0-next.7";
262
262
  } catch {
263
263
  return "unknown";
264
264
  }
@@ -7754,6 +7754,7 @@ var useCommentsStore = defineStore("comments", () => {
7754
7754
  const instantSidebarAlignmentInstanceId = ref(null);
7755
7755
  const pendingComment = ref(null);
7756
7756
  const pendingV2CommentTarget = shallowRef$1(null);
7757
+ let pendingCommentRequest = 0;
7757
7758
  const isViewingMode = computed$1(() => viewingVisibility.documentMode === "viewing");
7758
7759
  const shouldRenderReviewInViewing = computed$1(() => {
7759
7760
  if (!isViewingMode.value) return true;
@@ -7761,6 +7762,7 @@ var useCommentsStore = defineStore("comments", () => {
7761
7762
  });
7762
7763
  const v2CommentsAdapter = shallowRef$1(null);
7763
7764
  const setV2CommentsAdapter = (adapter) => {
7765
+ if (v2CommentsAdapter.value !== (adapter ?? null)) pendingCommentRequest += 1;
7764
7766
  v2CommentsAdapter.value = adapter ?? null;
7765
7767
  };
7766
7768
  const getV2CommentsAdapter = (superdoc) => {
@@ -8619,26 +8621,41 @@ var useCommentsStore = defineStore("comments", () => {
8619
8621
  }
8620
8622
  if (typeof currentSelection !== "function") return null;
8621
8623
  try {
8622
- return currentSelection();
8624
+ const snapshot = currentSelection();
8625
+ return typeof snapshot?.then === "function" ? Promise.resolve(snapshot).catch(() => null) : snapshot;
8623
8626
  } catch {
8624
8627
  return null;
8625
8628
  }
8626
8629
  };
8627
8630
  const showAddComment = (superdoc, targetClientY = null) => {
8631
+ const request = ++pendingCommentRequest;
8632
+ const editor = superdoc?.activeEditor;
8628
8633
  const v2Adapter = getV2CommentsAdapter(superdoc);
8629
- const pendingSelection = getPendingSelectionSnapshot(superdoc, superdocStore.activeSelection);
8630
- const event = {
8631
- type: COMMENT_EVENTS.PENDING,
8632
- pendingSelection
8634
+ const ownsRequest = () => pendingCommentRequest === request;
8635
+ const emitPending = (snapshot) => {
8636
+ if (!ownsRequest()) return;
8637
+ superdoc.emit("comments-update", {
8638
+ type: COMMENT_EVENTS.PENDING,
8639
+ pendingSelection: superdoc?.activeEditor === editor ? snapshot : null
8640
+ });
8633
8641
  };
8634
- superdoc.emit("comments-update", event);
8635
8642
  if (v2Adapter) {
8636
8643
  const cap = v2Adapter.getCapabilityState?.();
8637
8644
  if (cap && cap.canWrite === false) return {
8638
8645
  ok: false,
8639
8646
  reason: cap.reason
8640
8647
  };
8641
- return Promise.resolve(v2Adapter.captureCurrentSelection?.()).then((capture) => {
8648
+ return Promise.resolve(v2Adapter.captureCurrentSelection?.({ beforeReady: (snapshot) => {
8649
+ if (superdoc?.activeEditor === editor && getV2CommentsAdapter(superdoc) === v2Adapter) emitPending(snapshot);
8650
+ } })).then((capture) => {
8651
+ if (!ownsRequest()) return {
8652
+ ok: false,
8653
+ reason: "pending-comment-superseded"
8654
+ };
8655
+ if (superdoc?.activeEditor !== editor || getV2CommentsAdapter(superdoc) !== v2Adapter) return {
8656
+ ok: false,
8657
+ reason: "document-replaced"
8658
+ };
8642
8659
  if (!capture?.ok) return {
8643
8660
  ok: false,
8644
8661
  reason: capture?.reason ?? "editing-range-required",
@@ -8667,25 +8684,52 @@ var useCommentsStore = defineStore("comments", () => {
8667
8684
  detail: err?.message ?? String(err)
8668
8685
  }));
8669
8686
  }
8670
- const selection = { ...superdocStore.activeSelection };
8671
- selection.selectionBounds = { ...selection.selectionBounds };
8672
- if (superdocStore.selectionPosition?.source && superdocStore.selectionPosition.source !== "pdf") superdocStore.selectionPosition.source = null;
8673
- pendingComment.value = getPendingComment({
8674
- selection,
8675
- documentId: selection.documentId,
8676
- parentCommentId: null
8677
- });
8678
- if (!superdoc.config.isInternal) pendingComment.value.isInternal = false;
8679
- if (superdoc.activeEditor?.commands) superdoc.activeEditor.commands.insertComment({
8680
- ...pendingComment.value.getValues(),
8681
- commentId: "pending",
8682
- skipEmit: true
8683
- });
8684
- if (pendingComment.value.selection.source === "document-editor" && superdocStore.selectionPosition) superdocStore.selectionPosition.source = DOCUMENT_EDITOR_SELECTION_SOURCE;
8685
- requestInstantSidebarAlignment(targetClientY, "pending");
8686
- setActiveFloatingCommentInstance(null);
8687
- activeComment.value = pendingComment.value.commentId;
8688
- return { ok: true };
8687
+ const pendingSelection = getPendingSelectionSnapshot(superdoc, superdocStore.activeSelection);
8688
+ const asyncSnapshot = typeof pendingSelection?.then === "function";
8689
+ if (!asyncSnapshot) emitPending(pendingSelection);
8690
+ const showLegacyPending = (selection) => {
8691
+ selection.selectionBounds = { ...selection.selectionBounds };
8692
+ if (superdocStore.selectionPosition?.source && superdocStore.selectionPosition.source !== "pdf") superdocStore.selectionPosition.source = null;
8693
+ pendingComment.value = getPendingComment({
8694
+ selection,
8695
+ documentId: selection.documentId,
8696
+ parentCommentId: null
8697
+ });
8698
+ if (!superdoc.config.isInternal) pendingComment.value.isInternal = false;
8699
+ if (superdoc.activeEditor?.commands) superdoc.activeEditor.commands.insertComment({
8700
+ ...pendingComment.value.getValues(),
8701
+ commentId: "pending",
8702
+ skipEmit: true
8703
+ });
8704
+ if (pendingComment.value.selection.source === "document-editor" && superdocStore.selectionPosition) superdocStore.selectionPosition.source = DOCUMENT_EDITOR_SELECTION_SOURCE;
8705
+ requestInstantSidebarAlignment(targetClientY, "pending");
8706
+ setActiveFloatingCommentInstance(null);
8707
+ activeComment.value = pendingComment.value.commentId;
8708
+ return { ok: true };
8709
+ };
8710
+ if (asyncSnapshot) {
8711
+ const selection = { ...superdocStore.activeSelection };
8712
+ selection.selectionBounds = { ...selection.selectionBounds };
8713
+ return pendingSelection.then((snapshot) => {
8714
+ if (!ownsRequest()) return {
8715
+ ok: false,
8716
+ reason: "pending-comment-superseded"
8717
+ };
8718
+ emitPending(snapshot);
8719
+ if (!ownsRequest()) return {
8720
+ ok: false,
8721
+ reason: "pending-comment-superseded"
8722
+ };
8723
+ return superdoc?.activeEditor === editor ? showLegacyPending(selection) : {
8724
+ ok: false,
8725
+ reason: "document-replaced"
8726
+ };
8727
+ });
8728
+ }
8729
+ return ownsRequest() ? showLegacyPending({ ...superdocStore.activeSelection }) : {
8730
+ ok: false,
8731
+ reason: "pending-comment-superseded"
8732
+ };
8689
8733
  };
8690
8734
  /**
8691
8735
  * Get the numeric position value for sorting a comment by document order.
@@ -8840,7 +8884,7 @@ var useCommentsStore = defineStore("comments", () => {
8840
8884
  *
8841
8885
  * @returns {void}
8842
8886
  */
8843
- const removePendingComment = (superdoc) => {
8887
+ const resetPendingCommentState = (superdoc, clearViewingSelection = true) => {
8844
8888
  const hadPending = !!pendingComment.value;
8845
8889
  currentCommentText.value = "";
8846
8890
  currentCommentMentions.value = [];
@@ -8849,13 +8893,17 @@ var useCommentsStore = defineStore("comments", () => {
8849
8893
  superdocStore.selectionPosition = null;
8850
8894
  if (hadPending) clearActiveCommentSelection();
8851
8895
  if (isV2EditorActive(superdoc)) {
8852
- if (hadPending && isViewingMode.value) try {
8896
+ if (hadPending && clearViewingSelection && isViewingMode.value) try {
8853
8897
  superdoc?.activeEditor?.host?.getHandles?.()?.selection?.clear?.();
8854
8898
  } catch {}
8855
8899
  return;
8856
8900
  }
8857
8901
  superdoc?.activeEditor?.commands?.removeComment({ commentId: "pending" });
8858
8902
  };
8903
+ const removePendingComment = (superdoc) => {
8904
+ pendingCommentRequest += 1;
8905
+ resetPendingCommentState(superdoc);
8906
+ };
8859
8907
  const getV2CreatedComment = ({ outcome, reconciled, documentId }) => {
8860
8908
  const createdId = normalizeCommentId(outcome?.createdCommentId);
8861
8909
  if (!createdId) return reconciled?.added ?? null;
@@ -8873,6 +8921,7 @@ var useCommentsStore = defineStore("comments", () => {
8873
8921
  const v2Adapter = !skipEditorUpdate && !isHydration ? getV2CommentsAdapter(superdoc) : null;
8874
8922
  if (v2Adapter && !comment.trackedChange) {
8875
8923
  const submittedPendingComment = pendingComment.value;
8924
+ const submittedPendingRequest = pendingCommentRequest;
8876
8925
  const text = normalizeV2CommentDraftText(submittedPendingComment ? currentCommentText.value : comment.commentText);
8877
8926
  const mentions = pendingComment.value ? currentCommentMentions.value : comment.mentions ?? [];
8878
8927
  const target = pendingComment.value ? pendingV2CommentTarget.value : null;
@@ -8921,9 +8970,11 @@ var useCommentsStore = defineStore("comments", () => {
8921
8970
  documentId: v2Adapter.documentId
8922
8971
  });
8923
8972
  const hadPendingComment = submittedPendingComment != null && pendingComment.value?.commentId === submittedPendingComment.commentId;
8924
- if (hadPendingComment) removePendingComment(superdoc);
8973
+ const ownsSubmittedRequest = pendingCommentRequest === submittedPendingRequest;
8974
+ if (hadPendingComment) if (ownsSubmittedRequest) removePendingComment(superdoc);
8975
+ else resetPendingCommentState(superdoc, false);
8925
8976
  const createdId = created?.commentId ?? null;
8926
- if (hadPendingComment && createdId) {
8977
+ if (hadPendingComment && ownsSubmittedRequest && createdId) {
8927
8978
  setActiveComment(superdoc, createdId);
8928
8979
  setActiveFloatingCommentInstance(createdId);
8929
8980
  }
@@ -13514,6 +13565,7 @@ var CommentDialog_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
13514
13565
  };
13515
13566
  };
13516
13567
  const CLICK_OUTSIDE_IGNORED_SELECTORS = [
13568
+ ".superdoc__tools [data-id=\"is-tool\"]",
13517
13569
  ".comments-dropdown__option-label",
13518
13570
  ".comments-dropdown__menu",
13519
13571
  ".comments-dropdown__option",
@@ -14635,7 +14687,7 @@ var CommentDialog_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
14635
14687
  ], 64))], 14, _hoisted_1$26)), [[_directive_click_outside, handleClickOutside]]);
14636
14688
  };
14637
14689
  }
14638
- }, [["__scopeId", "data-v-05d27982"]]);
14690
+ }, [["__scopeId", "data-v-f8b79c74"]]);
14639
14691
  //#endregion
14640
14692
  //#region src/components/CommentsLayer/commentsList/ReviewDirectoryListItem.vue
14641
14693
  var _hoisted_1$25 = [
@@ -15358,6 +15410,80 @@ var composeAuthorColorResolver = (config) => {
15358
15410
  };
15359
15411
  };
15360
15412
  //#endregion
15413
+ //#region ../document-api/src/errors.ts
15414
+ /**
15415
+ * Structured validation error thrown by document-api execute* functions.
15416
+ *
15417
+ * Consumers should prefer checking `error.code` over `instanceof` for resilience
15418
+ * across package boundaries and bundling scenarios.
15419
+ */
15420
+ var DocumentApiValidationError = class DocumentApiValidationError extends Error {
15421
+ constructor(code, message, details) {
15422
+ super(message);
15423
+ this.name = "DocumentApiValidationError";
15424
+ this.code = code;
15425
+ this.details = details;
15426
+ Object.setPrototypeOf(this, DocumentApiValidationError.prototype);
15427
+ }
15428
+ };
15429
+ //#endregion
15430
+ //#region ../document-api/src/export/export.types.ts
15431
+ /** Canonical tracked-change export modes accepted by every public export surface. */
15432
+ var SD_EXPORT_MODES = [
15433
+ "review-preserving",
15434
+ "final",
15435
+ "original"
15436
+ ];
15437
+ /** Default mode for modeful DOCX export. */
15438
+ var DEFAULT_SD_EXPORT_MODE = "review-preserving";
15439
+ var SD_COMMENT_EXPORT_POLICIES = [
15440
+ "preserve",
15441
+ "resolve",
15442
+ "remove"
15443
+ ];
15444
+ var SD_CONTENT_CONTROL_EXPORT_POLICIES = ["preserve", "flatten"];
15445
+ //#endregion
15446
+ //#region ../document-api/src/export/export.ts
15447
+ /**
15448
+ * Export namespace: engine-agnostic public API and adapter contract.
15449
+ *
15450
+ * Validates the requested mode at the public boundary so an invalid mode fails
15451
+ * closed with `INVALID_INPUT` before any document work happens, then delegates
15452
+ * byte production and degradation reporting to the engine adapter.
15453
+ */
15454
+ function resolveMode$1(input) {
15455
+ if (input != null && !isRecord(input)) throw new DocumentApiValidationError("INVALID_INPUT", "export.toDocx input must be an object.");
15456
+ const raw = input?.mode;
15457
+ if (raw === void 0) return DEFAULT_SD_EXPORT_MODE;
15458
+ 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(", ")}.`, {
15459
+ mode: raw,
15460
+ allowedModes: [...SD_EXPORT_MODES]
15461
+ });
15462
+ return raw;
15463
+ }
15464
+ function resolveDocxExportPolicies(input = {}) {
15465
+ if (!isRecord(input)) throw new DocumentApiValidationError("INVALID_INPUT", "DOCX export input must be an object.");
15466
+ const mode = resolveMode$1(input);
15467
+ const policies = input.policies;
15468
+ if (policies !== void 0 && !isRecord(policies)) throw new DocumentApiValidationError("INVALID_INPUT", "DOCX export policies must be an object.");
15469
+ const allowed = {
15470
+ trackedChanges: SD_EXPORT_MODES,
15471
+ comments: SD_COMMENT_EXPORT_POLICIES,
15472
+ contentControls: SD_CONTENT_CONTROL_EXPORT_POLICIES
15473
+ };
15474
+ 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}.`, {
15475
+ policy: key,
15476
+ value
15477
+ });
15478
+ const requested = policies;
15479
+ if (input.mode !== void 0 && requested?.trackedChanges !== void 0 && mode !== requested.trackedChanges) throw new DocumentApiValidationError("INVALID_INPUT", "mode conflicts with policies.trackedChanges.");
15480
+ return {
15481
+ trackedChanges: requested?.trackedChanges ?? mode,
15482
+ comments: requested?.comments ?? "preserve",
15483
+ contentControls: requested?.contentControls ?? "preserve"
15484
+ };
15485
+ }
15486
+ //#endregion
15361
15487
  //#region ../document-api/src/permission-ranges/permission-ranges.ts
15362
15488
  function editorKey(editor) {
15363
15489
  return editor.id?.trim() ? editor.id : editor.email?.trim() || void 0;
@@ -20095,6 +20221,28 @@ function useLinkPopover({ getSurfaceManager, getActiveEditor, getUi, getActivati
20095
20221
  };
20096
20222
  }
20097
20223
  //#endregion
20224
+ //#region src/core/helpers/resolve-docx-export.ts
20225
+ function resolveV2DocxExportOptions(options = {}) {
20226
+ const policies = resolveDocxExportPolicies({ policies: options.policies });
20227
+ if (options.isFinalDoc !== void 0) {
20228
+ if (typeof options.isFinalDoc !== "boolean") throw new DocumentApiValidationError("INVALID_INPUT", "isFinalDoc must be a boolean.");
20229
+ const legacy = options.isFinalDoc ? "final" : "review-preserving";
20230
+ if (options.policies?.trackedChanges !== void 0 && policies.trackedChanges !== legacy) throw new DocumentApiValidationError("INVALID_INPUT", "isFinalDoc conflicts with policies.trackedChanges.");
20231
+ policies.trackedChanges = legacy;
20232
+ }
20233
+ if (options.commentsType !== void 0) {
20234
+ if (options.commentsType !== "external" && options.commentsType !== "clean") throw new DocumentApiValidationError("INVALID_INPUT", "commentsType must be external or clean.");
20235
+ const legacy = options.commentsType === "clean" ? "remove" : "preserve";
20236
+ if (options.policies?.comments !== void 0 && policies.comments !== legacy) throw new DocumentApiValidationError("INVALID_INPUT", "commentsType conflicts with policies.comments.");
20237
+ policies.comments = legacy;
20238
+ }
20239
+ return {
20240
+ mode: policies.trackedChanges,
20241
+ commentExportMode: policies.comments === "remove" ? "strip" : policies.comments,
20242
+ contentControlExportMode: policies.contentControls
20243
+ };
20244
+ }
20245
+ //#endregion
20098
20246
  //#region src/core/editor-runtime/v2/v2-editor-runtime-adapter.ts
20099
20247
  var DEFAULT_V2_LEGACY_PROJECTION = Object.freeze({
20100
20248
  editorVersion: 2,
@@ -20734,7 +20882,7 @@ function createV2EditorRuntimeAdapter(options) {
20734
20882
  save: () => host.save(),
20735
20883
  exportDocx: (options) => host.save({
20736
20884
  format: "docx",
20737
- commentExportMode: options?.commentsType === "clean" ? "strip" : "preserve"
20885
+ ...resolveV2DocxExportOptions(options)
20738
20886
  }),
20739
20887
  async setZoom(percent) {
20740
20888
  const result = host.setZoom(percent);
@@ -22127,6 +22275,10 @@ var SuperDoc_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
22127
22275
  return layers.value.getBoundingClientRect().top + top * zoom;
22128
22276
  };
22129
22277
  const handleCommentToolClick = async () => {
22278
+ if (isV2Mode.value) {
22279
+ cancelScheduledV2DomSelectionSync();
22280
+ if (applyCurrentV2DomSelection()?.ok === false) return;
22281
+ }
22130
22282
  if ((await showAddComment(proxy.$superdoc, getPendingCommentTargetClientY()))?.ok === false) return;
22131
22283
  if (!isV2Mode.value) return;
22132
22284
  const pendingPosition = buildV2PendingPositionEntry();
@@ -22399,10 +22551,9 @@ var SuperDoc_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
22399
22551
  return host.save(saveOptions);
22400
22552
  });
22401
22553
  const exportV2Docx = async (options = {}) => {
22402
- const commentExportMode = options?.commentsType === "clean" ? "strip" : "preserve";
22403
22554
  const bytes = await saveV2Bytes({
22404
22555
  format: "docx",
22405
- commentExportMode
22556
+ ...resolveV2DocxExportOptions(options)
22406
22557
  });
22407
22558
  return new Blob([bytes], { type: DOCX });
22408
22559
  };
@@ -22677,6 +22828,9 @@ var SuperDoc_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
22677
22828
  subscribe: (listener) => v2ReviewWindowController.subscribe?.(listener) ?? (() => void 0)
22678
22829
  },
22679
22830
  extensions: createV2ExtensionsFacet(host),
22831
+ get visuals() {
22832
+ return typeof host?.getHostVisuals === "function" ? host.getHostVisuals() : null;
22833
+ },
22680
22834
  fonts: fonts ?? host?.getFontRuntime?.() ?? null,
22681
22835
  /**
22682
22836
  * The v2 active-editor facade explicitly does NOT carry v1 commands /
@@ -22842,7 +22996,7 @@ var SuperDoc_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
22842
22996
  const result = handles?.selection?.applyDomSelection?.(selection);
22843
22997
  if (!result?.ok || result.mode !== "range") {
22844
22998
  clearV2SelectionToolbarState();
22845
- return;
22999
+ return { ok: false };
22846
23000
  }
22847
23001
  v2DomMirroredRange.value = true;
22848
23002
  v2HasRangeSelection.value = true;
@@ -24549,7 +24703,7 @@ var SuperDoc_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
24549
24703
  ], 46, _hoisted_1$17);
24550
24704
  };
24551
24705
  }
24552
- }, [["__scopeId", "data-v-2fc1721f"]]);
24706
+ }, [["__scopeId", "data-v-0f22e103"]]);
24553
24707
  //#endregion
24554
24708
  //#region src/core/create-app.js
24555
24709
  var PINIA_DEVTOOLS_SETUP_EVENT = "devtools-plugin:setup";
@@ -46246,7 +46400,7 @@ var SuperDoc = class extends import_eventemitter3.default {
46246
46400
  }
46247
46401
  this.userColorMap = /* @__PURE__ */ new Map();
46248
46402
  this.colorIndex = 0;
46249
- this.version = "2.28.0-next.6";
46403
+ this.version = "2.28.0-next.7";
46250
46404
  this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
46251
46405
  this.superdocId = config.superdocId || v4();
46252
46406
  this.colors = this.config.colors ?? [];
@@ -48200,12 +48354,13 @@ var SuperDoc = class extends import_eventemitter3.default {
48200
48354
  * Export the superdoc to a file
48201
48355
  * @param params - Export configuration
48202
48356
  */
48203
- async export({ exportType = ["docx"], commentsType = "external", exportedName, additionalFiles = [], additionalFileNames = [], isFinalDoc = false, triggerDownload = true, fieldsHighlightColor = null } = {}) {
48357
+ async export({ exportType = ["docx"], commentsType, exportedName, additionalFiles = [], additionalFileNames = [], isFinalDoc, policies, triggerDownload = true, fieldsHighlightColor = null } = {}) {
48204
48358
  if (!Array.isArray(exportType) || exportType.length !== 1 || exportType[0] !== "docx") throw new TypeError("SuperDoc.export() only supports exportType: [\"docx\"].");
48205
48359
  const baseFileName = exportedName ? cleanName(exportedName) : cleanName(this.config.title);
48206
48360
  const docxFiles = await this.exportEditorsToDOCX({
48207
48361
  commentsType,
48208
48362
  isFinalDoc,
48363
+ policies,
48209
48364
  fieldsHighlightColor
48210
48365
  });
48211
48366
  const blobsToZip = [...additionalFiles];
@@ -48291,7 +48446,12 @@ var SuperDoc = class extends import_eventemitter3.default {
48291
48446
  * Export editors to DOCX format.
48292
48447
  * @param [options]
48293
48448
  */
48294
- async exportEditorsToDOCX({ commentsType, isFinalDoc, fieldsHighlightColor } = {}) {
48449
+ async exportEditorsToDOCX({ commentsType, isFinalDoc, policies, fieldsHighlightColor } = {}) {
48450
+ if (policies !== void 0) resolveV2DocxExportOptions({
48451
+ policies,
48452
+ commentsType,
48453
+ isFinalDoc
48454
+ });
48295
48455
  const uiStoreHydrated = this.config?.modules?.comments !== false;
48296
48456
  let legacyComments;
48297
48457
  let legacyCommentsComputed = false;
@@ -48311,7 +48471,13 @@ var SuperDoc = class extends import_eventemitter3.default {
48311
48471
  };
48312
48472
  this.on("exception", rememberBridgedExportError);
48313
48473
  try {
48314
- const docxPromises = this.#requireSuperdocStore("exportEditorsToDOCX").documents.map(async (doc) => {
48474
+ const documents = this.#requireSuperdocStore("exportEditorsToDOCX").documents;
48475
+ if (policies !== void 0 && documents.some((doc) => {
48476
+ if (doc.type !== "application/vnd.openxmlformats-officedocument.wordprocessingml.document") return false;
48477
+ const editor = doc.getEditor?.();
48478
+ return editor?.editorVersion !== 2 || typeof editor.exportDocx !== "function";
48479
+ })) throw new Error("Independent DOCX export policies require a mounted V2 exporter for every document.");
48480
+ const docxPromises = documents.map(async (doc) => {
48315
48481
  if (!doc || doc.type !== "application/vnd.openxmlformats-officedocument.wordprocessingml.document") return null;
48316
48482
  const editor = typeof doc.getEditor === "function" ? doc.getEditor() : null;
48317
48483
  const fallbackDocx = () => {
@@ -48328,6 +48494,7 @@ var SuperDoc = class extends import_eventemitter3.default {
48328
48494
  const exported = await editor.exportDocx(isV2Editor ? {
48329
48495
  isFinalDoc,
48330
48496
  commentsType,
48497
+ policies,
48331
48498
  fieldsHighlightColor
48332
48499
  } : {
48333
48500
  isFinalDoc,
@@ -48656,4 +48823,8 @@ function defineSuperDocExtension(extension) {
48656
48823
  return extension;
48657
48824
  }
48658
48825
  //#endregion
48659
- export { blank_default as BlankDOCX, DOCX, DocumentLoadError, HTML, PDF, SuperDoc, buildTheme, compareVersions, createTheme, defineSuperDocExtension, getFileObject, listPermissionRangeEditors, resolvePermissionRangeEditor };
48826
+ //#region src/public/index.ts
48827
+ /** URL to the blank DOCX template. */
48828
+ var BlankDOCX = blank_default;
48829
+ //#endregion
48830
+ export { BlankDOCX, DOCX, DocumentLoadError, HTML, PDF, SuperDoc, buildTheme, compareVersions, createTheme, defineSuperDocExtension, getFileObject, listPermissionRangeEditors, resolvePermissionRangeEditor };