@harbour-enterprises/superdoc 1.3.0-next.9 → 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.
@@ -36435,7 +36435,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
36435
36435
  static getStoredSuperdocVersion(docx) {
36436
36436
  return SuperConverter.getStoredCustomProperty(docx, "SuperdocVersion");
36437
36437
  }
36438
- static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.3.0-next.9") {
36438
+ static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.3.0") {
36439
36439
  return SuperConverter.setStoredCustomProperty(docx, "SuperdocVersion", version2, false);
36440
36440
  }
36441
36441
  /**
@@ -47282,6 +47282,105 @@ Please report this to https://github.com/markedjs/marked.`, e) {
47282
47282
  tr.setNodeMarkup(pos, void 0, nextAttrs, node2.marks);
47283
47283
  return true;
47284
47284
  };
47285
+ function findGoverningSectPrParagraph(doc2, selectionPos) {
47286
+ const candidates = [];
47287
+ doc2.descendants((node2, nodePos) => {
47288
+ if (node2.type?.name === "paragraph" && node2.attrs?.paragraphProperties?.sectPr) {
47289
+ candidates.push({ node: node2, pos: nodePos });
47290
+ }
47291
+ });
47292
+ if (!candidates.length) return null;
47293
+ const inside = candidates.find((c2) => selectionPos >= c2.pos && selectionPos < c2.pos + c2.node.nodeSize);
47294
+ if (inside) return inside;
47295
+ const atOrAfter = candidates.find((c2) => c2.pos >= selectionPos);
47296
+ return atOrAfter ?? candidates[candidates.length - 1];
47297
+ }
47298
+ const setSectionPageMarginsAtSelection = ({ topInches, rightInches, bottomInches, leftInches } = {}) => ({ tr, state, editor }) => {
47299
+ if (!state || !editor) {
47300
+ console.warn("[setSectionPageMarginsAtSelection] Missing state or editor");
47301
+ return false;
47302
+ }
47303
+ const hasTop = typeof topInches === "number";
47304
+ const hasRight = typeof rightInches === "number";
47305
+ const hasBottom = typeof bottomInches === "number";
47306
+ const hasLeft = typeof leftInches === "number";
47307
+ if (!hasTop && !hasRight && !hasBottom && !hasLeft) {
47308
+ console.warn("[setSectionPageMarginsAtSelection] No margin values provided");
47309
+ return false;
47310
+ }
47311
+ if (hasTop && topInches < 0 || hasRight && rightInches < 0 || hasBottom && bottomInches < 0 || hasLeft && leftInches < 0) {
47312
+ console.warn("[setSectionPageMarginsAtSelection] Margin values must be >= 0");
47313
+ return false;
47314
+ }
47315
+ const updates = {};
47316
+ if (hasTop) updates.topInches = topInches;
47317
+ if (hasRight) updates.rightInches = rightInches;
47318
+ if (hasBottom) updates.bottomInches = bottomInches;
47319
+ if (hasLeft) updates.leftInches = leftInches;
47320
+ const { from: from2 } = state.selection;
47321
+ const governing = findGoverningSectPrParagraph(state.doc, from2);
47322
+ if (governing) {
47323
+ const { node: node2, pos } = governing;
47324
+ const paraProps = node2.attrs?.paragraphProperties || null;
47325
+ const existingSectPr = paraProps?.sectPr || null;
47326
+ if (!existingSectPr) {
47327
+ console.warn("[setSectionPageMarginsAtSelection] Paragraph found but has no sectPr");
47328
+ return false;
47329
+ }
47330
+ const sectPr2 = JSON.parse(JSON.stringify(existingSectPr));
47331
+ try {
47332
+ updateSectionMargins({ type: "sectPr", sectPr: sectPr2 }, updates);
47333
+ } catch (err) {
47334
+ console.error("[setSectionPageMarginsAtSelection] Failed to update sectPr:", err);
47335
+ return false;
47336
+ }
47337
+ const resolved = getSectPrMargins(sectPr2);
47338
+ const normalizedSectionMargins = {
47339
+ top: resolved.top ?? null,
47340
+ right: resolved.right ?? null,
47341
+ bottom: resolved.bottom ?? null,
47342
+ left: resolved.left ?? null,
47343
+ header: resolved.header ?? null,
47344
+ footer: resolved.footer ?? null
47345
+ };
47346
+ const newParagraphProperties = { ...paraProps || {}, sectPr: sectPr2 };
47347
+ const nextAttrs = {
47348
+ ...node2.attrs,
47349
+ paragraphProperties: newParagraphProperties,
47350
+ sectionMargins: normalizedSectionMargins
47351
+ };
47352
+ tr.setNodeMarkup(pos, void 0, nextAttrs, node2.marks);
47353
+ tr.setMeta("forceUpdatePagination", true);
47354
+ return true;
47355
+ }
47356
+ const docAttrs = state.doc.attrs ?? {};
47357
+ const converter = editor.converter ?? null;
47358
+ const baseBodySectPr = docAttrs.bodySectPr || converter?.bodySectPr || null;
47359
+ const sectPr = baseBodySectPr != null ? JSON.parse(JSON.stringify(baseBodySectPr)) : { type: "element", name: "w:sectPr", elements: [] };
47360
+ try {
47361
+ updateSectionMargins({ type: "sectPr", sectPr }, updates);
47362
+ } catch (err) {
47363
+ console.error("[setSectionPageMarginsAtSelection] Failed to update sectPr:", err);
47364
+ return false;
47365
+ }
47366
+ if (converter) {
47367
+ converter.bodySectPr = sectPr;
47368
+ if (!converter.pageStyles) converter.pageStyles = {};
47369
+ if (!converter.pageStyles.pageMargins) converter.pageStyles.pageMargins = {};
47370
+ const pageMargins = converter.pageStyles.pageMargins;
47371
+ const resolved = getSectPrMargins(sectPr);
47372
+ if (resolved.top != null) pageMargins.top = resolved.top;
47373
+ if (resolved.right != null) pageMargins.right = resolved.right;
47374
+ if (resolved.bottom != null) pageMargins.bottom = resolved.bottom;
47375
+ if (resolved.left != null) pageMargins.left = resolved.left;
47376
+ if (resolved.header != null) pageMargins.header = resolved.header;
47377
+ if (resolved.footer != null) pageMargins.footer = resolved.footer;
47378
+ }
47379
+ const nextDocAttrs = { ...docAttrs, bodySectPr: sectPr };
47380
+ tr.setNodeMarkup(0, void 0, nextDocAttrs);
47381
+ tr.setMeta("forceUpdatePagination", true);
47382
+ return true;
47383
+ };
47285
47384
  const insertSectionBreakAtSelection = ({ headerInches, footerInches } = {}) => ({ tr, state, editor }) => {
47286
47385
  if (!state || !editor) {
47287
47386
  console.warn("[insertSectionBreakAtSelection] Missing state or editor");
@@ -47813,6 +47912,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
47813
47912
  setMeta,
47814
47913
  setNode,
47815
47914
  setSectionHeaderFooterAtSelection,
47915
+ setSectionPageMarginsAtSelection,
47816
47916
  setTextIndentation,
47817
47917
  setTextSelection,
47818
47918
  skipTab,
@@ -62145,7 +62245,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
62145
62245
  return false;
62146
62246
  }
62147
62247
  };
62148
- const summaryVersion = "1.3.0-next.9";
62248
+ const summaryVersion = "1.3.0";
62149
62249
  const nodeKeys = ["group", "content", "marks", "inline", "atom", "defining", "code", "tableRole", "summary"];
62150
62250
  const markKeys = ["group", "inclusive", "excludes", "spanning", "code"];
62151
62251
  function mapAttributes(attrs) {
@@ -64148,9 +64248,8 @@ Please report this to https://github.com/markedjs/marked.`, e) {
64148
64248
  try {
64149
64249
  const jsonObj = json;
64150
64250
  const attrs = jsonObj.attrs;
64151
- const hasBody = attrs && "bodySectPr" in attrs;
64152
64251
  const converter = this.converter;
64153
- if (!hasBody && converter && converter.bodySectPr) {
64252
+ if (converter && converter.bodySectPr) {
64154
64253
  jsonObj.attrs = attrs || {};
64155
64254
  jsonObj.attrs.bodySectPr = converter.bodySectPr;
64156
64255
  }
@@ -64779,7 +64878,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
64779
64878
  * Process collaboration migrations
64780
64879
  */
64781
64880
  processCollaborationMigrations() {
64782
- console.debug("[checkVersionMigrations] Current editor version", "1.3.0-next.9");
64881
+ console.debug("[checkVersionMigrations] Current editor version", "1.3.0");
64783
64882
  if (!this.options.ydoc) return;
64784
64883
  const metaMap = this.options.ydoc.getMap("meta");
64785
64884
  let docVersion = metaMap.get("version");
@@ -87066,6 +87165,13 @@ ${l}
87066
87165
  );
87067
87166
  }
87068
87167
  });
87168
+ if ((config2.mode === "original" || config2.mode === "final") && config2.enabled) {
87169
+ filtered.forEach((run2) => {
87170
+ if (isTextRun$1(run2) && run2.trackedChange && (run2.trackedChange.kind === "insert" || run2.trackedChange.kind === "delete")) {
87171
+ delete run2.trackedChange;
87172
+ }
87173
+ });
87174
+ }
87069
87175
  }
87070
87176
  return filtered;
87071
87177
  };
@@ -90091,7 +90197,16 @@ ${l}
90091
90197
  if (!value || typeof value !== "object") return;
90092
90198
  return normalizePxIndent(value) ?? convertIndentTwipsToPx(value);
90093
90199
  };
90094
- const normalizedIndent = normalizeIndentObject(attrs.indent) ?? convertIndentTwipsToPx(paragraphProps.indent) ?? convertIndentTwipsToPx(hydrated?.indent) ?? normalizeParagraphIndent(attrs.textIndent);
90200
+ const hydratedIndentPx = convertIndentTwipsToPx(hydrated?.indent);
90201
+ const paragraphIndentPx = convertIndentTwipsToPx(paragraphProps.indent);
90202
+ const textIndentPx = normalizeParagraphIndent(attrs.textIndent);
90203
+ const attrsIndentPx = normalizeIndentObject(attrs.indent);
90204
+ const indentChain = [];
90205
+ if (hydratedIndentPx) indentChain.push({ indent: hydratedIndentPx });
90206
+ if (paragraphIndentPx) indentChain.push({ indent: paragraphIndentPx });
90207
+ if (textIndentPx) indentChain.push({ indent: textIndentPx });
90208
+ if (attrsIndentPx) indentChain.push({ indent: attrsIndentPx });
90209
+ const normalizedIndent = indentChain.length ? combineIndentProperties(indentChain).indent : void 0;
90095
90210
  const unwrapTabStops = (tabStops) => {
90096
90211
  if (!Array.isArray(tabStops)) {
90097
90212
  return void 0;
@@ -95370,10 +95485,13 @@ ${l}
95370
95485
  };
95371
95486
  }
95372
95487
  const originX = currentLine.width;
95373
- const { target, nextIndex, stop } = getNextTabStopPx(currentLine.width, tabStops, tabStopCursor);
95488
+ const effectiveIndent = lines.length === 0 ? indentLeft + rawFirstLineOffset : indentLeft;
95489
+ const absCurrentX = currentLine.width + effectiveIndent;
95490
+ const { target, nextIndex, stop } = getNextTabStopPx(absCurrentX, tabStops, tabStopCursor);
95374
95491
  tabStopCursor = nextIndex;
95375
- const clampedTarget = Math.min(target, currentLine.maxWidth);
95376
- const tabAdvance = Math.max(0, clampedTarget - currentLine.width);
95492
+ const maxAbsWidth = currentLine.maxWidth + effectiveIndent;
95493
+ const clampedTarget = Math.min(target, maxAbsWidth);
95494
+ const tabAdvance = Math.max(0, clampedTarget - absCurrentX);
95377
95495
  currentLine.width = roundValue(currentLine.width + tabAdvance);
95378
95496
  run2.width = tabAdvance;
95379
95497
  currentLine.maxFontSize = Math.max(currentLine.maxFontSize, 12);
@@ -95381,8 +95499,9 @@ ${l}
95381
95499
  currentLine.toChar = 1;
95382
95500
  if (stop && stop.leader && stop.leader !== "none") {
95383
95501
  const leaderStyle = stop.leader;
95384
- const from2 = Math.min(originX, clampedTarget);
95385
- const to = Math.max(originX, clampedTarget);
95502
+ const relativeTarget = clampedTarget - effectiveIndent;
95503
+ const from2 = Math.min(originX, relativeTarget);
95504
+ const to = Math.max(originX, relativeTarget);
95386
95505
  if (!currentLine.leaders) currentLine.leaders = [];
95387
95506
  currentLine.leaders.push({ from: from2, to, style: leaderStyle });
95388
95507
  }
@@ -95391,27 +95510,28 @@ ${l}
95391
95510
  if (stop.val === "end" || stop.val === "center" || stop.val === "decimal") {
95392
95511
  const groupMeasure = measureTabAlignmentGroup(runIndex + 1, runsToProcess, ctx2, decimalSeparator);
95393
95512
  if (groupMeasure.totalWidth > 0) {
95513
+ const relativeTarget = clampedTarget - effectiveIndent;
95394
95514
  let groupStartX;
95395
95515
  if (stop.val === "end") {
95396
- groupStartX = Math.max(0, clampedTarget - groupMeasure.totalWidth);
95516
+ groupStartX = Math.max(0, relativeTarget - groupMeasure.totalWidth);
95397
95517
  } else if (stop.val === "center") {
95398
- groupStartX = Math.max(0, clampedTarget - groupMeasure.totalWidth / 2);
95518
+ groupStartX = Math.max(0, relativeTarget - groupMeasure.totalWidth / 2);
95399
95519
  } else {
95400
95520
  const beforeDecimal = groupMeasure.beforeDecimalWidth ?? groupMeasure.totalWidth;
95401
- groupStartX = Math.max(0, clampedTarget - beforeDecimal);
95521
+ groupStartX = Math.max(0, relativeTarget - beforeDecimal);
95402
95522
  }
95403
95523
  activeTabGroup = {
95404
95524
  measure: groupMeasure,
95405
95525
  startX: groupStartX,
95406
95526
  currentX: groupStartX,
95407
- target: clampedTarget,
95527
+ target: relativeTarget,
95408
95528
  val: stop.val
95409
95529
  };
95410
95530
  currentLine.width = roundValue(groupStartX);
95411
95531
  }
95412
95532
  pendingTabAlignment = null;
95413
95533
  } else {
95414
- pendingTabAlignment = { target: clampedTarget, val: stop.val };
95534
+ pendingTabAlignment = { target: clampedTarget - effectiveIndent, val: stop.val };
95415
95535
  }
95416
95536
  } else {
95417
95537
  pendingTabAlignment = null;
@@ -96052,10 +96172,13 @@ ${l}
96052
96172
  };
96053
96173
  }
96054
96174
  const originX = currentLine.width;
96055
- const { target, nextIndex, stop } = getNextTabStopPx(currentLine.width, tabStops, tabStopCursor);
96175
+ const effectiveIndent = lines.length === 0 ? indentLeft + rawFirstLineOffset : indentLeft;
96176
+ const absCurrentX = currentLine.width + effectiveIndent;
96177
+ const { target, nextIndex, stop } = getNextTabStopPx(absCurrentX, tabStops, tabStopCursor);
96056
96178
  tabStopCursor = nextIndex;
96057
- const clampedTarget = Math.min(target, currentLine.maxWidth);
96058
- const tabAdvance = Math.max(0, clampedTarget - currentLine.width);
96179
+ const maxAbsWidth = currentLine.maxWidth + effectiveIndent;
96180
+ const clampedTarget = Math.min(target, maxAbsWidth);
96181
+ const tabAdvance = Math.max(0, clampedTarget - absCurrentX);
96059
96182
  currentLine.width = roundValue(currentLine.width + tabAdvance);
96060
96183
  currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run2);
96061
96184
  currentLine.maxFontSize = Math.max(currentLine.maxFontSize, run2.fontSize);
@@ -96064,14 +96187,15 @@ ${l}
96064
96187
  charPosInRun += 1;
96065
96188
  if (stop) {
96066
96189
  validateTabStopVal(stop);
96067
- pendingTabAlignment = { target: clampedTarget, val: stop.val };
96190
+ pendingTabAlignment = { target: clampedTarget - effectiveIndent, val: stop.val };
96068
96191
  } else {
96069
96192
  pendingTabAlignment = null;
96070
96193
  }
96071
96194
  if (stop && stop.leader && stop.leader !== "none" && stop.leader !== "middleDot") {
96072
96195
  const leaderStyle = stop.leader;
96073
- const from2 = Math.min(originX, clampedTarget);
96074
- const to = Math.max(originX, clampedTarget);
96196
+ const relativeTarget = clampedTarget - effectiveIndent;
96197
+ const from2 = Math.min(originX, relativeTarget);
96198
+ const to = Math.max(originX, relativeTarget);
96075
96199
  if (!currentLine.leaders) currentLine.leaders = [];
96076
96200
  currentLine.leaders.push({ from: from2, to, style: leaderStyle });
96077
96201
  }
@@ -96347,7 +96471,11 @@ ${l}
96347
96471
  }
96348
96472
  async function measureImageBlock(block, constraints) {
96349
96473
  const intrinsic = getIntrinsicImageSize(block, constraints.maxWidth);
96350
- const maxWidth = constraints.maxWidth > 0 ? constraints.maxWidth : intrinsic.width;
96474
+ const isBlockBehindDoc = block.anchor?.behindDoc;
96475
+ const isBlockWrapBehindDoc = block.wrap?.type === "None" && block.wrap?.behindDoc;
96476
+ const bypassWidthConstraint = isBlockBehindDoc || isBlockWrapBehindDoc;
96477
+ const isWidthConstraintBypassed = bypassWidthConstraint || constraints.maxWidth <= 0;
96478
+ const maxWidth = isWidthConstraintBypassed ? intrinsic.width : constraints.maxWidth;
96351
96479
  const hasNegativeVerticalPosition = block.anchor?.isAnchored && (typeof block.anchor?.offsetV === "number" && block.anchor.offsetV < 0 || typeof block.margin?.top === "number" && block.margin.top < 0);
96352
96480
  const maxHeight = hasNegativeVerticalPosition || !constraints.maxHeight || constraints.maxHeight <= 0 ? Infinity : constraints.maxHeight;
96353
96481
  const widthScale = maxWidth / intrinsic.width;
@@ -97514,9 +97642,10 @@ ${l}
97514
97642
  throw new TypeError("[PresentationEditor] setTrackedChangesOverrides expects an object or undefined");
97515
97643
  }
97516
97644
  if (overrides !== void 0) {
97517
- if (overrides.mode !== void 0 && !["review", "simple", "original"].includes(overrides.mode)) {
97645
+ const validModes = ["review", "original", "final", "off"];
97646
+ if (overrides.mode !== void 0 && !validModes.includes(overrides.mode)) {
97518
97647
  throw new TypeError(
97519
- `[PresentationEditor] Invalid tracked changes mode "${overrides.mode}". Must be one of: review, simple, original`
97648
+ `[PresentationEditor] Invalid tracked changes mode "${overrides.mode}". Must be one of: ${validModes.join(", ")}`
97520
97649
  );
97521
97650
  }
97522
97651
  if (overrides.enabled !== void 0 && typeof overrides.enabled !== "boolean") {
@@ -101423,7 +101552,7 @@ ${l}
101423
101552
  const zoom = this.#layoutOptions.zoom ?? 1;
101424
101553
  const layoutMode = this.#layoutOptions.layoutMode ?? "vertical";
101425
101554
  const pages = this.#layoutState.layout?.pages;
101426
- const pageGap = this.#layoutState.layout?.pageGap ?? this.#getEffectivePageGap();
101555
+ const pageGap = this.#getEffectivePageGap();
101427
101556
  const defaultWidth = this.#layoutOptions.pageSize?.w ?? DEFAULT_PAGE_SIZE.w;
101428
101557
  const defaultHeight = this.#layoutOptions.pageSize?.h ?? DEFAULT_PAGE_SIZE.h;
101429
101558
  let maxWidth = defaultWidth;
@@ -104531,7 +104660,11 @@ ${l}
104531
104660
  */
104532
104661
  clearDocument: () => ({ commands: commands2 }) => {
104533
104662
  return commands2.setContent("<p></p>");
104534
- }
104663
+ },
104664
+ /**
104665
+ * Set section page margins (top/right/bottom/left) for the section at the current selection.
104666
+ */
104667
+ setSectionPageMarginsAtSelection
104535
104668
  };
104536
104669
  }
104537
104670
  });
@@ -105185,12 +105318,18 @@ ${l}
105185
105318
  return null;
105186
105319
  }
105187
105320
  function extractParagraphContext(node2, startPos, helpers2, depth = 0) {
105188
- const paragraphProperties = getResolvedParagraphProperties(node2) ?? {};
105321
+ const paragraphProperties = getResolvedParagraphProperties(node2) ?? node2.attrs?.paragraphProperties ?? {};
105189
105322
  const alignmentAliases = { left: "start", right: "end" };
105190
105323
  let tabStops = [];
105191
105324
  if (Array.isArray(paragraphProperties.tabStops)) {
105192
105325
  tabStops = paragraphProperties.tabStops.map((stop) => {
105193
105326
  const ref2 = stop?.tab;
105327
+ if (!ref2 && stop?.pos != null) {
105328
+ return {
105329
+ ...stop,
105330
+ pos: twipsToPixels(Number(stop.pos) || 0)
105331
+ };
105332
+ }
105194
105333
  if (!ref2) return stop || null;
105195
105334
  const rawType = ref2.tabType || "start";
105196
105335
  const mappedVal = alignmentAliases[rawType] || rawType;
@@ -106456,6 +106595,13 @@ ${l}
106456
106595
  pos: entry.pos,
106457
106596
  nodeSize: node2.nodeSize
106458
106597
  });
106598
+ } else if (node2.type.name === "lineBreak" || node2.type.name === "hardBreak") {
106599
+ spans.push({
106600
+ type: node2.type.name,
106601
+ spanId,
106602
+ pos: entry.pos,
106603
+ nodeSize: node2.nodeSize
106604
+ });
106459
106605
  } else if (node2.type.name === "text") {
106460
106606
  spans.push({
106461
106607
  type: "text",
@@ -106505,6 +106651,7 @@ ${l}
106505
106651
  paragraphNode
106506
106652
  } = request;
106507
106653
  const tabs = {};
106654
+ const leftIndentPx = request.indents?.left ?? 0;
106508
106655
  let currentX = indentWidth;
106509
106656
  const measureText2 = (span) => {
106510
106657
  if (view && typeof span.from === "number" && typeof span.to === "number") {
@@ -106517,6 +106664,8 @@ ${l}
106517
106664
  const span = spans[i2];
106518
106665
  if (span.type === "text") {
106519
106666
  currentX += measureText2(span);
106667
+ } else if (span.type === "lineBreak" || span.type === "hardBreak") {
106668
+ currentX = leftIndentPx;
106520
106669
  } else if (span.type === "tab") {
106521
106670
  const followingText = collectFollowingText(spans, i2 + 1);
106522
106671
  let measureTextCallback;
@@ -106612,7 +106761,7 @@ ${l}
106612
106761
  let text2 = "";
106613
106762
  for (let i2 = startIndex; i2 < spans.length; i2++) {
106614
106763
  const span = spans[i2];
106615
- if (span.type === "tab") break;
106764
+ if (span.type === "tab" || span.type === "lineBreak" || span.type === "hardBreak") break;
106616
106765
  if (span.type === "text") text2 += span.text || "";
106617
106766
  }
106618
106767
  return text2;
@@ -106622,7 +106771,7 @@ ${l}
106622
106771
  let to = null;
106623
106772
  for (let i2 = startIndex; i2 < spans.length; i2++) {
106624
106773
  const span = spans[i2];
106625
- if (span.type === "tab") break;
106774
+ if (span.type === "tab" || span.type === "lineBreak" || span.type === "hardBreak") break;
106626
106775
  if (span.type === "text" && typeof span.from === "number" && typeof span.to === "number") {
106627
106776
  if (from2 === null) from2 = span.from;
106628
106777
  to = span.to;
@@ -111040,6 +111189,10 @@ ${l}
111040
111189
  }
111041
111190
  const hasAnchorData = Boolean(anchorData);
111042
111191
  const hasMarginOffsets = marginOffset?.horizontal != null || marginOffset?.top != null;
111192
+ const isWrapBehindDoc = wrap2?.attrs?.behindDoc;
111193
+ const isAnchorBehindDoc = anchorData?.behindDoc;
111194
+ const isBehindDocAnchor = wrap2?.type === "None" && (isWrapBehindDoc || isAnchorBehindDoc);
111195
+ const isAbsolutelyPositioned = style2.includes("position: absolute;");
111043
111196
  if (hasAnchorData) {
111044
111197
  switch (anchorData.hRelativeFrom) {
111045
111198
  case "page":
@@ -111067,7 +111220,6 @@ ${l}
111067
111220
  style2 += "float: left;";
111068
111221
  }
111069
111222
  } else if (!anchorData.alignH && marginOffset?.horizontal != null) {
111070
- const isAbsolutelyPositioned = style2.includes("position: absolute;");
111071
111223
  if (isAbsolutelyPositioned) {
111072
111224
  style2 += `left: ${baseHorizontal}px;`;
111073
111225
  style2 += "max-width: none;";
@@ -111081,7 +111233,8 @@ ${l}
111081
111233
  const relativeFromPageV = anchorData?.vRelativeFrom === "page";
111082
111234
  const relativeFromMarginV = anchorData?.vRelativeFrom === "margin";
111083
111235
  const maxMarginV = 500;
111084
- const baseTop = Math.max(0, marginOffset?.top ?? 0);
111236
+ const allowNegativeTopOffset = isBehindDocAnchor;
111237
+ const baseTop = allowNegativeTopOffset ? marginOffset?.top ?? 0 : Math.max(0, marginOffset?.top ?? 0);
111085
111238
  let rotationHorizontal = 0;
111086
111239
  let rotationTop = 0;
111087
111240
  const { rotation: rotation2 } = transformData ?? {};
@@ -111100,7 +111253,10 @@ ${l}
111100
111253
  margin.left += horizontal;
111101
111254
  }
111102
111255
  }
111103
- if (top2 && !relativeFromMarginV) {
111256
+ const appliedTopViaStyle = isAbsolutelyPositioned && allowNegativeTopOffset && !relativeFromMarginV;
111257
+ if (appliedTopViaStyle) {
111258
+ style2 += `top: ${top2}px;`;
111259
+ } else if (top2 && !relativeFromMarginV) {
111104
111260
  if (relativeFromPageV && top2 >= maxMarginV) margin.top += maxMarginV;
111105
111261
  else margin.top += top2;
111106
111262
  }
@@ -111113,6 +111269,9 @@ ${l}
111113
111269
  }
111114
111270
  if (margin.top) style2 += `margin-top: ${margin.top}px;`;
111115
111271
  if (margin.bottom) style2 += `margin-bottom: ${margin.bottom}px;`;
111272
+ if (isBehindDocAnchor) {
111273
+ style2 += "max-width: none;";
111274
+ }
111116
111275
  const finalAttributes = { ...htmlAttributes };
111117
111276
  if (style2) {
111118
111277
  const existingStyle = finalAttributes.style || "";
@@ -125601,7 +125760,7 @@ ${style2}
125601
125760
  };
125602
125761
  return ResizeObserverController2;
125603
125762
  })();
125604
- var ResizeObserver = (function() {
125763
+ var ResizeObserver$1 = (function() {
125605
125764
  function ResizeObserver2(callback) {
125606
125765
  if (arguments.length === 0) {
125607
125766
  throw new TypeError("Failed to construct 'ResizeObserver': 1 argument required, but only 0 present.");
@@ -125640,7 +125799,7 @@ ${style2}
125640
125799
  class ResizeObserverDelegate {
125641
125800
  constructor() {
125642
125801
  this.handleResize = this.handleResize.bind(this);
125643
- this.observer = new (typeof window !== "undefined" && window.ResizeObserver || ResizeObserver)(this.handleResize);
125802
+ this.observer = new (typeof window !== "undefined" && window.ResizeObserver || ResizeObserver$1)(this.handleResize);
125644
125803
  this.elHandlersMap = /* @__PURE__ */ new Map();
125645
125804
  }
125646
125805
  handleResize(entries) {
@@ -138553,6 +138712,31 @@ ${style2}
138553
138712
  },
138554
138713
  { immediate: true, deep: true }
138555
138714
  );
138715
+ watch(
138716
+ () => props.options?.rulerContainer,
138717
+ () => {
138718
+ nextTick(() => {
138719
+ syncRulerOffset();
138720
+ setupRulerObservers();
138721
+ });
138722
+ },
138723
+ { immediate: true }
138724
+ );
138725
+ watch(
138726
+ rulersVisible,
138727
+ (visible) => {
138728
+ nextTick(() => {
138729
+ if (visible) {
138730
+ syncRulerOffset();
138731
+ setupRulerObservers();
138732
+ } else {
138733
+ rulerHostStyle.value = {};
138734
+ cleanupRulerObservers();
138735
+ }
138736
+ });
138737
+ },
138738
+ { immediate: true }
138739
+ );
138556
138740
  const containerStyle = computed(() => {
138557
138741
  let maxWidth = 8.5 * 96;
138558
138742
  const ed = editor.value;
@@ -138577,6 +138761,71 @@ ${style2}
138577
138761
  minWidth: `${scaledWidth}px`
138578
138762
  };
138579
138763
  });
138764
+ const rulerHostStyle = ref({});
138765
+ const rulerContainerEl = ref(null);
138766
+ let editorResizeObserver = null;
138767
+ let rulerContainerResizeObserver = null;
138768
+ let layoutUpdatedHandler = null;
138769
+ const resolveRulerContainer = () => {
138770
+ const container = props.options?.rulerContainer;
138771
+ if (!container) return null;
138772
+ if (typeof container === "string") {
138773
+ const doc2 = editorWrapper.value?.ownerDocument ?? document;
138774
+ return doc2.querySelector(container);
138775
+ }
138776
+ return container instanceof HTMLElement ? container : null;
138777
+ };
138778
+ const getViewportRect2 = () => {
138779
+ const host = editorWrapper.value;
138780
+ if (!host) return null;
138781
+ const viewport2 = host.querySelector(".presentation-editor__viewport");
138782
+ const target = viewport2 ?? host;
138783
+ return target.getBoundingClientRect();
138784
+ };
138785
+ const syncRulerOffset = () => {
138786
+ if (!rulersVisible.value) {
138787
+ rulerHostStyle.value = {};
138788
+ return;
138789
+ }
138790
+ rulerContainerEl.value = resolveRulerContainer();
138791
+ if (!rulerContainerEl.value) {
138792
+ rulerHostStyle.value = {};
138793
+ return;
138794
+ }
138795
+ const viewportRect = getViewportRect2();
138796
+ if (!viewportRect) return;
138797
+ const hostRect = rulerContainerEl.value.getBoundingClientRect();
138798
+ const paddingLeft = Math.max(0, viewportRect.left - hostRect.left);
138799
+ const paddingRight = Math.max(0, hostRect.right - viewportRect.right);
138800
+ rulerHostStyle.value = {
138801
+ paddingLeft: `${paddingLeft}px`,
138802
+ paddingRight: `${paddingRight}px`
138803
+ };
138804
+ };
138805
+ const cleanupRulerObservers = () => {
138806
+ if (editorResizeObserver) {
138807
+ editorResizeObserver.disconnect();
138808
+ editorResizeObserver = null;
138809
+ }
138810
+ if (rulerContainerResizeObserver) {
138811
+ rulerContainerResizeObserver.disconnect();
138812
+ rulerContainerResizeObserver = null;
138813
+ }
138814
+ };
138815
+ const setupRulerObservers = () => {
138816
+ cleanupRulerObservers();
138817
+ if (typeof ResizeObserver === "undefined") return;
138818
+ const viewportHost = editorWrapper.value;
138819
+ const rulerHost = resolveRulerContainer();
138820
+ if (viewportHost) {
138821
+ editorResizeObserver = new ResizeObserver(() => syncRulerOffset());
138822
+ editorResizeObserver.observe(viewportHost);
138823
+ }
138824
+ if (rulerHost) {
138825
+ rulerContainerResizeObserver = new ResizeObserver(() => syncRulerOffset());
138826
+ rulerContainerResizeObserver.observe(rulerHost);
138827
+ }
138828
+ };
138580
138829
  const message = useMessage();
138581
138830
  const editorWrapper = ref(null);
138582
138831
  const editorElem = ref(null);
@@ -138888,7 +139137,7 @@ ${style2}
138888
139137
  presentationEditor.on("imageDeselected", () => {
138889
139138
  clearSelectedImage();
138890
139139
  });
138891
- presentationEditor.on("layoutUpdated", () => {
139140
+ layoutUpdatedHandler = () => {
138892
139141
  if (imageResizeState.visible && imageResizeState.blockId) {
138893
139142
  const escapedBlockId = CSS.escape(imageResizeState.blockId);
138894
139143
  const newElement = editorElem.value?.querySelector(
@@ -138921,13 +139170,17 @@ ${style2}
138921
139170
  clearSelectedImage();
138922
139171
  }
138923
139172
  }
138924
- });
139173
+ nextTick(() => syncRulerOffset());
139174
+ };
139175
+ presentationEditor.on("layoutUpdated", layoutUpdatedHandler);
138925
139176
  zoomChangeHandler = ({ zoom }) => {
138926
139177
  currentZoom.value = zoom;
139178
+ nextTick(() => syncRulerOffset());
138927
139179
  };
138928
139180
  presentationEditor.on("zoomChange", zoomChangeHandler);
138929
139181
  if (typeof presentationEditor.zoom === "number") {
138930
139182
  currentZoom.value = presentationEditor.zoom;
139183
+ nextTick(() => syncRulerOffset());
138931
139184
  }
138932
139185
  }
138933
139186
  editor.value.on("paginationUpdate", () => {
@@ -138987,6 +139240,11 @@ ${style2}
138987
139240
  onMounted(() => {
138988
139241
  initializeData();
138989
139242
  if (props.options?.suppressSkeletonLoader || !props.options?.collaborationProvider) editorReady.value = true;
139243
+ window.addEventListener("resize", syncRulerOffset, { passive: true });
139244
+ nextTick(() => {
139245
+ syncRulerOffset();
139246
+ setupRulerObservers();
139247
+ });
138990
139248
  });
138991
139249
  const handleMarginClick = (event) => {
138992
139250
  if (event.button !== 0) {
@@ -139001,10 +139259,14 @@ ${style2}
139001
139259
  const handleMarginChange = ({ side, value }) => {
139002
139260
  const base2 = activeEditor.value;
139003
139261
  if (!base2) return;
139004
- const pageStyles2 = base2.getPageStyles();
139005
- const { pageMargins } = pageStyles2;
139006
- const update = { ...pageMargins, [side]: value };
139007
- base2?.updatePageStyle({ pageMargins: update });
139262
+ const payload = side === "left" ? { leftInches: value } : side === "right" ? { rightInches: value } : side === "top" ? { topInches: value } : side === "bottom" ? { bottomInches: value } : {};
139263
+ const didUpdateSection = typeof base2.commands?.setSectionPageMarginsAtSelection === "function" ? base2.commands.setSectionPageMarginsAtSelection(payload) : false;
139264
+ if (!didUpdateSection) {
139265
+ const pageStyles2 = base2.getPageStyles();
139266
+ const { pageMargins } = pageStyles2;
139267
+ const update = { ...pageMargins, [side]: value };
139268
+ base2?.updatePageStyle({ pageMargins: update });
139269
+ }
139008
139270
  };
139009
139271
  onBeforeUnmount(() => {
139010
139272
  stopPolling();
@@ -139013,6 +139275,12 @@ ${style2}
139013
139275
  editor.value.off("zoomChange", zoomChangeHandler);
139014
139276
  zoomChangeHandler = null;
139015
139277
  }
139278
+ if (editor.value instanceof PresentationEditor && layoutUpdatedHandler) {
139279
+ editor.value.off("layoutUpdated", layoutUpdatedHandler);
139280
+ layoutUpdatedHandler = null;
139281
+ }
139282
+ cleanupRulerObservers();
139283
+ window.removeEventListener("resize", syncRulerOffset);
139016
139284
  editor.value?.destroy();
139017
139285
  editor.value = null;
139018
139286
  });
@@ -139024,18 +139292,28 @@ ${style2}
139024
139292
  __props.options.rulerContainer && rulersVisible.value && !!activeEditor.value ? (openBlock(), createBlock(Teleport, {
139025
139293
  key: 0,
139026
139294
  to: __props.options.rulerContainer
139295
+ }, [
139296
+ createBaseVNode("div", {
139297
+ class: "ruler-host",
139298
+ style: normalizeStyle(rulerHostStyle.value)
139299
+ }, [
139300
+ createVNode(Ruler, {
139301
+ class: "ruler superdoc-ruler",
139302
+ editor: activeEditor.value,
139303
+ onMarginChange: handleMarginChange
139304
+ }, null, 8, ["editor"])
139305
+ ], 4)
139306
+ ], 8, ["to"])) : rulersVisible.value && !!activeEditor.value ? (openBlock(), createElementBlock("div", {
139307
+ key: 1,
139308
+ class: "ruler-host",
139309
+ style: normalizeStyle(rulerHostStyle.value)
139027
139310
  }, [
139028
139311
  createVNode(Ruler, {
139029
- class: "ruler superdoc-ruler",
139312
+ class: "ruler",
139030
139313
  editor: activeEditor.value,
139031
139314
  onMarginChange: handleMarginChange
139032
139315
  }, null, 8, ["editor"])
139033
- ], 8, ["to"])) : rulersVisible.value && !!activeEditor.value ? (openBlock(), createBlock(Ruler, {
139034
- key: 1,
139035
- class: "ruler",
139036
- editor: activeEditor.value,
139037
- onMarginChange: handleMarginChange
139038
- }, null, 8, ["editor"])) : createCommentVNode("", true),
139316
+ ], 4)) : createCommentVNode("", true),
139039
139317
  createBaseVNode("div", {
139040
139318
  class: "super-editor",
139041
139319
  ref_key: "editorWrapper",
@@ -139140,7 +139418,7 @@ ${style2}
139140
139418
  };
139141
139419
  }
139142
139420
  });
139143
- const SuperEditor = /* @__PURE__ */ _export_sfc(_sfc_main$j, [["__scopeId", "data-v-8dd4cf59"]]);
139421
+ const SuperEditor = /* @__PURE__ */ _export_sfc(_sfc_main$j, [["__scopeId", "data-v-f5c4f915"]]);
139144
139422
  const _hoisted_1$h = ["innerHTML"];
139145
139423
  const _sfc_main$i = {
139146
139424
  __name: "SuperInput",
@@ -143313,6 +143591,7 @@ ${reason}`);
143313
143591
  commentsStore.proxy = proxy;
143314
143592
  const { isHighContrastMode: isHighContrastMode2 } = useHighContrastMode();
143315
143593
  const { uiFontFamily } = useUiFontFamily();
143594
+ const isViewingMode = () => proxy?.$superdoc?.config?.documentMode === "viewing";
143316
143595
  const commentsModuleConfig = computed(() => {
143317
143596
  const config2 = modules.comments;
143318
143597
  if (config2 === false || config2 == null) return null;
@@ -143407,6 +143686,10 @@ ${reason}`);
143407
143686
  const commentsConfig = proxy.$superdoc.config.modules?.comments;
143408
143687
  if (!commentsConfig || commentsConfig === false) return;
143409
143688
  if (!positions || Object.keys(positions).length === 0) return;
143689
+ if (isViewingMode()) {
143690
+ commentsStore.clearEditorCommentPositions?.();
143691
+ return;
143692
+ }
143410
143693
  const mappedPositions = presentationEditor.getCommentBounds(positions, layers.value);
143411
143694
  handleEditorLocationsUpdate(mappedPositions);
143412
143695
  });
@@ -143426,6 +143709,13 @@ ${reason}`);
143426
143709
  const onEditorSelectionChange = ({ editor, transaction }) => {
143427
143710
  if (skipSelectionUpdate.value) {
143428
143711
  skipSelectionUpdate.value = false;
143712
+ if (isViewingMode()) {
143713
+ resetSelection();
143714
+ }
143715
+ return;
143716
+ }
143717
+ if (isViewingMode()) {
143718
+ resetSelection();
143429
143719
  return;
143430
143720
  }
143431
143721
  const { documentId } = editor.options;
@@ -143604,6 +143894,10 @@ ${reason}`);
143604
143894
  const onEditorCommentLocationsUpdate = (doc2, { allCommentIds: activeThreadId, allCommentPositions } = {}) => {
143605
143895
  const commentsConfig = proxy.$superdoc.config.modules?.comments;
143606
143896
  if (!commentsConfig || commentsConfig === false) return;
143897
+ if (isViewingMode()) {
143898
+ commentsStore.clearEditorCommentPositions?.();
143899
+ return;
143900
+ }
143607
143901
  const presentation = PresentationEditor.getInstance(doc2.id);
143608
143902
  if (!presentation) {
143609
143903
  handleEditorLocationsUpdate(allCommentPositions, activeThreadId);
@@ -143659,11 +143953,12 @@ ${reason}`);
143659
143953
  };
143660
143954
  const isCommentsEnabled = computed(() => Boolean(commentsModuleConfig.value));
143661
143955
  const showCommentsSidebar = computed(() => {
143956
+ if (isViewingMode()) return false;
143662
143957
  return pendingComment.value || getFloatingComments.value?.length > 0 && isReady.value && layers.value && isCommentsEnabled.value && !isCommentsListVisible.value;
143663
143958
  });
143664
143959
  const showToolsFloatingMenu = computed(() => {
143665
143960
  if (!isCommentsEnabled.value) return false;
143666
- return toolsMenuPosition.top && !getConfig2.value?.readOnly;
143961
+ return selectionPosition.value && toolsMenuPosition.top && !getConfig2.value?.readOnly;
143667
143962
  });
143668
143963
  computed(() => {
143669
143964
  if (!isCommentsEnabled.value) return false;
@@ -143711,6 +144006,10 @@ ${reason}`);
143711
144006
  return style2;
143712
144007
  });
143713
144008
  const handleSelectionChange = (selection) => {
144009
+ if (isViewingMode()) {
144010
+ resetSelection();
144011
+ return;
144012
+ }
143714
144013
  if (!selection.selectionBounds || !isCommentsEnabled.value) return;
143715
144014
  resetSelection();
143716
144015
  const isMobileView = window.matchMedia("(max-width: 768px)").matches;
@@ -143736,12 +144035,14 @@ ${reason}`);
143736
144035
  };
143737
144036
  const resetSelection = () => {
143738
144037
  selectionPosition.value = null;
144038
+ toolsMenuPosition.top = null;
143739
144039
  };
143740
144040
  const updateSelection2 = ({ startX, startY, x: x2, y: y2, source }) => {
143741
144041
  const hasStartCoords = typeof startX === "number" || typeof startY === "number";
143742
144042
  const hasEndCoords = typeof x2 === "number" || typeof y2 === "number";
143743
144043
  if (!hasStartCoords && !hasEndCoords) {
143744
- return selectionPosition.value = null;
144044
+ resetSelection();
144045
+ return;
143745
144046
  }
143746
144047
  if (!selectionPosition.value) {
143747
144048
  if (startY == null || startX == null) return;
@@ -143994,7 +144295,7 @@ ${reason}`);
143994
144295
  };
143995
144296
  }
143996
144297
  };
143997
- const App = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-1e96f708"]]);
144298
+ const App = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-5196811d"]]);
143998
144299
  const createSuperdocVueApp = () => {
143999
144300
  const app = createApp(App);
144000
144301
  const pinia = createPinia();
@@ -144178,7 +144479,7 @@ ${reason}`);
144178
144479
  this.config.colors = shuffleArray(this.config.colors);
144179
144480
  this.userColorMap = /* @__PURE__ */ new Map();
144180
144481
  this.colorIndex = 0;
144181
- this.version = "1.3.0-next.9";
144482
+ this.version = "1.3.0";
144182
144483
  this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
144183
144484
  this.superdocId = config2.superdocId || v4();
144184
144485
  this.colors = this.config.colors;