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
package/dist/superdoc.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_rolldown_runtime = require("./chunks/rolldown-runtime-74VwNCz7.cjs");
3
3
  const require_blank_docx = require("./chunks/blank-docx-BuFAbRjs.cjs");
4
- const require_create_super_doc_ui = require("./chunks/create-super-doc-ui-D1eOhAjv.cjs");
4
+ const require_create_super_doc_ui = require("./chunks/create-super-doc-ui-B4c55pFy.cjs");
5
5
  const require_eventemitter3 = require("./chunks/eventemitter3-C_TAnXOl.cjs");
6
6
  const require_uuid = require("./chunks/uuid-BhG0ngwk.cjs");
7
7
  const require__plugin_vue_export_helper = require("./chunks/_plugin-vue_export-helper-BUdjGKyl.cjs");
@@ -260,7 +260,7 @@ var v_click_outside_default = {
260
260
  var DEFAULT_ENDPOINT = "https://ingest.superdoc.dev/v1/collect";
261
261
  function getSuperdocVersion() {
262
262
  try {
263
- return "2.28.0-next.6";
263
+ return "2.28.0-next.7";
264
264
  } catch {
265
265
  return "unknown";
266
266
  }
@@ -7756,6 +7756,7 @@ var useCommentsStore = defineStore("comments", () => {
7756
7756
  const instantSidebarAlignmentInstanceId = require__plugin_vue_export_helper.ref(null);
7757
7757
  const pendingComment = require__plugin_vue_export_helper.ref(null);
7758
7758
  const pendingV2CommentTarget = require__plugin_vue_export_helper.shallowRef(null);
7759
+ let pendingCommentRequest = 0;
7759
7760
  const isViewingMode = require__plugin_vue_export_helper.computed(() => viewingVisibility.documentMode === "viewing");
7760
7761
  const shouldRenderReviewInViewing = require__plugin_vue_export_helper.computed(() => {
7761
7762
  if (!isViewingMode.value) return true;
@@ -7763,6 +7764,7 @@ var useCommentsStore = defineStore("comments", () => {
7763
7764
  });
7764
7765
  const v2CommentsAdapter = require__plugin_vue_export_helper.shallowRef(null);
7765
7766
  const setV2CommentsAdapter = (adapter) => {
7767
+ if (v2CommentsAdapter.value !== (adapter ?? null)) pendingCommentRequest += 1;
7766
7768
  v2CommentsAdapter.value = adapter ?? null;
7767
7769
  };
7768
7770
  const getV2CommentsAdapter = (superdoc) => {
@@ -8621,26 +8623,41 @@ var useCommentsStore = defineStore("comments", () => {
8621
8623
  }
8622
8624
  if (typeof currentSelection !== "function") return null;
8623
8625
  try {
8624
- return currentSelection();
8626
+ const snapshot = currentSelection();
8627
+ return typeof snapshot?.then === "function" ? Promise.resolve(snapshot).catch(() => null) : snapshot;
8625
8628
  } catch {
8626
8629
  return null;
8627
8630
  }
8628
8631
  };
8629
8632
  const showAddComment = (superdoc, targetClientY = null) => {
8633
+ const request = ++pendingCommentRequest;
8634
+ const editor = superdoc?.activeEditor;
8630
8635
  const v2Adapter = getV2CommentsAdapter(superdoc);
8631
- const pendingSelection = getPendingSelectionSnapshot(superdoc, superdocStore.activeSelection);
8632
- const event = {
8633
- type: COMMENT_EVENTS.PENDING,
8634
- pendingSelection
8636
+ const ownsRequest = () => pendingCommentRequest === request;
8637
+ const emitPending = (snapshot) => {
8638
+ if (!ownsRequest()) return;
8639
+ superdoc.emit("comments-update", {
8640
+ type: COMMENT_EVENTS.PENDING,
8641
+ pendingSelection: superdoc?.activeEditor === editor ? snapshot : null
8642
+ });
8635
8643
  };
8636
- superdoc.emit("comments-update", event);
8637
8644
  if (v2Adapter) {
8638
8645
  const cap = v2Adapter.getCapabilityState?.();
8639
8646
  if (cap && cap.canWrite === false) return {
8640
8647
  ok: false,
8641
8648
  reason: cap.reason
8642
8649
  };
8643
- return Promise.resolve(v2Adapter.captureCurrentSelection?.()).then((capture) => {
8650
+ return Promise.resolve(v2Adapter.captureCurrentSelection?.({ beforeReady: (snapshot) => {
8651
+ if (superdoc?.activeEditor === editor && getV2CommentsAdapter(superdoc) === v2Adapter) emitPending(snapshot);
8652
+ } })).then((capture) => {
8653
+ if (!ownsRequest()) return {
8654
+ ok: false,
8655
+ reason: "pending-comment-superseded"
8656
+ };
8657
+ if (superdoc?.activeEditor !== editor || getV2CommentsAdapter(superdoc) !== v2Adapter) return {
8658
+ ok: false,
8659
+ reason: "document-replaced"
8660
+ };
8644
8661
  if (!capture?.ok) return {
8645
8662
  ok: false,
8646
8663
  reason: capture?.reason ?? "editing-range-required",
@@ -8669,25 +8686,52 @@ var useCommentsStore = defineStore("comments", () => {
8669
8686
  detail: err?.message ?? String(err)
8670
8687
  }));
8671
8688
  }
8672
- const selection = { ...superdocStore.activeSelection };
8673
- selection.selectionBounds = { ...selection.selectionBounds };
8674
- if (superdocStore.selectionPosition?.source && superdocStore.selectionPosition.source !== "pdf") superdocStore.selectionPosition.source = null;
8675
- pendingComment.value = getPendingComment({
8676
- selection,
8677
- documentId: selection.documentId,
8678
- parentCommentId: null
8679
- });
8680
- if (!superdoc.config.isInternal) pendingComment.value.isInternal = false;
8681
- if (superdoc.activeEditor?.commands) superdoc.activeEditor.commands.insertComment({
8682
- ...pendingComment.value.getValues(),
8683
- commentId: "pending",
8684
- skipEmit: true
8685
- });
8686
- if (pendingComment.value.selection.source === "document-editor" && superdocStore.selectionPosition) superdocStore.selectionPosition.source = DOCUMENT_EDITOR_SELECTION_SOURCE;
8687
- requestInstantSidebarAlignment(targetClientY, "pending");
8688
- setActiveFloatingCommentInstance(null);
8689
- activeComment.value = pendingComment.value.commentId;
8690
- return { ok: true };
8689
+ const pendingSelection = getPendingSelectionSnapshot(superdoc, superdocStore.activeSelection);
8690
+ const asyncSnapshot = typeof pendingSelection?.then === "function";
8691
+ if (!asyncSnapshot) emitPending(pendingSelection);
8692
+ const showLegacyPending = (selection) => {
8693
+ selection.selectionBounds = { ...selection.selectionBounds };
8694
+ if (superdocStore.selectionPosition?.source && superdocStore.selectionPosition.source !== "pdf") superdocStore.selectionPosition.source = null;
8695
+ pendingComment.value = getPendingComment({
8696
+ selection,
8697
+ documentId: selection.documentId,
8698
+ parentCommentId: null
8699
+ });
8700
+ if (!superdoc.config.isInternal) pendingComment.value.isInternal = false;
8701
+ if (superdoc.activeEditor?.commands) superdoc.activeEditor.commands.insertComment({
8702
+ ...pendingComment.value.getValues(),
8703
+ commentId: "pending",
8704
+ skipEmit: true
8705
+ });
8706
+ if (pendingComment.value.selection.source === "document-editor" && superdocStore.selectionPosition) superdocStore.selectionPosition.source = DOCUMENT_EDITOR_SELECTION_SOURCE;
8707
+ requestInstantSidebarAlignment(targetClientY, "pending");
8708
+ setActiveFloatingCommentInstance(null);
8709
+ activeComment.value = pendingComment.value.commentId;
8710
+ return { ok: true };
8711
+ };
8712
+ if (asyncSnapshot) {
8713
+ const selection = { ...superdocStore.activeSelection };
8714
+ selection.selectionBounds = { ...selection.selectionBounds };
8715
+ return pendingSelection.then((snapshot) => {
8716
+ if (!ownsRequest()) return {
8717
+ ok: false,
8718
+ reason: "pending-comment-superseded"
8719
+ };
8720
+ emitPending(snapshot);
8721
+ if (!ownsRequest()) return {
8722
+ ok: false,
8723
+ reason: "pending-comment-superseded"
8724
+ };
8725
+ return superdoc?.activeEditor === editor ? showLegacyPending(selection) : {
8726
+ ok: false,
8727
+ reason: "document-replaced"
8728
+ };
8729
+ });
8730
+ }
8731
+ return ownsRequest() ? showLegacyPending({ ...superdocStore.activeSelection }) : {
8732
+ ok: false,
8733
+ reason: "pending-comment-superseded"
8734
+ };
8691
8735
  };
8692
8736
  /**
8693
8737
  * Get the numeric position value for sorting a comment by document order.
@@ -8842,7 +8886,7 @@ var useCommentsStore = defineStore("comments", () => {
8842
8886
  *
8843
8887
  * @returns {void}
8844
8888
  */
8845
- const removePendingComment = (superdoc) => {
8889
+ const resetPendingCommentState = (superdoc, clearViewingSelection = true) => {
8846
8890
  const hadPending = !!pendingComment.value;
8847
8891
  currentCommentText.value = "";
8848
8892
  currentCommentMentions.value = [];
@@ -8851,13 +8895,17 @@ var useCommentsStore = defineStore("comments", () => {
8851
8895
  superdocStore.selectionPosition = null;
8852
8896
  if (hadPending) clearActiveCommentSelection();
8853
8897
  if (isV2EditorActive(superdoc)) {
8854
- if (hadPending && isViewingMode.value) try {
8898
+ if (hadPending && clearViewingSelection && isViewingMode.value) try {
8855
8899
  superdoc?.activeEditor?.host?.getHandles?.()?.selection?.clear?.();
8856
8900
  } catch {}
8857
8901
  return;
8858
8902
  }
8859
8903
  superdoc?.activeEditor?.commands?.removeComment({ commentId: "pending" });
8860
8904
  };
8905
+ const removePendingComment = (superdoc) => {
8906
+ pendingCommentRequest += 1;
8907
+ resetPendingCommentState(superdoc);
8908
+ };
8861
8909
  const getV2CreatedComment = ({ outcome, reconciled, documentId }) => {
8862
8910
  const createdId = normalizeCommentId(outcome?.createdCommentId);
8863
8911
  if (!createdId) return reconciled?.added ?? null;
@@ -8875,6 +8923,7 @@ var useCommentsStore = defineStore("comments", () => {
8875
8923
  const v2Adapter = !skipEditorUpdate && !isHydration ? getV2CommentsAdapter(superdoc) : null;
8876
8924
  if (v2Adapter && !comment.trackedChange) {
8877
8925
  const submittedPendingComment = pendingComment.value;
8926
+ const submittedPendingRequest = pendingCommentRequest;
8878
8927
  const text = normalizeV2CommentDraftText(submittedPendingComment ? currentCommentText.value : comment.commentText);
8879
8928
  const mentions = pendingComment.value ? currentCommentMentions.value : comment.mentions ?? [];
8880
8929
  const target = pendingComment.value ? pendingV2CommentTarget.value : null;
@@ -8923,9 +8972,11 @@ var useCommentsStore = defineStore("comments", () => {
8923
8972
  documentId: v2Adapter.documentId
8924
8973
  });
8925
8974
  const hadPendingComment = submittedPendingComment != null && pendingComment.value?.commentId === submittedPendingComment.commentId;
8926
- if (hadPendingComment) removePendingComment(superdoc);
8975
+ const ownsSubmittedRequest = pendingCommentRequest === submittedPendingRequest;
8976
+ if (hadPendingComment) if (ownsSubmittedRequest) removePendingComment(superdoc);
8977
+ else resetPendingCommentState(superdoc, false);
8927
8978
  const createdId = created?.commentId ?? null;
8928
- if (hadPendingComment && createdId) {
8979
+ if (hadPendingComment && ownsSubmittedRequest && createdId) {
8929
8980
  setActiveComment(superdoc, createdId);
8930
8981
  setActiveFloatingCommentInstance(createdId);
8931
8982
  }
@@ -13521,6 +13572,7 @@ var _sfc_main$33 = {
13521
13572
  };
13522
13573
  };
13523
13574
  const CLICK_OUTSIDE_IGNORED_SELECTORS = [
13575
+ ".superdoc__tools [data-id=\"is-tool\"]",
13524
13576
  ".comments-dropdown__option-label",
13525
13577
  ".comments-dropdown__menu",
13526
13578
  ".comments-dropdown__option",
@@ -14643,7 +14695,7 @@ var _sfc_main$33 = {
14643
14695
  };
14644
14696
  }
14645
14697
  };
14646
- var CommentDialog_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$33, [["__scopeId", "data-v-05d27982"]]);
14698
+ var CommentDialog_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$33, [["__scopeId", "data-v-f8b79c74"]]);
14647
14699
  //#endregion
14648
14700
  //#region src/components/CommentsLayer/commentsList/ReviewDirectoryListItem.vue
14649
14701
  var _hoisted_1$25 = [
@@ -15368,6 +15420,80 @@ var composeAuthorColorResolver = (config) => {
15368
15420
  };
15369
15421
  };
15370
15422
  //#endregion
15423
+ //#region ../document-api/src/errors.ts
15424
+ /**
15425
+ * Structured validation error thrown by document-api execute* functions.
15426
+ *
15427
+ * Consumers should prefer checking `error.code` over `instanceof` for resilience
15428
+ * across package boundaries and bundling scenarios.
15429
+ */
15430
+ var DocumentApiValidationError = class DocumentApiValidationError extends Error {
15431
+ constructor(code, message, details) {
15432
+ super(message);
15433
+ this.name = "DocumentApiValidationError";
15434
+ this.code = code;
15435
+ this.details = details;
15436
+ Object.setPrototypeOf(this, DocumentApiValidationError.prototype);
15437
+ }
15438
+ };
15439
+ //#endregion
15440
+ //#region ../document-api/src/export/export.types.ts
15441
+ /** Canonical tracked-change export modes accepted by every public export surface. */
15442
+ var SD_EXPORT_MODES = [
15443
+ "review-preserving",
15444
+ "final",
15445
+ "original"
15446
+ ];
15447
+ /** Default mode for modeful DOCX export. */
15448
+ var DEFAULT_SD_EXPORT_MODE = "review-preserving";
15449
+ var SD_COMMENT_EXPORT_POLICIES = [
15450
+ "preserve",
15451
+ "resolve",
15452
+ "remove"
15453
+ ];
15454
+ var SD_CONTENT_CONTROL_EXPORT_POLICIES = ["preserve", "flatten"];
15455
+ //#endregion
15456
+ //#region ../document-api/src/export/export.ts
15457
+ /**
15458
+ * Export namespace: engine-agnostic public API and adapter contract.
15459
+ *
15460
+ * Validates the requested mode at the public boundary so an invalid mode fails
15461
+ * closed with `INVALID_INPUT` before any document work happens, then delegates
15462
+ * byte production and degradation reporting to the engine adapter.
15463
+ */
15464
+ function resolveMode$1(input) {
15465
+ if (input != null && !require_create_super_doc_ui.isRecord(input)) throw new DocumentApiValidationError("INVALID_INPUT", "export.toDocx input must be an object.");
15466
+ const raw = input?.mode;
15467
+ if (raw === void 0) return DEFAULT_SD_EXPORT_MODE;
15468
+ 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(", ")}.`, {
15469
+ mode: raw,
15470
+ allowedModes: [...SD_EXPORT_MODES]
15471
+ });
15472
+ return raw;
15473
+ }
15474
+ function resolveDocxExportPolicies(input = {}) {
15475
+ if (!require_create_super_doc_ui.isRecord(input)) throw new DocumentApiValidationError("INVALID_INPUT", "DOCX export input must be an object.");
15476
+ const mode = resolveMode$1(input);
15477
+ const policies = input.policies;
15478
+ if (policies !== void 0 && !require_create_super_doc_ui.isRecord(policies)) throw new DocumentApiValidationError("INVALID_INPUT", "DOCX export policies must be an object.");
15479
+ const allowed = {
15480
+ trackedChanges: SD_EXPORT_MODES,
15481
+ comments: SD_COMMENT_EXPORT_POLICIES,
15482
+ contentControls: SD_CONTENT_CONTROL_EXPORT_POLICIES
15483
+ };
15484
+ 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}.`, {
15485
+ policy: key,
15486
+ value
15487
+ });
15488
+ const requested = policies;
15489
+ if (input.mode !== void 0 && requested?.trackedChanges !== void 0 && mode !== requested.trackedChanges) throw new DocumentApiValidationError("INVALID_INPUT", "mode conflicts with policies.trackedChanges.");
15490
+ return {
15491
+ trackedChanges: requested?.trackedChanges ?? mode,
15492
+ comments: requested?.comments ?? "preserve",
15493
+ contentControls: requested?.contentControls ?? "preserve"
15494
+ };
15495
+ }
15496
+ //#endregion
15371
15497
  //#region ../document-api/src/permission-ranges/permission-ranges.ts
15372
15498
  function editorKey(editor) {
15373
15499
  return editor.id?.trim() ? editor.id : editor.email?.trim() || void 0;
@@ -20127,6 +20253,28 @@ function useLinkPopover({ getSurfaceManager, getActiveEditor, getUi, getActivati
20127
20253
  };
20128
20254
  }
20129
20255
  //#endregion
20256
+ //#region src/core/helpers/resolve-docx-export.ts
20257
+ function resolveV2DocxExportOptions(options = {}) {
20258
+ const policies = resolveDocxExportPolicies({ policies: options.policies });
20259
+ if (options.isFinalDoc !== void 0) {
20260
+ if (typeof options.isFinalDoc !== "boolean") throw new DocumentApiValidationError("INVALID_INPUT", "isFinalDoc must be a boolean.");
20261
+ const legacy = options.isFinalDoc ? "final" : "review-preserving";
20262
+ if (options.policies?.trackedChanges !== void 0 && policies.trackedChanges !== legacy) throw new DocumentApiValidationError("INVALID_INPUT", "isFinalDoc conflicts with policies.trackedChanges.");
20263
+ policies.trackedChanges = legacy;
20264
+ }
20265
+ if (options.commentsType !== void 0) {
20266
+ if (options.commentsType !== "external" && options.commentsType !== "clean") throw new DocumentApiValidationError("INVALID_INPUT", "commentsType must be external or clean.");
20267
+ const legacy = options.commentsType === "clean" ? "remove" : "preserve";
20268
+ if (options.policies?.comments !== void 0 && policies.comments !== legacy) throw new DocumentApiValidationError("INVALID_INPUT", "commentsType conflicts with policies.comments.");
20269
+ policies.comments = legacy;
20270
+ }
20271
+ return {
20272
+ mode: policies.trackedChanges,
20273
+ commentExportMode: policies.comments === "remove" ? "strip" : policies.comments,
20274
+ contentControlExportMode: policies.contentControls
20275
+ };
20276
+ }
20277
+ //#endregion
20130
20278
  //#region src/core/editor-runtime/v2/v2-editor-runtime-adapter.ts
20131
20279
  var DEFAULT_V2_LEGACY_PROJECTION = Object.freeze({
20132
20280
  editorVersion: 2,
@@ -20766,7 +20914,7 @@ function createV2EditorRuntimeAdapter(options) {
20766
20914
  save: () => host.save(),
20767
20915
  exportDocx: (options) => host.save({
20768
20916
  format: "docx",
20769
- commentExportMode: options?.commentsType === "clean" ? "strip" : "preserve"
20917
+ ...resolveV2DocxExportOptions(options)
20770
20918
  }),
20771
20919
  async setZoom(percent) {
20772
20920
  const result = host.setZoom(percent);
@@ -22167,6 +22315,10 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
22167
22315
  return layers.value.getBoundingClientRect().top + top * zoom;
22168
22316
  };
22169
22317
  const handleCommentToolClick = async () => {
22318
+ if (isV2Mode.value) {
22319
+ cancelScheduledV2DomSelectionSync();
22320
+ if (applyCurrentV2DomSelection()?.ok === false) return;
22321
+ }
22170
22322
  if ((await showAddComment(proxy.$superdoc, getPendingCommentTargetClientY()))?.ok === false) return;
22171
22323
  if (!isV2Mode.value) return;
22172
22324
  const pendingPosition = buildV2PendingPositionEntry();
@@ -22439,10 +22591,9 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
22439
22591
  return host.save(saveOptions);
22440
22592
  });
22441
22593
  const exportV2Docx = async (options = {}) => {
22442
- const commentExportMode = options?.commentsType === "clean" ? "strip" : "preserve";
22443
22594
  const bytes = await saveV2Bytes({
22444
22595
  format: "docx",
22445
- commentExportMode
22596
+ ...resolveV2DocxExportOptions(options)
22446
22597
  });
22447
22598
  return new Blob([bytes], { type: DOCX });
22448
22599
  };
@@ -22717,6 +22868,9 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
22717
22868
  subscribe: (listener) => v2ReviewWindowController.subscribe?.(listener) ?? (() => void 0)
22718
22869
  },
22719
22870
  extensions: createV2ExtensionsFacet(host),
22871
+ get visuals() {
22872
+ return typeof host?.getHostVisuals === "function" ? host.getHostVisuals() : null;
22873
+ },
22720
22874
  fonts: fonts ?? host?.getFontRuntime?.() ?? null,
22721
22875
  /**
22722
22876
  * The v2 active-editor facade explicitly does NOT carry v1 commands /
@@ -22882,7 +23036,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
22882
23036
  const result = handles?.selection?.applyDomSelection?.(selection);
22883
23037
  if (!result?.ok || result.mode !== "range") {
22884
23038
  clearV2SelectionToolbarState();
22885
- return;
23039
+ return { ok: false };
22886
23040
  }
22887
23041
  v2DomMirroredRange.value = true;
22888
23042
  v2HasRangeSelection.value = true;
@@ -24589,7 +24743,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
24589
24743
  ], 46, _hoisted_1$17);
24590
24744
  };
24591
24745
  }
24592
- }, [["__scopeId", "data-v-2fc1721f"]]);
24746
+ }, [["__scopeId", "data-v-0f22e103"]]);
24593
24747
  //#endregion
24594
24748
  //#region src/core/create-app.js
24595
24749
  var PINIA_DEVTOOLS_SETUP_EVENT = "devtools-plugin:setup";
@@ -46318,7 +46472,7 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
46318
46472
  }
46319
46473
  this.userColorMap = /* @__PURE__ */ new Map();
46320
46474
  this.colorIndex = 0;
46321
- this.version = "2.28.0-next.6";
46475
+ this.version = "2.28.0-next.7";
46322
46476
  this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
46323
46477
  this.superdocId = config.superdocId || require_uuid.v4();
46324
46478
  this.colors = this.config.colors ?? [];
@@ -48272,12 +48426,13 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
48272
48426
  * Export the superdoc to a file
48273
48427
  * @param params - Export configuration
48274
48428
  */
48275
- async export({ exportType = ["docx"], commentsType = "external", exportedName, additionalFiles = [], additionalFileNames = [], isFinalDoc = false, triggerDownload = true, fieldsHighlightColor = null } = {}) {
48429
+ async export({ exportType = ["docx"], commentsType, exportedName, additionalFiles = [], additionalFileNames = [], isFinalDoc, policies, triggerDownload = true, fieldsHighlightColor = null } = {}) {
48276
48430
  if (!Array.isArray(exportType) || exportType.length !== 1 || exportType[0] !== "docx") throw new TypeError("SuperDoc.export() only supports exportType: [\"docx\"].");
48277
48431
  const baseFileName = exportedName ? cleanName(exportedName) : cleanName(this.config.title);
48278
48432
  const docxFiles = await this.exportEditorsToDOCX({
48279
48433
  commentsType,
48280
48434
  isFinalDoc,
48435
+ policies,
48281
48436
  fieldsHighlightColor
48282
48437
  });
48283
48438
  const blobsToZip = [...additionalFiles];
@@ -48363,7 +48518,12 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
48363
48518
  * Export editors to DOCX format.
48364
48519
  * @param [options]
48365
48520
  */
48366
- async exportEditorsToDOCX({ commentsType, isFinalDoc, fieldsHighlightColor } = {}) {
48521
+ async exportEditorsToDOCX({ commentsType, isFinalDoc, policies, fieldsHighlightColor } = {}) {
48522
+ if (policies !== void 0) resolveV2DocxExportOptions({
48523
+ policies,
48524
+ commentsType,
48525
+ isFinalDoc
48526
+ });
48367
48527
  const uiStoreHydrated = this.config?.modules?.comments !== false;
48368
48528
  let legacyComments;
48369
48529
  let legacyCommentsComputed = false;
@@ -48383,7 +48543,13 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
48383
48543
  };
48384
48544
  this.on("exception", rememberBridgedExportError);
48385
48545
  try {
48386
- const docxPromises = this.#requireSuperdocStore("exportEditorsToDOCX").documents.map(async (doc) => {
48546
+ const documents = this.#requireSuperdocStore("exportEditorsToDOCX").documents;
48547
+ if (policies !== void 0 && documents.some((doc) => {
48548
+ if (doc.type !== "application/vnd.openxmlformats-officedocument.wordprocessingml.document") return false;
48549
+ const editor = doc.getEditor?.();
48550
+ return editor?.editorVersion !== 2 || typeof editor.exportDocx !== "function";
48551
+ })) throw new Error("Independent DOCX export policies require a mounted V2 exporter for every document.");
48552
+ const docxPromises = documents.map(async (doc) => {
48387
48553
  if (!doc || doc.type !== "application/vnd.openxmlformats-officedocument.wordprocessingml.document") return null;
48388
48554
  const editor = typeof doc.getEditor === "function" ? doc.getEditor() : null;
48389
48555
  const fallbackDocx = () => {
@@ -48400,6 +48566,7 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
48400
48566
  const exported = await editor.exportDocx(isV2Editor ? {
48401
48567
  isFinalDoc,
48402
48568
  commentsType,
48569
+ policies,
48403
48570
  fieldsHighlightColor
48404
48571
  } : {
48405
48572
  isFinalDoc,
@@ -48728,7 +48895,11 @@ function defineSuperDocExtension(extension) {
48728
48895
  return extension;
48729
48896
  }
48730
48897
  //#endregion
48731
- exports.BlankDOCX = require_blank_docx.blank_default;
48898
+ //#region src/public/index.ts
48899
+ /** URL to the blank DOCX template. */
48900
+ var BlankDOCX = require_blank_docx.blank_default;
48901
+ //#endregion
48902
+ exports.BlankDOCX = BlankDOCX;
48732
48903
  exports.DOCX = DOCX;
48733
48904
  exports.DocumentLoadError = DocumentLoadError;
48734
48905
  exports.HTML = HTML;