@harbour-enterprises/superdoc 1.3.0-next.9 → 1.3.1-next.1

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-BuhT_Z5G.cjs");
4
+ const superEditor_converter = require("./SuperConverter-rwP6nlvC.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,
@@ -15351,7 +15451,7 @@ const canUseDOM = () => {
15351
15451
  return false;
15352
15452
  }
15353
15453
  };
15354
- const summaryVersion = "1.3.0-next.9";
15454
+ const summaryVersion = "1.3.1-next.1";
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.9");
18086
+ console.debug("[checkVersionMigrations] Current editor version", "1.3.1-next.1");
17988
18087
  if (!this.options.ydoc) return;
17989
18088
  const metaMap = this.options.ydoc.getMap("meta");
17990
18089
  let docVersion = metaMap.get("version");
@@ -24847,7 +24946,7 @@ function isMinimalWordLayout(value) {
24847
24946
  return true;
24848
24947
  }
24849
24948
  const LIST_MARKER_GAP$2 = 8;
24850
- const DEFAULT_TAB_INTERVAL_PX$2 = 48;
24949
+ const DEFAULT_TAB_INTERVAL_PX$1 = 48;
24851
24950
  const DEFAULT_PAGE_HEIGHT_PX = 1056;
24852
24951
  const DEFAULT_VIRTUALIZED_PAGE_GAP$1 = 72;
24853
24952
  const COMMENT_EXTERNAL_COLOR = "#B1124B";
@@ -25881,7 +25980,7 @@ class DomPainter {
25881
25980
  const textStart = paraIndentLeft + firstLine;
25882
25981
  tabWidth = textStart - currentPos;
25883
25982
  if (tabWidth <= 0) {
25884
- tabWidth = DEFAULT_TAB_INTERVAL_PX$2 - currentPos % DEFAULT_TAB_INTERVAL_PX$2;
25983
+ tabWidth = DEFAULT_TAB_INTERVAL_PX$1 - currentPos % DEFAULT_TAB_INTERVAL_PX$1;
25885
25984
  } else if (tabWidth < LIST_MARKER_GAP$2) {
25886
25985
  tabWidth = LIST_MARKER_GAP$2;
25887
25986
  }
@@ -26033,7 +26132,7 @@ class DomPainter {
26033
26132
  const textStart = paraIndentLeft + firstLine;
26034
26133
  tabWidth = textStart - currentPos;
26035
26134
  if (tabWidth <= 0) {
26036
- tabWidth = DEFAULT_TAB_INTERVAL_PX$2 - currentPos % DEFAULT_TAB_INTERVAL_PX$2;
26135
+ tabWidth = DEFAULT_TAB_INTERVAL_PX$1 - currentPos % DEFAULT_TAB_INTERVAL_PX$1;
26037
26136
  } else if (tabWidth < LIST_MARKER_GAP$2) {
26038
26137
  tabWidth = LIST_MARKER_GAP$2;
26039
26138
  }
@@ -27381,6 +27480,13 @@ class DomPainter {
27381
27480
  const trackedConfig = this.resolveTrackedChangesConfig(block);
27382
27481
  if (runsForLine.length === 0) {
27383
27482
  const span = this.doc.createElement("span");
27483
+ span.classList.add("superdoc-empty-run");
27484
+ if (lineRange.pmStart != null) {
27485
+ span.dataset.pmStart = String(lineRange.pmStart);
27486
+ }
27487
+ if (lineRange.pmEnd != null) {
27488
+ span.dataset.pmEnd = String(lineRange.pmEnd);
27489
+ }
27384
27490
  span.innerHTML = "&nbsp;";
27385
27491
  el.appendChild(span);
27386
27492
  }
@@ -30627,7 +30733,6 @@ const DEFAULT_LIST_INDENT_BASE_PX = 24;
30627
30733
  const DEFAULT_LIST_INDENT_STEP_PX = 24;
30628
30734
  const DEFAULT_LIST_HANGING_PX$1 = 18;
30629
30735
  const SPACE_SUFFIX_GAP_PX = 4;
30630
- const DEFAULT_TAB_INTERVAL_PX$1 = 48;
30631
30736
  function resolveListTextStartPx(wordLayout, indentLeft, firstLine, hanging, measureMarkerText) {
30632
30737
  const marker = wordLayout?.marker;
30633
30738
  if (!marker) {
@@ -30661,9 +30766,13 @@ function resolveListTextStartPx(wordLayout, indentLeft, firstLine, hanging, meas
30661
30766
  return markerStartPos + finalMarkerTextWidth;
30662
30767
  }
30663
30768
  const markerJustification = marker.justification ?? "left";
30769
+ const markerWidthEffective = Math.max(
30770
+ typeof marker.markerBoxWidthPx === "number" && Number.isFinite(marker.markerBoxWidthPx) ? marker.markerBoxWidthPx : 0,
30771
+ finalMarkerTextWidth
30772
+ );
30664
30773
  if (markerJustification !== "left") {
30665
- const gutterWidth = typeof marker.gutterWidthPx === "number" && Number.isFinite(marker.gutterWidthPx) && marker.gutterWidthPx > 0 ? marker.gutterWidthPx : LIST_MARKER_GAP$1;
30666
- return markerStartPos + finalMarkerTextWidth + Math.max(gutterWidth, LIST_MARKER_GAP$1);
30774
+ const gutterWidth2 = typeof marker.gutterWidthPx === "number" && Number.isFinite(marker.gutterWidthPx) && marker.gutterWidthPx > 0 ? marker.gutterWidthPx : LIST_MARKER_GAP$1;
30775
+ return markerStartPos + finalMarkerTextWidth + Math.max(gutterWidth2, LIST_MARKER_GAP$1);
30667
30776
  }
30668
30777
  if (wordLayout?.firstLineIndentMode === true) {
30669
30778
  let targetTabStop;
@@ -30675,12 +30784,12 @@ function resolveListTextStartPx(wordLayout, indentLeft, firstLine, hanging, meas
30675
30784
  }
30676
30785
  }
30677
30786
  }
30678
- const textStartTarget = typeof marker.textStartX === "number" && Number.isFinite(marker.textStartX) ? marker.textStartX : wordLayout.textStartPx;
30787
+ const textStartTarget2 = typeof marker.textStartX === "number" && Number.isFinite(marker.textStartX) ? marker.textStartX : wordLayout.textStartPx;
30679
30788
  let tabWidth2;
30680
30789
  if (targetTabStop !== void 0) {
30681
30790
  tabWidth2 = targetTabStop - currentPos;
30682
- } else if (textStartTarget !== void 0 && Number.isFinite(textStartTarget) && textStartTarget > currentPos) {
30683
- tabWidth2 = textStartTarget - currentPos;
30791
+ } else if (textStartTarget2 !== void 0 && Number.isFinite(textStartTarget2) && textStartTarget2 > currentPos) {
30792
+ tabWidth2 = textStartTarget2 - currentPos;
30684
30793
  } else {
30685
30794
  tabWidth2 = LIST_MARKER_GAP$1;
30686
30795
  }
@@ -30689,14 +30798,21 @@ function resolveListTextStartPx(wordLayout, indentLeft, firstLine, hanging, meas
30689
30798
  }
30690
30799
  return markerStartPos + finalMarkerTextWidth + tabWidth2;
30691
30800
  }
30801
+ const textStartTarget = typeof wordLayout?.textStartPx === "number" && Number.isFinite(wordLayout.textStartPx) ? wordLayout.textStartPx : void 0;
30802
+ const gutterWidth = typeof marker.gutterWidthPx === "number" && Number.isFinite(marker.gutterWidthPx) && marker.gutterWidthPx > 0 ? marker.gutterWidthPx : LIST_MARKER_GAP$1;
30803
+ const currentPosStandard = markerStartPos + markerWidthEffective;
30804
+ if (textStartTarget !== void 0) {
30805
+ const gap = Math.max(textStartTarget - currentPosStandard, gutterWidth);
30806
+ return currentPosStandard + gap;
30807
+ }
30692
30808
  const textStart = indentLeft + firstLine;
30693
- let tabWidth = textStart - currentPos;
30809
+ let tabWidth = textStart - currentPosStandard;
30694
30810
  if (tabWidth <= 0) {
30695
- tabWidth = DEFAULT_TAB_INTERVAL_PX$1 - currentPos % DEFAULT_TAB_INTERVAL_PX$1;
30811
+ tabWidth = gutterWidth;
30696
30812
  } else if (tabWidth < LIST_MARKER_GAP$1) {
30697
- tabWidth = LIST_MARKER_GAP$1;
30813
+ tabWidth = Math.max(tabWidth, gutterWidth);
30698
30814
  }
30699
- return markerStartPos + finalMarkerTextWidth + tabWidth;
30815
+ return currentPosStandard + tabWidth;
30700
30816
  }
30701
30817
  function getWordLayoutConfig(block) {
30702
30818
  if (!block || block.kind !== "paragraph") {
@@ -30725,21 +30841,45 @@ function isListItem(markerWidth, block) {
30725
30841
  return hasHangingIndentPattern;
30726
30842
  }
30727
30843
  function calculateTextStartIndent(params2) {
30728
- const { isFirstLine, isListItem: isListItem2, markerWidth, paraIndentLeft, firstLineIndent, hangingIndent, wordLayout } = params2;
30844
+ const {
30845
+ isFirstLine,
30846
+ isListItem: isListItem2,
30847
+ markerWidth,
30848
+ markerTextWidth,
30849
+ paraIndentLeft,
30850
+ firstLineIndent,
30851
+ hangingIndent,
30852
+ wordLayout
30853
+ } = params2;
30729
30854
  const firstLineOffset = firstLineIndent - hangingIndent;
30730
- const isFirstLineIndentMode = wordLayout?.firstLineIndentMode === true;
30855
+ const effectiveMarkerTextWidth = typeof markerTextWidth === "number" && Number.isFinite(markerTextWidth) && markerTextWidth > 0 ? markerTextWidth : markerWidth;
30731
30856
  let indentAdjust = paraIndentLeft;
30732
- if (isListItem2 && isFirstLine && isFirstLineIndentMode) {
30857
+ if (isListItem2 && isFirstLine) {
30733
30858
  const resolvedTextStart = resolveListTextStartPx(
30734
30859
  wordLayout,
30735
30860
  paraIndentLeft,
30736
30861
  Math.max(firstLineIndent, 0),
30737
30862
  Math.max(hangingIndent, 0),
30738
- () => markerWidth
30739
- // Use provided markerWidth since we don't have canvas access here
30863
+ () => effectiveMarkerTextWidth
30864
+ // Use measured marker text width when available
30740
30865
  );
30741
- const textStartFallback = paraIndentLeft + Math.max(firstLineIndent, 0) + markerWidth;
30742
- indentAdjust = typeof resolvedTextStart === "number" && Number.isFinite(resolvedTextStart) ? resolvedTextStart : textStartFallback;
30866
+ if (typeof resolvedTextStart === "number" && Number.isFinite(resolvedTextStart)) {
30867
+ indentAdjust = resolvedTextStart;
30868
+ } else {
30869
+ const explicitTextStart = wordLayout?.marker?.textStartX ?? wordLayout?.textStartPx;
30870
+ const isStandardHangingList = hangingIndent > 0 && wordLayout?.firstLineIndentMode !== true;
30871
+ const textStartLooksValid = typeof explicitTextStart === "number" && Number.isFinite(explicitTextStart) && (!isStandardHangingList || explicitTextStart > paraIndentLeft);
30872
+ if (textStartLooksValid) {
30873
+ indentAdjust = explicitTextStart;
30874
+ } else if (wordLayout?.firstLineIndentMode === true) {
30875
+ indentAdjust = paraIndentLeft + Math.max(firstLineIndent, 0) + markerWidth;
30876
+ } else if (isStandardHangingList && effectiveMarkerTextWidth > 0) {
30877
+ const markerStartPos = Math.max(0, paraIndentLeft - hangingIndent + firstLineIndent);
30878
+ const gutterWidthCandidate = wordLayout?.gutterWidthPx;
30879
+ const gutterWidth = typeof gutterWidthCandidate === "number" && Number.isFinite(gutterWidthCandidate) ? gutterWidthCandidate : wordLayout?.marker?.gutterWidthPx ?? LIST_MARKER_GAP$1;
30880
+ indentAdjust = markerStartPos + effectiveMarkerTextWidth + gutterWidth;
30881
+ }
30882
+ }
30743
30883
  } else if (isFirstLine && !isListItem2) {
30744
30884
  indentAdjust += firstLineOffset;
30745
30885
  }
@@ -31590,12 +31730,16 @@ function layoutParagraphBlock(ctx2, anchors) {
31590
31730
  const negativeRightIndent = indentRight < 0 ? indentRight : 0;
31591
31731
  const remeasureWidth = Math.max(1, columnWidth - indentLeft - indentRight);
31592
31732
  let didRemeasureForColumnWidth = false;
31733
+ let remeasuredMarkerInfo;
31593
31734
  if (typeof remeasureParagraph2 === "function" && typeof measurementWidth === "number" && measurementWidth > remeasureWidth) {
31594
31735
  const firstLineIndent = calculateFirstLineIndent(block, measure);
31595
31736
  const newMeasure = remeasureParagraph2(block, columnWidth, firstLineIndent);
31596
31737
  const newLines = normalizeLines(newMeasure);
31597
31738
  lines = newLines;
31598
31739
  didRemeasureForColumnWidth = true;
31740
+ if (newMeasure.marker) {
31741
+ remeasuredMarkerInfo = newMeasure.marker;
31742
+ }
31599
31743
  }
31600
31744
  let fromLine = 0;
31601
31745
  const attrs = getParagraphAttrs(block);
@@ -31634,10 +31778,12 @@ function layoutParagraphBlock(ctx2, anchors) {
31634
31778
  width: fragmentWidth,
31635
31779
  ...computeFragmentPmRange(block, lines, 0, lines.length)
31636
31780
  };
31637
- if (measure.marker) {
31638
- fragment.markerWidth = measure.marker.markerWidth;
31639
- if (measure.marker.markerTextWidth != null) {
31640
- fragment.markerTextWidth = measure.marker.markerTextWidth;
31781
+ if (measure.marker || remeasuredMarkerInfo) {
31782
+ const effectiveMarkerInfo = remeasuredMarkerInfo ?? measure.marker;
31783
+ fragment.markerWidth = effectiveMarkerInfo?.markerWidth ?? measure.marker?.markerWidth ?? 0;
31784
+ const markerTextWidth = remeasuredMarkerInfo?.markerTextWidth ?? measure.marker?.markerTextWidth;
31785
+ if (markerTextWidth != null) {
31786
+ fragment.markerTextWidth = markerTextWidth;
31641
31787
  }
31642
31788
  }
31643
31789
  state.page.fragments.push(fragment);
@@ -31679,6 +31825,9 @@ function layoutParagraphBlock(ctx2, anchors) {
31679
31825
  const newLines = normalizeLines(newMeasure);
31680
31826
  lines = newLines;
31681
31827
  didRemeasureForFloats = true;
31828
+ if (newMeasure.marker) {
31829
+ remeasuredMarkerInfo = newMeasure.marker;
31830
+ }
31682
31831
  }
31683
31832
  }
31684
31833
  while (fromLine < lines.length) {
@@ -31750,13 +31899,16 @@ function layoutParagraphBlock(ctx2, anchors) {
31750
31899
  if (didRemeasureForColumnWidth) {
31751
31900
  fragment.lines = lines.slice(fromLine, slice2.toLine);
31752
31901
  }
31753
- if (measure.marker && fromLine === 0) {
31754
- fragment.markerWidth = measure.marker.markerWidth;
31755
- if (measure.marker.markerTextWidth != null) {
31756
- fragment.markerTextWidth = measure.marker.markerTextWidth;
31902
+ if ((measure.marker || remeasuredMarkerInfo) && fromLine === 0) {
31903
+ const effectiveMarkerInfo = remeasuredMarkerInfo ?? measure.marker;
31904
+ fragment.markerWidth = effectiveMarkerInfo?.markerWidth ?? measure.marker?.markerWidth ?? 0;
31905
+ const markerTextWidth = remeasuredMarkerInfo?.markerTextWidth ?? measure.marker?.markerTextWidth;
31906
+ if (markerTextWidth != null) {
31907
+ fragment.markerTextWidth = markerTextWidth;
31757
31908
  }
31758
- if (measure.kind === "paragraph" && measure.marker?.gutterWidth != null) {
31759
- fragment.markerGutter = measure.marker.gutterWidth;
31909
+ const gutterWidth = remeasuredMarkerInfo?.gutterWidth ?? measure.marker?.gutterWidth;
31910
+ if (gutterWidth != null) {
31911
+ fragment.markerGutter = gutterWidth;
31760
31912
  }
31761
31913
  }
31762
31914
  if (fromLine > 0) fragment.continuesFromPrev = true;
@@ -35197,16 +35349,19 @@ function remeasureParagraph(block, maxWidth, firstLineIndent = 0) {
35197
35349
  const contentWidth = Math.max(1, maxWidth - indentLeft - indentRight);
35198
35350
  const markerTextStartX = wordLayout?.marker?.textStartX;
35199
35351
  const textStartPx = typeof markerTextStartX === "number" && Number.isFinite(markerTextStartX) ? markerTextStartX : typeof wordLayout?.textStartPx === "number" && Number.isFinite(wordLayout.textStartPx) ? wordLayout.textStartPx : void 0;
35352
+ let measuredMarkerTextWidth;
35200
35353
  const resolvedTextStartPx = resolveListTextStartPx(
35201
35354
  wordLayout,
35202
35355
  indentLeft,
35203
35356
  indentFirstLine,
35204
35357
  indentHanging,
35205
- (markerText, marker) => {
35358
+ (markerText, marker2) => {
35206
35359
  const context = getCtx();
35207
35360
  if (!context) return 0;
35208
- context.font = markerFontString(marker.run);
35209
- return context.measureText(markerText).width;
35361
+ context.font = markerFontString(marker2.run);
35362
+ const width = context.measureText(markerText).width;
35363
+ measuredMarkerTextWidth = width;
35364
+ return width;
35210
35365
  }
35211
35366
  );
35212
35367
  const effectiveTextStartPx = resolvedTextStartPx ?? textStartPx;
@@ -35297,7 +35452,14 @@ function remeasureParagraph(block, maxWidth, firstLineIndent = 0) {
35297
35452
  }
35298
35453
  }
35299
35454
  const totalHeight = lines.reduce((s2, l) => s2 + l.lineHeight, 0);
35300
- return { kind: "paragraph", lines, totalHeight };
35455
+ const marker = wordLayout?.marker;
35456
+ const markerInfo = marker ? {
35457
+ markerWidth: marker.markerBoxWidthPx ?? indentHanging ?? 0,
35458
+ markerTextWidth: measuredMarkerTextWidth ?? 0,
35459
+ indentLeft,
35460
+ gutterWidth: marker.gutterWidthPx
35461
+ } : void 0;
35462
+ return { kind: "paragraph", lines, totalHeight, marker: markerInfo };
35301
35463
  }
35302
35464
  function hasComments(run) {
35303
35465
  return "comments" in run && Array.isArray(run.comments) && run.comments.length > 0;
@@ -37348,6 +37510,7 @@ function selectionToRects(layout, blocks, measures, from3, to, geometryHelper) {
37348
37510
  isFirstLine,
37349
37511
  isListItem: isListItemFlag,
37350
37512
  markerWidth,
37513
+ markerTextWidth: fragment.markerTextWidth ?? measure.marker?.markerTextWidth ?? void 0,
37351
37514
  paraIndentLeft: indent.left,
37352
37515
  firstLineIndent: indent.firstLine,
37353
37516
  hangingIndent: indent.hanging,
@@ -37485,6 +37648,7 @@ function selectionToRects(layout, blocks, measures, from3, to, geometryHelper) {
37485
37648
  isFirstLine,
37486
37649
  isListItem: cellIsListItem,
37487
37650
  markerWidth: paragraphMarkerWidth,
37651
+ markerTextWidth: info.measure?.marker?.markerTextWidth ?? void 0,
37488
37652
  paraIndentLeft: cellIndent.left,
37489
37653
  firstLineIndent: cellIndent.firstLine,
37490
37654
  hangingIndent: cellIndent.hanging,
@@ -37736,25 +37900,36 @@ const mapPointToPm = (block, line, x, isRTL, availableWidthOverride, alignmentOv
37736
37900
  const range = computeLinePmRange(block, line);
37737
37901
  if (range.pmStart == null || range.pmEnd == null) return null;
37738
37902
  const result = findCharacterAtX(block, line, x, range.pmStart, availableWidthOverride, alignmentOverride);
37903
+ let pmPosition = result.pmPosition;
37739
37904
  if (isRTL) {
37740
37905
  const charOffset = result.charOffset;
37741
37906
  const charsInLine = Math.max(1, line.toChar - line.fromChar);
37742
37907
  const reversedOffset = Math.max(0, Math.min(charsInLine, charsInLine - charOffset));
37743
- return charOffsetToPm(block, line, reversedOffset, range.pmStart);
37908
+ pmPosition = charOffsetToPm(block, line, reversedOffset, range.pmStart);
37744
37909
  }
37745
- return result.pmPosition;
37910
+ return pmPosition;
37746
37911
  };
37747
37912
  const mapPmToX = (block, line, offset2, fragmentWidth, alignmentOverride) => {
37748
37913
  if (fragmentWidth <= 0 || line.width <= 0) return 0;
37749
37914
  let paraIndentLeft = 0;
37750
37915
  let paraIndentRight = 0;
37916
+ let effectiveLeft = 0;
37751
37917
  if (block.kind === "paragraph") {
37752
37918
  const indentLeft = typeof block.attrs?.indent?.left === "number" ? block.attrs.indent.left : 0;
37753
37919
  const indentRight = typeof block.attrs?.indent?.right === "number" ? block.attrs.indent.right : 0;
37754
37920
  paraIndentLeft = Number.isFinite(indentLeft) ? indentLeft : 0;
37755
37921
  paraIndentRight = Number.isFinite(indentRight) ? indentRight : 0;
37922
+ effectiveLeft = paraIndentLeft;
37923
+ const wl = getWordLayoutConfig(block);
37924
+ const isListParagraph = Boolean(block.attrs?.numberingProperties) || Boolean(wl?.marker);
37925
+ if (isListParagraph) {
37926
+ const explicitTextStart = typeof wl?.marker?.textStartX === "number" && Number.isFinite(wl.marker.textStartX) ? wl.marker.textStartX : typeof wl?.textStartPx === "number" && Number.isFinite(wl.textStartPx) ? wl.textStartPx : void 0;
37927
+ if (typeof explicitTextStart === "number" && explicitTextStart > paraIndentLeft) {
37928
+ effectiveLeft = explicitTextStart;
37929
+ }
37930
+ }
37756
37931
  }
37757
- const totalIndent = paraIndentLeft + paraIndentRight;
37932
+ const totalIndent = effectiveLeft + paraIndentRight;
37758
37933
  const availableWidth = Math.max(0, fragmentWidth - totalIndent);
37759
37934
  if (totalIndent > fragmentWidth) {
37760
37935
  console.warn(
@@ -39092,16 +39267,26 @@ function lineHeightBeforeIndex(lines, fromLine, targetIndex) {
39092
39267
  }
39093
39268
  function computeCaretLayoutRectGeometry({ layout, blocks, measures, painterHost, viewportHost, visibleHost, zoom }, pos, includeDomFallback = true) {
39094
39269
  if (!layout) return null;
39095
- const hit = getFragmentAtPosition(layout, blocks, measures, pos);
39270
+ let effectivePos = pos;
39271
+ let hit = getFragmentAtPosition(layout, blocks, measures, pos);
39096
39272
  if (!hit) {
39097
- return null;
39273
+ const fallbackCandidates = [pos - 1, pos + 1, pos - 2, pos + 2].filter((candidate) => candidate >= 0);
39274
+ for (const candidate of fallbackCandidates) {
39275
+ const fallbackHit = getFragmentAtPosition(layout, blocks, measures, candidate);
39276
+ if (fallbackHit) {
39277
+ hit = fallbackHit;
39278
+ effectivePos = candidate;
39279
+ break;
39280
+ }
39281
+ }
39282
+ if (!hit) return null;
39098
39283
  }
39099
39284
  const block = hit.block;
39100
39285
  const measure = hit.measure;
39101
39286
  if (hit.fragment.kind === "table" && block?.kind === "table" && measure?.kind === "table") {
39102
39287
  return computeTableCaretLayoutRectFromDom(
39103
39288
  { viewportHost, visibleHost, zoom },
39104
- pos,
39289
+ effectivePos,
39105
39290
  hit.fragment,
39106
39291
  block,
39107
39292
  measure,
@@ -39109,92 +39294,32 @@ function computeCaretLayoutRectGeometry({ layout, blocks, measures, painterHost,
39109
39294
  );
39110
39295
  }
39111
39296
  if (!block || block.kind !== "paragraph" || measure?.kind !== "paragraph") return null;
39112
- if (hit.fragment.kind !== "para") {
39113
- return null;
39114
- }
39297
+ if (hit.fragment.kind !== "para") return null;
39115
39298
  const fragment = hit.fragment;
39116
- const lineInfo = findLineContainingPos(block, measure, fragment.fromLine, fragment.toLine, pos);
39117
- if (!lineInfo) {
39118
- return null;
39119
- }
39299
+ const lineInfo = findLineContainingPos(block, measure, fragment.fromLine, fragment.toLine, effectivePos);
39300
+ if (!lineInfo) return null;
39120
39301
  const { line, index: index2 } = lineInfo;
39121
39302
  const range = computeLinePmRange(block, line);
39122
39303
  if (range.pmStart == null || range.pmEnd == null) return null;
39123
- const pmOffset = pmPosToCharOffset(block, line, pos);
39304
+ const pmOffset = pmPosToCharOffset(block, line, effectivePos);
39124
39305
  const markerWidth = fragment.markerWidth ?? measure.marker?.markerWidth ?? 0;
39125
- const indent = extractParagraphIndent(block.attrs?.indent);
39126
- const availableWidth = Math.max(0, fragment.width - (indent.left + indent.right));
39127
- const charX = measureCharacterX(block, line, pmOffset, availableWidth);
39306
+ const markerTextWidth = fragment.markerTextWidth ?? measure.marker?.markerTextWidth ?? void 0;
39128
39307
  const isFirstLine = index2 === fragment.fromLine;
39129
39308
  const isListItemFlag = isListItem(markerWidth, block);
39130
- const isListFirstLine = isFirstLine && !fragment.continuesFromPrev && isListItemFlag;
39131
39309
  const wordLayout = getWordLayoutConfig(block);
39132
- const isFirstLineIndentMode = wordLayout?.firstLineIndentMode === true;
39133
- if (isListFirstLine && isFirstLineIndentMode) {
39134
- const textStartPx = calculateTextStartIndent({
39135
- isFirstLine,
39136
- isListItem: isListItemFlag,
39137
- markerWidth,
39138
- paraIndentLeft: indent.left,
39139
- firstLineIndent: indent.firstLine,
39140
- hangingIndent: indent.hanging,
39141
- wordLayout
39142
- });
39143
- const localX2 = fragment.x + textStartPx + charX;
39144
- const lineOffset2 = lineHeightBeforeIndex(measure.lines, fragment.fromLine, index2);
39145
- const localY2 = fragment.y + lineOffset2;
39146
- const result2 = {
39147
- pageIndex: hit.pageIndex,
39148
- x: localX2,
39149
- y: localY2,
39150
- height: line.lineHeight
39151
- };
39152
- const pageEl2 = painterHost?.querySelector(
39153
- `.superdoc-page[data-page-index="${hit.pageIndex}"]`
39154
- );
39155
- const pageRect2 = pageEl2?.getBoundingClientRect();
39156
- let domCaretX2 = null;
39157
- let domCaretY2 = null;
39158
- const spanEls2 = pageEl2?.querySelectorAll("span[data-pm-start][data-pm-end]");
39159
- for (const spanEl of Array.from(spanEls2 ?? [])) {
39160
- const pmStart = Number(spanEl.dataset.pmStart);
39161
- const pmEnd = Number(spanEl.dataset.pmEnd);
39162
- if (pos >= pmStart && pos <= pmEnd && spanEl.firstChild?.nodeType === Node.TEXT_NODE) {
39163
- const textNode = spanEl.firstChild;
39164
- const charIndex = Math.min(pos - pmStart, textNode.length);
39165
- const rangeObj = document.createRange();
39166
- rangeObj.setStart(textNode, charIndex);
39167
- rangeObj.setEnd(textNode, charIndex);
39168
- if (typeof rangeObj.getBoundingClientRect !== "function") {
39169
- break;
39170
- }
39171
- const rangeRect = rangeObj.getBoundingClientRect();
39172
- if (pageRect2) {
39173
- domCaretX2 = (rangeRect.left - pageRect2.left) / zoom;
39174
- domCaretY2 = (rangeRect.top - pageRect2.top) / zoom;
39175
- }
39176
- break;
39177
- }
39178
- }
39179
- if (includeDomFallback && domCaretX2 != null && domCaretY2 != null) {
39180
- return {
39181
- pageIndex: hit.pageIndex,
39182
- x: domCaretX2,
39183
- y: domCaretY2,
39184
- height: line.lineHeight
39185
- };
39186
- }
39187
- return result2;
39188
- }
39310
+ const indent = extractParagraphIndent(block.attrs?.indent);
39189
39311
  const indentAdjust = calculateTextStartIndent({
39190
39312
  isFirstLine,
39191
39313
  isListItem: isListItemFlag,
39192
39314
  markerWidth,
39315
+ markerTextWidth,
39193
39316
  paraIndentLeft: indent.left,
39194
39317
  firstLineIndent: indent.firstLine,
39195
39318
  hangingIndent: indent.hanging,
39196
39319
  wordLayout
39197
39320
  });
39321
+ const availableWidth = Math.max(0, fragment.width - (indentAdjust + indent.right));
39322
+ const charX = measureCharacterX(block, line, pmOffset, availableWidth);
39198
39323
  const localX = fragment.x + indentAdjust + charX;
39199
39324
  const lineOffset = lineHeightBeforeIndex(measure.lines, fragment.fromLine, index2);
39200
39325
  const localY = fragment.y + lineOffset;
@@ -39212,9 +39337,9 @@ function computeCaretLayoutRectGeometry({ layout, blocks, measures, painterHost,
39212
39337
  for (const spanEl of Array.from(spanEls ?? [])) {
39213
39338
  const pmStart = Number(spanEl.dataset.pmStart);
39214
39339
  const pmEnd = Number(spanEl.dataset.pmEnd);
39215
- if (pos >= pmStart && pos <= pmEnd && spanEl.firstChild?.nodeType === Node.TEXT_NODE) {
39340
+ if (effectivePos >= pmStart && effectivePos <= pmEnd && spanEl.firstChild?.nodeType === Node.TEXT_NODE) {
39216
39341
  const textNode = spanEl.firstChild;
39217
- const charIndex = Math.min(pos - pmStart, textNode.length);
39342
+ const charIndex = Math.min(effectivePos - pmStart, textNode.length);
39218
39343
  const rangeObj = document.createRange();
39219
39344
  rangeObj.setStart(textNode, charIndex);
39220
39345
  rangeObj.setEnd(textNode, charIndex);
@@ -40283,6 +40408,13 @@ const applyTrackedChangesModeToRuns = (runs, config, hyperlinkConfig, applyMarks
40283
40408
  );
40284
40409
  }
40285
40410
  });
40411
+ if ((config.mode === "original" || config.mode === "final") && config.enabled) {
40412
+ filtered.forEach((run) => {
40413
+ if (isTextRun$1(run) && run.trackedChange && (run.trackedChange.kind === "insert" || run.trackedChange.kind === "delete")) {
40414
+ delete run.trackedChange;
40415
+ }
40416
+ });
40417
+ }
40286
40418
  }
40287
40419
  return filtered;
40288
40420
  };
@@ -43348,7 +43480,16 @@ const computeParagraphAttrs = (para, styleContext, listCounterContext, converter
43348
43480
  if (!value || typeof value !== "object") return;
43349
43481
  return normalizePxIndent(value) ?? convertIndentTwipsToPx(value);
43350
43482
  };
43351
- const normalizedIndent = normalizeIndentObject(attrs.indent) ?? convertIndentTwipsToPx(paragraphProps.indent) ?? convertIndentTwipsToPx(hydrated?.indent) ?? normalizeParagraphIndent(attrs.textIndent);
43483
+ const hydratedIndentPx = convertIndentTwipsToPx(hydrated?.indent);
43484
+ const paragraphIndentPx = convertIndentTwipsToPx(paragraphProps.indent);
43485
+ const textIndentPx = normalizeParagraphIndent(attrs.textIndent);
43486
+ const attrsIndentPx = normalizeIndentObject(attrs.indent);
43487
+ const indentChain = [];
43488
+ if (hydratedIndentPx) indentChain.push({ indent: hydratedIndentPx });
43489
+ if (paragraphIndentPx) indentChain.push({ indent: paragraphIndentPx });
43490
+ if (textIndentPx) indentChain.push({ indent: textIndentPx });
43491
+ if (attrsIndentPx) indentChain.push({ indent: attrsIndentPx });
43492
+ const normalizedIndent = indentChain.length ? superEditor_converter.combineIndentProperties(indentChain).indent : void 0;
43352
43493
  const unwrapTabStops = (tabStops) => {
43353
43494
  if (!Array.isArray(tabStops)) {
43354
43495
  return void 0;
@@ -48627,10 +48768,13 @@ async function measureParagraphBlock(block, maxWidth) {
48627
48768
  };
48628
48769
  }
48629
48770
  const originX = currentLine.width;
48630
- const { target, nextIndex, stop } = getNextTabStopPx(currentLine.width, tabStops, tabStopCursor);
48771
+ const effectiveIndent = lines.length === 0 ? indentLeft + rawFirstLineOffset : indentLeft;
48772
+ const absCurrentX = currentLine.width + effectiveIndent;
48773
+ const { target, nextIndex, stop } = getNextTabStopPx(absCurrentX, tabStops, tabStopCursor);
48631
48774
  tabStopCursor = nextIndex;
48632
- const clampedTarget = Math.min(target, currentLine.maxWidth);
48633
- const tabAdvance = Math.max(0, clampedTarget - currentLine.width);
48775
+ const maxAbsWidth = currentLine.maxWidth + effectiveIndent;
48776
+ const clampedTarget = Math.min(target, maxAbsWidth);
48777
+ const tabAdvance = Math.max(0, clampedTarget - absCurrentX);
48634
48778
  currentLine.width = roundValue(currentLine.width + tabAdvance);
48635
48779
  run.width = tabAdvance;
48636
48780
  currentLine.maxFontSize = Math.max(currentLine.maxFontSize, 12);
@@ -48638,8 +48782,9 @@ async function measureParagraphBlock(block, maxWidth) {
48638
48782
  currentLine.toChar = 1;
48639
48783
  if (stop && stop.leader && stop.leader !== "none") {
48640
48784
  const leaderStyle = stop.leader;
48641
- const from3 = Math.min(originX, clampedTarget);
48642
- const to = Math.max(originX, clampedTarget);
48785
+ const relativeTarget = clampedTarget - effectiveIndent;
48786
+ const from3 = Math.min(originX, relativeTarget);
48787
+ const to = Math.max(originX, relativeTarget);
48643
48788
  if (!currentLine.leaders) currentLine.leaders = [];
48644
48789
  currentLine.leaders.push({ from: from3, to, style: leaderStyle });
48645
48790
  }
@@ -48648,27 +48793,28 @@ async function measureParagraphBlock(block, maxWidth) {
48648
48793
  if (stop.val === "end" || stop.val === "center" || stop.val === "decimal") {
48649
48794
  const groupMeasure = measureTabAlignmentGroup(runIndex + 1, runsToProcess, ctx2, decimalSeparator);
48650
48795
  if (groupMeasure.totalWidth > 0) {
48796
+ const relativeTarget = clampedTarget - effectiveIndent;
48651
48797
  let groupStartX;
48652
48798
  if (stop.val === "end") {
48653
- groupStartX = Math.max(0, clampedTarget - groupMeasure.totalWidth);
48799
+ groupStartX = Math.max(0, relativeTarget - groupMeasure.totalWidth);
48654
48800
  } else if (stop.val === "center") {
48655
- groupStartX = Math.max(0, clampedTarget - groupMeasure.totalWidth / 2);
48801
+ groupStartX = Math.max(0, relativeTarget - groupMeasure.totalWidth / 2);
48656
48802
  } else {
48657
48803
  const beforeDecimal = groupMeasure.beforeDecimalWidth ?? groupMeasure.totalWidth;
48658
- groupStartX = Math.max(0, clampedTarget - beforeDecimal);
48804
+ groupStartX = Math.max(0, relativeTarget - beforeDecimal);
48659
48805
  }
48660
48806
  activeTabGroup = {
48661
48807
  measure: groupMeasure,
48662
48808
  startX: groupStartX,
48663
48809
  currentX: groupStartX,
48664
- target: clampedTarget,
48810
+ target: relativeTarget,
48665
48811
  val: stop.val
48666
48812
  };
48667
48813
  currentLine.width = roundValue(groupStartX);
48668
48814
  }
48669
48815
  pendingTabAlignment = null;
48670
48816
  } else {
48671
- pendingTabAlignment = { target: clampedTarget, val: stop.val };
48817
+ pendingTabAlignment = { target: clampedTarget - effectiveIndent, val: stop.val };
48672
48818
  }
48673
48819
  } else {
48674
48820
  pendingTabAlignment = null;
@@ -49309,10 +49455,13 @@ async function measureParagraphBlock(block, maxWidth) {
49309
49455
  };
49310
49456
  }
49311
49457
  const originX = currentLine.width;
49312
- const { target, nextIndex, stop } = getNextTabStopPx(currentLine.width, tabStops, tabStopCursor);
49458
+ const effectiveIndent = lines.length === 0 ? indentLeft + rawFirstLineOffset : indentLeft;
49459
+ const absCurrentX = currentLine.width + effectiveIndent;
49460
+ const { target, nextIndex, stop } = getNextTabStopPx(absCurrentX, tabStops, tabStopCursor);
49313
49461
  tabStopCursor = nextIndex;
49314
- const clampedTarget = Math.min(target, currentLine.maxWidth);
49315
- const tabAdvance = Math.max(0, clampedTarget - currentLine.width);
49462
+ const maxAbsWidth = currentLine.maxWidth + effectiveIndent;
49463
+ const clampedTarget = Math.min(target, maxAbsWidth);
49464
+ const tabAdvance = Math.max(0, clampedTarget - absCurrentX);
49316
49465
  currentLine.width = roundValue(currentLine.width + tabAdvance);
49317
49466
  currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run);
49318
49467
  currentLine.maxFontSize = Math.max(currentLine.maxFontSize, run.fontSize);
@@ -49321,14 +49470,15 @@ async function measureParagraphBlock(block, maxWidth) {
49321
49470
  charPosInRun += 1;
49322
49471
  if (stop) {
49323
49472
  validateTabStopVal(stop);
49324
- pendingTabAlignment = { target: clampedTarget, val: stop.val };
49473
+ pendingTabAlignment = { target: clampedTarget - effectiveIndent, val: stop.val };
49325
49474
  } else {
49326
49475
  pendingTabAlignment = null;
49327
49476
  }
49328
49477
  if (stop && stop.leader && stop.leader !== "none" && stop.leader !== "middleDot") {
49329
49478
  const leaderStyle = stop.leader;
49330
- const from3 = Math.min(originX, clampedTarget);
49331
- const to = Math.max(originX, clampedTarget);
49479
+ const relativeTarget = clampedTarget - effectiveIndent;
49480
+ const from3 = Math.min(originX, relativeTarget);
49481
+ const to = Math.max(originX, relativeTarget);
49332
49482
  if (!currentLine.leaders) currentLine.leaders = [];
49333
49483
  currentLine.leaders.push({ from: from3, to, style: leaderStyle });
49334
49484
  }
@@ -49604,7 +49754,11 @@ async function measureTableBlock(block, constraints) {
49604
49754
  }
49605
49755
  async function measureImageBlock(block, constraints) {
49606
49756
  const intrinsic = getIntrinsicImageSize(block, constraints.maxWidth);
49607
- const maxWidth = constraints.maxWidth > 0 ? constraints.maxWidth : intrinsic.width;
49757
+ const isBlockBehindDoc = block.anchor?.behindDoc;
49758
+ const isBlockWrapBehindDoc = block.wrap?.type === "None" && block.wrap?.behindDoc;
49759
+ const bypassWidthConstraint = isBlockBehindDoc || isBlockWrapBehindDoc;
49760
+ const isWidthConstraintBypassed = bypassWidthConstraint || constraints.maxWidth <= 0;
49761
+ const maxWidth = isWidthConstraintBypassed ? intrinsic.width : constraints.maxWidth;
49608
49762
  const hasNegativeVerticalPosition = block.anchor?.isAnchored && (typeof block.anchor?.offsetV === "number" && block.anchor.offsetV < 0 || typeof block.margin?.top === "number" && block.margin.top < 0);
49609
49763
  const maxHeight = hasNegativeVerticalPosition || !constraints.maxHeight || constraints.maxHeight <= 0 ? Infinity : constraints.maxHeight;
49610
49764
  const widthScale = maxWidth / intrinsic.width;
@@ -50771,9 +50925,10 @@ class PresentationEditor extends EventEmitter {
50771
50925
  throw new TypeError("[PresentationEditor] setTrackedChangesOverrides expects an object or undefined");
50772
50926
  }
50773
50927
  if (overrides !== void 0) {
50774
- if (overrides.mode !== void 0 && !["review", "simple", "original"].includes(overrides.mode)) {
50928
+ const validModes = ["review", "original", "final", "off"];
50929
+ if (overrides.mode !== void 0 && !validModes.includes(overrides.mode)) {
50775
50930
  throw new TypeError(
50776
- `[PresentationEditor] Invalid tracked changes mode "${overrides.mode}". Must be one of: review, simple, original`
50931
+ `[PresentationEditor] Invalid tracked changes mode "${overrides.mode}". Must be one of: ${validModes.join(", ")}`
50777
50932
  );
50778
50933
  }
50779
50934
  if (overrides.enabled !== void 0 && typeof overrides.enabled !== "boolean") {
@@ -52408,7 +52563,12 @@ class PresentationEditor extends EventEmitter {
52408
52563
  }
52409
52564
  if (!handledByDepth) {
52410
52565
  try {
52411
- const tr = this.#editor.state.tr.setSelection(superEditor_converter.TextSelection.create(this.#editor.state.doc, hit.pos));
52566
+ const doc22 = this.#editor.state.doc;
52567
+ let nextSelection = superEditor_converter.TextSelection.create(doc22, hit.pos);
52568
+ if (!nextSelection.$from.parent.inlineContent) {
52569
+ nextSelection = superEditor_converter.Selection.near(doc22.resolve(hit.pos), 1);
52570
+ }
52571
+ const tr = this.#editor.state.tr.setSelection(nextSelection);
52412
52572
  this.#editor.view?.dispatch(tr);
52413
52573
  } catch {
52414
52574
  }
@@ -53398,6 +53558,7 @@ class PresentationEditor extends EventEmitter {
53398
53558
  if (!layout) {
53399
53559
  return;
53400
53560
  }
53561
+ const { from: from3, to } = selection;
53401
53562
  const docEpoch = this.#epochMapper.getCurrentEpoch();
53402
53563
  if (this.#layoutEpoch < docEpoch) {
53403
53564
  return;
@@ -53412,7 +53573,6 @@ class PresentationEditor extends EventEmitter {
53412
53573
  }
53413
53574
  return;
53414
53575
  }
53415
- const { from: from3, to } = selection;
53416
53576
  if (from3 === to) {
53417
53577
  const caretLayout = this.#computeCaretLayoutRect(from3);
53418
53578
  if (!caretLayout) {
@@ -54724,7 +54884,7 @@ class PresentationEditor extends EventEmitter {
54724
54884
  const zoom = this.#layoutOptions.zoom ?? 1;
54725
54885
  const layoutMode = this.#layoutOptions.layoutMode ?? "vertical";
54726
54886
  const pages = this.#layoutState.layout?.pages;
54727
- const pageGap = this.#layoutState.layout?.pageGap ?? this.#getEffectivePageGap();
54887
+ const pageGap = this.#getEffectivePageGap();
54728
54888
  const defaultWidth = this.#layoutOptions.pageSize?.w ?? DEFAULT_PAGE_SIZE.w;
54729
54889
  const defaultHeight = this.#layoutOptions.pageSize?.h ?? DEFAULT_PAGE_SIZE.h;
54730
54890
  let maxWidth = defaultWidth;
@@ -57835,7 +57995,11 @@ const Document = Node$1.create({
57835
57995
  */
57836
57996
  clearDocument: () => ({ commands: commands2 }) => {
57837
57997
  return commands2.setContent("<p></p>");
57838
- }
57998
+ },
57999
+ /**
58000
+ * Set section page margins (top/right/bottom/left) for the section at the current selection.
58001
+ */
58002
+ setSectionPageMarginsAtSelection
57839
58003
  };
57840
58004
  }
57841
58005
  });
@@ -58007,6 +58171,28 @@ const createMarkDefsFromStyleRunProps = (styleRunProps) => {
58007
58171
  }
58008
58172
  return markDefs;
58009
58173
  };
58174
+ const normalizeSelectionIntoRun = (tr, runType) => {
58175
+ const selection = tr.selection;
58176
+ if (!(selection instanceof superEditor_converter.TextSelection)) return;
58177
+ if (selection.from !== selection.to) return;
58178
+ const $pos = tr.doc.resolve(selection.from);
58179
+ if ($pos.parent.type === runType) return;
58180
+ const nodeAfter = $pos.nodeAfter;
58181
+ if (nodeAfter?.type === runType && nodeAfter.content.size > 0) {
58182
+ const nextPos = selection.from + 1;
58183
+ if (nextPos <= tr.doc.content.size) {
58184
+ tr.setSelection(superEditor_converter.TextSelection.create(tr.doc, nextPos));
58185
+ }
58186
+ return;
58187
+ }
58188
+ const nodeBefore = $pos.nodeBefore;
58189
+ if (nodeBefore?.type === runType && nodeBefore.content.size > 0) {
58190
+ const prevPos = selection.from - 1;
58191
+ if (prevPos >= 0) {
58192
+ tr.setSelection(superEditor_converter.TextSelection.create(tr.doc, prevPos));
58193
+ }
58194
+ }
58195
+ };
58010
58196
  const buildWrapTransaction = (state, ranges, runType, editor, markDefsFromMeta = []) => {
58011
58197
  if (!ranges.length) return null;
58012
58198
  const replacements = [];
@@ -58040,6 +58226,7 @@ const buildWrapTransaction = (state, ranges, runType, editor, markDefsFromMeta =
58040
58226
  if (!replacements.length) return null;
58041
58227
  const tr = state.tr;
58042
58228
  replacements.sort((a, b) => b.from - a.from).forEach(({ from: from3, to, runNode }) => tr.replaceWith(from3, to, runNode));
58229
+ normalizeSelectionIntoRun(tr, runType);
58043
58230
  return tr.docChanged ? tr : null;
58044
58231
  };
58045
58232
  const wrapTextInRunsPlugin = (editor) => {
@@ -58489,12 +58676,18 @@ function findParagraphContext($pos, cache2, helpers2) {
58489
58676
  return null;
58490
58677
  }
58491
58678
  function extractParagraphContext(node, startPos, helpers2, depth = 0) {
58492
- const paragraphProperties = superEditor_converter.getResolvedParagraphProperties(node) ?? {};
58679
+ const paragraphProperties = superEditor_converter.getResolvedParagraphProperties(node) ?? node.attrs?.paragraphProperties ?? {};
58493
58680
  const alignmentAliases = { left: "start", right: "end" };
58494
58681
  let tabStops = [];
58495
58682
  if (Array.isArray(paragraphProperties.tabStops)) {
58496
58683
  tabStops = paragraphProperties.tabStops.map((stop) => {
58497
58684
  const ref = stop?.tab;
58685
+ if (!ref && stop?.pos != null) {
58686
+ return {
58687
+ ...stop,
58688
+ pos: twipsToPixels(Number(stop.pos) || 0)
58689
+ };
58690
+ }
58498
58691
  if (!ref) return stop || null;
58499
58692
  const rawType = ref.tabType || "start";
58500
58693
  const mappedVal = alignmentAliases[rawType] || rawType;
@@ -59760,6 +59953,13 @@ function createLayoutRequest(doc2, paragraphPos, view, helpers2, revision, parag
59760
59953
  pos: entry.pos,
59761
59954
  nodeSize: node.nodeSize
59762
59955
  });
59956
+ } else if (node.type.name === "lineBreak" || node.type.name === "hardBreak") {
59957
+ spans.push({
59958
+ type: node.type.name,
59959
+ spanId,
59960
+ pos: entry.pos,
59961
+ nodeSize: node.nodeSize
59962
+ });
59763
59963
  } else if (node.type.name === "text") {
59764
59964
  spans.push({
59765
59965
  type: "text",
@@ -59809,6 +60009,7 @@ function calculateTabLayout(request, measurement, view) {
59809
60009
  paragraphNode
59810
60010
  } = request;
59811
60011
  const tabs = {};
60012
+ const leftIndentPx = request.indents?.left ?? 0;
59812
60013
  let currentX = indentWidth;
59813
60014
  const measureText2 = (span) => {
59814
60015
  if (view && typeof span.from === "number" && typeof span.to === "number") {
@@ -59821,6 +60022,8 @@ function calculateTabLayout(request, measurement, view) {
59821
60022
  const span = spans[i];
59822
60023
  if (span.type === "text") {
59823
60024
  currentX += measureText2(span);
60025
+ } else if (span.type === "lineBreak" || span.type === "hardBreak") {
60026
+ currentX = leftIndentPx;
59824
60027
  } else if (span.type === "tab") {
59825
60028
  const followingText = collectFollowingText(spans, i + 1);
59826
60029
  let measureTextCallback;
@@ -59916,7 +60119,7 @@ function collectFollowingText(spans, startIndex) {
59916
60119
  let text = "";
59917
60120
  for (let i = startIndex; i < spans.length; i++) {
59918
60121
  const span = spans[i];
59919
- if (span.type === "tab") break;
60122
+ if (span.type === "tab" || span.type === "lineBreak" || span.type === "hardBreak") break;
59920
60123
  if (span.type === "text") text += span.text || "";
59921
60124
  }
59922
60125
  return text;
@@ -59926,7 +60129,7 @@ function getFollowingTextRange(spans, startIndex) {
59926
60129
  let to = null;
59927
60130
  for (let i = startIndex; i < spans.length; i++) {
59928
60131
  const span = spans[i];
59929
- if (span.type === "tab") break;
60132
+ if (span.type === "tab" || span.type === "lineBreak" || span.type === "hardBreak") break;
59930
60133
  if (span.type === "text" && typeof span.from === "number" && typeof span.to === "number") {
59931
60134
  if (from3 === null) from3 = span.from;
59932
60135
  to = span.to;
@@ -64344,6 +64547,10 @@ const Image = Node$1.create({
64344
64547
  }
64345
64548
  const hasAnchorData = Boolean(anchorData);
64346
64549
  const hasMarginOffsets = marginOffset?.horizontal != null || marginOffset?.top != null;
64550
+ const isWrapBehindDoc = wrap?.attrs?.behindDoc;
64551
+ const isAnchorBehindDoc = anchorData?.behindDoc;
64552
+ const isBehindDocAnchor = wrap?.type === "None" && (isWrapBehindDoc || isAnchorBehindDoc);
64553
+ const isAbsolutelyPositioned = style2.includes("position: absolute;");
64347
64554
  if (hasAnchorData) {
64348
64555
  switch (anchorData.hRelativeFrom) {
64349
64556
  case "page":
@@ -64371,7 +64578,6 @@ const Image = Node$1.create({
64371
64578
  style2 += "float: left;";
64372
64579
  }
64373
64580
  } else if (!anchorData.alignH && marginOffset?.horizontal != null) {
64374
- const isAbsolutelyPositioned = style2.includes("position: absolute;");
64375
64581
  if (isAbsolutelyPositioned) {
64376
64582
  style2 += `left: ${baseHorizontal}px;`;
64377
64583
  style2 += "max-width: none;";
@@ -64385,7 +64591,8 @@ const Image = Node$1.create({
64385
64591
  const relativeFromPageV = anchorData?.vRelativeFrom === "page";
64386
64592
  const relativeFromMarginV = anchorData?.vRelativeFrom === "margin";
64387
64593
  const maxMarginV = 500;
64388
- const baseTop = Math.max(0, marginOffset?.top ?? 0);
64594
+ const allowNegativeTopOffset = isBehindDocAnchor;
64595
+ const baseTop = allowNegativeTopOffset ? marginOffset?.top ?? 0 : Math.max(0, marginOffset?.top ?? 0);
64389
64596
  let rotationHorizontal = 0;
64390
64597
  let rotationTop = 0;
64391
64598
  const { rotation: rotation2 } = transformData ?? {};
@@ -64404,7 +64611,10 @@ const Image = Node$1.create({
64404
64611
  margin.left += horizontal;
64405
64612
  }
64406
64613
  }
64407
- if (top2 && !relativeFromMarginV) {
64614
+ const appliedTopViaStyle = isAbsolutelyPositioned && allowNegativeTopOffset && !relativeFromMarginV;
64615
+ if (appliedTopViaStyle) {
64616
+ style2 += `top: ${top2}px;`;
64617
+ } else if (top2 && !relativeFromMarginV) {
64408
64618
  if (relativeFromPageV && top2 >= maxMarginV) margin.top += maxMarginV;
64409
64619
  else margin.top += top2;
64410
64620
  }
@@ -64417,6 +64627,9 @@ const Image = Node$1.create({
64417
64627
  }
64418
64628
  if (margin.top) style2 += `margin-top: ${margin.top}px;`;
64419
64629
  if (margin.bottom) style2 += `margin-bottom: ${margin.bottom}px;`;
64630
+ if (isBehindDocAnchor) {
64631
+ style2 += "max-width: none;";
64632
+ }
64420
64633
  const finalAttributes = { ...htmlAttributes };
64421
64634
  if (style2) {
64422
64635
  const existingStyle = finalAttributes.style || "";
@@ -72921,6 +73134,7 @@ const useToolbarItem = (options) => {
72921
73134
  const parentItem = vue.ref(null);
72922
73135
  const iconColor = vue.ref(options.iconColor);
72923
73136
  const hasCaret = vue.ref(options.hasCaret);
73137
+ const restoreEditorFocus = Boolean(options.restoreEditorFocus);
72924
73138
  const dropdownStyles = vue.ref(options.dropdownStyles);
72925
73139
  const tooltip = vue.ref(options.tooltip);
72926
73140
  const tooltipVisible = vue.ref(options.tooltipVisible);
@@ -72996,6 +73210,7 @@ const useToolbarItem = (options) => {
72996
73210
  hideLabel,
72997
73211
  inlineTextInputVisible,
72998
73212
  hasInlineTextInput,
73213
+ restoreEditorFocus,
72999
73214
  markName,
73000
73215
  labelAttr,
73001
73216
  childItem,
@@ -75309,6 +75524,7 @@ const makeDefaultItems = ({
75309
75524
  command: "toggleBulletList",
75310
75525
  icon: toolbarIcons2.bulletList,
75311
75526
  tooltip: toolbarTexts2.bulletList,
75527
+ restoreEditorFocus: true,
75312
75528
  attributes: {
75313
75529
  ariaLabel: "Bullet list"
75314
75530
  }
@@ -75319,6 +75535,7 @@ const makeDefaultItems = ({
75319
75535
  command: "toggleOrderedList",
75320
75536
  icon: toolbarIcons2.numberedList,
75321
75537
  tooltip: toolbarTexts2.numberedList,
75538
+ restoreEditorFocus: true,
75322
75539
  attributes: {
75323
75540
  ariaLabel: "Numbered list"
75324
75541
  }
@@ -78870,7 +79087,7 @@ var ResizeObserverController = (function() {
78870
79087
  };
78871
79088
  return ResizeObserverController2;
78872
79089
  })();
78873
- var ResizeObserver = (function() {
79090
+ var ResizeObserver$1 = (function() {
78874
79091
  function ResizeObserver2(callback) {
78875
79092
  if (arguments.length === 0) {
78876
79093
  throw new TypeError("Failed to construct 'ResizeObserver': 1 argument required, but only 0 present.");
@@ -78909,7 +79126,7 @@ var ResizeObserver = (function() {
78909
79126
  class ResizeObserverDelegate {
78910
79127
  constructor() {
78911
79128
  this.handleResize = this.handleResize.bind(this);
78912
- this.observer = new (typeof window !== "undefined" && window.ResizeObserver || ResizeObserver)(this.handleResize);
79129
+ this.observer = new (typeof window !== "undefined" && window.ResizeObserver || ResizeObserver$1)(this.handleResize);
78913
79130
  this.elHandlersMap = /* @__PURE__ */ new Map();
78914
79131
  }
78915
79132
  handleResize(entries) {
@@ -86189,6 +86406,7 @@ class SuperToolbar extends eventemitter3.EventEmitter {
86189
86406
  selectionUpdate: null,
86190
86407
  focus: null
86191
86408
  };
86409
+ this._restoreFocusTimeoutId = null;
86192
86410
  if (!this.config.selector && this.config.element) {
86193
86411
  this.config.selector = this.config.element;
86194
86412
  }
@@ -86854,6 +87072,7 @@ class SuperToolbar extends eventemitter3.EventEmitter {
86854
87072
  const wasFocused = Boolean(typeof hasFocusFn === "function" && hasFocusFn.call(this.activeEditor.view));
86855
87073
  const { command: command2 } = item;
86856
87074
  const isMarkToggle = this.isMarkToggle(item);
87075
+ const shouldRestoreFocus = Boolean(item?.restoreEditorFocus);
86857
87076
  if (!wasFocused && isMarkToggle) {
86858
87077
  this.pendingMarkCommands.push({ command: command2, argument, item });
86859
87078
  item?.activate?.();
@@ -86884,6 +87103,13 @@ class SuperToolbar extends eventemitter3.EventEmitter {
86884
87103
  }
86885
87104
  if (isMarkToggle) this.#syncStickyMarksFromState();
86886
87105
  this.updateToolbarState();
87106
+ if (shouldRestoreFocus && this.activeEditor && !this.activeEditor.options.isHeaderOrFooter) {
87107
+ this._restoreFocusTimeoutId = setTimeout(() => {
87108
+ this._restoreFocusTimeoutId = null;
87109
+ if (!this.activeEditor || this.activeEditor.options.isHeaderOrFooter) return;
87110
+ this.activeEditor.focus();
87111
+ }, 0);
87112
+ }
86887
87113
  }
86888
87114
  /**
86889
87115
  * Processes and executes pending mark commands when editor selection updates.
@@ -87026,6 +87252,17 @@ class SuperToolbar extends eventemitter3.EventEmitter {
87026
87252
  const tr = state.tr.setStoredMarks([mark]);
87027
87253
  view.dispatch(tr);
87028
87254
  }
87255
+ /**
87256
+ * Cleans up resources when the toolbar is destroyed.
87257
+ * Clears any pending timeouts to prevent callbacks firing after unmount.
87258
+ * @returns {void}
87259
+ */
87260
+ destroy() {
87261
+ if (this._restoreFocusTimeoutId !== null) {
87262
+ clearTimeout(this._restoreFocusTimeoutId);
87263
+ this._restoreFocusTimeoutId = null;
87264
+ }
87265
+ }
87029
87266
  }
87030
87267
  const onMarginClickCursorChange = (event, editor) => {
87031
87268
  const y = event.clientY;
@@ -89778,6 +90015,31 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
89778
90015
  },
89779
90016
  { immediate: true, deep: true }
89780
90017
  );
90018
+ vue.watch(
90019
+ () => props.options?.rulerContainer,
90020
+ () => {
90021
+ vue.nextTick(() => {
90022
+ syncRulerOffset();
90023
+ setupRulerObservers();
90024
+ });
90025
+ },
90026
+ { immediate: true }
90027
+ );
90028
+ vue.watch(
90029
+ rulersVisible,
90030
+ (visible) => {
90031
+ vue.nextTick(() => {
90032
+ if (visible) {
90033
+ syncRulerOffset();
90034
+ setupRulerObservers();
90035
+ } else {
90036
+ rulerHostStyle.value = {};
90037
+ cleanupRulerObservers();
90038
+ }
90039
+ });
90040
+ },
90041
+ { immediate: true }
90042
+ );
89781
90043
  const containerStyle = vue.computed(() => {
89782
90044
  let maxWidth = 8.5 * 96;
89783
90045
  const ed = editor.value;
@@ -89802,6 +90064,71 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
89802
90064
  minWidth: `${scaledWidth}px`
89803
90065
  };
89804
90066
  });
90067
+ const rulerHostStyle = vue.ref({});
90068
+ const rulerContainerEl = vue.ref(null);
90069
+ let editorResizeObserver = null;
90070
+ let rulerContainerResizeObserver = null;
90071
+ let layoutUpdatedHandler = null;
90072
+ const resolveRulerContainer = () => {
90073
+ const container = props.options?.rulerContainer;
90074
+ if (!container) return null;
90075
+ if (typeof container === "string") {
90076
+ const doc2 = editorWrapper.value?.ownerDocument ?? document;
90077
+ return doc2.querySelector(container);
90078
+ }
90079
+ return container instanceof HTMLElement ? container : null;
90080
+ };
90081
+ const getViewportRect2 = () => {
90082
+ const host = editorWrapper.value;
90083
+ if (!host) return null;
90084
+ const viewport2 = host.querySelector(".presentation-editor__viewport");
90085
+ const target = viewport2 ?? host;
90086
+ return target.getBoundingClientRect();
90087
+ };
90088
+ const syncRulerOffset = () => {
90089
+ if (!rulersVisible.value) {
90090
+ rulerHostStyle.value = {};
90091
+ return;
90092
+ }
90093
+ rulerContainerEl.value = resolveRulerContainer();
90094
+ if (!rulerContainerEl.value) {
90095
+ rulerHostStyle.value = {};
90096
+ return;
90097
+ }
90098
+ const viewportRect = getViewportRect2();
90099
+ if (!viewportRect) return;
90100
+ const hostRect = rulerContainerEl.value.getBoundingClientRect();
90101
+ const paddingLeft = Math.max(0, viewportRect.left - hostRect.left);
90102
+ const paddingRight = Math.max(0, hostRect.right - viewportRect.right);
90103
+ rulerHostStyle.value = {
90104
+ paddingLeft: `${paddingLeft}px`,
90105
+ paddingRight: `${paddingRight}px`
90106
+ };
90107
+ };
90108
+ const cleanupRulerObservers = () => {
90109
+ if (editorResizeObserver) {
90110
+ editorResizeObserver.disconnect();
90111
+ editorResizeObserver = null;
90112
+ }
90113
+ if (rulerContainerResizeObserver) {
90114
+ rulerContainerResizeObserver.disconnect();
90115
+ rulerContainerResizeObserver = null;
90116
+ }
90117
+ };
90118
+ const setupRulerObservers = () => {
90119
+ cleanupRulerObservers();
90120
+ if (typeof ResizeObserver === "undefined") return;
90121
+ const viewportHost = editorWrapper.value;
90122
+ const rulerHost = resolveRulerContainer();
90123
+ if (viewportHost) {
90124
+ editorResizeObserver = new ResizeObserver(() => syncRulerOffset());
90125
+ editorResizeObserver.observe(viewportHost);
90126
+ }
90127
+ if (rulerHost) {
90128
+ rulerContainerResizeObserver = new ResizeObserver(() => syncRulerOffset());
90129
+ rulerContainerResizeObserver.observe(rulerHost);
90130
+ }
90131
+ };
89805
90132
  const message = useMessage();
89806
90133
  const editorWrapper = vue.ref(null);
89807
90134
  const editorElem = vue.ref(null);
@@ -90113,7 +90440,7 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
90113
90440
  presentationEditor.on("imageDeselected", () => {
90114
90441
  clearSelectedImage();
90115
90442
  });
90116
- presentationEditor.on("layoutUpdated", () => {
90443
+ layoutUpdatedHandler = () => {
90117
90444
  if (imageResizeState.visible && imageResizeState.blockId) {
90118
90445
  const escapedBlockId = CSS.escape(imageResizeState.blockId);
90119
90446
  const newElement = editorElem.value?.querySelector(
@@ -90146,13 +90473,17 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
90146
90473
  clearSelectedImage();
90147
90474
  }
90148
90475
  }
90149
- });
90476
+ vue.nextTick(() => syncRulerOffset());
90477
+ };
90478
+ presentationEditor.on("layoutUpdated", layoutUpdatedHandler);
90150
90479
  zoomChangeHandler = ({ zoom }) => {
90151
90480
  currentZoom.value = zoom;
90481
+ vue.nextTick(() => syncRulerOffset());
90152
90482
  };
90153
90483
  presentationEditor.on("zoomChange", zoomChangeHandler);
90154
90484
  if (typeof presentationEditor.zoom === "number") {
90155
90485
  currentZoom.value = presentationEditor.zoom;
90486
+ vue.nextTick(() => syncRulerOffset());
90156
90487
  }
90157
90488
  }
90158
90489
  editor.value.on("paginationUpdate", () => {
@@ -90212,6 +90543,11 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
90212
90543
  vue.onMounted(() => {
90213
90544
  initializeData();
90214
90545
  if (props.options?.suppressSkeletonLoader || !props.options?.collaborationProvider) editorReady.value = true;
90546
+ window.addEventListener("resize", syncRulerOffset, { passive: true });
90547
+ vue.nextTick(() => {
90548
+ syncRulerOffset();
90549
+ setupRulerObservers();
90550
+ });
90215
90551
  });
90216
90552
  const handleMarginClick = (event) => {
90217
90553
  if (event.button !== 0) {
@@ -90226,10 +90562,14 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
90226
90562
  const handleMarginChange = ({ side, value }) => {
90227
90563
  const base2 = activeEditor.value;
90228
90564
  if (!base2) return;
90229
- const pageStyles2 = base2.getPageStyles();
90230
- const { pageMargins } = pageStyles2;
90231
- const update = { ...pageMargins, [side]: value };
90232
- base2?.updatePageStyle({ pageMargins: update });
90565
+ const payload = side === "left" ? { leftInches: value } : side === "right" ? { rightInches: value } : side === "top" ? { topInches: value } : side === "bottom" ? { bottomInches: value } : {};
90566
+ const didUpdateSection = typeof base2.commands?.setSectionPageMarginsAtSelection === "function" ? base2.commands.setSectionPageMarginsAtSelection(payload) : false;
90567
+ if (!didUpdateSection) {
90568
+ const pageStyles2 = base2.getPageStyles();
90569
+ const { pageMargins } = pageStyles2;
90570
+ const update = { ...pageMargins, [side]: value };
90571
+ base2?.updatePageStyle({ pageMargins: update });
90572
+ }
90233
90573
  };
90234
90574
  vue.onBeforeUnmount(() => {
90235
90575
  stopPolling();
@@ -90238,6 +90578,12 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
90238
90578
  editor.value.off("zoomChange", zoomChangeHandler);
90239
90579
  zoomChangeHandler = null;
90240
90580
  }
90581
+ if (editor.value instanceof PresentationEditor && layoutUpdatedHandler) {
90582
+ editor.value.off("layoutUpdated", layoutUpdatedHandler);
90583
+ layoutUpdatedHandler = null;
90584
+ }
90585
+ cleanupRulerObservers();
90586
+ window.removeEventListener("resize", syncRulerOffset);
90241
90587
  editor.value?.destroy();
90242
90588
  editor.value = null;
90243
90589
  });
@@ -90249,18 +90595,28 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
90249
90595
  __props.options.rulerContainer && rulersVisible.value && !!activeEditor.value ? (vue.openBlock(), vue.createBlock(vue.Teleport, {
90250
90596
  key: 0,
90251
90597
  to: __props.options.rulerContainer
90598
+ }, [
90599
+ vue.createBaseVNode("div", {
90600
+ class: "ruler-host",
90601
+ style: vue.normalizeStyle(rulerHostStyle.value)
90602
+ }, [
90603
+ vue.createVNode(Ruler, {
90604
+ class: "ruler superdoc-ruler",
90605
+ editor: activeEditor.value,
90606
+ onMarginChange: handleMarginChange
90607
+ }, null, 8, ["editor"])
90608
+ ], 4)
90609
+ ], 8, ["to"])) : rulersVisible.value && !!activeEditor.value ? (vue.openBlock(), vue.createElementBlock("div", {
90610
+ key: 1,
90611
+ class: "ruler-host",
90612
+ style: vue.normalizeStyle(rulerHostStyle.value)
90252
90613
  }, [
90253
90614
  vue.createVNode(Ruler, {
90254
- class: "ruler superdoc-ruler",
90615
+ class: "ruler",
90255
90616
  editor: activeEditor.value,
90256
90617
  onMarginChange: handleMarginChange
90257
90618
  }, null, 8, ["editor"])
90258
- ], 8, ["to"])) : rulersVisible.value && !!activeEditor.value ? (vue.openBlock(), vue.createBlock(Ruler, {
90259
- key: 1,
90260
- class: "ruler",
90261
- editor: activeEditor.value,
90262
- onMarginChange: handleMarginChange
90263
- }, null, 8, ["editor"])) : vue.createCommentVNode("", true),
90619
+ ], 4)) : vue.createCommentVNode("", true),
90264
90620
  vue.createBaseVNode("div", {
90265
90621
  class: "super-editor",
90266
90622
  ref_key: "editorWrapper",
@@ -90365,7 +90721,7 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
90365
90721
  };
90366
90722
  }
90367
90723
  });
90368
- const SuperEditor = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-8dd4cf59"]]);
90724
+ const SuperEditor = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-f5c4f915"]]);
90369
90725
  const _hoisted_1 = ["innerHTML"];
90370
90726
  const _sfc_main = {
90371
90727
  __name: "SuperInput",