superdoc 2.12.0-next.8 → 2.12.0

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 (44) hide show
  1. package/dist/chunks/{FindReplaceSurface-40AnrqWk.es.js → FindReplaceSurface-CVKgivXi.es.js} +8 -2
  2. package/dist/chunks/{FindReplaceSurface-0p7EtMZh.cjs → FindReplaceSurface-qi9OhbwN.cjs} +8 -2
  3. package/dist/chunks/{create-super-doc-ui-CBFGggZ2.cjs → create-super-doc-ui-BWWWNPP8.cjs} +180 -84
  4. package/dist/chunks/{create-super-doc-ui-C-AuEM9F.es.js → create-super-doc-ui-FnwgTkUv.es.js} +180 -84
  5. package/dist/collaboration-upgrade-engine.cjs +1 -1
  6. package/dist/collaboration-upgrade-engine.es.js +1 -1
  7. package/dist/layout-engine/contracts/src/column-layout.d.ts +58 -1
  8. package/dist/layout-engine/contracts/src/graphic-placement.d.ts +3 -0
  9. package/dist/layout-engine/contracts/src/index.d.ts +17 -3
  10. package/dist/layout-engine/contracts/src/run-helpers.d.ts +8 -0
  11. package/dist/layout-engine/layout-bridge/src/cache.d.ts +5 -4
  12. package/dist/layout-engine/layout-bridge/src/incrementalLayout.d.ts +4 -1
  13. package/dist/layout-engine/layout-bridge/src/note-marker-measure-key.d.ts +3 -0
  14. package/dist/layout-engine/layout-engine/src/column-balancing.d.ts +11 -7
  15. package/dist/layout-engine/layout-engine/src/layout-paragraph.d.ts +2 -6
  16. package/dist/layout-engine/painters/dom/src/derived-run-text-plane.d.ts +9 -0
  17. package/dist/layout-engine/painters/dom/src/index.d.ts +1 -0
  18. package/dist/layout-engine/painters/dom/src/page-content.d.ts +3 -1
  19. package/dist/layout-engine/painters/dom/src/persistent-page-surface.d.ts +2 -0
  20. package/dist/layout-engine/painters/dom/src/renderer.d.ts +9 -16
  21. package/dist/public/ui-react.cjs +18 -1
  22. package/dist/public/ui-react.es.js +18 -2
  23. package/dist/public/ui-vue.cjs +18 -1
  24. package/dist/public/ui-vue.es.js +18 -2
  25. package/dist/public/ui.cjs +1 -1
  26. package/dist/public/ui.es.js +1 -1
  27. package/dist/shared/font-system/src/index.d.ts +1 -1
  28. package/dist/shared/font-system/src/resolver.d.ts +11 -0
  29. package/dist/style.css +40 -40
  30. package/dist/style.layered.css +40 -40
  31. package/dist/superdoc/src/core/types/index.d.ts +20 -12
  32. package/dist/superdoc/src/public/ui/react.d.ts +3 -1
  33. package/dist/superdoc/src/public/ui/types.d.ts +67 -9
  34. package/dist/superdoc/src/public/ui/vue.d.ts +3 -1
  35. package/dist/superdoc/src/public/ui-react.d.cts +1 -0
  36. package/dist/superdoc/src/public/ui-react.d.ts +1 -1
  37. package/dist/superdoc/src/public/ui-vue.d.cts +1 -0
  38. package/dist/superdoc/src/public/ui-vue.d.ts +1 -1
  39. package/dist/superdoc.cjs +138 -12
  40. package/dist/superdoc.es.js +138 -12
  41. package/dist-cdn/style.layered.css +1 -1
  42. package/dist-cdn/superdoc.min.css +1 -1
  43. package/dist-cdn/superdoc.min.js +37 -37
  44. package/package.json +2 -2
@@ -3,7 +3,7 @@ import { t as blank_default } from "./chunks/blank-docx-DzQccOlW.es.js";
3
3
  import { t as import_eventemitter3 } from "./chunks/eventemitter3-DEIiXiH2.es.js";
4
4
  import { t as v4 } from "./chunks/uuid-H0Xcmmhy.es.js";
5
5
  import { a as init_dist$1, i as global, n as init_dist$2, o as Buffer, r as process$1, s as init_dist, t as require_jszip_min } from "./chunks/jszip-BzJ3CyxR.es.js";
6
- import { a as DOM_CLASS_NAMES, i as getV2TrackedChangeMutationImpact, t as createSuperDocUI } from "./chunks/create-super-doc-ui-C-AuEM9F.es.js";
6
+ import { a as DOM_CLASS_NAMES, i as getV2TrackedChangeMutationImpact, t as createSuperDocUI } from "./chunks/create-super-doc-ui-FnwgTkUv.es.js";
7
7
  import { t as _plugin_vue_export_helper_default } from "./chunks/_plugin-vue_export-helper-BOaGB7Aw.es.js";
8
8
  import { t as PDF_TO_CSS_UNITS } from "./chunks/constants-B6VBlmKp.es.js";
9
9
  import * as Vue from "vue";
@@ -315,7 +315,7 @@ var shuffleArray = (array) => {
315
315
  var DEFAULT_ENDPOINT = "https://ingest.superdoc.dev/v1/collect";
316
316
  function getSuperdocVersion() {
317
317
  try {
318
- return "2.12.0-next.8";
318
+ return "2.12.0";
319
319
  } catch {
320
320
  return "unknown";
321
321
  }
@@ -10187,6 +10187,115 @@ var useCommentsStore = defineStore("comments", () => {
10187
10187
  const type = normalizeTrackedChangeDecisionType(comment?.trackedChangeDisplayType) ?? normalizeTrackedChangeDecisionType(comment?.trackedChangeType);
10188
10188
  return normalizedDecision === "accept" && type === "insertion" || normalizedDecision === "reject" && type === "deletion";
10189
10189
  };
10190
+ const getBodyTrackedChangeIdentityIds = (comment) => {
10191
+ const commentId = normalizeCommentId(comment.commentId);
10192
+ const canonicalId = normalizeCommentId(comment.trackedChangeCanonicalId);
10193
+ return [commentId, ...!(canonicalId && canonicalId !== commentId) ? [
10194
+ comment.importedId,
10195
+ canonicalId,
10196
+ comment.trackedChangeAnchorKey,
10197
+ ...normalizeTrackedChangePositionAliases(comment.trackedChangePositionAliases)
10198
+ ] : []].map((id) => normalizeCommentId(id)).filter(Boolean);
10199
+ };
10200
+ const groupBodyTrackedChangeCommentsByIdentity = (comments) => {
10201
+ const parents = comments.map((_, index) => index);
10202
+ const findRoot = (index) => {
10203
+ let root = index;
10204
+ while (parents[root] !== root) root = parents[root];
10205
+ while (parents[index] !== index) {
10206
+ const next = parents[index];
10207
+ parents[index] = root;
10208
+ index = next;
10209
+ }
10210
+ return root;
10211
+ };
10212
+ const join = (left, right) => {
10213
+ const leftRoot = findRoot(left);
10214
+ const rightRoot = findRoot(right);
10215
+ if (leftRoot === rightRoot) return;
10216
+ parents[Math.max(leftRoot, rightRoot)] = Math.min(leftRoot, rightRoot);
10217
+ };
10218
+ const identityOwner = /* @__PURE__ */ new Map();
10219
+ comments.forEach((comment, index) => {
10220
+ getBodyTrackedChangeIdentityIds(comment).forEach((identityId) => {
10221
+ const owner = identityOwner.get(identityId);
10222
+ if (owner === void 0) identityOwner.set(identityId, index);
10223
+ else join(index, owner);
10224
+ });
10225
+ });
10226
+ const groups = /* @__PURE__ */ new Map();
10227
+ comments.forEach((comment, index) => {
10228
+ const root = findRoot(index);
10229
+ const group = groups.get(root) ?? [];
10230
+ group.push(comment);
10231
+ groups.set(root, group);
10232
+ });
10233
+ return groups;
10234
+ };
10235
+ const mergeDuplicateBodyTrackedChangeComments = (groups) => {
10236
+ const duplicates = /* @__PURE__ */ new Map();
10237
+ groups.forEach(([survivor, ...duplicateRows]) => {
10238
+ if (!survivor || duplicateRows.length === 0) return;
10239
+ const resolvedDuplicate = duplicateRows.find((comment) => comment.resolvedTime != null);
10240
+ if (survivor.resolvedTime == null && resolvedDuplicate) {
10241
+ survivor.resolvedTime = resolvedDuplicate.resolvedTime;
10242
+ survivor.resolvedById = resolvedDuplicate.resolvedById;
10243
+ survivor.resolvedByEmail = resolvedDuplicate.resolvedByEmail;
10244
+ survivor.resolvedByName = resolvedDuplicate.resolvedByName;
10245
+ survivor.trackedChangeDecision = resolvedDuplicate.trackedChangeDecision;
10246
+ }
10247
+ survivor.trackedChangePositionAliases = normalizeTrackedChangePositionAliases([...normalizeTrackedChangePositionAliases(survivor.trackedChangePositionAliases), ...duplicateRows.flatMap((comment) => [
10248
+ comment.commentId,
10249
+ comment.importedId,
10250
+ comment.trackedChangeCanonicalId,
10251
+ ...normalizeTrackedChangePositionAliases(comment.trackedChangePositionAliases)
10252
+ ])]);
10253
+ duplicateRows.forEach((comment) => duplicates.set(comment, survivor));
10254
+ });
10255
+ return duplicates;
10256
+ };
10257
+ const createDroppedCommentIdMap = (duplicates) => {
10258
+ const droppedCommentIds = /* @__PURE__ */ new Map();
10259
+ duplicates.forEach((survivor, duplicate) => {
10260
+ const fromId = normalizeCommentId(duplicate.commentId);
10261
+ const toId = normalizeCommentId(survivor.commentId);
10262
+ if (fromId && toId) droppedCommentIds.set(fromId, toId);
10263
+ });
10264
+ return droppedCommentIds;
10265
+ };
10266
+ const remapTrackedChangeReferences = (droppedCommentIds, activeDocumentId) => {
10267
+ const remapSelection = (selection) => {
10268
+ const selectedId = normalizeCommentId(selection.value);
10269
+ if (selectedId && droppedCommentIds.has(selectedId)) selection.value = droppedCommentIds.get(selectedId);
10270
+ };
10271
+ remapSelection(activeComment);
10272
+ remapSelection(activeFloatingCommentInstanceId);
10273
+ commentsList.value.forEach((row) => {
10274
+ if (!belongsToTrackedChangeSyncDocument(row, activeDocumentId)) return;
10275
+ const rowIdentityUpdates = {};
10276
+ for (const field of [
10277
+ "trackedChangeThreadParentId",
10278
+ "trackedChangeParentId",
10279
+ "threadingParentCommentId",
10280
+ "parentCommentId"
10281
+ ]) {
10282
+ const replacementId = droppedCommentIds.get(normalizeCommentId(row?.[field]));
10283
+ if (!replacementId) continue;
10284
+ row[field] = replacementId;
10285
+ rowIdentityUpdates[field] = replacementId;
10286
+ }
10287
+ if (Object.keys(rowIdentityUpdates).length && typeof row.updateIdentityValues === "function") row.updateIdentityValues(rowIdentityUpdates);
10288
+ });
10289
+ };
10290
+ const compactDuplicateBodyTrackedChangeComments = (activeDocumentId) => {
10291
+ const candidates = commentsList.value.filter((comment) => isBodyTrackedChangeComment(comment) && belongsToTrackedChangeSyncDocument(comment, activeDocumentId));
10292
+ const groups = groupBodyTrackedChangeCommentsByIdentity(candidates);
10293
+ const duplicates = mergeDuplicateBodyTrackedChangeComments(groups);
10294
+ if (!duplicates.size) return 0;
10295
+ commentsList.value = commentsList.value.filter((comment) => !duplicates.has(comment));
10296
+ remapTrackedChangeReferences(createDroppedCommentIdMap(duplicates), activeDocumentId);
10297
+ return duplicates.size;
10298
+ };
10190
10299
  /**
10191
10300
  * Remove tracked-change comments that no longer have a corresponding mark in the editor.
10192
10301
  * Also removes any replies linked to those removed tracked-change threads.
@@ -10232,7 +10341,9 @@ var useCommentsStore = defineStore("comments", () => {
10232
10341
  if (importedId) removedIds.add(importedId);
10233
10342
  return false;
10234
10343
  });
10344
+ compactDuplicateBodyTrackedChangeComments(activeDocumentId);
10235
10345
  restoredComments.forEach((comment) => {
10346
+ if (!commentsList.value.includes(comment)) return;
10236
10347
  const payload = getCommentEventPayload(comment);
10237
10348
  const event = {
10238
10349
  type: COMMENT_EVENTS.UPDATE,
@@ -10822,11 +10933,14 @@ var useCommentsStore = defineStore("comments", () => {
10822
10933
  } finally {
10823
10934
  endInteractionSpan(identitySpan, trackedChangeIdentityIndex.work());
10824
10935
  }
10825
- if (!effectiveDocumentId || !pruneStale) return {
10826
- liveIds,
10827
- liveAnchorKeys,
10828
- appliedCount
10829
- };
10936
+ if (!effectiveDocumentId || !pruneStale) {
10937
+ if (effectiveDocumentId) compactDuplicateBodyTrackedChangeComments(String(effectiveDocumentId));
10938
+ return {
10939
+ liveIds,
10940
+ liveAnchorKeys,
10941
+ appliedCount
10942
+ };
10943
+ }
10830
10944
  pruneStaleTrackedChangeComments(liveIds, liveAnchorKeys, String(effectiveDocumentId), superdoc, { broadcastChanges: false });
10831
10945
  return {
10832
10946
  liveIds,
@@ -17248,6 +17362,7 @@ function useFindReplace({ getSurfaceManager, getActiveEditor, activeEditorRef, g
17248
17362
  const matchCount = ref(0);
17249
17363
  const activeMatchIndex = ref(-1);
17250
17364
  const canReplaceState = ref(true);
17365
+ const canReplaceAllState = ref(true);
17251
17366
  const replacePending = ref(false);
17252
17367
  const ignoreDiacriticsSupported = ref(true);
17253
17368
  const regexSupported = ref(false);
@@ -17262,6 +17377,7 @@ function useFindReplace({ getSurfaceManager, getActiveEditor, activeEditorRef, g
17262
17377
  });
17263
17378
  const hasMatches = computed(() => matchCount.value > 0);
17264
17379
  const canReplaceComputed = computed(() => hasMatches.value && !replacePending.value && canReplaceState.value);
17380
+ const canReplaceAllComputed = computed(() => canReplaceComputed.value && canReplaceAllState.value);
17265
17381
  /** @type {ReturnType<typeof setTimeout> | null} */
17266
17382
  let debounceTimer = null;
17267
17383
  /** @type {ReturnType<typeof setInterval> | null} */
@@ -17296,6 +17412,7 @@ function useFindReplace({ getSurfaceManager, getActiveEditor, activeEditorRef, g
17296
17412
  matchCount.value = typeof slice.total === "number" ? slice.total : 0;
17297
17413
  activeMatchIndex.value = typeof slice.activeIndex === "number" ? slice.activeIndex : -1;
17298
17414
  canReplaceState.value = slice.canReplace === true;
17415
+ canReplaceAllState.value = typeof slice.canReplaceAll === "boolean" ? slice.canReplaceAll : slice.canReplace === true;
17299
17416
  searchError.value = slice.reason === "search-invalid-pattern" ? currentTexts.invalidPatternLabel : null;
17300
17417
  }
17301
17418
  function runSearch() {
@@ -17432,7 +17549,7 @@ function useFindReplace({ getSurfaceManager, getActiveEditor, activeEditorRef, g
17432
17549
  if (replacePending.value) return;
17433
17550
  if (!hasMatches.value) return;
17434
17551
  if (currentV2Search) {
17435
- if (!canReplaceState.value) return;
17552
+ if (!canReplaceState.value || !canReplaceAllState.value) return;
17436
17553
  const search = currentV2Search;
17437
17554
  replacePending.value = true;
17438
17555
  const finish = createReplaceContinuation(search, {
@@ -17493,6 +17610,7 @@ function useFindReplace({ getSurfaceManager, getActiveEditor, activeEditorRef, g
17493
17610
  matchCount.value = 0;
17494
17611
  activeMatchIndex.value = -1;
17495
17612
  canReplaceState.value = true;
17613
+ canReplaceAllState.value = true;
17496
17614
  replacePending.value = false;
17497
17615
  }
17498
17616
  /**
@@ -17597,6 +17715,11 @@ function useFindReplace({ getSurfaceManager, getActiveEditor, activeEditorRef, g
17597
17715
  hasMatches,
17598
17716
  canReplace: canReplaceComputed,
17599
17717
  /**
17718
+ * `canReplace` plus the session enumerating every match. A truncated V2
17719
+ * session keeps Replace enabled and disables Replace all.
17720
+ */
17721
+ canReplaceAll: canReplaceAllComputed,
17722
+ /**
17600
17723
  * Runtime mutability of the active session (viewing/read-only mode sets
17601
17724
  * this false). Distinct from the static `replaceEnabled` config and from
17602
17725
  * `canReplace`, which also requires matches: surfaces hide replace
@@ -17686,6 +17809,9 @@ function useFindReplace({ getSurfaceManager, getActiveEditor, activeEditorRef, g
17686
17809
  get canReplace() {
17687
17810
  return handle.canReplace.value;
17688
17811
  },
17812
+ get canReplaceAll() {
17813
+ return handle.canReplaceAll ? handle.canReplaceAll.value : handle.canReplace.value;
17814
+ },
17689
17815
  get replacePending() {
17690
17816
  return handle.replacePending.value;
17691
17817
  },
@@ -17836,7 +17962,7 @@ function useFindReplace({ getSurfaceManager, getActiveEditor, activeEditorRef, g
17836
17962
  /** @type {object | undefined} */
17837
17963
  let FindReplaceSurface;
17838
17964
  try {
17839
- FindReplaceSurface = (await import("./chunks/FindReplaceSurface-40AnrqWk.es.js")).default;
17965
+ FindReplaceSurface = (await import("./chunks/FindReplaceSurface-CVKgivXi.es.js")).default;
17840
17966
  } catch {
17841
17967
  opening = false;
17842
17968
  return;
@@ -37402,7 +37528,7 @@ var TOOLBAR_ITEM_ALIASES = Object.freeze({
37402
37528
  * - `ui: false` renders no built-in chrome. It is an explicit
37403
37529
  * no-built-in-UI profile, not the inverse of a hypothetical `ui: true`,
37404
37530
  * and it never disables document content, the Document API, or
37405
- * `editor.ui`.
37531
+ * `superdoc.ui`.
37406
37532
  * - `ui: { ... }` opts in per surface. An omitted key keeps that surface's
37407
37533
  * historical default rather than inheriting from its siblings.
37408
37534
  *
@@ -45145,7 +45271,7 @@ var SuperDoc = class extends import_eventemitter3.default {
45145
45271
  this.config.colors = shuffleArray(this.config.colors);
45146
45272
  this.userColorMap = /* @__PURE__ */ new Map();
45147
45273
  this.colorIndex = 0;
45148
- this.version = "2.12.0-next.8";
45274
+ this.version = "2.12.0";
45149
45275
  this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
45150
45276
  this.superdocId = config.superdocId || v4();
45151
45277
  this.colors = this.config.colors ?? [];
@@ -45314,7 +45440,7 @@ var SuperDoc = class extends import_eventemitter3.default {
45314
45440
  this.#pendingContentControlInputSource = null;
45315
45441
  this.#pendingContentControlInputExpiresAt = null;
45316
45442
  });
45317
- contentControlsUnsub = this.#ui.contentControls.observe((snapshot) => {
45443
+ contentControlsUnsub = this.#ui.contentControls.observeActivePath((snapshot) => {
45318
45444
  const editor = this.activeEditor;
45319
45445
  const activePath = snapshot.activeIds.map((id) => toContentControlRef(snapshot.items.find((item) => item.id === id)));
45320
45446
  if (activePath.some((item) => item === null)) return;