superdoc 2.28.0-next.12 → 2.28.0-next.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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-8dttPeGi.cjs");
4
+ const require_create_super_doc_ui = require("./chunks/create-super-doc-ui-CFlvn2wr.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.12";
263
+ return "2.28.0-next.14";
264
264
  } catch {
265
265
  return "unknown";
266
266
  }
@@ -6843,87 +6843,6 @@ var useSuperdocStore = defineStore("superdoc", () => {
6843
6843
  };
6844
6844
  });
6845
6845
  //#endregion
6846
- //#region src/helpers/group-changes.js
6847
- /**
6848
- * Track changes helper
6849
- * Combines replace transactions which are represented by insertion + deletion
6850
- *
6851
- * @param {Array} changes - Array of tracked changes from the editor
6852
- * @returns {Array} Grouped track changes array with combined replacements
6853
- */
6854
- var groupChanges = (changes) => {
6855
- const markMetaKeys = {
6856
- trackInsert: "insertedMark",
6857
- trackDelete: "deletionMark",
6858
- trackFormat: "formatMark"
6859
- };
6860
- const byId = /* @__PURE__ */ new Map();
6861
- for (const change of changes) {
6862
- const id = change.mark.attrs.id;
6863
- if (!byId.has(id)) byId.set(id, []);
6864
- byId.get(id).push(change);
6865
- }
6866
- const grouped = [];
6867
- for (const [, group] of byId) {
6868
- if (group.length === 1) {
6869
- const c = group[0];
6870
- const key = markMetaKeys[c.mark.type.name];
6871
- grouped.push({
6872
- from: c.from,
6873
- to: c.to,
6874
- [key]: c
6875
- });
6876
- continue;
6877
- }
6878
- const processed = /* @__PURE__ */ new Set();
6879
- for (let i = 0; i < group.length; i++) {
6880
- if (processed.has(i)) continue;
6881
- const c1 = group[i];
6882
- const c1Key = markMetaKeys[c1.mark.type.name];
6883
- const c2 = group[i + 1];
6884
- if (c2 && !processed.has(i + 1) && c1.to === c2.from && c1.mark.type.name !== c2.mark.type.name) {
6885
- const c2Key = markMetaKeys[c2.mark.type.name];
6886
- grouped.push({
6887
- from: c1.from,
6888
- to: c2.to,
6889
- [c1Key]: c1,
6890
- [c2Key]: c2
6891
- });
6892
- processed.add(i);
6893
- processed.add(i + 1);
6894
- continue;
6895
- }
6896
- let foundMatch = false;
6897
- for (let j = i + 1; j < group.length; j++) {
6898
- if (processed.has(j)) continue;
6899
- const cj = group[j];
6900
- if (c1.mark.type.name !== cj.mark.type.name) {
6901
- const cjKey = markMetaKeys[cj.mark.type.name];
6902
- grouped.push({
6903
- from: Math.min(c1.from, cj.from),
6904
- to: Math.max(c1.to, cj.to),
6905
- [c1Key]: c1,
6906
- [cjKey]: cj
6907
- });
6908
- processed.add(i);
6909
- processed.add(j);
6910
- foundMatch = true;
6911
- break;
6912
- }
6913
- }
6914
- if (!foundMatch) {
6915
- grouped.push({
6916
- from: c1.from,
6917
- to: c1.to,
6918
- [c1Key]: c1
6919
- });
6920
- processed.add(i);
6921
- }
6922
- }
6923
- }
6924
- return grouped;
6925
- };
6926
- //#endregion
6927
6846
  //#region src/stores/helpers/floating-comment-instances.js
6928
6847
  var HEADER_FOOTER_TRACKED_CHANGE_STORY_TYPE = "headerFooterPart";
6929
6848
  var toFinitePageIndex = (value) => {
@@ -7484,20 +7403,6 @@ var buildTrackedChangeDecisionLinkIndex = (allComments, previous = /* @__PURE__
7484
7403
  };
7485
7404
  //#endregion
7486
7405
  //#region src/stores/comments-store.js
7487
- var Editor = class {
7488
- constructor() {
7489
- throw new Error("SuperDoc v2 beta: v1 editor-backed comment import paths are not available.");
7490
- }
7491
- };
7492
- var trackChangesHelpers = {
7493
- getTrackChanges: () => [],
7494
- enumerateStructuralRowChanges: () => []
7495
- };
7496
- var CommentsPluginKey = Symbol("comments-plugin-disabled");
7497
- var getRichTextExtensions = () => [];
7498
- var createOrUpdateTrackedChangeComment = () => null;
7499
- var getTrackedChangeIndex = () => null;
7500
- var resolveTrackedChangeInStory = () => null;
7501
7406
  var makeTrackedChangeAnchorKey = ({ storyKey, rawId }) => `tc::${storyKey}::${rawId}`;
7502
7407
  var COMMENT_DRAFT_BR_TAG = /<br(?:\s[^>]*)?\s*\/?>/gi;
7503
7408
  var COMMENT_DRAFT_BLOCK_BOUNDARY = /(?:<\/(?:p|div|li|blockquote|pre|h[1-6])\s*>\s*)+(?:<(?:p|div|li|blockquote|pre|h[1-6])(?:\s[^>]*)?\s*\/?>)+/gi;
@@ -7642,25 +7547,6 @@ var useCommentsStore = defineStore("comments", () => {
7642
7547
  rawId: String(rawId)
7643
7548
  });
7644
7549
  };
7645
- /**
7646
- * Compute the stable public id for a structural (whole-table) tracked change.
7647
- *
7648
- * This MUST match the public id the document-api projects for the same change
7649
- * (`tracked-change-resolver.groupTrackedChanges`), otherwise the right-rail
7650
- * accept/reject would route `trackChanges.decide` to a change that does not
7651
- * exist. The doc-api derives the public id as `word:structural:<sourceId>`
7652
- * for imported Word revisions, falling back to the per-import logical id.
7653
- * Reuse the exact rule here so the bubble id is the decide id.
7654
- *
7655
- * @param {{ sourceId?: string, id?: string }} structural
7656
- * @returns {string | null}
7657
- */
7658
- const buildStructuralTrackedChangeId = (structural) => {
7659
- if (!structural) return null;
7660
- const sourceId = structural.sourceId ? String(structural.sourceId) : "";
7661
- if (sourceId) return `word:structural:${sourceId}`;
7662
- return structural.id ? String(structural.id) : null;
7663
- };
7664
7550
  const superdocStore = useSuperdocStore();
7665
7551
  const commentsConfig = require__plugin_vue_export_helper.reactive({
7666
7552
  name: "comments",
@@ -7692,8 +7578,6 @@ var useCommentsStore = defineStore("comments", () => {
7692
7578
  const isDebugging = false;
7693
7579
  const debounceTimers = {};
7694
7580
  const trackedChangeResolutionSnapshots = /* @__PURE__ */ new WeakMap();
7695
- const importedTrackedChangeBootstrapTasks = /* @__PURE__ */ new Map();
7696
- let importedTrackedChangeBootstrapGeneration = 0;
7697
7581
  const isBenchmarkCommentsDebugEnabled = () => {
7698
7582
  if (typeof window === "undefined") return false;
7699
7583
  return "__labsSuperDocV2BenchmarkDebug" in window;
@@ -8078,72 +7962,6 @@ var useCommentsStore = defineStore("comments", () => {
8078
7962
  return source === DOCUMENT_EDITOR_SELECTION_SOURCE;
8079
7963
  };
8080
7964
  const isTrackedChangeThread = (comment) => Boolean(comment?.trackedChange) || Boolean(trackedChangeThreadParentIdForComment$1(comment));
8081
- const syncTrackedChangePositionsWithDocument = ({ documentId, editor } = {}) => {
8082
- if (!editor?.state) return 0;
8083
- if (!commentsList.value?.length) return 0;
8084
- const currentPositions = editorCommentPositions.value || {};
8085
- if (!Object.keys(currentPositions).length) return 0;
8086
- const resolveExistingPositionKey = (aliasIds) => aliasIds.find((key) => currentPositions[key] !== void 0) ?? null;
8087
- const candidateRootPositionKeys = /* @__PURE__ */ new Set();
8088
- const rootAliasesByPositionKey = /* @__PURE__ */ new Map();
8089
- commentsList.value.forEach((comment) => {
8090
- if (!comment?.trackedChange) return;
8091
- if (documentId) {
8092
- const resolvedDocumentId = comment?.fileId ?? null;
8093
- if (resolvedDocumentId && resolvedDocumentId !== documentId) return;
8094
- }
8095
- const aliasIds = getCommentAliasIds(comment);
8096
- const normalizedPositionKey = resolveExistingPositionKey(aliasIds);
8097
- if (!normalizedPositionKey) return;
8098
- candidateRootPositionKeys.add(normalizedPositionKey);
8099
- rootAliasesByPositionKey.set(normalizedPositionKey, new Set(aliasIds));
8100
- });
8101
- if (!candidateRootPositionKeys.size) return 0;
8102
- const trackedIds = new Set(trackChangesHelpers.getTrackChanges(editor.state).map(({ mark }) => mark?.attrs?.id).filter((id) => id !== void 0 && id !== null).map((id) => String(id)));
8103
- const trackedChangeIndex = typeof getTrackedChangeIndex === "function" ? getTrackedChangeIndex(editor) : null;
8104
- let liveAnchorKeySource = [];
8105
- try {
8106
- liveAnchorKeySource = trackedChangeIndex?.getAll?.() ?? [];
8107
- } catch {}
8108
- const liveAnchorKeys = new Set(liveAnchorKeySource.map((snapshot) => snapshot?.anchorKey).filter((anchorKey) => typeof anchorKey === "string" && anchorKey.length > 0));
8109
- const staleRootPositionKeys = new Set(Array.from(candidateRootPositionKeys).filter((positionKey) => {
8110
- const aliases = rootAliasesByPositionKey.get(positionKey) ?? /* @__PURE__ */ new Set([positionKey]);
8111
- if (Array.from(aliases).some((alias) => liveAnchorKeys.has(alias))) return false;
8112
- return !Array.from(aliases).some((alias) => trackedIds.has(alias));
8113
- }));
8114
- if (!staleRootPositionKeys.size) return 0;
8115
- const staleRootAliasIds = /* @__PURE__ */ new Set();
8116
- staleRootPositionKeys.forEach((positionKey) => {
8117
- (rootAliasesByPositionKey.get(positionKey) ?? /* @__PURE__ */ new Set([positionKey])).forEach((alias) => staleRootAliasIds.add(alias));
8118
- });
8119
- const stalePositionKeys = new Set(staleRootPositionKeys);
8120
- commentsList.value.forEach((comment) => {
8121
- const aliasIds = getCommentAliasIds(comment);
8122
- const normalizedPositionKey = resolveExistingPositionKey(aliasIds);
8123
- if (!normalizedPositionKey) return;
8124
- if ([
8125
- trackedChangeThreadParentIdForComment$1(comment),
8126
- comment?.threadingParentCommentId,
8127
- comment?.parentCommentId
8128
- ].map((id) => normalizeCommentId(id)).filter(Boolean).some((id) => staleRootAliasIds.has(id))) stalePositionKeys.add(normalizedPositionKey);
8129
- });
8130
- const nextPositions = { ...currentPositions };
8131
- stalePositionKeys.forEach((key) => {
8132
- delete nextPositions[key];
8133
- });
8134
- editorCommentPositions.value = nextPositions;
8135
- if (activeComment.value !== void 0 && activeComment.value !== null) {
8136
- const activeCommentModel = getComment(activeComment.value);
8137
- const activeAliases = new Set(getCommentAliasIds(activeCommentModel ?? activeComment.value));
8138
- const activeParentKeys = [
8139
- trackedChangeThreadParentIdForComment$1(activeCommentModel),
8140
- activeCommentModel?.threadingParentCommentId,
8141
- activeCommentModel?.parentCommentId
8142
- ].map((id) => normalizeCommentId(id)).filter(Boolean);
8143
- if (Array.from(activeAliases).some((id) => staleRootAliasIds.has(id)) || activeParentKeys.some((id) => staleRootAliasIds.has(id))) clearActiveCommentSelection();
8144
- }
8145
- return stalePositionKeys.size;
8146
- };
8147
7965
  const collectStandardCommentDocumentState = (editor) => {
8148
7966
  const doc = editor?.state?.doc;
8149
7967
  if (!doc || typeof doc.descendants !== "function") return null;
@@ -8325,7 +8143,7 @@ var useCommentsStore = defineStore("comments", () => {
8325
8143
  * @param {Object} param0.params The tracked change params
8326
8144
  * @returns {void}
8327
8145
  */
8328
- const handleTrackedChangeUpdate = ({ superdoc, params, broadcastChanges = true, documentState = void 0, trackedChangeIdentityIndex = null }) => {
8146
+ const handleTrackedChangeUpdate = ({ superdoc, params, broadcastChanges = true, trackedChangeIdentityIndex = null }) => {
8329
8147
  const span = startInteractionSpan("store.trackedChanges.handleUpdate", "store-reconciliation", {
8330
8148
  event: params?.event ?? null,
8331
8149
  changeId: params?.changeId ?? null,
@@ -8342,26 +8160,6 @@ var useCommentsStore = defineStore("comments", () => {
8342
8160
  const normalizedCustomAttributes = hasCustomAttributes ? normalizeTrackedChangeCustomAttributes(customAttributes) : void 0;
8343
8161
  const normalizedImportedId = hasImportedId ? importedId != null ? String(importedId) : null : void 0;
8344
8162
  const normalizedDocumentId = documentId != null ? String(documentId) : null;
8345
- if (!(trackedChangeDisplayType === "tableInsert" || trackedChangeDisplayType === "tableDelete") && normalizedChangeId) {
8346
- const effectiveDocumentId = normalizedDocumentId ?? (superdoc?.activeEditor?.options?.documentId != null ? String(superdoc.activeEditor.options.documentId) : null);
8347
- const docEditor = effectiveDocumentId ? superdocStore.getDocument(effectiveDocumentId)?.getEditor?.() : null;
8348
- const docState = documentState !== void 0 ? documentState : docEditor?.state ?? superdoc?.activeEditor?.state ?? null;
8349
- if (docState) {
8350
- const { ranges: tableRanges, ids: structuralIds } = computeTrackedTableSummaryForState(docState);
8351
- const ranges = trackChangesHelpers.getTrackChanges(docState, normalizedChangeId);
8352
- const inRange = tableRanges.length > 0 && ranges.length > 0 && isInlineRangeInsideTrackedTable(ranges, tableRanges);
8353
- const isStructuralRowIdEcho = ranges.length === 0 && structuralIds.has(normalizedChangeId);
8354
- if (inRange || isStructuralRowIdEcho) {
8355
- pruneSuppressedInlineTableComments({
8356
- suppressedIds: /* @__PURE__ */ new Set([normalizedChangeId]),
8357
- activeDocumentId: effectiveDocumentId,
8358
- superdoc,
8359
- broadcastChanges
8360
- });
8361
- return;
8362
- }
8363
- }
8364
- }
8365
8163
  const hasStoryMetadata = trackedChangeStory !== void 0 || trackedChangeStoryKind !== void 0 || trackedChangeStoryLabel !== void 0 || trackedChangeAnchorKey !== void 0;
8366
8164
  const normalizedTrackedChangeStory = hasStoryMetadata ? trackedChangeStory ?? null : BODY_TRACKED_CHANGE_STORY;
8367
8165
  const normalizedTrackedChangeStoryKind = hasStoryMetadata ? trackedChangeStoryKind ?? null : "body";
@@ -8555,38 +8353,6 @@ var useCommentsStore = defineStore("comments", () => {
8555
8353
  endInteractionSpan(span);
8556
8354
  }
8557
8355
  };
8558
- const collectTrackedChangeMarksByType = (trackedChanges = []) => ({
8559
- insertedMark: trackedChanges.find(({ mark }) => mark?.type?.name === "trackInsert")?.mark ?? null,
8560
- deletionMark: trackedChanges.find(({ mark }) => mark?.type?.name === "trackDelete")?.mark ?? null,
8561
- formatMark: trackedChanges.find(({ mark }) => mark?.type?.name === "trackFormat")?.mark ?? null
8562
- });
8563
- const refreshTrackedChangeCommentsByIds = ({ superdoc, editor, changeIds, broadcastChanges = true }) => {
8564
- if (!superdoc || !editor?.state || !Array.isArray(changeIds) || !changeIds.length) return;
8565
- const documentId = editor?.options?.documentId != null ? String(editor.options.documentId) : null;
8566
- if (!documentId) return;
8567
- for (const changeId of new Set(changeIds.map((id) => id != null ? String(id) : null).filter(Boolean))) {
8568
- const trackedChangesForId = trackChangesHelpers.getTrackChanges(editor.state, changeId);
8569
- if (!trackedChangesForId.length) continue;
8570
- const params = createOrUpdateTrackedChangeComment({
8571
- event: "update",
8572
- marks: collectTrackedChangeMarksByType(trackedChangesForId),
8573
- nodes: [],
8574
- newEditorState: editor.state,
8575
- documentId,
8576
- trackedChangesForId
8577
- });
8578
- if (!params) continue;
8579
- params.trackedChangeStory = BODY_TRACKED_CHANGE_STORY;
8580
- params.trackedChangeStoryKind = "body";
8581
- params.trackedChangeStoryLabel = "";
8582
- params.trackedChangeAnchorKey = buildBodyTrackedChangeAnchorKey(params.changeId ?? changeId);
8583
- handleTrackedChangeUpdate({
8584
- superdoc,
8585
- params,
8586
- broadcastChanges
8587
- });
8588
- }
8589
- };
8590
8356
  const requestInstantSidebarAlignment = (targetY = null, threadId = null, instanceId = null) => {
8591
8357
  const hasTargetY = Number.isFinite(targetY);
8592
8358
  instantSidebarAlignmentTargetY.value = hasTargetY ? targetY : null;
@@ -10196,178 +9962,6 @@ var useCommentsStore = defineStore("comments", () => {
10196
9962
  removePendingComment(superdoc);
10197
9963
  };
10198
9964
  /**
10199
- * Imported DOCX comments can omit the normalized author string.
10200
- * Strip the exporter suffix when present and tolerate missing metadata.
10201
- *
10202
- * @param {string | null | undefined} creatorName
10203
- * @returns {string | null}
10204
- */
10205
- const normalizeImportedCreatorName = (creatorName) => {
10206
- if (typeof creatorName !== "string") return null;
10207
- return creatorName.replace(/\s*\(imported\)\s*$/u, "").trim() || null;
10208
- };
10209
- /**
10210
- * Read the mounted editor view and state without touching `editor.state`.
10211
- * The editor convenience getter delegates to `view.state` and throws after
10212
- * teardown, which is precisely when a deferred import callback can run.
10213
- *
10214
- * @param {Object | null | undefined} editor
10215
- * @returns {{ view: Object, state: Object } | null}
10216
- */
10217
- const readMountedEditorSnapshot = (editor) => {
10218
- if (!editor) return null;
10219
- try {
10220
- if (editor.isDestroyed === true) return null;
10221
- const view = editor.view;
10222
- if (!view || view.isDestroyed === true || view.destroyed === true) return null;
10223
- const state = view.state;
10224
- if (!state) return null;
10225
- return {
10226
- view,
10227
- state
10228
- };
10229
- } catch {
10230
- return null;
10231
- }
10232
- };
10233
- const normalizeBootstrapDocumentId = (documentId) => documentId !== void 0 && documentId !== null && String(documentId).length > 0 ? String(documentId) : null;
10234
- /**
10235
- * Cancel deferred imported tracked-change comment work. Passing a document
10236
- * id cancels only that document; omitting it cancels every pending task.
10237
- *
10238
- * @param {string | null | undefined} documentId
10239
- * @returns {number} number of invalidated tasks
10240
- */
10241
- const cancelImportedTrackedChangeBootstrap = (documentId) => {
10242
- const normalizedDocumentId = normalizeBootstrapDocumentId(documentId);
10243
- const entries = normalizedDocumentId ? [[normalizedDocumentId, importedTrackedChangeBootstrapTasks.get(normalizedDocumentId)]] : Array.from(importedTrackedChangeBootstrapTasks.entries());
10244
- let canceled = 0;
10245
- for (const [taskDocumentId, task] of entries) {
10246
- if (!task) continue;
10247
- importedTrackedChangeBootstrapTasks.delete(taskDocumentId);
10248
- if (task.timeoutHandle !== null && task.timeoutHandle !== void 0) clearTimeout(task.timeoutHandle);
10249
- canceled += 1;
10250
- }
10251
- return canceled;
10252
- };
10253
- const captureImportedTrackedChangeBootstrapSnapshot = (editor) => {
10254
- const mountedEditor = readMountedEditorSnapshot(editor);
10255
- if (!mountedEditor) return null;
10256
- let trackedChanges = [];
10257
- try {
10258
- trackedChanges = trackChangesHelpers.getTrackChanges(mountedEditor.state) ?? [];
10259
- } catch {
10260
- return null;
10261
- }
10262
- const enumerateStructuralChanges = trackChangesHelpers?.enumerateStructuralRowChanges;
10263
- let structuralChanges = [];
10264
- if (typeof enumerateStructuralChanges === "function") try {
10265
- structuralChanges = enumerateStructuralChanges(mountedEditor.state) ?? [];
10266
- } catch {
10267
- structuralChanges = [];
10268
- }
10269
- let storySnapshots = [];
10270
- if (typeof getTrackedChangeIndex === "function") try {
10271
- storySnapshots = getTrackedChangeIndex(editor)?.getAll?.() ?? [];
10272
- } catch {
10273
- storySnapshots = [];
10274
- }
10275
- return {
10276
- ...mountedEditor,
10277
- trackedChanges,
10278
- structuralChanges,
10279
- storySnapshots
10280
- };
10281
- };
10282
- /**
10283
- * Bootstrap tracked-change comment threads after a DOCX import finishes.
10284
- *
10285
- * Initial import historically rebuilt only body tracked-change threads so
10286
- * resolved imported body comments stayed resolved. Header/footer and note
10287
- * tracked changes live outside the body PM state, so they need an additional
10288
- * story-aware bootstrap pass here.
10289
- *
10290
- * We intentionally keep the existing body-only rebuild instead of switching
10291
- * to the broader syncTrackedChangeComments() path so imported resolved body
10292
- * tracked-change threads preserve their initial resolved state.
10293
- *
10294
- * @param {Object | null | undefined} editor
10295
- * @param {Object | null | undefined} superdoc
10296
- * @param {Object | null | undefined} snapshot
10297
- * @returns {boolean}
10298
- */
10299
- const bootstrapImportedTrackedChangeComments = (editor, superdoc, snapshot = null) => {
10300
- if (!editor || !superdoc) return false;
10301
- const captured = snapshot ?? captureImportedTrackedChangeBootstrapSnapshot(editor);
10302
- if (!captured) return false;
10303
- createCommentForTrackChanges(editor, superdoc, captured.trackedChanges, {
10304
- editorState: captured.state,
10305
- editorView: captured.view
10306
- });
10307
- syncStoryTrackedChangeComments({
10308
- superdoc,
10309
- editor,
10310
- snapshots: captured.storySnapshots,
10311
- documentState: captured.state,
10312
- resolveFromEditor: false
10313
- });
10314
- syncStructuralTrackedChangeComments({
10315
- superdoc,
10316
- editor,
10317
- structuralChanges: captured.structuralChanges
10318
- });
10319
- return true;
10320
- };
10321
- const isCurrentImportedTrackedChangeBootstrap = (task) => {
10322
- if (!task) return false;
10323
- if (importedTrackedChangeBootstrapTasks.get(task.documentId) !== task) return false;
10324
- try {
10325
- const editorDocumentId = task.editor?.options?.documentId;
10326
- if (editorDocumentId != null && String(editorDocumentId) !== task.documentId) return false;
10327
- const mountedDocument = superdocStore.getDocument(task.documentId);
10328
- if (!mountedDocument) return false;
10329
- if (mountedDocument.getEditor?.() !== task.editor) return false;
10330
- } catch {
10331
- return false;
10332
- }
10333
- return true;
10334
- };
10335
- const runImportedTrackedChangeBootstrap = (task) => {
10336
- if (!isCurrentImportedTrackedChangeBootstrap(task)) {
10337
- if (importedTrackedChangeBootstrapTasks.get(task?.documentId) === task) importedTrackedChangeBootstrapTasks.delete(task.documentId);
10338
- return false;
10339
- }
10340
- const snapshot = captureImportedTrackedChangeBootstrapSnapshot(task.editor);
10341
- if (!snapshot || !isCurrentImportedTrackedChangeBootstrap(task)) {
10342
- if (importedTrackedChangeBootstrapTasks.get(task.documentId) === task) importedTrackedChangeBootstrapTasks.delete(task.documentId);
10343
- return false;
10344
- }
10345
- try {
10346
- return bootstrapImportedTrackedChangeComments(task.editor, task.superdoc, snapshot);
10347
- } finally {
10348
- if (importedTrackedChangeBootstrapTasks.get(task.documentId) === task) importedTrackedChangeBootstrapTasks.delete(task.documentId);
10349
- }
10350
- };
10351
- const scheduleImportedTrackedChangeBootstrap = ({ editor, superdoc, documentId, defer = true }) => {
10352
- const normalizedDocumentId = normalizeBootstrapDocumentId(documentId);
10353
- if (!normalizedDocumentId || !editor || !superdoc) return false;
10354
- cancelImportedTrackedChangeBootstrap(normalizedDocumentId);
10355
- const task = {
10356
- documentId: normalizedDocumentId,
10357
- editor,
10358
- superdoc,
10359
- generation: ++importedTrackedChangeBootstrapGeneration,
10360
- timeoutHandle: null
10361
- };
10362
- importedTrackedChangeBootstrapTasks.set(normalizedDocumentId, task);
10363
- if (!defer) return runImportedTrackedChangeBootstrap(task);
10364
- task.timeoutHandle = setTimeout(() => {
10365
- task.timeoutHandle = null;
10366
- runImportedTrackedChangeBootstrap(task);
10367
- }, 0);
10368
- return true;
10369
- };
10370
- /**
10371
9965
  * Drop imported threads and cached positions for one document id.
10372
9966
  *
10373
9967
  * Replace-file swaps call this before hydrating the replacement so stale
@@ -10384,7 +9978,6 @@ var useCommentsStore = defineStore("comments", () => {
10384
9978
  delete next[activeDocumentId];
10385
9979
  committedReviewPresentations.value = next;
10386
9980
  }
10387
- cancelImportedTrackedChangeBootstrap(activeDocumentId);
10388
9981
  const removedComments = commentsList.value.filter((comment) => belongsToDocument(comment, activeDocumentId, { allowSingleDocumentMismatch: true }));
10389
9982
  if (!removedComments.length) return;
10390
9983
  const removedAliasIds = /* @__PURE__ */ new Set();
@@ -10402,217 +9995,6 @@ var useCommentsStore = defineStore("comments", () => {
10402
9995
  const activeCommentId = activeComment.value != null ? String(activeComment.value) : null;
10403
9996
  if (activeCommentId && removedAliasIds.has(activeCommentId)) clearActiveCommentSelection();
10404
9997
  }
10405
- function resetCommentsForReplacedDocument(documentId) {
10406
- removeCommentsForDocument(documentId);
10407
- }
10408
- /**
10409
- * Initialize loaded comments into SuperDoc by mapping the imported
10410
- * comment data to SuperDoc useComment objects.
10411
- *
10412
- * Updates the commentsList ref with the new comments.
10413
- *
10414
- * @param {Object} param0
10415
- * @param {Array} param0.comments The comments to be loaded
10416
- * @param {String} param0.documentId The document ID
10417
- * @param {boolean} [param0.replacedFile] Whether this load replaces an existing document in place
10418
- * @returns {void}
10419
- */
10420
- const processLoadedDocxComments = async ({ superdoc, editor, comments, documentId, replacedFile = false }) => {
10421
- const document = superdocStore.getDocument(documentId);
10422
- if (document?.commentThreadingProfile) document.commentThreadingProfile.value = editor?.converter?.commentThreadingProfile || null;
10423
- if (replacedFile) resetCommentsForReplacedDocument(documentId);
10424
- comments.forEach((comment) => {
10425
- const textElements = Array.isArray(comment.elements) ? comment.elements : [];
10426
- const htmlContent = getHtmlFromComment(textElements);
10427
- if (!htmlContent && !comment.trackedChange) return;
10428
- const creatorName = normalizeImportedCreatorName(comment.creatorName);
10429
- const importedName = creatorName ? `${creatorName} (imported)` : null;
10430
- const newComment = useComment({
10431
- fileId: documentId,
10432
- fileType: document.type,
10433
- docxCommentJSON: textElements.length ? textElements : null,
10434
- commentId: comment.commentId,
10435
- isInternal: false,
10436
- parentCommentId: comment.parentCommentId,
10437
- trackedChangeParentId: comment.trackedChangeParentId,
10438
- trackedChangeThreadParentId: comment.trackedChangeThreadParentId,
10439
- creatorId: null,
10440
- creatorName,
10441
- createdTime: comment.createdTime,
10442
- creatorEmail: comment.creatorEmail,
10443
- importedAuthor: {
10444
- ...importedName ? { name: importedName } : {},
10445
- email: comment.creatorEmail
10446
- },
10447
- commentText: htmlContent,
10448
- resolvedTime: comment.isDone ? Date.now() : null,
10449
- resolvedById: null,
10450
- resolvedByEmail: comment.isDone ? comment.creatorEmail : null,
10451
- resolvedByName: comment.isDone ? importedName || "(Imported)" : null,
10452
- trackedChange: comment.trackedChange || false,
10453
- trackedChangeText: comment.trackedChangeText,
10454
- trackedChangeType: comment.trackedChangeType,
10455
- trackedChangeDisplayType: comment.trackedChangeDisplayType,
10456
- deletedText: comment.trackedDeletedText,
10457
- origin: comment.origin || "word",
10458
- threadingMethod: comment.threadingMethod,
10459
- threadingStyleOverride: comment.threadingStyleOverride,
10460
- threadingParentCommentId: comment.threadingParentCommentId,
10461
- originalXmlStructure: comment.originalXmlStructure
10462
- });
10463
- addHydratedComment({
10464
- superdoc,
10465
- comment: newComment
10466
- });
10467
- });
10468
- if (replacedFile) {
10469
- scheduleImportedTrackedChangeBootstrap({
10470
- editor,
10471
- superdoc,
10472
- documentId,
10473
- defer: false
10474
- });
10475
- return;
10476
- }
10477
- scheduleImportedTrackedChangeBootstrap({
10478
- editor,
10479
- superdoc,
10480
- documentId
10481
- });
10482
- };
10483
- const createCommentForTrackChanges = (editor, superdoc, trackedChangesOverride = null, options = {}) => {
10484
- const { reopenResolved = false, refreshExisting = false, broadcastChanges = true, editorState: editorStateOverride = null, editorView: editorViewOverride = null } = options;
10485
- const mountedEditor = editorStateOverride ? {
10486
- state: editorStateOverride,
10487
- view: editorViewOverride
10488
- } : readMountedEditorSnapshot(editor);
10489
- if (!mountedEditor?.state) return;
10490
- const editorState = mountedEditor.state;
10491
- const trackedChanges = trackedChangesOverride ?? trackChangesHelpers.getTrackChanges(editorState);
10492
- const groupedChanges = groupChanges(trackedChanges);
10493
- const activeDocumentId = editor?.options?.documentId != null ? String(editor.options.documentId) : null;
10494
- if (!activeDocumentId) return;
10495
- const skipIds = /* @__PURE__ */ new Set();
10496
- const existingTrackedChangeById = /* @__PURE__ */ new Map();
10497
- commentsList.value.forEach((comment) => {
10498
- if (!comment?.trackedChange) return;
10499
- if (!belongsToTrackedChangeSyncDocument(comment, activeDocumentId)) return;
10500
- if (!isBodyTrackedChangeComment(comment)) return;
10501
- const commentIds = [comment.commentId, comment.importedId].map((id) => id != null ? String(id) : null).filter(Boolean);
10502
- if (comment.resolvedTime) {
10503
- if (!reopenResolved) commentIds.forEach((id) => skipIds.add(id));
10504
- return;
10505
- }
10506
- commentIds.forEach((id) => {
10507
- existingTrackedChangeById.set(id, comment);
10508
- if (!refreshExisting) skipIds.add(id);
10509
- });
10510
- });
10511
- const changesByIdMap = /* @__PURE__ */ new Map();
10512
- for (const change of trackedChanges) {
10513
- const id = change.mark.attrs.id;
10514
- if (!changesByIdMap.has(id)) changesByIdMap.set(id, []);
10515
- changesByIdMap.get(id).push(change);
10516
- }
10517
- const documentId = activeDocumentId;
10518
- const processedIds = /* @__PURE__ */ new Set();
10519
- groupedChanges.forEach(({ insertedMark, deletionMark, formatMark }) => {
10520
- const id = insertedMark?.mark.attrs.id || deletionMark?.mark.attrs.id || formatMark?.mark.attrs.id;
10521
- if (id == null) return;
10522
- const normalizedId = String(id);
10523
- if (processedIds.has(normalizedId)) return;
10524
- processedIds.add(normalizedId);
10525
- if (!refreshExisting && skipIds.has(normalizedId)) return;
10526
- const existingTrackedChange = existingTrackedChangeById.get(normalizedId);
10527
- const marks = {
10528
- ...insertedMark && { insertedMark: insertedMark.mark },
10529
- ...deletionMark && { deletionMark: deletionMark.mark },
10530
- ...formatMark && { formatMark: formatMark.mark }
10531
- };
10532
- const params = createOrUpdateTrackedChangeComment({
10533
- event: existingTrackedChange ? "update" : "add",
10534
- marks,
10535
- nodes: [],
10536
- newEditorState: editorState,
10537
- documentId,
10538
- trackedChangesForId: changesByIdMap.get(id) || []
10539
- });
10540
- if (params) {
10541
- const anchorKey = buildBodyTrackedChangeAnchorKey(params.changeId ?? id);
10542
- params.trackedChangeStory = BODY_TRACKED_CHANGE_STORY;
10543
- params.trackedChangeStoryKind = "body";
10544
- params.trackedChangeStoryLabel = "";
10545
- params.trackedChangeAnchorKey = anchorKey;
10546
- handleTrackedChangeUpdate({
10547
- superdoc,
10548
- params,
10549
- broadcastChanges,
10550
- documentState: editorState
10551
- });
10552
- if (!existingTrackedChange) {
10553
- skipIds.add(normalizedId);
10554
- if (params.changeId != null) skipIds.add(String(params.changeId));
10555
- if (params.importedId != null) skipIds.add(String(params.importedId));
10556
- }
10557
- }
10558
- });
10559
- const editorView = mountedEditor.view;
10560
- try {
10561
- if (!editorView || editor.view !== editorView || editorView.isDestroyed === true || editorView.destroyed === true) return;
10562
- } catch {
10563
- return;
10564
- }
10565
- const { tr } = editorState;
10566
- tr.setMeta(CommentsPluginKey, { type: "force" });
10567
- editorView.dispatch(tr);
10568
- };
10569
- /**
10570
- * Remove inline tracked-change comments whose change id is subsumed by a
10571
- * tracked whole-table change. Mirrors the deletion-event emission of
10572
- * `pruneStaleTrackedChangeComments` but is keyed on an explicit suppressed-id
10573
- * set rather than mark liveness (the mark is still live; only the review item
10574
- * is unwanted). Also clears the active-comment selection if it pointed at a
10575
- * now-suppressed change, so no stale active-on-click dialog can reference it.
10576
- *
10577
- * @param {{ suppressedIds: Set<string>, activeDocumentId: string, superdoc: any, broadcastChanges?: boolean }} input
10578
- */
10579
- const pruneSuppressedInlineTableComments = ({ suppressedIds, activeDocumentId, superdoc = null, broadcastChanges = true }) => {
10580
- if (!(suppressedIds instanceof Set) || !suppressedIds.size || !activeDocumentId) return;
10581
- const removedComments = [];
10582
- commentsList.value = commentsList.value.filter((comment) => {
10583
- if (!comment?.trackedChange) return true;
10584
- if (!isBodyTrackedChangeComment(comment)) return true;
10585
- if (isStructuralTableBubble(comment)) return true;
10586
- if (!belongsToTrackedChangeSyncDocument(comment, activeDocumentId)) return true;
10587
- const commentId = comment.commentId != null ? String(comment.commentId) : null;
10588
- const importedId = comment.importedId != null ? String(comment.importedId) : null;
10589
- if (!(commentId && suppressedIds.has(commentId) || importedId && suppressedIds.has(importedId))) return true;
10590
- removedComments.push(comment);
10591
- return false;
10592
- });
10593
- if (!removedComments.length) return;
10594
- const removedIds = /* @__PURE__ */ new Set();
10595
- removedComments.forEach((comment) => {
10596
- if (comment.commentId != null) removedIds.add(String(comment.commentId));
10597
- if (comment.importedId != null) removedIds.add(String(comment.importedId));
10598
- const payload = getCommentEventPayload(comment);
10599
- const event = {
10600
- type: COMMENT_EVENTS.DELETED,
10601
- comment: payload,
10602
- changes: [{
10603
- key: "deleted",
10604
- commentId: payload.commentId,
10605
- fileId: payload.fileId
10606
- }]
10607
- };
10608
- if (broadcastChanges) {
10609
- syncCommentsToClients(superdoc, event);
10610
- superdoc?.emit?.("comments-update", event);
10611
- }
10612
- });
10613
- const activeCommentId = activeComment.value != null ? String(activeComment.value) : null;
10614
- if (activeCommentId && removedIds.has(activeCommentId)) clearActiveCommentSelection();
10615
- };
10616
9998
  const getCommentDocumentId = (comment) => {
10617
9999
  if (!comment) return null;
10618
10000
  if (comment.fileId != null) return String(comment.fileId);
@@ -11468,286 +10850,6 @@ var useCommentsStore = defineStore("comments", () => {
11468
10850
  return rowDocumentId != null && String(rowDocumentId) === normalizedDocumentId;
11469
10851
  }).length;
11470
10852
  };
11471
- const syncTrackedChangeComments = ({ superdoc, editor, broadcastChanges = true }) => {
11472
- if (!superdoc || !editor) return;
11473
- const activeDocumentId = editor?.options?.documentId != null ? String(editor.options.documentId) : null;
11474
- if (!activeDocumentId) return;
11475
- const captured = captureImportedTrackedChangeBootstrapSnapshot(editor);
11476
- if (!captured) return;
11477
- const trackedChanges = captured.trackedChanges;
11478
- const liveTrackedChangeIds = /* @__PURE__ */ new Set();
11479
- trackedChanges.forEach((change) => {
11480
- const id = change?.mark?.attrs?.id;
11481
- if (id == null) return;
11482
- liveTrackedChangeIds.add(String(id));
11483
- });
11484
- const storySnapshots = captured.storySnapshots;
11485
- const liveTrackedChangeAnchorKeys = new Set(storySnapshots.map((snapshot) => snapshot?.anchorKey).filter((anchorKey) => typeof anchorKey === "string" && anchorKey.length > 0));
11486
- pruneStaleTrackedChangeComments(liveTrackedChangeIds, liveTrackedChangeAnchorKeys, activeDocumentId, superdoc, { broadcastChanges });
11487
- createCommentForTrackChanges(editor, superdoc, trackedChanges, {
11488
- reopenResolved: true,
11489
- refreshExisting: true,
11490
- broadcastChanges,
11491
- editorState: captured.state,
11492
- editorView: captured.view
11493
- });
11494
- syncStoryTrackedChangeComments({
11495
- superdoc,
11496
- editor,
11497
- broadcastChanges,
11498
- snapshots: storySnapshots,
11499
- documentState: captured.state
11500
- });
11501
- syncStructuralTrackedChangeComments({
11502
- superdoc,
11503
- editor,
11504
- broadcastChanges,
11505
- structuralChanges: captured.structuralChanges
11506
- });
11507
- };
11508
- /**
11509
- * Surface decidable whole-table structural tracked changes (table insert /
11510
- * table delete) as right-rail bubbles, mirroring the inline tracked-change
11511
- * path. Structural row revisions live on node attrs (not inline marks), so
11512
- * the inline `getTrackChanges` enumerator never sees them — they are
11513
- * enumerated separately here.
11514
- *
11515
- * Only `decidable` whole-table changes are surfaced; partial/mixed shapes are
11516
- * not actionable (the decision engine fails them closed) so they get no
11517
- * bubble. The bubble id is the document-api public id so accept/reject in the
11518
- * sidebar routes `trackChanges.decide` to the same change.
11519
- *
11520
- * Positioning: the bubble carries a body-story anchorKey (matching the
11521
- * tracked-change index snapshot) and a body PM range (table start/end). The
11522
- * DocumentRendererRuntime position pass emits a body-story position entry for that
11523
- * anchorKey, whose bounds resolve through the same `getRangeRects` path inline
11524
- * body comments/TC use — so it lines up with the table in layout-engine
11525
- * viewing mode.
11526
- */
11527
- const syncStructuralTrackedChangeComments = ({ superdoc, editor, broadcastChanges = true, structuralChanges: structuralChangesOverride = null }) => {
11528
- const activeDocumentId = editor?.options?.documentId != null ? String(editor.options.documentId) : null;
11529
- if (!activeDocumentId) return;
11530
- const enumerate = trackChangesHelpers?.enumerateStructuralRowChanges;
11531
- if (typeof enumerate !== "function") return;
11532
- let structuralChanges = structuralChangesOverride;
11533
- if (!Array.isArray(structuralChanges)) {
11534
- const mountedEditor = readMountedEditorSnapshot(editor);
11535
- if (!mountedEditor) return;
11536
- try {
11537
- structuralChanges = enumerate(mountedEditor.state) ?? [];
11538
- } catch {
11539
- structuralChanges = [];
11540
- }
11541
- }
11542
- for (const structural of structuralChanges) {
11543
- if (!structural?.decidable || !structural?.wholeTable) continue;
11544
- const publicId = buildStructuralTrackedChangeId(structural);
11545
- if (!publicId) continue;
11546
- const anchorKey = buildBodyTrackedChangeAnchorKey(publicId);
11547
- const displayType = structural.subtype === "table-insert" ? "tableInsert" : "tableDelete";
11548
- const trackedChangeType = structural.side === "insertion" ? "trackInsert" : "trackDelete";
11549
- const normalizedPublicId = String(publicId);
11550
- const normalizedAnchorKey = anchorKey != null ? String(anchorKey) : null;
11551
- const params = {
11552
- event: commentsList.value.find((comment) => {
11553
- if (!comment?.trackedChange) return false;
11554
- if (!belongsToTrackedChangeSyncDocument(comment, activeDocumentId)) return false;
11555
- const commentAnchorKey = comment.trackedChangeAnchorKey != null ? String(comment.trackedChangeAnchorKey) : null;
11556
- if (normalizedAnchorKey && commentAnchorKey) return commentAnchorKey === normalizedAnchorKey;
11557
- const commentId = comment.commentId != null ? String(comment.commentId) : null;
11558
- const importedId = comment.importedId != null ? String(comment.importedId) : null;
11559
- return commentId === normalizedPublicId || importedId === normalizedPublicId;
11560
- }) ? "update" : "add",
11561
- changeId: publicId,
11562
- trackedChangeText: "",
11563
- trackedChangeType,
11564
- trackedChangeDisplayType: displayType,
11565
- deletedText: null,
11566
- authorId: null,
11567
- authorEmail: structural.authorEmail || null,
11568
- authorImage: structural.authorImage || null,
11569
- date: structural.date || null,
11570
- author: structural.author || null,
11571
- importedAuthor: structural.importedAuthor ? { name: structural.importedAuthor } : null,
11572
- semanticColorKey: structural.semanticColorKey ?? null,
11573
- semanticColor: structural.semanticColor ?? null,
11574
- documentId: activeDocumentId,
11575
- coords: null,
11576
- trackedChangeStory: BODY_TRACKED_CHANGE_STORY,
11577
- trackedChangeStoryKind: "body",
11578
- trackedChangeStoryLabel: "",
11579
- trackedChangeAnchorKey: anchorKey
11580
- };
11581
- handleTrackedChangeUpdate({
11582
- superdoc,
11583
- params,
11584
- broadcastChanges
11585
- });
11586
- }
11587
- };
11588
- const syncStoryTrackedChangeComments = ({ superdoc, editor, broadcastChanges = true, snapshots = null, documentState = void 0, resolveFromEditor = true }) => {
11589
- const activeDocumentId = editor?.options?.documentId != null ? String(editor.options.documentId) : null;
11590
- if (!activeDocumentId) return;
11591
- let resolvedSnapshots = snapshots;
11592
- if (!Array.isArray(resolvedSnapshots)) {
11593
- if (typeof getTrackedChangeIndex !== "function") return;
11594
- if (!readMountedEditorSnapshot(editor)) return;
11595
- let index = null;
11596
- try {
11597
- index = getTrackedChangeIndex(editor);
11598
- } catch {
11599
- return;
11600
- }
11601
- if (!index) return;
11602
- try {
11603
- resolvedSnapshots = index.getAll();
11604
- } catch {
11605
- return;
11606
- }
11607
- }
11608
- for (const snapshot of resolvedSnapshots) {
11609
- if (snapshot.storyKind === "body") continue;
11610
- upsertStoryTrackedChangeComment({
11611
- superdoc,
11612
- editor,
11613
- snapshot,
11614
- documentId: activeDocumentId,
11615
- broadcastChanges,
11616
- documentState,
11617
- resolveFromEditor
11618
- });
11619
- }
11620
- };
11621
- const getStoryTrackedChangeDisplayType = (snapshot) => {
11622
- if (snapshot?.type !== "structural") return snapshot?.type ?? null;
11623
- return snapshot?.subtype === "table-delete" ? "tableDelete" : "tableInsert";
11624
- };
11625
- const getStoryTrackedChangeType = (snapshot) => {
11626
- if (snapshot?.type !== "structural") return snapshot?.type ?? null;
11627
- return snapshot?.subtype === "table-delete" ? "trackDelete" : "trackInsert";
11628
- };
11629
- const isStoryTrackedChangeDeletion = (snapshot) => {
11630
- if (!snapshot) return false;
11631
- if (snapshot.type === "delete") return true;
11632
- return snapshot.type === "structural" && snapshot.subtype === "table-delete";
11633
- };
11634
- const buildStoryTrackedChangeParams = ({ editor, snapshot, documentId, event, resolveFromEditor = true }) => {
11635
- const trackedChangeType = getStoryTrackedChangeType(snapshot);
11636
- const trackedChangeDisplayType = getStoryTrackedChangeDisplayType(snapshot);
11637
- const fallbackParams = {
11638
- event,
11639
- changeId: snapshot.runtimeRef.rawId,
11640
- trackedChangeText: isStoryTrackedChangeDeletion(snapshot) ? "" : snapshot.excerpt ?? "",
11641
- trackedChangeType,
11642
- trackedChangeDisplayType,
11643
- semanticColorKey: snapshot.semanticColorKey ?? null,
11644
- semanticColor: snapshot.semanticColor ?? null,
11645
- deletedText: isStoryTrackedChangeDeletion(snapshot) ? snapshot.excerpt ?? "" : null,
11646
- authorId: snapshot.authorId,
11647
- authorEmail: snapshot.authorEmail,
11648
- authorImage: snapshot.authorImage,
11649
- date: snapshot.date,
11650
- author: snapshot.author,
11651
- documentId,
11652
- coords: null,
11653
- trackedChangeStory: snapshot.story,
11654
- trackedChangeStoryKind: snapshot.storyKind,
11655
- trackedChangeStoryLabel: snapshot.storyLabel,
11656
- trackedChangeAnchorKey: snapshot.anchorKey
11657
- };
11658
- if (!resolveFromEditor || typeof resolveTrackedChangeInStory !== "function") return fallbackParams;
11659
- let resolvedChange = null;
11660
- try {
11661
- resolvedChange = resolveTrackedChangeInStory(editor, {
11662
- kind: "entity",
11663
- entityType: "trackedChange",
11664
- entityId: snapshot.runtimeRef.rawId,
11665
- story: snapshot.story
11666
- });
11667
- } catch {
11668
- resolvedChange = null;
11669
- }
11670
- const storyEditorState = resolvedChange?.editor?.state ?? null;
11671
- if (!storyEditorState) return fallbackParams;
11672
- let trackedChangesForId = [];
11673
- try {
11674
- trackedChangesForId = trackChangesHelpers.getTrackChanges(storyEditorState, resolvedChange.change.rawId) ?? [];
11675
- } catch {
11676
- trackedChangesForId = [];
11677
- }
11678
- const resolvedParams = createOrUpdateTrackedChangeComment({
11679
- event,
11680
- marks: collectTrackedChangeMarksByType(trackedChangesForId),
11681
- nodes: [],
11682
- newEditorState: storyEditorState,
11683
- documentId,
11684
- trackedChangesForId
11685
- });
11686
- if (!resolvedParams) return fallbackParams;
11687
- if (resolvedParams.semanticColorKey == null && snapshot.semanticColorKey != null) resolvedParams.semanticColorKey = snapshot.semanticColorKey;
11688
- if (resolvedParams.semanticColor == null && snapshot.semanticColor != null) resolvedParams.semanticColor = snapshot.semanticColor;
11689
- resolvedParams.trackedChangeStory = snapshot.story;
11690
- resolvedParams.trackedChangeStoryKind = snapshot.storyKind;
11691
- resolvedParams.trackedChangeStoryLabel = snapshot.storyLabel;
11692
- resolvedParams.trackedChangeAnchorKey = snapshot.anchorKey;
11693
- return resolvedParams;
11694
- };
11695
- const upsertStoryTrackedChangeComment = ({ superdoc, editor, snapshot, documentId, broadcastChanges, documentState, resolveFromEditor }) => {
11696
- if (!snapshot?.runtimeRef?.rawId) return;
11697
- const existingComment = commentsList.value.find((comment) => {
11698
- if (!comment?.trackedChange) return false;
11699
- const commentAnchorKey = comment.trackedChangeAnchorKey != null ? String(comment.trackedChangeAnchorKey) : null;
11700
- if (commentAnchorKey && snapshot.anchorKey) return commentAnchorKey === snapshot.anchorKey;
11701
- if (commentAnchorKey || snapshot.anchorKey) return false;
11702
- return comment.commentId === snapshot.runtimeRef.rawId || comment.importedId === snapshot.runtimeRef.rawId;
11703
- });
11704
- const params = buildStoryTrackedChangeParams({
11705
- editor,
11706
- snapshot,
11707
- documentId,
11708
- event: existingComment ? "update" : "add",
11709
- resolveFromEditor
11710
- });
11711
- handleTrackedChangeUpdate({
11712
- superdoc,
11713
- params,
11714
- broadcastChanges,
11715
- documentState
11716
- });
11717
- if (existingComment) {
11718
- existingComment.trackedChangeStory = snapshot.story;
11719
- existingComment.trackedChangeStoryKind = snapshot.storyKind;
11720
- existingComment.trackedChangeStoryLabel = snapshot.storyLabel;
11721
- existingComment.trackedChangeAnchorKey = snapshot.anchorKey;
11722
- }
11723
- };
11724
- const normalizeDocxSchemaForExport = (value) => {
11725
- if (!value) return [];
11726
- return (Array.isArray(value) ? value : [value]).filter(Boolean);
11727
- };
11728
- const translateCommentsForExport = () => {
11729
- const processedComments = [];
11730
- commentsList.value.forEach((comment) => {
11731
- const values = comment.getValues();
11732
- const richText = values.commentText;
11733
- const docxSchema = normalizeDocxSchemaForExport(values.docxCommentJSON);
11734
- const schema = docxSchema.length ? docxSchema : convertHtmlToSchema(richText);
11735
- processedComments.push({
11736
- ...values,
11737
- commentJSON: schema
11738
- });
11739
- });
11740
- return processedComments;
11741
- };
11742
- const convertHtmlToSchema = (commentHTML) => {
11743
- const json = new Editor({
11744
- mode: "text",
11745
- isHeadless: true,
11746
- content: commentHTML,
11747
- extensions: getRichTextExtensions()
11748
- }).getJSON();
11749
- return Array.isArray(json?.content) ? json.content.filter(Boolean) : [];
11750
- };
11751
10853
  /**
11752
10854
  * Triggered when the editor locations are updated
11753
10855
  * Updates floating comment locations from the editor
@@ -11810,150 +10912,12 @@ var useCommentsStore = defineStore("comments", () => {
11810
10912
  const clearEditorCommentPositions = () => {
11811
10913
  editorCommentPositions.value = {};
11812
10914
  };
11813
- /**
11814
- * Identify the single structural (whole-table) bubble for a tracked table so
11815
- * it is NEVER suppressed by the table-subsume filter below. The structural
11816
- * bubble is the parent "Added table" / "Deleted table" change; its public
11817
- * id is `word:structural:<id>` (or a bare structural fallback) and its display
11818
- * type is `tableInsert` / `tableDelete`.
11819
- *
11820
- * @param {Object} comment
11821
- * @returns {boolean}
11822
- */
11823
- const isStructuralTableBubble = (comment) => {
11824
- if (!comment?.trackedChange) return false;
11825
- const displayType = comment?.trackedChangeDisplayType;
11826
- if (displayType === "tableInsert" || displayType === "tableDelete") return true;
11827
- return [
11828
- comment?.commentId,
11829
- comment?.importedId,
11830
- comment?.trackedChangeAnchorKey
11831
- ].map((id) => id != null ? String(id) : "").filter(Boolean).some((id) => id.includes("word:structural:"));
11832
- };
11833
- /**
11834
- * Compute the decidable whole-table tracked-change ranges for a comment's
11835
- * document, memoized per editor state so the filter does not re-enumerate the
11836
- * document once per comment. Returns `[]` when the document has no tracked
11837
- * whole-table change (the common case), so non-tracked tables and inline-only
11838
- * tracked changes are never affected.
11839
- *
11840
- * @param {string | null | undefined} fileId
11841
- * @returns {Array<{ from: number, to: number }>}
11842
- */
11843
- const trackedTableSummaryCache = /* @__PURE__ */ new WeakMap();
11844
- /**
11845
- * Single source of truth for the decidable whole-table tracked changes in an
11846
- * editor state, enumerated and memoized ONCE per state. Returns:
11847
- * - `ranges`: each tracked whole-table's `{ from, to }` document span. Used to
11848
- * test whether an inline tracked change falls inside a tracked table.
11849
- * - `ids`: every change id associated with those tables (the change's public
11850
- * id / revisionId / revisionGroupId / sourceId plus each row's trackChange
11851
- * id / sourceId). Text typed inside a tracked-inserted row inherits that
11852
- * row's revision id, so such an inline change reports a changeId that is one
11853
- * of these — it must be subsumed by the structural bubble, not get its own
11854
- * review item.
11855
- *
11856
- * @param {object | null | undefined} state
11857
- * @returns {{ ranges: Array<{ from: number, to: number }>, ids: Set<string> }}
11858
- */
11859
- const computeTrackedTableSummaryForState = (state) => {
11860
- if (!state) return {
11861
- ranges: [],
11862
- ids: /* @__PURE__ */ new Set()
11863
- };
11864
- const cached = trackedTableSummaryCache.get(state);
11865
- if (cached) return cached;
11866
- const ranges = [];
11867
- const ids = /* @__PURE__ */ new Set();
11868
- const add = (value) => {
11869
- if (value != null && value !== "") ids.add(String(value));
11870
- };
11871
- const enumerate = trackChangesHelpers?.enumerateStructuralRowChanges;
11872
- if (typeof enumerate === "function") {
11873
- let structuralChanges = [];
11874
- try {
11875
- structuralChanges = enumerate(state) ?? [];
11876
- } catch {
11877
- structuralChanges = [];
11878
- }
11879
- for (const change of structuralChanges) {
11880
- if (!change?.decidable || !change?.wholeTable) continue;
11881
- const from = Number(change.tableFrom);
11882
- const to = Number(change.tableTo);
11883
- if (Number.isFinite(from) && Number.isFinite(to)) ranges.push({
11884
- from,
11885
- to
11886
- });
11887
- add(change.id);
11888
- add(change.revisionId);
11889
- add(change.revisionGroupId);
11890
- add(change.sourceId);
11891
- for (const row of change.rows || []) {
11892
- const tc = row?.node?.attrs?.trackChange;
11893
- add(tc?.id);
11894
- add(tc?.sourceId);
11895
- }
11896
- }
11897
- }
11898
- const summary = {
11899
- ranges,
11900
- ids
11901
- };
11902
- trackedTableSummaryCache.set(state, summary);
11903
- return summary;
11904
- };
11905
- const getTrackedTableRangesForDocument = (fileId) => {
11906
- const editor = superdocStore.getDocument(fileId)?.getEditor?.();
11907
- return computeTrackedTableSummaryForState(editor?.state).ranges;
11908
- };
11909
- /**
11910
- * True when every `{ from, to }` range of an inline tracked change is wholly
11911
- * contained within some decidable whole-table tracked-change range. Such an
11912
- * inline change is subsumed by the structural "Inserted/Deleted table" review
11913
- * item and must NOT become an independent review item (no comment object →
11914
- * no floating bubble and no active-on-click dialog). The underlying
11915
- * trackInsert/trackDelete mark (the green highlight) is untouched — only the
11916
- * review-item comment is suppressed.
11917
- *
11918
- * @param {Array<{ from?: number, to?: number }>} changeRanges
11919
- * @param {Array<{ from: number, to: number }>} tableRanges
11920
- * @returns {boolean}
11921
- */
11922
- const isInlineRangeInsideTrackedTable = (changeRanges, tableRanges) => {
11923
- if (!tableRanges?.length || !changeRanges?.length) return false;
11924
- return changeRanges.every((seg) => {
11925
- const start = Number(seg?.from);
11926
- const end = Number(seg?.to);
11927
- if (!Number.isFinite(start) || !Number.isFinite(end)) return false;
11928
- return tableRanges.some((table) => start >= table.from && end <= table.to);
11929
- });
11930
- };
11931
- /**
11932
- * Suppress an inline tracked-change bubble whose document range falls within a
11933
- * tracked whole-table change's range, so only the structural "Added table"
11934
- * / "Deleted table" bubble shows for that table (matching Word / Google Docs).
11935
- * The structural bubble itself, real user comments, and inline tracked changes
11936
- * inside a NON-tracked table are never suppressed.
11937
- *
11938
- * @param {Object} comment
11939
- * @returns {boolean} True when the bubble must NOT render.
11940
- */
11941
- const isInlineTrackedChangeInsideTrackedTable = (comment) => {
11942
- if (!comment?.trackedChange) return false;
11943
- if (isStructuralTableBubble(comment)) return false;
11944
- const ranges = getTrackedTableRangesForDocument(comment?.fileId);
11945
- if (!ranges.length) return false;
11946
- const entry = resolveCommentPositionEntry(comment).entry;
11947
- const range = getCommentPositionRange(entry);
11948
- if (!range) return false;
11949
- return ranges.some((table) => range.start >= table.from && range.end <= table.to);
11950
- };
11951
10915
  const getFloatingComments = require__plugin_vue_export_helper.computed(() => {
11952
10916
  return getGroupedComments.value?.parentComments.filter((c) => !c.resolvedTime).filter((c) => {
11953
10917
  if (!isEditorBackedComment(c)) return true;
11954
10918
  if (isTrackedChangeThread(c)) return true;
11955
10919
  return Boolean(resolveCommentPositionEntry(c).entry);
11956
- }).filter((c) => !isInlineTrackedChangeInsideTrackedTable(c));
10920
+ });
11957
10921
  });
11958
10922
  const getFloatingCommentInstances = require__plugin_vue_export_helper.computed(() => {
11959
10923
  return getFloatingComments.value.flatMap((comment) => {
@@ -11998,75 +10962,6 @@ var useCommentsStore = defineStore("comments", () => {
11998
10962
  if (typeof commentsVisible === "boolean") viewingVisibility.commentsVisible = commentsVisible;
11999
10963
  if (typeof trackChangesVisible === "boolean") viewingVisibility.trackChangesVisible = trackChangesVisible;
12000
10964
  };
12001
- /**
12002
- * Get HTML content from the comment text JSON (which uses DOCX schema)
12003
- *
12004
- * @param {Object} commentTextJson The comment text JSON
12005
- * @returns {string} The HTML content
12006
- */
12007
- const normalizeCommentForEditor = (node) => {
12008
- if (Array.isArray(node)) return node.map((child) => normalizeCommentForEditor(child)).flat().filter(Boolean);
12009
- if (!node || typeof node !== "object") return node;
12010
- const stripTextStyleAttrs = (attrs) => {
12011
- if (!attrs) return attrs;
12012
- const rest = { ...attrs };
12013
- delete rest.fontSize;
12014
- delete rest.fontFamily;
12015
- delete rest.eastAsiaFontFamily;
12016
- return Object.keys(rest).length ? rest : void 0;
12017
- };
12018
- const normalizeMark = (mark) => {
12019
- if (!mark) return mark;
12020
- const typeName = typeof mark.type === "string" ? mark.type : mark.type?.name;
12021
- const attrs = mark?.attrs ? { ...mark.attrs } : void 0;
12022
- if (typeName === "textStyle" && attrs) return {
12023
- ...mark,
12024
- attrs: stripTextStyleAttrs(attrs)
12025
- };
12026
- return {
12027
- ...mark,
12028
- attrs
12029
- };
12030
- };
12031
- const cloneMarks = (marks) => Array.isArray(marks) ? marks.filter(Boolean).map((mark) => normalizeMark(mark)) : void 0;
12032
- const cloneAttrs = (attrs) => attrs && typeof attrs === "object" ? { ...attrs } : void 0;
12033
- if (!Array.isArray(node.content)) return {
12034
- type: node.type,
12035
- ...node.text !== void 0 ? { text: node.text } : {},
12036
- ...node.attrs ? { attrs: cloneAttrs(node.attrs) } : {},
12037
- ...node.marks ? { marks: cloneMarks(node.marks) } : {}
12038
- };
12039
- const normalizedChildren = node.content.map((child) => normalizeCommentForEditor(child)).flat().filter(Boolean);
12040
- if (node.type === "run") return normalizedChildren;
12041
- return {
12042
- type: node.type,
12043
- ...node.attrs ? { attrs: cloneAttrs(node.attrs) } : {},
12044
- ...node.marks ? { marks: cloneMarks(node.marks) } : {},
12045
- content: normalizedChildren
12046
- };
12047
- };
12048
- const getHtmlFromComment = (commentTextElements) => {
12049
- const elementsArray = Array.isArray(commentTextElements) ? commentTextElements : commentTextElements ? [commentTextElements] : [];
12050
- if (!elementsArray.some((element) => element?.content?.length)) return;
12051
- try {
12052
- const normalizedContent = normalizeCommentForEditor(elementsArray);
12053
- const contentArray = Array.isArray(normalizedContent) ? normalizedContent : normalizedContent ? [normalizedContent] : [];
12054
- if (!contentArray.length) return null;
12055
- return new Editor({
12056
- mode: "text",
12057
- isHeadless: true,
12058
- content: {
12059
- type: "doc",
12060
- content: contentArray
12061
- },
12062
- loadFromSchema: true,
12063
- extensions: getRichTextExtensions()
12064
- }).getHTML();
12065
- } catch (error) {
12066
- console.warn("Failed to convert comment", error);
12067
- return;
12068
- }
12069
- };
12070
10965
  return {
12071
10966
  COMMENT_EVENTS,
12072
10967
  isDebugging,
@@ -12135,23 +11030,17 @@ var useCommentsStore = defineStore("comments", () => {
12135
11030
  cancelComment,
12136
11031
  deleteComment,
12137
11032
  removePendingComment,
12138
- cancelImportedTrackedChangeBootstrap,
12139
11033
  removeCommentsForDocument,
12140
11034
  setReviewDirectoryFromV2,
12141
11035
  clearReviewDirectory,
12142
- processLoadedDocxComments,
12143
- translateCommentsForExport,
12144
11036
  handleEditorLocationsUpdate,
12145
11037
  clearEditorCommentPositions,
12146
11038
  handleTrackedChangeUpdate,
12147
- refreshTrackedChangeCommentsByIds,
12148
11039
  syncResolvedCommentsWithDocument,
12149
- syncTrackedChangePositionsWithDocument,
12150
11040
  setActiveFloatingCommentInstance,
12151
11041
  requestInstantSidebarAlignment,
12152
11042
  peekInstantSidebarAlignment,
12153
11043
  clearInstantSidebarAlignment,
12154
- syncTrackedChangeComments,
12155
11044
  decideTrackedChangeFromSidebar,
12156
11045
  v2CommentsAdapter,
12157
11046
  setV2CommentsAdapter,
@@ -22168,7 +21057,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
22168
21057
  }
22169
21058
  });
22170
21059
  const { getConfig, documentsWithConverations, commentsList, pendingComment, activeComment, skipSelectionUpdate, commentsByDocument, isCommentsListVisible, isFloatingCommentsReady, generalCommentIds, hasSyncedCollaborationComments, editorCommentPositions, hasInitializedLocations, isCommentHighlighted, hasOpenTrackedChanges } = storeToRefs(commentsStore);
22171
- const { showAddComment, handleEditorLocationsUpdate, handleTrackedChangeUpdate, refreshTrackedChangeCommentsByIds, syncTrackedChangePositionsWithDocument, syncTrackedChangeComments, addComment, addHydratedComment, getComment, resolveCommentPositionEntry, belongsToDocument, COMMENT_EVENTS, requestInstantSidebarAlignment, peekInstantSidebarAlignment, clearInstantSidebarAlignment } = commentsStore;
21060
+ const { showAddComment, handleEditorLocationsUpdate, handleTrackedChangeUpdate, addComment, addHydratedComment, getComment, resolveCommentPositionEntry, belongsToDocument, COMMENT_EVENTS, requestInstantSidebarAlignment, peekInstantSidebarAlignment, clearInstantSidebarAlignment } = commentsStore;
22172
21061
  const { proxy } = require__plugin_vue_export_helper.getCurrentInstance();
22173
21062
  commentsStore.proxy = proxy;
22174
21063
  const documentOpenTelemetry = createDocumentOpenTelemetry(proxy.$superdoc.config);
@@ -22220,7 +21109,6 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
22220
21109
  const layers = require__plugin_vue_export_helper.ref(null);
22221
21110
  const rightSidebarRef = require__plugin_vue_export_helper.ref(null);
22222
21111
  const pdfViewerRef = require__plugin_vue_export_helper.ref(null);
22223
- const pendingReplayTrackedChangeSync = require__plugin_vue_export_helper.ref(false);
22224
21112
  const toolsMenuPosition = require__plugin_vue_export_helper.reactive({
22225
21113
  top: null,
22226
21114
  right: "-25px",
@@ -22283,20 +21171,6 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
22283
21171
  }
22284
21172
  });
22285
21173
  const pdfConfig = proxy.$superdoc.config.modules?.pdf || {};
22286
- const flushPendingReplayTrackedChangeSync = () => {
22287
- if (!pendingReplayTrackedChangeSync.value) return;
22288
- pendingReplayTrackedChangeSync.value = false;
22289
- syncTrackedChangeComments({
22290
- superdoc: proxy.$superdoc,
22291
- editor: proxy.$superdoc?.activeEditor
22292
- });
22293
- };
22294
- const scheduleReplayTrackedChangeSync = () => {
22295
- pendingReplayTrackedChangeSync.value = true;
22296
- require__plugin_vue_export_helper.nextTick(() => {
22297
- flushPendingReplayTrackedChangeSync();
22298
- });
22299
- };
22300
21174
  const handleDocumentReady = (documentId, container) => {
22301
21175
  const doc = getDocument(documentId);
22302
21176
  if (!doc || doc.loadScope && !doc.loadScope.finish()) return;
@@ -23296,7 +22170,6 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
23296
22170
  v2PageMetricsSnapshot.value = null;
23297
22171
  const clearedDocumentId = payload?.documentId == null ? null : String(payload.documentId);
23298
22172
  clearV2MutationRejectionNotifications(clearedDocumentId);
23299
- commentsStore.cancelImportedTrackedChangeBootstrap?.(clearedDocumentId ?? void 0);
23300
22173
  if (clearedDocumentId) v2MountStagesByDocumentId.delete(clearedDocumentId);
23301
22174
  if (latestV2MountStage && (clearedDocumentId == null || latestV2MountStage.dataset?.superdocV2DocumentId === clearedDocumentId)) latestV2MountStage = null;
23302
22175
  v2ReviewWindowController.reset("render-cleared");
@@ -23312,7 +22185,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
23312
22185
  ...event,
23313
22186
  documentId: document?.id ?? null
23314
22187
  }));
23315
- if (event.type === "mutation:committed" && event.origin === "extension") return;
22188
+ if (event.type === "mutation:committed" && event.dryRun) return;
23316
22189
  const documentId = document?.id ?? null;
23317
22190
  if (event.type === "history:changed" && event.state) {
23318
22191
  proxy.$superdoc.emit("history-change", {
@@ -23830,7 +22703,6 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
23830
22703
  existingComment: null
23831
22704
  };
23832
22705
  };
23833
- if (type === "replayCompleted") scheduleReplayTrackedChangeSync();
23834
22706
  if (COMMENT_EVENTS?.ADD && type === COMMENT_EVENTS.ADD && commentPayload) {
23835
22707
  commentPayload = normalizeReplayCommentModelPayload(commentPayload);
23836
22708
  const currentUser = proxy.$superdoc?.user;
@@ -24139,7 +23011,6 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
24139
23011
  handleFormattingMarksShortcut(e);
24140
23012
  }
24141
23013
  require__plugin_vue_export_helper.onBeforeUnmount(() => {
24142
- commentsStore.cancelImportedTrackedChangeBootstrap?.();
24143
23014
  passwordPrompt.destroy();
24144
23015
  findReplace.destroy();
24145
23016
  linkPopover.destroy();
@@ -24755,7 +23626,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
24755
23626
  ], 46, _hoisted_1$17);
24756
23627
  };
24757
23628
  }
24758
- }, [["__scopeId", "data-v-3ac816de"]]);
23629
+ }, [["__scopeId", "data-v-9c1ff6d7"]]);
24759
23630
  //#endregion
24760
23631
  //#region src/core/create-app.js
24761
23632
  var PINIA_DEVTOOLS_SETUP_EVENT = "devtools-plugin:setup";
@@ -46487,7 +45358,7 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
46487
45358
  }
46488
45359
  this.userColorMap = /* @__PURE__ */ new Map();
46489
45360
  this.colorIndex = 0;
46490
- this.version = "2.28.0-next.12";
45361
+ this.version = "2.28.0-next.14";
46491
45362
  this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
46492
45363
  this.superdocId = config.superdocId || require_uuid.v4();
46493
45364
  this.colors = this.config.colors ?? [];
@@ -48511,23 +47382,6 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
48511
47382
  confirmed
48512
47383
  };
48513
47384
  }
48514
- const legacyReplaceFile = activeEditor && !isV2ActiveEditorFacade(activeEditor) ? activeEditor.replaceFile : null;
48515
- if (typeof legacyReplaceFile === "function") {
48516
- const result = await legacyReplaceFile.call(activeEditor, source);
48517
- const legacyState = result && typeof result === "object" ? result.state : void 0;
48518
- const legacyConfirmed = legacyState === void 0 || legacyState === null || legacyState === "review-ready" || legacyState === "editing-ready";
48519
- if (legacyConfirmed) {
48520
- this.#replaceActiveDocumentData(activeEditor, source);
48521
- this.emit("document-replaced", {
48522
- editor: activeEditor,
48523
- host: activeEditor?.host
48524
- });
48525
- }
48526
- return {
48527
- raw: result,
48528
- confirmed: legacyConfirmed
48529
- };
48530
- }
48531
47385
  throw new Error("SuperDoc: replaceFile is unavailable for the active editor");
48532
47386
  }
48533
47387
  /**
@@ -48540,19 +47394,6 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
48540
47394
  commentsType,
48541
47395
  isFinalDoc
48542
47396
  });
48543
- const uiStoreHydrated = this.config?.modules?.comments !== false;
48544
- let legacyComments;
48545
- let legacyCommentsComputed = false;
48546
- const getLegacyCommentsForV1 = () => {
48547
- if (legacyCommentsComputed) return legacyComments;
48548
- legacyCommentsComputed = true;
48549
- if (commentsType === "clean") legacyComments = [];
48550
- else if (uiStoreHydrated && this.commentsStore && typeof this.commentsStore.translateCommentsForExport === "function") {
48551
- legacyComments = this.commentsStore.translateCommentsForExport();
48552
- if (!Array.isArray(legacyComments)) legacyComments = [];
48553
- }
48554
- return legacyComments;
48555
- };
48556
47397
  const bridgedExportErrors = /* @__PURE__ */ new WeakSet();
48557
47398
  const rememberBridgedExportError = (payload) => {
48558
47399
  if ("editor" in payload && payload.error && typeof payload.error === "object") bridgedExportErrors.add(payload.error);
@@ -48563,7 +47404,7 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
48563
47404
  if (policies !== void 0 && documents.some((doc) => {
48564
47405
  if (doc.type !== "application/vnd.openxmlformats-officedocument.wordprocessingml.document") return false;
48565
47406
  const editor = doc.getEditor?.();
48566
- return editor?.editorVersion !== 2 || typeof editor.exportDocx !== "function";
47407
+ return !isV2ActiveEditorFacade(editor) || typeof editor.exportDocx !== "function";
48567
47408
  })) throw new Error("Independent DOCX export policies require a mounted V2 exporter for every document.");
48568
47409
  const docxPromises = documents.map(async (doc) => {
48569
47410
  if (!doc || doc.type !== "application/vnd.openxmlformats-officedocument.wordprocessingml.document") return null;
@@ -48576,19 +47417,13 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
48576
47417
  if (isDocumentByteSource(doc.data)) return this.#savedDocxToBlob(doc.data);
48577
47418
  return null;
48578
47419
  };
48579
- if (!editor || typeof editor.exportDocx !== "function") return fallbackDocx();
48580
- const isV2Editor = editor.editorVersion === 2;
47420
+ if (!isV2ActiveEditorFacade(editor) || typeof editor.exportDocx !== "function") return fallbackDocx();
48581
47421
  try {
48582
- const exported = await editor.exportDocx(isV2Editor ? {
47422
+ const exported = await editor.exportDocx({
48583
47423
  isFinalDoc,
48584
47424
  commentsType,
48585
47425
  policies,
48586
47426
  fieldsHighlightColor
48587
- } : {
48588
- isFinalDoc,
48589
- comments: getLegacyCommentsForV1(),
48590
- commentsType,
48591
- fieldsHighlightColor
48592
47427
  });
48593
47428
  if (exported) return exported;
48594
47429
  } catch (error) {
@@ -48602,7 +47437,7 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
48602
47437
  editor: null
48603
47438
  }));
48604
47439
  }
48605
- if (isV2Editor) throw error;
47440
+ throw error;
48606
47441
  }
48607
47442
  return fallbackDocx();
48608
47443
  });