@harbour-enterprises/superdoc 1.3.0-next.3 → 1.3.0-next.5

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-CVOKZex3.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-DMbipzpl.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";
@@ -13392,8 +13392,12 @@ const createOrUpdateTrackedChangeComment = ({ event, marks, deletionNodes, nodes
13392
13392
  const hasMatchingId = changeMarks.find((mark) => mark.attrs.id === id);
13393
13393
  if (hasMatchingId) nodesWithMark.push(node2);
13394
13394
  });
13395
+ const nodesToProcess = nodesWithMark.length ? nodesWithMark : node ? [node] : [];
13396
+ if (!nodesToProcess.length) {
13397
+ return;
13398
+ }
13395
13399
  const { deletionText, trackedChangeText } = getTrackedChangeText({
13396
- nodes: nodesWithMark.length ? nodesWithMark : [node],
13400
+ nodes: nodesToProcess,
13397
13401
  mark: trackedMark,
13398
13402
  trackedChangeType,
13399
13403
  isDeletionInsertion
@@ -14109,6 +14113,45 @@ const updateYdocDocxData = async (editor, ydoc) => {
14109
14113
  console.warn("[collaboration] Failed to update Ydoc docx data", error);
14110
14114
  }
14111
14115
  };
14116
+ let isApplyingRemoteChanges = false;
14117
+ const isApplyingRemoteHeaderFooterChanges = () => isApplyingRemoteChanges;
14118
+ const pushHeaderFooterToYjs = (editor, type, sectionId, content) => {
14119
+ if (isApplyingRemoteChanges) return;
14120
+ const ydoc = editor?.options?.ydoc;
14121
+ if (!ydoc) return;
14122
+ const headerFooterMap = ydoc.getMap("headerFooterJson");
14123
+ const key2 = `${type}:${sectionId}`;
14124
+ const existing = headerFooterMap.get(key2)?.content;
14125
+ if (existing && JSON.stringify(existing) === JSON.stringify(content)) {
14126
+ return;
14127
+ }
14128
+ ydoc.transact(() => headerFooterMap.set(key2, { type, sectionId, content }), {
14129
+ event: "header-footer-update",
14130
+ user: editor.options.user
14131
+ });
14132
+ };
14133
+ const applyRemoteHeaderFooterChanges = (editor, key2, data) => {
14134
+ if (!editor || editor.isDestroyed || !editor.converter) return;
14135
+ const { type, sectionId, content } = data;
14136
+ if (!type || !sectionId || !content) return;
14137
+ isApplyingRemoteChanges = true;
14138
+ try {
14139
+ const storage = editor.converter[`${type}s`];
14140
+ if (storage) storage[sectionId] = content;
14141
+ editor.converter.headerFooterModified = true;
14142
+ const editors = editor.converter[`${type}Editors`];
14143
+ editors?.forEach((item) => {
14144
+ if (item.id === sectionId && item.editor) {
14145
+ item.editor.replaceContent(content);
14146
+ }
14147
+ });
14148
+ editor.emit("remoteHeaderFooterChanged", { type, sectionId, content });
14149
+ } finally {
14150
+ setTimeout(() => {
14151
+ isApplyingRemoteChanges = false;
14152
+ }, 0);
14153
+ }
14154
+ };
14112
14155
  new PluginKey("collaboration");
14113
14156
  const Collaboration = Extension.create({
14114
14157
  name: "collaboration",
@@ -14137,6 +14180,18 @@ const Collaboration = Extension.create({
14137
14180
  }
14138
14181
  });
14139
14182
  });
14183
+ const headerFooterMap = this.options.ydoc.getMap("headerFooterJson");
14184
+ headerFooterMap.observe((event) => {
14185
+ if (event.transaction.local) return;
14186
+ event.changes.keys.forEach((change, key2) => {
14187
+ if (change.action === "add" || change.action === "update") {
14188
+ const data = headerFooterMap.get(key2);
14189
+ if (data) {
14190
+ applyRemoteHeaderFooterChanges(this.editor, key2, data);
14191
+ }
14192
+ }
14193
+ });
14194
+ });
14140
14195
  return [syncPlugin];
14141
14196
  },
14142
14197
  addCommands() {
@@ -15279,7 +15334,7 @@ const canUseDOM = () => {
15279
15334
  return false;
15280
15335
  }
15281
15336
  };
15282
- const summaryVersion = "1.3.0-next.3";
15337
+ const summaryVersion = "1.3.0-next.5";
15283
15338
  const nodeKeys = ["group", "content", "marks", "inline", "atom", "defining", "code", "tableRole", "summary"];
15284
15339
  const markKeys = ["group", "inclusive", "excludes", "spanning", "code"];
15285
15340
  function mapAttributes(attrs) {
@@ -17912,7 +17967,7 @@ class Editor extends EventEmitter {
17912
17967
  * Process collaboration migrations
17913
17968
  */
17914
17969
  processCollaborationMigrations() {
17915
- console.debug("[checkVersionMigrations] Current editor version", "1.3.0-next.3");
17970
+ console.debug("[checkVersionMigrations] Current editor version", "1.3.0-next.5");
17916
17971
  if (!this.options.ydoc) return;
17917
17972
  const metaMap = this.options.ydoc.getMap("meta");
17918
17973
  let docVersion = metaMap.get("version");
@@ -27489,7 +27544,12 @@ class DomPainter {
27489
27544
  const hanging = paraIndent?.hanging ?? 0;
27490
27545
  const isFirstLineOfPara = lineIndex === 0 || lineIndex === void 0;
27491
27546
  const firstLineOffsetForCumX = isFirstLineOfPara ? firstLine - hanging : 0;
27492
- const indentOffset = indentLeft + firstLineOffsetForCumX;
27547
+ const wordLayoutValue = block.attrs?.wordLayout;
27548
+ const wordLayout = isMinimalWordLayout(wordLayoutValue) ? wordLayoutValue : void 0;
27549
+ const isListParagraph = Boolean(wordLayout?.marker);
27550
+ const rawTextStartPx = typeof wordLayout?.marker?.textStartX === "number" && Number.isFinite(wordLayout.marker.textStartX) ? wordLayout.marker.textStartX : typeof wordLayout?.textStartPx === "number" && Number.isFinite(wordLayout.textStartPx) ? wordLayout.textStartPx : void 0;
27551
+ const listIndentOffset = isFirstLineOfPara ? rawTextStartPx ?? indentLeft : indentLeft;
27552
+ const indentOffset = isListParagraph ? listIndentOffset : indentLeft + firstLineOffsetForCumX;
27493
27553
  let cumulativeX = 0;
27494
27554
  const segmentsByRun = /* @__PURE__ */ new Map();
27495
27555
  line.segments.forEach((segment) => {
@@ -40050,6 +40110,15 @@ const pxToPt = (px) => {
40050
40110
  if (px == null || !Number.isFinite(px)) return void 0;
40051
40111
  return px / PX_PER_PT;
40052
40112
  };
40113
+ const convertIndentTwipsToPx$1 = (indent) => {
40114
+ if (!indent) return void 0;
40115
+ const result = {};
40116
+ if (isFiniteNumber(indent.left)) result.left = twipsToPx$1(indent.left);
40117
+ if (isFiniteNumber(indent.right)) result.right = twipsToPx$1(indent.right);
40118
+ if (isFiniteNumber(indent.firstLine)) result.firstLine = twipsToPx$1(indent.firstLine);
40119
+ if (isFiniteNumber(indent.hanging)) result.hanging = twipsToPx$1(indent.hanging);
40120
+ return Object.keys(result).length ? result : void 0;
40121
+ };
40053
40122
  const isFiniteNumber = (value) => typeof value === "number" && Number.isFinite(value);
40054
40123
  const isPlainObject$2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
40055
40124
  const normalizePrefix = (value) => {
@@ -41160,6 +41229,19 @@ function tokenNodeToRun(node, positions, defaultFont, defaultSize, inheritedMark
41160
41229
  const effectiveMarks = nodeMarks.length > 0 ? nodeMarks : marksAsAttrs;
41161
41230
  const marks = [...effectiveMarks, ...inheritedMarks ?? []];
41162
41231
  applyMarksToRun(run, marks, hyperlinkConfig, themeColors);
41232
+ if (marksAsAttrs.length > 0) {
41233
+ run._explicitFont = true;
41234
+ }
41235
+ console.debug("[token-debug] tokenNodeToRun", {
41236
+ token,
41237
+ fontFamily: run.fontFamily,
41238
+ fontSize: run.fontSize,
41239
+ defaultFont,
41240
+ defaultSize,
41241
+ nodeMarksCount: nodeMarks.length,
41242
+ marksAsAttrsCount: marksAsAttrs.length,
41243
+ inheritedMarksCount: inheritedMarks?.length ?? 0
41244
+ });
41163
41245
  return run;
41164
41246
  }
41165
41247
  const EIGHTHS_PER_POINT = 8;
@@ -43074,8 +43156,11 @@ const computeParagraphAttrs = (para, styleContext, listCounterContext, converter
43074
43156
  const hydrated = hydrationOverride ?? hydrateParagraphStyleAttrs(para, converterContext);
43075
43157
  const mergedSpacing = mergeSpacingSources(hydrated?.spacing, paragraphProps.spacing, attrs.spacing);
43076
43158
  const normalizedSpacing = normalizeParagraphSpacing(mergedSpacing);
43077
- const indentSource = attrs.indent ?? paragraphProps.indent ?? hydrated?.indent;
43078
- const normalizedIndent = normalizePxIndent(indentSource) ?? normalizeParagraphIndent(indentSource ?? attrs.textIndent);
43159
+ const normalizeIndentObject = (value) => {
43160
+ if (!value || typeof value !== "object") return;
43161
+ return normalizePxIndent(value) ?? convertIndentTwipsToPx(value);
43162
+ };
43163
+ const normalizedIndent = normalizeIndentObject(attrs.indent) ?? convertIndentTwipsToPx(paragraphProps.indent) ?? convertIndentTwipsToPx(hydrated?.indent) ?? normalizeParagraphIndent(attrs.textIndent);
43079
43164
  const unwrapTabStops = (tabStops) => {
43080
43165
  if (!Array.isArray(tabStops)) {
43081
43166
  return void 0;
@@ -44645,9 +44730,12 @@ function paragraphToFlowBlocks$1(para, nextBlockId, positions, defaultFont, defa
44645
44730
  };
44646
44731
  } else {
44647
44732
  const spacingSource = para.attrs?.spacing !== void 0 ? para.attrs.spacing : paragraphProps.spacing !== void 0 ? paragraphProps.spacing : paragraphHydration?.spacing;
44648
- const indentSource = para.attrs?.indent ?? paragraphProps.indent ?? paragraphHydration?.indent;
44733
+ const normalizeIndentObject = (value) => {
44734
+ if (!value || typeof value !== "object") return;
44735
+ return normalizePxIndent(value) ?? convertIndentTwipsToPx$1(value);
44736
+ };
44649
44737
  const normalizedSpacing = normalizeParagraphSpacing(spacingSource);
44650
- const normalizedIndent = normalizePxIndent(indentSource) ?? normalizeParagraphIndent(indentSource ?? para.attrs?.textIndent);
44738
+ const normalizedIndent = normalizeIndentObject(para.attrs?.indent) ?? convertIndentTwipsToPx$1(paragraphProps.indent) ?? convertIndentTwipsToPx$1(paragraphHydration?.indent) ?? normalizeParagraphIndent(para.attrs?.textIndent);
44651
44739
  const styleNodeAttrs = paragraphHydration?.tabStops && !para.attrs?.tabStops && !para.attrs?.tabs ? { ...para.attrs ?? {}, tabStops: paragraphHydration.tabStops } : para.attrs ?? {};
44652
44740
  const styleNode = buildStyleNodeFromAttrs(styleNodeAttrs, normalizedSpacing, normalizedIndent);
44653
44741
  if (styleNodeAttrs.styleId == null && paragraphProps.styleId) {
@@ -44902,6 +44990,10 @@ function paragraphToFlowBlocks$1(para, nextBlockId, positions, defaultFont, defa
44902
44990
  if (TOKEN_INLINE_TYPES.has(node.type)) {
44903
44991
  const tokenKind = TOKEN_INLINE_TYPES.get(node.type);
44904
44992
  if (tokenKind) {
44993
+ const marksAsAttrs = Array.isArray(node.attrs?.marksAsAttrs) ? node.attrs.marksAsAttrs : [];
44994
+ const nodeMarks = node.marks ?? [];
44995
+ const effectiveMarks = nodeMarks.length > 0 ? nodeMarks : marksAsAttrs;
44996
+ const mergedMarks = [...effectiveMarks, ...inheritedMarks ?? []];
44905
44997
  const tokenRun = tokenNodeToRun(
44906
44998
  node,
44907
44999
  positions,
@@ -44918,6 +45010,23 @@ function paragraphToFlowBlocks$1(para, nextBlockId, positions, defaultFont, defa
44918
45010
  const inlineStyleId = getInlineStyleId(inheritedMarks);
44919
45011
  applyRunStyles2(tokenRun, inlineStyleId, activeRunStyleId);
44920
45012
  applyBaseRunDefaults(tokenRun, baseRunDefaults, defaultFont, defaultSize);
45013
+ if (mergedMarks.length > 0) {
45014
+ applyMarksToRun(
45015
+ tokenRun,
45016
+ mergedMarks,
45017
+ hyperlinkConfig,
45018
+ themeColors,
45019
+ converterContext?.backgroundColor
45020
+ );
45021
+ }
45022
+ console.debug("[token-debug] paragraph-token-run", {
45023
+ token: tokenRun.token,
45024
+ fontFamily: tokenRun.fontFamily,
45025
+ fontSize: tokenRun.fontSize,
45026
+ inlineStyleId,
45027
+ runStyleId: activeRunStyleId,
45028
+ mergedMarksCount: mergedMarks.length
45029
+ });
44921
45030
  currentRuns.push(tokenRun);
44922
45031
  }
44923
45032
  return;
@@ -46368,6 +46477,9 @@ const createHeaderFooterEditor = ({
46368
46477
  };
46369
46478
  const onHeaderFooterDataUpdate = async ({ editor, transaction }, mainEditor, sectionId, type) => {
46370
46479
  if (!type || !sectionId) return;
46480
+ if (isApplyingRemoteHeaderFooterChanges()) {
46481
+ return;
46482
+ }
46371
46483
  const updatedData = editor.getUpdatedJson();
46372
46484
  const editorsList = mainEditor.converter[`${type}Editors`];
46373
46485
  if (Array.isArray(editorsList)) {
@@ -46391,6 +46503,7 @@ const onHeaderFooterDataUpdate = async ({ editor, transaction }, mainEditor, sec
46391
46503
  if (editor.docChanged && mainEditor.converter) {
46392
46504
  mainEditor.converter.headerFooterModified = true;
46393
46505
  }
46506
+ pushHeaderFooterToYjs(mainEditor, type, sectionId, updatedData);
46394
46507
  await updateYdocDocxData(mainEditor);
46395
46508
  };
46396
46509
  const setEditorToolbar = ({ editor }, mainEditor) => {
@@ -47898,6 +48011,77 @@ function isLineBreakRun(run) {
47898
48011
  function isFieldAnnotationRun(run) {
47899
48012
  return run.kind === "fieldAnnotation";
47900
48013
  }
48014
+ function measureTabAlignmentGroup(startRunIndex, runs, ctx2, decimalSeparator = ".") {
48015
+ const result = {
48016
+ totalWidth: 0,
48017
+ runs: [],
48018
+ endRunIndex: runs.length
48019
+ };
48020
+ let foundDecimal = false;
48021
+ for (let i = startRunIndex; i < runs.length; i++) {
48022
+ const run = runs[i];
48023
+ if (isTabRun(run)) {
48024
+ result.endRunIndex = i;
48025
+ break;
48026
+ }
48027
+ if (isLineBreakRun(run) || run.kind === "break" && run.breakType === "line") {
48028
+ result.endRunIndex = i;
48029
+ break;
48030
+ }
48031
+ if (run.kind === "text" || run.kind === void 0) {
48032
+ const textRun = run;
48033
+ const text = textRun.text || "";
48034
+ if (text.length > 0) {
48035
+ const { font } = buildFontString(textRun);
48036
+ const width = measureRunWidth(text, font, ctx2, textRun, 0);
48037
+ let beforeDecimalWidth;
48038
+ if (!foundDecimal) {
48039
+ const decimalIdx = text.indexOf(decimalSeparator);
48040
+ if (decimalIdx >= 0) {
48041
+ foundDecimal = true;
48042
+ const beforeText = text.slice(0, decimalIdx);
48043
+ beforeDecimalWidth = beforeText.length > 0 ? measureRunWidth(beforeText, font, ctx2, textRun, 0) : 0;
48044
+ result.beforeDecimalWidth = result.totalWidth + beforeDecimalWidth;
48045
+ }
48046
+ }
48047
+ result.runs.push({
48048
+ runIndex: i,
48049
+ width,
48050
+ text,
48051
+ beforeDecimalWidth
48052
+ });
48053
+ result.totalWidth += width;
48054
+ } else {
48055
+ result.runs.push({ runIndex: i, width: 0, text: "" });
48056
+ }
48057
+ continue;
48058
+ }
48059
+ if (isImageRun(run)) {
48060
+ const leftSpace = run.distLeft ?? 0;
48061
+ const rightSpace = run.distRight ?? 0;
48062
+ const imageWidth = run.width + leftSpace + rightSpace;
48063
+ result.runs.push({ runIndex: i, width: imageWidth });
48064
+ result.totalWidth += imageWidth;
48065
+ continue;
48066
+ }
48067
+ if (isFieldAnnotationRun(run)) {
48068
+ const fontSize2 = run.fontSize ?? DEFAULT_FIELD_ANNOTATION_FONT_SIZE;
48069
+ const { font } = buildFontString({
48070
+ fontFamily: run.fontFamily ?? "Arial",
48071
+ fontSize: fontSize2,
48072
+ bold: run.bold,
48073
+ italic: run.italic
48074
+ });
48075
+ const textWidth = run.displayLabel ? measureRunWidth(run.displayLabel, font, ctx2, run, 0) : 0;
48076
+ const pillWidth = textWidth + FIELD_ANNOTATION_PILL_PADDING;
48077
+ result.runs.push({ runIndex: i, width: pillWidth });
48078
+ result.totalWidth += pillWidth;
48079
+ continue;
48080
+ }
48081
+ result.runs.push({ runIndex: i, width: 0 });
48082
+ }
48083
+ return result;
48084
+ }
47901
48085
  async function measureBlock(block, constraints) {
47902
48086
  const normalized = normalizeConstraints(constraints);
47903
48087
  if (block.kind === "drawing") {
@@ -48021,6 +48205,7 @@ async function measureParagraphBlock(block, maxWidth) {
48021
48205
  let pendingTabAlignment = null;
48022
48206
  let lastAppliedTabAlign = null;
48023
48207
  const warnedTabVals = /* @__PURE__ */ new Set();
48208
+ let activeTabGroup = null;
48024
48209
  const validateTabStopVal = (stop) => {
48025
48210
  if (!ALLOWED_TAB_VALS.has(stop.val) && !warnedTabVals.has(stop.val)) {
48026
48211
  warnedTabVals.add(stop.val);
@@ -48200,6 +48385,7 @@ async function measureParagraphBlock(block, maxWidth) {
48200
48385
  continue;
48201
48386
  }
48202
48387
  if (isTabRun(run)) {
48388
+ activeTabGroup = null;
48203
48389
  if (!currentLine) {
48204
48390
  currentLine = {
48205
48391
  fromRun: runIndex,
@@ -48224,12 +48410,6 @@ async function measureParagraphBlock(block, maxWidth) {
48224
48410
  currentLine.maxFontSize = Math.max(currentLine.maxFontSize, 12);
48225
48411
  currentLine.toRun = runIndex;
48226
48412
  currentLine.toChar = 1;
48227
- if (stop) {
48228
- validateTabStopVal(stop);
48229
- pendingTabAlignment = { target: clampedTarget, val: stop.val };
48230
- } else {
48231
- pendingTabAlignment = null;
48232
- }
48233
48413
  if (stop && stop.leader && stop.leader !== "none") {
48234
48414
  const leaderStyle = stop.leader;
48235
48415
  const from3 = Math.min(originX, clampedTarget);
@@ -48237,6 +48417,36 @@ async function measureParagraphBlock(block, maxWidth) {
48237
48417
  if (!currentLine.leaders) currentLine.leaders = [];
48238
48418
  currentLine.leaders.push({ from: from3, to, style: leaderStyle });
48239
48419
  }
48420
+ if (stop) {
48421
+ validateTabStopVal(stop);
48422
+ if (stop.val === "end" || stop.val === "center" || stop.val === "decimal") {
48423
+ const groupMeasure = measureTabAlignmentGroup(runIndex + 1, runsToProcess, ctx2, decimalSeparator);
48424
+ if (groupMeasure.totalWidth > 0) {
48425
+ let groupStartX;
48426
+ if (stop.val === "end") {
48427
+ groupStartX = Math.max(0, clampedTarget - groupMeasure.totalWidth);
48428
+ } else if (stop.val === "center") {
48429
+ groupStartX = Math.max(0, clampedTarget - groupMeasure.totalWidth / 2);
48430
+ } else {
48431
+ const beforeDecimal = groupMeasure.beforeDecimalWidth ?? groupMeasure.totalWidth;
48432
+ groupStartX = Math.max(0, clampedTarget - beforeDecimal);
48433
+ }
48434
+ activeTabGroup = {
48435
+ measure: groupMeasure,
48436
+ startX: groupStartX,
48437
+ currentX: groupStartX,
48438
+ target: clampedTarget,
48439
+ val: stop.val
48440
+ };
48441
+ currentLine.width = roundValue(groupStartX);
48442
+ }
48443
+ pendingTabAlignment = null;
48444
+ } else {
48445
+ pendingTabAlignment = { target: clampedTarget, val: stop.val };
48446
+ }
48447
+ } else {
48448
+ pendingTabAlignment = null;
48449
+ }
48240
48450
  continue;
48241
48451
  }
48242
48452
  if (isImageRun(run)) {
@@ -48247,7 +48457,10 @@ async function measureParagraphBlock(block, maxWidth) {
48247
48457
  const bottomSpace = run.distBottom ?? 0;
48248
48458
  const imageHeight = run.height + topSpace + bottomSpace;
48249
48459
  let imageStartX;
48250
- if (pendingTabAlignment && currentLine) {
48460
+ if (activeTabGroup && currentLine) {
48461
+ imageStartX = activeTabGroup.currentX;
48462
+ activeTabGroup.currentX = roundValue(activeTabGroup.currentX + imageWidth);
48463
+ } else if (pendingTabAlignment && currentLine) {
48251
48464
  imageStartX = alignPendingTabForWidth(imageWidth);
48252
48465
  }
48253
48466
  if (!currentLine) {
@@ -48272,10 +48485,14 @@ async function measureParagraphBlock(block, maxWidth) {
48272
48485
  }
48273
48486
  ]
48274
48487
  };
48488
+ if (activeTabGroup && runIndex + 1 >= activeTabGroup.measure.endRunIndex) {
48489
+ activeTabGroup = null;
48490
+ }
48275
48491
  continue;
48276
48492
  }
48277
48493
  const appliedTabAlign = lastAppliedTabAlign;
48278
- if (currentLine.width + imageWidth > currentLine.maxWidth && currentLine.width > 0) {
48494
+ const skipFitCheck = activeTabGroup !== null;
48495
+ if (!skipFitCheck && currentLine.width + imageWidth > currentLine.maxWidth && currentLine.width > 0) {
48279
48496
  trimTrailingWrapSpaces(currentLine);
48280
48497
  const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing, currentLine.maxFontInfo);
48281
48498
  const lineBase = currentLine;
@@ -48288,6 +48505,7 @@ async function measureParagraphBlock(block, maxWidth) {
48288
48505
  tabStopCursor = 0;
48289
48506
  pendingTabAlignment = null;
48290
48507
  lastAppliedTabAlign = null;
48508
+ activeTabGroup = null;
48291
48509
  currentLine = {
48292
48510
  fromRun: runIndex,
48293
48511
  fromChar: 0,
@@ -48320,6 +48538,9 @@ async function measureParagraphBlock(block, maxWidth) {
48320
48538
  ...imageStartX !== void 0 ? { x: imageStartX } : {}
48321
48539
  });
48322
48540
  }
48541
+ if (activeTabGroup && runIndex + 1 >= activeTabGroup.measure.endRunIndex) {
48542
+ activeTabGroup = null;
48543
+ }
48323
48544
  const tabAlign = appliedTabAlign;
48324
48545
  if (tabAlign && currentLine && tabAlign.val === "end") {
48325
48546
  currentLine.width = roundValue(tabAlign.target);
@@ -48495,7 +48716,11 @@ async function measureParagraphBlock(block, maxWidth) {
48495
48716
  }
48496
48717
  }
48497
48718
  let segmentStartX;
48498
- if (currentLine && pendingTabAlignment) {
48719
+ let inActiveTabGroup = false;
48720
+ if (activeTabGroup && currentLine) {
48721
+ segmentStartX = activeTabGroup.currentX;
48722
+ inActiveTabGroup = true;
48723
+ } else if (currentLine && pendingTabAlignment) {
48499
48724
  segmentStartX = alignSegmentAtTab(segment, font, run, charPosInRun);
48500
48725
  if (segmentStartX == null) {
48501
48726
  segmentStartX = currentLine.width;
@@ -48532,6 +48757,7 @@ async function measureParagraphBlock(block, maxWidth) {
48532
48757
  tabStopCursor = 0;
48533
48758
  pendingTabAlignment = null;
48534
48759
  lastAppliedTabAlign = null;
48760
+ activeTabGroup = null;
48535
48761
  currentLine = {
48536
48762
  fromRun: runIndex,
48537
48763
  fromChar: spaceStartChar,
@@ -48550,7 +48776,19 @@ async function measureParagraphBlock(block, maxWidth) {
48550
48776
  currentLine.width = roundValue(currentLine.width + boundarySpacing2 + singleSpaceWidth);
48551
48777
  currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run);
48552
48778
  currentLine.maxFontSize = Math.max(currentLine.maxFontSize, run.fontSize);
48553
- appendSegment(currentLine.segments, runIndex, spaceStartChar, spaceEndChar, singleSpaceWidth);
48779
+ let spaceExplicitX;
48780
+ if (inActiveTabGroup && activeTabGroup) {
48781
+ spaceExplicitX = activeTabGroup.currentX;
48782
+ activeTabGroup.currentX = roundValue(activeTabGroup.currentX + singleSpaceWidth);
48783
+ }
48784
+ appendSegment(
48785
+ currentLine.segments,
48786
+ runIndex,
48787
+ spaceStartChar,
48788
+ spaceEndChar,
48789
+ singleSpaceWidth,
48790
+ spaceExplicitX
48791
+ );
48554
48792
  currentLine.spaceCount += 1;
48555
48793
  }
48556
48794
  }
@@ -48698,7 +48936,7 @@ async function measureParagraphBlock(block, maxWidth) {
48698
48936
  const totalWidthWithWord = currentLine.width + boundarySpacing + wordCommitWidth + // Safe cast: only TextRuns produce word segments from split(), other run types are handled earlier
48699
48937
  (shouldIncludeDelimiterSpace ? run.letterSpacing ?? 0 : 0);
48700
48938
  const availableWidth = currentLine.maxWidth - WIDTH_FUDGE_PX2;
48701
- let shouldBreak = currentLine.width + boundarySpacing + wordOnlyWidth > availableWidth && currentLine.width > 0 && !isTocEntry;
48939
+ let shouldBreak = !inActiveTabGroup && currentLine.width + boundarySpacing + wordOnlyWidth > availableWidth && currentLine.width > 0 && !isTocEntry;
48702
48940
  let compressedWidth = null;
48703
48941
  if (shouldBreak && justifyAlignment) {
48704
48942
  const isLastNonEmptyWordInSegment = wordIndex === lastNonEmptyWordIndex;
@@ -48763,15 +49001,14 @@ async function measureParagraphBlock(block, maxWidth) {
48763
49001
  currentLine.width = roundValue(currentLine.width + boundarySpacing + wordOnlyWidth);
48764
49002
  currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run);
48765
49003
  currentLine.maxFontSize = Math.max(currentLine.maxFontSize, run.fontSize);
48766
- const useExplicitXHere = wordIndex === 0 && segmentStartX !== void 0;
48767
- appendSegment(
48768
- currentLine.segments,
48769
- runIndex,
48770
- wordStartChar,
48771
- wordEndNoSpace,
48772
- wordOnlyWidth,
48773
- useExplicitXHere ? segmentStartX : void 0
48774
- );
49004
+ let explicitXHere;
49005
+ if (inActiveTabGroup && activeTabGroup) {
49006
+ explicitXHere = activeTabGroup.currentX;
49007
+ activeTabGroup.currentX = roundValue(activeTabGroup.currentX + wordOnlyWidth);
49008
+ } else if (wordIndex === 0 && segmentStartX !== void 0) {
49009
+ explicitXHere = segmentStartX;
49010
+ }
49011
+ appendSegment(currentLine.segments, runIndex, wordStartChar, wordEndNoSpace, wordOnlyWidth, explicitXHere);
48775
49012
  trimTrailingWrapSpaces(currentLine);
48776
49013
  const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing, currentLine.maxFontInfo);
48777
49014
  const lineBase = currentLine;
@@ -48786,8 +49023,13 @@ async function measureParagraphBlock(block, maxWidth) {
48786
49023
  }
48787
49024
  const newToChar = shouldIncludeDelimiterSpace ? wordEndWithSpace : wordEndNoSpace;
48788
49025
  currentLine.toChar = newToChar;
48789
- const useExplicitX = wordIndex === 0 && segmentStartX !== void 0;
48790
- const explicitX = useExplicitX ? segmentStartX : void 0;
49026
+ let explicitX;
49027
+ if (inActiveTabGroup && activeTabGroup) {
49028
+ explicitX = activeTabGroup.currentX;
49029
+ activeTabGroup.currentX = roundValue(activeTabGroup.currentX + wordCommitWidth);
49030
+ } else if (wordIndex === 0 && segmentStartX !== void 0) {
49031
+ explicitX = segmentStartX;
49032
+ }
48791
49033
  const targetWidth = compressedWidth != null ? compressedWidth : currentLine.width + boundarySpacing + wordCommitWidth + (shouldIncludeDelimiterSpace ? run.letterSpacing ?? 0 : 0);
48792
49034
  if (compressedWidth != null) {
48793
49035
  currentLine.naturalWidth = roundValue(totalWidthWithWord);
@@ -48809,6 +49051,12 @@ async function measureParagraphBlock(block, maxWidth) {
48809
49051
  }
48810
49052
  }
48811
49053
  lastAppliedTabAlign = null;
49054
+ if (activeTabGroup && runIndex + 1 >= activeTabGroup.measure.endRunIndex) {
49055
+ if (currentLine && activeTabGroup.val === "end") {
49056
+ currentLine.width = roundValue(activeTabGroup.target);
49057
+ }
49058
+ activeTabGroup = null;
49059
+ }
48812
49060
  if (!isLastSegment) {
48813
49061
  pendingTabAlignment = null;
48814
49062
  if (!currentLine) {
@@ -51242,6 +51490,17 @@ class PresentationEditor extends EventEmitter {
51242
51490
  event: "collaborationReady",
51243
51491
  handler: handleCollaborationReady
51244
51492
  });
51493
+ const handleRemoteHeaderFooterChanged = (payload) => {
51494
+ this.#headerFooterAdapter?.invalidate(payload.sectionId);
51495
+ this.#headerFooterManager?.refresh();
51496
+ this.#pendingDocChange = true;
51497
+ this.#scheduleRerender();
51498
+ };
51499
+ this.#editor.on("remoteHeaderFooterChanged", handleRemoteHeaderFooterChanged);
51500
+ this.#editorListeners.push({
51501
+ event: "remoteHeaderFooterChanged",
51502
+ handler: handleRemoteHeaderFooterChanged
51503
+ });
51245
51504
  }
51246
51505
  /**
51247
51506
  * Setup awareness event subscriptions for remote cursor tracking.
@@ -2,6 +2,6 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  require("../chunks/jszip-C8_CqJxM.cjs");
4
4
  require("../chunks/helpers-nOdwpmwb.cjs");
5
- const superEditor_converter = require("../chunks/SuperConverter-XGlv5pME.cjs");
5
+ const superEditor_converter = require("../chunks/SuperConverter-tcg6NQjY.cjs");
6
6
  require("../chunks/uuid-R7L08bOx.cjs");
7
7
  exports.SuperConverter = superEditor_converter.SuperConverter;
@@ -1,6 +1,6 @@
1
1
  import "../chunks/jszip-B1fkPkPJ.es.js";
2
2
  import "../chunks/helpers-C8e9wR5l.es.js";
3
- import { S } from "../chunks/SuperConverter-CVOKZex3.es.js";
3
+ import { S } from "../chunks/SuperConverter-DMbipzpl.es.js";
4
4
  import "../chunks/uuid-CjlX8hrF.es.js";
5
5
  export {
6
6
  S as SuperConverter
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const index = require("./chunks/index-D0lYfjMI.cjs");
3
+ const index = require("./chunks/index-BHIGTNEQ.cjs");
4
4
  const superEditor_docxZipper = require("./super-editor/docx-zipper.cjs");
5
5
  const superEditor_fileZipper = require("./super-editor/file-zipper.cjs");
6
6
  const vue = require("./chunks/vue-De9wkgLl.cjs");
7
- const superEditor_converter = require("./chunks/SuperConverter-XGlv5pME.cjs");
7
+ const superEditor_converter = require("./chunks/SuperConverter-tcg6NQjY.cjs");
8
8
  function isNodeType(node, name) {
9
9
  return node.type.name === name;
10
10
  }
@@ -1,9 +1,9 @@
1
- import { ax as Node, ay as Mark } from "./chunks/index-M8MvGhiF.es.js";
2
- import { ao, au, a9, ab, aw, am, av, aA, an, ak, aq, az, aa, as, aC, aE, aB, ac, aD, ar, at } from "./chunks/index-M8MvGhiF.es.js";
1
+ import { ax as Node, ay as Mark } from "./chunks/index-BSxlafD_.es.js";
2
+ import { ao, au, a9, ab, aw, am, av, aA, an, ak, aq, az, aa, as, aC, aE, aB, ac, aD, ar, at } from "./chunks/index-BSxlafD_.es.js";
3
3
  import { default as default2 } from "./super-editor/docx-zipper.es.js";
4
4
  import { createZip } from "./super-editor/file-zipper.es.js";
5
5
  import { d as defineComponent, E as createElementBlock, G as openBlock, K as createBaseVNode } from "./chunks/vue-BnBKJwCW.es.js";
6
- import { S, r } from "./chunks/SuperConverter-CVOKZex3.es.js";
6
+ import { S, r } from "./chunks/SuperConverter-DMbipzpl.es.js";
7
7
  function isNodeType(node, name) {
8
8
  return node.type.name === name;
9
9
  }
package/dist/superdoc.cjs CHANGED
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const index = require("./chunks/index-D0lYfjMI.cjs");
4
- const superdoc = require("./chunks/index-HQW67fDU.cjs");
5
- const superEditor_converter = require("./chunks/SuperConverter-XGlv5pME.cjs");
3
+ const index = require("./chunks/index-BHIGTNEQ.cjs");
4
+ const superdoc = require("./chunks/index-79lZpkMi.cjs");
5
+ const superEditor_converter = require("./chunks/SuperConverter-tcg6NQjY.cjs");
6
6
  const blankDocx = require("./chunks/blank-docx-DfW3Eeh2.cjs");
7
7
  require("./chunks/jszip-C8_CqJxM.cjs");
8
8
  require("./chunks/helpers-nOdwpmwb.cjs");
@@ -1,6 +1,6 @@
1
- import { au, ab, aw, av, as, a7, ac, ar, at } from "./chunks/index-M8MvGhiF.es.js";
2
- import { D, H, P, S, c } from "./chunks/index-e6096-IC.es.js";
3
- import { S as S2, r } from "./chunks/SuperConverter-CVOKZex3.es.js";
1
+ import { au, ab, aw, av, as, a7, ac, ar, at } from "./chunks/index-BSxlafD_.es.js";
2
+ import { D, H, P, S, c } from "./chunks/index-B697vddF.es.js";
3
+ import { S as S2, r } from "./chunks/SuperConverter-DMbipzpl.es.js";
4
4
  import { B } from "./chunks/blank-docx-ABm6XYAA.es.js";
5
5
  import "./chunks/jszip-B1fkPkPJ.es.js";
6
6
  import "./chunks/helpers-C8e9wR5l.es.js";