superdoc 1.2.1 → 1.3.0-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-D7wt-eeZ.cjs");
4
+ const superEditor_converter = require("./SuperConverter-Dy0-KTCc.cjs");
5
5
  const vue = require("./vue-De9wkgLl.cjs");
6
6
  require("./jszip.min-BPh2MMAa.cjs");
7
7
  const eventemitter3 = require("./eventemitter3-BQuRcMPI.cjs");
@@ -14915,7 +14915,7 @@ const canUseDOM = () => {
14915
14915
  return false;
14916
14916
  }
14917
14917
  };
14918
- const summaryVersion = "1.2.1";
14918
+ const summaryVersion = "1.3.0-next.1";
14919
14919
  const nodeKeys = ["group", "content", "marks", "inline", "atom", "defining", "code", "tableRole", "summary"];
14920
14920
  const markKeys = ["group", "inclusive", "excludes", "spanning", "code"];
14921
14921
  function mapAttributes(attrs) {
@@ -17548,7 +17548,7 @@ class Editor extends EventEmitter {
17548
17548
  * Process collaboration migrations
17549
17549
  */
17550
17550
  processCollaborationMigrations() {
17551
- console.debug("[checkVersionMigrations] Current editor version", "1.2.1");
17551
+ console.debug("[checkVersionMigrations] Current editor version", "1.3.0-next.1");
17552
17552
  if (!this.options.ydoc) return;
17553
17553
  const metaMap = this.options.ydoc.getMap("meta");
17554
17554
  let docVersion = metaMap.get("version");
@@ -19807,6 +19807,15 @@ function calculateTabWidth(params2) {
19807
19807
  tabStopPosUsed: nextStop.pos
19808
19808
  };
19809
19809
  }
19810
+ const OOXML_PCT_DIVISOR = 5e3;
19811
+ function resolveColumnWidths(columns, availableWidth) {
19812
+ const columnCount = columns.length;
19813
+ const width = availableWidth / columnCount;
19814
+ return columns.map(() => width);
19815
+ }
19816
+ function measureRowHeights(cells, _columnWidths) {
19817
+ return cells.map(() => 20);
19818
+ }
19810
19819
  const SPACE_CHARS$1 = /* @__PURE__ */ new Set([" ", " "]);
19811
19820
  function shouldApplyJustify(params2) {
19812
19821
  const { alignment: alignment2, hasExplicitPositioning, isLastLineOfParagraph, paragraphEndsWithLineBreak, skipJustifyOverride } = params2;
@@ -20080,16 +20089,9 @@ function computeWrapExclusion(image, lineY, lineHeight2) {
20080
20089
  return null;
20081
20090
  }
20082
20091
  }
20083
- function resolveColumnWidths(columns, availableWidth) {
20084
- const columnCount = columns.length;
20085
- const width = availableWidth / columnCount;
20086
- return columns.map(() => width);
20087
- }
20088
- function measureRowHeights(cells, _columnWidths) {
20089
- return cells.map(() => 20);
20090
- }
20091
20092
  const Engines = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
20092
20093
  __proto__: null,
20094
+ OOXML_PCT_DIVISOR,
20093
20095
  calculateTabWidth,
20094
20096
  computeListIndent,
20095
20097
  computeTabStops: computeTabStops$1,
@@ -23191,6 +23193,37 @@ function renderListMarker(params2) {
23191
23193
  lineContainer.appendChild(lineEl);
23192
23194
  return lineContainer;
23193
23195
  }
23196
+ function applyParagraphBordersAndShading(paraWrapper, block) {
23197
+ const borders = block.attrs?.borders;
23198
+ if (borders) {
23199
+ paraWrapper.style.boxSizing = "border-box";
23200
+ const sideStyles = {
23201
+ top: { width: "border-top-width", style: "border-top-style", color: "border-top-color" },
23202
+ bottom: { width: "border-bottom-width", style: "border-bottom-style", color: "border-bottom-color" },
23203
+ left: { width: "border-left-width", style: "border-left-style", color: "border-left-color" },
23204
+ right: { width: "border-right-width", style: "border-right-style", color: "border-right-color" }
23205
+ };
23206
+ ["top", "bottom", "left", "right"].forEach((side) => {
23207
+ const border = borders[side];
23208
+ if (!border) return;
23209
+ const styleValue = border.style ?? "solid";
23210
+ let widthValue = typeof border.width === "number" ? Math.max(0, border.width) : 1;
23211
+ if (styleValue === "none") {
23212
+ widthValue = 0;
23213
+ }
23214
+ const cssKeys = sideStyles[side];
23215
+ paraWrapper.style.setProperty(cssKeys.style, styleValue);
23216
+ paraWrapper.style.setProperty(cssKeys.width, `${widthValue}px`);
23217
+ if (border.color) {
23218
+ paraWrapper.style.setProperty(cssKeys.color, border.color);
23219
+ }
23220
+ });
23221
+ }
23222
+ const shadingFill = block.attrs?.shading?.fill;
23223
+ if (shadingFill) {
23224
+ paraWrapper.style.backgroundColor = shadingFill;
23225
+ }
23226
+ }
23194
23227
  const renderTableCell = (deps) => {
23195
23228
  const {
23196
23229
  doc: doc2,
@@ -23353,6 +23386,9 @@ const renderTableCell = (deps) => {
23353
23386
  paraWrapper.style.left = "0";
23354
23387
  paraWrapper.style.width = "100%";
23355
23388
  applySdtDataset(paraWrapper, block.attrs?.sdt);
23389
+ applyParagraphBordersAndShading(paraWrapper, block);
23390
+ applyParagraphBorderStyles(paraWrapper, block.attrs?.borders);
23391
+ applyParagraphShadingStyles(paraWrapper, block.attrs?.shading);
23356
23392
  let renderedHeight = 0;
23357
23393
  for (let lineIdx = localStartLine; lineIdx < localEndLine && lineIdx < lines.length; lineIdx++) {
23358
23394
  const line = lines[lineIdx];
@@ -23383,15 +23419,26 @@ const renderTableCell = (deps) => {
23383
23419
  } else {
23384
23420
  const indent = block.attrs?.indent;
23385
23421
  if (indent) {
23386
- if (typeof indent.left === "number" && indent.left > 0) {
23387
- lineEl.style.paddingLeft = `${indent.left}px`;
23422
+ const leftIndent = typeof indent.left === "number" ? indent.left : 0;
23423
+ const hanging = typeof indent.hanging === "number" ? indent.hanging : 0;
23424
+ const firstLine = typeof indent.firstLine === "number" ? indent.firstLine : 0;
23425
+ const isFirstLine = lineIdx === 0 && localStartLine === 0;
23426
+ const firstLineOffset = firstLine - hanging;
23427
+ if (isFirstLine) {
23428
+ if (leftIndent > 0) {
23429
+ lineEl.style.paddingLeft = `${leftIndent}px`;
23430
+ }
23431
+ if (firstLineOffset !== 0) {
23432
+ lineEl.style.textIndent = `${firstLineOffset}px`;
23433
+ }
23434
+ } else {
23435
+ if (leftIndent > 0) {
23436
+ lineEl.style.paddingLeft = `${leftIndent}px`;
23437
+ }
23388
23438
  }
23389
23439
  if (typeof indent.right === "number" && indent.right > 0) {
23390
23440
  lineEl.style.paddingRight = `${indent.right}px`;
23391
23441
  }
23392
- if (lineIdx === 0 && typeof indent.firstLine === "number" && indent.firstLine !== 0) {
23393
- lineEl.style.textIndent = `${indent.firstLine}px`;
23394
- }
23395
23442
  }
23396
23443
  }
23397
23444
  paraWrapper.appendChild(lineEl);
@@ -31499,6 +31546,27 @@ function getCellPadding(cellIdx, blockRow) {
31499
31546
  function getCellTotalLines(cell) {
31500
31547
  return getCellLines(cell).length;
31501
31548
  }
31549
+ const ROW_HEIGHT_EPSILON = 0.1;
31550
+ function getRowContentHeight(blockRow, rowMeasure) {
31551
+ let contentHeight = 0;
31552
+ for (let cellIdx = 0; cellIdx < rowMeasure.cells.length; cellIdx++) {
31553
+ const cell = rowMeasure.cells[cellIdx];
31554
+ const cellPadding = getCellPadding(cellIdx, blockRow);
31555
+ const paddingTotal = cellPadding.top + cellPadding.bottom;
31556
+ const lines = getCellLines(cell);
31557
+ const linesHeight = lines.reduce((sum, line) => sum + (line.lineHeight || 0), 0);
31558
+ contentHeight = Math.max(contentHeight, linesHeight + paddingTotal);
31559
+ }
31560
+ return contentHeight;
31561
+ }
31562
+ function hasExplicitRowHeightSlack(blockRow, rowMeasure) {
31563
+ const rowHeightSpec = blockRow?.attrs?.rowHeight;
31564
+ if (!rowHeightSpec || rowHeightSpec.value == null || !Number.isFinite(rowHeightSpec.value)) {
31565
+ return false;
31566
+ }
31567
+ const contentHeight = getRowContentHeight(blockRow, rowMeasure);
31568
+ return rowMeasure.height > contentHeight + ROW_HEIGHT_EPSILON;
31569
+ }
31502
31570
  function mergePmRange(target, range) {
31503
31571
  if (typeof range.pmStart === "number") {
31504
31572
  target.pmStart = target.pmStart == null ? range.pmStart : Math.min(target.pmStart, range.pmStart);
@@ -31668,8 +31736,12 @@ function findSplitPoint(block, measure, startRow, availableHeight, fullPageHeigh
31668
31736
  let lastFitRow = startRow;
31669
31737
  for (let i = startRow; i < block.rows.length; i++) {
31670
31738
  const row = block.rows[i];
31671
- const rowHeight = measure.rows[i]?.height || 0;
31672
- const cantSplit = row.attrs?.tableRowProperties?.cantSplit === true;
31739
+ const rowMeasure = measure.rows[i];
31740
+ const rowHeight = rowMeasure?.height || 0;
31741
+ let cantSplit = row.attrs?.tableRowProperties?.cantSplit === true;
31742
+ if (rowMeasure && hasExplicitRowHeightSlack(row, rowMeasure) && (!fullPageHeight || rowHeight <= fullPageHeight)) {
31743
+ cantSplit = true;
31744
+ }
31673
31745
  if (accumulatedHeight + rowHeight <= availableHeight) {
31674
31746
  accumulatedHeight += rowHeight;
31675
31747
  lastFitRow = i + 1;
@@ -31760,7 +31832,10 @@ function layoutTableBlock({
31760
31832
  if (hasMeasuredRows && hasPriorFragments) {
31761
31833
  const firstRowCantSplit = block.rows[0]?.attrs?.tableRowProperties?.cantSplit === true;
31762
31834
  const firstRowHeight = measure.rows[0]?.height ?? measure.totalHeight ?? 0;
31763
- if (firstRowCantSplit) {
31835
+ const firstRowSlack = hasExplicitRowHeightSlack(block.rows[0], measure.rows[0]);
31836
+ const firstRowFitsPage = firstRowHeight <= state.contentBottom;
31837
+ const treatFirstRowAsCantSplit = firstRowCantSplit || firstRowSlack && firstRowFitsPage;
31838
+ if (treatFirstRowAsCantSplit) {
31764
31839
  if (firstRowHeight > availableHeight) {
31765
31840
  state = advanceColumn(state);
31766
31841
  }
@@ -32326,6 +32401,36 @@ const DEFAULT_PARAGRAPH_LINE_HEIGHT_PX = 20;
32326
32401
  function hasHeight(fragment) {
32327
32402
  return fragment.kind === "image" || fragment.kind === "drawing" || fragment.kind === "table";
32328
32403
  }
32404
+ function getParagraphSpacingBefore(block) {
32405
+ const spacing = block.attrs?.spacing;
32406
+ const value = spacing?.before ?? spacing?.lineSpaceBefore;
32407
+ return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 0;
32408
+ }
32409
+ function getParagraphSpacingAfter(block) {
32410
+ const spacing = block.attrs?.spacing;
32411
+ const value = spacing?.after ?? spacing?.lineSpaceAfter;
32412
+ return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 0;
32413
+ }
32414
+ function getMeasureHeight(block, measure) {
32415
+ switch (measure.kind) {
32416
+ case "paragraph":
32417
+ return measure.totalHeight;
32418
+ case "table":
32419
+ return measure.totalHeight;
32420
+ case "list":
32421
+ return measure.totalHeight;
32422
+ case "image":
32423
+ case "drawing":
32424
+ return measure.height;
32425
+ case "sectionBreak":
32426
+ case "pageBreak":
32427
+ case "columnBreak":
32428
+ return 0;
32429
+ default: {
32430
+ return block.kind === "paragraph" ? DEFAULT_PARAGRAPH_LINE_HEIGHT_PX : 0;
32431
+ }
32432
+ }
32433
+ }
32329
32434
  const DEFAULT_PAGE_SIZE$2 = { w: 612, h: 792 };
32330
32435
  const DEFAULT_MARGINS$2 = { top: 72, right: 72, bottom: 72, left: 72 };
32331
32436
  const COLUMN_EPSILON = 1e-4;
@@ -33040,6 +33145,36 @@ function layoutDocument(blocks, measures, options = {}) {
33040
33145
  placedAnchoredTableIds.add(tableBlock.id);
33041
33146
  }
33042
33147
  }
33148
+ if (paraBlock.attrs?.keepNext === true) {
33149
+ const nextBlock = blocks[index2 + 1];
33150
+ const nextMeasure = measures[index2 + 1];
33151
+ if (nextBlock && nextMeasure && nextBlock.kind !== "sectionBreak" && nextBlock.kind !== "pageBreak" && nextBlock.kind !== "columnBreak") {
33152
+ const shouldSkipAnchoredTable = nextBlock.kind === "table" && nextBlock.anchor?.isAnchored === true;
33153
+ if (!shouldSkipAnchoredTable) {
33154
+ let state = paginator.ensurePage();
33155
+ const availableHeight = state.contentBottom - state.cursorY;
33156
+ const spacingAfter = getParagraphSpacingAfter(paraBlock);
33157
+ const currentHeight = getMeasureHeight(paraBlock, measure);
33158
+ const nextHeight = getMeasureHeight(nextBlock, nextMeasure);
33159
+ const nextIsParagraph = nextBlock.kind === "paragraph" && nextMeasure.kind === "paragraph";
33160
+ const nextSpacingBefore = nextIsParagraph ? getParagraphSpacingBefore(nextBlock) : 0;
33161
+ const nextFirstLineHeight = (() => {
33162
+ if (!nextIsParagraph) {
33163
+ return nextHeight;
33164
+ }
33165
+ const firstLineHeight = nextMeasure.lines[0]?.lineHeight;
33166
+ if (typeof firstLineHeight === "number" && Number.isFinite(firstLineHeight) && firstLineHeight > 0) {
33167
+ return firstLineHeight;
33168
+ }
33169
+ return nextHeight;
33170
+ })();
33171
+ const combinedHeight = nextIsParagraph ? currentHeight + Math.max(spacingAfter, nextSpacingBefore) + nextFirstLineHeight : currentHeight + spacingAfter + nextHeight;
33172
+ if (combinedHeight > availableHeight && state.page.fragments.length > 0) {
33173
+ state = paginator.advanceColumn(state);
33174
+ }
33175
+ }
33176
+ }
33177
+ }
33043
33178
  layoutParagraphBlock(
33044
33179
  {
33045
33180
  block,
@@ -40148,6 +40283,23 @@ const applyThemeShade = (baseHex, ratio) => {
40148
40283
  };
40149
40284
  return rgbToHex(shaded);
40150
40285
  };
40286
+ const getLuminance = (hexColor) => {
40287
+ const rgb = hexToRgb(hexColor);
40288
+ if (!rgb) return 1;
40289
+ const toLinear = (channel) => {
40290
+ const c2 = channel / 255;
40291
+ return c2 <= 0.03928 ? c2 / 12.92 : Math.pow((c2 + 0.055) / 1.055, 2.4);
40292
+ };
40293
+ const R = toLinear(rgb.r);
40294
+ const G = toLinear(rgb.g);
40295
+ const B = toLinear(rgb.b);
40296
+ return 0.2126 * R + 0.7152 * G + 0.0722 * B;
40297
+ };
40298
+ const WCAG_AA_LUMINANCE_THRESHOLD = 0.18;
40299
+ const resolveAutoColor = (backgroundColor) => {
40300
+ const luminance = getLuminance(backgroundColor);
40301
+ return luminance < WCAG_AA_LUMINANCE_THRESHOLD ? "#FFFFFF" : "#000000";
40302
+ };
40151
40303
  const resolveThemeColor = (attrs, themeColors) => {
40152
40304
  if (!attrs || !themeColors) return void 0;
40153
40305
  const rawKey = attrs.themeColor;
@@ -40473,8 +40625,9 @@ const applyTextStyleMark = (run, attrs, themeColors) => {
40473
40625
  const DEFAULT_HYPERLINK_CONFIG = {
40474
40626
  enableRichHyperlinks: false
40475
40627
  };
40476
- const applyMarksToRun = (run, marks, hyperlinkConfig = DEFAULT_HYPERLINK_CONFIG, themeColors) => {
40628
+ const applyMarksToRun = (run, marks, hyperlinkConfig = DEFAULT_HYPERLINK_CONFIG, themeColors, backgroundColor) => {
40477
40629
  const isTabRun2 = run.kind === "tab";
40630
+ let markSetColor = false;
40478
40631
  marks.forEach((mark) => {
40479
40632
  const forwardedDataAttrs = extractDataAttributes(mark.attrs);
40480
40633
  try {
@@ -40510,7 +40663,11 @@ const applyMarksToRun = (run, marks, hyperlinkConfig = DEFAULT_HYPERLINK_CONFIG,
40510
40663
  }
40511
40664
  case "textStyle":
40512
40665
  if (!isTabRun2) {
40666
+ const colorBefore = run.color;
40513
40667
  applyTextStyleMark(run, mark.attrs ?? {}, themeColors);
40668
+ if (run.color !== colorBefore && run.color !== void 0) {
40669
+ markSetColor = true;
40670
+ }
40514
40671
  }
40515
40672
  break;
40516
40673
  case "commentMark":
@@ -40591,6 +40748,15 @@ const applyMarksToRun = (run, marks, hyperlinkConfig = DEFAULT_HYPERLINK_CONFIG,
40591
40748
  run.dataAttrs = { ...run.dataAttrs ?? {}, ...forwardedDataAttrs };
40592
40749
  }
40593
40750
  });
40751
+ if (!isTabRun2 && !markSetColor && backgroundColor) {
40752
+ const normalizedExisting = normalizeColor$1(run.color);
40753
+ const normalizedUpper = normalizedExisting?.toUpperCase();
40754
+ const isDefaultBlack = normalizedUpper === "#000000" || normalizedUpper === "#000";
40755
+ const isAutoColorValue = typeof run.color === "string" && ["auto", "none"].includes(run.color.trim().replace(/^#/, "").toLowerCase());
40756
+ if (!normalizedExisting || isAutoColorValue || isDefaultBlack) {
40757
+ run.color = resolveAutoColor(backgroundColor);
40758
+ }
40759
+ }
40594
40760
  };
40595
40761
  function textNodeToRun(textNode, positions, defaultFont, defaultSize, inheritedMarks = [], sdtMetadata, hyperlinkConfig = DEFAULT_HYPERLINK_CONFIG$1, themeColors) {
40596
40762
  const run = {
@@ -44413,7 +44579,13 @@ function paragraphToFlowBlocks$1(para, nextBlockId, positions, defaultFont, defa
44413
44579
  const inlineStyleId = getInlineStyleId(inheritedMarks);
44414
44580
  applyRunStyles2(run, inlineStyleId, activeRunStyleId);
44415
44581
  applyBaseRunDefaults(run, baseRunDefaults, defaultFont, defaultSize);
44416
- applyMarksToRun(run, [...node.marks ?? [], ...inheritedMarks ?? []], hyperlinkConfig, themeColors);
44582
+ applyMarksToRun(
44583
+ run,
44584
+ [...node.marks ?? [], ...inheritedMarks ?? []],
44585
+ hyperlinkConfig,
44586
+ themeColors,
44587
+ converterContext?.backgroundColor
44588
+ );
44417
44589
  currentRuns.push(run);
44418
44590
  return;
44419
44591
  }
@@ -45132,9 +45304,21 @@ const parseTableCell = (args) => {
45132
45304
  return null;
45133
45305
  }
45134
45306
  const blocks = [];
45135
- const cellConverterContext = tableStyleParagraphProps ? {
45307
+ const cellBackground = cellNode.attrs?.background;
45308
+ let cellBackgroundColor;
45309
+ if (cellBackground && typeof cellBackground.color === "string") {
45310
+ const rawColor = cellBackground.color.trim();
45311
+ if (rawColor) {
45312
+ const normalized = rawColor.startsWith("#") ? rawColor : `#${rawColor}`;
45313
+ if (/^#[0-9A-Fa-f]{3}([0-9A-Fa-f]{3})?$/.test(normalized)) {
45314
+ cellBackgroundColor = normalized;
45315
+ }
45316
+ }
45317
+ }
45318
+ const cellConverterContext = tableStyleParagraphProps || cellBackgroundColor ? {
45136
45319
  ...context.converterContext,
45137
- tableStyleParagraphProps
45320
+ ...tableStyleParagraphProps && { tableStyleParagraphProps },
45321
+ ...cellBackgroundColor && { backgroundColor: cellBackgroundColor }
45138
45322
  } : context.converterContext;
45139
45323
  const paragraphToFlowBlocks2 = context.converters?.paragraphToFlowBlocks ?? context.paragraphToFlowBlocks;
45140
45324
  const listCounterContext = context.listCounterContext;
@@ -48514,8 +48698,33 @@ async function measureParagraphBlock(block, maxWidth) {
48514
48698
  ...dropCapMeasure ? { dropCap: dropCapMeasure } : {}
48515
48699
  };
48516
48700
  }
48701
+ function validateTableWidthValue(attr) {
48702
+ const value = attr.width ?? attr.value;
48703
+ if (typeof value === "number" && Number.isFinite(value) && value > 0) {
48704
+ return value;
48705
+ }
48706
+ return void 0;
48707
+ }
48708
+ function resolveTableWidth(attrs, maxWidth) {
48709
+ const tableWidthAttr = attrs?.tableWidth;
48710
+ if (!tableWidthAttr || typeof tableWidthAttr !== "object") {
48711
+ return void 0;
48712
+ }
48713
+ const typedAttr = tableWidthAttr;
48714
+ const validValue = validateTableWidthValue(typedAttr);
48715
+ if (validValue === void 0) {
48716
+ return void 0;
48717
+ }
48718
+ if (typedAttr.type === "pct") {
48719
+ return Math.round(maxWidth * (validValue / OOXML_PCT_DIVISOR));
48720
+ } else if (typedAttr.type === "px" || typedAttr.type === "pixel") {
48721
+ return validValue;
48722
+ }
48723
+ return void 0;
48724
+ }
48517
48725
  async function measureTableBlock(block, constraints) {
48518
48726
  const maxWidth = typeof constraints === "number" ? constraints : constraints.maxWidth;
48727
+ const resolvedTableWidth = resolveTableWidth(block.attrs, maxWidth);
48519
48728
  let columnWidths;
48520
48729
  const scaleColumnWidths = (widths, targetWidth) => {
48521
48730
  const totalWidth2 = widths.reduce((a, b) => a + b, 0);
@@ -48546,19 +48755,26 @@ async function measureTableBlock(block, constraints) {
48546
48755
  return scaled;
48547
48756
  };
48548
48757
  const maxCellCount = Math.max(1, Math.max(...block.rows.map((r2) => r2.cells.length)));
48758
+ const effectiveTargetWidth = resolvedTableWidth != null ? Math.min(resolvedTableWidth, maxWidth) : maxWidth;
48549
48759
  if (block.columnWidths && block.columnWidths.length > 0) {
48550
48760
  columnWidths = [...block.columnWidths];
48551
- const hasExplicitWidth = block.attrs?.tableWidth != null;
48761
+ const hasExplicitWidth = resolvedTableWidth != null;
48552
48762
  const hasFixedLayout = block.attrs?.tableLayout === "fixed";
48553
48763
  if (hasExplicitWidth || hasFixedLayout) {
48554
48764
  const totalWidth2 = columnWidths.reduce((a, b) => a + b, 0);
48555
- if (totalWidth2 > maxWidth) {
48556
- columnWidths = scaleColumnWidths(columnWidths, maxWidth);
48765
+ if (totalWidth2 !== effectiveTargetWidth && effectiveTargetWidth > 0) {
48766
+ const scale = effectiveTargetWidth / totalWidth2;
48767
+ columnWidths = columnWidths.map((w) => Math.max(1, Math.round(w * scale)));
48768
+ const scaledSum = columnWidths.reduce((a, b) => a + b, 0);
48769
+ if (scaledSum !== effectiveTargetWidth && columnWidths.length > 0) {
48770
+ const diff = effectiveTargetWidth - scaledSum;
48771
+ columnWidths[columnWidths.length - 1] = Math.max(1, columnWidths[columnWidths.length - 1] + diff);
48772
+ }
48557
48773
  }
48558
48774
  } else {
48559
48775
  if (columnWidths.length < maxCellCount) {
48560
48776
  const usedWidth = columnWidths.reduce((a, b) => a + b, 0);
48561
- const remainingWidth = Math.max(0, maxWidth - usedWidth);
48777
+ const remainingWidth = Math.max(0, effectiveTargetWidth - usedWidth);
48562
48778
  const missingColumns = maxCellCount - columnWidths.length;
48563
48779
  const paddingWidth = Math.max(1, Math.floor(remainingWidth / missingColumns));
48564
48780
  columnWidths.push(...Array.from({ length: missingColumns }, () => paddingWidth));
@@ -48566,12 +48782,12 @@ async function measureTableBlock(block, constraints) {
48566
48782
  columnWidths = columnWidths.slice(0, maxCellCount);
48567
48783
  }
48568
48784
  const totalWidth2 = columnWidths.reduce((a, b) => a + b, 0);
48569
- if (totalWidth2 > maxWidth) {
48570
- columnWidths = scaleColumnWidths(columnWidths, maxWidth);
48785
+ if (totalWidth2 > effectiveTargetWidth) {
48786
+ columnWidths = scaleColumnWidths(columnWidths, effectiveTargetWidth);
48571
48787
  }
48572
48788
  }
48573
48789
  } else {
48574
- const columnWidth = Math.max(1, Math.floor(maxWidth / maxCellCount));
48790
+ const columnWidth = Math.max(1, Math.floor(effectiveTargetWidth / maxCellCount));
48575
48791
  columnWidths = Array.from({ length: maxCellCount }, () => columnWidth);
48576
48792
  }
48577
48793
  const gridColumnCount = columnWidths.length;
@@ -49103,6 +49319,7 @@ const CommentMarkName = "commentMark";
49103
49319
  const TrackInsertMarkName = "trackInsert";
49104
49320
  const TrackDeleteMarkName = "trackDelete";
49105
49321
  const TrackFormatMarkName = "trackFormat";
49322
+ const SUBSCRIPT_SUPERSCRIPT_SCALE = 0.65;
49106
49323
  const DEFAULT_PAGE_SIZE = { w: 612, h: 792 };
49107
49324
  const DEFAULT_MARGINS = { top: 72, right: 72, bottom: 72, left: 72 };
49108
49325
  const DEFAULT_VIRTUALIZED_PAGE_GAP = 72;
@@ -52347,6 +52564,7 @@ class PresentationEditor extends EventEmitter {
52347
52564
  );
52348
52565
  this.#domIndexObserverManager?.pause();
52349
52566
  painter.paint(layout, this.#painterHost);
52567
+ this.#applyVertAlignToLayout();
52350
52568
  this.#rebuildDomPositionIndex();
52351
52569
  this.#domIndexObserverManager?.resume();
52352
52570
  this.#layoutEpoch = layoutEpoch;
@@ -54109,6 +54327,90 @@ class PresentationEditor extends EventEmitter {
54109
54327
  this.#errorBanner = null;
54110
54328
  this.#errorBannerMessage = null;
54111
54329
  }
54330
+ /**
54331
+ * Applies vertical alignment and font scaling to layout DOM elements for subscript/superscript rendering.
54332
+ *
54333
+ * This method post-processes the painted DOM layout to apply vertical alignment styles
54334
+ * (super, sub, baseline, or custom position) based on run properties and text style marks.
54335
+ * It handles both DOCX-style vertAlign ('superscript', 'subscript', 'baseline') and
54336
+ * custom position offsets (in half-points).
54337
+ *
54338
+ * Processing logic:
54339
+ * 1. Queries all text spans with ProseMirror position markers
54340
+ * 2. For each span, resolves the ProseMirror position to find the containing run node
54341
+ * 3. Extracts vertAlign and position from run properties and/or text style marks
54342
+ * 4. Applies CSS vertical-align and font-size styles based on the extracted properties
54343
+ * 5. Position takes precedence over vertAlign when both are present
54344
+ *
54345
+ * @throws Does not throw - DOM manipulation errors are silently caught to prevent layout corruption
54346
+ * @private
54347
+ */
54348
+ #applyVertAlignToLayout() {
54349
+ const doc2 = this.#editor?.state?.doc;
54350
+ if (!doc2 || !this.#painterHost) return;
54351
+ try {
54352
+ const spans = this.#painterHost.querySelectorAll(".superdoc-line span[data-pm-start]");
54353
+ spans.forEach((span) => {
54354
+ try {
54355
+ if (span.closest(".superdoc-page-header, .superdoc-page-footer")) return;
54356
+ const pmStart = Number(span.dataset.pmStart ?? "NaN");
54357
+ if (!Number.isFinite(pmStart)) return;
54358
+ const pos = Math.max(0, Math.min(pmStart, doc2.content.size));
54359
+ const $pos = doc2.resolve(pos);
54360
+ let runNode = null;
54361
+ for (let depth = $pos.depth; depth >= 0; depth--) {
54362
+ const node = $pos.node(depth);
54363
+ if (node.type.name === "run") {
54364
+ runNode = node;
54365
+ break;
54366
+ }
54367
+ }
54368
+ let vertAlign = runNode?.attrs?.runProperties?.vertAlign ?? null;
54369
+ let position = runNode?.attrs?.runProperties?.position ?? null;
54370
+ let fontSizeHalfPts = runNode?.attrs?.runProperties?.fontSize ?? null;
54371
+ if (!vertAlign && position == null && runNode) {
54372
+ runNode.forEach((child) => {
54373
+ if (!child.isText || !child.marks?.length) return;
54374
+ const rpr = superEditor_converter.decodeRPrFromMarks(child.marks);
54375
+ if (rpr.vertAlign && !vertAlign) vertAlign = rpr.vertAlign;
54376
+ if (rpr.position != null && position == null) position = rpr.position;
54377
+ if (rpr.fontSize != null && fontSizeHalfPts == null) fontSizeHalfPts = rpr.fontSize;
54378
+ });
54379
+ }
54380
+ if (vertAlign == null && position == null) return;
54381
+ const styleEntries = [];
54382
+ if (position != null && Number.isFinite(position)) {
54383
+ const pts = helpers$1.halfPointToPoints(position);
54384
+ if (Number.isFinite(pts)) {
54385
+ styleEntries.push(`vertical-align: ${pts}pt`);
54386
+ }
54387
+ } else if (vertAlign === "superscript" || vertAlign === "subscript") {
54388
+ styleEntries.push(`vertical-align: ${vertAlign === "superscript" ? "super" : "sub"}`);
54389
+ if (fontSizeHalfPts != null && Number.isFinite(fontSizeHalfPts)) {
54390
+ const scaledPts = helpers$1.halfPointToPoints(fontSizeHalfPts * SUBSCRIPT_SUPERSCRIPT_SCALE);
54391
+ if (Number.isFinite(scaledPts)) {
54392
+ styleEntries.push(`font-size: ${scaledPts}pt`);
54393
+ } else {
54394
+ styleEntries.push(`font-size: ${SUBSCRIPT_SUPERSCRIPT_SCALE * 100}%`);
54395
+ }
54396
+ } else {
54397
+ styleEntries.push(`font-size: ${SUBSCRIPT_SUPERSCRIPT_SCALE * 100}%`);
54398
+ }
54399
+ } else if (vertAlign === "baseline") {
54400
+ styleEntries.push("vertical-align: baseline");
54401
+ }
54402
+ if (!styleEntries.length) return;
54403
+ const existing = span.getAttribute("style");
54404
+ const merged = existing ? `${existing}; ${styleEntries.join("; ")}` : styleEntries.join("; ");
54405
+ span.setAttribute("style", merged);
54406
+ } catch (error) {
54407
+ console.error("Failed to apply vertical alignment to span:", error);
54408
+ }
54409
+ });
54410
+ } catch (error) {
54411
+ console.error("Failed to apply vertical alignment to layout:", error);
54412
+ }
54413
+ }
54112
54414
  }
54113
54415
  const Color = Extension.create({
54114
54416
  name: "color",
@@ -65650,7 +65952,63 @@ const TextStyle = Mark.create({
65650
65952
  * @category Attribute
65651
65953
  * @param {string} [styleId] - Style identifier for referencing predefined styles
65652
65954
  */
65653
- styleId: {}
65955
+ styleId: {},
65956
+ /**
65957
+ * Vertical alignment for subscript/superscript text (DOCX w:vertAlign).
65958
+ * Standard values: 'superscript', 'subscript', 'baseline'.
65959
+ * When both vertAlign and position are present, position takes precedence.
65960
+ * Renders as CSS vertical-align with 65% font-size scaling for super/subscript.
65961
+ * @category Attribute
65962
+ * @param {string} [vertAlign] - Vertical alignment mode ('superscript' | 'subscript' | 'baseline')
65963
+ */
65964
+ vertAlign: {
65965
+ default: null,
65966
+ renderDOM: (attrs) => {
65967
+ if (!attrs.vertAlign || attrs.position) return {};
65968
+ if (attrs.vertAlign === "superscript") {
65969
+ return { style: "vertical-align: super; font-size: 65%;" };
65970
+ }
65971
+ if (attrs.vertAlign === "subscript") {
65972
+ return { style: "vertical-align: sub; font-size: 65%;" };
65973
+ }
65974
+ if (attrs.vertAlign === "baseline") {
65975
+ return { style: "vertical-align: baseline;" };
65976
+ }
65977
+ return {};
65978
+ },
65979
+ parseDOM: (el) => {
65980
+ const va = el.style?.verticalAlign;
65981
+ if (va === "super") return "superscript";
65982
+ if (va === "sub") return "subscript";
65983
+ if (va === "baseline") return "baseline";
65984
+ return null;
65985
+ }
65986
+ },
65987
+ /**
65988
+ * Custom vertical position offset in points (DOCX w:position).
65989
+ * Numeric value specifying vertical offset (positive raises, negative lowers).
65990
+ * Format: '{number}pt' (e.g., '2pt', '-1.5pt').
65991
+ * Takes precedence over vertAlign when both are present.
65992
+ * Renders as CSS vertical-align with the exact offset value.
65993
+ * @category Attribute
65994
+ * @param {string} [position] - Vertical position offset (e.g., '2pt', '-1pt')
65995
+ */
65996
+ position: {
65997
+ default: null,
65998
+ renderDOM: (attrs) => {
65999
+ if (!attrs.position) return {};
66000
+ return { style: `vertical-align: ${attrs.position};` };
66001
+ },
66002
+ parseDOM: (el) => {
66003
+ const va = el.style?.verticalAlign;
66004
+ if (!va) return null;
66005
+ const numeric = parseFloat(va);
66006
+ if (!Number.isNaN(numeric)) {
66007
+ return `${numeric}pt`;
66008
+ }
66009
+ return null;
66010
+ }
66011
+ }
65654
66012
  };
65655
66013
  },
65656
66014
  addCommands() {
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
- const index = require("./index-MvYBJo1p.cjs");
3
- require("./SuperConverter-D7wt-eeZ.cjs");
2
+ const index = require("./index-BNpbdx2a.cjs");
3
+ require("./SuperConverter-Dy0-KTCc.cjs");
4
4
  const blankDocx = require("./blank-docx-DfW3Eeh2.cjs");
5
5
  const eventemitter3 = require("./eventemitter3-BQuRcMPI.cjs");
6
6
  const provider = require("@hocuspocus/provider");
@@ -7461,7 +7461,7 @@ const _sfc_main = {
7461
7461
  __name: "SuperDoc",
7462
7462
  emits: ["selection-update"],
7463
7463
  setup(__props, { emit: __emit }) {
7464
- const PdfViewer = vue.defineAsyncComponent(() => Promise.resolve().then(() => require("./PdfViewer-DAuugJGV.cjs")));
7464
+ const PdfViewer = vue.defineAsyncComponent(() => Promise.resolve().then(() => require("./PdfViewer-BAoRLNIo.cjs")));
7465
7465
  const superdocStore = useSuperdocStore();
7466
7466
  const commentsStore = useCommentsStore();
7467
7467
  const {
@@ -8367,7 +8367,7 @@ class SuperDoc extends eventemitter3.EventEmitter {
8367
8367
  this.config.colors = shuffleArray(this.config.colors);
8368
8368
  this.userColorMap = /* @__PURE__ */ new Map();
8369
8369
  this.colorIndex = 0;
8370
- this.version = "1.2.1";
8370
+ this.version = "1.3.0-next.1";
8371
8371
  this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
8372
8372
  this.superdocId = config.superdocId || uuid.v4();
8373
8373
  this.colors = this.config.colors;