@harbour-enterprises/superdoc 1.3.0-next.8 → 1.3.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.
@@ -1,6 +1,6 @@
1
1
  import { B as Buffer$2 } from "./jszip-B1fkPkPJ.es.js";
2
2
  import { t as twipsToInches, i as inchesToTwips, p as ptToTwips, l as linesToTwips, a as twipsToLines, b as pixelsToTwips, h as halfPointToPoints, c as twipsToPixels$2, d as convertSizeToCSS, e as inchesToPixels } from "./helpers-C8e9wR5l.es.js";
3
- import { g as generateDocxRandomId, T as TextSelection$1, o as objectIncludes, w as wrapTextsInRuns, D as DOMParser$1, c as createDocFromMarkdown, a as createDocFromHTML, b as chainableEditorState, d as convertMarkdownToHTML, f as findParentNode, e as findParentNodeClosestToPos, h as generateRandom32BitHex, i as generateRandomSigned32BitIntStrId, P as PluginKey, j as Plugin, M as Mapping, N as NodeSelection, k as Selection, l as Slice, m as DOMSerializer, F as Fragment, n as Mark$1, p as dropPoint, A as AllSelection, q as Schema$1, s as canSplit, t as resolveRunProperties, u as encodeMarksFromRPr, v as liftTarget, x as canJoin, y as joinPoint, z as replaceStep$1, R as ReplaceAroundStep$1, B as htmlHandler, C as ReplaceStep, E as getResolvedParagraphProperties, G as changeListLevel, H as isList$1, I as updateNumberingProperties, L as ListHelpers, J as inputRulesPlugin, K as TrackDeleteMarkName$1, O as TrackInsertMarkName$1, Q as TrackFormatMarkName$1, U as AddMarkStep, V as RemoveMarkStep, W as CommandService, S as SuperConverter, X as EditorState, Y as unflattenListsInHtml, Z as SelectionRange, _ as Transform, $ as createOoxmlResolver, a0 as translator, a1 as translator$1, a2 as resolveDocxFontFamily, a3 as _getReferencedTableStyles, a4 as decodeRPrFromMarks, a5 as calculateResolvedParagraphProperties, a6 as encodeCSSFromPPr, a7 as encodeCSSFromRPr, a8 as generateOrderedListIndex, a9 as docxNumberingHelpers, aa as InputRule, ab as insertNewRelationship, ac as kebabCase$1, ad as getUnderlineCssString } from "./SuperConverter-DwLhA2mM.es.js";
3
+ import { g as generateDocxRandomId, T as TextSelection$1, o as objectIncludes, w as wrapTextsInRuns, D as DOMParser$1, c as createDocFromMarkdown, a as createDocFromHTML, b as chainableEditorState, d as convertMarkdownToHTML, f as findParentNode, e as findParentNodeClosestToPos, h as generateRandom32BitHex, i as generateRandomSigned32BitIntStrId, P as PluginKey, j as Plugin, M as Mapping, N as NodeSelection, k as Selection, l as Slice, m as DOMSerializer, F as Fragment, n as Mark$1, p as dropPoint, A as AllSelection, q as Schema$1, s as canSplit, t as resolveRunProperties, u as encodeMarksFromRPr, v as liftTarget, x as canJoin, y as joinPoint, z as replaceStep$1, R as ReplaceAroundStep$1, B as htmlHandler, C as ReplaceStep, E as getResolvedParagraphProperties, G as changeListLevel, H as isList$1, I as updateNumberingProperties, L as ListHelpers, J as inputRulesPlugin, K as TrackDeleteMarkName$1, O as TrackInsertMarkName$1, Q as TrackFormatMarkName$1, U as AddMarkStep, V as RemoveMarkStep, W as CommandService, S as SuperConverter, X as EditorState, Y as unflattenListsInHtml, Z as SelectionRange, _ as Transform, $ as createOoxmlResolver, a0 as translator, a1 as translator$1, a2 as resolveDocxFontFamily, a3 as combineIndentProperties, a4 as _getReferencedTableStyles, a5 as decodeRPrFromMarks, a6 as calculateResolvedParagraphProperties, a7 as encodeCSSFromPPr, a8 as encodeCSSFromRPr, a9 as generateOrderedListIndex, aa as docxNumberingHelpers, ab as InputRule, ac as insertNewRelationship, ad as kebabCase$1, ae as getUnderlineCssString } from "./SuperConverter-z20LprsX.es.js";
4
4
  import { p as process$1, r as ref, C as global$1, c as computed, E as createElementBlock, F as Fragment$1, S as renderList, O as withModifiers, G as openBlock, P as normalizeClass, M as createCommentVNode, H as toDisplayString, K as createBaseVNode, U as createApp, f as onMounted, X as onUnmounted, R as withDirectives, v as unref, Y as vModelText, y as nextTick, L as normalizeStyle, u as watch, Z as withKeys, _ as createTextVNode, I as createVNode, h, $ as readonly, s as getCurrentInstance, o as onBeforeUnmount, j as reactive, b as onBeforeMount, i as inject, a0 as onActivated, a1 as onDeactivated, a2 as Comment, d as defineComponent, a as provide, g as Teleport, t as toRef, a3 as renderSlot, a4 as isVNode, D as shallowRef, w as watchEffect, T as Transition, a5 as mergeProps, a6 as vShow, a7 as cloneVNode, a8 as Text$2, m as markRaw, N as createBlock, J as withCtx, a9 as useCssVars, V as resolveDynamicComponent, aa as normalizeProps, ab as guardReactiveProps } from "./vue-BnBKJwCW.es.js";
5
5
  import "./jszip.min-DCl8qkFO.es.js";
6
6
  import { E as EventEmitter$1 } from "./eventemitter3-CwrdEv8r.es.js";
@@ -10936,6 +10936,105 @@ const setSectionHeaderFooterAtSelection = ({ headerInches, footerInches } = {})
10936
10936
  tr.setNodeMarkup(pos, void 0, nextAttrs, node.marks);
10937
10937
  return true;
10938
10938
  };
10939
+ function findGoverningSectPrParagraph(doc2, selectionPos) {
10940
+ const candidates = [];
10941
+ doc2.descendants((node, nodePos) => {
10942
+ if (node.type?.name === "paragraph" && node.attrs?.paragraphProperties?.sectPr) {
10943
+ candidates.push({ node, pos: nodePos });
10944
+ }
10945
+ });
10946
+ if (!candidates.length) return null;
10947
+ const inside = candidates.find((c2) => selectionPos >= c2.pos && selectionPos < c2.pos + c2.node.nodeSize);
10948
+ if (inside) return inside;
10949
+ const atOrAfter = candidates.find((c2) => c2.pos >= selectionPos);
10950
+ return atOrAfter ?? candidates[candidates.length - 1];
10951
+ }
10952
+ const setSectionPageMarginsAtSelection = ({ topInches, rightInches, bottomInches, leftInches } = {}) => ({ tr, state, editor }) => {
10953
+ if (!state || !editor) {
10954
+ console.warn("[setSectionPageMarginsAtSelection] Missing state or editor");
10955
+ return false;
10956
+ }
10957
+ const hasTop = typeof topInches === "number";
10958
+ const hasRight = typeof rightInches === "number";
10959
+ const hasBottom = typeof bottomInches === "number";
10960
+ const hasLeft = typeof leftInches === "number";
10961
+ if (!hasTop && !hasRight && !hasBottom && !hasLeft) {
10962
+ console.warn("[setSectionPageMarginsAtSelection] No margin values provided");
10963
+ return false;
10964
+ }
10965
+ if (hasTop && topInches < 0 || hasRight && rightInches < 0 || hasBottom && bottomInches < 0 || hasLeft && leftInches < 0) {
10966
+ console.warn("[setSectionPageMarginsAtSelection] Margin values must be >= 0");
10967
+ return false;
10968
+ }
10969
+ const updates = {};
10970
+ if (hasTop) updates.topInches = topInches;
10971
+ if (hasRight) updates.rightInches = rightInches;
10972
+ if (hasBottom) updates.bottomInches = bottomInches;
10973
+ if (hasLeft) updates.leftInches = leftInches;
10974
+ const { from: from3 } = state.selection;
10975
+ const governing = findGoverningSectPrParagraph(state.doc, from3);
10976
+ if (governing) {
10977
+ const { node, pos } = governing;
10978
+ const paraProps = node.attrs?.paragraphProperties || null;
10979
+ const existingSectPr = paraProps?.sectPr || null;
10980
+ if (!existingSectPr) {
10981
+ console.warn("[setSectionPageMarginsAtSelection] Paragraph found but has no sectPr");
10982
+ return false;
10983
+ }
10984
+ const sectPr2 = JSON.parse(JSON.stringify(existingSectPr));
10985
+ try {
10986
+ updateSectionMargins({ type: "sectPr", sectPr: sectPr2 }, updates);
10987
+ } catch (err) {
10988
+ console.error("[setSectionPageMarginsAtSelection] Failed to update sectPr:", err);
10989
+ return false;
10990
+ }
10991
+ const resolved = getSectPrMargins(sectPr2);
10992
+ const normalizedSectionMargins = {
10993
+ top: resolved.top ?? null,
10994
+ right: resolved.right ?? null,
10995
+ bottom: resolved.bottom ?? null,
10996
+ left: resolved.left ?? null,
10997
+ header: resolved.header ?? null,
10998
+ footer: resolved.footer ?? null
10999
+ };
11000
+ const newParagraphProperties = { ...paraProps || {}, sectPr: sectPr2 };
11001
+ const nextAttrs = {
11002
+ ...node.attrs,
11003
+ paragraphProperties: newParagraphProperties,
11004
+ sectionMargins: normalizedSectionMargins
11005
+ };
11006
+ tr.setNodeMarkup(pos, void 0, nextAttrs, node.marks);
11007
+ tr.setMeta("forceUpdatePagination", true);
11008
+ return true;
11009
+ }
11010
+ const docAttrs = state.doc.attrs ?? {};
11011
+ const converter = editor.converter ?? null;
11012
+ const baseBodySectPr = docAttrs.bodySectPr || converter?.bodySectPr || null;
11013
+ const sectPr = baseBodySectPr != null ? JSON.parse(JSON.stringify(baseBodySectPr)) : { type: "element", name: "w:sectPr", elements: [] };
11014
+ try {
11015
+ updateSectionMargins({ type: "sectPr", sectPr }, updates);
11016
+ } catch (err) {
11017
+ console.error("[setSectionPageMarginsAtSelection] Failed to update sectPr:", err);
11018
+ return false;
11019
+ }
11020
+ if (converter) {
11021
+ converter.bodySectPr = sectPr;
11022
+ if (!converter.pageStyles) converter.pageStyles = {};
11023
+ if (!converter.pageStyles.pageMargins) converter.pageStyles.pageMargins = {};
11024
+ const pageMargins = converter.pageStyles.pageMargins;
11025
+ const resolved = getSectPrMargins(sectPr);
11026
+ if (resolved.top != null) pageMargins.top = resolved.top;
11027
+ if (resolved.right != null) pageMargins.right = resolved.right;
11028
+ if (resolved.bottom != null) pageMargins.bottom = resolved.bottom;
11029
+ if (resolved.left != null) pageMargins.left = resolved.left;
11030
+ if (resolved.header != null) pageMargins.header = resolved.header;
11031
+ if (resolved.footer != null) pageMargins.footer = resolved.footer;
11032
+ }
11033
+ const nextDocAttrs = { ...docAttrs, bodySectPr: sectPr };
11034
+ tr.setNodeMarkup(0, void 0, nextDocAttrs);
11035
+ tr.setMeta("forceUpdatePagination", true);
11036
+ return true;
11037
+ };
10939
11038
  const insertSectionBreakAtSelection = ({ headerInches, footerInches } = {}) => ({ tr, state, editor }) => {
10940
11039
  if (!state || !editor) {
10941
11040
  console.warn("[insertSectionBreakAtSelection] Missing state or editor");
@@ -11467,6 +11566,7 @@ const commands$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePr
11467
11566
  setMeta,
11468
11567
  setNode,
11469
11568
  setSectionHeaderFooterAtSelection,
11569
+ setSectionPageMarginsAtSelection,
11470
11570
  setTextIndentation,
11471
11571
  setTextSelection,
11472
11572
  skipTab,
@@ -13202,8 +13302,8 @@ const CommentsPlugin = Extension.create({
13202
13302
  }
13203
13303
  if (!onlyActiveThreadChanged) {
13204
13304
  const positionsChanged = hasPositionsChanged(prevAllCommentPositions, allCommentPositions);
13205
- const hasComments = Object.keys(allCommentPositions).length > 0;
13206
- const shouldEmitPositions = positionsChanged || !hasEverEmitted && hasComments;
13305
+ const hasComments2 = Object.keys(allCommentPositions).length > 0;
13306
+ const shouldEmitPositions = positionsChanged || !hasEverEmitted && hasComments2;
13207
13307
  if (shouldEmitPositions) {
13208
13308
  prevAllCommentPositions = allCommentPositions;
13209
13309
  hasEverEmitted = true;
@@ -15334,7 +15434,7 @@ const canUseDOM = () => {
15334
15434
  return false;
15335
15435
  }
15336
15436
  };
15337
- const summaryVersion = "1.3.0-next.8";
15437
+ const summaryVersion = "1.3.0";
15338
15438
  const nodeKeys = ["group", "content", "marks", "inline", "atom", "defining", "code", "tableRole", "summary"];
15339
15439
  const markKeys = ["group", "inclusive", "excludes", "spanning", "code"];
15340
15440
  function mapAttributes(attrs) {
@@ -17336,9 +17436,8 @@ class Editor extends EventEmitter {
17336
17436
  try {
17337
17437
  const jsonObj = json;
17338
17438
  const attrs = jsonObj.attrs;
17339
- const hasBody = attrs && "bodySectPr" in attrs;
17340
17439
  const converter = this.converter;
17341
- if (!hasBody && converter && converter.bodySectPr) {
17440
+ if (converter && converter.bodySectPr) {
17342
17441
  jsonObj.attrs = attrs || {};
17343
17442
  jsonObj.attrs.bodySectPr = converter.bodySectPr;
17344
17443
  }
@@ -17967,7 +18066,7 @@ class Editor extends EventEmitter {
17967
18066
  * Process collaboration migrations
17968
18067
  */
17969
18068
  processCollaborationMigrations() {
17970
- console.debug("[checkVersionMigrations] Current editor version", "1.3.0-next.8");
18069
+ console.debug("[checkVersionMigrations] Current editor version", "1.3.0");
17971
18070
  if (!this.options.ydoc) return;
17972
18071
  const metaMap = this.options.ydoc.getMap("meta");
17973
18072
  let docVersion = metaMap.get("version");
@@ -28198,7 +28297,9 @@ const deriveBlockVersion = (block) => {
28198
28297
  textRun.pmEnd ?? "",
28199
28298
  textRun.token ?? "",
28200
28299
  // Tracked changes - force re-render when added or removed tracked change
28201
- textRun.trackedChange ? 1 : 0
28300
+ textRun.trackedChange ? 1 : 0,
28301
+ // Comment annotations - force re-render when comments are enabled/disabled
28302
+ textRun.comments?.length ?? 0
28202
28303
  ].join(",");
28203
28304
  }).join("|");
28204
28305
  const attrs = block.attrs;
@@ -34070,6 +34171,9 @@ const hashCellBorders = (borders) => {
34070
34171
  if (borders.left) parts.push(`l:[${hashBorderSpec(borders.left)}]`);
34071
34172
  return parts.join(";");
34072
34173
  };
34174
+ function hasComments$1(run) {
34175
+ return "comments" in run && Array.isArray(run.comments) && run.comments.length > 0;
34176
+ }
34073
34177
  const MAX_CACHE_SIZE$1 = 1e4;
34074
34178
  const BYTES_PER_ENTRY_ESTIMATE = 5e3;
34075
34179
  const hashParagraphFrame = (frame) => {
@@ -34137,6 +34241,7 @@ const hashRuns = (block) => {
34137
34241
  fontFamily2 ? `ff:${fontFamily2}` : "",
34138
34242
  highlight ? `hl:${highlight}` : ""
34139
34243
  ].join("");
34244
+ const commentHash = hasComments$1(run) ? run.comments.map((c2) => `${c2.commentId ?? ""}:${c2.internal ? "1" : "0"}`).join("|") : "";
34140
34245
  let trackedKey = "";
34141
34246
  if (hasTrackedChange(run)) {
34142
34247
  const tc = run.trackedChange;
@@ -34144,7 +34249,8 @@ const hashRuns = (block) => {
34144
34249
  const afterHash = tc.after ? JSON.stringify(tc.after) : "";
34145
34250
  trackedKey = `|tc:${tc.kind ?? ""}:${tc.id ?? ""}:${tc.author ?? ""}:${tc.date ?? ""}:${beforeHash}:${afterHash}`;
34146
34251
  }
34147
- cellHashes.push(`${text}:${marks}${trackedKey}`);
34252
+ const commentKey = commentHash ? `|cm:${commentHash}` : "";
34253
+ cellHashes.push(`${text}:${marks}${trackedKey}${commentKey}`);
34148
34254
  }
34149
34255
  if (paragraphBlock.attrs) {
34150
34256
  const attrs = paragraphBlock.attrs;
@@ -35275,6 +35381,9 @@ function remeasureParagraph(block, maxWidth, firstLineIndent = 0) {
35275
35381
  const totalHeight = lines.reduce((s2, l) => s2 + l.lineHeight, 0);
35276
35382
  return { kind: "paragraph", lines, totalHeight };
35277
35383
  }
35384
+ function hasComments(run) {
35385
+ return "comments" in run && Array.isArray(run.comments) && run.comments.length > 0;
35386
+ }
35278
35387
  const computeDirtyRegions = (previous, next) => {
35279
35388
  const prevMap = new Map(previous.map((block, index2) => [block.id, { block, index: index2 }]));
35280
35389
  const nextMap = new Map(next.map((block, index2) => [block.id, { block, index: index2 }]));
@@ -35335,6 +35444,10 @@ const getTrackedChangeKey = (run) => {
35335
35444
  }
35336
35445
  return "";
35337
35446
  };
35447
+ const getCommentKey = (run) => {
35448
+ if (!hasComments(run)) return "";
35449
+ return run.comments.map((c2) => `${c2.commentId ?? ""}:${c2.internal ? "1" : "0"}`).join("|");
35450
+ };
35338
35451
  const paragraphSpacingEqual = (a, b) => {
35339
35452
  if (a === b) return true;
35340
35453
  if (!a || !b) return !a && !b;
@@ -35416,7 +35529,7 @@ const paragraphBlocksEqual = (a, b) => {
35416
35529
  for (let i = 0; i < a.runs.length; i += 1) {
35417
35530
  const runA = a.runs[i];
35418
35531
  const runB = b.runs[i];
35419
- if (("src" in runA || runA.kind === "lineBreak" || runA.kind === "break" || runA.kind === "fieldAnnotation" ? "" : runA.text) !== ("src" in runB || runB.kind === "lineBreak" || runB.kind === "break" || runB.kind === "fieldAnnotation" ? "" : runB.text) || ("bold" in runA ? runA.bold : false) !== ("bold" in runB ? runB.bold : false) || ("italic" in runA ? runA.italic : false) !== ("italic" in runB ? runB.italic : false) || ("color" in runA ? runA.color : void 0) !== ("color" in runB ? runB.color : void 0) || ("fontSize" in runA ? runA.fontSize : void 0) !== ("fontSize" in runB ? runB.fontSize : void 0) || ("fontFamily" in runA ? runA.fontFamily : void 0) !== ("fontFamily" in runB ? runB.fontFamily : void 0) || ("highlight" in runA ? runA.highlight : void 0) !== ("highlight" in runB ? runB.highlight : void 0) || getTrackedChangeKey(runA) !== getTrackedChangeKey(runB)) {
35532
+ if (("src" in runA || runA.kind === "lineBreak" || runA.kind === "break" || runA.kind === "fieldAnnotation" ? "" : runA.text) !== ("src" in runB || runB.kind === "lineBreak" || runB.kind === "break" || runB.kind === "fieldAnnotation" ? "" : runB.text) || ("bold" in runA ? runA.bold : false) !== ("bold" in runB ? runB.bold : false) || ("italic" in runA ? runA.italic : false) !== ("italic" in runB ? runB.italic : false) || ("color" in runA ? runA.color : void 0) !== ("color" in runB ? runB.color : void 0) || ("fontSize" in runA ? runA.fontSize : void 0) !== ("fontSize" in runB ? runB.fontSize : void 0) || ("fontFamily" in runA ? runA.fontFamily : void 0) !== ("fontFamily" in runB ? runB.fontFamily : void 0) || ("highlight" in runA ? runA.highlight : void 0) !== ("highlight" in runB ? runB.highlight : void 0) || getTrackedChangeKey(runA) !== getTrackedChangeKey(runB) || getCommentKey(runA) !== getCommentKey(runB)) {
35420
35533
  return false;
35421
35534
  }
35422
35535
  }
@@ -40166,7 +40279,7 @@ const resetRunFormatting = (run) => {
40166
40279
  delete run.link;
40167
40280
  delete run.letterSpacing;
40168
40281
  };
40169
- const applyFormatChangeMarks = (run, config, hyperlinkConfig, applyMarksToRun2, themeColors) => {
40282
+ const applyFormatChangeMarks = (run, config, hyperlinkConfig, applyMarksToRun2, themeColors, enableComments = true) => {
40170
40283
  const tracked = run.trackedChange;
40171
40284
  if (!tracked || tracked.kind !== "format") {
40172
40285
  return;
@@ -40191,7 +40304,7 @@ const applyFormatChangeMarks = (run, config, hyperlinkConfig, applyMarksToRun2,
40191
40304
  }
40192
40305
  resetRunFormatting(run);
40193
40306
  try {
40194
- applyMarksToRun2(run, beforeMarks, hyperlinkConfig, themeColors);
40307
+ applyMarksToRun2(run, beforeMarks, hyperlinkConfig, themeColors, void 0, enableComments);
40195
40308
  } catch (error) {
40196
40309
  if (process$1.env.NODE_ENV === "development") {
40197
40310
  console.warn("[PM-Adapter] Error applying format change marks, resetting formatting:", error);
@@ -40199,7 +40312,7 @@ const applyFormatChangeMarks = (run, config, hyperlinkConfig, applyMarksToRun2,
40199
40312
  resetRunFormatting(run);
40200
40313
  }
40201
40314
  };
40202
- const applyTrackedChangesModeToRuns = (runs, config, hyperlinkConfig, applyMarksToRun2, themeColors) => {
40315
+ const applyTrackedChangesModeToRuns = (runs, config, hyperlinkConfig, applyMarksToRun2, themeColors, enableComments = true) => {
40203
40316
  if (!config) {
40204
40317
  return runs;
40205
40318
  }
@@ -40212,7 +40325,7 @@ const applyTrackedChangesModeToRuns = (runs, config, hyperlinkConfig, applyMarks
40212
40325
  } else {
40213
40326
  runs.forEach((run) => {
40214
40327
  if (isTextRun$1(run)) {
40215
- applyFormatChangeMarks(run, config, hyperlinkConfig, applyMarksToRun2, themeColors);
40328
+ applyFormatChangeMarks(run, config, hyperlinkConfig, applyMarksToRun2, themeColors, enableComments);
40216
40329
  }
40217
40330
  });
40218
40331
  }
@@ -40242,9 +40355,23 @@ const applyTrackedChangesModeToRuns = (runs, config, hyperlinkConfig, applyMarks
40242
40355
  } else {
40243
40356
  filtered.forEach((run) => {
40244
40357
  if (isTextRun$1(run)) {
40245
- applyFormatChangeMarks(run, config, hyperlinkConfig || DEFAULT_HYPERLINK_CONFIG$1, applyMarksToRun2, themeColors);
40358
+ applyFormatChangeMarks(
40359
+ run,
40360
+ config,
40361
+ hyperlinkConfig || DEFAULT_HYPERLINK_CONFIG$1,
40362
+ applyMarksToRun2,
40363
+ themeColors,
40364
+ enableComments
40365
+ );
40246
40366
  }
40247
40367
  });
40368
+ if ((config.mode === "original" || config.mode === "final") && config.enabled) {
40369
+ filtered.forEach((run) => {
40370
+ if (isTextRun$1(run) && run.trackedChange && (run.trackedChange.kind === "insert" || run.trackedChange.kind === "delete")) {
40371
+ delete run.trackedChange;
40372
+ }
40373
+ });
40374
+ }
40248
40375
  }
40249
40376
  return filtered;
40250
40377
  };
@@ -41186,7 +41313,10 @@ const applyTextStyleMark = (run, attrs, themeColors) => {
41186
41313
  const DEFAULT_HYPERLINK_CONFIG = {
41187
41314
  enableRichHyperlinks: false
41188
41315
  };
41189
- const applyMarksToRun = (run, marks, hyperlinkConfig = DEFAULT_HYPERLINK_CONFIG, themeColors, backgroundColor) => {
41316
+ const applyMarksToRun = (run, marks, hyperlinkConfig = DEFAULT_HYPERLINK_CONFIG, themeColors, backgroundColor, enableComments = true) => {
41317
+ if (!enableComments && "comments" in run && run.comments) {
41318
+ delete run.comments;
41319
+ }
41190
41320
  const isTabRun2 = run.kind === "tab";
41191
41321
  let markSetColor = false;
41192
41322
  marks.forEach((mark) => {
@@ -41233,7 +41363,7 @@ const applyMarksToRun = (run, marks, hyperlinkConfig = DEFAULT_HYPERLINK_CONFIG,
41233
41363
  break;
41234
41364
  case "commentMark":
41235
41365
  case "comment": {
41236
- if (!isTabRun2) {
41366
+ if (!isTabRun2 && enableComments) {
41237
41367
  pushCommentAnnotation(run, mark.attrs ?? {});
41238
41368
  }
41239
41369
  break;
@@ -43307,7 +43437,16 @@ const computeParagraphAttrs = (para, styleContext, listCounterContext, converter
43307
43437
  if (!value || typeof value !== "object") return;
43308
43438
  return normalizePxIndent(value) ?? convertIndentTwipsToPx(value);
43309
43439
  };
43310
- const normalizedIndent = normalizeIndentObject(attrs.indent) ?? convertIndentTwipsToPx(paragraphProps.indent) ?? convertIndentTwipsToPx(hydrated?.indent) ?? normalizeParagraphIndent(attrs.textIndent);
43440
+ const hydratedIndentPx = convertIndentTwipsToPx(hydrated?.indent);
43441
+ const paragraphIndentPx = convertIndentTwipsToPx(paragraphProps.indent);
43442
+ const textIndentPx = normalizeParagraphIndent(attrs.textIndent);
43443
+ const attrsIndentPx = normalizeIndentObject(attrs.indent);
43444
+ const indentChain = [];
43445
+ if (hydratedIndentPx) indentChain.push({ indent: hydratedIndentPx });
43446
+ if (paragraphIndentPx) indentChain.push({ indent: paragraphIndentPx });
43447
+ if (textIndentPx) indentChain.push({ indent: textIndentPx });
43448
+ if (attrsIndentPx) indentChain.push({ indent: attrsIndentPx });
43449
+ const normalizedIndent = indentChain.length ? combineIndentProperties(indentChain).indent : void 0;
43311
43450
  const unwrapTabStops = (tabStops) => {
43312
43451
  if (!Array.isArray(tabStops)) {
43313
43452
  return void 0;
@@ -44859,7 +44998,7 @@ const applyInlineRunProperties = (run, runProperties) => {
44859
44998
  run.letterSpacing = twipsToPx$1(runProperties.letterSpacing);
44860
44999
  }
44861
45000
  };
44862
- function paragraphToFlowBlocks$1(para, nextBlockId, positions, defaultFont, defaultSize, styleContext, listCounterContext, trackedChanges, bookmarks, hyperlinkConfig = DEFAULT_HYPERLINK_CONFIG$1, themeColors, converters, converterContext) {
45001
+ function paragraphToFlowBlocks$1(para, nextBlockId, positions, defaultFont, defaultSize, styleContext, listCounterContext, trackedChanges, bookmarks, hyperlinkConfig = DEFAULT_HYPERLINK_CONFIG$1, themeColors, converters, converterContext, enableComments = true) {
44863
45002
  const baseBlockId = nextBlockId("paragraph");
44864
45003
  const paragraphProps = typeof para.attrs?.paragraphProperties === "object" && para.attrs.paragraphProperties !== null ? para.attrs.paragraphProperties : {};
44865
45004
  const paragraphStyleId = typeof para.attrs?.styleId === "string" && para.attrs.styleId.trim() ? para.attrs.styleId : typeof paragraphProps.styleId === "string" && paragraphProps.styleId.trim() ? paragraphProps.styleId : null;
@@ -45033,7 +45172,8 @@ function paragraphToFlowBlocks$1(para, nextBlockId, positions, defaultFont, defa
45033
45172
  [...node.marks ?? [], ...inheritedMarks ?? []],
45034
45173
  hyperlinkConfig,
45035
45174
  themeColors,
45036
- converterContext?.backgroundColor
45175
+ converterContext?.backgroundColor,
45176
+ enableComments
45037
45177
  );
45038
45178
  currentRuns.push(run);
45039
45179
  return;
@@ -45095,7 +45235,8 @@ function paragraphToFlowBlocks$1(para, nextBlockId, positions, defaultFont, defa
45095
45235
  positions,
45096
45236
  defaultFont,
45097
45237
  defaultSize,
45098
- mergedMarks,
45238
+ [],
45239
+ // Empty marks - will be applied after linked styles
45099
45240
  activeSdt,
45100
45241
  hyperlinkConfig,
45101
45242
  themeColors
@@ -45104,6 +45245,14 @@ function paragraphToFlowBlocks$1(para, nextBlockId, positions, defaultFont, defa
45104
45245
  applyRunStyles2(tokenRun, inlineStyleId, activeRunStyleId);
45105
45246
  applyBaseRunDefaults(tokenRun, baseRunDefaults, defaultFont, defaultSize);
45106
45247
  applyInlineRunProperties(tokenRun, activeRunProperties);
45248
+ applyMarksToRun(
45249
+ tokenRun,
45250
+ mergedMarks,
45251
+ hyperlinkConfig,
45252
+ themeColors,
45253
+ converterContext?.backgroundColor,
45254
+ enableComments
45255
+ );
45107
45256
  if (pageRefPos) {
45108
45257
  tokenRun.pmStart = pageRefPos.start;
45109
45258
  tokenRun.pmEnd = pageRefPos.end;
@@ -45177,7 +45326,8 @@ function paragraphToFlowBlocks$1(para, nextBlockId, positions, defaultFont, defa
45177
45326
  mergedMarks,
45178
45327
  hyperlinkConfig,
45179
45328
  themeColors,
45180
- converterContext?.backgroundColor
45329
+ converterContext?.backgroundColor,
45330
+ enableComments
45181
45331
  );
45182
45332
  }
45183
45333
  console.debug("[token-debug] paragraph-token-run", {
@@ -45376,7 +45526,8 @@ function paragraphToFlowBlocks$1(para, nextBlockId, positions, defaultFont, defa
45376
45526
  trackedChanges,
45377
45527
  hyperlinkConfig,
45378
45528
  applyMarksToRun,
45379
- themeColors
45529
+ themeColors,
45530
+ enableComments
45380
45531
  );
45381
45532
  if (trackedChanges.enabled && filteredRuns.length === 0) {
45382
45533
  return;
@@ -46275,6 +46426,7 @@ function toFlowBlocks(pmDoc, options) {
46275
46426
  const hyperlinkConfig = {
46276
46427
  enableRichHyperlinks: options?.enableRichHyperlinks ?? false
46277
46428
  };
46429
+ const enableComments = options?.enableComments ?? true;
46278
46430
  const themeColors = options?.themeColors;
46279
46431
  const converterContext = options?.converterContext;
46280
46432
  if (!doc2.content) {
@@ -46324,7 +46476,8 @@ function toFlowBlocks(pmDoc, options) {
46324
46476
  bookmarks2,
46325
46477
  hyperlinkConfig2,
46326
46478
  themeColorsParam ?? themeColors,
46327
- converterCtx ?? converterContext
46479
+ converterCtx ?? converterContext,
46480
+ enableComments
46328
46481
  );
46329
46482
  const tableConverter = (node, nextBlockId2, positions2, defaultFont2, defaultSize2, context, trackedChanges, bookmarks2, hyperlinkConfig2, themeColorsParam, converterCtx) => tableNodeToBlock(
46330
46483
  node,
@@ -46363,6 +46516,7 @@ function toFlowBlocks(pmDoc, options) {
46363
46516
  listCounterContext: { getListCounter, incrementListCounter, resetListCounter },
46364
46517
  trackedChangesConfig,
46365
46518
  hyperlinkConfig,
46519
+ enableComments,
46366
46520
  bookmarks,
46367
46521
  sectionState: {
46368
46522
  ranges: sectionRanges,
@@ -46431,7 +46585,7 @@ function mergeDropCapParagraphs(blocks) {
46431
46585
  }
46432
46586
  return result;
46433
46587
  }
46434
- function paragraphToFlowBlocks(para, nextBlockId, positions, defaultFont, defaultSize, styleContext, listCounterContext, trackedChanges, bookmarks, hyperlinkConfig = DEFAULT_HYPERLINK_CONFIG$1, themeColors, converterContext) {
46588
+ function paragraphToFlowBlocks(para, nextBlockId, positions, defaultFont, defaultSize, styleContext, listCounterContext, trackedChanges, bookmarks, hyperlinkConfig = DEFAULT_HYPERLINK_CONFIG$1, themeColors, converterContext, enableComments = true) {
46435
46589
  return paragraphToFlowBlocks$1(
46436
46590
  para,
46437
46591
  nextBlockId,
@@ -46478,7 +46632,8 @@ function paragraphToFlowBlocks(para, nextBlockId, positions, defaultFont, defaul
46478
46632
  }
46479
46633
  )
46480
46634
  },
46481
- converterContext
46635
+ converterContext,
46636
+ enableComments
46482
46637
  );
46483
46638
  }
46484
46639
  function tableNodeToBlock(node, nextBlockId, positions, defaultFont, defaultSize, styleContext, trackedChanges, bookmarks, hyperlinkConfig, themeColors, _paragraphToFlowBlocksParam, converterContext, options) {
@@ -48570,10 +48725,13 @@ async function measureParagraphBlock(block, maxWidth) {
48570
48725
  };
48571
48726
  }
48572
48727
  const originX = currentLine.width;
48573
- const { target, nextIndex, stop } = getNextTabStopPx(currentLine.width, tabStops, tabStopCursor);
48728
+ const effectiveIndent = lines.length === 0 ? indentLeft + rawFirstLineOffset : indentLeft;
48729
+ const absCurrentX = currentLine.width + effectiveIndent;
48730
+ const { target, nextIndex, stop } = getNextTabStopPx(absCurrentX, tabStops, tabStopCursor);
48574
48731
  tabStopCursor = nextIndex;
48575
- const clampedTarget = Math.min(target, currentLine.maxWidth);
48576
- const tabAdvance = Math.max(0, clampedTarget - currentLine.width);
48732
+ const maxAbsWidth = currentLine.maxWidth + effectiveIndent;
48733
+ const clampedTarget = Math.min(target, maxAbsWidth);
48734
+ const tabAdvance = Math.max(0, clampedTarget - absCurrentX);
48577
48735
  currentLine.width = roundValue(currentLine.width + tabAdvance);
48578
48736
  run.width = tabAdvance;
48579
48737
  currentLine.maxFontSize = Math.max(currentLine.maxFontSize, 12);
@@ -48581,8 +48739,9 @@ async function measureParagraphBlock(block, maxWidth) {
48581
48739
  currentLine.toChar = 1;
48582
48740
  if (stop && stop.leader && stop.leader !== "none") {
48583
48741
  const leaderStyle = stop.leader;
48584
- const from3 = Math.min(originX, clampedTarget);
48585
- const to = Math.max(originX, clampedTarget);
48742
+ const relativeTarget = clampedTarget - effectiveIndent;
48743
+ const from3 = Math.min(originX, relativeTarget);
48744
+ const to = Math.max(originX, relativeTarget);
48586
48745
  if (!currentLine.leaders) currentLine.leaders = [];
48587
48746
  currentLine.leaders.push({ from: from3, to, style: leaderStyle });
48588
48747
  }
@@ -48591,27 +48750,28 @@ async function measureParagraphBlock(block, maxWidth) {
48591
48750
  if (stop.val === "end" || stop.val === "center" || stop.val === "decimal") {
48592
48751
  const groupMeasure = measureTabAlignmentGroup(runIndex + 1, runsToProcess, ctx2, decimalSeparator);
48593
48752
  if (groupMeasure.totalWidth > 0) {
48753
+ const relativeTarget = clampedTarget - effectiveIndent;
48594
48754
  let groupStartX;
48595
48755
  if (stop.val === "end") {
48596
- groupStartX = Math.max(0, clampedTarget - groupMeasure.totalWidth);
48756
+ groupStartX = Math.max(0, relativeTarget - groupMeasure.totalWidth);
48597
48757
  } else if (stop.val === "center") {
48598
- groupStartX = Math.max(0, clampedTarget - groupMeasure.totalWidth / 2);
48758
+ groupStartX = Math.max(0, relativeTarget - groupMeasure.totalWidth / 2);
48599
48759
  } else {
48600
48760
  const beforeDecimal = groupMeasure.beforeDecimalWidth ?? groupMeasure.totalWidth;
48601
- groupStartX = Math.max(0, clampedTarget - beforeDecimal);
48761
+ groupStartX = Math.max(0, relativeTarget - beforeDecimal);
48602
48762
  }
48603
48763
  activeTabGroup = {
48604
48764
  measure: groupMeasure,
48605
48765
  startX: groupStartX,
48606
48766
  currentX: groupStartX,
48607
- target: clampedTarget,
48767
+ target: relativeTarget,
48608
48768
  val: stop.val
48609
48769
  };
48610
48770
  currentLine.width = roundValue(groupStartX);
48611
48771
  }
48612
48772
  pendingTabAlignment = null;
48613
48773
  } else {
48614
- pendingTabAlignment = { target: clampedTarget, val: stop.val };
48774
+ pendingTabAlignment = { target: clampedTarget - effectiveIndent, val: stop.val };
48615
48775
  }
48616
48776
  } else {
48617
48777
  pendingTabAlignment = null;
@@ -49252,10 +49412,13 @@ async function measureParagraphBlock(block, maxWidth) {
49252
49412
  };
49253
49413
  }
49254
49414
  const originX = currentLine.width;
49255
- const { target, nextIndex, stop } = getNextTabStopPx(currentLine.width, tabStops, tabStopCursor);
49415
+ const effectiveIndent = lines.length === 0 ? indentLeft + rawFirstLineOffset : indentLeft;
49416
+ const absCurrentX = currentLine.width + effectiveIndent;
49417
+ const { target, nextIndex, stop } = getNextTabStopPx(absCurrentX, tabStops, tabStopCursor);
49256
49418
  tabStopCursor = nextIndex;
49257
- const clampedTarget = Math.min(target, currentLine.maxWidth);
49258
- const tabAdvance = Math.max(0, clampedTarget - currentLine.width);
49419
+ const maxAbsWidth = currentLine.maxWidth + effectiveIndent;
49420
+ const clampedTarget = Math.min(target, maxAbsWidth);
49421
+ const tabAdvance = Math.max(0, clampedTarget - absCurrentX);
49259
49422
  currentLine.width = roundValue(currentLine.width + tabAdvance);
49260
49423
  currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run);
49261
49424
  currentLine.maxFontSize = Math.max(currentLine.maxFontSize, run.fontSize);
@@ -49264,14 +49427,15 @@ async function measureParagraphBlock(block, maxWidth) {
49264
49427
  charPosInRun += 1;
49265
49428
  if (stop) {
49266
49429
  validateTabStopVal(stop);
49267
- pendingTabAlignment = { target: clampedTarget, val: stop.val };
49430
+ pendingTabAlignment = { target: clampedTarget - effectiveIndent, val: stop.val };
49268
49431
  } else {
49269
49432
  pendingTabAlignment = null;
49270
49433
  }
49271
49434
  if (stop && stop.leader && stop.leader !== "none" && stop.leader !== "middleDot") {
49272
49435
  const leaderStyle = stop.leader;
49273
- const from3 = Math.min(originX, clampedTarget);
49274
- const to = Math.max(originX, clampedTarget);
49436
+ const relativeTarget = clampedTarget - effectiveIndent;
49437
+ const from3 = Math.min(originX, relativeTarget);
49438
+ const to = Math.max(originX, relativeTarget);
49275
49439
  if (!currentLine.leaders) currentLine.leaders = [];
49276
49440
  currentLine.leaders.push({ from: from3, to, style: leaderStyle });
49277
49441
  }
@@ -49547,7 +49711,11 @@ async function measureTableBlock(block, constraints) {
49547
49711
  }
49548
49712
  async function measureImageBlock(block, constraints) {
49549
49713
  const intrinsic = getIntrinsicImageSize(block, constraints.maxWidth);
49550
- const maxWidth = constraints.maxWidth > 0 ? constraints.maxWidth : intrinsic.width;
49714
+ const isBlockBehindDoc = block.anchor?.behindDoc;
49715
+ const isBlockWrapBehindDoc = block.wrap?.type === "None" && block.wrap?.behindDoc;
49716
+ const bypassWidthConstraint = isBlockBehindDoc || isBlockWrapBehindDoc;
49717
+ const isWidthConstraintBypassed = bypassWidthConstraint || constraints.maxWidth <= 0;
49718
+ const maxWidth = isWidthConstraintBypassed ? intrinsic.width : constraints.maxWidth;
49551
49719
  const hasNegativeVerticalPosition = block.anchor?.isAnchored && (typeof block.anchor?.offsetV === "number" && block.anchor.offsetV < 0 || typeof block.margin?.top === "number" && block.margin.top < 0);
49552
49720
  const maxHeight = hasNegativeVerticalPosition || !constraints.maxHeight || constraints.maxHeight <= 0 ? Infinity : constraints.maxHeight;
49553
49721
  const widthScale = maxWidth / intrinsic.width;
@@ -50687,12 +50855,13 @@ class PresentationEditor extends EventEmitter {
50687
50855
  if (!validModes.includes(mode)) {
50688
50856
  throw new TypeError(`[PresentationEditor] Invalid mode "${mode}". Must be one of: ${validModes.join(", ")}`);
50689
50857
  }
50858
+ const modeChanged = this.#documentMode !== mode;
50690
50859
  this.#documentMode = mode;
50691
50860
  this.#editor.setDocumentMode(mode);
50692
50861
  this.#syncDocumentModeClass();
50693
50862
  this.#syncHiddenEditorA11yAttributes();
50694
50863
  const trackedChangesChanged = this.#syncTrackedChangesPreferences();
50695
- if (trackedChangesChanged) {
50864
+ if (modeChanged || trackedChangesChanged) {
50696
50865
  this.#pendingDocChange = true;
50697
50866
  this.#scheduleRerender();
50698
50867
  }
@@ -50713,9 +50882,10 @@ class PresentationEditor extends EventEmitter {
50713
50882
  throw new TypeError("[PresentationEditor] setTrackedChangesOverrides expects an object or undefined");
50714
50883
  }
50715
50884
  if (overrides !== void 0) {
50716
- if (overrides.mode !== void 0 && !["review", "simple", "original"].includes(overrides.mode)) {
50885
+ const validModes = ["review", "original", "final", "off"];
50886
+ if (overrides.mode !== void 0 && !validModes.includes(overrides.mode)) {
50717
50887
  throw new TypeError(
50718
- `[PresentationEditor] Invalid tracked changes mode "${overrides.mode}". Must be one of: review, simple, original`
50888
+ `[PresentationEditor] Invalid tracked changes mode "${overrides.mode}". Must be one of: ${validModes.join(", ")}`
50719
50889
  );
50720
50890
  }
50721
50891
  if (overrides.enabled !== void 0 && typeof overrides.enabled !== "boolean") {
@@ -53097,12 +53267,14 @@ class PresentationEditor extends EventEmitter {
53097
53267
  } : void 0;
53098
53268
  const atomNodeTypes = getAtomNodeTypes(this.#editor?.schema ?? null);
53099
53269
  const positionMap = this.#editor?.state?.doc && docJson ? buildPositionMapFromPmDoc(this.#editor.state.doc, docJson) : null;
53270
+ const commentsEnabled = this.#documentMode !== "viewing";
53100
53271
  const result = toFlowBlocks(docJson, {
53101
53272
  mediaFiles: this.#editor?.storage?.image?.media,
53102
53273
  emitSectionBreaks: true,
53103
53274
  sectionMetadata,
53104
53275
  trackedChangesMode: this.#trackedChangesMode,
53105
53276
  enableTrackedChanges: this.#trackedChangesEnabled,
53277
+ enableComments: commentsEnabled,
53106
53278
  enableRichHyperlinks: true,
53107
53279
  themeColors: this.#editor?.converter?.themeColors ?? void 0,
53108
53280
  converterContext,
@@ -53233,10 +53405,12 @@ class PresentationEditor extends EventEmitter {
53233
53405
  const payload = { layout, blocks, measures, metrics };
53234
53406
  this.emit("layoutUpdated", payload);
53235
53407
  this.emit("paginationUpdate", payload);
53236
- const commentPositions = this.#collectCommentPositions();
53237
- const positionKeys = Object.keys(commentPositions);
53238
- if (positionKeys.length > 0) {
53239
- this.emit("commentPositions", { positions: commentPositions });
53408
+ if (this.#documentMode !== "viewing") {
53409
+ const commentPositions = this.#collectCommentPositions();
53410
+ const positionKeys = Object.keys(commentPositions);
53411
+ if (positionKeys.length > 0) {
53412
+ this.emit("commentPositions", { positions: commentPositions });
53413
+ }
53240
53414
  }
53241
53415
  if (this.#telemetryEmitter && metrics) {
53242
53416
  this.#telemetryEmitter({ type: "layout", data: { layout, blocks, measures, metrics } });
@@ -54662,7 +54836,7 @@ class PresentationEditor extends EventEmitter {
54662
54836
  const zoom = this.#layoutOptions.zoom ?? 1;
54663
54837
  const layoutMode = this.#layoutOptions.layoutMode ?? "vertical";
54664
54838
  const pages = this.#layoutState.layout?.pages;
54665
- const pageGap = this.#layoutState.layout?.pageGap ?? this.#getEffectivePageGap();
54839
+ const pageGap = this.#getEffectivePageGap();
54666
54840
  const defaultWidth = this.#layoutOptions.pageSize?.w ?? DEFAULT_PAGE_SIZE.w;
54667
54841
  const defaultHeight = this.#layoutOptions.pageSize?.h ?? DEFAULT_PAGE_SIZE.h;
54668
54842
  let maxWidth = defaultWidth;
@@ -57773,7 +57947,11 @@ const Document = Node$1.create({
57773
57947
  */
57774
57948
  clearDocument: () => ({ commands: commands2 }) => {
57775
57949
  return commands2.setContent("<p></p>");
57776
- }
57950
+ },
57951
+ /**
57952
+ * Set section page margins (top/right/bottom/left) for the section at the current selection.
57953
+ */
57954
+ setSectionPageMarginsAtSelection
57777
57955
  };
57778
57956
  }
57779
57957
  });
@@ -58427,12 +58605,18 @@ function findParagraphContext($pos, cache2, helpers2) {
58427
58605
  return null;
58428
58606
  }
58429
58607
  function extractParagraphContext(node, startPos, helpers2, depth = 0) {
58430
- const paragraphProperties = getResolvedParagraphProperties(node) ?? {};
58608
+ const paragraphProperties = getResolvedParagraphProperties(node) ?? node.attrs?.paragraphProperties ?? {};
58431
58609
  const alignmentAliases = { left: "start", right: "end" };
58432
58610
  let tabStops = [];
58433
58611
  if (Array.isArray(paragraphProperties.tabStops)) {
58434
58612
  tabStops = paragraphProperties.tabStops.map((stop) => {
58435
58613
  const ref2 = stop?.tab;
58614
+ if (!ref2 && stop?.pos != null) {
58615
+ return {
58616
+ ...stop,
58617
+ pos: twipsToPixels(Number(stop.pos) || 0)
58618
+ };
58619
+ }
58436
58620
  if (!ref2) return stop || null;
58437
58621
  const rawType = ref2.tabType || "start";
58438
58622
  const mappedVal = alignmentAliases[rawType] || rawType;
@@ -59698,6 +59882,13 @@ function createLayoutRequest(doc2, paragraphPos, view, helpers2, revision, parag
59698
59882
  pos: entry.pos,
59699
59883
  nodeSize: node.nodeSize
59700
59884
  });
59885
+ } else if (node.type.name === "lineBreak" || node.type.name === "hardBreak") {
59886
+ spans.push({
59887
+ type: node.type.name,
59888
+ spanId,
59889
+ pos: entry.pos,
59890
+ nodeSize: node.nodeSize
59891
+ });
59701
59892
  } else if (node.type.name === "text") {
59702
59893
  spans.push({
59703
59894
  type: "text",
@@ -59747,6 +59938,7 @@ function calculateTabLayout(request, measurement, view) {
59747
59938
  paragraphNode
59748
59939
  } = request;
59749
59940
  const tabs = {};
59941
+ const leftIndentPx = request.indents?.left ?? 0;
59750
59942
  let currentX = indentWidth;
59751
59943
  const measureText2 = (span) => {
59752
59944
  if (view && typeof span.from === "number" && typeof span.to === "number") {
@@ -59759,6 +59951,8 @@ function calculateTabLayout(request, measurement, view) {
59759
59951
  const span = spans[i];
59760
59952
  if (span.type === "text") {
59761
59953
  currentX += measureText2(span);
59954
+ } else if (span.type === "lineBreak" || span.type === "hardBreak") {
59955
+ currentX = leftIndentPx;
59762
59956
  } else if (span.type === "tab") {
59763
59957
  const followingText = collectFollowingText(spans, i + 1);
59764
59958
  let measureTextCallback;
@@ -59854,7 +60048,7 @@ function collectFollowingText(spans, startIndex) {
59854
60048
  let text = "";
59855
60049
  for (let i = startIndex; i < spans.length; i++) {
59856
60050
  const span = spans[i];
59857
- if (span.type === "tab") break;
60051
+ if (span.type === "tab" || span.type === "lineBreak" || span.type === "hardBreak") break;
59858
60052
  if (span.type === "text") text += span.text || "";
59859
60053
  }
59860
60054
  return text;
@@ -59864,7 +60058,7 @@ function getFollowingTextRange(spans, startIndex) {
59864
60058
  let to = null;
59865
60059
  for (let i = startIndex; i < spans.length; i++) {
59866
60060
  const span = spans[i];
59867
- if (span.type === "tab") break;
60061
+ if (span.type === "tab" || span.type === "lineBreak" || span.type === "hardBreak") break;
59868
60062
  if (span.type === "text" && typeof span.from === "number" && typeof span.to === "number") {
59869
60063
  if (from3 === null) from3 = span.from;
59870
60064
  to = span.to;
@@ -64282,6 +64476,10 @@ const Image = Node$1.create({
64282
64476
  }
64283
64477
  const hasAnchorData = Boolean(anchorData);
64284
64478
  const hasMarginOffsets = marginOffset?.horizontal != null || marginOffset?.top != null;
64479
+ const isWrapBehindDoc = wrap?.attrs?.behindDoc;
64480
+ const isAnchorBehindDoc = anchorData?.behindDoc;
64481
+ const isBehindDocAnchor = wrap?.type === "None" && (isWrapBehindDoc || isAnchorBehindDoc);
64482
+ const isAbsolutelyPositioned = style2.includes("position: absolute;");
64285
64483
  if (hasAnchorData) {
64286
64484
  switch (anchorData.hRelativeFrom) {
64287
64485
  case "page":
@@ -64309,7 +64507,6 @@ const Image = Node$1.create({
64309
64507
  style2 += "float: left;";
64310
64508
  }
64311
64509
  } else if (!anchorData.alignH && marginOffset?.horizontal != null) {
64312
- const isAbsolutelyPositioned = style2.includes("position: absolute;");
64313
64510
  if (isAbsolutelyPositioned) {
64314
64511
  style2 += `left: ${baseHorizontal}px;`;
64315
64512
  style2 += "max-width: none;";
@@ -64323,7 +64520,8 @@ const Image = Node$1.create({
64323
64520
  const relativeFromPageV = anchorData?.vRelativeFrom === "page";
64324
64521
  const relativeFromMarginV = anchorData?.vRelativeFrom === "margin";
64325
64522
  const maxMarginV = 500;
64326
- const baseTop = Math.max(0, marginOffset?.top ?? 0);
64523
+ const allowNegativeTopOffset = isBehindDocAnchor;
64524
+ const baseTop = allowNegativeTopOffset ? marginOffset?.top ?? 0 : Math.max(0, marginOffset?.top ?? 0);
64327
64525
  let rotationHorizontal = 0;
64328
64526
  let rotationTop = 0;
64329
64527
  const { rotation: rotation2 } = transformData ?? {};
@@ -64342,7 +64540,10 @@ const Image = Node$1.create({
64342
64540
  margin.left += horizontal;
64343
64541
  }
64344
64542
  }
64345
- if (top2 && !relativeFromMarginV) {
64543
+ const appliedTopViaStyle = isAbsolutelyPositioned && allowNegativeTopOffset && !relativeFromMarginV;
64544
+ if (appliedTopViaStyle) {
64545
+ style2 += `top: ${top2}px;`;
64546
+ } else if (top2 && !relativeFromMarginV) {
64346
64547
  if (relativeFromPageV && top2 >= maxMarginV) margin.top += maxMarginV;
64347
64548
  else margin.top += top2;
64348
64549
  }
@@ -64355,6 +64556,9 @@ const Image = Node$1.create({
64355
64556
  }
64356
64557
  if (margin.top) style2 += `margin-top: ${margin.top}px;`;
64357
64558
  if (margin.bottom) style2 += `margin-bottom: ${margin.bottom}px;`;
64559
+ if (isBehindDocAnchor) {
64560
+ style2 += "max-width: none;";
64561
+ }
64358
64562
  const finalAttributes = { ...htmlAttributes };
64359
64563
  if (style2) {
64360
64564
  const existingStyle = finalAttributes.style || "";
@@ -78808,7 +79012,7 @@ var ResizeObserverController = (function() {
78808
79012
  };
78809
79013
  return ResizeObserverController2;
78810
79014
  })();
78811
- var ResizeObserver = (function() {
79015
+ var ResizeObserver$1 = (function() {
78812
79016
  function ResizeObserver2(callback) {
78813
79017
  if (arguments.length === 0) {
78814
79018
  throw new TypeError("Failed to construct 'ResizeObserver': 1 argument required, but only 0 present.");
@@ -78847,7 +79051,7 @@ var ResizeObserver = (function() {
78847
79051
  class ResizeObserverDelegate {
78848
79052
  constructor() {
78849
79053
  this.handleResize = this.handleResize.bind(this);
78850
- this.observer = new (typeof window !== "undefined" && window.ResizeObserver || ResizeObserver)(this.handleResize);
79054
+ this.observer = new (typeof window !== "undefined" && window.ResizeObserver || ResizeObserver$1)(this.handleResize);
78851
79055
  this.elHandlersMap = /* @__PURE__ */ new Map();
78852
79056
  }
78853
79057
  handleResize(entries) {
@@ -89716,6 +89920,31 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
89716
89920
  },
89717
89921
  { immediate: true, deep: true }
89718
89922
  );
89923
+ watch(
89924
+ () => props.options?.rulerContainer,
89925
+ () => {
89926
+ nextTick(() => {
89927
+ syncRulerOffset();
89928
+ setupRulerObservers();
89929
+ });
89930
+ },
89931
+ { immediate: true }
89932
+ );
89933
+ watch(
89934
+ rulersVisible,
89935
+ (visible) => {
89936
+ nextTick(() => {
89937
+ if (visible) {
89938
+ syncRulerOffset();
89939
+ setupRulerObservers();
89940
+ } else {
89941
+ rulerHostStyle.value = {};
89942
+ cleanupRulerObservers();
89943
+ }
89944
+ });
89945
+ },
89946
+ { immediate: true }
89947
+ );
89719
89948
  const containerStyle = computed(() => {
89720
89949
  let maxWidth = 8.5 * 96;
89721
89950
  const ed = editor.value;
@@ -89740,6 +89969,71 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
89740
89969
  minWidth: `${scaledWidth}px`
89741
89970
  };
89742
89971
  });
89972
+ const rulerHostStyle = ref({});
89973
+ const rulerContainerEl = ref(null);
89974
+ let editorResizeObserver = null;
89975
+ let rulerContainerResizeObserver = null;
89976
+ let layoutUpdatedHandler = null;
89977
+ const resolveRulerContainer = () => {
89978
+ const container = props.options?.rulerContainer;
89979
+ if (!container) return null;
89980
+ if (typeof container === "string") {
89981
+ const doc2 = editorWrapper.value?.ownerDocument ?? document;
89982
+ return doc2.querySelector(container);
89983
+ }
89984
+ return container instanceof HTMLElement ? container : null;
89985
+ };
89986
+ const getViewportRect2 = () => {
89987
+ const host = editorWrapper.value;
89988
+ if (!host) return null;
89989
+ const viewport2 = host.querySelector(".presentation-editor__viewport");
89990
+ const target = viewport2 ?? host;
89991
+ return target.getBoundingClientRect();
89992
+ };
89993
+ const syncRulerOffset = () => {
89994
+ if (!rulersVisible.value) {
89995
+ rulerHostStyle.value = {};
89996
+ return;
89997
+ }
89998
+ rulerContainerEl.value = resolveRulerContainer();
89999
+ if (!rulerContainerEl.value) {
90000
+ rulerHostStyle.value = {};
90001
+ return;
90002
+ }
90003
+ const viewportRect = getViewportRect2();
90004
+ if (!viewportRect) return;
90005
+ const hostRect = rulerContainerEl.value.getBoundingClientRect();
90006
+ const paddingLeft = Math.max(0, viewportRect.left - hostRect.left);
90007
+ const paddingRight = Math.max(0, hostRect.right - viewportRect.right);
90008
+ rulerHostStyle.value = {
90009
+ paddingLeft: `${paddingLeft}px`,
90010
+ paddingRight: `${paddingRight}px`
90011
+ };
90012
+ };
90013
+ const cleanupRulerObservers = () => {
90014
+ if (editorResizeObserver) {
90015
+ editorResizeObserver.disconnect();
90016
+ editorResizeObserver = null;
90017
+ }
90018
+ if (rulerContainerResizeObserver) {
90019
+ rulerContainerResizeObserver.disconnect();
90020
+ rulerContainerResizeObserver = null;
90021
+ }
90022
+ };
90023
+ const setupRulerObservers = () => {
90024
+ cleanupRulerObservers();
90025
+ if (typeof ResizeObserver === "undefined") return;
90026
+ const viewportHost = editorWrapper.value;
90027
+ const rulerHost = resolveRulerContainer();
90028
+ if (viewportHost) {
90029
+ editorResizeObserver = new ResizeObserver(() => syncRulerOffset());
90030
+ editorResizeObserver.observe(viewportHost);
90031
+ }
90032
+ if (rulerHost) {
90033
+ rulerContainerResizeObserver = new ResizeObserver(() => syncRulerOffset());
90034
+ rulerContainerResizeObserver.observe(rulerHost);
90035
+ }
90036
+ };
89743
90037
  const message = useMessage();
89744
90038
  const editorWrapper = ref(null);
89745
90039
  const editorElem = ref(null);
@@ -90051,7 +90345,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
90051
90345
  presentationEditor.on("imageDeselected", () => {
90052
90346
  clearSelectedImage();
90053
90347
  });
90054
- presentationEditor.on("layoutUpdated", () => {
90348
+ layoutUpdatedHandler = () => {
90055
90349
  if (imageResizeState.visible && imageResizeState.blockId) {
90056
90350
  const escapedBlockId = CSS.escape(imageResizeState.blockId);
90057
90351
  const newElement = editorElem.value?.querySelector(
@@ -90084,13 +90378,17 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
90084
90378
  clearSelectedImage();
90085
90379
  }
90086
90380
  }
90087
- });
90381
+ nextTick(() => syncRulerOffset());
90382
+ };
90383
+ presentationEditor.on("layoutUpdated", layoutUpdatedHandler);
90088
90384
  zoomChangeHandler = ({ zoom }) => {
90089
90385
  currentZoom.value = zoom;
90386
+ nextTick(() => syncRulerOffset());
90090
90387
  };
90091
90388
  presentationEditor.on("zoomChange", zoomChangeHandler);
90092
90389
  if (typeof presentationEditor.zoom === "number") {
90093
90390
  currentZoom.value = presentationEditor.zoom;
90391
+ nextTick(() => syncRulerOffset());
90094
90392
  }
90095
90393
  }
90096
90394
  editor.value.on("paginationUpdate", () => {
@@ -90150,6 +90448,11 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
90150
90448
  onMounted(() => {
90151
90449
  initializeData();
90152
90450
  if (props.options?.suppressSkeletonLoader || !props.options?.collaborationProvider) editorReady.value = true;
90451
+ window.addEventListener("resize", syncRulerOffset, { passive: true });
90452
+ nextTick(() => {
90453
+ syncRulerOffset();
90454
+ setupRulerObservers();
90455
+ });
90153
90456
  });
90154
90457
  const handleMarginClick = (event) => {
90155
90458
  if (event.button !== 0) {
@@ -90164,10 +90467,14 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
90164
90467
  const handleMarginChange = ({ side, value }) => {
90165
90468
  const base2 = activeEditor.value;
90166
90469
  if (!base2) return;
90167
- const pageStyles2 = base2.getPageStyles();
90168
- const { pageMargins } = pageStyles2;
90169
- const update = { ...pageMargins, [side]: value };
90170
- base2?.updatePageStyle({ pageMargins: update });
90470
+ const payload = side === "left" ? { leftInches: value } : side === "right" ? { rightInches: value } : side === "top" ? { topInches: value } : side === "bottom" ? { bottomInches: value } : {};
90471
+ const didUpdateSection = typeof base2.commands?.setSectionPageMarginsAtSelection === "function" ? base2.commands.setSectionPageMarginsAtSelection(payload) : false;
90472
+ if (!didUpdateSection) {
90473
+ const pageStyles2 = base2.getPageStyles();
90474
+ const { pageMargins } = pageStyles2;
90475
+ const update = { ...pageMargins, [side]: value };
90476
+ base2?.updatePageStyle({ pageMargins: update });
90477
+ }
90171
90478
  };
90172
90479
  onBeforeUnmount(() => {
90173
90480
  stopPolling();
@@ -90176,6 +90483,12 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
90176
90483
  editor.value.off("zoomChange", zoomChangeHandler);
90177
90484
  zoomChangeHandler = null;
90178
90485
  }
90486
+ if (editor.value instanceof PresentationEditor && layoutUpdatedHandler) {
90487
+ editor.value.off("layoutUpdated", layoutUpdatedHandler);
90488
+ layoutUpdatedHandler = null;
90489
+ }
90490
+ cleanupRulerObservers();
90491
+ window.removeEventListener("resize", syncRulerOffset);
90179
90492
  editor.value?.destroy();
90180
90493
  editor.value = null;
90181
90494
  });
@@ -90187,18 +90500,28 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
90187
90500
  __props.options.rulerContainer && rulersVisible.value && !!activeEditor.value ? (openBlock(), createBlock(Teleport, {
90188
90501
  key: 0,
90189
90502
  to: __props.options.rulerContainer
90503
+ }, [
90504
+ createBaseVNode("div", {
90505
+ class: "ruler-host",
90506
+ style: normalizeStyle(rulerHostStyle.value)
90507
+ }, [
90508
+ createVNode(Ruler, {
90509
+ class: "ruler superdoc-ruler",
90510
+ editor: activeEditor.value,
90511
+ onMarginChange: handleMarginChange
90512
+ }, null, 8, ["editor"])
90513
+ ], 4)
90514
+ ], 8, ["to"])) : rulersVisible.value && !!activeEditor.value ? (openBlock(), createElementBlock("div", {
90515
+ key: 1,
90516
+ class: "ruler-host",
90517
+ style: normalizeStyle(rulerHostStyle.value)
90190
90518
  }, [
90191
90519
  createVNode(Ruler, {
90192
- class: "ruler superdoc-ruler",
90520
+ class: "ruler",
90193
90521
  editor: activeEditor.value,
90194
90522
  onMarginChange: handleMarginChange
90195
90523
  }, null, 8, ["editor"])
90196
- ], 8, ["to"])) : rulersVisible.value && !!activeEditor.value ? (openBlock(), createBlock(Ruler, {
90197
- key: 1,
90198
- class: "ruler",
90199
- editor: activeEditor.value,
90200
- onMarginChange: handleMarginChange
90201
- }, null, 8, ["editor"])) : createCommentVNode("", true),
90524
+ ], 4)) : createCommentVNode("", true),
90202
90525
  createBaseVNode("div", {
90203
90526
  class: "super-editor",
90204
90527
  ref_key: "editorWrapper",
@@ -90303,7 +90626,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
90303
90626
  };
90304
90627
  }
90305
90628
  });
90306
- const SuperEditor = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-8dd4cf59"]]);
90629
+ const SuperEditor = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-f5c4f915"]]);
90307
90630
  const _hoisted_1 = ["innerHTML"];
90308
90631
  const _sfc_main = {
90309
90632
  __name: "SuperInput",