@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,7 +1,7 @@
1
1
  "use strict";
2
2
  const jszip = require("./jszip-C8_CqJxM.cjs");
3
3
  const helpers$1 = require("./helpers-nOdwpmwb.cjs");
4
- const superEditor_converter = require("./SuperConverter-d7nvQrVD.cjs");
4
+ const superEditor_converter = require("./SuperConverter-BJ-tba6U.cjs");
5
5
  const vue = require("./vue-De9wkgLl.cjs");
6
6
  require("./jszip.min-BPh2MMAa.cjs");
7
7
  const eventemitter3 = require("./eventemitter3-BQuRcMPI.cjs");
@@ -10953,6 +10953,105 @@ const setSectionHeaderFooterAtSelection = ({ headerInches, footerInches } = {})
10953
10953
  tr.setNodeMarkup(pos, void 0, nextAttrs, node.marks);
10954
10954
  return true;
10955
10955
  };
10956
+ function findGoverningSectPrParagraph(doc2, selectionPos) {
10957
+ const candidates = [];
10958
+ doc2.descendants((node, nodePos) => {
10959
+ if (node.type?.name === "paragraph" && node.attrs?.paragraphProperties?.sectPr) {
10960
+ candidates.push({ node, pos: nodePos });
10961
+ }
10962
+ });
10963
+ if (!candidates.length) return null;
10964
+ const inside = candidates.find((c2) => selectionPos >= c2.pos && selectionPos < c2.pos + c2.node.nodeSize);
10965
+ if (inside) return inside;
10966
+ const atOrAfter = candidates.find((c2) => c2.pos >= selectionPos);
10967
+ return atOrAfter ?? candidates[candidates.length - 1];
10968
+ }
10969
+ const setSectionPageMarginsAtSelection = ({ topInches, rightInches, bottomInches, leftInches } = {}) => ({ tr, state, editor }) => {
10970
+ if (!state || !editor) {
10971
+ console.warn("[setSectionPageMarginsAtSelection] Missing state or editor");
10972
+ return false;
10973
+ }
10974
+ const hasTop = typeof topInches === "number";
10975
+ const hasRight = typeof rightInches === "number";
10976
+ const hasBottom = typeof bottomInches === "number";
10977
+ const hasLeft = typeof leftInches === "number";
10978
+ if (!hasTop && !hasRight && !hasBottom && !hasLeft) {
10979
+ console.warn("[setSectionPageMarginsAtSelection] No margin values provided");
10980
+ return false;
10981
+ }
10982
+ if (hasTop && topInches < 0 || hasRight && rightInches < 0 || hasBottom && bottomInches < 0 || hasLeft && leftInches < 0) {
10983
+ console.warn("[setSectionPageMarginsAtSelection] Margin values must be >= 0");
10984
+ return false;
10985
+ }
10986
+ const updates = {};
10987
+ if (hasTop) updates.topInches = topInches;
10988
+ if (hasRight) updates.rightInches = rightInches;
10989
+ if (hasBottom) updates.bottomInches = bottomInches;
10990
+ if (hasLeft) updates.leftInches = leftInches;
10991
+ const { from: from3 } = state.selection;
10992
+ const governing = findGoverningSectPrParagraph(state.doc, from3);
10993
+ if (governing) {
10994
+ const { node, pos } = governing;
10995
+ const paraProps = node.attrs?.paragraphProperties || null;
10996
+ const existingSectPr = paraProps?.sectPr || null;
10997
+ if (!existingSectPr) {
10998
+ console.warn("[setSectionPageMarginsAtSelection] Paragraph found but has no sectPr");
10999
+ return false;
11000
+ }
11001
+ const sectPr2 = JSON.parse(JSON.stringify(existingSectPr));
11002
+ try {
11003
+ updateSectionMargins({ type: "sectPr", sectPr: sectPr2 }, updates);
11004
+ } catch (err) {
11005
+ console.error("[setSectionPageMarginsAtSelection] Failed to update sectPr:", err);
11006
+ return false;
11007
+ }
11008
+ const resolved = getSectPrMargins(sectPr2);
11009
+ const normalizedSectionMargins = {
11010
+ top: resolved.top ?? null,
11011
+ right: resolved.right ?? null,
11012
+ bottom: resolved.bottom ?? null,
11013
+ left: resolved.left ?? null,
11014
+ header: resolved.header ?? null,
11015
+ footer: resolved.footer ?? null
11016
+ };
11017
+ const newParagraphProperties = { ...paraProps || {}, sectPr: sectPr2 };
11018
+ const nextAttrs = {
11019
+ ...node.attrs,
11020
+ paragraphProperties: newParagraphProperties,
11021
+ sectionMargins: normalizedSectionMargins
11022
+ };
11023
+ tr.setNodeMarkup(pos, void 0, nextAttrs, node.marks);
11024
+ tr.setMeta("forceUpdatePagination", true);
11025
+ return true;
11026
+ }
11027
+ const docAttrs = state.doc.attrs ?? {};
11028
+ const converter = editor.converter ?? null;
11029
+ const baseBodySectPr = docAttrs.bodySectPr || converter?.bodySectPr || null;
11030
+ const sectPr = baseBodySectPr != null ? JSON.parse(JSON.stringify(baseBodySectPr)) : { type: "element", name: "w:sectPr", elements: [] };
11031
+ try {
11032
+ updateSectionMargins({ type: "sectPr", sectPr }, updates);
11033
+ } catch (err) {
11034
+ console.error("[setSectionPageMarginsAtSelection] Failed to update sectPr:", err);
11035
+ return false;
11036
+ }
11037
+ if (converter) {
11038
+ converter.bodySectPr = sectPr;
11039
+ if (!converter.pageStyles) converter.pageStyles = {};
11040
+ if (!converter.pageStyles.pageMargins) converter.pageStyles.pageMargins = {};
11041
+ const pageMargins = converter.pageStyles.pageMargins;
11042
+ const resolved = getSectPrMargins(sectPr);
11043
+ if (resolved.top != null) pageMargins.top = resolved.top;
11044
+ if (resolved.right != null) pageMargins.right = resolved.right;
11045
+ if (resolved.bottom != null) pageMargins.bottom = resolved.bottom;
11046
+ if (resolved.left != null) pageMargins.left = resolved.left;
11047
+ if (resolved.header != null) pageMargins.header = resolved.header;
11048
+ if (resolved.footer != null) pageMargins.footer = resolved.footer;
11049
+ }
11050
+ const nextDocAttrs = { ...docAttrs, bodySectPr: sectPr };
11051
+ tr.setNodeMarkup(0, void 0, nextDocAttrs);
11052
+ tr.setMeta("forceUpdatePagination", true);
11053
+ return true;
11054
+ };
10956
11055
  const insertSectionBreakAtSelection = ({ headerInches, footerInches } = {}) => ({ tr, state, editor }) => {
10957
11056
  if (!state || !editor) {
10958
11057
  console.warn("[insertSectionBreakAtSelection] Missing state or editor");
@@ -11484,6 +11583,7 @@ const commands$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePr
11484
11583
  setMeta,
11485
11584
  setNode,
11486
11585
  setSectionHeaderFooterAtSelection,
11586
+ setSectionPageMarginsAtSelection,
11487
11587
  setTextIndentation,
11488
11588
  setTextSelection,
11489
11589
  skipTab,
@@ -13219,8 +13319,8 @@ const CommentsPlugin = Extension.create({
13219
13319
  }
13220
13320
  if (!onlyActiveThreadChanged) {
13221
13321
  const positionsChanged = hasPositionsChanged(prevAllCommentPositions, allCommentPositions);
13222
- const hasComments = Object.keys(allCommentPositions).length > 0;
13223
- const shouldEmitPositions = positionsChanged || !hasEverEmitted && hasComments;
13322
+ const hasComments2 = Object.keys(allCommentPositions).length > 0;
13323
+ const shouldEmitPositions = positionsChanged || !hasEverEmitted && hasComments2;
13224
13324
  if (shouldEmitPositions) {
13225
13325
  prevAllCommentPositions = allCommentPositions;
13226
13326
  hasEverEmitted = true;
@@ -15351,7 +15451,7 @@ const canUseDOM = () => {
15351
15451
  return false;
15352
15452
  }
15353
15453
  };
15354
- const summaryVersion = "1.3.0-next.8";
15454
+ const summaryVersion = "1.3.0";
15355
15455
  const nodeKeys = ["group", "content", "marks", "inline", "atom", "defining", "code", "tableRole", "summary"];
15356
15456
  const markKeys = ["group", "inclusive", "excludes", "spanning", "code"];
15357
15457
  function mapAttributes(attrs) {
@@ -17353,9 +17453,8 @@ class Editor extends EventEmitter {
17353
17453
  try {
17354
17454
  const jsonObj = json;
17355
17455
  const attrs = jsonObj.attrs;
17356
- const hasBody = attrs && "bodySectPr" in attrs;
17357
17456
  const converter = this.converter;
17358
- if (!hasBody && converter && converter.bodySectPr) {
17457
+ if (converter && converter.bodySectPr) {
17359
17458
  jsonObj.attrs = attrs || {};
17360
17459
  jsonObj.attrs.bodySectPr = converter.bodySectPr;
17361
17460
  }
@@ -17984,7 +18083,7 @@ class Editor extends EventEmitter {
17984
18083
  * Process collaboration migrations
17985
18084
  */
17986
18085
  processCollaborationMigrations() {
17987
- console.debug("[checkVersionMigrations] Current editor version", "1.3.0-next.8");
18086
+ console.debug("[checkVersionMigrations] Current editor version", "1.3.0");
17988
18087
  if (!this.options.ydoc) return;
17989
18088
  const metaMap = this.options.ydoc.getMap("meta");
17990
18089
  let docVersion = metaMap.get("version");
@@ -28215,7 +28314,9 @@ const deriveBlockVersion = (block) => {
28215
28314
  textRun.pmEnd ?? "",
28216
28315
  textRun.token ?? "",
28217
28316
  // Tracked changes - force re-render when added or removed tracked change
28218
- textRun.trackedChange ? 1 : 0
28317
+ textRun.trackedChange ? 1 : 0,
28318
+ // Comment annotations - force re-render when comments are enabled/disabled
28319
+ textRun.comments?.length ?? 0
28219
28320
  ].join(",");
28220
28321
  }).join("|");
28221
28322
  const attrs = block.attrs;
@@ -34087,6 +34188,9 @@ const hashCellBorders = (borders) => {
34087
34188
  if (borders.left) parts.push(`l:[${hashBorderSpec(borders.left)}]`);
34088
34189
  return parts.join(";");
34089
34190
  };
34191
+ function hasComments$1(run) {
34192
+ return "comments" in run && Array.isArray(run.comments) && run.comments.length > 0;
34193
+ }
34090
34194
  const MAX_CACHE_SIZE$1 = 1e4;
34091
34195
  const BYTES_PER_ENTRY_ESTIMATE = 5e3;
34092
34196
  const hashParagraphFrame = (frame) => {
@@ -34154,6 +34258,7 @@ const hashRuns = (block) => {
34154
34258
  fontFamily2 ? `ff:${fontFamily2}` : "",
34155
34259
  highlight ? `hl:${highlight}` : ""
34156
34260
  ].join("");
34261
+ const commentHash = hasComments$1(run) ? run.comments.map((c2) => `${c2.commentId ?? ""}:${c2.internal ? "1" : "0"}`).join("|") : "";
34157
34262
  let trackedKey = "";
34158
34263
  if (hasTrackedChange(run)) {
34159
34264
  const tc = run.trackedChange;
@@ -34161,7 +34266,8 @@ const hashRuns = (block) => {
34161
34266
  const afterHash = tc.after ? JSON.stringify(tc.after) : "";
34162
34267
  trackedKey = `|tc:${tc.kind ?? ""}:${tc.id ?? ""}:${tc.author ?? ""}:${tc.date ?? ""}:${beforeHash}:${afterHash}`;
34163
34268
  }
34164
- cellHashes.push(`${text}:${marks}${trackedKey}`);
34269
+ const commentKey = commentHash ? `|cm:${commentHash}` : "";
34270
+ cellHashes.push(`${text}:${marks}${trackedKey}${commentKey}`);
34165
34271
  }
34166
34272
  if (paragraphBlock.attrs) {
34167
34273
  const attrs = paragraphBlock.attrs;
@@ -35292,6 +35398,9 @@ function remeasureParagraph(block, maxWidth, firstLineIndent = 0) {
35292
35398
  const totalHeight = lines.reduce((s2, l) => s2 + l.lineHeight, 0);
35293
35399
  return { kind: "paragraph", lines, totalHeight };
35294
35400
  }
35401
+ function hasComments(run) {
35402
+ return "comments" in run && Array.isArray(run.comments) && run.comments.length > 0;
35403
+ }
35295
35404
  const computeDirtyRegions = (previous, next) => {
35296
35405
  const prevMap = new Map(previous.map((block, index2) => [block.id, { block, index: index2 }]));
35297
35406
  const nextMap = new Map(next.map((block, index2) => [block.id, { block, index: index2 }]));
@@ -35352,6 +35461,10 @@ const getTrackedChangeKey = (run) => {
35352
35461
  }
35353
35462
  return "";
35354
35463
  };
35464
+ const getCommentKey = (run) => {
35465
+ if (!hasComments(run)) return "";
35466
+ return run.comments.map((c2) => `${c2.commentId ?? ""}:${c2.internal ? "1" : "0"}`).join("|");
35467
+ };
35355
35468
  const paragraphSpacingEqual = (a, b) => {
35356
35469
  if (a === b) return true;
35357
35470
  if (!a || !b) return !a && !b;
@@ -35433,7 +35546,7 @@ const paragraphBlocksEqual = (a, b) => {
35433
35546
  for (let i = 0; i < a.runs.length; i += 1) {
35434
35547
  const runA = a.runs[i];
35435
35548
  const runB = b.runs[i];
35436
- 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)) {
35549
+ 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)) {
35437
35550
  return false;
35438
35551
  }
35439
35552
  }
@@ -40183,7 +40296,7 @@ const resetRunFormatting = (run) => {
40183
40296
  delete run.link;
40184
40297
  delete run.letterSpacing;
40185
40298
  };
40186
- const applyFormatChangeMarks = (run, config, hyperlinkConfig, applyMarksToRun2, themeColors) => {
40299
+ const applyFormatChangeMarks = (run, config, hyperlinkConfig, applyMarksToRun2, themeColors, enableComments = true) => {
40187
40300
  const tracked = run.trackedChange;
40188
40301
  if (!tracked || tracked.kind !== "format") {
40189
40302
  return;
@@ -40208,7 +40321,7 @@ const applyFormatChangeMarks = (run, config, hyperlinkConfig, applyMarksToRun2,
40208
40321
  }
40209
40322
  resetRunFormatting(run);
40210
40323
  try {
40211
- applyMarksToRun2(run, beforeMarks, hyperlinkConfig, themeColors);
40324
+ applyMarksToRun2(run, beforeMarks, hyperlinkConfig, themeColors, void 0, enableComments);
40212
40325
  } catch (error) {
40213
40326
  if (vue.process$1.env.NODE_ENV === "development") {
40214
40327
  console.warn("[PM-Adapter] Error applying format change marks, resetting formatting:", error);
@@ -40216,7 +40329,7 @@ const applyFormatChangeMarks = (run, config, hyperlinkConfig, applyMarksToRun2,
40216
40329
  resetRunFormatting(run);
40217
40330
  }
40218
40331
  };
40219
- const applyTrackedChangesModeToRuns = (runs, config, hyperlinkConfig, applyMarksToRun2, themeColors) => {
40332
+ const applyTrackedChangesModeToRuns = (runs, config, hyperlinkConfig, applyMarksToRun2, themeColors, enableComments = true) => {
40220
40333
  if (!config) {
40221
40334
  return runs;
40222
40335
  }
@@ -40229,7 +40342,7 @@ const applyTrackedChangesModeToRuns = (runs, config, hyperlinkConfig, applyMarks
40229
40342
  } else {
40230
40343
  runs.forEach((run) => {
40231
40344
  if (isTextRun$1(run)) {
40232
- applyFormatChangeMarks(run, config, hyperlinkConfig, applyMarksToRun2, themeColors);
40345
+ applyFormatChangeMarks(run, config, hyperlinkConfig, applyMarksToRun2, themeColors, enableComments);
40233
40346
  }
40234
40347
  });
40235
40348
  }
@@ -40259,9 +40372,23 @@ const applyTrackedChangesModeToRuns = (runs, config, hyperlinkConfig, applyMarks
40259
40372
  } else {
40260
40373
  filtered.forEach((run) => {
40261
40374
  if (isTextRun$1(run)) {
40262
- applyFormatChangeMarks(run, config, hyperlinkConfig || DEFAULT_HYPERLINK_CONFIG$1, applyMarksToRun2, themeColors);
40375
+ applyFormatChangeMarks(
40376
+ run,
40377
+ config,
40378
+ hyperlinkConfig || DEFAULT_HYPERLINK_CONFIG$1,
40379
+ applyMarksToRun2,
40380
+ themeColors,
40381
+ enableComments
40382
+ );
40263
40383
  }
40264
40384
  });
40385
+ if ((config.mode === "original" || config.mode === "final") && config.enabled) {
40386
+ filtered.forEach((run) => {
40387
+ if (isTextRun$1(run) && run.trackedChange && (run.trackedChange.kind === "insert" || run.trackedChange.kind === "delete")) {
40388
+ delete run.trackedChange;
40389
+ }
40390
+ });
40391
+ }
40265
40392
  }
40266
40393
  return filtered;
40267
40394
  };
@@ -41203,7 +41330,10 @@ const applyTextStyleMark = (run, attrs, themeColors) => {
41203
41330
  const DEFAULT_HYPERLINK_CONFIG = {
41204
41331
  enableRichHyperlinks: false
41205
41332
  };
41206
- const applyMarksToRun = (run, marks, hyperlinkConfig = DEFAULT_HYPERLINK_CONFIG, themeColors, backgroundColor) => {
41333
+ const applyMarksToRun = (run, marks, hyperlinkConfig = DEFAULT_HYPERLINK_CONFIG, themeColors, backgroundColor, enableComments = true) => {
41334
+ if (!enableComments && "comments" in run && run.comments) {
41335
+ delete run.comments;
41336
+ }
41207
41337
  const isTabRun2 = run.kind === "tab";
41208
41338
  let markSetColor = false;
41209
41339
  marks.forEach((mark) => {
@@ -41250,7 +41380,7 @@ const applyMarksToRun = (run, marks, hyperlinkConfig = DEFAULT_HYPERLINK_CONFIG,
41250
41380
  break;
41251
41381
  case "commentMark":
41252
41382
  case "comment": {
41253
- if (!isTabRun2) {
41383
+ if (!isTabRun2 && enableComments) {
41254
41384
  pushCommentAnnotation(run, mark.attrs ?? {});
41255
41385
  }
41256
41386
  break;
@@ -43324,7 +43454,16 @@ const computeParagraphAttrs = (para, styleContext, listCounterContext, converter
43324
43454
  if (!value || typeof value !== "object") return;
43325
43455
  return normalizePxIndent(value) ?? convertIndentTwipsToPx(value);
43326
43456
  };
43327
- const normalizedIndent = normalizeIndentObject(attrs.indent) ?? convertIndentTwipsToPx(paragraphProps.indent) ?? convertIndentTwipsToPx(hydrated?.indent) ?? normalizeParagraphIndent(attrs.textIndent);
43457
+ const hydratedIndentPx = convertIndentTwipsToPx(hydrated?.indent);
43458
+ const paragraphIndentPx = convertIndentTwipsToPx(paragraphProps.indent);
43459
+ const textIndentPx = normalizeParagraphIndent(attrs.textIndent);
43460
+ const attrsIndentPx = normalizeIndentObject(attrs.indent);
43461
+ const indentChain = [];
43462
+ if (hydratedIndentPx) indentChain.push({ indent: hydratedIndentPx });
43463
+ if (paragraphIndentPx) indentChain.push({ indent: paragraphIndentPx });
43464
+ if (textIndentPx) indentChain.push({ indent: textIndentPx });
43465
+ if (attrsIndentPx) indentChain.push({ indent: attrsIndentPx });
43466
+ const normalizedIndent = indentChain.length ? superEditor_converter.combineIndentProperties(indentChain).indent : void 0;
43328
43467
  const unwrapTabStops = (tabStops) => {
43329
43468
  if (!Array.isArray(tabStops)) {
43330
43469
  return void 0;
@@ -44876,7 +45015,7 @@ const applyInlineRunProperties = (run, runProperties) => {
44876
45015
  run.letterSpacing = twipsToPx$1(runProperties.letterSpacing);
44877
45016
  }
44878
45017
  };
44879
- function paragraphToFlowBlocks$1(para, nextBlockId, positions, defaultFont, defaultSize, styleContext, listCounterContext, trackedChanges, bookmarks, hyperlinkConfig = DEFAULT_HYPERLINK_CONFIG$1, themeColors, converters, converterContext) {
45018
+ function paragraphToFlowBlocks$1(para, nextBlockId, positions, defaultFont, defaultSize, styleContext, listCounterContext, trackedChanges, bookmarks, hyperlinkConfig = DEFAULT_HYPERLINK_CONFIG$1, themeColors, converters, converterContext, enableComments = true) {
44880
45019
  const baseBlockId = nextBlockId("paragraph");
44881
45020
  const paragraphProps = typeof para.attrs?.paragraphProperties === "object" && para.attrs.paragraphProperties !== null ? para.attrs.paragraphProperties : {};
44882
45021
  const paragraphStyleId = typeof para.attrs?.styleId === "string" && para.attrs.styleId.trim() ? para.attrs.styleId : typeof paragraphProps.styleId === "string" && paragraphProps.styleId.trim() ? paragraphProps.styleId : null;
@@ -45050,7 +45189,8 @@ function paragraphToFlowBlocks$1(para, nextBlockId, positions, defaultFont, defa
45050
45189
  [...node.marks ?? [], ...inheritedMarks ?? []],
45051
45190
  hyperlinkConfig,
45052
45191
  themeColors,
45053
- converterContext?.backgroundColor
45192
+ converterContext?.backgroundColor,
45193
+ enableComments
45054
45194
  );
45055
45195
  currentRuns.push(run);
45056
45196
  return;
@@ -45112,7 +45252,8 @@ function paragraphToFlowBlocks$1(para, nextBlockId, positions, defaultFont, defa
45112
45252
  positions,
45113
45253
  defaultFont,
45114
45254
  defaultSize,
45115
- mergedMarks,
45255
+ [],
45256
+ // Empty marks - will be applied after linked styles
45116
45257
  activeSdt,
45117
45258
  hyperlinkConfig,
45118
45259
  themeColors
@@ -45121,6 +45262,14 @@ function paragraphToFlowBlocks$1(para, nextBlockId, positions, defaultFont, defa
45121
45262
  applyRunStyles2(tokenRun, inlineStyleId, activeRunStyleId);
45122
45263
  applyBaseRunDefaults(tokenRun, baseRunDefaults, defaultFont, defaultSize);
45123
45264
  applyInlineRunProperties(tokenRun, activeRunProperties);
45265
+ applyMarksToRun(
45266
+ tokenRun,
45267
+ mergedMarks,
45268
+ hyperlinkConfig,
45269
+ themeColors,
45270
+ converterContext?.backgroundColor,
45271
+ enableComments
45272
+ );
45124
45273
  if (pageRefPos) {
45125
45274
  tokenRun.pmStart = pageRefPos.start;
45126
45275
  tokenRun.pmEnd = pageRefPos.end;
@@ -45194,7 +45343,8 @@ function paragraphToFlowBlocks$1(para, nextBlockId, positions, defaultFont, defa
45194
45343
  mergedMarks,
45195
45344
  hyperlinkConfig,
45196
45345
  themeColors,
45197
- converterContext?.backgroundColor
45346
+ converterContext?.backgroundColor,
45347
+ enableComments
45198
45348
  );
45199
45349
  }
45200
45350
  console.debug("[token-debug] paragraph-token-run", {
@@ -45393,7 +45543,8 @@ function paragraphToFlowBlocks$1(para, nextBlockId, positions, defaultFont, defa
45393
45543
  trackedChanges,
45394
45544
  hyperlinkConfig,
45395
45545
  applyMarksToRun,
45396
- themeColors
45546
+ themeColors,
45547
+ enableComments
45397
45548
  );
45398
45549
  if (trackedChanges.enabled && filteredRuns.length === 0) {
45399
45550
  return;
@@ -46292,6 +46443,7 @@ function toFlowBlocks(pmDoc, options) {
46292
46443
  const hyperlinkConfig = {
46293
46444
  enableRichHyperlinks: options?.enableRichHyperlinks ?? false
46294
46445
  };
46446
+ const enableComments = options?.enableComments ?? true;
46295
46447
  const themeColors = options?.themeColors;
46296
46448
  const converterContext = options?.converterContext;
46297
46449
  if (!doc2.content) {
@@ -46341,7 +46493,8 @@ function toFlowBlocks(pmDoc, options) {
46341
46493
  bookmarks2,
46342
46494
  hyperlinkConfig2,
46343
46495
  themeColorsParam ?? themeColors,
46344
- converterCtx ?? converterContext
46496
+ converterCtx ?? converterContext,
46497
+ enableComments
46345
46498
  );
46346
46499
  const tableConverter = (node, nextBlockId2, positions2, defaultFont2, defaultSize2, context, trackedChanges, bookmarks2, hyperlinkConfig2, themeColorsParam, converterCtx) => tableNodeToBlock(
46347
46500
  node,
@@ -46380,6 +46533,7 @@ function toFlowBlocks(pmDoc, options) {
46380
46533
  listCounterContext: { getListCounter, incrementListCounter, resetListCounter },
46381
46534
  trackedChangesConfig,
46382
46535
  hyperlinkConfig,
46536
+ enableComments,
46383
46537
  bookmarks,
46384
46538
  sectionState: {
46385
46539
  ranges: sectionRanges,
@@ -46448,7 +46602,7 @@ function mergeDropCapParagraphs(blocks) {
46448
46602
  }
46449
46603
  return result;
46450
46604
  }
46451
- function paragraphToFlowBlocks(para, nextBlockId, positions, defaultFont, defaultSize, styleContext, listCounterContext, trackedChanges, bookmarks, hyperlinkConfig = DEFAULT_HYPERLINK_CONFIG$1, themeColors, converterContext) {
46605
+ function paragraphToFlowBlocks(para, nextBlockId, positions, defaultFont, defaultSize, styleContext, listCounterContext, trackedChanges, bookmarks, hyperlinkConfig = DEFAULT_HYPERLINK_CONFIG$1, themeColors, converterContext, enableComments = true) {
46452
46606
  return paragraphToFlowBlocks$1(
46453
46607
  para,
46454
46608
  nextBlockId,
@@ -46495,7 +46649,8 @@ function paragraphToFlowBlocks(para, nextBlockId, positions, defaultFont, defaul
46495
46649
  }
46496
46650
  )
46497
46651
  },
46498
- converterContext
46652
+ converterContext,
46653
+ enableComments
46499
46654
  );
46500
46655
  }
46501
46656
  function tableNodeToBlock(node, nextBlockId, positions, defaultFont, defaultSize, styleContext, trackedChanges, bookmarks, hyperlinkConfig, themeColors, _paragraphToFlowBlocksParam, converterContext, options) {
@@ -48587,10 +48742,13 @@ async function measureParagraphBlock(block, maxWidth) {
48587
48742
  };
48588
48743
  }
48589
48744
  const originX = currentLine.width;
48590
- const { target, nextIndex, stop } = getNextTabStopPx(currentLine.width, tabStops, tabStopCursor);
48745
+ const effectiveIndent = lines.length === 0 ? indentLeft + rawFirstLineOffset : indentLeft;
48746
+ const absCurrentX = currentLine.width + effectiveIndent;
48747
+ const { target, nextIndex, stop } = getNextTabStopPx(absCurrentX, tabStops, tabStopCursor);
48591
48748
  tabStopCursor = nextIndex;
48592
- const clampedTarget = Math.min(target, currentLine.maxWidth);
48593
- const tabAdvance = Math.max(0, clampedTarget - currentLine.width);
48749
+ const maxAbsWidth = currentLine.maxWidth + effectiveIndent;
48750
+ const clampedTarget = Math.min(target, maxAbsWidth);
48751
+ const tabAdvance = Math.max(0, clampedTarget - absCurrentX);
48594
48752
  currentLine.width = roundValue(currentLine.width + tabAdvance);
48595
48753
  run.width = tabAdvance;
48596
48754
  currentLine.maxFontSize = Math.max(currentLine.maxFontSize, 12);
@@ -48598,8 +48756,9 @@ async function measureParagraphBlock(block, maxWidth) {
48598
48756
  currentLine.toChar = 1;
48599
48757
  if (stop && stop.leader && stop.leader !== "none") {
48600
48758
  const leaderStyle = stop.leader;
48601
- const from3 = Math.min(originX, clampedTarget);
48602
- const to = Math.max(originX, clampedTarget);
48759
+ const relativeTarget = clampedTarget - effectiveIndent;
48760
+ const from3 = Math.min(originX, relativeTarget);
48761
+ const to = Math.max(originX, relativeTarget);
48603
48762
  if (!currentLine.leaders) currentLine.leaders = [];
48604
48763
  currentLine.leaders.push({ from: from3, to, style: leaderStyle });
48605
48764
  }
@@ -48608,27 +48767,28 @@ async function measureParagraphBlock(block, maxWidth) {
48608
48767
  if (stop.val === "end" || stop.val === "center" || stop.val === "decimal") {
48609
48768
  const groupMeasure = measureTabAlignmentGroup(runIndex + 1, runsToProcess, ctx2, decimalSeparator);
48610
48769
  if (groupMeasure.totalWidth > 0) {
48770
+ const relativeTarget = clampedTarget - effectiveIndent;
48611
48771
  let groupStartX;
48612
48772
  if (stop.val === "end") {
48613
- groupStartX = Math.max(0, clampedTarget - groupMeasure.totalWidth);
48773
+ groupStartX = Math.max(0, relativeTarget - groupMeasure.totalWidth);
48614
48774
  } else if (stop.val === "center") {
48615
- groupStartX = Math.max(0, clampedTarget - groupMeasure.totalWidth / 2);
48775
+ groupStartX = Math.max(0, relativeTarget - groupMeasure.totalWidth / 2);
48616
48776
  } else {
48617
48777
  const beforeDecimal = groupMeasure.beforeDecimalWidth ?? groupMeasure.totalWidth;
48618
- groupStartX = Math.max(0, clampedTarget - beforeDecimal);
48778
+ groupStartX = Math.max(0, relativeTarget - beforeDecimal);
48619
48779
  }
48620
48780
  activeTabGroup = {
48621
48781
  measure: groupMeasure,
48622
48782
  startX: groupStartX,
48623
48783
  currentX: groupStartX,
48624
- target: clampedTarget,
48784
+ target: relativeTarget,
48625
48785
  val: stop.val
48626
48786
  };
48627
48787
  currentLine.width = roundValue(groupStartX);
48628
48788
  }
48629
48789
  pendingTabAlignment = null;
48630
48790
  } else {
48631
- pendingTabAlignment = { target: clampedTarget, val: stop.val };
48791
+ pendingTabAlignment = { target: clampedTarget - effectiveIndent, val: stop.val };
48632
48792
  }
48633
48793
  } else {
48634
48794
  pendingTabAlignment = null;
@@ -49269,10 +49429,13 @@ async function measureParagraphBlock(block, maxWidth) {
49269
49429
  };
49270
49430
  }
49271
49431
  const originX = currentLine.width;
49272
- const { target, nextIndex, stop } = getNextTabStopPx(currentLine.width, tabStops, tabStopCursor);
49432
+ const effectiveIndent = lines.length === 0 ? indentLeft + rawFirstLineOffset : indentLeft;
49433
+ const absCurrentX = currentLine.width + effectiveIndent;
49434
+ const { target, nextIndex, stop } = getNextTabStopPx(absCurrentX, tabStops, tabStopCursor);
49273
49435
  tabStopCursor = nextIndex;
49274
- const clampedTarget = Math.min(target, currentLine.maxWidth);
49275
- const tabAdvance = Math.max(0, clampedTarget - currentLine.width);
49436
+ const maxAbsWidth = currentLine.maxWidth + effectiveIndent;
49437
+ const clampedTarget = Math.min(target, maxAbsWidth);
49438
+ const tabAdvance = Math.max(0, clampedTarget - absCurrentX);
49276
49439
  currentLine.width = roundValue(currentLine.width + tabAdvance);
49277
49440
  currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run);
49278
49441
  currentLine.maxFontSize = Math.max(currentLine.maxFontSize, run.fontSize);
@@ -49281,14 +49444,15 @@ async function measureParagraphBlock(block, maxWidth) {
49281
49444
  charPosInRun += 1;
49282
49445
  if (stop) {
49283
49446
  validateTabStopVal(stop);
49284
- pendingTabAlignment = { target: clampedTarget, val: stop.val };
49447
+ pendingTabAlignment = { target: clampedTarget - effectiveIndent, val: stop.val };
49285
49448
  } else {
49286
49449
  pendingTabAlignment = null;
49287
49450
  }
49288
49451
  if (stop && stop.leader && stop.leader !== "none" && stop.leader !== "middleDot") {
49289
49452
  const leaderStyle = stop.leader;
49290
- const from3 = Math.min(originX, clampedTarget);
49291
- const to = Math.max(originX, clampedTarget);
49453
+ const relativeTarget = clampedTarget - effectiveIndent;
49454
+ const from3 = Math.min(originX, relativeTarget);
49455
+ const to = Math.max(originX, relativeTarget);
49292
49456
  if (!currentLine.leaders) currentLine.leaders = [];
49293
49457
  currentLine.leaders.push({ from: from3, to, style: leaderStyle });
49294
49458
  }
@@ -49564,7 +49728,11 @@ async function measureTableBlock(block, constraints) {
49564
49728
  }
49565
49729
  async function measureImageBlock(block, constraints) {
49566
49730
  const intrinsic = getIntrinsicImageSize(block, constraints.maxWidth);
49567
- const maxWidth = constraints.maxWidth > 0 ? constraints.maxWidth : intrinsic.width;
49731
+ const isBlockBehindDoc = block.anchor?.behindDoc;
49732
+ const isBlockWrapBehindDoc = block.wrap?.type === "None" && block.wrap?.behindDoc;
49733
+ const bypassWidthConstraint = isBlockBehindDoc || isBlockWrapBehindDoc;
49734
+ const isWidthConstraintBypassed = bypassWidthConstraint || constraints.maxWidth <= 0;
49735
+ const maxWidth = isWidthConstraintBypassed ? intrinsic.width : constraints.maxWidth;
49568
49736
  const hasNegativeVerticalPosition = block.anchor?.isAnchored && (typeof block.anchor?.offsetV === "number" && block.anchor.offsetV < 0 || typeof block.margin?.top === "number" && block.margin.top < 0);
49569
49737
  const maxHeight = hasNegativeVerticalPosition || !constraints.maxHeight || constraints.maxHeight <= 0 ? Infinity : constraints.maxHeight;
49570
49738
  const widthScale = maxWidth / intrinsic.width;
@@ -50704,12 +50872,13 @@ class PresentationEditor extends EventEmitter {
50704
50872
  if (!validModes.includes(mode)) {
50705
50873
  throw new TypeError(`[PresentationEditor] Invalid mode "${mode}". Must be one of: ${validModes.join(", ")}`);
50706
50874
  }
50875
+ const modeChanged = this.#documentMode !== mode;
50707
50876
  this.#documentMode = mode;
50708
50877
  this.#editor.setDocumentMode(mode);
50709
50878
  this.#syncDocumentModeClass();
50710
50879
  this.#syncHiddenEditorA11yAttributes();
50711
50880
  const trackedChangesChanged = this.#syncTrackedChangesPreferences();
50712
- if (trackedChangesChanged) {
50881
+ if (modeChanged || trackedChangesChanged) {
50713
50882
  this.#pendingDocChange = true;
50714
50883
  this.#scheduleRerender();
50715
50884
  }
@@ -50730,9 +50899,10 @@ class PresentationEditor extends EventEmitter {
50730
50899
  throw new TypeError("[PresentationEditor] setTrackedChangesOverrides expects an object or undefined");
50731
50900
  }
50732
50901
  if (overrides !== void 0) {
50733
- if (overrides.mode !== void 0 && !["review", "simple", "original"].includes(overrides.mode)) {
50902
+ const validModes = ["review", "original", "final", "off"];
50903
+ if (overrides.mode !== void 0 && !validModes.includes(overrides.mode)) {
50734
50904
  throw new TypeError(
50735
- `[PresentationEditor] Invalid tracked changes mode "${overrides.mode}". Must be one of: review, simple, original`
50905
+ `[PresentationEditor] Invalid tracked changes mode "${overrides.mode}". Must be one of: ${validModes.join(", ")}`
50736
50906
  );
50737
50907
  }
50738
50908
  if (overrides.enabled !== void 0 && typeof overrides.enabled !== "boolean") {
@@ -53114,12 +53284,14 @@ class PresentationEditor extends EventEmitter {
53114
53284
  } : void 0;
53115
53285
  const atomNodeTypes = getAtomNodeTypes(this.#editor?.schema ?? null);
53116
53286
  const positionMap = this.#editor?.state?.doc && docJson ? buildPositionMapFromPmDoc(this.#editor.state.doc, docJson) : null;
53287
+ const commentsEnabled = this.#documentMode !== "viewing";
53117
53288
  const result = toFlowBlocks(docJson, {
53118
53289
  mediaFiles: this.#editor?.storage?.image?.media,
53119
53290
  emitSectionBreaks: true,
53120
53291
  sectionMetadata,
53121
53292
  trackedChangesMode: this.#trackedChangesMode,
53122
53293
  enableTrackedChanges: this.#trackedChangesEnabled,
53294
+ enableComments: commentsEnabled,
53123
53295
  enableRichHyperlinks: true,
53124
53296
  themeColors: this.#editor?.converter?.themeColors ?? void 0,
53125
53297
  converterContext,
@@ -53250,10 +53422,12 @@ class PresentationEditor extends EventEmitter {
53250
53422
  const payload = { layout, blocks, measures, metrics };
53251
53423
  this.emit("layoutUpdated", payload);
53252
53424
  this.emit("paginationUpdate", payload);
53253
- const commentPositions = this.#collectCommentPositions();
53254
- const positionKeys = Object.keys(commentPositions);
53255
- if (positionKeys.length > 0) {
53256
- this.emit("commentPositions", { positions: commentPositions });
53425
+ if (this.#documentMode !== "viewing") {
53426
+ const commentPositions = this.#collectCommentPositions();
53427
+ const positionKeys = Object.keys(commentPositions);
53428
+ if (positionKeys.length > 0) {
53429
+ this.emit("commentPositions", { positions: commentPositions });
53430
+ }
53257
53431
  }
53258
53432
  if (this.#telemetryEmitter && metrics) {
53259
53433
  this.#telemetryEmitter({ type: "layout", data: { layout, blocks, measures, metrics } });
@@ -54679,7 +54853,7 @@ class PresentationEditor extends EventEmitter {
54679
54853
  const zoom = this.#layoutOptions.zoom ?? 1;
54680
54854
  const layoutMode = this.#layoutOptions.layoutMode ?? "vertical";
54681
54855
  const pages = this.#layoutState.layout?.pages;
54682
- const pageGap = this.#layoutState.layout?.pageGap ?? this.#getEffectivePageGap();
54856
+ const pageGap = this.#getEffectivePageGap();
54683
54857
  const defaultWidth = this.#layoutOptions.pageSize?.w ?? DEFAULT_PAGE_SIZE.w;
54684
54858
  const defaultHeight = this.#layoutOptions.pageSize?.h ?? DEFAULT_PAGE_SIZE.h;
54685
54859
  let maxWidth = defaultWidth;
@@ -57790,7 +57964,11 @@ const Document = Node$1.create({
57790
57964
  */
57791
57965
  clearDocument: () => ({ commands: commands2 }) => {
57792
57966
  return commands2.setContent("<p></p>");
57793
- }
57967
+ },
57968
+ /**
57969
+ * Set section page margins (top/right/bottom/left) for the section at the current selection.
57970
+ */
57971
+ setSectionPageMarginsAtSelection
57794
57972
  };
57795
57973
  }
57796
57974
  });
@@ -58444,12 +58622,18 @@ function findParagraphContext($pos, cache2, helpers2) {
58444
58622
  return null;
58445
58623
  }
58446
58624
  function extractParagraphContext(node, startPos, helpers2, depth = 0) {
58447
- const paragraphProperties = superEditor_converter.getResolvedParagraphProperties(node) ?? {};
58625
+ const paragraphProperties = superEditor_converter.getResolvedParagraphProperties(node) ?? node.attrs?.paragraphProperties ?? {};
58448
58626
  const alignmentAliases = { left: "start", right: "end" };
58449
58627
  let tabStops = [];
58450
58628
  if (Array.isArray(paragraphProperties.tabStops)) {
58451
58629
  tabStops = paragraphProperties.tabStops.map((stop) => {
58452
58630
  const ref = stop?.tab;
58631
+ if (!ref && stop?.pos != null) {
58632
+ return {
58633
+ ...stop,
58634
+ pos: twipsToPixels(Number(stop.pos) || 0)
58635
+ };
58636
+ }
58453
58637
  if (!ref) return stop || null;
58454
58638
  const rawType = ref.tabType || "start";
58455
58639
  const mappedVal = alignmentAliases[rawType] || rawType;
@@ -59715,6 +59899,13 @@ function createLayoutRequest(doc2, paragraphPos, view, helpers2, revision, parag
59715
59899
  pos: entry.pos,
59716
59900
  nodeSize: node.nodeSize
59717
59901
  });
59902
+ } else if (node.type.name === "lineBreak" || node.type.name === "hardBreak") {
59903
+ spans.push({
59904
+ type: node.type.name,
59905
+ spanId,
59906
+ pos: entry.pos,
59907
+ nodeSize: node.nodeSize
59908
+ });
59718
59909
  } else if (node.type.name === "text") {
59719
59910
  spans.push({
59720
59911
  type: "text",
@@ -59764,6 +59955,7 @@ function calculateTabLayout(request, measurement, view) {
59764
59955
  paragraphNode
59765
59956
  } = request;
59766
59957
  const tabs = {};
59958
+ const leftIndentPx = request.indents?.left ?? 0;
59767
59959
  let currentX = indentWidth;
59768
59960
  const measureText2 = (span) => {
59769
59961
  if (view && typeof span.from === "number" && typeof span.to === "number") {
@@ -59776,6 +59968,8 @@ function calculateTabLayout(request, measurement, view) {
59776
59968
  const span = spans[i];
59777
59969
  if (span.type === "text") {
59778
59970
  currentX += measureText2(span);
59971
+ } else if (span.type === "lineBreak" || span.type === "hardBreak") {
59972
+ currentX = leftIndentPx;
59779
59973
  } else if (span.type === "tab") {
59780
59974
  const followingText = collectFollowingText(spans, i + 1);
59781
59975
  let measureTextCallback;
@@ -59871,7 +60065,7 @@ function collectFollowingText(spans, startIndex) {
59871
60065
  let text = "";
59872
60066
  for (let i = startIndex; i < spans.length; i++) {
59873
60067
  const span = spans[i];
59874
- if (span.type === "tab") break;
60068
+ if (span.type === "tab" || span.type === "lineBreak" || span.type === "hardBreak") break;
59875
60069
  if (span.type === "text") text += span.text || "";
59876
60070
  }
59877
60071
  return text;
@@ -59881,7 +60075,7 @@ function getFollowingTextRange(spans, startIndex) {
59881
60075
  let to = null;
59882
60076
  for (let i = startIndex; i < spans.length; i++) {
59883
60077
  const span = spans[i];
59884
- if (span.type === "tab") break;
60078
+ if (span.type === "tab" || span.type === "lineBreak" || span.type === "hardBreak") break;
59885
60079
  if (span.type === "text" && typeof span.from === "number" && typeof span.to === "number") {
59886
60080
  if (from3 === null) from3 = span.from;
59887
60081
  to = span.to;
@@ -64299,6 +64493,10 @@ const Image = Node$1.create({
64299
64493
  }
64300
64494
  const hasAnchorData = Boolean(anchorData);
64301
64495
  const hasMarginOffsets = marginOffset?.horizontal != null || marginOffset?.top != null;
64496
+ const isWrapBehindDoc = wrap?.attrs?.behindDoc;
64497
+ const isAnchorBehindDoc = anchorData?.behindDoc;
64498
+ const isBehindDocAnchor = wrap?.type === "None" && (isWrapBehindDoc || isAnchorBehindDoc);
64499
+ const isAbsolutelyPositioned = style2.includes("position: absolute;");
64302
64500
  if (hasAnchorData) {
64303
64501
  switch (anchorData.hRelativeFrom) {
64304
64502
  case "page":
@@ -64326,7 +64524,6 @@ const Image = Node$1.create({
64326
64524
  style2 += "float: left;";
64327
64525
  }
64328
64526
  } else if (!anchorData.alignH && marginOffset?.horizontal != null) {
64329
- const isAbsolutelyPositioned = style2.includes("position: absolute;");
64330
64527
  if (isAbsolutelyPositioned) {
64331
64528
  style2 += `left: ${baseHorizontal}px;`;
64332
64529
  style2 += "max-width: none;";
@@ -64340,7 +64537,8 @@ const Image = Node$1.create({
64340
64537
  const relativeFromPageV = anchorData?.vRelativeFrom === "page";
64341
64538
  const relativeFromMarginV = anchorData?.vRelativeFrom === "margin";
64342
64539
  const maxMarginV = 500;
64343
- const baseTop = Math.max(0, marginOffset?.top ?? 0);
64540
+ const allowNegativeTopOffset = isBehindDocAnchor;
64541
+ const baseTop = allowNegativeTopOffset ? marginOffset?.top ?? 0 : Math.max(0, marginOffset?.top ?? 0);
64344
64542
  let rotationHorizontal = 0;
64345
64543
  let rotationTop = 0;
64346
64544
  const { rotation: rotation2 } = transformData ?? {};
@@ -64359,7 +64557,10 @@ const Image = Node$1.create({
64359
64557
  margin.left += horizontal;
64360
64558
  }
64361
64559
  }
64362
- if (top2 && !relativeFromMarginV) {
64560
+ const appliedTopViaStyle = isAbsolutelyPositioned && allowNegativeTopOffset && !relativeFromMarginV;
64561
+ if (appliedTopViaStyle) {
64562
+ style2 += `top: ${top2}px;`;
64563
+ } else if (top2 && !relativeFromMarginV) {
64363
64564
  if (relativeFromPageV && top2 >= maxMarginV) margin.top += maxMarginV;
64364
64565
  else margin.top += top2;
64365
64566
  }
@@ -64372,6 +64573,9 @@ const Image = Node$1.create({
64372
64573
  }
64373
64574
  if (margin.top) style2 += `margin-top: ${margin.top}px;`;
64374
64575
  if (margin.bottom) style2 += `margin-bottom: ${margin.bottom}px;`;
64576
+ if (isBehindDocAnchor) {
64577
+ style2 += "max-width: none;";
64578
+ }
64375
64579
  const finalAttributes = { ...htmlAttributes };
64376
64580
  if (style2) {
64377
64581
  const existingStyle = finalAttributes.style || "";
@@ -78825,7 +79029,7 @@ var ResizeObserverController = (function() {
78825
79029
  };
78826
79030
  return ResizeObserverController2;
78827
79031
  })();
78828
- var ResizeObserver = (function() {
79032
+ var ResizeObserver$1 = (function() {
78829
79033
  function ResizeObserver2(callback) {
78830
79034
  if (arguments.length === 0) {
78831
79035
  throw new TypeError("Failed to construct 'ResizeObserver': 1 argument required, but only 0 present.");
@@ -78864,7 +79068,7 @@ var ResizeObserver = (function() {
78864
79068
  class ResizeObserverDelegate {
78865
79069
  constructor() {
78866
79070
  this.handleResize = this.handleResize.bind(this);
78867
- this.observer = new (typeof window !== "undefined" && window.ResizeObserver || ResizeObserver)(this.handleResize);
79071
+ this.observer = new (typeof window !== "undefined" && window.ResizeObserver || ResizeObserver$1)(this.handleResize);
78868
79072
  this.elHandlersMap = /* @__PURE__ */ new Map();
78869
79073
  }
78870
79074
  handleResize(entries) {
@@ -89733,6 +89937,31 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
89733
89937
  },
89734
89938
  { immediate: true, deep: true }
89735
89939
  );
89940
+ vue.watch(
89941
+ () => props.options?.rulerContainer,
89942
+ () => {
89943
+ vue.nextTick(() => {
89944
+ syncRulerOffset();
89945
+ setupRulerObservers();
89946
+ });
89947
+ },
89948
+ { immediate: true }
89949
+ );
89950
+ vue.watch(
89951
+ rulersVisible,
89952
+ (visible) => {
89953
+ vue.nextTick(() => {
89954
+ if (visible) {
89955
+ syncRulerOffset();
89956
+ setupRulerObservers();
89957
+ } else {
89958
+ rulerHostStyle.value = {};
89959
+ cleanupRulerObservers();
89960
+ }
89961
+ });
89962
+ },
89963
+ { immediate: true }
89964
+ );
89736
89965
  const containerStyle = vue.computed(() => {
89737
89966
  let maxWidth = 8.5 * 96;
89738
89967
  const ed = editor.value;
@@ -89757,6 +89986,71 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
89757
89986
  minWidth: `${scaledWidth}px`
89758
89987
  };
89759
89988
  });
89989
+ const rulerHostStyle = vue.ref({});
89990
+ const rulerContainerEl = vue.ref(null);
89991
+ let editorResizeObserver = null;
89992
+ let rulerContainerResizeObserver = null;
89993
+ let layoutUpdatedHandler = null;
89994
+ const resolveRulerContainer = () => {
89995
+ const container = props.options?.rulerContainer;
89996
+ if (!container) return null;
89997
+ if (typeof container === "string") {
89998
+ const doc2 = editorWrapper.value?.ownerDocument ?? document;
89999
+ return doc2.querySelector(container);
90000
+ }
90001
+ return container instanceof HTMLElement ? container : null;
90002
+ };
90003
+ const getViewportRect2 = () => {
90004
+ const host = editorWrapper.value;
90005
+ if (!host) return null;
90006
+ const viewport2 = host.querySelector(".presentation-editor__viewport");
90007
+ const target = viewport2 ?? host;
90008
+ return target.getBoundingClientRect();
90009
+ };
90010
+ const syncRulerOffset = () => {
90011
+ if (!rulersVisible.value) {
90012
+ rulerHostStyle.value = {};
90013
+ return;
90014
+ }
90015
+ rulerContainerEl.value = resolveRulerContainer();
90016
+ if (!rulerContainerEl.value) {
90017
+ rulerHostStyle.value = {};
90018
+ return;
90019
+ }
90020
+ const viewportRect = getViewportRect2();
90021
+ if (!viewportRect) return;
90022
+ const hostRect = rulerContainerEl.value.getBoundingClientRect();
90023
+ const paddingLeft = Math.max(0, viewportRect.left - hostRect.left);
90024
+ const paddingRight = Math.max(0, hostRect.right - viewportRect.right);
90025
+ rulerHostStyle.value = {
90026
+ paddingLeft: `${paddingLeft}px`,
90027
+ paddingRight: `${paddingRight}px`
90028
+ };
90029
+ };
90030
+ const cleanupRulerObservers = () => {
90031
+ if (editorResizeObserver) {
90032
+ editorResizeObserver.disconnect();
90033
+ editorResizeObserver = null;
90034
+ }
90035
+ if (rulerContainerResizeObserver) {
90036
+ rulerContainerResizeObserver.disconnect();
90037
+ rulerContainerResizeObserver = null;
90038
+ }
90039
+ };
90040
+ const setupRulerObservers = () => {
90041
+ cleanupRulerObservers();
90042
+ if (typeof ResizeObserver === "undefined") return;
90043
+ const viewportHost = editorWrapper.value;
90044
+ const rulerHost = resolveRulerContainer();
90045
+ if (viewportHost) {
90046
+ editorResizeObserver = new ResizeObserver(() => syncRulerOffset());
90047
+ editorResizeObserver.observe(viewportHost);
90048
+ }
90049
+ if (rulerHost) {
90050
+ rulerContainerResizeObserver = new ResizeObserver(() => syncRulerOffset());
90051
+ rulerContainerResizeObserver.observe(rulerHost);
90052
+ }
90053
+ };
89760
90054
  const message = useMessage();
89761
90055
  const editorWrapper = vue.ref(null);
89762
90056
  const editorElem = vue.ref(null);
@@ -90068,7 +90362,7 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
90068
90362
  presentationEditor.on("imageDeselected", () => {
90069
90363
  clearSelectedImage();
90070
90364
  });
90071
- presentationEditor.on("layoutUpdated", () => {
90365
+ layoutUpdatedHandler = () => {
90072
90366
  if (imageResizeState.visible && imageResizeState.blockId) {
90073
90367
  const escapedBlockId = CSS.escape(imageResizeState.blockId);
90074
90368
  const newElement = editorElem.value?.querySelector(
@@ -90101,13 +90395,17 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
90101
90395
  clearSelectedImage();
90102
90396
  }
90103
90397
  }
90104
- });
90398
+ vue.nextTick(() => syncRulerOffset());
90399
+ };
90400
+ presentationEditor.on("layoutUpdated", layoutUpdatedHandler);
90105
90401
  zoomChangeHandler = ({ zoom }) => {
90106
90402
  currentZoom.value = zoom;
90403
+ vue.nextTick(() => syncRulerOffset());
90107
90404
  };
90108
90405
  presentationEditor.on("zoomChange", zoomChangeHandler);
90109
90406
  if (typeof presentationEditor.zoom === "number") {
90110
90407
  currentZoom.value = presentationEditor.zoom;
90408
+ vue.nextTick(() => syncRulerOffset());
90111
90409
  }
90112
90410
  }
90113
90411
  editor.value.on("paginationUpdate", () => {
@@ -90167,6 +90465,11 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
90167
90465
  vue.onMounted(() => {
90168
90466
  initializeData();
90169
90467
  if (props.options?.suppressSkeletonLoader || !props.options?.collaborationProvider) editorReady.value = true;
90468
+ window.addEventListener("resize", syncRulerOffset, { passive: true });
90469
+ vue.nextTick(() => {
90470
+ syncRulerOffset();
90471
+ setupRulerObservers();
90472
+ });
90170
90473
  });
90171
90474
  const handleMarginClick = (event) => {
90172
90475
  if (event.button !== 0) {
@@ -90181,10 +90484,14 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
90181
90484
  const handleMarginChange = ({ side, value }) => {
90182
90485
  const base2 = activeEditor.value;
90183
90486
  if (!base2) return;
90184
- const pageStyles2 = base2.getPageStyles();
90185
- const { pageMargins } = pageStyles2;
90186
- const update = { ...pageMargins, [side]: value };
90187
- base2?.updatePageStyle({ pageMargins: update });
90487
+ const payload = side === "left" ? { leftInches: value } : side === "right" ? { rightInches: value } : side === "top" ? { topInches: value } : side === "bottom" ? { bottomInches: value } : {};
90488
+ const didUpdateSection = typeof base2.commands?.setSectionPageMarginsAtSelection === "function" ? base2.commands.setSectionPageMarginsAtSelection(payload) : false;
90489
+ if (!didUpdateSection) {
90490
+ const pageStyles2 = base2.getPageStyles();
90491
+ const { pageMargins } = pageStyles2;
90492
+ const update = { ...pageMargins, [side]: value };
90493
+ base2?.updatePageStyle({ pageMargins: update });
90494
+ }
90188
90495
  };
90189
90496
  vue.onBeforeUnmount(() => {
90190
90497
  stopPolling();
@@ -90193,6 +90500,12 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
90193
90500
  editor.value.off("zoomChange", zoomChangeHandler);
90194
90501
  zoomChangeHandler = null;
90195
90502
  }
90503
+ if (editor.value instanceof PresentationEditor && layoutUpdatedHandler) {
90504
+ editor.value.off("layoutUpdated", layoutUpdatedHandler);
90505
+ layoutUpdatedHandler = null;
90506
+ }
90507
+ cleanupRulerObservers();
90508
+ window.removeEventListener("resize", syncRulerOffset);
90196
90509
  editor.value?.destroy();
90197
90510
  editor.value = null;
90198
90511
  });
@@ -90204,18 +90517,28 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
90204
90517
  __props.options.rulerContainer && rulersVisible.value && !!activeEditor.value ? (vue.openBlock(), vue.createBlock(vue.Teleport, {
90205
90518
  key: 0,
90206
90519
  to: __props.options.rulerContainer
90520
+ }, [
90521
+ vue.createBaseVNode("div", {
90522
+ class: "ruler-host",
90523
+ style: vue.normalizeStyle(rulerHostStyle.value)
90524
+ }, [
90525
+ vue.createVNode(Ruler, {
90526
+ class: "ruler superdoc-ruler",
90527
+ editor: activeEditor.value,
90528
+ onMarginChange: handleMarginChange
90529
+ }, null, 8, ["editor"])
90530
+ ], 4)
90531
+ ], 8, ["to"])) : rulersVisible.value && !!activeEditor.value ? (vue.openBlock(), vue.createElementBlock("div", {
90532
+ key: 1,
90533
+ class: "ruler-host",
90534
+ style: vue.normalizeStyle(rulerHostStyle.value)
90207
90535
  }, [
90208
90536
  vue.createVNode(Ruler, {
90209
- class: "ruler superdoc-ruler",
90537
+ class: "ruler",
90210
90538
  editor: activeEditor.value,
90211
90539
  onMarginChange: handleMarginChange
90212
90540
  }, null, 8, ["editor"])
90213
- ], 8, ["to"])) : rulersVisible.value && !!activeEditor.value ? (vue.openBlock(), vue.createBlock(Ruler, {
90214
- key: 1,
90215
- class: "ruler",
90216
- editor: activeEditor.value,
90217
- onMarginChange: handleMarginChange
90218
- }, null, 8, ["editor"])) : vue.createCommentVNode("", true),
90541
+ ], 4)) : vue.createCommentVNode("", true),
90219
90542
  vue.createBaseVNode("div", {
90220
90543
  class: "super-editor",
90221
90544
  ref_key: "editorWrapper",
@@ -90320,7 +90643,7 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
90320
90643
  };
90321
90644
  }
90322
90645
  });
90323
- const SuperEditor = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-8dd4cf59"]]);
90646
+ const SuperEditor = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-f5c4f915"]]);
90324
90647
  const _hoisted_1 = ["innerHTML"];
90325
90648
  const _sfc_main = {
90326
90649
  __name: "SuperInput",