superdoc 2.28.0-next.1 → 2.28.0-next.11

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 (136) hide show
  1. package/dist/chunks/{create-super-doc-ui-D1eOhAjv.cjs → create-super-doc-ui-8dttPeGi.cjs} +431 -85
  2. package/dist/chunks/{create-super-doc-ui-B29zw5qD.es.js → create-super-doc-ui-B6Va_J_0.es.js} +426 -86
  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 +44 -44
  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 +2 -1
  14. package/dist/document-api/src/replace/replace.d.ts +4 -1
  15. package/dist/document-api/src/types/mutation-plan.types.d.ts +2 -0
  16. package/dist/document-api/src/types/track-changes.types.d.ts +10 -2
  17. package/dist/layout-engine/contracts/src/index.d.ts +2 -0
  18. package/dist/layout-engine/contracts/src/resolved-layout.d.ts +1 -0
  19. package/dist/public/ui-react.cjs +1 -1
  20. package/dist/public/ui-react.es.js +1 -1
  21. package/dist/public/ui-vue.cjs +1 -1
  22. package/dist/public/ui-vue.es.js +1 -1
  23. package/dist/public/ui.cjs +1 -1
  24. package/dist/public/ui.es.js +1 -1
  25. package/dist/shared/common/list-marker-utils.d.ts +3 -0
  26. package/dist/style.css +1 -1
  27. package/dist/style.layered.css +1 -1
  28. package/dist/superdoc/src/core/SuperDoc.d.ts +2 -6
  29. package/dist/superdoc/src/core/collaboration/resolve-v2-collaboration-target.d.ts +2 -0
  30. package/dist/superdoc/src/core/config/normalize-ui-config.d.ts +1 -0
  31. package/dist/superdoc/src/core/editor-runtime/types.d.ts +1 -0
  32. package/dist/superdoc/src/core/editor-runtime/v2/v2-editor-runtime-adapter.d.ts +2 -2
  33. package/dist/superdoc/src/core/extensions/types.d.ts +14 -3
  34. package/dist/superdoc/src/core/helpers/resolve-docx-export.d.ts +6 -0
  35. package/dist/superdoc/src/core/types/index.d.ts +35 -1
  36. package/dist/superdoc/src/core/v2-integration/v2-integration.d.ts +0 -8
  37. package/dist/superdoc/src/internal/toolbar/built-in/color-dropdown-helpers.d.ts +0 -1
  38. package/dist/superdoc/src/internal/toolbar/built-in/constants.d.ts +0 -2
  39. package/dist/superdoc/src/public/export-types.d.ts +3 -0
  40. package/dist/superdoc/src/public/ui/entity-at.d.ts +1 -0
  41. package/dist/superdoc/src/public/ui/format-painter-helpers.d.ts +0 -13
  42. package/dist/superdoc/src/public/ui/types.d.ts +16 -2
  43. package/dist/superdoc/src/public/ui.d.cts +14 -0
  44. package/dist/superdoc/src/public/ui.d.ts +1 -1
  45. package/dist/superdoc/src/stores/comments-store.d.ts +3 -57
  46. package/dist/superdoc/src/stores/superdoc-store.d.ts +9 -171
  47. package/dist/superdoc.cjs +363 -159
  48. package/dist/superdoc.es.js +363 -159
  49. package/dist/word-layout/src/types.d.ts +1 -0
  50. package/dist-cdn/style.layered.css +1 -1
  51. package/dist-cdn/superdoc.min.css +1 -1
  52. package/dist-cdn/superdoc.min.js +42 -42
  53. package/package.json +2 -2
  54. package/dist/footnote-table-order.docx +0 -0
  55. package/dist/images/altText_add.svg +0 -3
  56. package/dist/images/altText_disclaimer.svg +0 -3
  57. package/dist/images/altText_done.svg +0 -3
  58. package/dist/images/altText_spinner.svg +0 -30
  59. package/dist/images/altText_warning.svg +0 -3
  60. package/dist/images/annotation-check.svg +0 -11
  61. package/dist/images/annotation-comment.svg +0 -16
  62. package/dist/images/annotation-help.svg +0 -26
  63. package/dist/images/annotation-insert.svg +0 -10
  64. package/dist/images/annotation-key.svg +0 -11
  65. package/dist/images/annotation-newparagraph.svg +0 -11
  66. package/dist/images/annotation-noicon.svg +0 -7
  67. package/dist/images/annotation-note.svg +0 -42
  68. package/dist/images/annotation-paperclip.svg +0 -6
  69. package/dist/images/annotation-paragraph.svg +0 -16
  70. package/dist/images/annotation-pushpin.svg +0 -7
  71. package/dist/images/checkmark.svg +0 -5
  72. package/dist/images/comment-actionsButton.svg +0 -3
  73. package/dist/images/comment-closeButton.svg +0 -3
  74. package/dist/images/comment-editButton.svg +0 -8
  75. package/dist/images/comment-popup-editButton.svg +0 -5
  76. package/dist/images/cursor-editorFreeHighlight.svg +0 -6
  77. package/dist/images/cursor-editorFreeText.svg +0 -3
  78. package/dist/images/cursor-editorInk.svg +0 -4
  79. package/dist/images/cursor-editorTextHighlight.svg +0 -8
  80. package/dist/images/editor-toolbar-delete.svg +0 -5
  81. package/dist/images/editor-toolbar-edit.svg +0 -3
  82. package/dist/images/findbarButton-next.svg +0 -3
  83. package/dist/images/findbarButton-previous.svg +0 -3
  84. package/dist/images/gv-toolbarButton-download.svg +0 -3
  85. package/dist/images/loading-icon.gif +0 -0
  86. package/dist/images/loading.svg +0 -1
  87. package/dist/images/messageBar_closingButton.svg +0 -3
  88. package/dist/images/messageBar_info.svg +0 -3
  89. package/dist/images/messageBar_warning.svg +0 -3
  90. package/dist/images/pages_closeButton.svg +0 -3
  91. package/dist/images/pages_selected.svg +0 -7
  92. package/dist/images/pages_viewArrow.svg +0 -3
  93. package/dist/images/pages_viewButton.svg +0 -3
  94. package/dist/images/secondaryToolbarButton-documentProperties.svg +0 -3
  95. package/dist/images/secondaryToolbarButton-firstPage.svg +0 -3
  96. package/dist/images/secondaryToolbarButton-handTool.svg +0 -3
  97. package/dist/images/secondaryToolbarButton-lastPage.svg +0 -3
  98. package/dist/images/secondaryToolbarButton-rotateCcw.svg +0 -3
  99. package/dist/images/secondaryToolbarButton-rotateCw.svg +0 -3
  100. package/dist/images/secondaryToolbarButton-scrollHorizontal.svg +0 -3
  101. package/dist/images/secondaryToolbarButton-scrollPage.svg +0 -3
  102. package/dist/images/secondaryToolbarButton-scrollVertical.svg +0 -3
  103. package/dist/images/secondaryToolbarButton-scrollWrapped.svg +0 -3
  104. package/dist/images/secondaryToolbarButton-selectTool.svg +0 -3
  105. package/dist/images/secondaryToolbarButton-spreadEven.svg +0 -3
  106. package/dist/images/secondaryToolbarButton-spreadNone.svg +0 -3
  107. package/dist/images/secondaryToolbarButton-spreadOdd.svg +0 -3
  108. package/dist/images/toolbarButton-bookmark.svg +0 -3
  109. package/dist/images/toolbarButton-currentOutlineItem.svg +0 -3
  110. package/dist/images/toolbarButton-download.svg +0 -4
  111. package/dist/images/toolbarButton-editorFreeText.svg +0 -5
  112. package/dist/images/toolbarButton-editorHighlight.svg +0 -6
  113. package/dist/images/toolbarButton-editorInk.svg +0 -4
  114. package/dist/images/toolbarButton-editorSignature.svg +0 -6
  115. package/dist/images/toolbarButton-editorStamp.svg +0 -8
  116. package/dist/images/toolbarButton-menuArrow.svg +0 -3
  117. package/dist/images/toolbarButton-openFile.svg +0 -3
  118. package/dist/images/toolbarButton-pageDown.svg +0 -3
  119. package/dist/images/toolbarButton-pageUp.svg +0 -3
  120. package/dist/images/toolbarButton-presentationMode.svg +0 -3
  121. package/dist/images/toolbarButton-print.svg +0 -3
  122. package/dist/images/toolbarButton-search.svg +0 -3
  123. package/dist/images/toolbarButton-secondaryToolbarToggle.svg +0 -3
  124. package/dist/images/toolbarButton-viewAttachments.svg +0 -3
  125. package/dist/images/toolbarButton-viewLayers.svg +0 -3
  126. package/dist/images/toolbarButton-viewOutline.svg +0 -3
  127. package/dist/images/toolbarButton-viewThumbnail.svg +0 -3
  128. package/dist/images/toolbarButton-viewsManagerToggle.svg +0 -3
  129. package/dist/images/toolbarButton-zoomIn.svg +0 -3
  130. package/dist/images/toolbarButton-zoomOut.svg +0 -3
  131. package/dist/images/treeitem-collapsed.svg +0 -1
  132. package/dist/images/treeitem-expanded.svg +0 -1
  133. package/dist/superdoc/src/helpers/floor.d.ts +0 -1
  134. package/dist/superdoc/src/index.d.cts +0 -18
  135. package/dist/superdoc/src/index.d.ts +0 -14
  136. package/dist-cdn/footnote-table-order.docx +0 -0
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-8dttPeGi.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.1";
263
+ return "2.28.0-next.11";
264
264
  } catch {
265
265
  return "unknown";
266
266
  }
@@ -5464,7 +5464,8 @@ function resolveWebsocketFamily(family, candidate) {
5464
5464
  roomMode,
5465
5465
  serverUrl,
5466
5466
  ...params ? { params } : {},
5467
- ...token ? { token } : {}
5467
+ ...token ? { token } : {},
5468
+ ...family === "hocuspocus" && candidate.retry !== void 0 ? { retry: candidate.retry } : {}
5468
5469
  }
5469
5470
  };
5470
5471
  }
@@ -7187,16 +7188,6 @@ function createDefaultV2Integration() {
7187
7188
  return createStubV2Integration();
7188
7189
  }
7189
7190
  }
7190
- /**
7191
- * Backwards-compatible alias. The v2 branch no longer reads any customer
7192
- * config; the parameter is ignored and retained only so existing call sites do
7193
- * not need to change in lockstep with this internalization.
7194
- *
7195
- * @returns {SuperDocV2Integration}
7196
- */
7197
- function resolveV2Integration() {
7198
- return createDefaultV2Integration();
7199
- }
7200
7191
  //#endregion
7201
7192
  //#region src/helpers/interaction-trace.js
7202
7193
  function safeTraceCollector() {
@@ -7755,6 +7746,7 @@ var useCommentsStore = defineStore("comments", () => {
7755
7746
  const instantSidebarAlignmentInstanceId = require__plugin_vue_export_helper.ref(null);
7756
7747
  const pendingComment = require__plugin_vue_export_helper.ref(null);
7757
7748
  const pendingV2CommentTarget = require__plugin_vue_export_helper.shallowRef(null);
7749
+ let pendingCommentRequest = 0;
7758
7750
  const isViewingMode = require__plugin_vue_export_helper.computed(() => viewingVisibility.documentMode === "viewing");
7759
7751
  const shouldRenderReviewInViewing = require__plugin_vue_export_helper.computed(() => {
7760
7752
  if (!isViewingMode.value) return true;
@@ -7762,6 +7754,7 @@ var useCommentsStore = defineStore("comments", () => {
7762
7754
  });
7763
7755
  const v2CommentsAdapter = require__plugin_vue_export_helper.shallowRef(null);
7764
7756
  const setV2CommentsAdapter = (adapter) => {
7757
+ if (v2CommentsAdapter.value !== (adapter ?? null)) pendingCommentRequest += 1;
7765
7758
  v2CommentsAdapter.value = adapter ?? null;
7766
7759
  };
7767
7760
  const getV2CommentsAdapter = (superdoc) => {
@@ -8620,26 +8613,41 @@ var useCommentsStore = defineStore("comments", () => {
8620
8613
  }
8621
8614
  if (typeof currentSelection !== "function") return null;
8622
8615
  try {
8623
- return currentSelection();
8616
+ const snapshot = currentSelection();
8617
+ return typeof snapshot?.then === "function" ? Promise.resolve(snapshot).catch(() => null) : snapshot;
8624
8618
  } catch {
8625
8619
  return null;
8626
8620
  }
8627
8621
  };
8628
8622
  const showAddComment = (superdoc, targetClientY = null) => {
8623
+ const request = ++pendingCommentRequest;
8624
+ const editor = superdoc?.activeEditor;
8629
8625
  const v2Adapter = getV2CommentsAdapter(superdoc);
8630
- const pendingSelection = getPendingSelectionSnapshot(superdoc, superdocStore.activeSelection);
8631
- const event = {
8632
- type: COMMENT_EVENTS.PENDING,
8633
- 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
+ });
8634
8633
  };
8635
- superdoc.emit("comments-update", event);
8636
8634
  if (v2Adapter) {
8637
8635
  const cap = v2Adapter.getCapabilityState?.();
8638
8636
  if (cap && cap.canWrite === false) return {
8639
8637
  ok: false,
8640
8638
  reason: cap.reason
8641
8639
  };
8642
- 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
+ };
8643
8651
  if (!capture?.ok) return {
8644
8652
  ok: false,
8645
8653
  reason: capture?.reason ?? "editing-range-required",
@@ -8668,25 +8676,52 @@ var useCommentsStore = defineStore("comments", () => {
8668
8676
  detail: err?.message ?? String(err)
8669
8677
  }));
8670
8678
  }
8671
- const selection = { ...superdocStore.activeSelection };
8672
- selection.selectionBounds = { ...selection.selectionBounds };
8673
- if (superdocStore.selectionPosition?.source && superdocStore.selectionPosition.source !== "pdf") superdocStore.selectionPosition.source = null;
8674
- pendingComment.value = getPendingComment({
8675
- selection,
8676
- documentId: selection.documentId,
8677
- parentCommentId: null
8678
- });
8679
- if (!superdoc.config.isInternal) pendingComment.value.isInternal = false;
8680
- if (superdoc.activeEditor?.commands) superdoc.activeEditor.commands.insertComment({
8681
- ...pendingComment.value.getValues(),
8682
- commentId: "pending",
8683
- skipEmit: true
8684
- });
8685
- if (pendingComment.value.selection.source === "document-editor" && superdocStore.selectionPosition) superdocStore.selectionPosition.source = DOCUMENT_EDITOR_SELECTION_SOURCE;
8686
- requestInstantSidebarAlignment(targetClientY, "pending");
8687
- setActiveFloatingCommentInstance(null);
8688
- activeComment.value = pendingComment.value.commentId;
8689
- 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
+ };
8690
8725
  };
8691
8726
  /**
8692
8727
  * Get the numeric position value for sorting a comment by document order.
@@ -8841,7 +8876,7 @@ var useCommentsStore = defineStore("comments", () => {
8841
8876
  *
8842
8877
  * @returns {void}
8843
8878
  */
8844
- const removePendingComment = (superdoc) => {
8879
+ const resetPendingCommentState = (superdoc, clearViewingSelection = true) => {
8845
8880
  const hadPending = !!pendingComment.value;
8846
8881
  currentCommentText.value = "";
8847
8882
  currentCommentMentions.value = [];
@@ -8850,13 +8885,17 @@ var useCommentsStore = defineStore("comments", () => {
8850
8885
  superdocStore.selectionPosition = null;
8851
8886
  if (hadPending) clearActiveCommentSelection();
8852
8887
  if (isV2EditorActive(superdoc)) {
8853
- if (hadPending && isViewingMode.value) try {
8888
+ if (hadPending && clearViewingSelection && isViewingMode.value) try {
8854
8889
  superdoc?.activeEditor?.host?.getHandles?.()?.selection?.clear?.();
8855
8890
  } catch {}
8856
8891
  return;
8857
8892
  }
8858
8893
  superdoc?.activeEditor?.commands?.removeComment({ commentId: "pending" });
8859
8894
  };
8895
+ const removePendingComment = (superdoc) => {
8896
+ pendingCommentRequest += 1;
8897
+ resetPendingCommentState(superdoc);
8898
+ };
8860
8899
  const getV2CreatedComment = ({ outcome, reconciled, documentId }) => {
8861
8900
  const createdId = normalizeCommentId(outcome?.createdCommentId);
8862
8901
  if (!createdId) return reconciled?.added ?? null;
@@ -8874,6 +8913,7 @@ var useCommentsStore = defineStore("comments", () => {
8874
8913
  const v2Adapter = !skipEditorUpdate && !isHydration ? getV2CommentsAdapter(superdoc) : null;
8875
8914
  if (v2Adapter && !comment.trackedChange) {
8876
8915
  const submittedPendingComment = pendingComment.value;
8916
+ const submittedPendingRequest = pendingCommentRequest;
8877
8917
  const text = normalizeV2CommentDraftText(submittedPendingComment ? currentCommentText.value : comment.commentText);
8878
8918
  const mentions = pendingComment.value ? currentCommentMentions.value : comment.mentions ?? [];
8879
8919
  const target = pendingComment.value ? pendingV2CommentTarget.value : null;
@@ -8922,9 +8962,11 @@ var useCommentsStore = defineStore("comments", () => {
8922
8962
  documentId: v2Adapter.documentId
8923
8963
  });
8924
8964
  const hadPendingComment = submittedPendingComment != null && pendingComment.value?.commentId === submittedPendingComment.commentId;
8925
- if (hadPendingComment) removePendingComment(superdoc);
8965
+ const ownsSubmittedRequest = pendingCommentRequest === submittedPendingRequest;
8966
+ if (hadPendingComment) if (ownsSubmittedRequest) removePendingComment(superdoc);
8967
+ else resetPendingCommentState(superdoc, false);
8926
8968
  const createdId = created?.commentId ?? null;
8927
- if (hadPendingComment && createdId) {
8969
+ if (hadPendingComment && ownsSubmittedRequest && createdId) {
8928
8970
  setActiveComment(superdoc, createdId);
8929
8971
  setActiveFloatingCommentInstance(createdId);
8930
8972
  }
@@ -9021,6 +9063,8 @@ var useCommentsStore = defineStore("comments", () => {
9021
9063
  rejected: true,
9022
9064
  comment: comment.getValues(),
9023
9065
  reason: outcome?.reason ?? "v2-delete-failed",
9066
+ ...outcome?.code !== void 0 ? { code: outcome.code } : {},
9067
+ ...outcome?.detail !== void 0 ? { detail: outcome.detail } : {},
9024
9068
  ...outcome?.committed ? { committed: true } : {}
9025
9069
  });
9026
9070
  return outcome;
@@ -13338,97 +13382,107 @@ var _hoisted_2$19 = {
13338
13382
  class: "existing-internal-input"
13339
13383
  };
13340
13384
  var _hoisted_3$16 = { class: "new-comment-input-wrapper" };
13341
- var _hoisted_4$11 = { class: "reply-actions" };
13342
- var _hoisted_5$8 = ["disabled"];
13343
- var _hoisted_6$6 = {
13385
+ var _hoisted_4$11 = {
13386
+ key: 1,
13387
+ class: "tracked-change-decision-alert",
13388
+ role: "alert"
13389
+ };
13390
+ var _hoisted_5$8 = { class: "reply-actions" };
13391
+ var _hoisted_6$6 = ["disabled"];
13392
+ var _hoisted_7$4 = {
13344
13393
  key: 0,
13345
13394
  class: "resolved-badge"
13346
13395
  };
13347
- var _hoisted_7$4 = ["innerHTML"];
13348
- var _hoisted_8$4 = {
13396
+ var _hoisted_8$4 = ["innerHTML"];
13397
+ var _hoisted_9$3 = {
13349
13398
  key: 1,
13350
13399
  class: "existing-internal-input"
13351
13400
  };
13352
- var _hoisted_9$3 = {
13401
+ var _hoisted_10$3 = {
13402
+ key: 2,
13403
+ class: "tracked-change-decision-alert",
13404
+ role: "alert"
13405
+ };
13406
+ var _hoisted_11$3 = {
13353
13407
  key: 0,
13354
13408
  class: "card-section comment-body"
13355
13409
  };
13356
- var _hoisted_10$3 = ["data-track-change-semantic-color-key"];
13357
- var _hoisted_11$3 = { key: 0 };
13358
- var _hoisted_12$2 = { class: "change-type tracked-change-label" };
13359
- var _hoisted_13$2 = {
13410
+ var _hoisted_12$2 = ["data-track-change-semantic-color-key"];
13411
+ var _hoisted_13$2 = { key: 0 };
13412
+ var _hoisted_14$2 = { class: "change-type tracked-change-label" };
13413
+ var _hoisted_15$2 = {
13360
13414
  key: 0,
13361
13415
  class: "tracked-change-detail-lines"
13362
13416
  };
13363
- var _hoisted_14$2 = {
13417
+ var _hoisted_16$2 = {
13364
13418
  key: 0,
13365
13419
  class: "tracked-change-text"
13366
13420
  };
13367
- var _hoisted_15$2 = {
13421
+ var _hoisted_17$2 = {
13368
13422
  key: 1,
13369
13423
  class: "change-type"
13370
13424
  };
13371
- var _hoisted_16$2 = { class: "change-type" };
13372
- var _hoisted_17$2 = { key: 1 };
13373
- var _hoisted_18$2 = { class: "tracked-change-text is-inserted" };
13374
- var _hoisted_19$1 = { key: 2 };
13425
+ var _hoisted_18$2 = { class: "change-type" };
13426
+ var _hoisted_19$1 = { key: 1 };
13375
13427
  var _hoisted_20$1 = { class: "tracked-change-text is-inserted" };
13376
- var _hoisted_21$1 = { key: 3 };
13377
- var _hoisted_22$1 = { key: 4 };
13378
- var _hoisted_23$1 = { key: 5 };
13379
- var _hoisted_24 = { key: 6 };
13380
- var _hoisted_25 = { class: "tracked-change-text" };
13381
- var _hoisted_26 = { key: 7 };
13382
- var _hoisted_27 = { class: "tracked-change-text is-deleted" };
13383
- var _hoisted_28 = { class: "tracked-change-text is-inserted" };
13384
- var _hoisted_29 = { key: 8 };
13385
- var _hoisted_30 = { key: 9 };
13386
- var _hoisted_31 = { key: 10 };
13387
- var _hoisted_32 = { class: "tracked-change-text is-deleted" };
13388
- var _hoisted_33 = { key: 11 };
13389
- var _hoisted_34 = { class: "tracked-change-text is-inserted" };
13390
- var _hoisted_35 = ["data-track-change-image-preview-role"];
13391
- var _hoisted_36 = ["src", "alt"];
13392
- var _hoisted_37 = {
13428
+ var _hoisted_21$1 = { key: 2 };
13429
+ var _hoisted_22$1 = { class: "tracked-change-text is-inserted" };
13430
+ var _hoisted_23$1 = { key: 3 };
13431
+ var _hoisted_24 = { key: 4 };
13432
+ var _hoisted_25 = { key: 5 };
13433
+ var _hoisted_26 = { key: 6 };
13434
+ var _hoisted_27 = { class: "tracked-change-text" };
13435
+ var _hoisted_28 = { key: 7 };
13436
+ var _hoisted_29 = { class: "tracked-change-text is-deleted" };
13437
+ var _hoisted_30 = { class: "tracked-change-text is-inserted" };
13438
+ var _hoisted_31 = { key: 8 };
13439
+ var _hoisted_32 = { key: 9 };
13440
+ var _hoisted_33 = { key: 10 };
13441
+ var _hoisted_34 = { class: "tracked-change-text is-deleted" };
13442
+ var _hoisted_35 = { key: 11 };
13443
+ var _hoisted_36 = { class: "tracked-change-text is-inserted" };
13444
+ var _hoisted_37 = ["data-track-change-image-preview-role"];
13445
+ var _hoisted_38 = ["src", "alt"];
13446
+ var _hoisted_39 = {
13393
13447
  key: 1,
13394
13448
  class: "card-section comment-body"
13395
13449
  };
13396
- var _hoisted_38 = ["innerHTML"];
13397
- var _hoisted_39 = {
13450
+ var _hoisted_40 = ["innerHTML"];
13451
+ var _hoisted_41 = {
13398
13452
  key: 1,
13399
13453
  class: "comment"
13400
13454
  };
13401
- var _hoisted_40 = {
13455
+ var _hoisted_42 = {
13402
13456
  key: 2,
13403
13457
  class: "reply-expanded"
13404
13458
  };
13405
- var _hoisted_41 = { class: "reply-input-wrapper" };
13406
- var _hoisted_42 = { class: "reply-actions" };
13407
- var _hoisted_43 = ["onClick"];
13408
- var _hoisted_44 = [
13459
+ var _hoisted_43 = { class: "reply-input-wrapper" };
13460
+ var _hoisted_44 = { class: "reply-actions" };
13461
+ var _hoisted_45 = ["onClick"];
13462
+ var _hoisted_46 = [
13409
13463
  "onClick",
13410
13464
  "disabled",
13411
13465
  "data-disabled-reason"
13412
13466
  ];
13413
- var _hoisted_45 = { class: "collapsed-avatars" };
13414
- var _hoisted_46 = {
13467
+ var _hoisted_47 = { class: "collapsed-avatars" };
13468
+ var _hoisted_48 = {
13415
13469
  key: 3,
13416
13470
  class: "comment-separator"
13417
13471
  };
13418
- var _hoisted_47 = {
13419
- key: 2,
13472
+ var _hoisted_49 = {
13473
+ key: 3,
13420
13474
  class: "tracked-change-decision-alert",
13421
13475
  role: "alert"
13422
13476
  };
13423
- var _hoisted_48 = { class: "tracked-change-decision-alert__message" };
13424
- var _hoisted_49 = ["disabled", "data-disabled-reason"];
13425
- var _hoisted_50 = {
13477
+ var _hoisted_50 = { class: "tracked-change-decision-alert__message" };
13478
+ var _hoisted_51 = ["disabled", "data-disabled-reason"];
13479
+ var _hoisted_52 = {
13426
13480
  key: 1,
13427
13481
  class: "reply-expanded"
13428
13482
  };
13429
- var _hoisted_51 = { class: "reply-input-wrapper" };
13430
- var _hoisted_52 = { class: "reply-actions" };
13431
- var _hoisted_53 = ["disabled", "data-disabled-reason"];
13483
+ var _hoisted_53 = { class: "reply-input-wrapper" };
13484
+ var _hoisted_54 = { class: "reply-actions" };
13485
+ var _hoisted_55 = ["disabled", "data-disabled-reason"];
13432
13486
  var commentEditSessions = /* @__PURE__ */ new WeakMap();
13433
13487
  var _sfc_main$33 = {
13434
13488
  __name: "CommentDialog",
@@ -13508,6 +13562,7 @@ var _sfc_main$33 = {
13508
13562
  };
13509
13563
  };
13510
13564
  const CLICK_OUTSIDE_IGNORED_SELECTORS = [
13565
+ ".superdoc__tools [data-id=\"is-tool\"]",
13511
13566
  ".comments-dropdown__option-label",
13512
13567
  ".comments-dropdown__menu",
13513
13568
  ".comments-dropdown__option",
@@ -13681,12 +13736,17 @@ var _sfc_main$33 = {
13681
13736
  const isReplying = require__plugin_vue_export_helper.ref(false);
13682
13737
  const isSubmittingReply = require__plugin_vue_export_helper.ref(false);
13683
13738
  const isSubmittingNewComment = require__plugin_vue_export_helper.ref(false);
13739
+ const commentSaveFailure = require__plugin_vue_export_helper.ref("");
13740
+ const commentSaveFailureMessage = (outcome, hasDraft = true) => {
13741
+ return `Your comment could not be saved${outcome?.detail === "document-mode-read-only" ? " because the document or connection is read-only" : outcome?.code === "PERMISSION_DENIED" ? " because you do not have permission" : ""}.${hasDraft ? " Your draft is still here. Try again or cancel." : " Try again."}`;
13742
+ };
13684
13743
  const startReply = () => {
13685
13744
  if (commentsAreReadOnly()) return readOnlyMutationOutcome();
13686
13745
  if (isV2WriteDisabled.value) return {
13687
13746
  ok: false,
13688
13747
  reason: v2WriteCapability.value?.reason ?? "v2-write-unavailable"
13689
13748
  };
13749
+ commentSaveFailure.value = "";
13690
13750
  isReplying.value = true;
13691
13751
  require__plugin_vue_export_helper.nextTick(() => {
13692
13752
  commentInput.value?.focus?.();
@@ -13936,6 +13996,7 @@ var _sfc_main$33 = {
13936
13996
  reason: "reply-submit-in-flight"
13937
13997
  };
13938
13998
  isSubmittingReply.value = true;
13999
+ commentSaveFailure.value = "";
13939
14000
  try {
13940
14001
  const parentCommentId = getV2ExistingReplyParentId(props.comment);
13941
14002
  const trackedChangeTarget = getV2TrackedChangeCommentTarget(props.comment);
@@ -13947,6 +14008,7 @@ var _sfc_main$33 = {
13947
14008
  ...trackedChangeTarget ? { trackedChangeTarget } : {}
13948
14009
  });
13949
14010
  if (!outcome?.ok) {
14011
+ commentSaveFailure.value = commentSaveFailureMessage(outcome);
13950
14012
  require__plugin_vue_export_helper.nextTick(() => emit("resize"));
13951
14013
  return outcome;
13952
14014
  }
@@ -13965,6 +14027,7 @@ var _sfc_main$33 = {
13965
14027
  reason: "comment-submit-in-flight"
13966
14028
  };
13967
14029
  isSubmittingNewComment.value = true;
14030
+ commentSaveFailure.value = "";
13968
14031
  }
13969
14032
  const options = {
13970
14033
  documentId: props.comment.fileId,
@@ -13980,7 +14043,10 @@ var _sfc_main$33 = {
13980
14043
  Promise.resolve().then(() => addComment({
13981
14044
  superdoc: proxy.$superdoc,
13982
14045
  comment
13983
- })).catch((err) => {
14046
+ })).then((outcome) => {
14047
+ if (isPendingNewComment.value && outcome?.ok === false) commentSaveFailure.value = commentSaveFailureMessage(outcome);
14048
+ }).catch((err) => {
14049
+ commentSaveFailure.value = commentSaveFailureMessage();
13984
14050
  console.error("[SuperDoc] addComment failed", err);
13985
14051
  }).finally(() => {
13986
14052
  isSubmittingNewComment.value = false;
@@ -14018,15 +14084,8 @@ var _sfc_main$33 = {
14018
14084
  const v2WriteCapability = require__plugin_vue_export_helper.computed(() => {
14019
14085
  v2CapabilityRevision.value;
14020
14086
  if (!v2CommentsAdapter.value) return null;
14021
- const documentMode = commentsStore.viewingVisibility.documentMode;
14022
14087
  const command = isPendingNewComment.value ? "comments.createFromSelection" : null;
14023
- const capability = v2CommentsAdapter.value.getCapabilityState?.(command) ?? null;
14024
- if (documentMode === "viewing" && !isPendingNewComment.value) return {
14025
- ...capability ?? {},
14026
- canWrite: false,
14027
- reason: "review-surface-read-only"
14028
- };
14029
- return capability;
14088
+ return v2CommentsAdapter.value.getCapabilityState?.(command) ?? null;
14030
14089
  });
14031
14090
  const isV2WriteDisabled = require__plugin_vue_export_helper.computed(() => {
14032
14091
  if (!isV2Mode.value) return false;
@@ -14212,10 +14271,15 @@ var _sfc_main$33 = {
14212
14271
  });
14213
14272
  v1TrackedChangeDecisionApplied = Boolean(outcome?.ok) && outcome.success !== false;
14214
14273
  } else if (isV2Mode.value && v2CommentsAdapter.value) {
14215
- if (!(await commentsStore.resolveCommentV2({
14274
+ const outcome = await commentsStore.resolveCommentV2({
14216
14275
  superdoc: proxy.$superdoc,
14217
14276
  commentId: props.comment.commentId
14218
- }))?.ok) return;
14277
+ });
14278
+ if (!outcome?.ok) {
14279
+ commentSaveFailure.value = commentSaveFailureMessage(outcome, false);
14280
+ return outcome;
14281
+ }
14282
+ commentSaveFailure.value = "";
14219
14283
  } else props.comment.resolveComment({
14220
14284
  id: superdocStore.user.id,
14221
14285
  email: superdocStore.user.email,
@@ -14244,17 +14308,22 @@ var _sfc_main$33 = {
14244
14308
  reason: "resolve-disabled"
14245
14309
  };
14246
14310
  if (!isV2Mode.value || !v2CommentsAdapter.value) return;
14247
- if (!(await commentsStore.reopenCommentV2({
14311
+ const outcome = await commentsStore.reopenCommentV2({
14248
14312
  superdoc: proxy.$superdoc,
14249
14313
  commentId: props.comment.commentId
14250
- }))?.ok) return;
14314
+ });
14315
+ if (!outcome?.ok) {
14316
+ commentSaveFailure.value = commentSaveFailureMessage(outcome, false);
14317
+ return outcome;
14318
+ }
14319
+ commentSaveFailure.value = "";
14251
14320
  require__plugin_vue_export_helper.nextTick(() => {
14252
14321
  commentsStore.lastUpdate = /* @__PURE__ */ new Date();
14253
14322
  commentsStore.setActiveComment(proxy.$superdoc, activeComment.value);
14254
14323
  proxy.$superdoc.focus?.();
14255
14324
  });
14256
14325
  };
14257
- const handleOverflowSelect = (value, comment) => {
14326
+ const handleOverflowSelect = async (value, comment) => {
14258
14327
  if (commentsAreReadOnly()) return readOnlyMutationOutcome();
14259
14328
  switch (value) {
14260
14329
  case "edit":
@@ -14273,10 +14342,13 @@ var _sfc_main$33 = {
14273
14342
  });
14274
14343
  break;
14275
14344
  case "delete":
14276
- deleteComment({
14277
- superdoc: proxy.$superdoc,
14278
- commentId: comment.commentId
14279
- });
14345
+ {
14346
+ const outcome = await deleteComment({
14347
+ superdoc: proxy.$superdoc,
14348
+ commentId: comment.commentId
14349
+ });
14350
+ commentSaveFailure.value = outcome?.ok ? "" : commentSaveFailureMessage(outcome, false);
14351
+ }
14280
14352
  break;
14281
14353
  }
14282
14354
  };
@@ -14297,8 +14369,12 @@ var _sfc_main$33 = {
14297
14369
  commentId: comment.commentId,
14298
14370
  text: draft
14299
14371
  });
14300
- if (!outcome?.ok) return outcome;
14301
14372
  if (session?.owner !== editSessionOwner || commentEditSessions.get(commentsStore) !== session || session.submission !== submission || proxy.$superdoc.activeEditor !== editor || editor.v2Comments !== adapter || adapter.documentId !== documentId || editor.doc !== document || props.comment !== thread || editingCommentId.value !== comment.commentId || currentCommentText.value !== draft) return outcome;
14373
+ if (!outcome?.ok) {
14374
+ commentSaveFailure.value = commentSaveFailureMessage(outcome);
14375
+ return outcome;
14376
+ }
14377
+ commentSaveFailure.value = "";
14302
14378
  retireOwnEditSession();
14303
14379
  editingCommentId.value = null;
14304
14380
  removePendingComment(proxy.$superdoc);
@@ -14330,6 +14406,7 @@ var _sfc_main$33 = {
14330
14406
  return typeof timestamp === "string" ? new Date(timestamp).getTime() : timestamp;
14331
14407
  };
14332
14408
  const handleCancel = (comment) => {
14409
+ commentSaveFailure.value = "";
14333
14410
  retireOwnEditSession();
14334
14411
  editingCommentId.value = null;
14335
14412
  isReplying.value = false;
@@ -14429,26 +14506,28 @@ var _sfc_main$33 = {
14429
14506
  "config",
14430
14507
  "comment"
14431
14508
  ])]),
14432
- require__plugin_vue_export_helper.createElementVNode("div", _hoisted_4$11, [require__plugin_vue_export_helper.createElementVNode("button", {
14509
+ commentSaveFailure.value ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("p", _hoisted_4$11, require__plugin_vue_export_helper.toDisplayString(commentSaveFailure.value), 1)) : require__plugin_vue_export_helper.createCommentVNode("", true),
14510
+ require__plugin_vue_export_helper.createElementVNode("div", _hoisted_5$8, [require__plugin_vue_export_helper.createElementVNode("button", {
14433
14511
  class: "sd-button reply-btn-cancel",
14434
14512
  onClick: require__plugin_vue_export_helper.withModifiers(handleCancel, ["stop", "prevent"])
14435
14513
  }, "Cancel"), require__plugin_vue_export_helper.createElementVNode("button", {
14436
14514
  class: require__plugin_vue_export_helper.normalizeClass(["sd-button primary reply-btn-primary", { "sd-is-disabled": !hasTextContent.value || isSubmittingNewComment.value }]),
14437
14515
  onClick: require__plugin_vue_export_helper.withModifiers(handleAddComment, ["stop", "prevent"]),
14438
14516
  disabled: !hasTextContent.value || isSubmittingNewComment.value
14439
- }, " Comment ", 10, _hoisted_5$8)])
14517
+ }, " Comment ", 10, _hoisted_6$6)])
14440
14518
  ], 64)) : (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock(require__plugin_vue_export_helper.Fragment, { key: 1 }, [
14441
- resolvedBadgeLabel.value ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_6$6, [require__plugin_vue_export_helper.createElementVNode("span", {
14519
+ resolvedBadgeLabel.value ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_7$4, [require__plugin_vue_export_helper.createElementVNode("span", {
14442
14520
  class: "resolved-badge__icon",
14443
14521
  innerHTML: require__plugin_vue_export_helper.unref(superdocIcons).markDone
14444
- }, null, 8, _hoisted_7$4), require__plugin_vue_export_helper.createTextVNode(" " + require__plugin_vue_export_helper.toDisplayString(resolvedBadgeLabel.value), 1)])) : require__plugin_vue_export_helper.createCommentVNode("", true),
14445
- shouldShowInternalExternal.value ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_8$4, [require__plugin_vue_export_helper.createVNode(InternalDropdown_default, {
14522
+ }, null, 8, _hoisted_8$4), require__plugin_vue_export_helper.createTextVNode(" " + require__plugin_vue_export_helper.toDisplayString(resolvedBadgeLabel.value), 1)])) : require__plugin_vue_export_helper.createCommentVNode("", true),
14523
+ shouldShowInternalExternal.value ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_9$3, [require__plugin_vue_export_helper.createVNode(InternalDropdown_default, {
14446
14524
  onClick: _cache[1] || (_cache[1] = require__plugin_vue_export_helper.withModifiers(() => {}, ["stop", "prevent"])),
14447
14525
  class: "sd-internal-dropdown",
14448
14526
  "is-disabled": isInternalDropdownDisabled.value,
14449
14527
  state: __props.comment.isInternal ? "internal" : "external",
14450
14528
  onSelect: handleInternalExternalSelect
14451
14529
  }, null, 8, ["is-disabled", "state"])])) : require__plugin_vue_export_helper.createCommentVNode("", true),
14530
+ commentSaveFailure.value ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("p", _hoisted_10$3, require__plugin_vue_export_helper.toDisplayString(commentSaveFailure.value), 1)) : require__plugin_vue_export_helper.createCommentVNode("", true),
14452
14531
  (require__plugin_vue_export_helper.openBlock(true), require__plugin_vue_export_helper.createElementBlock(require__plugin_vue_export_helper.Fragment, null, require__plugin_vue_export_helper.renderList(visibleComments.value, (comment, index) => {
14453
14532
  return require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", {
14454
14533
  key: comment.commentId,
@@ -14480,27 +14559,27 @@ var _sfc_main$33 = {
14480
14559
  "write-disabled-reason",
14481
14560
  "onOverflowSelect"
14482
14561
  ]),
14483
- comment.trackedChange ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_9$3, [
14562
+ comment.trackedChange ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_11$3, [
14484
14563
  require__plugin_vue_export_helper.createElementVNode("div", {
14485
14564
  class: require__plugin_vue_export_helper.normalizeClass(["tracked-change", index === 0 ? bodyOverflowClass.value : void 0]),
14486
14565
  "data-track-change-semantic-color-key": comment.semanticColorKey ?? void 0,
14487
14566
  ref_for: true,
14488
14567
  ref: index === 0 ? setParentBodyRef : void 0
14489
- }, [comment.trackedChangeLabel ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_11$3, [require__plugin_vue_export_helper.createElementVNode("span", _hoisted_12$2, require__plugin_vue_export_helper.toDisplayString(comment.trackedChangeLabel), 1), comment.trackedChangeDetailLines && comment.trackedChangeDetailLines.length ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_13$2, [(require__plugin_vue_export_helper.openBlock(true), require__plugin_vue_export_helper.createElementBlock(require__plugin_vue_export_helper.Fragment, null, require__plugin_vue_export_helper.renderList(comment.trackedChangeDetailLines, (line, lineIndex) => {
14568
+ }, [comment.trackedChangeLabel ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_13$2, [require__plugin_vue_export_helper.createElementVNode("span", _hoisted_14$2, require__plugin_vue_export_helper.toDisplayString(comment.trackedChangeLabel), 1), comment.trackedChangeDetailLines && comment.trackedChangeDetailLines.length ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_15$2, [(require__plugin_vue_export_helper.openBlock(true), require__plugin_vue_export_helper.createElementBlock(require__plugin_vue_export_helper.Fragment, null, require__plugin_vue_export_helper.renderList(comment.trackedChangeDetailLines, (line, lineIndex) => {
14490
14569
  return require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", {
14491
14570
  key: lineIndex,
14492
14571
  class: "tracked-change-detail-line"
14493
14572
  }, [
14494
- line.excerpt ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("span", _hoisted_14$2, "\"" + require__plugin_vue_export_helper.toDisplayString(line.excerpt) + "\"", 1)) : require__plugin_vue_export_helper.createCommentVNode("", true),
14495
- line.excerpt ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("span", _hoisted_15$2, " — ")) : require__plugin_vue_export_helper.createCommentVNode("", true),
14496
- require__plugin_vue_export_helper.createElementVNode("span", _hoisted_16$2, require__plugin_vue_export_helper.toDisplayString(line.label), 1)
14573
+ line.excerpt ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("span", _hoisted_16$2, "\"" + require__plugin_vue_export_helper.toDisplayString(line.excerpt) + "\"", 1)) : require__plugin_vue_export_helper.createCommentVNode("", true),
14574
+ line.excerpt ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("span", _hoisted_17$2, " — ")) : require__plugin_vue_export_helper.createCommentVNode("", true),
14575
+ require__plugin_vue_export_helper.createElementVNode("span", _hoisted_18$2, require__plugin_vue_export_helper.toDisplayString(line.label), 1)
14497
14576
  ]);
14498
- }), 128))])) : require__plugin_vue_export_helper.createCommentVNode("", true)])) : comment.trackedChangeDisplayType === "hyperlinkAdded" ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_17$2, [_cache[2] || (_cache[2] = require__plugin_vue_export_helper.createElementVNode("span", { class: "change-type" }, "Added hyperlink ", -1)), require__plugin_vue_export_helper.createElementVNode("span", _hoisted_18$2, "\"" + require__plugin_vue_export_helper.toDisplayString(comment.trackedChangeText) + "\"", 1)])) : comment.trackedChangeDisplayType === "hyperlinkModified" ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_19$1, [_cache[3] || (_cache[3] = require__plugin_vue_export_helper.createElementVNode("span", { class: "change-type" }, "Changed hyperlink to ", -1)), require__plugin_vue_export_helper.createElementVNode("span", _hoisted_20$1, "\"" + require__plugin_vue_export_helper.toDisplayString(comment.trackedChangeText) + "\"", 1)])) : comment.trackedChangeDisplayType === "paragraphSplit" ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_21$1, [..._cache[4] || (_cache[4] = [require__plugin_vue_export_helper.createElementVNode("span", { class: "change-type" }, "Added new line", -1)])])) : comment.trackedChangeDisplayType === "tableInsert" ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_22$1, [..._cache[5] || (_cache[5] = [require__plugin_vue_export_helper.createElementVNode("span", { class: "change-type" }, "Added table", -1)])])) : comment.trackedChangeDisplayType === "tableDelete" ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_23$1, [..._cache[6] || (_cache[6] = [require__plugin_vue_export_helper.createElementVNode("span", { class: "change-type" }, "Deleted table", -1)])])) : comment.trackedChangeType === "trackFormat" ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_24, [_cache[7] || (_cache[7] = require__plugin_vue_export_helper.createElementVNode("span", { class: "change-type" }, "Format: ", -1)), require__plugin_vue_export_helper.createElementVNode("span", _hoisted_25, require__plugin_vue_export_helper.toDisplayString(comment.trackedChangeText), 1)])) : comment.trackedChangeType === "both" ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_26, [
14577
+ }), 128))])) : require__plugin_vue_export_helper.createCommentVNode("", true)])) : comment.trackedChangeDisplayType === "hyperlinkAdded" ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_19$1, [_cache[2] || (_cache[2] = require__plugin_vue_export_helper.createElementVNode("span", { class: "change-type" }, "Added hyperlink ", -1)), require__plugin_vue_export_helper.createElementVNode("span", _hoisted_20$1, "\"" + require__plugin_vue_export_helper.toDisplayString(comment.trackedChangeText) + "\"", 1)])) : comment.trackedChangeDisplayType === "hyperlinkModified" ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_21$1, [_cache[3] || (_cache[3] = require__plugin_vue_export_helper.createElementVNode("span", { class: "change-type" }, "Changed hyperlink to ", -1)), require__plugin_vue_export_helper.createElementVNode("span", _hoisted_22$1, "\"" + require__plugin_vue_export_helper.toDisplayString(comment.trackedChangeText) + "\"", 1)])) : comment.trackedChangeDisplayType === "paragraphSplit" ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_23$1, [..._cache[4] || (_cache[4] = [require__plugin_vue_export_helper.createElementVNode("span", { class: "change-type" }, "Added new line", -1)])])) : comment.trackedChangeDisplayType === "tableInsert" ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_24, [..._cache[5] || (_cache[5] = [require__plugin_vue_export_helper.createElementVNode("span", { class: "change-type" }, "Added table", -1)])])) : comment.trackedChangeDisplayType === "tableDelete" ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_25, [..._cache[6] || (_cache[6] = [require__plugin_vue_export_helper.createElementVNode("span", { class: "change-type" }, "Deleted table", -1)])])) : comment.trackedChangeType === "trackFormat" ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_26, [_cache[7] || (_cache[7] = require__plugin_vue_export_helper.createElementVNode("span", { class: "change-type" }, "Format: ", -1)), require__plugin_vue_export_helper.createElementVNode("span", _hoisted_27, require__plugin_vue_export_helper.toDisplayString(comment.trackedChangeText), 1)])) : comment.trackedChangeType === "both" ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_28, [
14499
14578
  _cache[8] || (_cache[8] = require__plugin_vue_export_helper.createElementVNode("span", { class: "change-type" }, "Replaced ", -1)),
14500
- require__plugin_vue_export_helper.createElementVNode("span", _hoisted_27, "\"" + require__plugin_vue_export_helper.toDisplayString(comment.deletedText) + "\"", 1),
14579
+ require__plugin_vue_export_helper.createElementVNode("span", _hoisted_29, "\"" + require__plugin_vue_export_helper.toDisplayString(comment.deletedText) + "\"", 1),
14501
14580
  _cache[9] || (_cache[9] = require__plugin_vue_export_helper.createElementVNode("span", { class: "change-type" }, " with ", -1)),
14502
- require__plugin_vue_export_helper.createElementVNode("span", _hoisted_28, "\"" + require__plugin_vue_export_helper.toDisplayString(comment.trackedChangeText) + "\"", 1)
14503
- ])) : comment.deletedText && comment.deletedText === "\n" ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_29, [..._cache[10] || (_cache[10] = [require__plugin_vue_export_helper.createElementVNode("span", { class: "change-type" }, "Deleted line break", -1)])])) : comment.trackedChangeText && comment.trackedChangeText === "\n" ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_30, [..._cache[11] || (_cache[11] = [require__plugin_vue_export_helper.createElementVNode("span", { class: "change-type" }, "Added line break", -1)])])) : comment.deletedText ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_31, [_cache[12] || (_cache[12] = require__plugin_vue_export_helper.createElementVNode("span", { class: "change-type" }, "Deleted ", -1)), require__plugin_vue_export_helper.createElementVNode("span", _hoisted_32, "\"" + require__plugin_vue_export_helper.toDisplayString(comment.deletedText) + "\"", 1)])) : comment.trackedChangeText ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_33, [_cache[13] || (_cache[13] = require__plugin_vue_export_helper.createElementVNode("span", { class: "change-type" }, "Added ", -1)), require__plugin_vue_export_helper.createElementVNode("span", _hoisted_34, "\"" + require__plugin_vue_export_helper.toDisplayString(comment.trackedChangeText) + "\"", 1)])) : require__plugin_vue_export_helper.createCommentVNode("", true), comment.trackedChangeImagePreview?.src ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", {
14581
+ require__plugin_vue_export_helper.createElementVNode("span", _hoisted_30, "\"" + require__plugin_vue_export_helper.toDisplayString(comment.trackedChangeText) + "\"", 1)
14582
+ ])) : comment.deletedText && comment.deletedText === "\n" ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_31, [..._cache[10] || (_cache[10] = [require__plugin_vue_export_helper.createElementVNode("span", { class: "change-type" }, "Deleted line break", -1)])])) : comment.trackedChangeText && comment.trackedChangeText === "\n" ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_32, [..._cache[11] || (_cache[11] = [require__plugin_vue_export_helper.createElementVNode("span", { class: "change-type" }, "Added line break", -1)])])) : comment.deletedText ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_33, [_cache[12] || (_cache[12] = require__plugin_vue_export_helper.createElementVNode("span", { class: "change-type" }, "Deleted ", -1)), require__plugin_vue_export_helper.createElementVNode("span", _hoisted_34, "\"" + require__plugin_vue_export_helper.toDisplayString(comment.deletedText) + "\"", 1)])) : comment.trackedChangeText ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_35, [_cache[13] || (_cache[13] = require__plugin_vue_export_helper.createElementVNode("span", { class: "change-type" }, "Added ", -1)), require__plugin_vue_export_helper.createElementVNode("span", _hoisted_36, "\"" + require__plugin_vue_export_helper.toDisplayString(comment.trackedChangeText) + "\"", 1)])) : require__plugin_vue_export_helper.createCommentVNode("", true), comment.trackedChangeImagePreview?.src ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", {
14504
14583
  key: 12,
14505
14584
  class: "tracked-change-image-preview",
14506
14585
  "data-track-change-image-preview-role": comment.trackedChangeImagePreview.role ?? void 0
@@ -14511,7 +14590,7 @@ var _sfc_main$33 = {
14511
14590
  style: require__plugin_vue_export_helper.normalizeStyle(trackedChangeImagePreviewStyle(comment.trackedChangeImagePreview)),
14512
14591
  loading: "lazy",
14513
14592
  decoding: "async"
14514
- }, null, 12, _hoisted_36)], 8, _hoisted_35)) : require__plugin_vue_export_helper.createCommentVNode("", true)], 10, _hoisted_10$3),
14593
+ }, null, 12, _hoisted_38)], 8, _hoisted_37)) : require__plugin_vue_export_helper.createCommentVNode("", true)], 10, _hoisted_12$2),
14515
14594
  shouldTruncate.value && isTextOverflowing.value && index === 0 ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", {
14516
14595
  key: 0,
14517
14596
  class: "show-more-toggle",
@@ -14523,29 +14602,29 @@ var _sfc_main$33 = {
14523
14602
  onClick: require__plugin_vue_export_helper.withModifiers(toggleTruncation, ["stop", "prevent"])
14524
14603
  }, " Show less ")) : require__plugin_vue_export_helper.createCommentVNode("", true)
14525
14604
  ])) : require__plugin_vue_export_helper.createCommentVNode("", true),
14526
- !comment.trackedChange ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_37, [
14605
+ !comment.trackedChange ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_39, [
14527
14606
  !require__plugin_vue_export_helper.unref(isDebugging) && !isEditingThisComment.value(comment) ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", {
14528
14607
  key: 0,
14529
14608
  class: require__plugin_vue_export_helper.normalizeClass(["comment", index === 0 ? bodyOverflowClass.value : void 0]),
14530
14609
  ref_for: true,
14531
14610
  ref: index === 0 ? setParentBodyRef : void 0,
14532
14611
  innerHTML: renderedCommentTexts.value.get(comment.commentId)
14533
- }, null, 10, _hoisted_38)) : require__plugin_vue_export_helper.unref(isDebugging) && !isEditingThisComment.value(comment) ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_39, require__plugin_vue_export_helper.toDisplayString(require__plugin_vue_export_helper.unref(editorCommentPositions)[comment.importedId !== void 0 ? comment.importedId : comment.commentId]?.bounds), 1)) : (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_40, [require__plugin_vue_export_helper.createElementVNode("div", _hoisted_41, [require__plugin_vue_export_helper.createVNode(CommentInput_default, {
14612
+ }, null, 10, _hoisted_40)) : require__plugin_vue_export_helper.unref(isDebugging) && !isEditingThisComment.value(comment) ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_41, require__plugin_vue_export_helper.toDisplayString(require__plugin_vue_export_helper.unref(editorCommentPositions)[comment.importedId !== void 0 ? comment.importedId : comment.commentId]?.bounds), 1)) : (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_42, [require__plugin_vue_export_helper.createElementVNode("div", _hoisted_43, [require__plugin_vue_export_helper.createVNode(CommentInput_default, {
14534
14613
  ref_for: true,
14535
14614
  ref: setEditCommentInputRef(comment.commentId),
14536
14615
  users: [],
14537
14616
  config: require__plugin_vue_export_helper.unref(getConfig),
14538
14617
  "include-header": false,
14539
14618
  comment
14540
- }, null, 8, ["config", "comment"])]), require__plugin_vue_export_helper.createElementVNode("div", _hoisted_42, [require__plugin_vue_export_helper.createElementVNode("button", {
14619
+ }, null, 8, ["config", "comment"])]), require__plugin_vue_export_helper.createElementVNode("div", _hoisted_44, [require__plugin_vue_export_helper.createElementVNode("button", {
14541
14620
  class: "sd-button reply-btn-cancel",
14542
14621
  onClick: require__plugin_vue_export_helper.withModifiers(($event) => handleCancel(comment), ["stop", "prevent"])
14543
- }, "Cancel", 8, _hoisted_43), require__plugin_vue_export_helper.createElementVNode("button", {
14622
+ }, "Cancel", 8, _hoisted_45), require__plugin_vue_export_helper.createElementVNode("button", {
14544
14623
  class: require__plugin_vue_export_helper.normalizeClass(["sd-button primary reply-btn-primary", { "sd-is-disabled": !hasTextContent.value || isV2WriteDisabled.value }]),
14545
14624
  onClick: require__plugin_vue_export_helper.withModifiers(($event) => handleCommentUpdate(comment), ["stop", "prevent"]),
14546
14625
  disabled: !hasTextContent.value || isV2WriteDisabled.value,
14547
14626
  "data-disabled-reason": isV2WriteDisabled.value ? v2WriteCapability.value?.reason ?? null : null
14548
- }, " Update ", 10, _hoisted_44)])])),
14627
+ }, " Update ", 10, _hoisted_46)])])),
14549
14628
  shouldTruncate.value && isTextOverflowing.value && index === 0 && !isEditingThisComment.value(comment) ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", {
14550
14629
  key: 3,
14551
14630
  class: "show-more-toggle",
@@ -14560,29 +14639,29 @@ var _sfc_main$33 = {
14560
14639
  shouldCollapseThread.value && index === 0 ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock(require__plugin_vue_export_helper.Fragment, { key: 2 }, [_cache[14] || (_cache[14] = require__plugin_vue_export_helper.createElementVNode("div", { class: "comment-separator" }, null, -1)), require__plugin_vue_export_helper.createElementVNode("div", {
14561
14640
  class: "collapsed-replies",
14562
14641
  onClick: require__plugin_vue_export_helper.withModifiers(expandThread, ["stop", "prevent"])
14563
- }, [require__plugin_vue_export_helper.createElementVNode("div", _hoisted_45, [(require__plugin_vue_export_helper.openBlock(true), require__plugin_vue_export_helper.createElementBlock(require__plugin_vue_export_helper.Fragment, null, require__plugin_vue_export_helper.renderList(collapsedReplyAuthors.value, (author) => {
14642
+ }, [require__plugin_vue_export_helper.createElementVNode("div", _hoisted_47, [(require__plugin_vue_export_helper.openBlock(true), require__plugin_vue_export_helper.createElementBlock(require__plugin_vue_export_helper.Fragment, null, require__plugin_vue_export_helper.renderList(collapsedReplyAuthors.value, (author) => {
14564
14643
  return require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createBlock(Avatar_default, {
14565
14644
  key: author.email || author.name,
14566
14645
  user: author,
14567
14646
  class: "mini-avatar"
14568
14647
  }, null, 8, ["user"]);
14569
14648
  }), 128))]), require__plugin_vue_export_helper.createElementVNode("span", null, require__plugin_vue_export_helper.toDisplayString(collapsedReplyCount.value) + " more " + require__plugin_vue_export_helper.toDisplayString(collapsedReplyCount.value === 1 ? "reply" : "replies"), 1)])], 64)) : require__plugin_vue_export_helper.createCommentVNode("", true),
14570
- showSeparator.value(index) ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_46)) : require__plugin_vue_export_helper.createCommentVNode("", true)
14649
+ showSeparator.value(index) ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_48)) : require__plugin_vue_export_helper.createCommentVNode("", true)
14571
14650
  ]);
14572
14651
  }), 128)),
14573
- trackedChangeDecisionFailure.value ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_47, [require__plugin_vue_export_helper.createElementVNode("span", _hoisted_48, require__plugin_vue_export_helper.toDisplayString(trackedChangeDecisionFailureMessage.value), 1), require__plugin_vue_export_helper.createElementVNode("button", {
14652
+ trackedChangeDecisionFailure.value ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_49, [require__plugin_vue_export_helper.createElementVNode("span", _hoisted_50, require__plugin_vue_export_helper.toDisplayString(trackedChangeDecisionFailureMessage.value), 1), require__plugin_vue_export_helper.createElementVNode("button", {
14574
14653
  type: "button",
14575
14654
  class: "sd-button tracked-change-decision-alert__retry",
14576
14655
  onClick: require__plugin_vue_export_helper.withModifiers(retryTrackedChangeDecision, ["stop", "prevent"])
14577
14656
  }, " Retry ")])) : require__plugin_vue_export_helper.createCommentVNode("", true),
14578
- showInputSection.value && !require__plugin_vue_export_helper.unref(getConfig).readOnly ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock(require__plugin_vue_export_helper.Fragment, { key: 3 }, [!isReplying.value ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("button", {
14657
+ showInputSection.value && !require__plugin_vue_export_helper.unref(getConfig).readOnly ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock(require__plugin_vue_export_helper.Fragment, { key: 4 }, [!isReplying.value ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("button", {
14579
14658
  key: 0,
14580
14659
  type: "button",
14581
14660
  class: require__plugin_vue_export_helper.normalizeClass(["reply-pill", { "sd-is-disabled": isV2WriteDisabled.value }]),
14582
14661
  onClick: require__plugin_vue_export_helper.withModifiers(startReply, ["stop", "prevent"]),
14583
14662
  disabled: isV2WriteDisabled.value,
14584
14663
  "data-disabled-reason": isV2WriteDisabled.value ? v2WriteCapability.value?.reason ?? null : null
14585
- }, " Reply or add others with @ ", 10, _hoisted_49)) : (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_50, [require__plugin_vue_export_helper.createElementVNode("div", _hoisted_51, [require__plugin_vue_export_helper.createVNode(CommentInput_default, {
14664
+ }, " Reply or add others with @ ", 10, _hoisted_51)) : (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_52, [require__plugin_vue_export_helper.createElementVNode("div", _hoisted_53, [require__plugin_vue_export_helper.createVNode(CommentInput_default, {
14586
14665
  ref_key: "commentInput",
14587
14666
  ref: commentInput,
14588
14667
  users: usersFiltered.value,
@@ -14593,7 +14672,7 @@ var _sfc_main$33 = {
14593
14672
  "users",
14594
14673
  "config",
14595
14674
  "comment"
14596
- ])]), require__plugin_vue_export_helper.createElementVNode("div", _hoisted_52, [require__plugin_vue_export_helper.createElementVNode("button", {
14675
+ ])]), require__plugin_vue_export_helper.createElementVNode("div", _hoisted_54, [require__plugin_vue_export_helper.createElementVNode("button", {
14597
14676
  class: "sd-button reply-btn-cancel",
14598
14677
  onClick: require__plugin_vue_export_helper.withModifiers(handleCancel, ["stop", "prevent"])
14599
14678
  }, "Cancel"), require__plugin_vue_export_helper.createElementVNode("button", {
@@ -14601,12 +14680,12 @@ var _sfc_main$33 = {
14601
14680
  onClick: require__plugin_vue_export_helper.withModifiers(handleAddComment, ["stop", "prevent"]),
14602
14681
  disabled: !hasTextContent.value || isV2WriteDisabled.value || isSubmittingReply.value,
14603
14682
  "data-disabled-reason": v2ReplyDisabledReason.value
14604
- }, " Reply ", 10, _hoisted_53)])]))], 64)) : require__plugin_vue_export_helper.createCommentVNode("", true)
14683
+ }, " Reply ", 10, _hoisted_55)])]))], 64)) : require__plugin_vue_export_helper.createCommentVNode("", true)
14605
14684
  ], 64))], 14, _hoisted_1$26)), [[_directive_click_outside, handleClickOutside]]);
14606
14685
  };
14607
14686
  }
14608
14687
  };
14609
- var CommentDialog_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$33, [["__scopeId", "data-v-f5016db4"]]);
14688
+ var CommentDialog_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$33, [["__scopeId", "data-v-f8b79c74"]]);
14610
14689
  //#endregion
14611
14690
  //#region src/components/CommentsLayer/commentsList/ReviewDirectoryListItem.vue
14612
14691
  var _hoisted_1$25 = [
@@ -15331,6 +15410,80 @@ var composeAuthorColorResolver = (config) => {
15331
15410
  };
15332
15411
  };
15333
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
15334
15487
  //#region ../document-api/src/permission-ranges/permission-ranges.ts
15335
15488
  function editorKey(editor) {
15336
15489
  return editor.id?.trim() ? editor.id : editor.email?.trim() || void 0;
@@ -20090,6 +20243,28 @@ function useLinkPopover({ getSurfaceManager, getActiveEditor, getUi, getActivati
20090
20243
  };
20091
20244
  }
20092
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
20093
20268
  //#region src/core/editor-runtime/v2/v2-editor-runtime-adapter.ts
20094
20269
  var DEFAULT_V2_LEGACY_PROJECTION = Object.freeze({
20095
20270
  editorVersion: 2,
@@ -20729,7 +20904,7 @@ function createV2EditorRuntimeAdapter(options) {
20729
20904
  save: () => host.save(),
20730
20905
  exportDocx: (options) => host.save({
20731
20906
  format: "docx",
20732
- commentExportMode: options?.commentsType === "clean" ? "strip" : "preserve"
20907
+ ...resolveV2DocxExportOptions(options)
20733
20908
  }),
20734
20909
  async setZoom(percent) {
20735
20910
  const result = host.setZoom(percent);
@@ -21984,7 +22159,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
21984
22159
  const { proxy } = require__plugin_vue_export_helper.getCurrentInstance();
21985
22160
  commentsStore.proxy = proxy;
21986
22161
  const documentOpenTelemetry = createDocumentOpenTelemetry(proxy.$superdoc.config);
21987
- const resolvedEditorIntegration = resolveV2Integration(proxy.$superdoc.config);
22162
+ const resolvedEditorIntegration = createDefaultV2Integration();
21988
22163
  const V2DocumentEditor = require__plugin_vue_export_helper.markRaw(resolvedEditorIntegration.EditorComponent);
21989
22164
  const V2Ruler = resolvedEditorIntegration.RulerComponent ? require__plugin_vue_export_helper.markRaw(resolvedEditorIntegration.RulerComponent) : null;
21990
22165
  const floatingComments = require__plugin_vue_export_helper.computed(() => {
@@ -22130,6 +22305,10 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
22130
22305
  return layers.value.getBoundingClientRect().top + top * zoom;
22131
22306
  };
22132
22307
  const handleCommentToolClick = async () => {
22308
+ if (isV2Mode.value) {
22309
+ cancelScheduledV2DomSelectionSync();
22310
+ if (applyCurrentV2DomSelection()?.ok === false) return;
22311
+ }
22133
22312
  if ((await showAddComment(proxy.$superdoc, getPendingCommentTargetClientY()))?.ok === false) return;
22134
22313
  if (!isV2Mode.value) return;
22135
22314
  const pendingPosition = buildV2PendingPositionEntry();
@@ -22402,10 +22581,9 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
22402
22581
  return host.save(saveOptions);
22403
22582
  });
22404
22583
  const exportV2Docx = async (options = {}) => {
22405
- const commentExportMode = options?.commentsType === "clean" ? "strip" : "preserve";
22406
22584
  const bytes = await saveV2Bytes({
22407
22585
  format: "docx",
22408
- commentExportMode
22586
+ ...resolveV2DocxExportOptions(options)
22409
22587
  });
22410
22588
  return new Blob([bytes], { type: DOCX });
22411
22589
  };
@@ -22680,6 +22858,9 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
22680
22858
  subscribe: (listener) => v2ReviewWindowController.subscribe?.(listener) ?? (() => void 0)
22681
22859
  },
22682
22860
  extensions: createV2ExtensionsFacet(host),
22861
+ get visuals() {
22862
+ return typeof host?.getHostVisuals === "function" ? host.getHostVisuals() : null;
22863
+ },
22683
22864
  fonts: fonts ?? host?.getFontRuntime?.() ?? null,
22684
22865
  /**
22685
22866
  * The v2 active-editor facade explicitly does NOT carry v1 commands /
@@ -22845,7 +23026,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
22845
23026
  const result = handles?.selection?.applyDomSelection?.(selection);
22846
23027
  if (!result?.ok || result.mode !== "range") {
22847
23028
  clearV2SelectionToolbarState();
22848
- return;
23029
+ return { ok: false };
22849
23030
  }
22850
23031
  v2DomMirroredRange.value = true;
22851
23032
  v2HasRangeSelection.value = true;
@@ -23307,7 +23488,8 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
23307
23488
  return;
23308
23489
  }
23309
23490
  const collaborationException = createCollaborationException(reason, documentId);
23310
- const message = collaborationException?.error.message ?? getV2EditorFailureMessage(reason);
23491
+ const baseMessage = collaborationException?.error.message ?? getV2EditorFailureMessage(reason);
23492
+ const message = reason === "collaboration-config-invalid" && detail ? `${baseMessage} ${detail}` : baseMessage;
23311
23493
  const workerFailure = payload?.workerFailure && typeof payload.workerFailure === "object" ? payload.workerFailure : null;
23312
23494
  setV2EditorFailure(documentId, {
23313
23495
  reason,
@@ -23323,7 +23505,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
23323
23505
  };
23324
23506
  if (reason === "collaboration-v1-config-unsupported" || reason === "collaboration-room-format-unsupported" || reason === "collaboration-room-format-conflict" || reason === "collaboration-room-corrupt" || reason === "collaboration-v2-room-missing" || reason === "collaboration-v2-room-already-exists" || reason === "collaboration-v2-room-initializing" || reason === "collaboration-v2-room-bootstrap-stalled" || reason === "collaboration-open-intent-invalid" || reason === "collaboration-config-invalid") console.warn(`[SuperDoc] ${message}`, logContext);
23325
23507
  else console.error(`[SuperDoc] ${message}`, logContext);
23326
- proxy.$superdoc.emit("exception", collaborationException ?? {
23508
+ proxy.$superdoc.emit("exception", collaborationException && reason !== "collaboration-config-invalid" ? collaborationException : {
23327
23509
  error: new Error(message),
23328
23510
  code: reason,
23329
23511
  ...documentId ? { documentId } : {},
@@ -23497,6 +23679,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
23497
23679
  emitCommentPositionsInViewing: isViewingMode() && shouldRenderCommentsInViewing.value,
23498
23680
  enableCommentsInViewing: isViewingCommentsVisible.value,
23499
23681
  contentControlsChrome: proxy.$superdoc.uiConfig.contentControls.options.chrome,
23682
+ commentHighlights: proxy.$superdoc.uiConfig.comments.highlights,
23500
23683
  resolveTrackedChangeColor: composeAuthorColorResolver(proxy.$superdoc.config.modules?.trackChanges?.authorColors)
23501
23684
  } : void 0,
23502
23685
  permissionResolver: createTrackedChangePermissionResolver(proxy.$superdoc)
@@ -24551,7 +24734,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
24551
24734
  ], 46, _hoisted_1$17);
24552
24735
  };
24553
24736
  }
24554
- }, [["__scopeId", "data-v-143de6c8"]]);
24737
+ }, [["__scopeId", "data-v-f2db957f"]]);
24555
24738
  //#endregion
24556
24739
  //#region src/core/create-app.js
24557
24740
  var PINIA_DEVTOOLS_SETUP_EVENT = "devtools-plugin:setup";
@@ -38013,6 +38196,11 @@ var COMMENT_POLICY_FIELDS = Object.freeze([
38013
38196
  "allowResolve",
38014
38197
  "permissionResolver"
38015
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
+ }
38016
38204
  /**
38017
38205
  * Drop policy fields from a presentation options bag.
38018
38206
  */
@@ -38357,8 +38545,9 @@ function normalizeUiConfig(config = {}) {
38357
38545
  }
38358
38546
  },
38359
38547
  comments: {
38360
- enabled: explicit("comments") ?? (!allDisabled && config.modules?.comments !== false),
38361
- 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")))) || {}
38362
38551
  },
38363
38552
  contextMenu: {
38364
38553
  enabled: explicit("contextMenu") ?? (!allDisabled && config.disableContextMenu !== true),
@@ -41492,9 +41681,6 @@ var TABLE_ACTION_COMMAND_MAP = {
41492
41681
  fixTables: "table-fix"
41493
41682
  };
41494
41683
  var TABLE_ACTION_COMMAND_IDS = Object.values(TABLE_ACTION_COMMAND_MAP);
41495
- [.../* @__PURE__ */ new Set([...Object.values(HEADLESS_ITEM_MAP), ...TABLE_ACTION_COMMAND_IDS])];
41496
- var NON_HEADLESS_EXECUTE_ITEM_NAMES = /* @__PURE__ */ new Set(["link"]);
41497
- new Set(Object.keys(HEADLESS_ITEM_MAP).filter((itemName) => !NON_HEADLESS_EXECUTE_ITEM_NAMES.has(itemName)));
41498
41684
  //#endregion
41499
41685
  //#region src/internal/toolbar/built-in/Toolbar.vue
41500
41686
  var _hoisted_1$10 = ["data-superdoc-ui-owner"];
@@ -46280,7 +46466,7 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
46280
46466
  }
46281
46467
  this.userColorMap = /* @__PURE__ */ new Map();
46282
46468
  this.colorIndex = 0;
46283
- this.version = "2.28.0-next.1";
46469
+ this.version = "2.28.0-next.11";
46284
46470
  this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
46285
46471
  this.superdocId = config.superdocId || require_uuid.v4();
46286
46472
  this.colors = this.config.colors ?? [];
@@ -46996,7 +47182,8 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
46996
47182
  ...syncTimeoutOption,
46997
47183
  ...target.serverUrl ? { serverUrl: target.serverUrl } : {},
46998
47184
  ...target.params ? { params: target.params } : {},
46999
- ...target.token ? { token: target.token } : {}
47185
+ ...target.token ? { token: target.token } : {},
47186
+ ...target.retry !== void 0 ? { retry: target.retry } : {}
47000
47187
  };
47001
47188
  return {
47002
47189
  providerType: "y-websocket",
@@ -48233,12 +48420,13 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
48233
48420
  * Export the superdoc to a file
48234
48421
  * @param params - Export configuration
48235
48422
  */
48236
- 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 } = {}) {
48237
48424
  if (!Array.isArray(exportType) || exportType.length !== 1 || exportType[0] !== "docx") throw new TypeError("SuperDoc.export() only supports exportType: [\"docx\"].");
48238
48425
  const baseFileName = exportedName ? cleanName(exportedName) : cleanName(this.config.title);
48239
48426
  const docxFiles = await this.exportEditorsToDOCX({
48240
48427
  commentsType,
48241
48428
  isFinalDoc,
48429
+ policies,
48242
48430
  fieldsHighlightColor
48243
48431
  });
48244
48432
  const blobsToZip = [...additionalFiles];
@@ -48324,7 +48512,12 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
48324
48512
  * Export editors to DOCX format.
48325
48513
  * @param [options]
48326
48514
  */
48327
- 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
+ });
48328
48521
  const uiStoreHydrated = this.config?.modules?.comments !== false;
48329
48522
  let legacyComments;
48330
48523
  let legacyCommentsComputed = false;
@@ -48344,7 +48537,13 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
48344
48537
  };
48345
48538
  this.on("exception", rememberBridgedExportError);
48346
48539
  try {
48347
- 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) => {
48348
48547
  if (!doc || doc.type !== "application/vnd.openxmlformats-officedocument.wordprocessingml.document") return null;
48349
48548
  const editor = typeof doc.getEditor === "function" ? doc.getEditor() : null;
48350
48549
  const fallbackDocx = () => {
@@ -48361,6 +48560,7 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
48361
48560
  const exported = await editor.exportDocx(isV2Editor ? {
48362
48561
  isFinalDoc,
48363
48562
  commentsType,
48563
+ policies,
48364
48564
  fieldsHighlightColor
48365
48565
  } : {
48366
48566
  isFinalDoc,
@@ -48689,7 +48889,11 @@ function defineSuperDocExtension(extension) {
48689
48889
  return extension;
48690
48890
  }
48691
48891
  //#endregion
48692
- 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;
48693
48897
  exports.DOCX = DOCX;
48694
48898
  exports.DocumentLoadError = DocumentLoadError;
48695
48899
  exports.HTML = HTML;