@extend-ai/react-docx 0.6.1 → 0.6.3

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.
package/dist/index.cjs CHANGED
@@ -3978,10 +3978,14 @@ function parseParagraphRuns(paragraphXml2, context) {
3978
3978
  }
3979
3979
  }
3980
3980
  });
3981
+ let hyperlinkRangeCursor = 0;
3981
3982
  return runRanges.map((range, runIndex) => {
3982
- const link = hyperlinkRanges.find(
3983
- (hyperlinkRange) => range.start >= hyperlinkRange.start && range.end <= hyperlinkRange.end && hyperlinkRange.href
3984
- )?.href ?? fieldLinksByRun.get(runIndex);
3983
+ while (hyperlinkRangeCursor < hyperlinkRanges.length && hyperlinkRanges[hyperlinkRangeCursor].end <= range.start) {
3984
+ hyperlinkRangeCursor += 1;
3985
+ }
3986
+ const currentHyperlinkRange = hyperlinkRanges[hyperlinkRangeCursor];
3987
+ const hyperlinkHref = currentHyperlinkRange && range.start >= currentHyperlinkRange.start && range.end <= currentHyperlinkRange.end ? currentHyperlinkRange.href : void 0;
3988
+ const link = hyperlinkHref ?? fieldLinksByRun.get(runIndex);
3985
3989
  return {
3986
3990
  xml: paragraphXml2.slice(range.start, range.end),
3987
3991
  start: range.start,
@@ -4577,9 +4581,14 @@ function parseParagraph(paragraphXml2, context) {
4577
4581
  runs
4578
4582
  );
4579
4583
  const contentTokens = [];
4584
+ let formFieldTokenCursor = 0;
4580
4585
  for (const run of runs) {
4581
- const insideFormField = formFieldTokens.some(
4582
- (formFieldToken) => run.start >= formFieldToken.start && run.end <= formFieldToken.end
4586
+ while (formFieldTokenCursor < formFieldTokens.length && formFieldTokens[formFieldTokenCursor].end <= run.start) {
4587
+ formFieldTokenCursor += 1;
4588
+ }
4589
+ const currentFormFieldToken = formFieldTokens[formFieldTokenCursor];
4590
+ const insideFormField = Boolean(
4591
+ currentFormFieldToken && run.start >= currentFormFieldToken.start && run.end <= currentFormFieldToken.end
4583
4592
  );
4584
4593
  if (insideFormField) {
4585
4594
  continue;
@@ -8994,6 +9003,9 @@ function paragraphHasExplicitPageBreak(paragraph) {
8994
9003
  return sourceXml.length > 0 && PAGE_BREAK_XML_PATTERN.test(sourceXml);
8995
9004
  }
8996
9005
  function paragraphHasPageBreakBefore(paragraph) {
9006
+ if (paragraph.style?.pageBreakBefore === true) {
9007
+ return true;
9008
+ }
8997
9009
  const sourceXml = paragraph.sourceXml ?? "";
8998
9010
  if (!sourceXml) {
8999
9011
  return false;
@@ -10379,6 +10391,8 @@ var LARGE_TABLE_PAGE_VIRTUALIZATION_OVERSCAN = 0;
10379
10391
  var LARGE_TABLE_PAGE_ADJACENT_RENDER_COUNT = 1;
10380
10392
  var DEFAULT_PAGE_VIRTUALIZATION_SETTLE_DELAY_MS = 350;
10381
10393
  var ENABLE_TABLE_ROW_SLICING = true;
10394
+ var MIN_TABLE_ROW_SLICE_REMAINING_HEIGHT_PX = MIN_PARAGRAPH_LINE_HEIGHT_PX * 2;
10395
+ var TABLE_ROW_SLICE_BOUNDARY_TOLERANCE_PX = 2;
10382
10396
  var TOP_AND_BOTTOM_VERTICAL_DRAG_SNAP_PX = 10;
10383
10397
  var HEADER_FOOTER_INACTIVE_OPACITY = 0.5;
10384
10398
  var LETTERHEAD_INDENT_MIN_TWIPS = 900;
@@ -10414,6 +10428,10 @@ var paragraphDropCapBySourceXml = /* @__PURE__ */ new Map();
10414
10428
  var paragraphTrackedMarkupBySourceXml = /* @__PURE__ */ new Map();
10415
10429
  var paragraphMeasureCanvasContext;
10416
10430
  var textWidthByFontAndValue = /* @__PURE__ */ new Map();
10431
+ var estimatedTextAdvanceWidthByFontAndValue = /* @__PURE__ */ new Map();
10432
+ var pretextWordBreakModeByText = /* @__PURE__ */ new Map();
10433
+ var paragraphBaseFontSizePxByParagraph = /* @__PURE__ */ new WeakMap();
10434
+ var paragraphDominantFontFamilyByParagraph = /* @__PURE__ */ new WeakMap();
10417
10435
  function setCacheEntry(cache, key, value) {
10418
10436
  if (!cache.has(key) && cache.size >= XML_CACHE_MAX_ENTRIES) {
10419
10437
  const oldestKey = cache.keys().next().value;
@@ -11877,7 +11895,23 @@ function resolvePageContentHeightPxForPageSegments(pageSegments, pageIndex, defa
11877
11895
  );
11878
11896
  }
11879
11897
  function resolveRenderPageContentHeightPxForPageSegments(params) {
11880
- const resolvedHeightPx = resolvePageContentHeightPxForPageSegments(
11898
+ const firstNodeIndex = params.pageSegments[0]?.nodeIndex ?? 0;
11899
+ const metricsIndex = resolvePaginationSectionMetricsIndexForNodeIndex(
11900
+ params.metricsBySection,
11901
+ firstNodeIndex,
11902
+ 0
11903
+ );
11904
+ const sectionHeightMultiplier = Math.max(
11905
+ 1,
11906
+ Math.round(
11907
+ params.metricsBySection[metricsIndex]?.pageContentHeightMultiplier ?? 1
11908
+ )
11909
+ );
11910
+ const pageContainsOnlySplitParagraphSegments = documentPageContainsOnlySplitParagraphSegments(params.pageSegments);
11911
+ const measuredHeightPx = params.useMeasuredPageContentHeights === false ? void 0 : params.measuredPageContentHeightsPxByPageIndex?.[params.pageIndex];
11912
+ const measuredHeightMatchesCurrentPage = params.pageIdentityKey === void 0 || params.measuredPageContentIdentityKeysByPageIndex?.[params.pageIndex] === void 0 || params.measuredPageContentIdentityKeysByPageIndex?.[params.pageIndex] === params.pageIdentityKey;
11913
+ const usesMeasuredVisualHeight = Number.isFinite(measuredHeightPx) && measuredHeightMatchesCurrentPage && !pageContainsOnlySplitParagraphSegments;
11914
+ let resolvedHeightPx = resolvePageContentHeightPxForPageSegments(
11881
11915
  params.pageSegments,
11882
11916
  params.pageIndex,
11883
11917
  params.defaultPageContentHeightPx,
@@ -11887,12 +11921,15 @@ function resolveRenderPageContentHeightPxForPageSegments(params) {
11887
11921
  params.pageIdentityKey
11888
11922
  );
11889
11923
  if (params.useMeasuredPageContentHeights === false && Number.isFinite(params.pageContentHeightScale) && Math.abs(params.pageContentHeightScale - 1) >= 1e-3) {
11890
- return Math.max(
11924
+ resolvedHeightPx = Math.max(
11891
11925
  120,
11892
11926
  Math.round(resolvedHeightPx * params.pageContentHeightScale)
11893
11927
  );
11894
11928
  }
11895
- return resolvedHeightPx;
11929
+ if (usesMeasuredVisualHeight || sectionHeightMultiplier <= 1) {
11930
+ return resolvedHeightPx;
11931
+ }
11932
+ return Math.max(120, Math.round(resolvedHeightPx / sectionHeightMultiplier));
11896
11933
  }
11897
11934
  function documentPageContainsOnlySplitParagraphSegments(pageSegments) {
11898
11935
  return pageSegments.length > 0 && pageSegments.every(
@@ -12251,76 +12288,7 @@ var defaultStarterModel = {
12251
12288
  nodes: [
12252
12289
  {
12253
12290
  type: "paragraph",
12254
- style: { headingLevel: 1, styleId: "Heading1", styleName: "Heading 1" },
12255
- children: [
12256
- { type: "text", text: "React DOCX WYSIWYG", style: { bold: true } }
12257
- ]
12258
- },
12259
- {
12260
- type: "paragraph",
12261
- children: [
12262
- {
12263
- type: "text",
12264
- text: "Import a .docx, edit styles from the toolbar, and export.",
12265
- style: { highlight: "yellow" }
12266
- }
12267
- ]
12268
- },
12269
- {
12270
- type: "table",
12271
- style: {
12272
- borders: createDefaultEditorTableBorders()
12273
- },
12274
- rows: [
12275
- {
12276
- type: "table-row",
12277
- cells: [
12278
- {
12279
- type: "table-cell",
12280
- style: { backgroundColor: "#eef2ff" },
12281
- nodes: [
12282
- {
12283
- type: "paragraph",
12284
- children: [{ type: "text", text: "Header A" }]
12285
- }
12286
- ]
12287
- },
12288
- {
12289
- type: "table-cell",
12290
- style: { backgroundColor: "#eef2ff" },
12291
- nodes: [
12292
- {
12293
- type: "paragraph",
12294
- children: [{ type: "text", text: "Header B" }]
12295
- }
12296
- ]
12297
- }
12298
- ]
12299
- },
12300
- {
12301
- type: "table-row",
12302
- cells: [
12303
- {
12304
- type: "table-cell",
12305
- nodes: [
12306
- {
12307
- type: "paragraph",
12308
- children: [{ type: "text", text: "Row 1" }]
12309
- }
12310
- ]
12311
- },
12312
- {
12313
- type: "table-cell",
12314
- nodes: [
12315
- {
12316
- type: "paragraph",
12317
- children: [{ type: "text", text: "Value" }]
12318
- }
12319
- ]
12320
- }
12321
- ]
12322
- }
12323
- ]
12291
+ children: [{ type: "text", text: "" }]
12324
12292
  }
12325
12293
  ],
12326
12294
  metadata: {
@@ -12403,6 +12371,9 @@ var defaultStarterModel = {
12403
12371
  defaultParagraphStyleId: "Normal"
12404
12372
  }
12405
12373
  };
12374
+ function createBlankDocumentModel() {
12375
+ return cloneDocModel(defaultStarterModel);
12376
+ }
12406
12377
  function textRuns2(paragraph) {
12407
12378
  return paragraph.children.filter(
12408
12379
  (child) => child.type === "text"
@@ -12446,7 +12417,9 @@ function firstExplicitFontFamilyInNodeTree(nodes) {
12446
12417
  if (node.type === "table") {
12447
12418
  for (const row of node.rows) {
12448
12419
  for (const cell of row.cells) {
12449
- const nestedFontFamily = firstExplicitFontFamilyInNodeTree(cell.nodes);
12420
+ const nestedFontFamily = firstExplicitFontFamilyInNodeTree(
12421
+ cell.nodes
12422
+ );
12450
12423
  if (nestedFontFamily) {
12451
12424
  return nestedFontFamily;
12452
12425
  }
@@ -13352,11 +13325,19 @@ function buildParagraphPretextTabSpacerText(widthPx, style, paragraphBaseFontPx)
13352
13325
  while (measuredWidthPx + spacerAdvancePx * 0.5 < safeWidthPx && spacerCount < 64) {
13353
13326
  spacerCount += 1;
13354
13327
  spacerText = spacerCharacter.repeat(spacerCount);
13355
- measuredWidthPx = measureTextWidthPx2(spacerText, style, paragraphBaseFontPx);
13328
+ measuredWidthPx = measureTextWidthPx2(
13329
+ spacerText,
13330
+ style,
13331
+ paragraphBaseFontPx
13332
+ );
13356
13333
  }
13357
13334
  while (spacerCount > 1) {
13358
13335
  const nextText = spacerCharacter.repeat(spacerCount - 1);
13359
- const nextWidthPx = measureTextWidthPx2(nextText, style, paragraphBaseFontPx);
13336
+ const nextWidthPx = measureTextWidthPx2(
13337
+ nextText,
13338
+ style,
13339
+ paragraphBaseFontPx
13340
+ );
13360
13341
  if (Math.abs(nextWidthPx - safeWidthPx) >= Math.abs(measuredWidthPx - safeWidthPx)) {
13361
13342
  break;
13362
13343
  }
@@ -13647,7 +13628,20 @@ function buildSyntheticPretextLayoutSource(text, style) {
13647
13628
  };
13648
13629
  }
13649
13630
  function pretextWordBreakModeForText(text) {
13650
- return KEEP_ALL_SCRIPT_RE.test(text) ? "keep-all" : "normal";
13631
+ const cached = pretextWordBreakModeByText.get(text);
13632
+ if (cached) {
13633
+ return cached;
13634
+ }
13635
+ const mode = KEEP_ALL_SCRIPT_RE.test(text) ? "keep-all" : "normal";
13636
+ setCacheEntry(pretextWordBreakModeByText, text, mode);
13637
+ while (pretextWordBreakModeByText.size > TEXT_MEASURE_CACHE_MAX_ENTRIES) {
13638
+ const firstKey = pretextWordBreakModeByText.keys().next().value;
13639
+ if (!firstKey) {
13640
+ break;
13641
+ }
13642
+ pretextWordBreakModeByText.delete(firstKey);
13643
+ }
13644
+ return mode;
13651
13645
  }
13652
13646
  function sanitizeRenderedPretextFragmentText(text) {
13653
13647
  return text.replace(/\r\n?|\n/g, "");
@@ -14131,36 +14125,55 @@ function estimateTextAdvanceWidthPx(text, style) {
14131
14125
  if (!text) {
14132
14126
  return 0;
14133
14127
  }
14134
- const normalized = text.replace(/\u00a0/g, " ");
14135
14128
  const fontSizePx = runFontSizePx(style);
14129
+ const normalized = text.includes("\xA0") ? text.replace(/\u00a0/g, " ") : text;
14130
+ const cacheKey = `${fontSizePx}\0${normalized}`;
14131
+ const cached = estimatedTextAdvanceWidthByFontAndValue.get(cacheKey);
14132
+ if (cached !== void 0) {
14133
+ return cached;
14134
+ }
14136
14135
  let total = 0;
14137
- for (const char of normalized) {
14138
- if (char === "\n" || char === "\r") {
14136
+ for (let index = 0; index < normalized.length; index += 1) {
14137
+ const code = normalized.charCodeAt(index);
14138
+ if (code === 10 || code === 13) {
14139
14139
  continue;
14140
14140
  }
14141
- if (char === " ") {
14141
+ if (code === 9) {
14142
14142
  total += fontSizePx * 2;
14143
14143
  continue;
14144
14144
  }
14145
- if (char === " ") {
14145
+ if (code === 32) {
14146
14146
  total += fontSizePx * 0.33;
14147
14147
  continue;
14148
14148
  }
14149
- if (/[.,:;'"`!|ilI1]/.test(char)) {
14149
+ if (code === 33 || code === 39 || code === 44 || code === 46 || code === 49 || code === 58 || code === 59 || code === 73 || code === 96 || code === 105 || code === 108 || code === 124) {
14150
14150
  total += fontSizePx * 0.29;
14151
14151
  continue;
14152
14152
  }
14153
- if (/[A-Z0-9]/.test(char)) {
14153
+ if (code >= 65 && code <= 90 || code >= 48 && code <= 57) {
14154
14154
  total += fontSizePx * 0.6;
14155
14155
  continue;
14156
14156
  }
14157
- if (/[\u3000-\u9fff]/.test(char)) {
14157
+ if (code >= 12288 && code <= 40959) {
14158
14158
  total += fontSizePx * 0.95;
14159
14159
  continue;
14160
14160
  }
14161
14161
  total += fontSizePx * 0.54;
14162
14162
  }
14163
- return Math.max(0, Math.round(total));
14163
+ const estimatedWidthPx = Math.max(0, Math.round(total));
14164
+ setCacheEntry(
14165
+ estimatedTextAdvanceWidthByFontAndValue,
14166
+ cacheKey,
14167
+ estimatedWidthPx
14168
+ );
14169
+ while (estimatedTextAdvanceWidthByFontAndValue.size > TEXT_MEASURE_CACHE_MAX_ENTRIES) {
14170
+ const firstKey = estimatedTextAdvanceWidthByFontAndValue.keys().next().value;
14171
+ if (!firstKey) {
14172
+ break;
14173
+ }
14174
+ estimatedTextAdvanceWidthByFontAndValue.delete(firstKey);
14175
+ }
14176
+ return estimatedWidthPx;
14164
14177
  }
14165
14178
  function updateEstimatedLineWidthPxForText(currentLineWidthPx, text, style) {
14166
14179
  if (!text) {
@@ -14466,7 +14479,8 @@ function paragraphHasLastRenderedPageBreak(paragraph) {
14466
14479
  if (cached) {
14467
14480
  return cached.lastRenderedPageBreak;
14468
14481
  }
14469
- return paragraphHasExplicitPageBreak2(paragraph) ? paragraphBreakFlagsBySourceXml.get(xml)?.lastRenderedPageBreak ?? false : false;
14482
+ paragraphHasExplicitPageBreak2(paragraph);
14483
+ return paragraphBreakFlagsBySourceXml.get(xml)?.lastRenderedPageBreak ?? false;
14470
14484
  }
14471
14485
  function paragraphStartsWithLastRenderedPageBreak(paragraph) {
14472
14486
  const xml = paragraph.sourceXml ?? "";
@@ -14640,7 +14654,8 @@ function paragraphHasPageBreakBefore2(paragraph) {
14640
14654
  if (cached) {
14641
14655
  return cached.pageBreakBefore;
14642
14656
  }
14643
- return paragraphHasExplicitPageBreak2(paragraph) ? paragraphBreakFlagsBySourceXml.get(xml)?.pageBreakBefore ?? false : false;
14657
+ paragraphHasExplicitPageBreak2(paragraph);
14658
+ return paragraphBreakFlagsBySourceXml.get(xml)?.pageBreakBefore ?? false;
14644
14659
  }
14645
14660
  function sectionBreakAfterParagraphStartsNewPage(paragraph) {
14646
14661
  const xml = paragraph.sourceXml ?? "";
@@ -14820,9 +14835,15 @@ function paragraphDominantFontSizePt(paragraph) {
14820
14835
  return dominantFontSizePt;
14821
14836
  }
14822
14837
  function paragraphBaseFontSizePx(paragraph) {
14838
+ const cached = paragraphBaseFontSizePxByParagraph.get(paragraph);
14839
+ if (cached !== void 0) {
14840
+ return cached;
14841
+ }
14823
14842
  const dominantRunFontSizePt = paragraphDominantFontSizePt(paragraph);
14824
14843
  const fontSizePt = dominantRunFontSizePt && dominantRunFontSizePt > 0 ? dominantRunFontSizePt : Number.isFinite(paragraph.style?.headingLevel) ? DEFAULT_PARAGRAPH_FONT_SIZE_PT + Math.max(0, 6 - (paragraph.style?.headingLevel ?? 6)) : DEFAULT_PARAGRAPH_FONT_SIZE_PT;
14825
- return Math.max(10, Math.round(fontSizePt * 96 / 72));
14844
+ const baseFontSizePx = Math.max(10, Math.round(fontSizePt * 96 / 72));
14845
+ paragraphBaseFontSizePxByParagraph.set(paragraph, baseFontSizePx);
14846
+ return baseFontSizePx;
14826
14847
  }
14827
14848
  function paragraphMaxFontSizePx(paragraph) {
14828
14849
  const paragraphBaseFontPx = paragraphBaseFontSizePx(paragraph);
@@ -14847,6 +14868,10 @@ function normalizeFontFamilyToken(fontFamily) {
14847
14868
  return normalized || void 0;
14848
14869
  }
14849
14870
  function paragraphDominantFontFamily(paragraph) {
14871
+ const cached = paragraphDominantFontFamilyByParagraph.get(paragraph);
14872
+ if (cached !== void 0) {
14873
+ return cached ?? void 0;
14874
+ }
14850
14875
  const weightByFamily = /* @__PURE__ */ new Map();
14851
14876
  const addWeight = (fontFamily, weight) => {
14852
14877
  const normalizedFamily = normalizeFontFamilyToken(fontFamily);
@@ -14867,6 +14892,7 @@ function paragraphDominantFontFamily(paragraph) {
14867
14892
  addWeight(child.style?.fontFamily, text.length);
14868
14893
  });
14869
14894
  if (weightByFamily.size === 0) {
14895
+ paragraphDominantFontFamilyByParagraph.set(paragraph, null);
14870
14896
  return void 0;
14871
14897
  }
14872
14898
  let dominantFamily;
@@ -14877,6 +14903,7 @@ function paragraphDominantFontFamily(paragraph) {
14877
14903
  dominantWeight = weight;
14878
14904
  }
14879
14905
  }
14906
+ paragraphDominantFontFamilyByParagraph.set(paragraph, dominantFamily ?? null);
14880
14907
  return dominantFamily;
14881
14908
  }
14882
14909
  function singleLineAutoScaleForFontFamily(fontFamily) {
@@ -15966,6 +15993,11 @@ function rowHasDeepFlowContent(row) {
15966
15993
  }
15967
15994
  return nestedTableCount > 0 || blockNodeCount >= SPLITTABLE_TABLE_ROW_DEEP_CONTENT_NODE_THRESHOLD;
15968
15995
  }
15996
+ function rowHasNestedTableContent(row) {
15997
+ return row.cells.some(
15998
+ (cell) => cell.nodes.some((contentNode) => contentNode.type === "table")
15999
+ );
16000
+ }
15969
16001
  function capSplitFriendlyTableRowEstimatePx(row, estimatedRowHeightPx, explicitHeightPx, pageContentHeightPx) {
15970
16002
  if (!rowAllowsPageSplit(row)) {
15971
16003
  return estimatedRowHeightPx;
@@ -16099,6 +16131,280 @@ function estimateTableRowHeightsPx(table, maxAvailableWidthPx, numberingDefiniti
16099
16131
  return Math.max(MIN_PARAGRAPH_LINE_HEIGHT_PX, rowHeightPx);
16100
16132
  });
16101
16133
  }
16134
+ function uniqueSortedPixelBoundaries(values) {
16135
+ const sorted = values.filter((value) => Number.isFinite(value)).map((value) => Math.max(0, Math.round(value))).sort((left, right) => left - right);
16136
+ const unique = [];
16137
+ for (const value of sorted) {
16138
+ const previous = unique[unique.length - 1];
16139
+ if (previous === void 0 || Math.abs(previous - value) > TABLE_ROW_SLICE_BOUNDARY_TOLERANCE_PX) {
16140
+ unique.push(value);
16141
+ }
16142
+ }
16143
+ return unique;
16144
+ }
16145
+ function estimateParagraphBoundaryOffsetsPx(paragraph, availableWidthPx, numberingDefinitions, applyWordTableDefaults, docGridLinePitchPx, paragraphIndex) {
16146
+ const paragraphForLayout = wordLikeTableCellParagraph(
16147
+ paragraph,
16148
+ applyWordTableDefaults
16149
+ );
16150
+ const disableDocGridSnap = paragraphDocGridSnapState(paragraph) === "disable";
16151
+ const paragraphHeightPx = estimateParagraphHeightPx(
16152
+ paragraphForLayout,
16153
+ availableWidthPx,
16154
+ numberingDefinitions,
16155
+ docGridLinePitchPx,
16156
+ disableDocGridSnap
16157
+ );
16158
+ const suppressTopSpacing = paragraphIndex === 0 && suppressFirstTableCellParagraphTopSpacing(paragraph);
16159
+ const beforeSpacingPx = suppressTopSpacing ? 0 : twipsToPixels(paragraphForLayout.style?.spacing?.beforeTwips) ?? 0;
16160
+ const afterSpacingPx = twipsToPixels(paragraphForLayout.style?.spacing?.afterTwips) ?? 0;
16161
+ const topBorderInsetPx = paragraphBorderInsetPx(
16162
+ paragraphForLayout.style?.borders?.top
16163
+ );
16164
+ const bottomBorderInsetPx = paragraphBorderInsetPx(
16165
+ paragraphForLayout.style?.borders?.bottom
16166
+ );
16167
+ const lineHeightPx = Math.max(
16168
+ MIN_PARAGRAPH_LINE_HEIGHT_PX,
16169
+ estimateParagraphLineHeightPx(
16170
+ paragraphForLayout,
16171
+ docGridLinePitchPx,
16172
+ disableDocGridSnap
16173
+ )
16174
+ );
16175
+ const pretextSource = buildParagraphPretextLayoutSource(paragraphForLayout, {
16176
+ allowExplicitLineBreakText: true,
16177
+ expandTabsForLayout: true
16178
+ });
16179
+ const paragraphTextWidthPx = paragraphAvailableTextWidthPx(
16180
+ paragraphForLayout,
16181
+ availableWidthPx,
16182
+ numberingDefinitions
16183
+ );
16184
+ const pretextLayout = pretextSource ? layoutParagraphPretextSource(
16185
+ paragraphForLayout,
16186
+ pretextSource,
16187
+ paragraphTextWidthPx,
16188
+ lineHeightPx,
16189
+ []
16190
+ ) : void 0;
16191
+ const lineTopOffsetsPx = pretextLayout ? pretextLayout.lines.map((line) => Math.max(0, Math.round(line.y))) : Array.from(
16192
+ {
16193
+ length: Math.max(
16194
+ 1,
16195
+ paragraphLineCountWithinWidth(
16196
+ paragraphForLayout,
16197
+ availableWidthPx,
16198
+ numberingDefinitions
16199
+ )
16200
+ )
16201
+ },
16202
+ (_, lineIndex) => lineIndex * lineHeightPx
16203
+ );
16204
+ const textTopPx = beforeSpacingPx + topBorderInsetPx;
16205
+ const textHeightPx = pretextLayout ? wrappedPretextParagraphBlockHeightPx(pretextLayout) : lineTopOffsetsPx.length * lineHeightPx;
16206
+ const visualHeightPx = Math.max(
16207
+ 1,
16208
+ beforeSpacingPx + topBorderInsetPx + textHeightPx + bottomBorderInsetPx + afterSpacingPx
16209
+ );
16210
+ const heightPx = Math.max(1, paragraphHeightPx, visualHeightPx);
16211
+ const lineBoundariesPx = lineTopOffsetsPx.map(
16212
+ (lineTopPx) => textTopPx + lineTopPx + lineHeightPx
16213
+ );
16214
+ return {
16215
+ heightPx,
16216
+ safeBoundariesPx: uniqueSortedPixelBoundaries([
16217
+ ...lineBoundariesPx,
16218
+ heightPx
16219
+ ])
16220
+ };
16221
+ }
16222
+ function estimateNestedTableBoundaryOffsetsPx(table, availableWidthPx, numberingDefinitions, docGridLinePitchPx) {
16223
+ const rowHeightsPx = estimateTableRowHeightsPx(
16224
+ table,
16225
+ availableWidthPx,
16226
+ numberingDefinitions,
16227
+ docGridLinePitchPx
16228
+ );
16229
+ const boundariesPx = [];
16230
+ let cursorPx = 0;
16231
+ for (const rowHeightPx of rowHeightsPx) {
16232
+ cursorPx += Math.max(MIN_PARAGRAPH_LINE_HEIGHT_PX, rowHeightPx);
16233
+ boundariesPx.push(cursorPx);
16234
+ }
16235
+ return {
16236
+ heightPx: Math.max(MIN_PARAGRAPH_LINE_HEIGHT_PX, cursorPx),
16237
+ safeBoundariesPx: uniqueSortedPixelBoundaries(boundariesPx)
16238
+ };
16239
+ }
16240
+ function estimateTableCellSliceBoundaryLayoutPx(params) {
16241
+ const {
16242
+ cell,
16243
+ rowHeightPx,
16244
+ contentWidthPx,
16245
+ tableCellMarginTwips,
16246
+ numberingDefinitions,
16247
+ applyWordTableDefaults,
16248
+ docGridLinePitchPx
16249
+ } = params;
16250
+ const paddingPx = resolveTableSpacingPaddingPx(
16251
+ mergeTableSpacing(tableCellMarginTwips, cell.style?.marginTwips)
16252
+ );
16253
+ const localBoundariesPx = [0, paddingPx.top];
16254
+ let contentCursorPx = paddingPx.top;
16255
+ let paragraphIndex = 0;
16256
+ for (const contentNode of cell.nodes) {
16257
+ const layout = contentNode.type === "paragraph" ? estimateParagraphBoundaryOffsetsPx(
16258
+ contentNode,
16259
+ contentWidthPx,
16260
+ numberingDefinitions,
16261
+ applyWordTableDefaults,
16262
+ docGridLinePitchPx,
16263
+ paragraphIndex++
16264
+ ) : estimateNestedTableBoundaryOffsetsPx(
16265
+ contentNode,
16266
+ contentWidthPx,
16267
+ numberingDefinitions,
16268
+ docGridLinePitchPx
16269
+ );
16270
+ localBoundariesPx.push(
16271
+ ...layout.safeBoundariesPx.map(
16272
+ (boundaryPx) => contentCursorPx + boundaryPx
16273
+ )
16274
+ );
16275
+ contentCursorPx += layout.heightPx;
16276
+ }
16277
+ const contentBottomPx = contentCursorPx + paddingPx.bottom;
16278
+ const contentFlowHeightPx = Math.max(0, contentCursorPx - paddingPx.top);
16279
+ const availableContentHeightPx = Math.max(
16280
+ 0,
16281
+ rowHeightPx - paddingPx.top - paddingPx.bottom
16282
+ );
16283
+ const extraVerticalSpacePx = Math.max(
16284
+ 0,
16285
+ availableContentHeightPx - contentFlowHeightPx
16286
+ );
16287
+ const verticalOffsetPx = cell.style?.verticalAlign === "center" ? Math.round(extraVerticalSpacePx / 2) : cell.style?.verticalAlign === "bottom" ? extraVerticalSpacePx : 0;
16288
+ return {
16289
+ safeBoundariesPx: uniqueSortedPixelBoundaries(
16290
+ localBoundariesPx.map(
16291
+ (boundaryPx) => Math.min(rowHeightPx, boundaryPx + verticalOffsetPx)
16292
+ )
16293
+ ),
16294
+ contentBottomPx: Math.min(rowHeightPx, contentBottomPx + verticalOffsetPx)
16295
+ };
16296
+ }
16297
+ function tableCellSliceBoundaryIsSafe(layout, boundaryPx) {
16298
+ if (boundaryPx <= TABLE_ROW_SLICE_BOUNDARY_TOLERANCE_PX) {
16299
+ return true;
16300
+ }
16301
+ if (boundaryPx >= layout.contentBottomPx - TABLE_ROW_SLICE_BOUNDARY_TOLERANCE_PX) {
16302
+ return true;
16303
+ }
16304
+ return layout.safeBoundariesPx.some(
16305
+ (safeBoundaryPx) => Math.abs(safeBoundaryPx - boundaryPx) <= TABLE_ROW_SLICE_BOUNDARY_TOLERANCE_PX
16306
+ );
16307
+ }
16308
+ function resolveTableRowSliceHeightOnSafeBoundaryPx(params) {
16309
+ const {
16310
+ table,
16311
+ rowIndex,
16312
+ rowHeightPx,
16313
+ rowSliceOffsetPx,
16314
+ preferredSliceHeightPx,
16315
+ maxAvailableWidthPx,
16316
+ numberingDefinitions,
16317
+ docGridLinePitchPx
16318
+ } = params;
16319
+ const row = table.rows[rowIndex];
16320
+ if (!row || !rowHasNestedTableContent(row)) {
16321
+ return preferredSliceHeightPx;
16322
+ }
16323
+ const sliceStartPx = Math.max(0, Math.round(rowSliceOffsetPx));
16324
+ const preferredSliceEndPx = Math.min(
16325
+ rowHeightPx,
16326
+ sliceStartPx + Math.max(0, Math.round(preferredSliceHeightPx))
16327
+ );
16328
+ if (preferredSliceEndPx >= rowHeightPx - TABLE_ROW_SLICE_BOUNDARY_TOLERANCE_PX) {
16329
+ return Math.max(0, rowHeightPx - sliceStartPx);
16330
+ }
16331
+ const columnCount = tableColumnCount(table);
16332
+ const tableWidthPx = twipsToPixels(table.style?.widthTwips);
16333
+ const rawTableColumnWidthsPx = (() => {
16334
+ const definedWidthsTwips = columnWidthsFromTableDefinition(
16335
+ table,
16336
+ columnCount
16337
+ );
16338
+ if (!definedWidthsTwips || definedWidthsTwips.length === 0) {
16339
+ return defaultColumnWidthsPx(columnCount, tableWidthPx);
16340
+ }
16341
+ const widthsPx = definedWidthsTwips.map(
16342
+ (widthTwips) => twipsToPixels(widthTwips) ?? 0
16343
+ );
16344
+ return normalizeColumnWidthsPx(widthsPx, columnCount, tableWidthPx, 1);
16345
+ })();
16346
+ const rawResolvedTableWidthPx = tableWidthPx ?? rawTableColumnWidthsPx.reduce((sum, widthPx) => sum + widthPx, 0);
16347
+ const collapsedHorizontalBorderBleedPx = resolveCollapsedTableHorizontalOuterBleedPx(table, columnCount);
16348
+ const maxTableWidthPx = Number.isFinite(maxAvailableWidthPx) && maxAvailableWidthPx > 0 ? Math.max(
16349
+ 120,
16350
+ maxAvailableWidthPx - collapsedHorizontalBorderBleedPx
16351
+ ) : void 0;
16352
+ const resolvedTableWidthPx = clampTableWidthPx(
16353
+ rawResolvedTableWidthPx,
16354
+ maxTableWidthPx
16355
+ );
16356
+ const tableColumnWidthsPx = fitColumnWidthsToWidth(
16357
+ rawTableColumnWidthsPx,
16358
+ resolvedTableWidthPx
16359
+ );
16360
+ const applyWordTableDefaults = tableUsesWordLikeParagraphDefaults(table);
16361
+ const tableCellMarginTwips = table.style?.cellMarginTwips;
16362
+ const cellLayouts = [];
16363
+ const candidateBoundariesPx = [preferredSliceEndPx];
16364
+ let columnCursor = 0;
16365
+ for (const cell of row.cells) {
16366
+ const colSpanValue = cell.style?.gridSpan && cell.style.gridSpan > 1 ? cell.style.gridSpan : 1;
16367
+ const startColumnIndex = columnCursor;
16368
+ const endColumnIndex = Math.min(
16369
+ columnCount - 1,
16370
+ startColumnIndex + colSpanValue - 1
16371
+ );
16372
+ columnCursor += colSpanValue;
16373
+ const spannedWidthPx = tableColumnWidthsPx.slice(startColumnIndex, endColumnIndex + 1).reduce((sum, widthPx) => sum + widthPx, 0);
16374
+ const fallbackCellWidthPx = resolvedTableWidthPx / Math.max(1, columnCount) * colSpanValue;
16375
+ const cellRenderedWidthPx = twipsToPixels(cell.style?.widthTwips) ?? (spannedWidthPx > 0 ? spannedWidthPx : fallbackCellWidthPx);
16376
+ const cellPaddingPx = resolveTableSpacingPaddingPx(
16377
+ mergeTableSpacing(tableCellMarginTwips, cell.style?.marginTwips)
16378
+ );
16379
+ const cellContentWidthPx = Math.max(
16380
+ 1,
16381
+ cellRenderedWidthPx - cellPaddingPx.left - cellPaddingPx.right
16382
+ );
16383
+ const cellLayout = estimateTableCellSliceBoundaryLayoutPx({
16384
+ cell,
16385
+ rowHeightPx,
16386
+ contentWidthPx: cellContentWidthPx,
16387
+ tableCellMarginTwips,
16388
+ numberingDefinitions,
16389
+ applyWordTableDefaults,
16390
+ docGridLinePitchPx
16391
+ });
16392
+ cellLayouts.push(cellLayout);
16393
+ candidateBoundariesPx.push(...cellLayout.safeBoundariesPx);
16394
+ }
16395
+ const minimumSliceEndPx = sliceStartPx + Math.max(1, MIN_TABLE_ROW_SLICE_REMAINING_HEIGHT_PX);
16396
+ const candidatesPx = uniqueSortedPixelBoundaries(candidateBoundariesPx).filter(
16397
+ (boundaryPx) => boundaryPx >= minimumSliceEndPx && boundaryPx <= preferredSliceEndPx + TABLE_ROW_SLICE_BOUNDARY_TOLERANCE_PX
16398
+ ).sort((left, right) => right - left);
16399
+ for (const candidatePx of candidatesPx) {
16400
+ if (cellLayouts.every(
16401
+ (layout) => tableCellSliceBoundaryIsSafe(layout, candidatePx)
16402
+ )) {
16403
+ return Math.max(0, candidatePx - sliceStartPx);
16404
+ }
16405
+ }
16406
+ return void 0;
16407
+ }
16102
16408
  function estimateTableHeightPx(table, maxAvailableWidthPx, numberingDefinitions, docGridLinePitchPx) {
16103
16409
  const sourceXml = table.sourceXml;
16104
16410
  const widthKey = heightEstimateCacheKeyPx(
@@ -16387,6 +16693,234 @@ function estimateRenderedPageSegmentHeightPx(node, segment, model, availableWidt
16387
16693
  )
16388
16694
  );
16389
16695
  }
16696
+ function resolveParagraphColumnRenderLineRange(paragraph, segment, availableWidthPx, numberingDefinitions, docGridLinePitchPx) {
16697
+ const lineHeightPx = Math.max(
16698
+ 1,
16699
+ segment.paragraphLineRange?.lineHeightPx ?? estimateParagraphLineHeightPx(paragraph, docGridLinePitchPx)
16700
+ );
16701
+ if (segment.paragraphLineRange) {
16702
+ return {
16703
+ ...segment.paragraphLineRange,
16704
+ lineHeightPx
16705
+ };
16706
+ }
16707
+ const paragraphTextWidthPx = paragraphAvailableTextWidthPx(
16708
+ paragraph,
16709
+ availableWidthPx,
16710
+ numberingDefinitions
16711
+ );
16712
+ const pretextSource = buildParagraphPretextLayoutSource(paragraph, {
16713
+ allowExplicitLineBreakText: true,
16714
+ expandTabsForLayout: true
16715
+ });
16716
+ const pretextLayout = pretextSource ? layoutParagraphPretextSource(
16717
+ paragraph,
16718
+ pretextSource,
16719
+ paragraphTextWidthPx,
16720
+ lineHeightPx,
16721
+ []
16722
+ ) : void 0;
16723
+ const totalLineCount = pretextLayout && pretextLayout.lineCount > 0 ? pretextLayout.lineCount : paragraphLineCountWithinWidth(
16724
+ paragraph,
16725
+ availableWidthPx,
16726
+ numberingDefinitions
16727
+ );
16728
+ return {
16729
+ startLineIndex: 0,
16730
+ endLineIndex: Math.max(1, totalLineCount),
16731
+ totalLineCount: Math.max(1, totalLineCount),
16732
+ lineHeightPx
16733
+ };
16734
+ }
16735
+ function splitParagraphSegmentForColumnRender(params) {
16736
+ const {
16737
+ paragraph,
16738
+ segment,
16739
+ model,
16740
+ availableWidthPx,
16741
+ availableHeightPx,
16742
+ numberingDefinitions,
16743
+ docGridLinePitchPx
16744
+ } = params;
16745
+ if (segment.tableRowRange || segment.tableRowSlice || paragraphHasExplicitColumnBreak(paragraph)) {
16746
+ return void 0;
16747
+ }
16748
+ const fullLineRange = resolveParagraphColumnRenderLineRange(
16749
+ paragraph,
16750
+ segment,
16751
+ availableWidthPx,
16752
+ numberingDefinitions,
16753
+ docGridLinePitchPx
16754
+ );
16755
+ const startLineIndex = Math.max(0, fullLineRange.startLineIndex);
16756
+ const endLineIndex = Math.max(startLineIndex, fullLineRange.endLineIndex);
16757
+ if (endLineIndex - startLineIndex < 2 || !paragraphCanSplitAcrossPages(paragraph, fullLineRange.totalLineCount)) {
16758
+ return void 0;
16759
+ }
16760
+ const safeAvailableHeightPx = Math.max(0, Math.round(availableHeightPx));
16761
+ let bestSegment;
16762
+ let bestHeightPx = 0;
16763
+ for (let candidateEndLineIndex = startLineIndex + 1; candidateEndLineIndex < endLineIndex; candidateEndLineIndex += 1) {
16764
+ const candidateSegment = {
16765
+ ...segment,
16766
+ paragraphLineRange: {
16767
+ startLineIndex,
16768
+ endLineIndex: candidateEndLineIndex,
16769
+ totalLineCount: fullLineRange.totalLineCount,
16770
+ lineHeightPx: fullLineRange.lineHeightPx
16771
+ }
16772
+ };
16773
+ const candidateHeightPx = estimateRenderedPageSegmentHeightPx(
16774
+ paragraph,
16775
+ candidateSegment,
16776
+ model,
16777
+ availableWidthPx,
16778
+ numberingDefinitions,
16779
+ docGridLinePitchPx
16780
+ );
16781
+ if (candidateHeightPx > safeAvailableHeightPx + PAGE_OVERFLOW_TOLERANCE_PX) {
16782
+ break;
16783
+ }
16784
+ bestSegment = candidateSegment;
16785
+ bestHeightPx = candidateHeightPx;
16786
+ }
16787
+ if (!bestSegment?.paragraphLineRange) {
16788
+ return void 0;
16789
+ }
16790
+ return {
16791
+ currentSegment: bestSegment,
16792
+ currentHeightPx: bestHeightPx,
16793
+ remainderSegment: {
16794
+ ...segment,
16795
+ paragraphLineRange: {
16796
+ startLineIndex: bestSegment.paragraphLineRange.endLineIndex,
16797
+ endLineIndex,
16798
+ totalLineCount: fullLineRange.totalLineCount,
16799
+ lineHeightPx: fullLineRange.lineHeightPx
16800
+ }
16801
+ }
16802
+ };
16803
+ }
16804
+ function buildRenderColumnSegmentsForPageSection(model, flowSegments, columnWidthsPx, columnHeightPx, numberingDefinitions, docGridLinePitchPxByNodeIndex, measuredParagraphOuterHeightsPxByNodeIndex, balanceColumns = false) {
16805
+ const columnCount = Math.max(1, columnWidthsPx.length);
16806
+ const columns = Array.from(
16807
+ { length: columnCount },
16808
+ () => []
16809
+ );
16810
+ const maxColumnHeightPx = Math.max(120, Math.round(columnHeightPx));
16811
+ const resolveSegmentHeightPx = (segment, columnWidthPx) => {
16812
+ const segmentNode = model.nodes[segment.nodeIndex];
16813
+ if (!segmentNode) {
16814
+ return MIN_PARAGRAPH_LINE_HEIGHT_PX;
16815
+ }
16816
+ const docGridLinePitchPx = docGridLinePitchPxByNodeIndex?.get(
16817
+ segment.nodeIndex
16818
+ );
16819
+ const measuredSegmentHeightPx = segmentNode.type === "paragraph" && !segment.paragraphLineRange && !segment.tableRowRange && !segment.tableRowSlice ? measuredParagraphOuterHeightsPxByNodeIndex?.get(segment.nodeIndex) : void 0;
16820
+ return Number.isFinite(measuredSegmentHeightPx) && measuredSegmentHeightPx > 0 ? Math.max(1, Math.round(measuredSegmentHeightPx)) : estimateRenderedPageSegmentHeightPx(
16821
+ segmentNode,
16822
+ segment,
16823
+ model,
16824
+ columnWidthPx,
16825
+ numberingDefinitions,
16826
+ docGridLinePitchPx
16827
+ );
16828
+ };
16829
+ const safeColumnHeightPx = balanceColumns && columnCount > 1 ? Math.min(
16830
+ maxColumnHeightPx,
16831
+ Math.max(
16832
+ MIN_PARAGRAPH_LINE_HEIGHT_PX * 4,
16833
+ Math.ceil(
16834
+ flowSegments.reduce((totalHeightPx, segment) => {
16835
+ const columnWidthPx = Math.max(
16836
+ 120,
16837
+ Math.round(columnWidthsPx[0] ?? 120)
16838
+ );
16839
+ return totalHeightPx + resolveSegmentHeightPx(segment, columnWidthPx);
16840
+ }, 0) / columnCount
16841
+ ) + PAGE_OVERFLOW_TOLERANCE_PX
16842
+ )
16843
+ ) : maxColumnHeightPx;
16844
+ let columnIndex = 0;
16845
+ let consumedHeightPx = 0;
16846
+ const moveToNextColumn = () => {
16847
+ if (columnIndex + 1 >= columnCount) {
16848
+ return false;
16849
+ }
16850
+ columnIndex += 1;
16851
+ consumedHeightPx = 0;
16852
+ return true;
16853
+ };
16854
+ const pushSegment = (segment, heightPx) => {
16855
+ columns[columnIndex]?.push(segment);
16856
+ consumedHeightPx += Math.max(1, Math.round(heightPx));
16857
+ };
16858
+ for (const flowSegment of flowSegments) {
16859
+ let pendingSegment = flowSegment;
16860
+ let splitGuard = 0;
16861
+ while (pendingSegment && splitGuard < 256) {
16862
+ splitGuard += 1;
16863
+ const currentSegment = pendingSegment;
16864
+ const segmentNode = model.nodes[currentSegment.nodeIndex];
16865
+ if (!segmentNode) {
16866
+ columns[columnIndex]?.push(currentSegment);
16867
+ break;
16868
+ }
16869
+ const columnWidthPx = Math.max(
16870
+ 120,
16871
+ Math.round(columnWidthsPx[columnIndex] ?? columnWidthsPx[0] ?? 120)
16872
+ );
16873
+ const docGridLinePitchPx = docGridLinePitchPxByNodeIndex?.get(
16874
+ currentSegment.nodeIndex
16875
+ );
16876
+ const segmentHeightPx = resolveSegmentHeightPx(
16877
+ currentSegment,
16878
+ columnWidthPx
16879
+ );
16880
+ const remainingHeightPx = Math.max(
16881
+ 0,
16882
+ safeColumnHeightPx - consumedHeightPx
16883
+ );
16884
+ if (segmentHeightPx <= remainingHeightPx + PAGE_OVERFLOW_TOLERANCE_PX || columnIndex + 1 >= columnCount) {
16885
+ pushSegment(currentSegment, segmentHeightPx);
16886
+ pendingSegment = void 0;
16887
+ break;
16888
+ }
16889
+ const splitSegment = segmentNode.type === "paragraph" ? splitParagraphSegmentForColumnRender({
16890
+ paragraph: segmentNode,
16891
+ segment: currentSegment,
16892
+ model,
16893
+ availableWidthPx: columnWidthPx,
16894
+ availableHeightPx: remainingHeightPx,
16895
+ numberingDefinitions,
16896
+ docGridLinePitchPx
16897
+ }) : void 0;
16898
+ if (splitSegment) {
16899
+ pushSegment(splitSegment.currentSegment, splitSegment.currentHeightPx);
16900
+ pendingSegment = splitSegment.remainderSegment;
16901
+ if (!moveToNextColumn()) {
16902
+ const remainderSegment = splitSegment.remainderSegment;
16903
+ const remainderHeightPx = estimateRenderedPageSegmentHeightPx(
16904
+ segmentNode,
16905
+ remainderSegment,
16906
+ model,
16907
+ columnWidthPx,
16908
+ numberingDefinitions,
16909
+ docGridLinePitchPx
16910
+ );
16911
+ pushSegment(remainderSegment, remainderHeightPx);
16912
+ pendingSegment = void 0;
16913
+ }
16914
+ continue;
16915
+ }
16916
+ if (!moveToNextColumn()) {
16917
+ pushSegment(currentSegment, segmentHeightPx);
16918
+ pendingSegment = void 0;
16919
+ }
16920
+ }
16921
+ }
16922
+ return columns;
16923
+ }
16390
16924
  function sumEstimatedTableRowHeightsPx(rowHeightsPx, startRowIndex, endRowIndex) {
16391
16925
  let total = 0;
16392
16926
  const clampedStart = Math.max(0, startRowIndex);
@@ -16860,16 +17394,10 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
16860
17394
  const exactSegmentEndLineIndex = resolveMaxPretextLineRangeEndIndexThatFits(
16861
17395
  pretextLayoutForSegmentSplitting,
16862
17396
  lineCursor,
16863
- Math.min(
16864
- resolvedParagraphLineCount,
16865
- lineCursor + linesThatFit
16866
- ),
17397
+ Math.min(resolvedParagraphLineCount, lineCursor + linesThatFit),
16867
17398
  availableForLinesPx
16868
17399
  );
16869
- linesThatFit = Math.max(
16870
- 0,
16871
- exactSegmentEndLineIndex - lineCursor
16872
- );
17400
+ linesThatFit = Math.max(0, exactSegmentEndLineIndex - lineCursor);
16873
17401
  }
16874
17402
  if (linesThatFit < minLinesPerSegment) {
16875
17403
  if (currentPageSegments.length > 0) {
@@ -16906,10 +17434,7 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
16906
17434
  lineCursor,
16907
17435
  segmentEndLineIndex
16908
17436
  );
16909
- if (topSpacingPx + resolveSegmentContentHeightPx(
16910
- lineCursor,
16911
- segmentEndLineIndex
16912
- ) + segmentReservePx <= remainingHeightPx2) {
17437
+ if (topSpacingPx + resolveSegmentContentHeightPx(lineCursor, segmentEndLineIndex) + segmentReservePx <= remainingHeightPx2) {
16913
17438
  break;
16914
17439
  }
16915
17440
  linesThatFit -= 1;
@@ -17110,6 +17635,7 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
17110
17635
  let rowStartIndex = 0;
17111
17636
  let rowSliceOffsetPx = 0;
17112
17637
  let repeatedHeaderHeightPxOnThisPage = 0;
17638
+ let tableBreakStartRowCursor = 0;
17113
17639
  while (rowStartIndex < estimatedRowHeightsPx.length) {
17114
17640
  if (currentPageSegments.length === 0) {
17115
17641
  repeatedHeaderHeightPxOnThisPage = 0;
@@ -17144,9 +17670,10 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
17144
17670
  currentPageContentHeightPx - repeatedHeaderHeightPxOnThisPage
17145
17671
  );
17146
17672
  const rowExceedsFreshPageHeightPx = currentRowTotalHeightPx > freshPageAvailableHeightPx + PAGE_OVERFLOW_TOLERANCE_PX;
17673
+ const hasUsableCurrentPageSliceSpace = pageConsumedHeightPx > 0 && remainingHeightPx >= MIN_TABLE_ROW_SLICE_REMAINING_HEIGHT_PX;
17147
17674
  const canSplitCurrentRow = rowSliceOffsetPx > 0 || rowAllowsPageSplit(currentRow) || rowExceedsFreshPageHeightPx;
17148
17675
  const shouldContinueExistingRowSlice = rowSliceOffsetPx > 0;
17149
- const rowNeedsSliceOnThisPage = ENABLE_TABLE_ROW_SLICING && canSplitCurrentRow && currentRowRemainingHeightPx > remainingHeightPx + PAGE_OVERFLOW_TOLERANCE_PX && (shouldContinueExistingRowSlice || rowExceedsFreshPageHeightPx);
17676
+ const rowNeedsSliceOnThisPage = ENABLE_TABLE_ROW_SLICING && canSplitCurrentRow && currentRowRemainingHeightPx > remainingHeightPx + PAGE_OVERFLOW_TOLERANCE_PX && (shouldContinueExistingRowSlice || rowExceedsFreshPageHeightPx || hasUsableCurrentPageSliceSpace);
17150
17677
  if (canSplitCurrentRow && currentRowRemainingHeightPx > remainingHeightPx + PAGE_OVERFLOW_TOLERANCE_PX && !rowNeedsSliceOnThisPage && currentPageSegments.length > 0) {
17151
17678
  startNextPage();
17152
17679
  pageConsumedHeightPx = 0;
@@ -17174,10 +17701,38 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
17174
17701
  MIN_PARAGRAPH_LINE_HEIGHT_PX,
17175
17702
  Math.round(remainingHeightPx)
17176
17703
  );
17177
- const sliceHeightPx = Math.max(
17704
+ const preferredSliceHeightPx = Math.max(
17178
17705
  MIN_PARAGRAPH_LINE_HEIGHT_PX,
17179
17706
  Math.min(currentRowRemainingHeightPx, availableSliceHeightPx)
17180
17707
  );
17708
+ const safeSliceHeightPx = resolveTableRowSliceHeightOnSafeBoundaryPx({
17709
+ table: node,
17710
+ rowIndex: rowStartIndex,
17711
+ rowHeightPx: currentRowTotalHeightPx,
17712
+ rowSliceOffsetPx,
17713
+ preferredSliceHeightPx,
17714
+ maxAvailableWidthPx: nodeMetrics.pageContentWidthPx,
17715
+ numberingDefinitions,
17716
+ docGridLinePitchPx: nodeMetrics.docGridLinePitchPx
17717
+ });
17718
+ if (safeSliceHeightPx === void 0 && pageConsumedHeightPx > 0 && currentPageSegments.length > 0) {
17719
+ startNextPage();
17720
+ pageConsumedHeightPx = 0;
17721
+ previousParagraphAfterPx = 0;
17722
+ currentSectionPageFlowOriginPx = 0;
17723
+ currentPageContentHeightPx = resolveMetricsPageContentHeightPx(
17724
+ currentPageIndex,
17725
+ nodeMetrics
17726
+ );
17727
+ continue;
17728
+ }
17729
+ const sliceHeightPx = Math.max(
17730
+ MIN_PARAGRAPH_LINE_HEIGHT_PX,
17731
+ Math.min(
17732
+ currentRowRemainingHeightPx,
17733
+ safeSliceHeightPx ?? preferredSliceHeightPx
17734
+ )
17735
+ );
17181
17736
  currentPageSegments.push({
17182
17737
  nodeIndex,
17183
17738
  tableRowRange: {
@@ -17243,9 +17798,10 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
17243
17798
  pageConsumedHeightPx <= 0
17244
17799
  );
17245
17800
  let rowEndIndex = fittedRowEndIndex;
17246
- const forcedBreakRowIndex = tableBreakStartRows.find(
17247
- (breakRowIndex) => breakRowIndex > rowStartIndex
17248
- );
17801
+ while (tableBreakStartRowCursor < tableBreakStartRows.length && tableBreakStartRows[tableBreakStartRowCursor] <= rowStartIndex) {
17802
+ tableBreakStartRowCursor += 1;
17803
+ }
17804
+ const forcedBreakRowIndex = tableBreakStartRows[tableBreakStartRowCursor];
17249
17805
  if (forcedBreakRowIndex !== void 0) {
17250
17806
  rowEndIndex = Math.min(rowEndIndex, forcedBreakRowIndex);
17251
17807
  }
@@ -17311,6 +17867,19 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
17311
17867
  rowStartIndex = rowEndIndex;
17312
17868
  rowSliceOffsetPx = 0;
17313
17869
  if (rowStartIndex < estimatedRowHeightsPx.length) {
17870
+ const nextRow = node.rows[rowStartIndex];
17871
+ const nextRowHeightPx = Math.max(
17872
+ MIN_PARAGRAPH_LINE_HEIGHT_PX,
17873
+ estimatedRowHeightsPx[rowStartIndex] ?? MIN_PARAGRAPH_LINE_HEIGHT_PX
17874
+ );
17875
+ const remainingHeightAfterSegmentPx = Math.max(
17876
+ 0,
17877
+ currentPageContentHeightPx - pageConsumedHeightPx
17878
+ );
17879
+ const canSliceNextRowOnCurrentPage = ENABLE_TABLE_ROW_SLICING && nextRow !== void 0 && rowAllowsPageSplit(nextRow) && !tableBreakStartRows.includes(rowStartIndex) && remainingHeightAfterSegmentPx >= MIN_TABLE_ROW_SLICE_REMAINING_HEIGHT_PX && nextRowHeightPx > remainingHeightAfterSegmentPx + PAGE_OVERFLOW_TOLERANCE_PX;
17880
+ if (canSliceNextRowOnCurrentPage) {
17881
+ continue;
17882
+ }
17314
17883
  startNextPage();
17315
17884
  pageConsumedHeightPx = 0;
17316
17885
  previousParagraphAfterPx = 0;
@@ -24363,7 +24932,8 @@ function useDocxEditor(options = {}) {
24363
24932
  const [status, setStatus] = React.useState(
24364
24933
  options.initialStatus ?? "Ready"
24365
24934
  );
24366
- const isImporting = false;
24935
+ const [importError, setImportError] = React.useState();
24936
+ const [isImporting, setIsImporting] = React.useState(false);
24367
24937
  const [documentTheme, setDocumentThemeState] = React.useState(options.initialDocumentTheme ?? "light");
24368
24938
  const [showTrackedChanges, setShowTrackedChangesState] = React.useState(options.initialShowTrackedChanges ?? false);
24369
24939
  const [paginationInfo, setPaginationInfo] = React.useState({
@@ -24880,12 +25450,36 @@ function useDocxEditor(options = {}) {
24880
25450
  },
24881
25451
  [dispatchEditorTransaction]
24882
25452
  );
25453
+ const replaceDocumentWithImportError = React.useCallback(
25454
+ (fileName2, error) => {
25455
+ unloadEmbeddedFonts();
25456
+ setModel(createBlankDocumentModel());
25457
+ setDocumentLoadNonce((current) => current + 1);
25458
+ setHistory({ past: [], future: [] });
25459
+ setHistoryRestoreRequest(void 0);
25460
+ setBasePackage(void 0);
25461
+ setFileName(fileName2);
25462
+ setSelection({ kind: "paragraph", nodeIndex: 0 });
25463
+ setActiveTextRangeState(void 0);
25464
+ setPendingRunStyle(void 0);
25465
+ setSelectedFormFieldLocation(void 0);
25466
+ setImportError(error);
25467
+ setStatus(`Failed to load file: ${error.message}`);
25468
+ },
25469
+ [unloadEmbeddedFonts]
25470
+ );
24883
25471
  const importDocxFile = React.useCallback(
24884
25472
  async (file) => {
24885
25473
  if (!/\.docx$/i.test(file.name)) {
24886
- setStatus("Only .docx files are supported");
25474
+ replaceDocumentWithImportError(
25475
+ file.name,
25476
+ new Error("Only .docx files are supported")
25477
+ );
24887
25478
  return;
24888
25479
  }
25480
+ setIsImporting(true);
25481
+ setImportError(void 0);
25482
+ setStatus(`Loading ${file.name}...`);
24889
25483
  try {
24890
25484
  const buffer = await file.arrayBuffer();
24891
25485
  const pkg = await parseDocx(buffer);
@@ -24901,14 +25495,16 @@ function useDocxEditor(options = {}) {
24901
25495
  setActiveTextRangeState(void 0);
24902
25496
  setPendingRunStyle(void 0);
24903
25497
  setSelectedFormFieldLocation(void 0);
25498
+ setImportError(void 0);
24904
25499
  setStatus(`Loaded ${file.name}`);
24905
25500
  } catch (error) {
24906
- setStatus(
24907
- `Failed to load file: ${error instanceof Error ? error.message : "Unknown error"}`
24908
- );
25501
+ const nextError = error instanceof Error ? error : new Error("Unknown error");
25502
+ replaceDocumentWithImportError(file.name, nextError);
25503
+ } finally {
25504
+ setIsImporting(false);
24909
25505
  }
24910
25506
  },
24911
- [loadEmbeddedFontsFromPackage]
25507
+ [loadEmbeddedFontsFromPackage, replaceDocumentWithImportError]
24912
25508
  );
24913
25509
  const newDocument = React.useCallback(() => {
24914
25510
  unloadEmbeddedFonts();
@@ -24922,6 +25518,7 @@ function useDocxEditor(options = {}) {
24922
25518
  setSelectedFormFieldLocation(void 0);
24923
25519
  setHistory({ past: [], future: [] });
24924
25520
  setHistoryRestoreRequest(void 0);
25521
+ setImportError(void 0);
24925
25522
  setStatus("Created new document");
24926
25523
  }, [unloadEmbeddedFonts]);
24927
25524
  const exportDocx = React.useCallback(() => {
@@ -27830,6 +28427,7 @@ function useDocxEditor(options = {}) {
27830
28427
  documentLoadNonce,
27831
28428
  fileName,
27832
28429
  status,
28430
+ importError,
27833
28431
  isImporting,
27834
28432
  documentTheme,
27835
28433
  trackedChanges,
@@ -29395,7 +29993,7 @@ function DocxEditorViewer({
29395
29993
  style,
29396
29994
  pageBackgroundColor,
29397
29995
  pageGapBackgroundColor,
29398
- deferInitialPaginationPaint = true,
29996
+ deferInitialPaginationPaint = false,
29399
29997
  loadingState,
29400
29998
  pageVirtualization,
29401
29999
  visiblePageRange,
@@ -29456,6 +30054,10 @@ function DocxEditorViewer({
29456
30054
  const paragraphElementsRef = React.useRef(
29457
30055
  /* @__PURE__ */ new Map()
29458
30056
  );
30057
+ const [
30058
+ measuredParagraphOuterHeightsPxByNodeIndex,
30059
+ setMeasuredParagraphOuterHeightsPxByNodeIndex
30060
+ ] = React.useState(() => /* @__PURE__ */ new Map());
29459
30061
  const tableCellEditorElementsRef = React.useRef(
29460
30062
  /* @__PURE__ */ new Map()
29461
30063
  );
@@ -29730,6 +30332,9 @@ function DocxEditorViewer({
29730
30332
  const paginationMeasurementResumeTimeoutRef = React.useRef(
29731
30333
  null
29732
30334
  );
30335
+ React.useLayoutEffect(() => {
30336
+ setMeasuredParagraphOuterHeightsPxByNodeIndex(/* @__PURE__ */ new Map());
30337
+ }, [editor.documentLoadNonce, paragraphStructureEpoch]);
29733
30338
  const schedulePaginationMeasurementResume = React.useCallback(
29734
30339
  (delayMs) => {
29735
30340
  if (typeof window === "undefined") {
@@ -29942,10 +30547,20 @@ function DocxEditorViewer({
29942
30547
  () => buildPaginationSectionMetrics(documentSections, documentLayout),
29943
30548
  [documentLayout, documentSections]
29944
30549
  );
29945
- const docGridLinePitchPxByNodeIndex = React.useMemo(() => {
30550
+ const {
30551
+ docGridLinePitchPxByNodeIndex,
30552
+ pageContentWidthPxByNodeIndex,
30553
+ pageContentHeightPxByNodeIndex
30554
+ } = React.useMemo(() => {
29946
30555
  const pitchByNodeIndex = /* @__PURE__ */ new Map();
30556
+ const widthByNodeIndex = /* @__PURE__ */ new Map();
30557
+ const heightByNodeIndex = /* @__PURE__ */ new Map();
29947
30558
  if (editor.model.nodes.length === 0 || paginationSectionMetrics.length === 0) {
29948
- return pitchByNodeIndex;
30559
+ return {
30560
+ docGridLinePitchPxByNodeIndex: pitchByNodeIndex,
30561
+ pageContentWidthPxByNodeIndex: widthByNodeIndex,
30562
+ pageContentHeightPxByNodeIndex: heightByNodeIndex
30563
+ };
29949
30564
  }
29950
30565
  let currentMetricsIndex = 0;
29951
30566
  for (let nodeIndex = 0; nodeIndex < editor.model.nodes.length; nodeIndex += 1) {
@@ -29954,51 +30569,22 @@ function DocxEditorViewer({
29954
30569
  nodeIndex,
29955
30570
  currentMetricsIndex
29956
30571
  );
29957
- const docGridLinePitchPx = paginationSectionMetrics[currentMetricsIndex]?.docGridLinePitchPx;
30572
+ const nodeMetrics = paginationSectionMetrics[currentMetricsIndex];
30573
+ const docGridLinePitchPx = nodeMetrics?.docGridLinePitchPx;
29958
30574
  if (Number.isFinite(docGridLinePitchPx) && docGridLinePitchPx > 0) {
29959
30575
  pitchByNodeIndex.set(
29960
30576
  nodeIndex,
29961
30577
  Math.round(docGridLinePitchPx)
29962
30578
  );
29963
30579
  }
29964
- }
29965
- return pitchByNodeIndex;
29966
- }, [editor.model.nodes, paginationSectionMetrics]);
29967
- const pageContentWidthPxByNodeIndex = React.useMemo(() => {
29968
- const widthByNodeIndex = /* @__PURE__ */ new Map();
29969
- if (editor.model.nodes.length === 0 || paginationSectionMetrics.length === 0) {
29970
- return widthByNodeIndex;
29971
- }
29972
- let currentMetricsIndex = 0;
29973
- for (let nodeIndex = 0; nodeIndex < editor.model.nodes.length; nodeIndex += 1) {
29974
- currentMetricsIndex = resolvePaginationSectionMetricsIndexForNodeIndex(
29975
- paginationSectionMetrics,
29976
- nodeIndex,
29977
- currentMetricsIndex
29978
- );
29979
- const pageContentWidthPx = paginationSectionMetrics[currentMetricsIndex]?.pageContentWidthPx;
30580
+ const pageContentWidthPx = nodeMetrics?.pageContentWidthPx;
29980
30581
  if (Number.isFinite(pageContentWidthPx) && pageContentWidthPx > 0) {
29981
30582
  widthByNodeIndex.set(
29982
30583
  nodeIndex,
29983
30584
  Math.round(pageContentWidthPx)
29984
30585
  );
29985
30586
  }
29986
- }
29987
- return widthByNodeIndex;
29988
- }, [editor.model.nodes, paginationSectionMetrics]);
29989
- const pageContentHeightPxByNodeIndex = React.useMemo(() => {
29990
- const heightByNodeIndex = /* @__PURE__ */ new Map();
29991
- if (editor.model.nodes.length === 0 || paginationSectionMetrics.length === 0) {
29992
- return heightByNodeIndex;
29993
- }
29994
- let currentMetricsIndex = 0;
29995
- for (let nodeIndex = 0; nodeIndex < editor.model.nodes.length; nodeIndex += 1) {
29996
- currentMetricsIndex = resolvePaginationSectionMetricsIndexForNodeIndex(
29997
- paginationSectionMetrics,
29998
- nodeIndex,
29999
- currentMetricsIndex
30000
- );
30001
- const pageContentHeightPx = paginationSectionMetrics[currentMetricsIndex]?.pageContentHeightPx;
30587
+ const pageContentHeightPx = nodeMetrics?.pageContentHeightPx;
30002
30588
  if (Number.isFinite(pageContentHeightPx) && pageContentHeightPx > 0) {
30003
30589
  heightByNodeIndex.set(
30004
30590
  nodeIndex,
@@ -30006,7 +30592,11 @@ function DocxEditorViewer({
30006
30592
  );
30007
30593
  }
30008
30594
  }
30009
- return heightByNodeIndex;
30595
+ return {
30596
+ docGridLinePitchPxByNodeIndex: pitchByNodeIndex,
30597
+ pageContentWidthPxByNodeIndex: widthByNodeIndex,
30598
+ pageContentHeightPxByNodeIndex: heightByNodeIndex
30599
+ };
30010
30600
  }, [editor.model.nodes, paginationSectionMetrics]);
30011
30601
  const sectionColumnsBySectionIndex = React.useMemo(
30012
30602
  () => documentSections.map(
@@ -30158,11 +30748,11 @@ function DocxEditorViewer({
30158
30748
  renderPageContentHeightScale: estimatedRenderPageContentHeightScale
30159
30749
  };
30160
30750
  }
30161
- const pureEstimatedPages = buildEstimatedPages(
30162
- tableMeasuredRowHeightsForPagination,
30163
- null
30164
- );
30165
30751
  if (measuredPageContentHeightByIndex && measuredPageContentHeightByIndex.length > 0) {
30752
+ const pureEstimatedPages = buildEstimatedPages(
30753
+ tableMeasuredRowHeightsForPagination,
30754
+ null
30755
+ );
30166
30756
  const measuredPagesAreOnlySplitParagraphs = estimatedPages.length > 0 && estimatedPages.every(
30167
30757
  (pageSegments) => documentPageContainsOnlySplitParagraphSegments(pageSegments)
30168
30758
  );
@@ -30209,9 +30799,9 @@ function DocxEditorViewer({
30209
30799
  estimatedRenderMeasuredPageContentHeightsPxByPageIndex = bestCandidate.renderMeasuredPageContentHeightsPxByPageIndex;
30210
30800
  estimatedRenderPageContentHeightScale = bestCandidate.renderPageContentHeightScale;
30211
30801
  } else if (!editor.canUndo && !editor.canRedo && targetPageCount !== void 0 && !hasMultiColumnRenderedPageBreakHints) {
30212
- const pureEstimatedPages2 = buildEstimatedPages(void 0, null);
30213
- if (Math.abs(pureEstimatedPages2.length - targetPageCount) < Math.abs(estimatedPages.length - targetPageCount)) {
30214
- estimatedPages = pureEstimatedPages2;
30802
+ const pureEstimatedPages = buildEstimatedPages(void 0, null);
30803
+ if (Math.abs(pureEstimatedPages.length - targetPageCount) < Math.abs(estimatedPages.length - targetPageCount)) {
30804
+ estimatedPages = pureEstimatedPages;
30215
30805
  estimatedPagesUseMeasuredPageContentHeightsForRender = false;
30216
30806
  estimatedRenderMeasuredPageContentHeightsPxByPageIndex = void 0;
30217
30807
  estimatedRenderPageContentHeightScale = void 0;
@@ -30331,9 +30921,9 @@ function DocxEditorViewer({
30331
30921
  ) : void 0;
30332
30922
  let reconciledRenderPageContentHeightScale = reconciledPagesUseMeasuredPageContentHeightsForRender ? void 0 : reconciledCandidate.scale;
30333
30923
  if (!editor.canUndo && !editor.canRedo) {
30334
- const pureEstimatedPages2 = buildEstimatedPages(void 0, null);
30924
+ const pureEstimatedPages = buildEstimatedPages(void 0, null);
30335
30925
  const pureReconciledCandidate = reconcileCandidatePages(
30336
- pureEstimatedPages2,
30926
+ pureEstimatedPages,
30337
30927
  void 0,
30338
30928
  null
30339
30929
  );
@@ -30830,8 +31420,9 @@ function DocxEditorViewer({
30830
31420
  pageCount,
30831
31421
  pageVirtualization?.overscan
30832
31422
  ]);
31423
+ const shouldObserveVisiblePageRange = hasLargeTableLayoutSurface || internalVirtualItems.length === 0;
30833
31424
  React.useLayoutEffect(() => {
30834
- if (!internalPageVirtualizationEnabled || !internalVirtualScrollElement || internalVirtualItems.length > 0 || typeof window === "undefined") {
31425
+ if (!internalPageVirtualizationEnabled || !internalVirtualScrollElement || !shouldObserveVisiblePageRange || typeof window === "undefined") {
30835
31426
  setObservedVisiblePageRange(
30836
31427
  (current) => current === void 0 ? current : void 0
30837
31428
  );
@@ -30845,6 +31436,15 @@ function DocxEditorViewer({
30845
31436
  return;
30846
31437
  }
30847
31438
  let frameId = null;
31439
+ const commitObservedVisiblePageRange = (updater) => {
31440
+ if (hasLargeTableLayoutSurface) {
31441
+ (0, import_react_dom.flushSync)(() => {
31442
+ setObservedVisiblePageRange(updater);
31443
+ });
31444
+ return;
31445
+ }
31446
+ setObservedVisiblePageRange(updater);
31447
+ };
30848
31448
  const syncVisiblePageRange = () => {
30849
31449
  frameId = null;
30850
31450
  const viewportRect = internalVirtualScrollUsesWindow ? {
@@ -30878,7 +31478,7 @@ function DocxEditorViewer({
30878
31478
  lastVisiblePageIndex = pageIndex;
30879
31479
  }
30880
31480
  if (firstVisiblePageIndex === void 0 || lastVisiblePageIndex === void 0) {
30881
- setObservedVisiblePageRange(
31481
+ commitObservedVisiblePageRange(
30882
31482
  (current) => current === void 0 ? current : void 0
30883
31483
  );
30884
31484
  return;
@@ -30893,7 +31493,7 @@ function DocxEditorViewer({
30893
31493
  startPageIndex,
30894
31494
  pageCount - 1
30895
31495
  );
30896
- setObservedVisiblePageRange((current) => {
31496
+ commitObservedVisiblePageRange((current) => {
30897
31497
  if (current?.startPageIndex === startPageIndex && current?.endPageIndex === endPageIndex) {
30898
31498
  return current;
30899
31499
  }
@@ -30945,14 +31545,42 @@ function DocxEditorViewer({
30945
31545
  }
30946
31546
  };
30947
31547
  }, [
31548
+ hasLargeTableLayoutSurface,
30948
31549
  internalPageVirtualizationEnabled,
30949
31550
  internalVirtualItems.length,
30950
31551
  internalVirtualScrollElement,
30951
31552
  internalVirtualScrollUsesWindow,
30952
31553
  pageCount,
30953
- pageVirtualizationOverscan
31554
+ pageVirtualizationOverscan,
31555
+ shouldObserveVisiblePageRange
30954
31556
  ]);
30955
- const effectiveVisiblePageRange = visiblePageRange ?? internalRenderVisiblePageRange ?? observedVisiblePageRange ?? (internalPageVirtualizationPending ? {
31557
+ const internalEffectiveRenderVisiblePageRange = React.useMemo(() => {
31558
+ if (!internalRenderVisiblePageRange) {
31559
+ return observedVisiblePageRange;
31560
+ }
31561
+ if (!observedVisiblePageRange || !hasLargeTableLayoutSurface) {
31562
+ return internalRenderVisiblePageRange;
31563
+ }
31564
+ const rangesAreAdjacentOrOverlapping = observedVisiblePageRange.startPageIndex <= internalRenderVisiblePageRange.endPageIndex + 2 && internalRenderVisiblePageRange.startPageIndex <= observedVisiblePageRange.endPageIndex + 2;
31565
+ if (!rangesAreAdjacentOrOverlapping) {
31566
+ return internalRenderVisiblePageRange;
31567
+ }
31568
+ return {
31569
+ startPageIndex: Math.min(
31570
+ internalRenderVisiblePageRange.startPageIndex,
31571
+ observedVisiblePageRange.startPageIndex
31572
+ ),
31573
+ endPageIndex: Math.max(
31574
+ internalRenderVisiblePageRange.endPageIndex,
31575
+ observedVisiblePageRange.endPageIndex
31576
+ )
31577
+ };
31578
+ }, [
31579
+ hasLargeTableLayoutSurface,
31580
+ internalRenderVisiblePageRange,
31581
+ observedVisiblePageRange
31582
+ ]);
31583
+ const effectiveVisiblePageRange = visiblePageRange ?? internalEffectiveRenderVisiblePageRange ?? observedVisiblePageRange ?? (internalPageVirtualizationPending ? {
30956
31584
  startPageIndex: 0,
30957
31585
  endPageIndex: Math.min(
30958
31586
  pageCount - 1,
@@ -31001,6 +31629,43 @@ function DocxEditorViewer({
31001
31629
  }
31002
31630
  return indexes;
31003
31631
  }, [pageCount, visiblePageEndIndex, visiblePageStartIndex]);
31632
+ React.useLayoutEffect(() => {
31633
+ if (typeof window === "undefined") {
31634
+ return;
31635
+ }
31636
+ setMeasuredParagraphOuterHeightsPxByNodeIndex((current) => {
31637
+ const next = new Map(current);
31638
+ let changed = false;
31639
+ paragraphElementsRef.current.forEach((element, nodeIndex) => {
31640
+ if (!element.isConnected || element.dataset.docxParagraphPartialLineRange === "true" || element.closest('[data-docx-header-footer-region="footer"]') || element.closest('[data-docx-header-footer-region="header"]')) {
31641
+ return;
31642
+ }
31643
+ const rect = element.getBoundingClientRect();
31644
+ if (rect.width <= 0 && rect.height <= 0) {
31645
+ return;
31646
+ }
31647
+ const style2 = window.getComputedStyle(element);
31648
+ const marginTop = Number.parseFloat(style2.marginTop || "0");
31649
+ const marginBottom = Number.parseFloat(style2.marginBottom || "0");
31650
+ const outerHeightPx = Math.max(
31651
+ 1,
31652
+ Math.round(
31653
+ rect.height + (Number.isFinite(marginTop) ? marginTop : 0) + (Number.isFinite(marginBottom) ? marginBottom : 0)
31654
+ )
31655
+ );
31656
+ if (next.get(nodeIndex) !== outerHeightPx) {
31657
+ next.set(nodeIndex, outerHeightPx);
31658
+ changed = true;
31659
+ }
31660
+ });
31661
+ return changed ? next : current;
31662
+ });
31663
+ }, [
31664
+ editor.documentLoadNonce,
31665
+ pageNodeSegmentIdentityKeysByPage,
31666
+ visiblePageEndIndex,
31667
+ visiblePageStartIndex
31668
+ ]);
31004
31669
  const visibleTableRowIndexesByNodeIndex = React.useMemo(() => {
31005
31670
  const rowsByNodeIndex = /* @__PURE__ */ new Map();
31006
31671
  const addRowIndex = (nodeIndex, rowIndex) => {
@@ -31075,7 +31740,8 @@ function DocxEditorViewer({
31075
31740
  tableMeasuredRowHeights,
31076
31741
  visiblePageIndexes
31077
31742
  ]);
31078
- const visiblePagesNeedMeasurementUnlock = !hideDocumentUntilPaginationSettled && visiblePagesHavePendingPaginationMeasurements;
31743
+ const allowPostImportPaginationMeasurement = !hasLargeTableLayoutSurface || !internalPageVirtualizationEnabled;
31744
+ const visiblePagesNeedMeasurementUnlock = !hideDocumentUntilPaginationSettled && allowPostImportPaginationMeasurement && visiblePagesHavePendingPaginationMeasurements;
31079
31745
  React.useEffect(() => {
31080
31746
  if (!visiblePagesNeedMeasurementUnlock) {
31081
31747
  return;
@@ -41047,11 +41713,17 @@ function DocxEditorViewer({
41047
41713
  } : void 0,
41048
41714
  outline: "none"
41049
41715
  };
41050
- const fallbackParagraphRuns = renderInteractiveParagraphRuns(
41051
- paragraph,
41052
- `body-cell-${tableIndex}-${rowIndex}-${cellIndex}-${contentIndex}`,
41053
- location
41054
- );
41716
+ let fallbackParagraphRuns;
41717
+ const getFallbackParagraphRuns = () => {
41718
+ if (fallbackParagraphRuns === void 0) {
41719
+ fallbackParagraphRuns = renderInteractiveParagraphRuns(
41720
+ paragraph,
41721
+ `body-cell-${tableIndex}-${rowIndex}-${cellIndex}-${contentIndex}`,
41722
+ location
41723
+ );
41724
+ }
41725
+ return fallbackParagraphRuns;
41726
+ };
41055
41727
  const renderedInteractiveParagraphContent = shouldRenderParagraphSegmentWithPretext ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
41056
41728
  "div",
41057
41729
  {
@@ -41089,11 +41761,11 @@ function DocxEditorViewer({
41089
41761
  style: {
41090
41762
  transform: `translateY(-${paragraphSegmentTranslateYPx - paragraphSegmentClipBleedTopPx}px)`
41091
41763
  },
41092
- children: fallbackParagraphRuns
41764
+ children: getFallbackParagraphRuns()
41093
41765
  }
41094
41766
  )
41095
41767
  }
41096
- ) : fallbackParagraphRuns;
41768
+ ) : getFallbackParagraphRuns();
41097
41769
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
41098
41770
  "div",
41099
41771
  {
@@ -41335,6 +42007,7 @@ function DocxEditorViewer({
41335
42007
  ...resolvedAfterSpacingPx !== void 0 ? { marginBottom: resolvedAfterSpacingPx } : void 0
41336
42008
  } : void 0,
41337
42009
  ...letterheadStyleAdjustments ?? void 0,
42010
+ ...options?.normalizeParagraphHostFontSize ? { fontSize: `${paragraphBaseFontSizePx(node)}px` } : void 0,
41338
42011
  ...options?.suppressLetterheadColumnLayout && options?.isFirstInLetterheadColumn ? { marginTop: 0 } : void 0,
41339
42012
  ...pageAbsoluteAnchorOnlyParagraph ? {
41340
42013
  position: "relative",
@@ -41353,19 +42026,25 @@ function DocxEditorViewer({
41353
42026
  } : void 0,
41354
42027
  outline: "none"
41355
42028
  };
41356
- const fallbackParagraphRuns = renderInteractiveParagraphRuns(
41357
- node,
41358
- `node-${nodeIndex}`,
41359
- {
41360
- kind: "paragraph",
41361
- nodeIndex
41362
- },
41363
- {
41364
- pageFlowTopPx: paragraphPageFlowTopPx,
41365
- pageLayout: resolvedPageLayout,
41366
- suppressLikelyFullPageCoverImageKeys: options?.suppressLikelyFullPageCoverImageKeys
42029
+ let fallbackParagraphRuns;
42030
+ const getFallbackParagraphRuns = () => {
42031
+ if (fallbackParagraphRuns === void 0) {
42032
+ fallbackParagraphRuns = renderInteractiveParagraphRuns(
42033
+ node,
42034
+ `node-${nodeIndex}`,
42035
+ {
42036
+ kind: "paragraph",
42037
+ nodeIndex
42038
+ },
42039
+ {
42040
+ pageFlowTopPx: paragraphPageFlowTopPx,
42041
+ pageLayout: resolvedPageLayout,
42042
+ suppressLikelyFullPageCoverImageKeys: options?.suppressLikelyFullPageCoverImageKeys
42043
+ }
42044
+ );
41367
42045
  }
41368
- );
42046
+ return fallbackParagraphRuns;
42047
+ };
41369
42048
  const renderedInteractiveParagraphContent = shouldRenderParagraphSegmentWithPretext ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
41370
42049
  "div",
41371
42050
  {
@@ -41406,11 +42085,11 @@ function DocxEditorViewer({
41406
42085
  style: {
41407
42086
  transform: `translateY(-${paragraphSegmentTranslateYPx - paragraphSegmentClipBleedTopPx}px)`
41408
42087
  },
41409
- children: fallbackParagraphRuns
42088
+ children: getFallbackParagraphRuns()
41410
42089
  }
41411
42090
  )
41412
42091
  }
41413
- ) : fallbackParagraphRuns;
42092
+ ) : getFallbackParagraphRuns();
41414
42093
  const paragraphDraftHtml = paragraphDraftsRef.current.get(nodeIndex);
41415
42094
  const renderedEditableParagraphHtml = typeof paragraphDraftHtml === "string" ? paragraphDraftHtml : renderStaticHtml(renderedInteractiveParagraphContent);
41416
42095
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
@@ -41421,6 +42100,7 @@ function DocxEditorViewer({
41421
42100
  "data-docx-paragraph-node-index": nodeIndex,
41422
42101
  "data-docx-paragraph-start-line": paragraphSegmentStartLine,
41423
42102
  "data-docx-paragraph-end-line": paragraphSegmentEndLine,
42103
+ "data-docx-paragraph-partial-line-range": hasPartialLineRange ? "true" : void 0,
41424
42104
  style: paragraphStyle,
41425
42105
  dangerouslySetInnerHTML: editable ? {
41426
42106
  __html: renderedEditableParagraphHtml
@@ -42458,6 +43138,68 @@ ${currentText.slice(end)}`;
42458
43138
  })() : void 0;
42459
43139
  const tableCellDraftHtml = tableCellDraftsRef.current.get(cellDraftKey);
42460
43140
  const renderedEditableCellHtml = editableCell ? typeof tableCellDraftHtml === "string" ? tableCellDraftHtml : renderStaticHtml(renderedEditableCellContent) : void 0;
43141
+ const renderStaticCellContent = () => {
43142
+ let paragraphCursor = 0;
43143
+ return cell.nodes.map(
43144
+ (cellContent, contentIndex) => {
43145
+ if (cellContent.type === "paragraph") {
43146
+ const paragraphIndex = paragraphCursor;
43147
+ paragraphCursor += 1;
43148
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
43149
+ "div",
43150
+ {
43151
+ "data-docx-paragraph-host": "true",
43152
+ "data-docx-paragraph-kind": "table-cell",
43153
+ "data-docx-table-index": nodeIndex,
43154
+ "data-docx-row-index": rowIndex,
43155
+ "data-docx-cell-index": cellIndex,
43156
+ "data-docx-paragraph-index": paragraphIndex,
43157
+ "data-docx-table-paragraph-index": paragraphIndex,
43158
+ style: tableCellParagraphBlockStyle(
43159
+ cellContent,
43160
+ editor.model.metadata.numberingDefinitions,
43161
+ headingStyles,
43162
+ paragraphIndex,
43163
+ applyWordTableDefaults,
43164
+ nodeDocGridLinePitchPx
43165
+ ),
43166
+ children: renderInteractiveParagraphRuns(
43167
+ cellContent,
43168
+ `body-cell-${nodeIndex}-${rowIndex}-${cellIndex}-${contentIndex}`,
43169
+ {
43170
+ kind: "table-cell",
43171
+ tableIndex: nodeIndex,
43172
+ rowIndex,
43173
+ cellIndex,
43174
+ paragraphIndex
43175
+ }
43176
+ )
43177
+ },
43178
+ `body-cell-p-${nodeIndex}-${rowIndex}-${cellIndex}-${contentIndex}`
43179
+ );
43180
+ }
43181
+ return renderHeaderNode(
43182
+ cellContent,
43183
+ `body-cell-nested-table-${nodeIndex}-${rowIndex}-${cellIndex}-${contentIndex}`,
43184
+ documentContentTheme,
43185
+ editor.model.metadata.numberingDefinitions,
43186
+ headingStyles,
43187
+ spannedWidthPx > 0 ? spannedWidthPx : void 0,
43188
+ scrollToBookmark,
43189
+ void 0,
43190
+ void 0,
43191
+ void 0,
43192
+ void 0,
43193
+ paragraphRunRenderOptions,
43194
+ void 0,
43195
+ void 0,
43196
+ tableCellEditScope,
43197
+ void 0,
43198
+ embeddedTableResizeController
43199
+ );
43200
+ }
43201
+ );
43202
+ };
42461
43203
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
42462
43204
  "td",
42463
43205
  {
@@ -43343,68 +44085,27 @@ ${currentText.slice(end)}`;
43343
44085
  );
43344
44086
  })
43345
44087
  }
43346
- ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { display: "grid", gap: 4 }, children: (() => {
43347
- let paragraphCursor = 0;
43348
- return cell.nodes.map(
43349
- (cellContent, contentIndex) => {
43350
- if (cellContent.type === "paragraph") {
43351
- const paragraphIndex = paragraphCursor;
43352
- paragraphCursor += 1;
43353
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
43354
- "div",
43355
- {
43356
- "data-docx-paragraph-host": "true",
43357
- "data-docx-paragraph-kind": "table-cell",
43358
- "data-docx-table-index": nodeIndex,
43359
- "data-docx-row-index": rowIndex,
43360
- "data-docx-cell-index": cellIndex,
43361
- "data-docx-paragraph-index": paragraphIndex,
43362
- "data-docx-table-paragraph-index": paragraphIndex,
43363
- style: tableCellParagraphBlockStyle(
43364
- cellContent,
43365
- editor.model.metadata.numberingDefinitions,
43366
- headingStyles,
43367
- paragraphIndex,
43368
- applyWordTableDefaults,
43369
- nodeDocGridLinePitchPx
43370
- ),
43371
- children: renderInteractiveParagraphRuns(
43372
- cellContent,
43373
- `body-cell-${nodeIndex}-${rowIndex}-${cellIndex}-${contentIndex}`,
43374
- {
43375
- kind: "table-cell",
43376
- tableIndex: nodeIndex,
43377
- rowIndex,
43378
- cellIndex,
43379
- paragraphIndex
43380
- }
43381
- )
43382
- },
43383
- `body-cell-p-${nodeIndex}-${rowIndex}-${cellIndex}-${contentIndex}`
43384
- );
44088
+ ) : isSlicedRow && slicedCellViewportHeightPx ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
44089
+ "div",
44090
+ {
44091
+ style: {
44092
+ height: slicedCellViewportHeightPx,
44093
+ overflow: "hidden",
44094
+ position: "relative"
44095
+ },
44096
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
44097
+ "div",
44098
+ {
44099
+ style: {
44100
+ display: "grid",
44101
+ gap: 0,
44102
+ transform: `translateY(-${tableRowSliceOffsetPx}px)`
44103
+ },
44104
+ children: renderStaticCellContent()
43385
44105
  }
43386
- return renderHeaderNode(
43387
- cellContent,
43388
- `body-cell-nested-table-${nodeIndex}-${rowIndex}-${cellIndex}-${contentIndex}`,
43389
- documentContentTheme,
43390
- editor.model.metadata.numberingDefinitions,
43391
- headingStyles,
43392
- spannedWidthPx > 0 ? spannedWidthPx : void 0,
43393
- scrollToBookmark,
43394
- void 0,
43395
- void 0,
43396
- void 0,
43397
- void 0,
43398
- paragraphRunRenderOptions,
43399
- void 0,
43400
- void 0,
43401
- tableCellEditScope,
43402
- void 0,
43403
- embeddedTableResizeController
43404
- );
43405
- }
43406
- );
43407
- })() })
44106
+ )
44107
+ }
44108
+ ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { display: "grid", gap: 0 }, children: renderStaticCellContent() })
43408
44109
  },
43409
44110
  `cell-${nodeIndex}-${rowIndex}-${cellIndex}`
43410
44111
  );
@@ -44463,8 +45164,11 @@ ${currentText.slice(end)}`;
44463
45164
  () => new Map(endnotes.map((note) => [note.id, note])),
44464
45165
  [endnotes]
44465
45166
  );
44466
- const pageFootnotesByIndex = React.useMemo(
44467
- () => pageNodeSegmentsByPage.map((nodeSegments) => {
45167
+ const pageFootnotesByIndex = React.useMemo(() => {
45168
+ if (footnotes.length === 0) {
45169
+ return pageNodeSegmentsByPage.map(() => []);
45170
+ }
45171
+ return pageNodeSegmentsByPage.map((nodeSegments) => {
44468
45172
  const referencedIds = [];
44469
45173
  const seen = /* @__PURE__ */ new Set();
44470
45174
  nodeSegments.forEach((segment) => {
@@ -44486,10 +45190,17 @@ ${currentText.slice(end)}`;
44486
45190
  });
44487
45191
  });
44488
45192
  return referencedIds.map((referenceId) => footnotesById.get(referenceId)).filter((note) => Boolean(note));
44489
- }),
44490
- [editor.model.nodes, footnotesById, pageNodeSegmentsByPage]
44491
- );
45193
+ });
45194
+ }, [
45195
+ editor.model.nodes,
45196
+ footnotes.length,
45197
+ footnotesById,
45198
+ pageNodeSegmentsByPage
45199
+ ]);
44492
45200
  const referencedEndnotes = React.useMemo(() => {
45201
+ if (endnotes.length === 0) {
45202
+ return endnotes;
45203
+ }
44493
45204
  const referencedIds = [];
44494
45205
  const seen = /* @__PURE__ */ new Set();
44495
45206
  editor.model.nodes.forEach((node) => {
@@ -44696,6 +45407,35 @@ ${currentText.slice(end)}`;
44696
45407
  children: "Drop .docx anywhere to replace current document"
44697
45408
  }
44698
45409
  ) : null,
45410
+ editor.importError ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
45411
+ "div",
45412
+ {
45413
+ role: "alert",
45414
+ "data-docx-import-error": "true",
45415
+ style: {
45416
+ position: "absolute",
45417
+ top: 24,
45418
+ left: "50%",
45419
+ transform: "translateX(-50%)",
45420
+ zIndex: 80,
45421
+ width: "min(520px, calc(100% - 32px))",
45422
+ display: "grid",
45423
+ gap: 6,
45424
+ padding: "12px 14px",
45425
+ borderRadius: 8,
45426
+ border: `1px solid ${editor.documentTheme === "dark" ? "rgba(248, 113, 113, 0.42)" : "rgba(185, 28, 28, 0.26)"}`,
45427
+ backgroundColor: editor.documentTheme === "dark" ? "rgba(69, 10, 10, 0.96)" : "rgba(254, 242, 242, 0.98)",
45428
+ color: editor.documentTheme === "dark" ? "#fee2e2" : "#7f1d1d",
45429
+ boxShadow: editor.documentTheme === "dark" ? "0 12px 28px rgba(2, 6, 23, 0.44)" : "0 12px 28px rgba(127, 29, 29, 0.12)",
45430
+ fontSize: 13,
45431
+ lineHeight: 1.35
45432
+ },
45433
+ children: [
45434
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { style: { fontWeight: 600 }, children: "Failed to load DOCX" }),
45435
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { overflowWrap: "anywhere" }, children: editor.importError.message })
45436
+ ]
45437
+ }
45438
+ ) : null,
44699
45439
  tableMoveDropPreview && !isReadOnly ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
44700
45440
  "div",
44701
45441
  {
@@ -44719,6 +45459,7 @@ ${currentText.slice(end)}`;
44719
45459
  const pageVisible = isPageVisible(pageIndex);
44720
45460
  const pageWrapperWidthPx = showTrackedChangeGutter ? pageLayout.pageWidthPx + TRACKED_CHANGE_GUTTER_WIDTH_PX : pageLayout.pageWidthPx;
44721
45461
  if (!pageVisible) {
45462
+ const placeholderBackgroundColor = pageBackgroundColor ?? editor.model.metadata.documentBackgroundColor ?? pageSurfaceBaseStyle.backgroundColor;
44722
45463
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
44723
45464
  "div",
44724
45465
  {
@@ -44736,8 +45477,12 @@ ${currentText.slice(end)}`;
44736
45477
  "data-docx-page-placeholder": "true",
44737
45478
  ref: pagePlaceholderRefForIndex(pageIndex),
44738
45479
  style: {
45480
+ ...pageSurfaceBaseStyle,
44739
45481
  height: pageLayout.pageHeightPx,
44740
- width: pageLayout.pageWidthPx
45482
+ minHeight: pageLayout.pageHeightPx,
45483
+ width: pageLayout.pageWidthPx,
45484
+ backgroundColor: placeholderBackgroundColor,
45485
+ pointerEvents: "none"
44741
45486
  }
44742
45487
  }
44743
45488
  )
@@ -45195,6 +45940,14 @@ ${currentText.slice(end)}`;
45195
45940
  }
45196
45941
  );
45197
45942
  const explicitColumnWidthsPx = sectionColumns && sectionColumns.widthsPx?.length === sectionColumns.count ? sectionColumns.widthsPx : void 0;
45943
+ const flowSegmentsHaveExplicitColumnBreak = flowSegments.some((segment) => {
45944
+ if (segment.tableRowRange) {
45945
+ return false;
45946
+ }
45947
+ const segmentNode = editor.model.nodes[segment.nodeIndex];
45948
+ return segmentNode?.type === "paragraph" && paragraphHasExplicitColumnBreak(segmentNode);
45949
+ });
45950
+ const canUseColumnLineSplitRender = flowSegments.length > 0 && !flowSegmentsHaveExplicitColumnBreak;
45198
45951
  const renderSegmentInColumn = (columnSegment, columnContentWidthPx) => {
45199
45952
  const columnNode = editor.model.nodes[columnSegment.nodeIndex];
45200
45953
  if (!columnNode) {
@@ -45226,7 +45979,8 @@ ${currentText.slice(end)}`;
45226
45979
  suppressParagraphElementTracking: segmentIndex > 0,
45227
45980
  syntheticKeySuffix: `column-break-${segmentIndex}`,
45228
45981
  overrideBeforeSpacingPx: segmentIndex === 0 ? void 0 : 0,
45229
- overrideAfterSpacingPx: isLastSegment ? void 0 : 0
45982
+ overrideAfterSpacingPx: isLastSegment ? void 0 : 0,
45983
+ normalizeParagraphHostFontSize: true
45230
45984
  }
45231
45985
  )
45232
45986
  },
@@ -45247,7 +46001,8 @@ ${currentText.slice(end)}`;
45247
46001
  {
45248
46002
  pageLayout,
45249
46003
  contentWidthPxOverride: columnContentWidthPx,
45250
- suppressLikelyFullPageCoverImageKeys: suppressedLikelyFullPageCoverImageKeys
46004
+ suppressLikelyFullPageCoverImageKeys: suppressedLikelyFullPageCoverImageKeys,
46005
+ normalizeParagraphHostFontSize: true
45251
46006
  }
45252
46007
  );
45253
46008
  const segmentKeySuffix = columnSegment.tableRowRange ? `rows-${columnSegment.tableRowRange.startRowIndex}-${columnSegment.tableRowRange.endRowIndex}${columnSegment.tableRowSlice ? `-slice-${Math.max(
@@ -45286,7 +46041,91 @@ ${currentText.slice(end)}`;
45286
46041
  "div",
45287
46042
  {
45288
46043
  style: { position: "relative" },
45289
- children: explicitColumnWidthsPx && explicitColumnWidthsPx.length === 2 && flowSegments.length > 0 ? (() => {
46044
+ children: canUseColumnLineSplitRender ? (() => {
46045
+ const columnWidthsPx = explicitColumnWidthsPx && explicitColumnWidthsPx.length === sectionColumns.count ? explicitColumnWidthsPx : (() => {
46046
+ const inferredColumnWidthPx = Math.max(
46047
+ 120,
46048
+ Math.round(
46049
+ (pageContentWidthPx - sectionColumns.gapPx * Math.max(
46050
+ 0,
46051
+ sectionColumns.count - 1
46052
+ )) / Math.max(1, sectionColumns.count)
46053
+ )
46054
+ );
46055
+ return Array.from(
46056
+ { length: sectionColumns.count },
46057
+ () => inferredColumnWidthPx
46058
+ );
46059
+ })();
46060
+ const columnSegments = buildRenderColumnSegmentsForPageSection(
46061
+ editor.model,
46062
+ flowSegments,
46063
+ columnWidthsPx,
46064
+ pageBodyAvailableHeightPx,
46065
+ editor.model.metadata.numberingDefinitions,
46066
+ docGridLinePitchPxByNodeIndex,
46067
+ measuredParagraphOuterHeightsPxByNodeIndex,
46068
+ isLastPage
46069
+ );
46070
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
46071
+ overlaySegments.map((overlaySegment) => {
46072
+ const overlayNode = editor.model.nodes[overlaySegment.nodeIndex];
46073
+ if (!overlayNode) {
46074
+ return null;
46075
+ }
46076
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
46077
+ React.Fragment,
46078
+ {
46079
+ children: renderDocumentNode(
46080
+ overlayNode,
46081
+ overlaySegment.nodeIndex,
46082
+ overlaySegment.tableRowRange,
46083
+ overlaySegment.tableRowSlice,
46084
+ overlaySegment.paragraphLineRange,
46085
+ {
46086
+ pageLayout,
46087
+ suppressLikelyFullPageCoverImageKeys: suppressedLikelyFullPageCoverImageKeys
46088
+ }
46089
+ )
46090
+ },
46091
+ `column-layout-overlay-${pageIndex}-${overlaySegment.nodeIndex}-${segmentIdentityKey(
46092
+ overlaySegment
46093
+ )}`
46094
+ );
46095
+ }),
46096
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
46097
+ "div",
46098
+ {
46099
+ style: {
46100
+ display: "grid",
46101
+ gridTemplateColumns: columnWidthsPx.map((widthPx) => `${widthPx}px`).join(" "),
46102
+ columnGap: sectionColumns.gapPx,
46103
+ alignItems: "start",
46104
+ minHeight: pageBodyAvailableHeightPx,
46105
+ position: "relative",
46106
+ zIndex: 1
46107
+ },
46108
+ children: columnSegments.map(
46109
+ (segmentsForColumn, columnIndex) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
46110
+ "div",
46111
+ {
46112
+ style: {
46113
+ minHeight: pageBodyAvailableHeightPx
46114
+ },
46115
+ children: segmentsForColumn.map(
46116
+ (segment) => renderSegmentInColumn(
46117
+ segment,
46118
+ columnWidthsPx[columnIndex]
46119
+ )
46120
+ )
46121
+ },
46122
+ `column-layout-flow-${pageIndex}-${groupIndex}-${columnIndex}`
46123
+ )
46124
+ )
46125
+ }
46126
+ )
46127
+ ] });
46128
+ })() : explicitColumnWidthsPx && explicitColumnWidthsPx.length === 2 && flowSegments.length > 0 ? (() => {
45290
46129
  const [leftColumnWidthPx, rightColumnWidthPx] = explicitColumnWidthsPx;
45291
46130
  const prefixHeightsPx = new Array(
45292
46131
  flowSegments.length + 1
@@ -47600,6 +48439,7 @@ function buildDocumentPageNodeSegments2(model, pageContentHeightPx, pageContentW
47600
48439
  );
47601
48440
  }
47602
48441
  let rowStartIndex = 0;
48442
+ let tableBreakStartRowCursor = 0;
47603
48443
  while (rowStartIndex < estimatedRowHeightsPx.length) {
47604
48444
  const remainingHeightPx = Math.max(0, currentPageContentHeightPx - pageConsumedHeightPx);
47605
48445
  const fittedRowEndIndex = fitTableRowsWithinHeightPx2(
@@ -47611,9 +48451,10 @@ function buildDocumentPageNodeSegments2(model, pageContentHeightPx, pageContentW
47611
48451
  pageOverflowTolerancePx
47612
48452
  );
47613
48453
  let rowEndIndex = fittedRowEndIndex;
47614
- const forcedBreakRowIndex = tableBreakStartRows.find(
47615
- (breakRowIndex) => breakRowIndex > rowStartIndex
47616
- );
48454
+ while (tableBreakStartRowCursor < tableBreakStartRows.length && tableBreakStartRows[tableBreakStartRowCursor] <= rowStartIndex) {
48455
+ tableBreakStartRowCursor += 1;
48456
+ }
48457
+ const forcedBreakRowIndex = tableBreakStartRows[tableBreakStartRowCursor];
47617
48458
  if (forcedBreakRowIndex !== void 0) {
47618
48459
  rowEndIndex = Math.min(rowEndIndex, forcedBreakRowIndex);
47619
48460
  }