superdoc 2.28.0-next.6 → 2.28.0-next.8

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 (53) 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 +33 -33
  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/hyperlinks/hyperlinks.types.d.ts +2 -0
  13. package/dist/document-api/src/index.d.ts +1 -0
  14. package/dist/document-api/src/types/track-changes.types.d.ts +10 -2
  15. package/dist/layout-engine/contracts/src/index.d.ts +2 -0
  16. package/dist/layout-engine/contracts/src/resolved-layout.d.ts +1 -0
  17. package/dist/public/ui-react.cjs +1 -1
  18. package/dist/public/ui-react.es.js +1 -1
  19. package/dist/public/ui-vue.cjs +1 -1
  20. package/dist/public/ui-vue.es.js +1 -1
  21. package/dist/public/ui.cjs +1 -1
  22. package/dist/public/ui.es.js +1 -1
  23. package/dist/shared/common/list-marker-utils.d.ts +3 -0
  24. package/dist/style.css +1 -1
  25. package/dist/style.layered.css +1 -1
  26. package/dist/superdoc/src/core/SuperDoc.d.ts +2 -6
  27. package/dist/superdoc/src/core/config/normalize-ui-config.d.ts +1 -0
  28. package/dist/superdoc/src/core/editor-runtime/types.d.ts +1 -0
  29. package/dist/superdoc/src/core/editor-runtime/v2/v2-editor-runtime-adapter.d.ts +2 -2
  30. package/dist/superdoc/src/core/extensions/types.d.ts +14 -3
  31. package/dist/superdoc/src/core/helpers/resolve-docx-export.d.ts +6 -0
  32. package/dist/superdoc/src/core/types/index.d.ts +12 -1
  33. package/dist/superdoc/src/core/v2-integration/v2-integration.d.ts +0 -8
  34. package/dist/superdoc/src/internal/toolbar/built-in/color-dropdown-helpers.d.ts +0 -1
  35. package/dist/superdoc/src/internal/toolbar/built-in/constants.d.ts +0 -2
  36. package/dist/superdoc/src/public/export-types.d.ts +3 -0
  37. package/dist/superdoc/src/public/ui/entity-at.d.ts +1 -0
  38. package/dist/superdoc/src/public/ui/format-painter-helpers.d.ts +0 -13
  39. package/dist/superdoc/src/public/ui/types.d.ts +16 -2
  40. package/dist/superdoc/src/public/ui.d.cts +14 -0
  41. package/dist/superdoc/src/public/ui.d.ts +1 -1
  42. package/dist/superdoc/src/stores/comments-store.d.ts +3 -57
  43. package/dist/superdoc/src/stores/superdoc-store.d.ts +9 -171
  44. package/dist/superdoc.cjs +224 -59
  45. package/dist/superdoc.es.js +224 -59
  46. package/dist/word-layout/src/types.d.ts +1 -0
  47. package/dist-cdn/style.layered.css +1 -1
  48. package/dist-cdn/superdoc.min.css +1 -1
  49. package/dist-cdn/superdoc.min.js +42 -42
  50. package/package.json +2 -2
  51. package/dist/superdoc/src/helpers/floor.d.ts +0 -1
  52. package/dist/superdoc/src/index.d.cts +0 -18
  53. 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.8";
264
264
  } catch {
265
265
  return "unknown";
266
266
  }
@@ -7188,16 +7188,6 @@ function createDefaultV2Integration() {
7188
7188
  return createStubV2Integration();
7189
7189
  }
7190
7190
  }
7191
- /**
7192
- * Backwards-compatible alias. The v2 branch no longer reads any customer
7193
- * config; the parameter is ignored and retained only so existing call sites do
7194
- * not need to change in lockstep with this internalization.
7195
- *
7196
- * @returns {SuperDocV2Integration}
7197
- */
7198
- function resolveV2Integration() {
7199
- return createDefaultV2Integration();
7200
- }
7201
7191
  //#endregion
7202
7192
  //#region src/helpers/interaction-trace.js
7203
7193
  function safeTraceCollector() {
@@ -7756,6 +7746,7 @@ var useCommentsStore = defineStore("comments", () => {
7756
7746
  const instantSidebarAlignmentInstanceId = require__plugin_vue_export_helper.ref(null);
7757
7747
  const pendingComment = require__plugin_vue_export_helper.ref(null);
7758
7748
  const pendingV2CommentTarget = require__plugin_vue_export_helper.shallowRef(null);
7749
+ let pendingCommentRequest = 0;
7759
7750
  const isViewingMode = require__plugin_vue_export_helper.computed(() => viewingVisibility.documentMode === "viewing");
7760
7751
  const shouldRenderReviewInViewing = require__plugin_vue_export_helper.computed(() => {
7761
7752
  if (!isViewingMode.value) return true;
@@ -7763,6 +7754,7 @@ var useCommentsStore = defineStore("comments", () => {
7763
7754
  });
7764
7755
  const v2CommentsAdapter = require__plugin_vue_export_helper.shallowRef(null);
7765
7756
  const setV2CommentsAdapter = (adapter) => {
7757
+ if (v2CommentsAdapter.value !== (adapter ?? null)) pendingCommentRequest += 1;
7766
7758
  v2CommentsAdapter.value = adapter ?? null;
7767
7759
  };
7768
7760
  const getV2CommentsAdapter = (superdoc) => {
@@ -8621,26 +8613,41 @@ var useCommentsStore = defineStore("comments", () => {
8621
8613
  }
8622
8614
  if (typeof currentSelection !== "function") return null;
8623
8615
  try {
8624
- return currentSelection();
8616
+ const snapshot = currentSelection();
8617
+ return typeof snapshot?.then === "function" ? Promise.resolve(snapshot).catch(() => null) : snapshot;
8625
8618
  } catch {
8626
8619
  return null;
8627
8620
  }
8628
8621
  };
8629
8622
  const showAddComment = (superdoc, targetClientY = null) => {
8623
+ const request = ++pendingCommentRequest;
8624
+ const editor = superdoc?.activeEditor;
8630
8625
  const v2Adapter = getV2CommentsAdapter(superdoc);
8631
- const pendingSelection = getPendingSelectionSnapshot(superdoc, superdocStore.activeSelection);
8632
- const event = {
8633
- type: COMMENT_EVENTS.PENDING,
8634
- pendingSelection
8626
+ const ownsRequest = () => pendingCommentRequest === request;
8627
+ const emitPending = (snapshot) => {
8628
+ if (!ownsRequest()) return;
8629
+ superdoc.emit("comments-update", {
8630
+ type: COMMENT_EVENTS.PENDING,
8631
+ pendingSelection: superdoc?.activeEditor === editor ? snapshot : null
8632
+ });
8635
8633
  };
8636
- superdoc.emit("comments-update", event);
8637
8634
  if (v2Adapter) {
8638
8635
  const cap = v2Adapter.getCapabilityState?.();
8639
8636
  if (cap && cap.canWrite === false) return {
8640
8637
  ok: false,
8641
8638
  reason: cap.reason
8642
8639
  };
8643
- return Promise.resolve(v2Adapter.captureCurrentSelection?.()).then((capture) => {
8640
+ return Promise.resolve(v2Adapter.captureCurrentSelection?.({ beforeReady: (snapshot) => {
8641
+ if (superdoc?.activeEditor === editor && getV2CommentsAdapter(superdoc) === v2Adapter) emitPending(snapshot);
8642
+ } })).then((capture) => {
8643
+ if (!ownsRequest()) return {
8644
+ ok: false,
8645
+ reason: "pending-comment-superseded"
8646
+ };
8647
+ if (superdoc?.activeEditor !== editor || getV2CommentsAdapter(superdoc) !== v2Adapter) return {
8648
+ ok: false,
8649
+ reason: "document-replaced"
8650
+ };
8644
8651
  if (!capture?.ok) return {
8645
8652
  ok: false,
8646
8653
  reason: capture?.reason ?? "editing-range-required",
@@ -8669,25 +8676,52 @@ var useCommentsStore = defineStore("comments", () => {
8669
8676
  detail: err?.message ?? String(err)
8670
8677
  }));
8671
8678
  }
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 };
8679
+ const pendingSelection = getPendingSelectionSnapshot(superdoc, superdocStore.activeSelection);
8680
+ const asyncSnapshot = typeof pendingSelection?.then === "function";
8681
+ if (!asyncSnapshot) emitPending(pendingSelection);
8682
+ const showLegacyPending = (selection) => {
8683
+ selection.selectionBounds = { ...selection.selectionBounds };
8684
+ if (superdocStore.selectionPosition?.source && superdocStore.selectionPosition.source !== "pdf") superdocStore.selectionPosition.source = null;
8685
+ pendingComment.value = getPendingComment({
8686
+ selection,
8687
+ documentId: selection.documentId,
8688
+ parentCommentId: null
8689
+ });
8690
+ if (!superdoc.config.isInternal) pendingComment.value.isInternal = false;
8691
+ if (superdoc.activeEditor?.commands) superdoc.activeEditor.commands.insertComment({
8692
+ ...pendingComment.value.getValues(),
8693
+ commentId: "pending",
8694
+ skipEmit: true
8695
+ });
8696
+ if (pendingComment.value.selection.source === "document-editor" && superdocStore.selectionPosition) superdocStore.selectionPosition.source = DOCUMENT_EDITOR_SELECTION_SOURCE;
8697
+ requestInstantSidebarAlignment(targetClientY, "pending");
8698
+ setActiveFloatingCommentInstance(null);
8699
+ activeComment.value = pendingComment.value.commentId;
8700
+ return { ok: true };
8701
+ };
8702
+ if (asyncSnapshot) {
8703
+ const selection = { ...superdocStore.activeSelection };
8704
+ selection.selectionBounds = { ...selection.selectionBounds };
8705
+ return pendingSelection.then((snapshot) => {
8706
+ if (!ownsRequest()) return {
8707
+ ok: false,
8708
+ reason: "pending-comment-superseded"
8709
+ };
8710
+ emitPending(snapshot);
8711
+ if (!ownsRequest()) return {
8712
+ ok: false,
8713
+ reason: "pending-comment-superseded"
8714
+ };
8715
+ return superdoc?.activeEditor === editor ? showLegacyPending(selection) : {
8716
+ ok: false,
8717
+ reason: "document-replaced"
8718
+ };
8719
+ });
8720
+ }
8721
+ return ownsRequest() ? showLegacyPending({ ...superdocStore.activeSelection }) : {
8722
+ ok: false,
8723
+ reason: "pending-comment-superseded"
8724
+ };
8691
8725
  };
8692
8726
  /**
8693
8727
  * Get the numeric position value for sorting a comment by document order.
@@ -8842,7 +8876,7 @@ var useCommentsStore = defineStore("comments", () => {
8842
8876
  *
8843
8877
  * @returns {void}
8844
8878
  */
8845
- const removePendingComment = (superdoc) => {
8879
+ const resetPendingCommentState = (superdoc, clearViewingSelection = true) => {
8846
8880
  const hadPending = !!pendingComment.value;
8847
8881
  currentCommentText.value = "";
8848
8882
  currentCommentMentions.value = [];
@@ -8851,13 +8885,17 @@ var useCommentsStore = defineStore("comments", () => {
8851
8885
  superdocStore.selectionPosition = null;
8852
8886
  if (hadPending) clearActiveCommentSelection();
8853
8887
  if (isV2EditorActive(superdoc)) {
8854
- if (hadPending && isViewingMode.value) try {
8888
+ if (hadPending && clearViewingSelection && isViewingMode.value) try {
8855
8889
  superdoc?.activeEditor?.host?.getHandles?.()?.selection?.clear?.();
8856
8890
  } catch {}
8857
8891
  return;
8858
8892
  }
8859
8893
  superdoc?.activeEditor?.commands?.removeComment({ commentId: "pending" });
8860
8894
  };
8895
+ const removePendingComment = (superdoc) => {
8896
+ pendingCommentRequest += 1;
8897
+ resetPendingCommentState(superdoc);
8898
+ };
8861
8899
  const getV2CreatedComment = ({ outcome, reconciled, documentId }) => {
8862
8900
  const createdId = normalizeCommentId(outcome?.createdCommentId);
8863
8901
  if (!createdId) return reconciled?.added ?? null;
@@ -8875,6 +8913,7 @@ var useCommentsStore = defineStore("comments", () => {
8875
8913
  const v2Adapter = !skipEditorUpdate && !isHydration ? getV2CommentsAdapter(superdoc) : null;
8876
8914
  if (v2Adapter && !comment.trackedChange) {
8877
8915
  const submittedPendingComment = pendingComment.value;
8916
+ const submittedPendingRequest = pendingCommentRequest;
8878
8917
  const text = normalizeV2CommentDraftText(submittedPendingComment ? currentCommentText.value : comment.commentText);
8879
8918
  const mentions = pendingComment.value ? currentCommentMentions.value : comment.mentions ?? [];
8880
8919
  const target = pendingComment.value ? pendingV2CommentTarget.value : null;
@@ -8923,9 +8962,11 @@ var useCommentsStore = defineStore("comments", () => {
8923
8962
  documentId: v2Adapter.documentId
8924
8963
  });
8925
8964
  const hadPendingComment = submittedPendingComment != null && pendingComment.value?.commentId === submittedPendingComment.commentId;
8926
- if (hadPendingComment) removePendingComment(superdoc);
8965
+ const ownsSubmittedRequest = pendingCommentRequest === submittedPendingRequest;
8966
+ if (hadPendingComment) if (ownsSubmittedRequest) removePendingComment(superdoc);
8967
+ else resetPendingCommentState(superdoc, false);
8927
8968
  const createdId = created?.commentId ?? null;
8928
- if (hadPendingComment && createdId) {
8969
+ if (hadPendingComment && ownsSubmittedRequest && createdId) {
8929
8970
  setActiveComment(superdoc, createdId);
8930
8971
  setActiveFloatingCommentInstance(createdId);
8931
8972
  }
@@ -13521,6 +13562,7 @@ var _sfc_main$33 = {
13521
13562
  };
13522
13563
  };
13523
13564
  const CLICK_OUTSIDE_IGNORED_SELECTORS = [
13565
+ ".superdoc__tools [data-id=\"is-tool\"]",
13524
13566
  ".comments-dropdown__option-label",
13525
13567
  ".comments-dropdown__menu",
13526
13568
  ".comments-dropdown__option",
@@ -14643,7 +14685,7 @@ var _sfc_main$33 = {
14643
14685
  };
14644
14686
  }
14645
14687
  };
14646
- var CommentDialog_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$33, [["__scopeId", "data-v-05d27982"]]);
14688
+ var CommentDialog_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$33, [["__scopeId", "data-v-f8b79c74"]]);
14647
14689
  //#endregion
14648
14690
  //#region src/components/CommentsLayer/commentsList/ReviewDirectoryListItem.vue
14649
14691
  var _hoisted_1$25 = [
@@ -15368,6 +15410,80 @@ var composeAuthorColorResolver = (config) => {
15368
15410
  };
15369
15411
  };
15370
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 && !require_create_super_doc_ui.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 (!require_create_super_doc_ui.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 && !require_create_super_doc_ui.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
15371
15487
  //#region ../document-api/src/permission-ranges/permission-ranges.ts
15372
15488
  function editorKey(editor) {
15373
15489
  return editor.id?.trim() ? editor.id : editor.email?.trim() || void 0;
@@ -20127,6 +20243,28 @@ function useLinkPopover({ getSurfaceManager, getActiveEditor, getUi, getActivati
20127
20243
  };
20128
20244
  }
20129
20245
  //#endregion
20246
+ //#region src/core/helpers/resolve-docx-export.ts
20247
+ function resolveV2DocxExportOptions(options = {}) {
20248
+ const policies = resolveDocxExportPolicies({ policies: options.policies });
20249
+ if (options.isFinalDoc !== void 0) {
20250
+ if (typeof options.isFinalDoc !== "boolean") throw new DocumentApiValidationError("INVALID_INPUT", "isFinalDoc must be a boolean.");
20251
+ const legacy = options.isFinalDoc ? "final" : "review-preserving";
20252
+ if (options.policies?.trackedChanges !== void 0 && policies.trackedChanges !== legacy) throw new DocumentApiValidationError("INVALID_INPUT", "isFinalDoc conflicts with policies.trackedChanges.");
20253
+ policies.trackedChanges = legacy;
20254
+ }
20255
+ if (options.commentsType !== void 0) {
20256
+ if (options.commentsType !== "external" && options.commentsType !== "clean") throw new DocumentApiValidationError("INVALID_INPUT", "commentsType must be external or clean.");
20257
+ const legacy = options.commentsType === "clean" ? "remove" : "preserve";
20258
+ if (options.policies?.comments !== void 0 && policies.comments !== legacy) throw new DocumentApiValidationError("INVALID_INPUT", "commentsType conflicts with policies.comments.");
20259
+ policies.comments = legacy;
20260
+ }
20261
+ return {
20262
+ mode: policies.trackedChanges,
20263
+ commentExportMode: policies.comments === "remove" ? "strip" : policies.comments,
20264
+ contentControlExportMode: policies.contentControls
20265
+ };
20266
+ }
20267
+ //#endregion
20130
20268
  //#region src/core/editor-runtime/v2/v2-editor-runtime-adapter.ts
20131
20269
  var DEFAULT_V2_LEGACY_PROJECTION = Object.freeze({
20132
20270
  editorVersion: 2,
@@ -20766,7 +20904,7 @@ function createV2EditorRuntimeAdapter(options) {
20766
20904
  save: () => host.save(),
20767
20905
  exportDocx: (options) => host.save({
20768
20906
  format: "docx",
20769
- commentExportMode: options?.commentsType === "clean" ? "strip" : "preserve"
20907
+ ...resolveV2DocxExportOptions(options)
20770
20908
  }),
20771
20909
  async setZoom(percent) {
20772
20910
  const result = host.setZoom(percent);
@@ -22021,7 +22159,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
22021
22159
  const { proxy } = require__plugin_vue_export_helper.getCurrentInstance();
22022
22160
  commentsStore.proxy = proxy;
22023
22161
  const documentOpenTelemetry = createDocumentOpenTelemetry(proxy.$superdoc.config);
22024
- const resolvedEditorIntegration = resolveV2Integration(proxy.$superdoc.config);
22162
+ const resolvedEditorIntegration = createDefaultV2Integration();
22025
22163
  const V2DocumentEditor = require__plugin_vue_export_helper.markRaw(resolvedEditorIntegration.EditorComponent);
22026
22164
  const V2Ruler = resolvedEditorIntegration.RulerComponent ? require__plugin_vue_export_helper.markRaw(resolvedEditorIntegration.RulerComponent) : null;
22027
22165
  const floatingComments = require__plugin_vue_export_helper.computed(() => {
@@ -22167,6 +22305,10 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
22167
22305
  return layers.value.getBoundingClientRect().top + top * zoom;
22168
22306
  };
22169
22307
  const handleCommentToolClick = async () => {
22308
+ if (isV2Mode.value) {
22309
+ cancelScheduledV2DomSelectionSync();
22310
+ if (applyCurrentV2DomSelection()?.ok === false) return;
22311
+ }
22170
22312
  if ((await showAddComment(proxy.$superdoc, getPendingCommentTargetClientY()))?.ok === false) return;
22171
22313
  if (!isV2Mode.value) return;
22172
22314
  const pendingPosition = buildV2PendingPositionEntry();
@@ -22439,10 +22581,9 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
22439
22581
  return host.save(saveOptions);
22440
22582
  });
22441
22583
  const exportV2Docx = async (options = {}) => {
22442
- const commentExportMode = options?.commentsType === "clean" ? "strip" : "preserve";
22443
22584
  const bytes = await saveV2Bytes({
22444
22585
  format: "docx",
22445
- commentExportMode
22586
+ ...resolveV2DocxExportOptions(options)
22446
22587
  });
22447
22588
  return new Blob([bytes], { type: DOCX });
22448
22589
  };
@@ -22717,6 +22858,9 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
22717
22858
  subscribe: (listener) => v2ReviewWindowController.subscribe?.(listener) ?? (() => void 0)
22718
22859
  },
22719
22860
  extensions: createV2ExtensionsFacet(host),
22861
+ get visuals() {
22862
+ return typeof host?.getHostVisuals === "function" ? host.getHostVisuals() : null;
22863
+ },
22720
22864
  fonts: fonts ?? host?.getFontRuntime?.() ?? null,
22721
22865
  /**
22722
22866
  * The v2 active-editor facade explicitly does NOT carry v1 commands /
@@ -22882,7 +23026,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
22882
23026
  const result = handles?.selection?.applyDomSelection?.(selection);
22883
23027
  if (!result?.ok || result.mode !== "range") {
22884
23028
  clearV2SelectionToolbarState();
22885
- return;
23029
+ return { ok: false };
22886
23030
  }
22887
23031
  v2DomMirroredRange.value = true;
22888
23032
  v2HasRangeSelection.value = true;
@@ -23535,6 +23679,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
23535
23679
  emitCommentPositionsInViewing: isViewingMode() && shouldRenderCommentsInViewing.value,
23536
23680
  enableCommentsInViewing: isViewingCommentsVisible.value,
23537
23681
  contentControlsChrome: proxy.$superdoc.uiConfig.contentControls.options.chrome,
23682
+ commentHighlights: proxy.$superdoc.uiConfig.comments.highlights,
23538
23683
  resolveTrackedChangeColor: composeAuthorColorResolver(proxy.$superdoc.config.modules?.trackChanges?.authorColors)
23539
23684
  } : void 0,
23540
23685
  permissionResolver: createTrackedChangePermissionResolver(proxy.$superdoc)
@@ -24589,7 +24734,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
24589
24734
  ], 46, _hoisted_1$17);
24590
24735
  };
24591
24736
  }
24592
- }, [["__scopeId", "data-v-2fc1721f"]]);
24737
+ }, [["__scopeId", "data-v-f2db957f"]]);
24593
24738
  //#endregion
24594
24739
  //#region src/core/create-app.js
24595
24740
  var PINIA_DEVTOOLS_SETUP_EVENT = "devtools-plugin:setup";
@@ -38051,6 +38196,11 @@ var COMMENT_POLICY_FIELDS = Object.freeze([
38051
38196
  "allowResolve",
38052
38197
  "permissionResolver"
38053
38198
  ]);
38199
+ function withoutSwitches(options) {
38200
+ if (!("panel" in options) && !("highlights" in options)) return options;
38201
+ const { panel: _panel, highlights: _highlights, ...rest } = options;
38202
+ return rest;
38203
+ }
38054
38204
  /**
38055
38205
  * Drop policy fields from a presentation options bag.
38056
38206
  */
@@ -38395,8 +38545,9 @@ function normalizeUiConfig(config = {}) {
38395
38545
  }
38396
38546
  },
38397
38547
  comments: {
38398
- enabled: explicit("comments") ?? (!allDisabled && config.modules?.comments !== false),
38399
- options: allDisabled ? {} : normalizeCommentsUiConfig(withoutCommentPolicy(options("comments"))) || {}
38548
+ enabled: (explicit("comments") ?? (!allDisabled && config.modules?.comments !== false)) && options("comments").panel !== false,
38549
+ highlights: options("comments").highlights !== false,
38550
+ options: allDisabled ? {} : normalizeCommentsUiConfig(withoutCommentPolicy(withoutSwitches(options("comments")))) || {}
38400
38551
  },
38401
38552
  contextMenu: {
38402
38553
  enabled: explicit("contextMenu") ?? (!allDisabled && config.disableContextMenu !== true),
@@ -41530,9 +41681,6 @@ var TABLE_ACTION_COMMAND_MAP = {
41530
41681
  fixTables: "table-fix"
41531
41682
  };
41532
41683
  var TABLE_ACTION_COMMAND_IDS = Object.values(TABLE_ACTION_COMMAND_MAP);
41533
- [.../* @__PURE__ */ new Set([...Object.values(HEADLESS_ITEM_MAP), ...TABLE_ACTION_COMMAND_IDS])];
41534
- var NON_HEADLESS_EXECUTE_ITEM_NAMES = /* @__PURE__ */ new Set(["link"]);
41535
- new Set(Object.keys(HEADLESS_ITEM_MAP).filter((itemName) => !NON_HEADLESS_EXECUTE_ITEM_NAMES.has(itemName)));
41536
41684
  //#endregion
41537
41685
  //#region src/internal/toolbar/built-in/Toolbar.vue
41538
41686
  var _hoisted_1$10 = ["data-superdoc-ui-owner"];
@@ -46318,7 +46466,7 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
46318
46466
  }
46319
46467
  this.userColorMap = /* @__PURE__ */ new Map();
46320
46468
  this.colorIndex = 0;
46321
- this.version = "2.28.0-next.6";
46469
+ this.version = "2.28.0-next.8";
46322
46470
  this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
46323
46471
  this.superdocId = config.superdocId || require_uuid.v4();
46324
46472
  this.colors = this.config.colors ?? [];
@@ -48272,12 +48420,13 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
48272
48420
  * Export the superdoc to a file
48273
48421
  * @param params - Export configuration
48274
48422
  */
48275
- async export({ exportType = ["docx"], commentsType = "external", exportedName, additionalFiles = [], additionalFileNames = [], isFinalDoc = false, triggerDownload = true, fieldsHighlightColor = null } = {}) {
48423
+ async export({ exportType = ["docx"], commentsType, exportedName, additionalFiles = [], additionalFileNames = [], isFinalDoc, policies, triggerDownload = true, fieldsHighlightColor = null } = {}) {
48276
48424
  if (!Array.isArray(exportType) || exportType.length !== 1 || exportType[0] !== "docx") throw new TypeError("SuperDoc.export() only supports exportType: [\"docx\"].");
48277
48425
  const baseFileName = exportedName ? cleanName(exportedName) : cleanName(this.config.title);
48278
48426
  const docxFiles = await this.exportEditorsToDOCX({
48279
48427
  commentsType,
48280
48428
  isFinalDoc,
48429
+ policies,
48281
48430
  fieldsHighlightColor
48282
48431
  });
48283
48432
  const blobsToZip = [...additionalFiles];
@@ -48363,7 +48512,12 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
48363
48512
  * Export editors to DOCX format.
48364
48513
  * @param [options]
48365
48514
  */
48366
- async exportEditorsToDOCX({ commentsType, isFinalDoc, fieldsHighlightColor } = {}) {
48515
+ async exportEditorsToDOCX({ commentsType, isFinalDoc, policies, fieldsHighlightColor } = {}) {
48516
+ if (policies !== void 0) resolveV2DocxExportOptions({
48517
+ policies,
48518
+ commentsType,
48519
+ isFinalDoc
48520
+ });
48367
48521
  const uiStoreHydrated = this.config?.modules?.comments !== false;
48368
48522
  let legacyComments;
48369
48523
  let legacyCommentsComputed = false;
@@ -48383,7 +48537,13 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
48383
48537
  };
48384
48538
  this.on("exception", rememberBridgedExportError);
48385
48539
  try {
48386
- const docxPromises = this.#requireSuperdocStore("exportEditorsToDOCX").documents.map(async (doc) => {
48540
+ const documents = this.#requireSuperdocStore("exportEditorsToDOCX").documents;
48541
+ if (policies !== void 0 && documents.some((doc) => {
48542
+ if (doc.type !== "application/vnd.openxmlformats-officedocument.wordprocessingml.document") return false;
48543
+ const editor = doc.getEditor?.();
48544
+ return editor?.editorVersion !== 2 || typeof editor.exportDocx !== "function";
48545
+ })) throw new Error("Independent DOCX export policies require a mounted V2 exporter for every document.");
48546
+ const docxPromises = documents.map(async (doc) => {
48387
48547
  if (!doc || doc.type !== "application/vnd.openxmlformats-officedocument.wordprocessingml.document") return null;
48388
48548
  const editor = typeof doc.getEditor === "function" ? doc.getEditor() : null;
48389
48549
  const fallbackDocx = () => {
@@ -48400,6 +48560,7 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
48400
48560
  const exported = await editor.exportDocx(isV2Editor ? {
48401
48561
  isFinalDoc,
48402
48562
  commentsType,
48563
+ policies,
48403
48564
  fieldsHighlightColor
48404
48565
  } : {
48405
48566
  isFinalDoc,
@@ -48728,7 +48889,11 @@ function defineSuperDocExtension(extension) {
48728
48889
  return extension;
48729
48890
  }
48730
48891
  //#endregion
48731
- exports.BlankDOCX = require_blank_docx.blank_default;
48892
+ //#region src/public/index.ts
48893
+ /** URL to the blank DOCX template. */
48894
+ var BlankDOCX = require_blank_docx.blank_default;
48895
+ //#endregion
48896
+ exports.BlankDOCX = BlankDOCX;
48732
48897
  exports.DOCX = DOCX;
48733
48898
  exports.DocumentLoadError = DocumentLoadError;
48734
48899
  exports.HTML = HTML;