@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.
@@ -1,6 +1,6 @@
1
1
  import { B as Buffer$2 } from "./jszip-B1fkPkPJ.es.js";
2
2
  import { t as twipsToInches, i as inchesToTwips, p as ptToTwips, l as linesToTwips, a as twipsToLines, b as pixelsToTwips, h as halfPointToPoints, c as twipsToPixels$2, d as convertSizeToCSS, e as inchesToPixels } from "./helpers-C8e9wR5l.es.js";
3
- import { g as generateDocxRandomId, T as TextSelection$1, o as objectIncludes, w as wrapTextsInRuns, D as DOMParser$1, c as createDocFromMarkdown, a as createDocFromHTML, b as chainableEditorState, d as convertMarkdownToHTML, f as findParentNode, e as findParentNodeClosestToPos, h as generateRandom32BitHex, i as generateRandomSigned32BitIntStrId, P as PluginKey, j as Plugin, M as Mapping, N as NodeSelection, k as Selection, l as Slice, m as DOMSerializer, F as Fragment, n as Mark$1, p as dropPoint, A as AllSelection, q as Schema$1, s as canSplit, t as resolveRunProperties, u as encodeMarksFromRPr, v as liftTarget, x as canJoin, y as joinPoint, z as replaceStep$1, R as ReplaceAroundStep$1, B as htmlHandler, C as ReplaceStep, E as getResolvedParagraphProperties, G as changeListLevel, H as isList$1, I as updateNumberingProperties, L as ListHelpers, J as inputRulesPlugin, K as TrackDeleteMarkName$1, O as TrackInsertMarkName$1, Q as TrackFormatMarkName$1, U as AddMarkStep, V as RemoveMarkStep, W as CommandService, S as SuperConverter, X as EditorState, Y as unflattenListsInHtml, Z as SelectionRange, _ as Transform, $ as createOoxmlResolver, a0 as translator, a1 as translator$1, a2 as resolveDocxFontFamily, a3 as _getReferencedTableStyles, a4 as decodeRPrFromMarks, a5 as calculateResolvedParagraphProperties, a6 as encodeCSSFromPPr, a7 as encodeCSSFromRPr, a8 as generateOrderedListIndex, a9 as docxNumberingHelpers, aa as InputRule, ab as insertNewRelationship, ac as kebabCase$1, ad as getUnderlineCssString } from "./SuperConverter-lLx4GqcF.es.js";
3
+ import { g as generateDocxRandomId, T as TextSelection$1, o as objectIncludes, w as wrapTextsInRuns, D as DOMParser$1, c as createDocFromMarkdown, a as createDocFromHTML, b as chainableEditorState, d as convertMarkdownToHTML, f as findParentNode, e as findParentNodeClosestToPos, h as generateRandom32BitHex, i as generateRandomSigned32BitIntStrId, P as PluginKey, j as Plugin, M as Mapping, N as NodeSelection, k as Selection, l as Slice, m as DOMSerializer, F as Fragment, n as Mark$1, p as dropPoint, A as AllSelection, q as Schema$1, s as canSplit, t as resolveRunProperties, u as encodeMarksFromRPr, v as liftTarget, x as canJoin, y as joinPoint, z as replaceStep$1, R as ReplaceAroundStep$1, B as htmlHandler, C as ReplaceStep, E as getResolvedParagraphProperties, G as changeListLevel, H as isList$1, I as updateNumberingProperties, L as ListHelpers, J as inputRulesPlugin, K as TrackDeleteMarkName$1, O as TrackInsertMarkName$1, Q as TrackFormatMarkName$1, U as AddMarkStep, V as RemoveMarkStep, W as CommandService, S as SuperConverter, X as EditorState, Y as unflattenListsInHtml, Z as SelectionRange, _ as Transform, $ as createOoxmlResolver, a0 as translator, a1 as translator$1, a2 as resolveDocxFontFamily, a3 as combineIndentProperties, a4 as _getReferencedTableStyles, a5 as decodeRPrFromMarks, a6 as calculateResolvedParagraphProperties, a7 as encodeCSSFromPPr, a8 as encodeCSSFromRPr, a9 as generateOrderedListIndex, aa as docxNumberingHelpers, ab as InputRule, ac as insertNewRelationship, ad as kebabCase$1, ae as getUnderlineCssString } from "./SuperConverter-z20LprsX.es.js";
4
4
  import { p as process$1, r as ref, C as global$1, c as computed, E as createElementBlock, F as Fragment$1, S as renderList, O as withModifiers, G as openBlock, P as normalizeClass, M as createCommentVNode, H as toDisplayString, K as createBaseVNode, U as createApp, f as onMounted, X as onUnmounted, R as withDirectives, v as unref, Y as vModelText, y as nextTick, L as normalizeStyle, u as watch, Z as withKeys, _ as createTextVNode, I as createVNode, h, $ as readonly, s as getCurrentInstance, o as onBeforeUnmount, j as reactive, b as onBeforeMount, i as inject, a0 as onActivated, a1 as onDeactivated, a2 as Comment, d as defineComponent, a as provide, g as Teleport, t as toRef, a3 as renderSlot, a4 as isVNode, D as shallowRef, w as watchEffect, T as Transition, a5 as mergeProps, a6 as vShow, a7 as cloneVNode, a8 as Text$2, m as markRaw, N as createBlock, J as withCtx, a9 as useCssVars, V as resolveDynamicComponent, aa as normalizeProps, ab as guardReactiveProps } from "./vue-BnBKJwCW.es.js";
5
5
  import "./jszip.min-DCl8qkFO.es.js";
6
6
  import { E as EventEmitter$1 } from "./eventemitter3-CwrdEv8r.es.js";
@@ -10936,6 +10936,105 @@ const setSectionHeaderFooterAtSelection = ({ headerInches, footerInches } = {})
10936
10936
  tr.setNodeMarkup(pos, void 0, nextAttrs, node.marks);
10937
10937
  return true;
10938
10938
  };
10939
+ function findGoverningSectPrParagraph(doc2, selectionPos) {
10940
+ const candidates = [];
10941
+ doc2.descendants((node, nodePos) => {
10942
+ if (node.type?.name === "paragraph" && node.attrs?.paragraphProperties?.sectPr) {
10943
+ candidates.push({ node, pos: nodePos });
10944
+ }
10945
+ });
10946
+ if (!candidates.length) return null;
10947
+ const inside = candidates.find((c2) => selectionPos >= c2.pos && selectionPos < c2.pos + c2.node.nodeSize);
10948
+ if (inside) return inside;
10949
+ const atOrAfter = candidates.find((c2) => c2.pos >= selectionPos);
10950
+ return atOrAfter ?? candidates[candidates.length - 1];
10951
+ }
10952
+ const setSectionPageMarginsAtSelection = ({ topInches, rightInches, bottomInches, leftInches } = {}) => ({ tr, state, editor }) => {
10953
+ if (!state || !editor) {
10954
+ console.warn("[setSectionPageMarginsAtSelection] Missing state or editor");
10955
+ return false;
10956
+ }
10957
+ const hasTop = typeof topInches === "number";
10958
+ const hasRight = typeof rightInches === "number";
10959
+ const hasBottom = typeof bottomInches === "number";
10960
+ const hasLeft = typeof leftInches === "number";
10961
+ if (!hasTop && !hasRight && !hasBottom && !hasLeft) {
10962
+ console.warn("[setSectionPageMarginsAtSelection] No margin values provided");
10963
+ return false;
10964
+ }
10965
+ if (hasTop && topInches < 0 || hasRight && rightInches < 0 || hasBottom && bottomInches < 0 || hasLeft && leftInches < 0) {
10966
+ console.warn("[setSectionPageMarginsAtSelection] Margin values must be >= 0");
10967
+ return false;
10968
+ }
10969
+ const updates = {};
10970
+ if (hasTop) updates.topInches = topInches;
10971
+ if (hasRight) updates.rightInches = rightInches;
10972
+ if (hasBottom) updates.bottomInches = bottomInches;
10973
+ if (hasLeft) updates.leftInches = leftInches;
10974
+ const { from: from3 } = state.selection;
10975
+ const governing = findGoverningSectPrParagraph(state.doc, from3);
10976
+ if (governing) {
10977
+ const { node, pos } = governing;
10978
+ const paraProps = node.attrs?.paragraphProperties || null;
10979
+ const existingSectPr = paraProps?.sectPr || null;
10980
+ if (!existingSectPr) {
10981
+ console.warn("[setSectionPageMarginsAtSelection] Paragraph found but has no sectPr");
10982
+ return false;
10983
+ }
10984
+ const sectPr2 = JSON.parse(JSON.stringify(existingSectPr));
10985
+ try {
10986
+ updateSectionMargins({ type: "sectPr", sectPr: sectPr2 }, updates);
10987
+ } catch (err) {
10988
+ console.error("[setSectionPageMarginsAtSelection] Failed to update sectPr:", err);
10989
+ return false;
10990
+ }
10991
+ const resolved = getSectPrMargins(sectPr2);
10992
+ const normalizedSectionMargins = {
10993
+ top: resolved.top ?? null,
10994
+ right: resolved.right ?? null,
10995
+ bottom: resolved.bottom ?? null,
10996
+ left: resolved.left ?? null,
10997
+ header: resolved.header ?? null,
10998
+ footer: resolved.footer ?? null
10999
+ };
11000
+ const newParagraphProperties = { ...paraProps || {}, sectPr: sectPr2 };
11001
+ const nextAttrs = {
11002
+ ...node.attrs,
11003
+ paragraphProperties: newParagraphProperties,
11004
+ sectionMargins: normalizedSectionMargins
11005
+ };
11006
+ tr.setNodeMarkup(pos, void 0, nextAttrs, node.marks);
11007
+ tr.setMeta("forceUpdatePagination", true);
11008
+ return true;
11009
+ }
11010
+ const docAttrs = state.doc.attrs ?? {};
11011
+ const converter = editor.converter ?? null;
11012
+ const baseBodySectPr = docAttrs.bodySectPr || converter?.bodySectPr || null;
11013
+ const sectPr = baseBodySectPr != null ? JSON.parse(JSON.stringify(baseBodySectPr)) : { type: "element", name: "w:sectPr", elements: [] };
11014
+ try {
11015
+ updateSectionMargins({ type: "sectPr", sectPr }, updates);
11016
+ } catch (err) {
11017
+ console.error("[setSectionPageMarginsAtSelection] Failed to update sectPr:", err);
11018
+ return false;
11019
+ }
11020
+ if (converter) {
11021
+ converter.bodySectPr = sectPr;
11022
+ if (!converter.pageStyles) converter.pageStyles = {};
11023
+ if (!converter.pageStyles.pageMargins) converter.pageStyles.pageMargins = {};
11024
+ const pageMargins = converter.pageStyles.pageMargins;
11025
+ const resolved = getSectPrMargins(sectPr);
11026
+ if (resolved.top != null) pageMargins.top = resolved.top;
11027
+ if (resolved.right != null) pageMargins.right = resolved.right;
11028
+ if (resolved.bottom != null) pageMargins.bottom = resolved.bottom;
11029
+ if (resolved.left != null) pageMargins.left = resolved.left;
11030
+ if (resolved.header != null) pageMargins.header = resolved.header;
11031
+ if (resolved.footer != null) pageMargins.footer = resolved.footer;
11032
+ }
11033
+ const nextDocAttrs = { ...docAttrs, bodySectPr: sectPr };
11034
+ tr.setNodeMarkup(0, void 0, nextDocAttrs);
11035
+ tr.setMeta("forceUpdatePagination", true);
11036
+ return true;
11037
+ };
10939
11038
  const insertSectionBreakAtSelection = ({ headerInches, footerInches } = {}) => ({ tr, state, editor }) => {
10940
11039
  if (!state || !editor) {
10941
11040
  console.warn("[insertSectionBreakAtSelection] Missing state or editor");
@@ -11467,6 +11566,7 @@ const commands$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePr
11467
11566
  setMeta,
11468
11567
  setNode,
11469
11568
  setSectionHeaderFooterAtSelection,
11569
+ setSectionPageMarginsAtSelection,
11470
11570
  setTextIndentation,
11471
11571
  setTextSelection,
11472
11572
  skipTab,
@@ -15334,7 +15434,7 @@ const canUseDOM = () => {
15334
15434
  return false;
15335
15435
  }
15336
15436
  };
15337
- const summaryVersion = "1.3.0-next.9";
15437
+ const summaryVersion = "1.3.0";
15338
15438
  const nodeKeys = ["group", "content", "marks", "inline", "atom", "defining", "code", "tableRole", "summary"];
15339
15439
  const markKeys = ["group", "inclusive", "excludes", "spanning", "code"];
15340
15440
  function mapAttributes(attrs) {
@@ -17336,9 +17436,8 @@ class Editor extends EventEmitter {
17336
17436
  try {
17337
17437
  const jsonObj = json;
17338
17438
  const attrs = jsonObj.attrs;
17339
- const hasBody = attrs && "bodySectPr" in attrs;
17340
17439
  const converter = this.converter;
17341
- if (!hasBody && converter && converter.bodySectPr) {
17440
+ if (converter && converter.bodySectPr) {
17342
17441
  jsonObj.attrs = attrs || {};
17343
17442
  jsonObj.attrs.bodySectPr = converter.bodySectPr;
17344
17443
  }
@@ -17967,7 +18066,7 @@ class Editor extends EventEmitter {
17967
18066
  * Process collaboration migrations
17968
18067
  */
17969
18068
  processCollaborationMigrations() {
17970
- console.debug("[checkVersionMigrations] Current editor version", "1.3.0-next.9");
18069
+ console.debug("[checkVersionMigrations] Current editor version", "1.3.0");
17971
18070
  if (!this.options.ydoc) return;
17972
18071
  const metaMap = this.options.ydoc.getMap("meta");
17973
18072
  let docVersion = metaMap.get("version");
@@ -40266,6 +40365,13 @@ const applyTrackedChangesModeToRuns = (runs, config, hyperlinkConfig, applyMarks
40266
40365
  );
40267
40366
  }
40268
40367
  });
40368
+ if ((config.mode === "original" || config.mode === "final") && config.enabled) {
40369
+ filtered.forEach((run) => {
40370
+ if (isTextRun$1(run) && run.trackedChange && (run.trackedChange.kind === "insert" || run.trackedChange.kind === "delete")) {
40371
+ delete run.trackedChange;
40372
+ }
40373
+ });
40374
+ }
40269
40375
  }
40270
40376
  return filtered;
40271
40377
  };
@@ -43331,7 +43437,16 @@ const computeParagraphAttrs = (para, styleContext, listCounterContext, converter
43331
43437
  if (!value || typeof value !== "object") return;
43332
43438
  return normalizePxIndent(value) ?? convertIndentTwipsToPx(value);
43333
43439
  };
43334
- const normalizedIndent = normalizeIndentObject(attrs.indent) ?? convertIndentTwipsToPx(paragraphProps.indent) ?? convertIndentTwipsToPx(hydrated?.indent) ?? normalizeParagraphIndent(attrs.textIndent);
43440
+ const hydratedIndentPx = convertIndentTwipsToPx(hydrated?.indent);
43441
+ const paragraphIndentPx = convertIndentTwipsToPx(paragraphProps.indent);
43442
+ const textIndentPx = normalizeParagraphIndent(attrs.textIndent);
43443
+ const attrsIndentPx = normalizeIndentObject(attrs.indent);
43444
+ const indentChain = [];
43445
+ if (hydratedIndentPx) indentChain.push({ indent: hydratedIndentPx });
43446
+ if (paragraphIndentPx) indentChain.push({ indent: paragraphIndentPx });
43447
+ if (textIndentPx) indentChain.push({ indent: textIndentPx });
43448
+ if (attrsIndentPx) indentChain.push({ indent: attrsIndentPx });
43449
+ const normalizedIndent = indentChain.length ? combineIndentProperties(indentChain).indent : void 0;
43335
43450
  const unwrapTabStops = (tabStops) => {
43336
43451
  if (!Array.isArray(tabStops)) {
43337
43452
  return void 0;
@@ -48610,10 +48725,13 @@ async function measureParagraphBlock(block, maxWidth) {
48610
48725
  };
48611
48726
  }
48612
48727
  const originX = currentLine.width;
48613
- const { target, nextIndex, stop } = getNextTabStopPx(currentLine.width, tabStops, tabStopCursor);
48728
+ const effectiveIndent = lines.length === 0 ? indentLeft + rawFirstLineOffset : indentLeft;
48729
+ const absCurrentX = currentLine.width + effectiveIndent;
48730
+ const { target, nextIndex, stop } = getNextTabStopPx(absCurrentX, tabStops, tabStopCursor);
48614
48731
  tabStopCursor = nextIndex;
48615
- const clampedTarget = Math.min(target, currentLine.maxWidth);
48616
- const tabAdvance = Math.max(0, clampedTarget - currentLine.width);
48732
+ const maxAbsWidth = currentLine.maxWidth + effectiveIndent;
48733
+ const clampedTarget = Math.min(target, maxAbsWidth);
48734
+ const tabAdvance = Math.max(0, clampedTarget - absCurrentX);
48617
48735
  currentLine.width = roundValue(currentLine.width + tabAdvance);
48618
48736
  run.width = tabAdvance;
48619
48737
  currentLine.maxFontSize = Math.max(currentLine.maxFontSize, 12);
@@ -48621,8 +48739,9 @@ async function measureParagraphBlock(block, maxWidth) {
48621
48739
  currentLine.toChar = 1;
48622
48740
  if (stop && stop.leader && stop.leader !== "none") {
48623
48741
  const leaderStyle = stop.leader;
48624
- const from3 = Math.min(originX, clampedTarget);
48625
- const to = Math.max(originX, clampedTarget);
48742
+ const relativeTarget = clampedTarget - effectiveIndent;
48743
+ const from3 = Math.min(originX, relativeTarget);
48744
+ const to = Math.max(originX, relativeTarget);
48626
48745
  if (!currentLine.leaders) currentLine.leaders = [];
48627
48746
  currentLine.leaders.push({ from: from3, to, style: leaderStyle });
48628
48747
  }
@@ -48631,27 +48750,28 @@ async function measureParagraphBlock(block, maxWidth) {
48631
48750
  if (stop.val === "end" || stop.val === "center" || stop.val === "decimal") {
48632
48751
  const groupMeasure = measureTabAlignmentGroup(runIndex + 1, runsToProcess, ctx2, decimalSeparator);
48633
48752
  if (groupMeasure.totalWidth > 0) {
48753
+ const relativeTarget = clampedTarget - effectiveIndent;
48634
48754
  let groupStartX;
48635
48755
  if (stop.val === "end") {
48636
- groupStartX = Math.max(0, clampedTarget - groupMeasure.totalWidth);
48756
+ groupStartX = Math.max(0, relativeTarget - groupMeasure.totalWidth);
48637
48757
  } else if (stop.val === "center") {
48638
- groupStartX = Math.max(0, clampedTarget - groupMeasure.totalWidth / 2);
48758
+ groupStartX = Math.max(0, relativeTarget - groupMeasure.totalWidth / 2);
48639
48759
  } else {
48640
48760
  const beforeDecimal = groupMeasure.beforeDecimalWidth ?? groupMeasure.totalWidth;
48641
- groupStartX = Math.max(0, clampedTarget - beforeDecimal);
48761
+ groupStartX = Math.max(0, relativeTarget - beforeDecimal);
48642
48762
  }
48643
48763
  activeTabGroup = {
48644
48764
  measure: groupMeasure,
48645
48765
  startX: groupStartX,
48646
48766
  currentX: groupStartX,
48647
- target: clampedTarget,
48767
+ target: relativeTarget,
48648
48768
  val: stop.val
48649
48769
  };
48650
48770
  currentLine.width = roundValue(groupStartX);
48651
48771
  }
48652
48772
  pendingTabAlignment = null;
48653
48773
  } else {
48654
- pendingTabAlignment = { target: clampedTarget, val: stop.val };
48774
+ pendingTabAlignment = { target: clampedTarget - effectiveIndent, val: stop.val };
48655
48775
  }
48656
48776
  } else {
48657
48777
  pendingTabAlignment = null;
@@ -49292,10 +49412,13 @@ async function measureParagraphBlock(block, maxWidth) {
49292
49412
  };
49293
49413
  }
49294
49414
  const originX = currentLine.width;
49295
- const { target, nextIndex, stop } = getNextTabStopPx(currentLine.width, tabStops, tabStopCursor);
49415
+ const effectiveIndent = lines.length === 0 ? indentLeft + rawFirstLineOffset : indentLeft;
49416
+ const absCurrentX = currentLine.width + effectiveIndent;
49417
+ const { target, nextIndex, stop } = getNextTabStopPx(absCurrentX, tabStops, tabStopCursor);
49296
49418
  tabStopCursor = nextIndex;
49297
- const clampedTarget = Math.min(target, currentLine.maxWidth);
49298
- const tabAdvance = Math.max(0, clampedTarget - currentLine.width);
49419
+ const maxAbsWidth = currentLine.maxWidth + effectiveIndent;
49420
+ const clampedTarget = Math.min(target, maxAbsWidth);
49421
+ const tabAdvance = Math.max(0, clampedTarget - absCurrentX);
49299
49422
  currentLine.width = roundValue(currentLine.width + tabAdvance);
49300
49423
  currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run);
49301
49424
  currentLine.maxFontSize = Math.max(currentLine.maxFontSize, run.fontSize);
@@ -49304,14 +49427,15 @@ async function measureParagraphBlock(block, maxWidth) {
49304
49427
  charPosInRun += 1;
49305
49428
  if (stop) {
49306
49429
  validateTabStopVal(stop);
49307
- pendingTabAlignment = { target: clampedTarget, val: stop.val };
49430
+ pendingTabAlignment = { target: clampedTarget - effectiveIndent, val: stop.val };
49308
49431
  } else {
49309
49432
  pendingTabAlignment = null;
49310
49433
  }
49311
49434
  if (stop && stop.leader && stop.leader !== "none" && stop.leader !== "middleDot") {
49312
49435
  const leaderStyle = stop.leader;
49313
- const from3 = Math.min(originX, clampedTarget);
49314
- const to = Math.max(originX, clampedTarget);
49436
+ const relativeTarget = clampedTarget - effectiveIndent;
49437
+ const from3 = Math.min(originX, relativeTarget);
49438
+ const to = Math.max(originX, relativeTarget);
49315
49439
  if (!currentLine.leaders) currentLine.leaders = [];
49316
49440
  currentLine.leaders.push({ from: from3, to, style: leaderStyle });
49317
49441
  }
@@ -49587,7 +49711,11 @@ async function measureTableBlock(block, constraints) {
49587
49711
  }
49588
49712
  async function measureImageBlock(block, constraints) {
49589
49713
  const intrinsic = getIntrinsicImageSize(block, constraints.maxWidth);
49590
- const maxWidth = constraints.maxWidth > 0 ? constraints.maxWidth : intrinsic.width;
49714
+ const isBlockBehindDoc = block.anchor?.behindDoc;
49715
+ const isBlockWrapBehindDoc = block.wrap?.type === "None" && block.wrap?.behindDoc;
49716
+ const bypassWidthConstraint = isBlockBehindDoc || isBlockWrapBehindDoc;
49717
+ const isWidthConstraintBypassed = bypassWidthConstraint || constraints.maxWidth <= 0;
49718
+ const maxWidth = isWidthConstraintBypassed ? intrinsic.width : constraints.maxWidth;
49591
49719
  const hasNegativeVerticalPosition = block.anchor?.isAnchored && (typeof block.anchor?.offsetV === "number" && block.anchor.offsetV < 0 || typeof block.margin?.top === "number" && block.margin.top < 0);
49592
49720
  const maxHeight = hasNegativeVerticalPosition || !constraints.maxHeight || constraints.maxHeight <= 0 ? Infinity : constraints.maxHeight;
49593
49721
  const widthScale = maxWidth / intrinsic.width;
@@ -50754,9 +50882,10 @@ class PresentationEditor extends EventEmitter {
50754
50882
  throw new TypeError("[PresentationEditor] setTrackedChangesOverrides expects an object or undefined");
50755
50883
  }
50756
50884
  if (overrides !== void 0) {
50757
- if (overrides.mode !== void 0 && !["review", "simple", "original"].includes(overrides.mode)) {
50885
+ const validModes = ["review", "original", "final", "off"];
50886
+ if (overrides.mode !== void 0 && !validModes.includes(overrides.mode)) {
50758
50887
  throw new TypeError(
50759
- `[PresentationEditor] Invalid tracked changes mode "${overrides.mode}". Must be one of: review, simple, original`
50888
+ `[PresentationEditor] Invalid tracked changes mode "${overrides.mode}". Must be one of: ${validModes.join(", ")}`
50760
50889
  );
50761
50890
  }
50762
50891
  if (overrides.enabled !== void 0 && typeof overrides.enabled !== "boolean") {
@@ -54707,7 +54836,7 @@ class PresentationEditor extends EventEmitter {
54707
54836
  const zoom = this.#layoutOptions.zoom ?? 1;
54708
54837
  const layoutMode = this.#layoutOptions.layoutMode ?? "vertical";
54709
54838
  const pages = this.#layoutState.layout?.pages;
54710
- const pageGap = this.#layoutState.layout?.pageGap ?? this.#getEffectivePageGap();
54839
+ const pageGap = this.#getEffectivePageGap();
54711
54840
  const defaultWidth = this.#layoutOptions.pageSize?.w ?? DEFAULT_PAGE_SIZE.w;
54712
54841
  const defaultHeight = this.#layoutOptions.pageSize?.h ?? DEFAULT_PAGE_SIZE.h;
54713
54842
  let maxWidth = defaultWidth;
@@ -57818,7 +57947,11 @@ const Document = Node$1.create({
57818
57947
  */
57819
57948
  clearDocument: () => ({ commands: commands2 }) => {
57820
57949
  return commands2.setContent("<p></p>");
57821
- }
57950
+ },
57951
+ /**
57952
+ * Set section page margins (top/right/bottom/left) for the section at the current selection.
57953
+ */
57954
+ setSectionPageMarginsAtSelection
57822
57955
  };
57823
57956
  }
57824
57957
  });
@@ -58472,12 +58605,18 @@ function findParagraphContext($pos, cache2, helpers2) {
58472
58605
  return null;
58473
58606
  }
58474
58607
  function extractParagraphContext(node, startPos, helpers2, depth = 0) {
58475
- const paragraphProperties = getResolvedParagraphProperties(node) ?? {};
58608
+ const paragraphProperties = getResolvedParagraphProperties(node) ?? node.attrs?.paragraphProperties ?? {};
58476
58609
  const alignmentAliases = { left: "start", right: "end" };
58477
58610
  let tabStops = [];
58478
58611
  if (Array.isArray(paragraphProperties.tabStops)) {
58479
58612
  tabStops = paragraphProperties.tabStops.map((stop) => {
58480
58613
  const ref2 = stop?.tab;
58614
+ if (!ref2 && stop?.pos != null) {
58615
+ return {
58616
+ ...stop,
58617
+ pos: twipsToPixels(Number(stop.pos) || 0)
58618
+ };
58619
+ }
58481
58620
  if (!ref2) return stop || null;
58482
58621
  const rawType = ref2.tabType || "start";
58483
58622
  const mappedVal = alignmentAliases[rawType] || rawType;
@@ -59743,6 +59882,13 @@ function createLayoutRequest(doc2, paragraphPos, view, helpers2, revision, parag
59743
59882
  pos: entry.pos,
59744
59883
  nodeSize: node.nodeSize
59745
59884
  });
59885
+ } else if (node.type.name === "lineBreak" || node.type.name === "hardBreak") {
59886
+ spans.push({
59887
+ type: node.type.name,
59888
+ spanId,
59889
+ pos: entry.pos,
59890
+ nodeSize: node.nodeSize
59891
+ });
59746
59892
  } else if (node.type.name === "text") {
59747
59893
  spans.push({
59748
59894
  type: "text",
@@ -59792,6 +59938,7 @@ function calculateTabLayout(request, measurement, view) {
59792
59938
  paragraphNode
59793
59939
  } = request;
59794
59940
  const tabs = {};
59941
+ const leftIndentPx = request.indents?.left ?? 0;
59795
59942
  let currentX = indentWidth;
59796
59943
  const measureText2 = (span) => {
59797
59944
  if (view && typeof span.from === "number" && typeof span.to === "number") {
@@ -59804,6 +59951,8 @@ function calculateTabLayout(request, measurement, view) {
59804
59951
  const span = spans[i];
59805
59952
  if (span.type === "text") {
59806
59953
  currentX += measureText2(span);
59954
+ } else if (span.type === "lineBreak" || span.type === "hardBreak") {
59955
+ currentX = leftIndentPx;
59807
59956
  } else if (span.type === "tab") {
59808
59957
  const followingText = collectFollowingText(spans, i + 1);
59809
59958
  let measureTextCallback;
@@ -59899,7 +60048,7 @@ function collectFollowingText(spans, startIndex) {
59899
60048
  let text = "";
59900
60049
  for (let i = startIndex; i < spans.length; i++) {
59901
60050
  const span = spans[i];
59902
- if (span.type === "tab") break;
60051
+ if (span.type === "tab" || span.type === "lineBreak" || span.type === "hardBreak") break;
59903
60052
  if (span.type === "text") text += span.text || "";
59904
60053
  }
59905
60054
  return text;
@@ -59909,7 +60058,7 @@ function getFollowingTextRange(spans, startIndex) {
59909
60058
  let to = null;
59910
60059
  for (let i = startIndex; i < spans.length; i++) {
59911
60060
  const span = spans[i];
59912
- if (span.type === "tab") break;
60061
+ if (span.type === "tab" || span.type === "lineBreak" || span.type === "hardBreak") break;
59913
60062
  if (span.type === "text" && typeof span.from === "number" && typeof span.to === "number") {
59914
60063
  if (from3 === null) from3 = span.from;
59915
60064
  to = span.to;
@@ -64327,6 +64476,10 @@ const Image = Node$1.create({
64327
64476
  }
64328
64477
  const hasAnchorData = Boolean(anchorData);
64329
64478
  const hasMarginOffsets = marginOffset?.horizontal != null || marginOffset?.top != null;
64479
+ const isWrapBehindDoc = wrap?.attrs?.behindDoc;
64480
+ const isAnchorBehindDoc = anchorData?.behindDoc;
64481
+ const isBehindDocAnchor = wrap?.type === "None" && (isWrapBehindDoc || isAnchorBehindDoc);
64482
+ const isAbsolutelyPositioned = style2.includes("position: absolute;");
64330
64483
  if (hasAnchorData) {
64331
64484
  switch (anchorData.hRelativeFrom) {
64332
64485
  case "page":
@@ -64354,7 +64507,6 @@ const Image = Node$1.create({
64354
64507
  style2 += "float: left;";
64355
64508
  }
64356
64509
  } else if (!anchorData.alignH && marginOffset?.horizontal != null) {
64357
- const isAbsolutelyPositioned = style2.includes("position: absolute;");
64358
64510
  if (isAbsolutelyPositioned) {
64359
64511
  style2 += `left: ${baseHorizontal}px;`;
64360
64512
  style2 += "max-width: none;";
@@ -64368,7 +64520,8 @@ const Image = Node$1.create({
64368
64520
  const relativeFromPageV = anchorData?.vRelativeFrom === "page";
64369
64521
  const relativeFromMarginV = anchorData?.vRelativeFrom === "margin";
64370
64522
  const maxMarginV = 500;
64371
- const baseTop = Math.max(0, marginOffset?.top ?? 0);
64523
+ const allowNegativeTopOffset = isBehindDocAnchor;
64524
+ const baseTop = allowNegativeTopOffset ? marginOffset?.top ?? 0 : Math.max(0, marginOffset?.top ?? 0);
64372
64525
  let rotationHorizontal = 0;
64373
64526
  let rotationTop = 0;
64374
64527
  const { rotation: rotation2 } = transformData ?? {};
@@ -64387,7 +64540,10 @@ const Image = Node$1.create({
64387
64540
  margin.left += horizontal;
64388
64541
  }
64389
64542
  }
64390
- if (top2 && !relativeFromMarginV) {
64543
+ const appliedTopViaStyle = isAbsolutelyPositioned && allowNegativeTopOffset && !relativeFromMarginV;
64544
+ if (appliedTopViaStyle) {
64545
+ style2 += `top: ${top2}px;`;
64546
+ } else if (top2 && !relativeFromMarginV) {
64391
64547
  if (relativeFromPageV && top2 >= maxMarginV) margin.top += maxMarginV;
64392
64548
  else margin.top += top2;
64393
64549
  }
@@ -64400,6 +64556,9 @@ const Image = Node$1.create({
64400
64556
  }
64401
64557
  if (margin.top) style2 += `margin-top: ${margin.top}px;`;
64402
64558
  if (margin.bottom) style2 += `margin-bottom: ${margin.bottom}px;`;
64559
+ if (isBehindDocAnchor) {
64560
+ style2 += "max-width: none;";
64561
+ }
64403
64562
  const finalAttributes = { ...htmlAttributes };
64404
64563
  if (style2) {
64405
64564
  const existingStyle = finalAttributes.style || "";
@@ -78853,7 +79012,7 @@ var ResizeObserverController = (function() {
78853
79012
  };
78854
79013
  return ResizeObserverController2;
78855
79014
  })();
78856
- var ResizeObserver = (function() {
79015
+ var ResizeObserver$1 = (function() {
78857
79016
  function ResizeObserver2(callback) {
78858
79017
  if (arguments.length === 0) {
78859
79018
  throw new TypeError("Failed to construct 'ResizeObserver': 1 argument required, but only 0 present.");
@@ -78892,7 +79051,7 @@ var ResizeObserver = (function() {
78892
79051
  class ResizeObserverDelegate {
78893
79052
  constructor() {
78894
79053
  this.handleResize = this.handleResize.bind(this);
78895
- this.observer = new (typeof window !== "undefined" && window.ResizeObserver || ResizeObserver)(this.handleResize);
79054
+ this.observer = new (typeof window !== "undefined" && window.ResizeObserver || ResizeObserver$1)(this.handleResize);
78896
79055
  this.elHandlersMap = /* @__PURE__ */ new Map();
78897
79056
  }
78898
79057
  handleResize(entries) {
@@ -89761,6 +89920,31 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
89761
89920
  },
89762
89921
  { immediate: true, deep: true }
89763
89922
  );
89923
+ watch(
89924
+ () => props.options?.rulerContainer,
89925
+ () => {
89926
+ nextTick(() => {
89927
+ syncRulerOffset();
89928
+ setupRulerObservers();
89929
+ });
89930
+ },
89931
+ { immediate: true }
89932
+ );
89933
+ watch(
89934
+ rulersVisible,
89935
+ (visible) => {
89936
+ nextTick(() => {
89937
+ if (visible) {
89938
+ syncRulerOffset();
89939
+ setupRulerObservers();
89940
+ } else {
89941
+ rulerHostStyle.value = {};
89942
+ cleanupRulerObservers();
89943
+ }
89944
+ });
89945
+ },
89946
+ { immediate: true }
89947
+ );
89764
89948
  const containerStyle = computed(() => {
89765
89949
  let maxWidth = 8.5 * 96;
89766
89950
  const ed = editor.value;
@@ -89785,6 +89969,71 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
89785
89969
  minWidth: `${scaledWidth}px`
89786
89970
  };
89787
89971
  });
89972
+ const rulerHostStyle = ref({});
89973
+ const rulerContainerEl = ref(null);
89974
+ let editorResizeObserver = null;
89975
+ let rulerContainerResizeObserver = null;
89976
+ let layoutUpdatedHandler = null;
89977
+ const resolveRulerContainer = () => {
89978
+ const container = props.options?.rulerContainer;
89979
+ if (!container) return null;
89980
+ if (typeof container === "string") {
89981
+ const doc2 = editorWrapper.value?.ownerDocument ?? document;
89982
+ return doc2.querySelector(container);
89983
+ }
89984
+ return container instanceof HTMLElement ? container : null;
89985
+ };
89986
+ const getViewportRect2 = () => {
89987
+ const host = editorWrapper.value;
89988
+ if (!host) return null;
89989
+ const viewport2 = host.querySelector(".presentation-editor__viewport");
89990
+ const target = viewport2 ?? host;
89991
+ return target.getBoundingClientRect();
89992
+ };
89993
+ const syncRulerOffset = () => {
89994
+ if (!rulersVisible.value) {
89995
+ rulerHostStyle.value = {};
89996
+ return;
89997
+ }
89998
+ rulerContainerEl.value = resolveRulerContainer();
89999
+ if (!rulerContainerEl.value) {
90000
+ rulerHostStyle.value = {};
90001
+ return;
90002
+ }
90003
+ const viewportRect = getViewportRect2();
90004
+ if (!viewportRect) return;
90005
+ const hostRect = rulerContainerEl.value.getBoundingClientRect();
90006
+ const paddingLeft = Math.max(0, viewportRect.left - hostRect.left);
90007
+ const paddingRight = Math.max(0, hostRect.right - viewportRect.right);
90008
+ rulerHostStyle.value = {
90009
+ paddingLeft: `${paddingLeft}px`,
90010
+ paddingRight: `${paddingRight}px`
90011
+ };
90012
+ };
90013
+ const cleanupRulerObservers = () => {
90014
+ if (editorResizeObserver) {
90015
+ editorResizeObserver.disconnect();
90016
+ editorResizeObserver = null;
90017
+ }
90018
+ if (rulerContainerResizeObserver) {
90019
+ rulerContainerResizeObserver.disconnect();
90020
+ rulerContainerResizeObserver = null;
90021
+ }
90022
+ };
90023
+ const setupRulerObservers = () => {
90024
+ cleanupRulerObservers();
90025
+ if (typeof ResizeObserver === "undefined") return;
90026
+ const viewportHost = editorWrapper.value;
90027
+ const rulerHost = resolveRulerContainer();
90028
+ if (viewportHost) {
90029
+ editorResizeObserver = new ResizeObserver(() => syncRulerOffset());
90030
+ editorResizeObserver.observe(viewportHost);
90031
+ }
90032
+ if (rulerHost) {
90033
+ rulerContainerResizeObserver = new ResizeObserver(() => syncRulerOffset());
90034
+ rulerContainerResizeObserver.observe(rulerHost);
90035
+ }
90036
+ };
89788
90037
  const message = useMessage();
89789
90038
  const editorWrapper = ref(null);
89790
90039
  const editorElem = ref(null);
@@ -90096,7 +90345,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
90096
90345
  presentationEditor.on("imageDeselected", () => {
90097
90346
  clearSelectedImage();
90098
90347
  });
90099
- presentationEditor.on("layoutUpdated", () => {
90348
+ layoutUpdatedHandler = () => {
90100
90349
  if (imageResizeState.visible && imageResizeState.blockId) {
90101
90350
  const escapedBlockId = CSS.escape(imageResizeState.blockId);
90102
90351
  const newElement = editorElem.value?.querySelector(
@@ -90129,13 +90378,17 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
90129
90378
  clearSelectedImage();
90130
90379
  }
90131
90380
  }
90132
- });
90381
+ nextTick(() => syncRulerOffset());
90382
+ };
90383
+ presentationEditor.on("layoutUpdated", layoutUpdatedHandler);
90133
90384
  zoomChangeHandler = ({ zoom }) => {
90134
90385
  currentZoom.value = zoom;
90386
+ nextTick(() => syncRulerOffset());
90135
90387
  };
90136
90388
  presentationEditor.on("zoomChange", zoomChangeHandler);
90137
90389
  if (typeof presentationEditor.zoom === "number") {
90138
90390
  currentZoom.value = presentationEditor.zoom;
90391
+ nextTick(() => syncRulerOffset());
90139
90392
  }
90140
90393
  }
90141
90394
  editor.value.on("paginationUpdate", () => {
@@ -90195,6 +90448,11 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
90195
90448
  onMounted(() => {
90196
90449
  initializeData();
90197
90450
  if (props.options?.suppressSkeletonLoader || !props.options?.collaborationProvider) editorReady.value = true;
90451
+ window.addEventListener("resize", syncRulerOffset, { passive: true });
90452
+ nextTick(() => {
90453
+ syncRulerOffset();
90454
+ setupRulerObservers();
90455
+ });
90198
90456
  });
90199
90457
  const handleMarginClick = (event) => {
90200
90458
  if (event.button !== 0) {
@@ -90209,10 +90467,14 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
90209
90467
  const handleMarginChange = ({ side, value }) => {
90210
90468
  const base2 = activeEditor.value;
90211
90469
  if (!base2) return;
90212
- const pageStyles2 = base2.getPageStyles();
90213
- const { pageMargins } = pageStyles2;
90214
- const update = { ...pageMargins, [side]: value };
90215
- base2?.updatePageStyle({ pageMargins: update });
90470
+ const payload = side === "left" ? { leftInches: value } : side === "right" ? { rightInches: value } : side === "top" ? { topInches: value } : side === "bottom" ? { bottomInches: value } : {};
90471
+ const didUpdateSection = typeof base2.commands?.setSectionPageMarginsAtSelection === "function" ? base2.commands.setSectionPageMarginsAtSelection(payload) : false;
90472
+ if (!didUpdateSection) {
90473
+ const pageStyles2 = base2.getPageStyles();
90474
+ const { pageMargins } = pageStyles2;
90475
+ const update = { ...pageMargins, [side]: value };
90476
+ base2?.updatePageStyle({ pageMargins: update });
90477
+ }
90216
90478
  };
90217
90479
  onBeforeUnmount(() => {
90218
90480
  stopPolling();
@@ -90221,6 +90483,12 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
90221
90483
  editor.value.off("zoomChange", zoomChangeHandler);
90222
90484
  zoomChangeHandler = null;
90223
90485
  }
90486
+ if (editor.value instanceof PresentationEditor && layoutUpdatedHandler) {
90487
+ editor.value.off("layoutUpdated", layoutUpdatedHandler);
90488
+ layoutUpdatedHandler = null;
90489
+ }
90490
+ cleanupRulerObservers();
90491
+ window.removeEventListener("resize", syncRulerOffset);
90224
90492
  editor.value?.destroy();
90225
90493
  editor.value = null;
90226
90494
  });
@@ -90232,18 +90500,28 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
90232
90500
  __props.options.rulerContainer && rulersVisible.value && !!activeEditor.value ? (openBlock(), createBlock(Teleport, {
90233
90501
  key: 0,
90234
90502
  to: __props.options.rulerContainer
90503
+ }, [
90504
+ createBaseVNode("div", {
90505
+ class: "ruler-host",
90506
+ style: normalizeStyle(rulerHostStyle.value)
90507
+ }, [
90508
+ createVNode(Ruler, {
90509
+ class: "ruler superdoc-ruler",
90510
+ editor: activeEditor.value,
90511
+ onMarginChange: handleMarginChange
90512
+ }, null, 8, ["editor"])
90513
+ ], 4)
90514
+ ], 8, ["to"])) : rulersVisible.value && !!activeEditor.value ? (openBlock(), createElementBlock("div", {
90515
+ key: 1,
90516
+ class: "ruler-host",
90517
+ style: normalizeStyle(rulerHostStyle.value)
90235
90518
  }, [
90236
90519
  createVNode(Ruler, {
90237
- class: "ruler superdoc-ruler",
90520
+ class: "ruler",
90238
90521
  editor: activeEditor.value,
90239
90522
  onMarginChange: handleMarginChange
90240
90523
  }, null, 8, ["editor"])
90241
- ], 8, ["to"])) : rulersVisible.value && !!activeEditor.value ? (openBlock(), createBlock(Ruler, {
90242
- key: 1,
90243
- class: "ruler",
90244
- editor: activeEditor.value,
90245
- onMarginChange: handleMarginChange
90246
- }, null, 8, ["editor"])) : createCommentVNode("", true),
90524
+ ], 4)) : createCommentVNode("", true),
90247
90525
  createBaseVNode("div", {
90248
90526
  class: "super-editor",
90249
90527
  ref_key: "editorWrapper",
@@ -90348,7 +90626,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
90348
90626
  };
90349
90627
  }
90350
90628
  });
90351
- const SuperEditor = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-8dd4cf59"]]);
90629
+ const SuperEditor = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-f5c4f915"]]);
90352
90630
  const _hoisted_1 = ["innerHTML"];
90353
90631
  const _sfc_main = {
90354
90632
  __name: "SuperInput",