@extend-ai/react-docx 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -6498,7 +6498,6 @@ function resolveDocumentLayout(model) {
6498
6498
  }
6499
6499
 
6500
6500
  // src/image-render.ts
6501
- import { convertEmfToDataUrl, convertWmfToDataUrl } from "emf-converter";
6502
6501
  import { encode as encodePng } from "fast-png";
6503
6502
  import UTIFModule from "utif";
6504
6503
  var TIFF_CONTENT_TYPES = /* @__PURE__ */ new Set(["image/tiff", "image/tif"]);
@@ -6513,9 +6512,6 @@ var EMF_DATA_URI_PREFIXES = ["data:image/emf", "data:image/x-emf"];
6513
6512
  var WMF_DATA_URI_PREFIXES = ["data:image/wmf", "data:image/x-wmf"];
6514
6513
  var UTIF = UTIFModule;
6515
6514
  var convertedTiffSrcCache = /* @__PURE__ */ new Map();
6516
- var convertedMetafileSrcCache = /* @__PURE__ */ new Map();
6517
- var pendingMetafileConversions = /* @__PURE__ */ new Map();
6518
- var renderableImageSourceListeners = /* @__PURE__ */ new Set();
6519
6515
  function normalizeImageContentType(image) {
6520
6516
  return image.contentType?.trim().toLowerCase();
6521
6517
  }
@@ -6556,45 +6552,15 @@ function imageUsesWmfContent(image) {
6556
6552
  const src = normalizeImageSrc(image)?.toLowerCase();
6557
6553
  return Boolean(src && WMF_DATA_URI_PREFIXES.some((prefix) => src.startsWith(prefix)));
6558
6554
  }
6559
- function metafileCacheKey(image) {
6560
- const src = normalizeImageSrc(image);
6561
- if (src) {
6562
- return src;
6563
- }
6564
- const bytes = image.data;
6565
- if (!bytes?.byteLength) {
6566
- return void 0;
6567
- }
6568
- const base64 = bytesToBase642(bytes);
6569
- const contentType = normalizeImageContentType(image) ?? "application/octet-stream";
6570
- return base64 ? `data:${contentType};base64,${base64}` : void 0;
6571
- }
6572
- function notifyRenderableImageSourceListeners() {
6573
- renderableImageSourceListeners.forEach((listener) => {
6574
- try {
6575
- listener();
6576
- } catch {
6577
- }
6578
- });
6579
- }
6580
6555
  function imageUsesPlaceholderFallback(image) {
6581
- const contentType = normalizeImageContentType(image);
6582
- if (!contentType || !PLACEHOLDER_FALLBACK_CONTENT_TYPES.has(contentType)) {
6583
- return false;
6584
- }
6585
- const cacheKey = metafileCacheKey(image);
6586
- if (!cacheKey) {
6587
- return true;
6588
- }
6589
- return convertedMetafileSrcCache.get(cacheKey) == null;
6556
+ return imageHasMetafileContent(image);
6590
6557
  }
6591
6558
  function unsupportedImageFallbackLabel(image, widthPx, heightPx) {
6592
6559
  const isSmallIcon = (widthPx ?? 0) <= 56 && (heightPx ?? 0) <= 56;
6593
- const contentType = normalizeImageContentType(image);
6594
- if (contentType === "image/x-emf" || contentType === "image/emf") {
6560
+ if (imageUsesEmfContent(image)) {
6595
6561
  return isSmallIcon ? "e" : "EMF";
6596
6562
  }
6597
- if (contentType === "image/x-wmf" || contentType === "image/wmf") {
6563
+ if (imageUsesWmfContent(image)) {
6598
6564
  return isSmallIcon ? "w" : "WMF";
6599
6565
  }
6600
6566
  return isSmallIcon ? "e" : "TIFF";
@@ -6640,13 +6606,6 @@ function toArrayBuffer(bytes) {
6640
6606
  }
6641
6607
  return buffer.slice(byteOffset, byteOffset + byteLength);
6642
6608
  }
6643
- function toStrictArrayBuffer(bytes) {
6644
- const arrayBuffer = toArrayBuffer(bytes);
6645
- if (arrayBuffer instanceof ArrayBuffer) {
6646
- return arrayBuffer;
6647
- }
6648
- return Uint8Array.from(bytes).buffer;
6649
- }
6650
6609
  function resolveTiffBytes(image) {
6651
6610
  if (image.data?.byteLength) {
6652
6611
  return image.data;
@@ -6708,37 +6667,6 @@ function resolveRenderableImageSource(image) {
6708
6667
  return void 0;
6709
6668
  }
6710
6669
  if (imageHasMetafileContent(image)) {
6711
- const cacheKey = metafileCacheKey(image);
6712
- if (!cacheKey) {
6713
- return void 0;
6714
- }
6715
- if (convertedMetafileSrcCache.has(cacheKey)) {
6716
- return convertedMetafileSrcCache.get(cacheKey) ?? void 0;
6717
- }
6718
- if (!pendingMetafileConversions.has(cacheKey)) {
6719
- const bytes = resolveTiffBytes(image);
6720
- if (bytes) {
6721
- const conversionPromise = (async () => {
6722
- try {
6723
- const arrayBuffer = toStrictArrayBuffer(bytes);
6724
- const converted2 = imageUsesEmfContent(image) ? await convertEmfToDataUrl(arrayBuffer, void 0, void 0, { dpiScale: 1 }) : imageUsesWmfContent(image) ? await convertWmfToDataUrl(arrayBuffer, void 0, void 0, { dpiScale: 1 }) : null;
6725
- const normalized = converted2 ?? void 0;
6726
- convertedMetafileSrcCache.set(cacheKey, normalized ?? null);
6727
- notifyRenderableImageSourceListeners();
6728
- return normalized;
6729
- } catch {
6730
- convertedMetafileSrcCache.set(cacheKey, null);
6731
- notifyRenderableImageSourceListeners();
6732
- return void 0;
6733
- } finally {
6734
- pendingMetafileConversions.delete(cacheKey);
6735
- }
6736
- })();
6737
- pendingMetafileConversions.set(cacheKey, conversionPromise);
6738
- } else {
6739
- convertedMetafileSrcCache.set(cacheKey, null);
6740
- }
6741
- }
6742
6670
  return void 0;
6743
6671
  }
6744
6672
  if (!imageHasTiffContent(image)) {
@@ -6761,9 +6689,8 @@ function resolveRenderableImageSource(image) {
6761
6689
  return converted;
6762
6690
  }
6763
6691
  function subscribeRenderableImageSourceUpdates(listener) {
6764
- renderableImageSourceListeners.add(listener);
6692
+ void listener;
6765
6693
  return () => {
6766
- renderableImageSourceListeners.delete(listener);
6767
6694
  };
6768
6695
  }
6769
6696
 
@@ -10198,6 +10125,9 @@ var LEADING_COVER_SPACER_EXTRA_HEIGHT_PX = 2;
10198
10125
  var PARAGRAPH_SEGMENT_TOP_BLEED_PX = 22;
10199
10126
  var PARAGRAPH_SEGMENT_DESCENDER_BLEED_PX = 6;
10200
10127
  var PARAGRAPH_SEGMENT_VISUAL_SAFETY_PX = 24;
10128
+ var PARAGRAPH_SEGMENT_FALLBACK_TOP_BLEED_MAX_PX = 4;
10129
+ var PARAGRAPH_SEGMENT_FALLBACK_BOTTOM_BLEED_MAX_PX = 0;
10130
+ var PARAGRAPH_SEGMENT_FALLBACK_VISUAL_SAFETY_PX = 4;
10201
10131
  var INITIAL_PAGINATION_PREMEASURE_PAGE_LIMIT = 8;
10202
10132
  var INITIAL_PAGINATION_PAGE_COUNT_OSCILLATION_DISTINCT_THRESHOLD = 2;
10203
10133
  var INITIAL_PAGINATION_PAGE_COUNT_OSCILLATION_CHANGE_THRESHOLD = 4;
@@ -10534,13 +10464,18 @@ var DOC_SURFACE_STYLE_BY_THEME = {
10534
10464
  boxShadow: "0 2px 10px rgba(15, 23, 42, 0.08), 0 1px 2px rgba(15, 23, 42, 0.05)"
10535
10465
  },
10536
10466
  dark: {
10537
- backgroundColor: "#111827",
10467
+ backgroundColor: "#0a0a0a",
10538
10468
  color: "#f3f4f6",
10539
10469
  colorScheme: "dark",
10540
10470
  border: "none",
10541
10471
  boxShadow: "0 2px 10px rgba(2, 6, 23, 0.55), 0 1px 2px rgba(2, 6, 23, 0.45)"
10542
10472
  }
10543
10473
  };
10474
+ var NIGHT_READER_INVERSION_FILTER = "invert(0.95) hue-rotate(180deg) saturate(0.9) brightness(0.9) contrast(0.94)";
10475
+ function appendCssFilters(...filters) {
10476
+ const resolvedFilters = filters.map((filter) => filter?.trim()).filter((filter) => Boolean(filter));
10477
+ return resolvedFilters.length > 0 ? resolvedFilters.join(" ") : void 0;
10478
+ }
10544
10479
  var TABLE_RESIZE_HANDLE_SIZE = 8;
10545
10480
  var TABLE_RESIZE_HANDLE_HIT_SIZE = 16;
10546
10481
  var TABLE_RESIZE_BORDER_SIZE = 1;
@@ -11471,7 +11406,7 @@ function resolveFooterPaginationReservePx(footerSections, layout) {
11471
11406
  floatingFooterBoundaryReservePx
11472
11407
  );
11473
11408
  }
11474
- function resolveMeasuredPageContentHeightPx(params) {
11409
+ function resolveMeasuredPageContentHeightDiagnostics(params) {
11475
11410
  const {
11476
11411
  pageLayout,
11477
11412
  fallbackHeightPx,
@@ -11511,34 +11446,41 @@ function resolveMeasuredPageContentHeightPx(params) {
11511
11446
  ) : 0;
11512
11447
  const correctedAllowedBodyBottomPx = Math.max(
11513
11448
  0,
11514
- guardedAllowedBodyBottomPx - renderedBodyOverrunPx - measuredFooterClearanceBufferPx
11449
+ guardedAllowedBodyBottomPx - measuredFooterClearanceBufferPx
11515
11450
  );
11516
- const iterativeMeasuredHeightPx = renderedBodyOverrunPx > 0 && Number.isFinite(effectiveCurrentMeasuredHeightPx) && effectiveCurrentMeasuredHeightPx > 0 ? Math.max(
11451
+ const iterativeMeasuredHeightPx = renderedBodyOverrunPx > 0 && !Number.isFinite(bodyTopPx) && Number.isFinite(effectiveCurrentMeasuredHeightPx) && effectiveCurrentMeasuredHeightPx > 0 ? Math.max(
11517
11452
  120,
11518
11453
  Math.round(
11519
11454
  effectiveCurrentMeasuredHeightPx - renderedBodyOverrunPx - measuredFooterClearanceBufferPx
11520
11455
  )
11521
11456
  ) : void 0;
11457
+ const bodyOverrunsFooter = renderedBodyOverrunPx > 0;
11522
11458
  if (Number.isFinite(bodyTopPx) && correctedAllowedBodyBottomPx > bodyTopPx) {
11523
11459
  const measuredHeaderClearanceBufferPx2 = headerHeightPx > 0 ? MEASURED_PAGE_HEADER_CLEARANCE_BUFFER_PX : 0;
11524
11460
  const correctedHeightPx = Math.max(
11525
11461
  120,
11526
11462
  Math.round(correctedAllowedBodyBottomPx - bodyTopPx)
11527
11463
  );
11528
- return Number.isFinite(iterativeMeasuredHeightPx) ? Math.min(
11529
- Math.max(120, correctedHeightPx - measuredHeaderClearanceBufferPx2),
11530
- Math.max(
11531
- 120,
11532
- iterativeMeasuredHeightPx - measuredHeaderClearanceBufferPx2
11533
- )
11534
- ) : Math.max(120, correctedHeightPx - measuredHeaderClearanceBufferPx2);
11464
+ return {
11465
+ heightPx: Number.isFinite(iterativeMeasuredHeightPx) ? Math.min(
11466
+ Math.max(120, correctedHeightPx - measuredHeaderClearanceBufferPx2),
11467
+ Math.max(
11468
+ 120,
11469
+ iterativeMeasuredHeightPx - measuredHeaderClearanceBufferPx2
11470
+ )
11471
+ ) : Math.max(120, correctedHeightPx - measuredHeaderClearanceBufferPx2),
11472
+ bodyOverrunsFooter
11473
+ };
11535
11474
  }
11536
11475
  const measuredHeaderClearanceBufferPx = headerHeightPx > 0 ? MEASURED_PAGE_HEADER_CLEARANCE_BUFFER_PX : 0;
11537
11476
  const correctedFallbackHeightPx = Math.max(
11538
11477
  120,
11539
11478
  fallbackHeightPx - headerHeightPx - measuredHeaderClearanceBufferPx - footerOverlapPx - renderedBodyOverrunPx - measuredFooterClearanceBufferPx
11540
11479
  );
11541
- return Number.isFinite(iterativeMeasuredHeightPx) ? Math.min(correctedFallbackHeightPx, iterativeMeasuredHeightPx) : correctedFallbackHeightPx;
11480
+ return {
11481
+ heightPx: Number.isFinite(iterativeMeasuredHeightPx) ? Math.min(correctedFallbackHeightPx, iterativeMeasuredHeightPx) : correctedFallbackHeightPx,
11482
+ bodyOverrunsFooter
11483
+ };
11542
11484
  }
11543
11485
  function resolveMeasuredBodyRenderedBottomPx(descendants) {
11544
11486
  let visualBottomPx;
@@ -11556,13 +11498,27 @@ function resolveMeasuredBodyRenderedBottomPx(descendants) {
11556
11498
  });
11557
11499
  return visualBottomPx;
11558
11500
  }
11559
- function stabilizeMeasuredPageContentHeights(current, next) {
11501
+ function stabilizeMeasuredPageContentHeights(current, next, options) {
11560
11502
  return next.map((heightPx, pageIndex) => {
11561
11503
  const roundedNextHeightPx = Math.round(heightPx);
11562
11504
  const currentHeightPx = current[pageIndex];
11563
- return Number.isFinite(currentHeightPx) ? Math.min(Math.round(currentHeightPx), roundedNextHeightPx) : roundedNextHeightPx;
11505
+ const currentPageIdentityKey = options?.currentPageIdentityKeys?.[pageIndex];
11506
+ const nextPageIdentityKey = options?.nextPageIdentityKeys?.[pageIndex];
11507
+ const canPreserveConservativeHeight = currentPageIdentityKey === void 0 || nextPageIdentityKey === void 0 || currentPageIdentityKey === nextPageIdentityKey;
11508
+ return Number.isFinite(currentHeightPx) ? canPreserveConservativeHeight ? Math.min(Math.round(currentHeightPx), roundedNextHeightPx) : roundedNextHeightPx : roundedNextHeightPx;
11564
11509
  });
11565
11510
  }
11511
+ function documentPageNodeSegmentIdentityKey(segment) {
11512
+ const tableRowRangeKey = segment.tableRowRange ? `${segment.tableRowRange.startRowIndex}-${segment.tableRowRange.endRowIndex}` : "none";
11513
+ const tableRowSliceKey = segment.tableRowSlice ? `${segment.tableRowSlice.rowIndex}-${Math.round(
11514
+ segment.tableRowSlice.startOffsetPx
11515
+ )}-${Math.round(segment.tableRowSlice.sliceHeightPx)}` : "none";
11516
+ const paragraphLineRangeKey = segment.paragraphLineRange ? `${segment.paragraphLineRange.startLineIndex}-${segment.paragraphLineRange.endLineIndex}-${segment.paragraphLineRange.totalLineCount}` : "none";
11517
+ return `${segment.nodeIndex}|${tableRowRangeKey}|${tableRowSliceKey}|${paragraphLineRangeKey}`;
11518
+ }
11519
+ function documentPageNodeSegmentsIdentityKey(pageSegments) {
11520
+ return pageSegments.map(documentPageNodeSegmentIdentityKey).join("::");
11521
+ }
11566
11522
  function buildPaginationSectionMetrics(sections, fallbackLayout) {
11567
11523
  const fallbackWidthPx = resolveSectionPaginationContentWidthPx(fallbackLayout);
11568
11524
  const fallbackHeightPx = Math.max(
@@ -11645,10 +11601,11 @@ function scaleMeasuredPageContentHeights(measuredPageContentHeightsPxByPageIndex
11645
11601
  (heightPx) => Math.max(120, Math.round(heightPx * heightScale))
11646
11602
  );
11647
11603
  }
11648
- function resolvePageContentHeightPxForPageSegments(pageSegments, pageIndex, defaultPageContentHeightPx, metricsBySection, measuredPageContentHeightsPxByPageIndex) {
11604
+ function resolvePageContentHeightPxForPageSegments(pageSegments, pageIndex, defaultPageContentHeightPx, metricsBySection, measuredPageContentHeightsPxByPageIndex, measuredPageContentIdentityKeysByPageIndex, pageIdentityKey) {
11649
11605
  const pageContainsOnlySplitParagraphSegments = documentPageContainsOnlySplitParagraphSegments(pageSegments);
11650
11606
  const measuredHeightPx = measuredPageContentHeightsPxByPageIndex?.[pageIndex];
11651
- if (Number.isFinite(measuredHeightPx) && !pageContainsOnlySplitParagraphSegments) {
11607
+ const measuredHeightMatchesCurrentPage = pageIdentityKey === void 0 || measuredPageContentIdentityKeysByPageIndex?.[pageIndex] === void 0 || measuredPageContentIdentityKeysByPageIndex?.[pageIndex] === pageIdentityKey;
11608
+ if (Number.isFinite(measuredHeightPx) && measuredHeightMatchesCurrentPage && !pageContainsOnlySplitParagraphSegments) {
11652
11609
  return Math.max(120, Math.round(measuredHeightPx));
11653
11610
  }
11654
11611
  const firstNodeIndex = pageSegments[0]?.nodeIndex ?? 0;
@@ -11664,6 +11621,17 @@ function resolvePageContentHeightPxForPageSegments(pageSegments, pageIndex, defa
11664
11621
  )
11665
11622
  );
11666
11623
  }
11624
+ function resolveRenderPageContentHeightPxForPageSegments(params) {
11625
+ return resolvePageContentHeightPxForPageSegments(
11626
+ params.pageSegments,
11627
+ params.pageIndex,
11628
+ params.defaultPageContentHeightPx,
11629
+ params.metricsBySection,
11630
+ params.useMeasuredPageContentHeights === false ? void 0 : params.measuredPageContentHeightsPxByPageIndex,
11631
+ params.useMeasuredPageContentHeights === false ? void 0 : params.measuredPageContentIdentityKeysByPageIndex,
11632
+ params.pageIdentityKey
11633
+ );
11634
+ }
11667
11635
  function documentPageContainsOnlySplitParagraphSegments(pageSegments) {
11668
11636
  return pageSegments.length > 0 && pageSegments.every(
11669
11637
  (segment) => !segment.tableRowRange && paragraphSegmentHasPartialLineRange(segment.paragraphLineRange)
@@ -12543,10 +12511,11 @@ function sectionNodesNeedPageWideLayout(nodes, pageWidthPx, contentWidthPx) {
12543
12511
  return false;
12544
12512
  }
12545
12513
  const horizontalRelativeTo = image.floating.horizontalRelativeTo?.toLowerCase();
12546
- if (image.floating.behindDocument || horizontalRelativeTo === "page") {
12514
+ const usesPageWidthAnchorOrigin = horizontalRelativeTo === "page" || horizontalRelativeTo === "margin";
12515
+ if (image.floating.behindDocument && usesPageWidthAnchorOrigin) {
12547
12516
  return true;
12548
12517
  }
12549
- if (shouldRenderAbsoluteFloatingImage(image)) {
12518
+ if (usesPageWidthAnchorOrigin && (shouldRenderAbsoluteFloatingImage(image) || shouldRenderWrappedFloatingImage(image))) {
12550
12519
  return true;
12551
12520
  }
12552
12521
  if (Number.isFinite(image.widthPx) && Number.isFinite(image.floating.xPx) && image.widthPx >= safeContentWidthPx - 12 && image.floating.xPx <= 12) {
@@ -13133,6 +13102,9 @@ function buildSyntheticPretextLayoutSource(text, style) {
13133
13102
  function pretextWordBreakModeForText(text) {
13134
13103
  return KEEP_ALL_SCRIPT_RE.test(text) ? "keep-all" : "normal";
13135
13104
  }
13105
+ function sanitizeRenderedPretextFragmentText(text) {
13106
+ return text.replace(/\r\n?|\n/g, "");
13107
+ }
13136
13108
  function buildParagraphPretextLayoutItems(paragraph, source) {
13137
13109
  const paragraphBaseFontPx = paragraphBaseFontSizePx(paragraph);
13138
13110
  const wordBreak = pretextWordBreakModeForText(source.text);
@@ -14245,6 +14217,20 @@ function paragraphBaseFontSizePx(paragraph) {
14245
14217
  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;
14246
14218
  return Math.max(10, Math.round(fontSizePt * 96 / 72));
14247
14219
  }
14220
+ function paragraphMaxFontSizePx(paragraph) {
14221
+ const paragraphBaseFontPx = paragraphBaseFontSizePx(paragraph);
14222
+ let maxFontSizePx = paragraphBaseFontPx;
14223
+ paragraph.children.forEach((child) => {
14224
+ if (child.type !== "text" && child.type !== "form-field") {
14225
+ return;
14226
+ }
14227
+ maxFontSizePx = Math.max(
14228
+ maxFontSizePx,
14229
+ resolveMeasureFontSizePx(child.style, paragraphBaseFontPx)
14230
+ );
14231
+ });
14232
+ return Math.max(1, Math.round(maxFontSizePx));
14233
+ }
14248
14234
  function normalizeFontFamilyToken(fontFamily) {
14249
14235
  if (!fontFamily) {
14250
14236
  return void 0;
@@ -15442,6 +15428,34 @@ function resolveParagraphSegmentClipBleedPx(paragraphLineRange) {
15442
15428
  bottomPx: Math.max(0, PARAGRAPH_SEGMENT_DESCENDER_BLEED_PX)
15443
15429
  };
15444
15430
  }
15431
+ function resolveFallbackParagraphSegmentClipBleedPx(paragraph, paragraphLineRange) {
15432
+ if (!paragraphSegmentHasPartialLineRange(paragraphLineRange)) {
15433
+ return {
15434
+ topPx: 0,
15435
+ bottomPx: 0
15436
+ };
15437
+ }
15438
+ const lineHeightPx = Math.max(1, paragraphLineRange?.lineHeightPx ?? 0);
15439
+ const maxFontSizePx = paragraphMaxFontSizePx(paragraph);
15440
+ const glyphOvershootPx = Math.max(
15441
+ 0,
15442
+ Math.ceil((maxFontSizePx - lineHeightPx) / 2)
15443
+ );
15444
+ const ascenderSafetyPx = Math.max(
15445
+ glyphOvershootPx,
15446
+ Math.ceil(lineHeightPx * 0.22)
15447
+ );
15448
+ return {
15449
+ topPx: paragraphLineRange && paragraphLineRange.startLineIndex > 0 ? Math.min(
15450
+ PARAGRAPH_SEGMENT_FALLBACK_TOP_BLEED_MAX_PX,
15451
+ ascenderSafetyPx
15452
+ ) : 0,
15453
+ bottomPx: paragraphLineRange && paragraphLineRange.endLineIndex < paragraphLineRange.totalLineCount ? Math.min(
15454
+ PARAGRAPH_SEGMENT_FALLBACK_BOTTOM_BLEED_MAX_PX,
15455
+ glyphOvershootPx
15456
+ ) : 0
15457
+ };
15458
+ }
15445
15459
  function resolveParagraphSegmentNonFlowReservePx(paragraphLineRange) {
15446
15460
  const bleed = resolveParagraphSegmentClipBleedPx(paragraphLineRange);
15447
15461
  if (bleed.topPx <= 0 && bleed.bottomPx <= 0) {
@@ -15453,6 +15467,20 @@ function resolveParagraphSegmentNonFlowReservePx(paragraphLineRange) {
15453
15467
  );
15454
15468
  return Math.max(0, bleed.topPx) + Math.max(0, bleed.bottomPx) + Math.max(0, PARAGRAPH_SEGMENT_VISUAL_SAFETY_PX, lineHeightSafetyPx);
15455
15469
  }
15470
+ function resolveFallbackParagraphSegmentNonFlowReservePx(paragraph, paragraphLineRange) {
15471
+ const bleed = resolveFallbackParagraphSegmentClipBleedPx(
15472
+ paragraph,
15473
+ paragraphLineRange
15474
+ );
15475
+ if (bleed.topPx <= 0 && bleed.bottomPx <= 0) {
15476
+ return 0;
15477
+ }
15478
+ const lineHeightSafetyPx = Math.max(
15479
+ 0,
15480
+ Math.ceil((paragraphLineRange?.lineHeightPx ?? 0) * 0.15)
15481
+ );
15482
+ return Math.max(0, bleed.topPx) + Math.max(0, bleed.bottomPx) + Math.max(1, PARAGRAPH_SEGMENT_FALLBACK_VISUAL_SAFETY_PX, lineHeightSafetyPx);
15483
+ }
15456
15484
  function paragraphSegmentIdentityMatches(segment, nodeIndex, paragraphLineRange) {
15457
15485
  if (!segment || !paragraphLineRange) {
15458
15486
  return false;
@@ -15792,13 +15820,17 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
15792
15820
  node,
15793
15821
  nodeMetrics.docGridLinePitchPx
15794
15822
  );
15823
+ const paragraphPretextSourceForSegmentRendering = buildParagraphPretextLayoutSource(node, {
15824
+ allowExplicitLineBreakText: true
15825
+ });
15826
+ const paragraphSupportsPretextSegmentRendering = Boolean(
15827
+ paragraphPretextSourceForSegmentRendering
15828
+ );
15795
15829
  const paragraphPretextLineCount = (() => {
15796
15830
  if (!paragraphContainsExplicitLineBreakText(node)) {
15797
15831
  return void 0;
15798
15832
  }
15799
- const pretextSource = buildParagraphPretextLayoutSource(node, {
15800
- allowExplicitLineBreakText: true
15801
- });
15833
+ const pretextSource = paragraphPretextSourceForSegmentRendering;
15802
15834
  if (!pretextSource) {
15803
15835
  return void 0;
15804
15836
  }
@@ -15816,11 +15848,7 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
15816
15848
  );
15817
15849
  return pretextLayout?.lineCount;
15818
15850
  })();
15819
- const supportsImageParagraphLineSplit = paragraphHasImage2(node) && Boolean(
15820
- buildParagraphPretextLayoutSource(node, {
15821
- allowExplicitLineBreakText: true
15822
- })
15823
- );
15851
+ const supportsImageParagraphLineSplit = paragraphHasImage2(node) && paragraphSupportsPretextSegmentRendering;
15824
15852
  const paragraphLineCount = paragraphLineCountWithinWidth(
15825
15853
  node,
15826
15854
  nodeMetrics.pageContentWidthPx,
@@ -15835,6 +15863,18 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
15835
15863
  allowImageParagraphSplit: supportsImageParagraphLineSplit
15836
15864
  }) && (!widowControlEnabled || resolvedParagraphLineCount > 3);
15837
15865
  if (canSplitParagraphAcrossPages && allowParagraphLineSplitting) {
15866
+ const resolveSegmentReservePx = (startLineIndex, endLineIndex) => {
15867
+ const paragraphSegmentRange = {
15868
+ startLineIndex,
15869
+ endLineIndex,
15870
+ totalLineCount: resolvedParagraphLineCount,
15871
+ lineHeightPx: paragraphLineHeightPx
15872
+ };
15873
+ return paragraphSupportsPretextSegmentRendering ? resolveParagraphSegmentNonFlowReservePx(paragraphSegmentRange) : resolveFallbackParagraphSegmentNonFlowReservePx(
15874
+ node,
15875
+ paragraphSegmentRange
15876
+ );
15877
+ };
15838
15878
  let lineCursor = 0;
15839
15879
  let isFirstSegment = true;
15840
15880
  while (lineCursor < resolvedParagraphLineCount) {
@@ -15846,12 +15886,10 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
15846
15886
  0,
15847
15887
  currentPageContentHeightPx - pageConsumedHeightPx
15848
15888
  );
15849
- const allRemainingSegmentReservePx = resolveParagraphSegmentNonFlowReservePx({
15850
- startLineIndex: lineCursor,
15851
- endLineIndex: resolvedParagraphLineCount,
15852
- totalLineCount: resolvedParagraphLineCount,
15853
- lineHeightPx: paragraphLineHeightPx
15854
- });
15889
+ const allRemainingSegmentReservePx = resolveSegmentReservePx(
15890
+ lineCursor,
15891
+ resolvedParagraphLineCount
15892
+ );
15855
15893
  const allRemainingHeightPx = topSpacingPx + linesRemaining * paragraphLineHeightPx + bottomSpacingPx;
15856
15894
  if (allRemainingHeightPx + allRemainingSegmentReservePx <= remainingHeightPx2) {
15857
15895
  currentPageSegments.push({
@@ -15872,15 +15910,10 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
15872
15910
  0,
15873
15911
  linesRemaining - minLinesPerSegment
15874
15912
  );
15875
- const continuingSegmentReservePx = resolveParagraphSegmentNonFlowReservePx({
15876
- startLineIndex: lineCursor,
15877
- endLineIndex: Math.min(
15878
- resolvedParagraphLineCount,
15879
- lineCursor + maxLinesThisPage
15880
- ),
15881
- totalLineCount: resolvedParagraphLineCount,
15882
- lineHeightPx: paragraphLineHeightPx
15883
- });
15913
+ const continuingSegmentReservePx = resolveSegmentReservePx(
15914
+ lineCursor,
15915
+ Math.min(resolvedParagraphLineCount, lineCursor + maxLinesThisPage)
15916
+ );
15884
15917
  const availableForLinesPx = Math.max(
15885
15918
  0,
15886
15919
  remainingHeightPx2 - topSpacingPx - continuingSegmentReservePx
@@ -15919,12 +15952,10 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
15919
15952
  lineCursor + linesThatFit
15920
15953
  );
15921
15954
  while (linesThatFit > minLinesPerSegment) {
15922
- const segmentReservePx = resolveParagraphSegmentNonFlowReservePx({
15923
- startLineIndex: lineCursor,
15924
- endLineIndex: segmentEndLineIndex,
15925
- totalLineCount: resolvedParagraphLineCount,
15926
- lineHeightPx: paragraphLineHeightPx
15927
- });
15955
+ const segmentReservePx = resolveSegmentReservePx(
15956
+ lineCursor,
15957
+ segmentEndLineIndex
15958
+ );
15928
15959
  if (topSpacingPx + (segmentEndLineIndex - lineCursor) * paragraphLineHeightPx + segmentReservePx <= remainingHeightPx2) {
15929
15960
  break;
15930
15961
  }
@@ -16425,17 +16456,18 @@ function wrappedFloatingImageStyle(image, options) {
16425
16456
  });
16426
16457
  const horizontalRelativeTo = floating.horizontalRelativeTo?.toLowerCase();
16427
16458
  const explicitHorizontalInsetPx = hasExplicitHorizontalOffset && !hasExplicitHorizontalAlign && (horizontalRelativeTo === "margin" || horizontalRelativeTo === "page" || horizontalRelativeTo === "column") ? side === "left" ? Math.max(0, leftOffsetPx) : Math.max(0, rightOffsetPx) : 0;
16459
+ const columnAnchoredExplicitInset = explicitHorizontalInsetPx > 0 && horizontalRelativeTo === "column";
16428
16460
  return {
16429
16461
  display: "block",
16430
16462
  ...intrinsicBlockWidthStyle,
16431
16463
  float: side,
16432
16464
  marginTop: topOffsetPx,
16433
16465
  marginBottom: distB,
16434
- marginLeft: side === "left" ? explicitHorizontalInsetPx > 0 ? 0 : hasExplicitHorizontalOffset ? leftOffsetPx : distL + leftOffsetPx : distL,
16435
- marginRight: side === "right" ? explicitHorizontalInsetPx > 0 ? 0 : hasExplicitHorizontalOffset ? rightOffsetPx : distR + rightOffsetPx : distR,
16436
- paddingLeft: side === "left" && explicitHorizontalInsetPx > 0 ? explicitHorizontalInsetPx : void 0,
16437
- paddingRight: side === "right" && explicitHorizontalInsetPx > 0 ? explicitHorizontalInsetPx : void 0,
16438
- boxSizing: explicitHorizontalInsetPx > 0 ? "content-box" : void 0
16466
+ marginLeft: side === "left" ? explicitHorizontalInsetPx > 0 ? columnAnchoredExplicitInset ? distL + explicitHorizontalInsetPx : 0 : hasExplicitHorizontalOffset ? leftOffsetPx : distL + leftOffsetPx : distL,
16467
+ marginRight: side === "right" ? explicitHorizontalInsetPx > 0 ? columnAnchoredExplicitInset ? distR + explicitHorizontalInsetPx : 0 : hasExplicitHorizontalOffset ? rightOffsetPx : distR + rightOffsetPx : distR,
16468
+ paddingLeft: side === "left" && explicitHorizontalInsetPx > 0 && !columnAnchoredExplicitInset ? explicitHorizontalInsetPx : void 0,
16469
+ paddingRight: side === "right" && explicitHorizontalInsetPx > 0 && !columnAnchoredExplicitInset ? explicitHorizontalInsetPx : void 0,
16470
+ boxSizing: explicitHorizontalInsetPx > 0 && !columnAnchoredExplicitInset ? "content-box" : void 0
16439
16471
  };
16440
16472
  }
16441
16473
  function wrappedFloatingImageDualExclusionLayout(image, options) {
@@ -19174,7 +19206,7 @@ function renderParagraphRuns(paragraph, keyPrefix, documentTheme = "light", numb
19174
19206
  (() => {
19175
19207
  const cropLayout = imageCropLayout(child, widthPx, heightPx);
19176
19208
  const imageVisualStyle = {
19177
- filter: child.cssFilter,
19209
+ filter: appendCssFilters(child.cssFilter, options?.imageFilterSuffix),
19178
19210
  opacity: child.cssOpacity
19179
19211
  };
19180
19212
  const imageTransformStyle = resolveImageRenderTransformStyle(child, {
@@ -26719,6 +26751,370 @@ function useDocxEditor(options = {}) {
26719
26751
  commitSectionParagraphText
26720
26752
  };
26721
26753
  }
26754
+ var docxViewerPageSurfaceRegistryByEditor = /* @__PURE__ */ new WeakMap();
26755
+ function docxViewerPageSurfaceRegistryOwner(editor) {
26756
+ return editor.syncPaginationInfo;
26757
+ }
26758
+ function ensureDocxViewerPageSurfaceRegistry(editor) {
26759
+ const owner = docxViewerPageSurfaceRegistryOwner(editor);
26760
+ let registry = docxViewerPageSurfaceRegistryByEditor.get(owner);
26761
+ if (!registry) {
26762
+ registry = {
26763
+ pageElements: /* @__PURE__ */ new Map(),
26764
+ listeners: /* @__PURE__ */ new Set()
26765
+ };
26766
+ docxViewerPageSurfaceRegistryByEditor.set(owner, registry);
26767
+ }
26768
+ return registry;
26769
+ }
26770
+ function subscribeDocxViewerPageSurfaces(editor, listener) {
26771
+ const registry = ensureDocxViewerPageSurfaceRegistry(editor);
26772
+ registry.listeners.add(listener);
26773
+ return () => {
26774
+ registry.listeners.delete(listener);
26775
+ };
26776
+ }
26777
+ function notifyDocxViewerPageSurfaceSubscribers(registry) {
26778
+ registry.listeners.forEach((listener) => {
26779
+ listener();
26780
+ });
26781
+ }
26782
+ function registerDocxViewerPageSurface(editor, pageIndex, element) {
26783
+ const registry = ensureDocxViewerPageSurfaceRegistry(editor);
26784
+ const normalizedPageIndex = Math.max(0, Math.round(pageIndex));
26785
+ const currentElement = registry.pageElements.get(normalizedPageIndex);
26786
+ if (element) {
26787
+ if (currentElement === element) {
26788
+ return;
26789
+ }
26790
+ registry.pageElements.set(normalizedPageIndex, element);
26791
+ notifyDocxViewerPageSurfaceSubscribers(registry);
26792
+ return;
26793
+ }
26794
+ if (!currentElement) {
26795
+ return;
26796
+ }
26797
+ registry.pageElements.delete(normalizedPageIndex);
26798
+ notifyDocxViewerPageSurfaceSubscribers(registry);
26799
+ }
26800
+ function resolveDocxViewerPageSurfaceSize(element, fallbackWidthPx, fallbackHeightPx) {
26801
+ if (element) {
26802
+ const rect = element.getBoundingClientRect();
26803
+ const rectWidthPx = Number.isFinite(rect.width) ? rect.width : 0;
26804
+ const rectHeightPx = Number.isFinite(rect.height) ? rect.height : 0;
26805
+ const offsetWidthPx = Number.isFinite(element.offsetWidth) ? element.offsetWidth : 0;
26806
+ const offsetHeightPx = Number.isFinite(element.offsetHeight) ? element.offsetHeight : 0;
26807
+ const clientWidthPx = Number.isFinite(element.clientWidth) ? element.clientWidth : 0;
26808
+ const clientHeightPx = Number.isFinite(element.clientHeight) ? element.clientHeight : 0;
26809
+ const resolvedWidthPx = Math.max(
26810
+ 0,
26811
+ rectWidthPx,
26812
+ offsetWidthPx,
26813
+ clientWidthPx
26814
+ );
26815
+ const resolvedHeightPx = Math.max(
26816
+ 0,
26817
+ rectHeightPx,
26818
+ offsetHeightPx,
26819
+ clientHeightPx
26820
+ );
26821
+ if (resolvedWidthPx > 0 && resolvedHeightPx > 0) {
26822
+ return {
26823
+ widthPx: Math.round(resolvedWidthPx),
26824
+ heightPx: Math.round(resolvedHeightPx)
26825
+ };
26826
+ }
26827
+ }
26828
+ return {
26829
+ widthPx: Math.max(1, Math.round(fallbackWidthPx)),
26830
+ heightPx: Math.max(1, Math.round(fallbackHeightPx))
26831
+ };
26832
+ }
26833
+ async function rasterizeDocxViewerPageSurfaceToCanvas(params) {
26834
+ if (typeof window === "undefined" || typeof XMLSerializer === "undefined") {
26835
+ throw new Error("DOCX thumbnails require a browser environment.");
26836
+ }
26837
+ const {
26838
+ pageElement,
26839
+ sourceWidthPx,
26840
+ sourceHeightPx,
26841
+ canvas,
26842
+ widthPx,
26843
+ heightPx,
26844
+ pixelWidthPx,
26845
+ pixelHeightPx
26846
+ } = params;
26847
+ const safeSourceWidthPx = Math.max(1, Math.round(sourceWidthPx));
26848
+ const safeSourceHeightPx = Math.max(1, Math.round(sourceHeightPx));
26849
+ const scaleX = widthPx / safeSourceWidthPx;
26850
+ const scaleY = heightPx / safeSourceHeightPx;
26851
+ const serializedPage = new XMLSerializer().serializeToString(
26852
+ pageElement.cloneNode(true)
26853
+ );
26854
+ const svgMarkup = `
26855
+ <svg xmlns="http://www.w3.org/2000/svg" width="${widthPx}" height="${heightPx}" viewBox="0 0 ${widthPx} ${heightPx}">
26856
+ <foreignObject x="0" y="0" width="100%" height="100%">
26857
+ <div xmlns="http://www.w3.org/1999/xhtml" style="width:${widthPx}px;height:${heightPx}px;overflow:hidden;">
26858
+ <div style="width:${safeSourceWidthPx}px;height:${safeSourceHeightPx}px;transform-origin:top left;transform:scale(${scaleX}, ${scaleY});">
26859
+ ${serializedPage}
26860
+ </div>
26861
+ </div>
26862
+ </foreignObject>
26863
+ </svg>
26864
+ `;
26865
+ const blob = new Blob([svgMarkup], {
26866
+ type: "image/svg+xml;charset=utf-8"
26867
+ });
26868
+ const objectUrl = URL.createObjectURL(blob);
26869
+ try {
26870
+ const image = await new Promise((resolve, reject) => {
26871
+ const nextImage = new Image();
26872
+ nextImage.decoding = "async";
26873
+ nextImage.onload = () => resolve(nextImage);
26874
+ nextImage.onerror = () => {
26875
+ reject(new Error("Failed to rasterize DOCX page thumbnail."));
26876
+ };
26877
+ nextImage.src = objectUrl;
26878
+ });
26879
+ canvas.width = Math.max(1, Math.round(pixelWidthPx));
26880
+ canvas.height = Math.max(1, Math.round(pixelHeightPx));
26881
+ canvas.style.width = `${Math.max(1, Math.round(widthPx))}px`;
26882
+ canvas.style.height = `${Math.max(1, Math.round(heightPx))}px`;
26883
+ const context = canvas.getContext("2d");
26884
+ if (!context) {
26885
+ throw new Error("2D canvas context is unavailable for DOCX thumbnails.");
26886
+ }
26887
+ context.setTransform(1, 0, 0, 1, 0, 0);
26888
+ context.clearRect(0, 0, canvas.width, canvas.height);
26889
+ context.imageSmoothingEnabled = true;
26890
+ context.imageSmoothingQuality = "high";
26891
+ context.drawImage(image, 0, 0, canvas.width, canvas.height);
26892
+ } finally {
26893
+ URL.revokeObjectURL(objectUrl);
26894
+ }
26895
+ }
26896
+ function resolveDocxPageThumbnailResolution(options) {
26897
+ const safeSourceWidthPx = Math.max(1, Math.round(options.sourceWidthPx));
26898
+ const safeSourceHeightPx = Math.max(1, Math.round(options.sourceHeightPx));
26899
+ const widthBoundPx = Number.isFinite(options.maxWidthPx) ? Math.max(1, Math.round(options.maxWidthPx)) : 180;
26900
+ const heightBoundPx = Number.isFinite(options.maxHeightPx) ? Math.max(1, Math.round(options.maxHeightPx)) : Number.POSITIVE_INFINITY;
26901
+ const scale = Math.min(
26902
+ 1,
26903
+ widthBoundPx / safeSourceWidthPx,
26904
+ heightBoundPx / safeSourceHeightPx
26905
+ );
26906
+ const pixelRatio = Number.isFinite(options.pixelRatio) ? Math.max(1, Number(options.pixelRatio)) : 1;
26907
+ const widthPx = Math.max(1, Math.round(safeSourceWidthPx * scale));
26908
+ const heightPx = Math.max(1, Math.round(safeSourceHeightPx * scale));
26909
+ return {
26910
+ widthPx,
26911
+ heightPx,
26912
+ pixelWidthPx: Math.max(1, Math.round(widthPx * pixelRatio)),
26913
+ pixelHeightPx: Math.max(1, Math.round(heightPx * pixelRatio)),
26914
+ scale
26915
+ };
26916
+ }
26917
+ function useDocxPageThumbnails(editor, options = {}) {
26918
+ const pageSurfaceRegistryOwner = docxViewerPageSurfaceRegistryOwner(editor);
26919
+ const pageSurfaceRegistryEditor = React.useMemo(
26920
+ () => ({ syncPaginationInfo: editor.syncPaginationInfo }),
26921
+ [pageSurfaceRegistryOwner]
26922
+ );
26923
+ const [pageSurfaceEpoch, setPageSurfaceEpoch] = React.useState(0);
26924
+ const [pageThumbnailStates, setPageThumbnailStates] = React.useState(() => /* @__PURE__ */ new Map());
26925
+ const attachedCanvasByPageRef = React.useRef(
26926
+ /* @__PURE__ */ new Map()
26927
+ );
26928
+ const canvasRefCallbacksRef = React.useRef(/* @__PURE__ */ new Map());
26929
+ const renderToCanvasCallbacksRef = React.useRef(/* @__PURE__ */ new Map());
26930
+ const fallbackLayout = React.useMemo(
26931
+ () => resolveDocumentLayout(editor.model),
26932
+ [editor.model]
26933
+ );
26934
+ const pageSurfaceRegistry = React.useMemo(
26935
+ () => ensureDocxViewerPageSurfaceRegistry(pageSurfaceRegistryEditor),
26936
+ [pageSurfaceRegistryEditor]
26937
+ );
26938
+ React.useEffect(
26939
+ () => subscribeDocxViewerPageSurfaces(
26940
+ pageSurfaceRegistryEditor,
26941
+ () => {
26942
+ setPageSurfaceEpoch((current) => current + 1);
26943
+ }
26944
+ ),
26945
+ [pageSurfaceRegistryEditor]
26946
+ );
26947
+ const mountedPageElements = React.useMemo(
26948
+ () => new Map(pageSurfaceRegistry.pageElements),
26949
+ [pageSurfaceEpoch, pageSurfaceRegistry.pageElements]
26950
+ );
26951
+ const updatePageThumbnailState = React.useCallback(
26952
+ (pageIndex, status, error) => {
26953
+ setPageThumbnailStates((current) => {
26954
+ const next = new Map(current);
26955
+ const previous = next.get(pageIndex);
26956
+ if (previous?.status === status && previous?.error?.message === error?.message) {
26957
+ return current;
26958
+ }
26959
+ next.set(pageIndex, { status, error });
26960
+ return next;
26961
+ });
26962
+ },
26963
+ []
26964
+ );
26965
+ const renderPageThumbnailToCanvas = React.useCallback(
26966
+ async (pageIndex, canvas) => {
26967
+ if (options.disabled) {
26968
+ return;
26969
+ }
26970
+ const targetCanvas = canvas ?? attachedCanvasByPageRef.current.get(pageIndex);
26971
+ if (!targetCanvas) {
26972
+ return;
26973
+ }
26974
+ const pageElement = mountedPageElements.get(pageIndex);
26975
+ if (!pageElement || !pageElement.isConnected) {
26976
+ updatePageThumbnailState(pageIndex, "unavailable");
26977
+ return;
26978
+ }
26979
+ const sourceSize = resolveDocxViewerPageSurfaceSize(
26980
+ pageElement,
26981
+ fallbackLayout.pageWidthPx,
26982
+ fallbackLayout.pageHeightPx
26983
+ );
26984
+ const resolution = resolveDocxPageThumbnailResolution({
26985
+ sourceWidthPx: sourceSize.widthPx,
26986
+ sourceHeightPx: sourceSize.heightPx,
26987
+ maxWidthPx: options.maxWidthPx,
26988
+ maxHeightPx: options.maxHeightPx,
26989
+ pixelRatio: options.pixelRatio
26990
+ });
26991
+ updatePageThumbnailState(pageIndex, "rendering");
26992
+ try {
26993
+ await rasterizeDocxViewerPageSurfaceToCanvas({
26994
+ pageElement,
26995
+ sourceWidthPx: sourceSize.widthPx,
26996
+ sourceHeightPx: sourceSize.heightPx,
26997
+ canvas: targetCanvas,
26998
+ widthPx: resolution.widthPx,
26999
+ heightPx: resolution.heightPx,
27000
+ pixelWidthPx: resolution.pixelWidthPx,
27001
+ pixelHeightPx: resolution.pixelHeightPx
27002
+ });
27003
+ updatePageThumbnailState(pageIndex, "ready");
27004
+ } catch (error) {
27005
+ updatePageThumbnailState(
27006
+ pageIndex,
27007
+ "error",
27008
+ error instanceof Error ? error : new Error("Failed to render DOCX page thumbnail.")
27009
+ );
27010
+ }
27011
+ },
27012
+ [
27013
+ fallbackLayout.pageHeightPx,
27014
+ fallbackLayout.pageWidthPx,
27015
+ mountedPageElements,
27016
+ options.disabled,
27017
+ options.maxHeightPx,
27018
+ options.maxWidthPx,
27019
+ options.pixelRatio,
27020
+ updatePageThumbnailState
27021
+ ]
27022
+ );
27023
+ const rerenderAttachedThumbnails = React.useCallback(async () => {
27024
+ const tasks = [...attachedCanvasByPageRef.current.keys()].map(
27025
+ (pageIndex) => renderPageThumbnailToCanvas(pageIndex)
27026
+ );
27027
+ await Promise.all(tasks);
27028
+ }, [renderPageThumbnailToCanvas]);
27029
+ const renderPageThumbnailToCanvasRef = React.useRef(renderPageThumbnailToCanvas);
27030
+ React.useEffect(() => {
27031
+ renderPageThumbnailToCanvasRef.current = renderPageThumbnailToCanvas;
27032
+ }, [renderPageThumbnailToCanvas]);
27033
+ React.useEffect(() => {
27034
+ canvasRefCallbacksRef.current.clear();
27035
+ renderToCanvasCallbacksRef.current.clear();
27036
+ }, [pageSurfaceRegistryOwner]);
27037
+ React.useEffect(() => {
27038
+ void rerenderAttachedThumbnails();
27039
+ }, [
27040
+ editor.documentLoadNonce,
27041
+ editor.documentTheme,
27042
+ editor.model,
27043
+ mountedPageElements,
27044
+ options.disabled,
27045
+ options.maxHeightPx,
27046
+ options.maxWidthPx,
27047
+ options.pixelRatio,
27048
+ rerenderAttachedThumbnails
27049
+ ]);
27050
+ const thumbnails = React.useMemo(() => {
27051
+ const totalPages = Math.max(1, editor.totalPages);
27052
+ return Array.from({ length: totalPages }, (_, pageIndex) => {
27053
+ const pageElement = mountedPageElements.get(pageIndex);
27054
+ const sourceSize = resolveDocxViewerPageSurfaceSize(
27055
+ pageElement,
27056
+ fallbackLayout.pageWidthPx,
27057
+ fallbackLayout.pageHeightPx
27058
+ );
27059
+ const resolution = resolveDocxPageThumbnailResolution({
27060
+ sourceWidthPx: sourceSize.widthPx,
27061
+ sourceHeightPx: sourceSize.heightPx,
27062
+ maxWidthPx: options.maxWidthPx,
27063
+ maxHeightPx: options.maxHeightPx,
27064
+ pixelRatio: options.pixelRatio
27065
+ });
27066
+ const state = pageThumbnailStates.get(pageIndex);
27067
+ return {
27068
+ pageIndex,
27069
+ pageNumber: pageIndex + 1,
27070
+ sourceWidthPx: sourceSize.widthPx,
27071
+ sourceHeightPx: sourceSize.heightPx,
27072
+ isMounted: Boolean(pageElement && pageElement.isConnected),
27073
+ status: state?.status ?? (pageElement ? "idle" : "unavailable"),
27074
+ error: state?.error,
27075
+ canvasRef: canvasRefCallbacksRef.current.get(pageIndex) ?? (() => {
27076
+ const nextCanvasRef = (canvas) => {
27077
+ if (canvas) {
27078
+ attachedCanvasByPageRef.current.set(pageIndex, canvas);
27079
+ void renderPageThumbnailToCanvasRef.current(pageIndex, canvas);
27080
+ return;
27081
+ }
27082
+ attachedCanvasByPageRef.current.delete(pageIndex);
27083
+ };
27084
+ canvasRefCallbacksRef.current.set(pageIndex, nextCanvasRef);
27085
+ return nextCanvasRef;
27086
+ })(),
27087
+ renderToCanvas: renderToCanvasCallbacksRef.current.get(pageIndex) ?? (() => {
27088
+ const nextRenderToCanvas = async (canvas) => {
27089
+ await renderPageThumbnailToCanvasRef.current(pageIndex, canvas);
27090
+ };
27091
+ renderToCanvasCallbacksRef.current.set(
27092
+ pageIndex,
27093
+ nextRenderToCanvas
27094
+ );
27095
+ return nextRenderToCanvas;
27096
+ })(),
27097
+ ...resolution
27098
+ };
27099
+ });
27100
+ }, [
27101
+ editor.totalPages,
27102
+ fallbackLayout.pageHeightPx,
27103
+ fallbackLayout.pageWidthPx,
27104
+ mountedPageElements,
27105
+ options.maxHeightPx,
27106
+ options.maxWidthPx,
27107
+ options.pixelRatio,
27108
+ pageThumbnailStates
27109
+ ]);
27110
+ return React.useMemo(
27111
+ () => ({
27112
+ thumbnails,
27113
+ rerenderAttachedThumbnails
27114
+ }),
27115
+ [rerenderAttachedThumbnails, thumbnails]
27116
+ );
27117
+ }
26722
27118
  function useDocxDocumentTheme(editor) {
26723
27119
  const setDocumentTheme = React.useCallback(
26724
27120
  (theme) => {
@@ -27780,6 +28176,7 @@ function DocxEditorViewer({
27780
28176
  editor,
27781
28177
  className,
27782
28178
  style,
28179
+ pageBackgroundColor,
27783
28180
  pageGapBackgroundColor,
27784
28181
  deferInitialPaginationPaint = true,
27785
28182
  loadingState,
@@ -27795,10 +28192,14 @@ function DocxEditorViewer({
27795
28192
  onFormFieldDoubleClick,
27796
28193
  mode = "edit"
27797
28194
  }) {
28195
+ const pageSurfaceRegistryOwner = docxViewerPageSurfaceRegistryOwner(editor);
27798
28196
  const trackedChangesEnabled = showTrackedChanges ?? editor.showTrackedChanges;
27799
28197
  const hasTrackedChanges = editor.trackedChanges.length > 0;
27800
28198
  const showTrackedChangeGutter = trackedChangesEnabled;
27801
28199
  const isReadOnly = mode === "read-only" || trackedChangesEnabled;
28200
+ const isNightReaderMode = isReadOnly && editor.documentTheme === "dark";
28201
+ const documentContentTheme = isNightReaderMode ? "light" : editor.documentTheme;
28202
+ const documentContentFilter = isNightReaderMode ? NIGHT_READER_INVERSION_FILTER : void 0;
27802
28203
  const canReplaceDocumentByDrop = mode !== "read-only";
27803
28204
  const formFieldLocationKey = React.useCallback(
27804
28205
  (location) => {
@@ -27814,9 +28215,11 @@ function DocxEditorViewer({
27814
28215
  () => ({
27815
28216
  showTrackedChanges: trackedChangesEnabled,
27816
28217
  numberingDefinitions: editor.model.metadata.numberingDefinitions,
27817
- tocLinkColorByLevel
28218
+ tocLinkColorByLevel,
28219
+ imageFilterSuffix: documentContentFilter
27818
28220
  }),
27819
28221
  [
28222
+ documentContentFilter,
27820
28223
  editor.model.metadata.numberingDefinitions,
27821
28224
  tocLinkColorByLevel,
27822
28225
  trackedChangesEnabled
@@ -27854,6 +28257,8 @@ function DocxEditorViewer({
27854
28257
  /* @__PURE__ */ new Map()
27855
28258
  );
27856
28259
  const pageElementsRef = React.useRef(/* @__PURE__ */ new Map());
28260
+ const pagePlaceholderRefCallbacksRef = React.useRef(/* @__PURE__ */ new Map());
28261
+ const pageSurfaceRefCallbacksRef = React.useRef(/* @__PURE__ */ new Map());
27857
28262
  const trackedChangeCardElementsRef = React.useRef(/* @__PURE__ */ new Map());
27858
28263
  const initialPaginationStableSignatureRef = React.useRef(
27859
28264
  void 0
@@ -27918,6 +28323,54 @@ function DocxEditorViewer({
27918
28323
  measuredPageContentHeightByIndex,
27919
28324
  setMeasuredPageContentHeightByIndex
27920
28325
  ] = React.useState([]);
28326
+ const pagePlaceholderRefForIndex = React.useCallback(
28327
+ (pageIndex) => {
28328
+ const normalizedPageIndex = Math.max(0, Math.round(pageIndex));
28329
+ const cached = pagePlaceholderRefCallbacksRef.current.get(normalizedPageIndex);
28330
+ if (cached) {
28331
+ return cached;
28332
+ }
28333
+ const nextRef = (element) => {
28334
+ if (element) {
28335
+ pageElementsRef.current.set(normalizedPageIndex, element);
28336
+ } else {
28337
+ pageElementsRef.current.delete(normalizedPageIndex);
28338
+ }
28339
+ registerDocxViewerPageSurface(editor, normalizedPageIndex, void 0);
28340
+ };
28341
+ pagePlaceholderRefCallbacksRef.current.set(normalizedPageIndex, nextRef);
28342
+ return nextRef;
28343
+ },
28344
+ [pageSurfaceRegistryOwner]
28345
+ );
28346
+ const pageSurfaceRefForIndex = React.useCallback(
28347
+ (pageIndex) => {
28348
+ const normalizedPageIndex = Math.max(0, Math.round(pageIndex));
28349
+ const cached = pageSurfaceRefCallbacksRef.current.get(normalizedPageIndex);
28350
+ if (cached) {
28351
+ return cached;
28352
+ }
28353
+ const nextRef = (element) => {
28354
+ if (element) {
28355
+ pageElementsRef.current.set(normalizedPageIndex, element);
28356
+ } else {
28357
+ pageElementsRef.current.delete(normalizedPageIndex);
28358
+ }
28359
+ registerDocxViewerPageSurface(editor, normalizedPageIndex, element);
28360
+ };
28361
+ pageSurfaceRefCallbacksRef.current.set(normalizedPageIndex, nextRef);
28362
+ return nextRef;
28363
+ },
28364
+ [pageSurfaceRegistryOwner]
28365
+ );
28366
+ React.useEffect(() => {
28367
+ pagePlaceholderRefCallbacksRef.current.clear();
28368
+ pageSurfaceRefCallbacksRef.current.clear();
28369
+ }, [pageSurfaceRegistryOwner]);
28370
+ const [
28371
+ measuredPageContentIdentityKeysByIndex,
28372
+ setMeasuredPageContentIdentityKeysByIndex
28373
+ ] = React.useState([]);
27921
28374
  const [, setRenderableImageSourceRevision] = React.useState(0);
27922
28375
  const [activeEditableParagraphSegment, setActiveEditableParagraphSegment] = React.useState(void 0);
27923
28376
  const wrappedParagraphTextareaRef = React.useRef(
@@ -27967,6 +28420,7 @@ function DocxEditorViewer({
27967
28420
  }, []);
27968
28421
  React.useEffect(() => {
27969
28422
  setMeasuredPageContentHeightByIndex([]);
28423
+ setMeasuredPageContentIdentityKeysByIndex([]);
27970
28424
  setTableMeasuredRowHeights({});
27971
28425
  setTableRowHeights({});
27972
28426
  setTableColumnWidths({});
@@ -28361,7 +28815,7 @@ function DocxEditorViewer({
28361
28815
  tableDraftLayoutEpoch,
28362
28816
  tableMeasuredRowHeights
28363
28817
  ]);
28364
- const pageNodeSegmentsByPage = React.useMemo(() => {
28818
+ const pageSegmentationPlan = React.useMemo(() => {
28365
28819
  const pageContentHeightPx = Math.max(
28366
28820
  120,
28367
28821
  documentLayout.pageHeightPx - documentLayout.marginsPx.top - documentLayout.marginsPx.bottom
@@ -28372,6 +28826,7 @@ function DocxEditorViewer({
28372
28826
  );
28373
28827
  const suppressSpacingBeforeAfterPageBreak = editor.model.metadata.compatibility?.suppressSpacingBeforeAfterPageBreak === true;
28374
28828
  const preferLastRenderedParagraphStartBreaks = !editor.canUndo && !editor.canRedo;
28829
+ const canUseMeasuredPageContentHeights = !editor.canUndo && !editor.canRedo && !disableMeasuredImportPagination && !floatingMovePreview && !dropCapMovePreview && (measuredPageContentHeightByIndex?.length ?? 0) > 0;
28375
28830
  const buildEstimatedPages = (measuredTableRowHeightsByNodeIndex, measuredPageContentHeightsOverride) => {
28376
28831
  const allowMeasuredPageContentHeights = !editor.canUndo && !editor.canRedo && !disableMeasuredImportPagination && !floatingMovePreview && !dropCapMovePreview;
28377
28832
  const baseMeasuredHeights = !allowMeasuredPageContentHeights || measuredPageContentHeightsOverride === null ? void 0 : measuredPageContentHeightsOverride ?? measuredPageContentHeightByIndex;
@@ -28417,14 +28872,13 @@ function DocxEditorViewer({
28417
28872
  minimumPageCount,
28418
28873
  Math.round(storedDocumentPageCount2)
28419
28874
  ) : void 0;
28420
- let estimatedPages = buildEstimatedPages(
28421
- tableMeasuredRowHeightsForPagination
28875
+ const pureEstimatedPages = buildEstimatedPages(
28876
+ tableMeasuredRowHeightsForPagination,
28877
+ null
28422
28878
  );
28879
+ let estimatedPages = buildEstimatedPages(tableMeasuredRowHeightsForPagination);
28880
+ let estimatedPagesUseMeasuredPageContentHeightsForRender = canUseMeasuredPageContentHeights;
28423
28881
  if (measuredPageContentHeightByIndex && measuredPageContentHeightByIndex.length > 0) {
28424
- const pureEstimatedPages = buildEstimatedPages(
28425
- tableMeasuredRowHeightsForPagination,
28426
- null
28427
- );
28428
28882
  const measuredPagesAreOnlySplitParagraphs = estimatedPages.length > 0 && estimatedPages.every(
28429
28883
  (pageSegments) => documentPageContainsOnlySplitParagraphSegments(pageSegments)
28430
28884
  );
@@ -28433,25 +28887,38 @@ function DocxEditorViewer({
28433
28887
  );
28434
28888
  if (measuredPagesAreOnlySplitParagraphs && purePagesAreOnlySplitParagraphs && pureEstimatedPages.length < estimatedPages.length) {
28435
28889
  estimatedPages = pureEstimatedPages;
28890
+ estimatedPagesUseMeasuredPageContentHeightsForRender = false;
28436
28891
  }
28437
28892
  }
28438
28893
  if (!editor.canUndo && !editor.canRedo && targetPageCount !== void 0 && tableMeasuredRowHeightsForPagination) {
28439
28894
  const candidatePages = [
28440
- estimatedPages,
28441
- buildEstimatedPages(void 0),
28442
- buildEstimatedPages(void 0, null)
28895
+ {
28896
+ pages: estimatedPages,
28897
+ useMeasuredPageContentHeightsForRender: estimatedPagesUseMeasuredPageContentHeightsForRender
28898
+ },
28899
+ {
28900
+ pages: buildEstimatedPages(void 0),
28901
+ useMeasuredPageContentHeightsForRender: canUseMeasuredPageContentHeights
28902
+ },
28903
+ {
28904
+ pages: buildEstimatedPages(void 0, null),
28905
+ useMeasuredPageContentHeightsForRender: false
28906
+ }
28443
28907
  ];
28444
- estimatedPages = candidatePages.reduce((bestCandidate, candidate) => {
28445
- const bestDifference = Math.abs(bestCandidate.length - targetPageCount);
28908
+ const bestCandidate = candidatePages.reduce((best, candidate) => {
28909
+ const bestDifference = Math.abs(best.pages.length - targetPageCount);
28446
28910
  const candidateDifference = Math.abs(
28447
- candidate.length - targetPageCount
28911
+ candidate.pages.length - targetPageCount
28448
28912
  );
28449
- return candidateDifference < bestDifference ? candidate : bestCandidate;
28913
+ return candidateDifference < bestDifference ? candidate : best;
28450
28914
  });
28915
+ estimatedPages = bestCandidate.pages;
28916
+ estimatedPagesUseMeasuredPageContentHeightsForRender = bestCandidate.useMeasuredPageContentHeightsForRender;
28451
28917
  } else if (!editor.canUndo && !editor.canRedo && targetPageCount !== void 0) {
28452
- const pureEstimatedPages = buildEstimatedPages(void 0, null);
28453
- if (Math.abs(pureEstimatedPages.length - targetPageCount) < Math.abs(estimatedPages.length - targetPageCount)) {
28454
- estimatedPages = pureEstimatedPages;
28918
+ const pureEstimatedPages2 = buildEstimatedPages(void 0, null);
28919
+ if (Math.abs(pureEstimatedPages2.length - targetPageCount) < Math.abs(estimatedPages.length - targetPageCount)) {
28920
+ estimatedPages = pureEstimatedPages2;
28921
+ estimatedPagesUseMeasuredPageContentHeightsForRender = false;
28455
28922
  }
28456
28923
  }
28457
28924
  const measuredPageHeightOverridesReduceContent = !editor.canUndo && !editor.canRedo && !floatingMovePreview && !dropCapMovePreview && estimatedPages.some((segments, pageIndex) => {
@@ -28476,7 +28943,10 @@ function DocxEditorViewer({
28476
28943
  )
28477
28944
  );
28478
28945
  if (!Number.isFinite(storedDocumentPageCount2) || storedDocumentPageCount2 <= 0) {
28479
- return estimatedPages;
28946
+ return {
28947
+ pages: estimatedPages,
28948
+ useMeasuredPageContentHeightsForRender: estimatedPagesUseMeasuredPageContentHeightsForRender
28949
+ };
28480
28950
  }
28481
28951
  const resolvedTargetPageCount = targetPageCount ?? minimumPageCount;
28482
28952
  const hasTableInternalPageBreaks = editor.model.nodes.some(
@@ -28492,10 +28962,16 @@ function DocxEditorViewer({
28492
28962
  renderedBreakHintPageCount
28493
28963
  }) && (!measuredPageHeightOverridesReduceContent || allowMeasuredReductionOverPaginationReconciliation);
28494
28964
  if (!allowStoredPageCountReconciliation) {
28495
- return estimatedPages;
28965
+ return {
28966
+ pages: estimatedPages,
28967
+ useMeasuredPageContentHeightsForRender: estimatedPagesUseMeasuredPageContentHeightsForRender
28968
+ };
28496
28969
  }
28497
28970
  if (estimatedPages.length === resolvedTargetPageCount) {
28498
- return estimatedPages;
28971
+ return {
28972
+ pages: estimatedPages,
28973
+ useMeasuredPageContentHeightsForRender: estimatedPagesUseMeasuredPageContentHeightsForRender
28974
+ };
28499
28975
  }
28500
28976
  const reconciliationScales = allowMeasuredReductionOverPaginationReconciliation ? [
28501
28977
  1.02,
@@ -28543,20 +29019,25 @@ function DocxEditorViewer({
28543
29019
  let reconciledPages = reconcileCandidatePages(
28544
29020
  estimatedPages,
28545
29021
  tableMeasuredRowHeightsForPagination,
28546
- measuredPageContentHeightByIndex
29022
+ estimatedPagesUseMeasuredPageContentHeightsForRender ? measuredPageContentHeightByIndex : null
28547
29023
  );
29024
+ let reconciledPagesUseMeasuredPageContentHeightsForRender = estimatedPagesUseMeasuredPageContentHeightsForRender;
28548
29025
  if (!editor.canUndo && !editor.canRedo) {
28549
- const pureEstimatedPages = buildEstimatedPages(void 0, null);
29026
+ const pureEstimatedPages2 = buildEstimatedPages(void 0, null);
28550
29027
  const pureReconciledPages = reconcileCandidatePages(
28551
- pureEstimatedPages,
29028
+ pureEstimatedPages2,
28552
29029
  void 0,
28553
29030
  null
28554
29031
  );
28555
29032
  if (Math.abs(pureReconciledPages.length - resolvedTargetPageCount) < Math.abs(reconciledPages.length - resolvedTargetPageCount)) {
28556
29033
  reconciledPages = pureReconciledPages;
29034
+ reconciledPagesUseMeasuredPageContentHeightsForRender = false;
28557
29035
  }
28558
29036
  }
28559
- return reconciledPages;
29037
+ return {
29038
+ pages: reconciledPages,
29039
+ useMeasuredPageContentHeightsForRender: reconciledPagesUseMeasuredPageContentHeightsForRender
29040
+ };
28560
29041
  }, [
28561
29042
  editor.canRedo,
28562
29043
  editor.canUndo,
@@ -28578,6 +29059,14 @@ function DocxEditorViewer({
28578
29059
  measuredPageContentHeightByIndex,
28579
29060
  tableMeasuredRowHeightsForPagination
28580
29061
  ]);
29062
+ const pageNodeSegmentsByPage = pageSegmentationPlan.pages;
29063
+ const useMeasuredPageContentHeightsForRender = pageSegmentationPlan.useMeasuredPageContentHeightsForRender;
29064
+ const pageNodeSegmentIdentityKeysByPage = React.useMemo(
29065
+ () => pageNodeSegmentsByPage.map(
29066
+ (pageSegments) => documentPageNodeSegmentsIdentityKey(pageSegments)
29067
+ ),
29068
+ [pageNodeSegmentsByPage]
29069
+ );
28581
29070
  const pageIndexByNodeIndex = React.useMemo(() => {
28582
29071
  const indexByNode = /* @__PURE__ */ new Map();
28583
29072
  pageNodeSegmentsByPage.forEach((segments, pageIndex) => {
@@ -29603,6 +30092,9 @@ function DocxEditorViewer({
29603
30092
  setMeasuredPageContentHeightByIndex(
29604
30093
  (current) => current.length === 0 ? current : []
29605
30094
  );
30095
+ setMeasuredPageContentIdentityKeysByIndex(
30096
+ (current) => current.length === 0 ? current : []
30097
+ );
29606
30098
  return;
29607
30099
  }
29608
30100
  if (!paginationMeasurementEnabled) {
@@ -29613,124 +30105,140 @@ function DocxEditorViewer({
29613
30105
  setMeasuredPageContentHeightByIndex(
29614
30106
  (current) => current.length === 0 ? current : []
29615
30107
  );
30108
+ setMeasuredPageContentIdentityKeysByIndex(
30109
+ (current) => current.length === 0 ? current : []
30110
+ );
29616
30111
  return;
29617
30112
  }
29618
30113
  if (Date.now() < paginationMeasurementSuspendUntilRef.current) {
29619
30114
  return;
29620
30115
  }
29621
30116
  const zoomScale = resolveEffectiveZoomScale(rootElement);
29622
- const nextMeasuredHeights = pageNodeSegmentsByPage.map((_, pageIndex) => {
29623
- const pageLayout = pageSectionInfoByIndex[pageIndex]?.layout ?? documentLayout;
29624
- const pageElement = pageElementsRef.current.get(pageIndex);
29625
- const fallbackHeightPx = Math.max(
29626
- 120,
29627
- pageLayout.pageHeightPx - pageLayout.marginsPx.top - pageLayout.marginsPx.bottom
29628
- );
29629
- if (!pageElement) {
29630
- return fallbackHeightPx;
29631
- }
29632
- const headerElement = pageHeaderElementsRef.current.get(pageIndex);
29633
- const bodyElement = pageBodyElementsRef.current.get(pageIndex);
29634
- const footerElement = pageFooterElementsRef.current.get(pageIndex);
29635
- const headerHeightPx = headerElement ? Math.max(
29636
- 0,
29637
- Math.round(headerElement.getBoundingClientRect().height / zoomScale)
29638
- ) : 0;
29639
- const docxFooterTopPx = resolveFooterNodesFloatingBoundaryTopPx(
29640
- pageHeaderAndFooterNodes[pageIndex]?.footerNodes ?? [],
29641
- pageLayout
29642
- );
29643
- let footerTopPx = Number.isFinite(docxFooterTopPx) ? Math.round(docxFooterTopPx) : void 0;
29644
- if (footerElement) {
29645
- const pageRect2 = pageElement.getBoundingClientRect();
29646
- const maxOverflowCapPx = Math.max(
29647
- 16,
29648
- Math.min(
29649
- Math.round(pageLayout.pageHeightPx * 0.12),
29650
- Math.round(
29651
- pageLayout.marginsPx.bottom + pageLayout.footerDistancePx + 24
29652
- )
29653
- )
30117
+ const nextMeasuredPageIdentityKeys = pageNodeSegmentIdentityKeysByPage;
30118
+ const nextMeasuredPageDiagnostics = pageNodeSegmentsByPage.map(
30119
+ (_, pageIndex) => {
30120
+ const pageLayout = pageSectionInfoByIndex[pageIndex]?.layout ?? documentLayout;
30121
+ const pageElement = pageElementsRef.current.get(pageIndex);
30122
+ const fallbackHeightPx = Math.max(
30123
+ 120,
30124
+ pageLayout.pageHeightPx - pageLayout.marginsPx.top - pageLayout.marginsPx.bottom
29654
30125
  );
29655
- const footerFlowBoundaryTopPx = Math.max(
30126
+ if (!pageElement) {
30127
+ return {
30128
+ heightPx: fallbackHeightPx,
30129
+ bodyOverrunsFooter: false
30130
+ };
30131
+ }
30132
+ const headerElement = pageHeaderElementsRef.current.get(pageIndex);
30133
+ const bodyElement = pageBodyElementsRef.current.get(pageIndex);
30134
+ const footerElement = pageFooterElementsRef.current.get(pageIndex);
30135
+ const headerHeightPx = headerElement ? Math.max(
29656
30136
  0,
29657
- pageLayout.pageHeightPx - Math.max(0, pageLayout.footerDistancePx)
30137
+ Math.round(headerElement.getBoundingClientRect().height / zoomScale)
30138
+ ) : 0;
30139
+ const docxFooterTopPx = resolveFooterNodesFloatingBoundaryTopPx(
30140
+ pageHeaderAndFooterNodes[pageIndex]?.footerNodes ?? [],
30141
+ pageLayout
29658
30142
  );
29659
- const minimumRelevantFooterTopPx = Number.isFinite(docxFooterTopPx) ? Math.max(
30143
+ let footerTopPx = Number.isFinite(docxFooterTopPx) ? Math.round(docxFooterTopPx) : void 0;
30144
+ if (footerElement) {
30145
+ const pageRect2 = pageElement.getBoundingClientRect();
30146
+ const maxOverflowCapPx = Math.max(
30147
+ 16,
30148
+ Math.min(
30149
+ Math.round(pageLayout.pageHeightPx * 0.12),
30150
+ Math.round(
30151
+ pageLayout.marginsPx.bottom + pageLayout.footerDistancePx + 24
30152
+ )
30153
+ )
30154
+ );
30155
+ const footerFlowBoundaryTopPx = Math.max(
30156
+ 0,
30157
+ pageLayout.pageHeightPx - Math.max(0, pageLayout.footerDistancePx)
30158
+ );
30159
+ const minimumRelevantFooterTopPx = Number.isFinite(docxFooterTopPx) ? Math.max(
30160
+ 0,
30161
+ Math.min(
30162
+ Math.max(0, footerFlowBoundaryTopPx - maxOverflowCapPx),
30163
+ Math.round(docxFooterTopPx - maxOverflowCapPx)
30164
+ )
30165
+ ) : Math.max(0, footerFlowBoundaryTopPx - maxOverflowCapPx);
30166
+ let visualTop = Number.POSITIVE_INFINITY;
30167
+ footerElement.querySelectorAll("*").forEach((element) => {
30168
+ if (!element.isConnected) {
30169
+ return;
30170
+ }
30171
+ const rect = element.getBoundingClientRect();
30172
+ if (rect.width <= 0 && rect.height <= 0) {
30173
+ return;
30174
+ }
30175
+ const relativeTopPx = (rect.top - pageRect2.top) / zoomScale;
30176
+ if (relativeTopPx < minimumRelevantFooterTopPx - 1) {
30177
+ return;
30178
+ }
30179
+ visualTop = Math.min(visualTop, rect.top);
30180
+ });
30181
+ if (Number.isFinite(visualTop)) {
30182
+ const measuredFooterTopPx = (visualTop - pageRect2.top) / zoomScale;
30183
+ footerTopPx = Number.isFinite(footerTopPx) ? Math.min(
30184
+ Math.round(footerTopPx),
30185
+ Math.round(measuredFooterTopPx)
30186
+ ) : Math.round(measuredFooterTopPx);
30187
+ }
30188
+ }
30189
+ const pageRect = pageElement.getBoundingClientRect();
30190
+ const bodyRect = bodyElement?.getBoundingClientRect();
30191
+ const bodyTopPx = bodyRect ? Math.max(0, Math.round((bodyRect.top - pageRect.top) / zoomScale)) : void 0;
30192
+ const bodyImageCount = bodyElement?.querySelectorAll("[data-docx-image-location]").length ?? 0;
30193
+ const bodyTextTrimmedLength = bodyElement?.textContent?.replace(/\s+/g, "").length ?? 0;
30194
+ const skipBodyBottomAdjustment = bodyImageCount > 0 && bodyTextTrimmedLength === 0;
30195
+ const visualBodyBottom = bodyElement && bodyRect ? resolveMeasuredBodyRenderedBottomPx(
30196
+ Array.from(bodyElement.querySelectorAll("*")).map(
30197
+ (element) => {
30198
+ const rect = element.getBoundingClientRect();
30199
+ return {
30200
+ bottomPx: rect.bottom,
30201
+ widthPx: rect.width,
30202
+ heightPx: rect.height,
30203
+ ignore: !element.isConnected || Boolean(element.closest("[data-docx-image-location]")) || Boolean(
30204
+ element.closest(
30205
+ `[${PAGE_CONTENT_MEASUREMENT_IGNORE_ATTRIBUTE}="true"]`
30206
+ )
30207
+ )
30208
+ };
30209
+ }
30210
+ )
30211
+ ) : void 0;
30212
+ const bodyRenderedBottomPx = bodyRect && Number.isFinite(visualBodyBottom) ? Math.max(
29660
30213
  0,
29661
- Math.min(
29662
- Math.max(0, footerFlowBoundaryTopPx - maxOverflowCapPx),
29663
- Math.round(docxFooterTopPx - maxOverflowCapPx)
30214
+ Math.round(
30215
+ (visualBodyBottom - pageRect.top) / zoomScale
29664
30216
  )
29665
- ) : Math.max(0, footerFlowBoundaryTopPx - maxOverflowCapPx);
29666
- let visualTop = Number.POSITIVE_INFINITY;
29667
- footerElement.querySelectorAll("*").forEach((element) => {
29668
- if (!element.isConnected) {
29669
- return;
29670
- }
29671
- const rect = element.getBoundingClientRect();
29672
- if (rect.width <= 0 && rect.height <= 0) {
29673
- return;
29674
- }
29675
- const relativeTopPx = (rect.top - pageRect2.top) / zoomScale;
29676
- if (relativeTopPx < minimumRelevantFooterTopPx - 1) {
29677
- return;
29678
- }
29679
- visualTop = Math.min(visualTop, rect.top);
30217
+ ) : void 0;
30218
+ return resolveMeasuredPageContentHeightDiagnostics({
30219
+ pageLayout,
30220
+ fallbackHeightPx,
30221
+ headerHeightPx,
30222
+ currentMeasuredHeightPx: measuredPageContentHeightByIndex?.[pageIndex],
30223
+ bodyTopPx,
30224
+ bodyRenderedBottomPx,
30225
+ footerTopPx,
30226
+ skipBodyBottomAdjustment
29680
30227
  });
29681
- if (Number.isFinite(visualTop)) {
29682
- const measuredFooterTopPx = (visualTop - pageRect2.top) / zoomScale;
29683
- footerTopPx = Number.isFinite(footerTopPx) ? Math.min(
29684
- Math.round(footerTopPx),
29685
- Math.round(measuredFooterTopPx)
29686
- ) : Math.round(measuredFooterTopPx);
29687
- }
29688
30228
  }
29689
- const pageRect = pageElement.getBoundingClientRect();
29690
- const bodyRect = bodyElement?.getBoundingClientRect();
29691
- const bodyTopPx = bodyRect ? Math.max(0, Math.round((bodyRect.top - pageRect.top) / zoomScale)) : void 0;
29692
- const bodyImageCount = bodyElement?.querySelectorAll("[data-docx-image-location]").length ?? 0;
29693
- const bodyTextTrimmedLength = bodyElement?.textContent?.replace(/\s+/g, "").length ?? 0;
29694
- const skipBodyBottomAdjustment = bodyImageCount > 0 && bodyTextTrimmedLength === 0;
29695
- const visualBodyBottom = bodyElement && bodyRect ? resolveMeasuredBodyRenderedBottomPx(
29696
- Array.from(bodyElement.querySelectorAll("*")).map(
29697
- (element) => {
29698
- const rect = element.getBoundingClientRect();
29699
- return {
29700
- bottomPx: rect.bottom,
29701
- widthPx: rect.width,
29702
- heightPx: rect.height,
29703
- ignore: !element.isConnected || Boolean(element.closest("[data-docx-image-location]")) || Boolean(
29704
- element.closest(
29705
- `[${PAGE_CONTENT_MEASUREMENT_IGNORE_ATTRIBUTE}="true"]`
29706
- )
29707
- )
29708
- };
29709
- }
29710
- )
29711
- ) : void 0;
29712
- const bodyRenderedBottomPx = bodyRect && Number.isFinite(visualBodyBottom) ? Math.max(
29713
- 0,
29714
- Math.round(
29715
- (visualBodyBottom - pageRect.top) / zoomScale
29716
- )
29717
- ) : void 0;
29718
- return resolveMeasuredPageContentHeightPx({
29719
- pageLayout,
29720
- fallbackHeightPx,
29721
- headerHeightPx,
29722
- currentMeasuredHeightPx: measuredPageContentHeightByIndex?.[pageIndex],
29723
- bodyTopPx,
29724
- bodyRenderedBottomPx,
29725
- footerTopPx,
29726
- skipBodyBottomAdjustment
29727
- });
29728
- });
30229
+ );
30230
+ const nextMeasuredHeights = nextMeasuredPageDiagnostics.map(
30231
+ (diagnostics) => diagnostics.heightPx
30232
+ );
29729
30233
  const frameId = window.requestAnimationFrame(() => {
29730
30234
  setMeasuredPageContentHeightByIndex((current) => {
29731
30235
  const stabilizedHeights = stabilizeMeasuredPageContentHeights(
29732
30236
  current,
29733
- nextMeasuredHeights
30237
+ nextMeasuredHeights,
30238
+ {
30239
+ currentPageIdentityKeys: measuredPageContentIdentityKeysByIndex,
30240
+ nextPageIdentityKeys: nextMeasuredPageIdentityKeys
30241
+ }
29734
30242
  );
29735
30243
  if (current.length === stabilizedHeights.length) {
29736
30244
  let equal = true;
@@ -29748,6 +30256,21 @@ function DocxEditorViewer({
29748
30256
  }
29749
30257
  return stabilizedHeights;
29750
30258
  });
30259
+ setMeasuredPageContentIdentityKeysByIndex((current) => {
30260
+ if (current.length === nextMeasuredPageIdentityKeys.length) {
30261
+ let equal = true;
30262
+ for (let pageIndex = 0; pageIndex < nextMeasuredPageIdentityKeys.length; pageIndex += 1) {
30263
+ if (current[pageIndex] !== nextMeasuredPageIdentityKeys[pageIndex]) {
30264
+ equal = false;
30265
+ break;
30266
+ }
30267
+ }
30268
+ if (equal) {
30269
+ return current;
30270
+ }
30271
+ }
30272
+ return nextMeasuredPageIdentityKeys;
30273
+ });
29751
30274
  });
29752
30275
  return () => {
29753
30276
  window.cancelAnimationFrame(frameId);
@@ -29756,10 +30279,12 @@ function DocxEditorViewer({
29756
30279
  disableMeasuredImportPagination,
29757
30280
  documentLayout,
29758
30281
  measuredPageContentHeightByIndex,
30282
+ measuredPageContentIdentityKeysByIndex,
29759
30283
  paginationMeasurementEnabled,
29760
30284
  paginationMeasurementEpoch,
29761
30285
  pageCount,
29762
30286
  pageNodeSegmentsByPage,
30287
+ pageNodeSegmentIdentityKeysByPage,
29763
30288
  pageSectionInfoByIndex,
29764
30289
  pageHeaderAndFooterNodes
29765
30290
  ]);
@@ -35592,7 +36117,10 @@ function DocxEditorViewer({
35592
36117
  height: run.image.heightPx ? `${run.image.heightPx}px` : void 0,
35593
36118
  verticalAlign: "middle",
35594
36119
  display: "inline-block",
35595
- filter: run.image.cssFilter,
36120
+ filter: appendCssFilters(
36121
+ run.image.cssFilter,
36122
+ documentContentFilter
36123
+ ),
35596
36124
  opacity: run.image.cssOpacity
35597
36125
  }
35598
36126
  },
@@ -35603,14 +36131,15 @@ function DocxEditorViewer({
35603
36131
  overlapStart - run.startOffset,
35604
36132
  overlapEnd - run.startOffset
35605
36133
  );
35606
- if (!slice) {
36134
+ const renderedSlice = sanitizeRenderedPretextFragmentText(slice);
36135
+ if (!renderedSlice) {
35607
36136
  return void 0;
35608
36137
  }
35609
36138
  const textStyle = run.link ? {
35610
- ...linkStyleToCss(run.style, editor.documentTheme),
36139
+ ...linkStyleToCss(run.style, documentContentTheme),
35611
36140
  whiteSpace: "pre"
35612
36141
  } : {
35613
- ...runStyleToCss(run.style, editor.documentTheme),
36142
+ ...runStyleToCss(run.style, documentContentTheme),
35614
36143
  whiteSpace: "pre"
35615
36144
  };
35616
36145
  if (activeSession) {
@@ -35618,7 +36147,7 @@ function DocxEditorViewer({
35618
36147
  "span",
35619
36148
  {
35620
36149
  style: textStyle,
35621
- children: slice
36150
+ children: renderedSlice
35622
36151
  },
35623
36152
  `${keyPrefix}-active-${lineIndex}-${run.key}-${overlapStart}`
35624
36153
  );
@@ -35645,14 +36174,14 @@ function DocxEditorViewer({
35645
36174
  scrollToBookmark(run.link.slice(1));
35646
36175
  },
35647
36176
  style: textStyle,
35648
- children: slice
36177
+ children: renderedSlice
35649
36178
  },
35650
36179
  `${keyPrefix}-fragment-${lineIndex}-${run.key}-${overlapStart}`
35651
36180
  ) : /* @__PURE__ */ jsx(
35652
36181
  "span",
35653
36182
  {
35654
36183
  style: textStyle,
35655
- children: slice
36184
+ children: renderedSlice
35656
36185
  },
35657
36186
  `${keyPrefix}-fragment-${lineIndex}-${run.key}-${overlapStart}`
35658
36187
  );
@@ -36344,7 +36873,7 @@ function DocxEditorViewer({
36344
36873
  return renderParagraphRuns(
36345
36874
  paragraph,
36346
36875
  keyPrefix,
36347
- editor.documentTheme,
36876
+ documentContentTheme,
36348
36877
  numberingLabel,
36349
36878
  scrollToBookmark,
36350
36879
  interactiveBodyFloatingPageOriginPx,
@@ -36412,7 +36941,10 @@ function DocxEditorViewer({
36412
36941
  height: run.image.heightPx ? `${run.image.heightPx}px` : void 0,
36413
36942
  verticalAlign: "middle",
36414
36943
  display: "inline-block",
36415
- filter: run.image.cssFilter,
36944
+ filter: appendCssFilters(
36945
+ run.image.cssFilter,
36946
+ documentContentFilter
36947
+ ),
36416
36948
  opacity: run.image.cssOpacity
36417
36949
  }
36418
36950
  },
@@ -36427,10 +36959,10 @@ function DocxEditorViewer({
36427
36959
  return void 0;
36428
36960
  }
36429
36961
  const textStyle = run.link ? {
36430
- ...linkStyleToCss(run.style, editor.documentTheme),
36962
+ ...linkStyleToCss(run.style, documentContentTheme),
36431
36963
  whiteSpace: "pre"
36432
36964
  } : {
36433
- ...runStyleToCss(run.style, editor.documentTheme),
36965
+ ...runStyleToCss(run.style, documentContentTheme),
36434
36966
  whiteSpace: "pre"
36435
36967
  };
36436
36968
  return run.link ? /* @__PURE__ */ jsx(
@@ -36567,7 +37099,10 @@ function DocxEditorViewer({
36567
37099
  heightPx
36568
37100
  );
36569
37101
  const imageVisualStyle = {
36570
- filter: manualImage.cssFilter,
37102
+ filter: appendCssFilters(
37103
+ manualImage.cssFilter,
37104
+ documentContentFilter
37105
+ ),
36571
37106
  opacity: manualImage.cssOpacity
36572
37107
  };
36573
37108
  const imageTransformStyle = resolveImageRenderTransformStyle(
@@ -36841,7 +37376,10 @@ function DocxEditorViewer({
36841
37376
  verticalAlign: "middle",
36842
37377
  display: "block",
36843
37378
  cursor: isReadOnly ? "default" : "move",
36844
- filter: manualImage.cssFilter,
37379
+ filter: appendCssFilters(
37380
+ manualImage.cssFilter,
37381
+ documentContentFilter
37382
+ ),
36845
37383
  opacity: manualImage.cssOpacity
36846
37384
  }
36847
37385
  }
@@ -37053,7 +37591,10 @@ function DocxEditorViewer({
37053
37591
  verticalAlign: "middle",
37054
37592
  display: "block",
37055
37593
  cursor: isReadOnly ? "default" : "move",
37056
- filter: manualImage.cssFilter,
37594
+ filter: appendCssFilters(
37595
+ manualImage.cssFilter,
37596
+ documentContentFilter
37597
+ ),
37057
37598
  opacity: manualImage.cssOpacity
37058
37599
  }
37059
37600
  }
@@ -37205,7 +37746,7 @@ function DocxEditorViewer({
37205
37746
  });
37206
37747
  }
37207
37748
  if (numberingLabel) {
37208
- const numberingTextStyle = numberingLabel.style ? runStyleToCss(numberingLabel.style, editor.documentTheme) : void 0;
37749
+ const numberingTextStyle = numberingLabel.style ? runStyleToCss(numberingLabel.style, documentContentTheme) : void 0;
37209
37750
  nodes.push(
37210
37751
  /* @__PURE__ */ jsx(
37211
37752
  "span",
@@ -37217,7 +37758,7 @@ function DocxEditorViewer({
37217
37758
  editor.model.metadata.numberingDefinitions,
37218
37759
  numberingLabel,
37219
37760
  numberingTextStyle,
37220
- editor.documentTheme
37761
+ documentContentTheme
37221
37762
  ),
37222
37763
  children: numberingLabel.imageSrc ? /* @__PURE__ */ jsxs(Fragment2, { children: [
37223
37764
  /* @__PURE__ */ jsx(
@@ -37534,7 +38075,7 @@ function DocxEditorViewer({
37534
38075
  {
37535
38076
  style: segment.style ? runStyleToCss(
37536
38077
  segment.style,
37537
- editor.documentTheme
38078
+ documentContentTheme
37538
38079
  ) : void 0,
37539
38080
  children: segment.text
37540
38081
  },
@@ -37548,7 +38089,10 @@ function DocxEditorViewer({
37548
38089
  ) : renderableImageSrc && !showsUnsupportedFallback ? (() => {
37549
38090
  const cropLayout = imageCropLayout(child, widthPx, heightPx);
37550
38091
  const imageVisualStyle = {
37551
- filter: child.cssFilter,
38092
+ filter: appendCssFilters(
38093
+ child.cssFilter,
38094
+ documentContentFilter
38095
+ ),
37552
38096
  opacity: child.cssOpacity
37553
38097
  };
37554
38098
  const imageTransformStyle = resolveImageRenderTransformStyle(
@@ -37814,10 +38358,10 @@ function DocxEditorViewer({
37814
38358
  const compactFieldLayout = compactTabStopFieldLayout || child.sourceKind === "legacy";
37815
38359
  const isTextLikeFormField = child.fieldType === "text" || child.fieldType === "date";
37816
38360
  const inputStyle = {
37817
- ...runStyleToCss(child.style, editor.documentTheme),
38361
+ ...runStyleToCss(child.style, documentContentTheme),
37818
38362
  fontFamily: cssFontFamily(child.style?.fontFamily) ?? "inherit",
37819
38363
  fontSize: child.style?.fontSizePt ? `${child.style.fontSizePt}pt` : "inherit",
37820
- color: themedRunColor(child.style?.color, editor.documentTheme) ?? "inherit",
38364
+ color: themedRunColor(child.style?.color, documentContentTheme) ?? "inherit",
37821
38365
  backgroundColor: isTextLikeFormField ? "rgba(148, 163, 184, 0.16)" : compactFieldLayout ? "transparent" : "#ffffff",
37822
38366
  border: isTextLikeFormField ? "1px solid rgba(148, 163, 184, 0.6)" : compactFieldLayout ? "none" : "1px solid #d4d4d8",
37823
38367
  borderRadius: isTextLikeFormField ? 4 : compactFieldLayout ? 0 : 6,
@@ -37899,7 +38443,7 @@ function DocxEditorViewer({
37899
38443
  cursor: isReadOnly ? "default" : "pointer",
37900
38444
  userSelect: "none",
37901
38445
  outline: "none",
37902
- ...runStyleToCss(child.style, editor.documentTheme)
38446
+ ...runStyleToCss(child.style, documentContentTheme)
37903
38447
  },
37904
38448
  children: checkboxSymbol
37905
38449
  },
@@ -38113,7 +38657,7 @@ function DocxEditorViewer({
38113
38657
  "span",
38114
38658
  {
38115
38659
  style: {
38116
- ...runStyleToCss(child.style, editor.documentTheme),
38660
+ ...runStyleToCss(child.style, documentContentTheme),
38117
38661
  verticalAlign: "super",
38118
38662
  fontSize: "0.75em"
38119
38663
  },
@@ -38158,7 +38702,7 @@ function DocxEditorViewer({
38158
38702
  const bookmarkName = linkHref.slice(1);
38159
38703
  scrollToBookmark(bookmarkName);
38160
38704
  },
38161
- style: linkStyleToCss(child.style, editor.documentTheme),
38705
+ style: linkStyleToCss(child.style, documentContentTheme),
38162
38706
  children: child.text
38163
38707
  },
38164
38708
  runKey
@@ -38173,7 +38717,7 @@ function DocxEditorViewer({
38173
38717
  );
38174
38718
  return;
38175
38719
  }
38176
- const runStyle = runStyleToCss(child.style, editor.documentTheme);
38720
+ const runStyle = runStyleToCss(child.style, documentContentTheme);
38177
38721
  const renderedText = attachTextToPreviousCheckbox(
38178
38722
  paragraph,
38179
38723
  childIndex,
@@ -38253,7 +38797,8 @@ function DocxEditorViewer({
38253
38797
  resizePreview,
38254
38798
  selectedImage,
38255
38799
  setSelectedSectionImageKey,
38256
- editor.documentTheme,
38800
+ documentContentFilter,
38801
+ documentContentTheme,
38257
38802
  editor.selectFormField,
38258
38803
  editor.setFormFieldValue,
38259
38804
  editor.toggleFormCheckbox,
@@ -38448,9 +38993,6 @@ function DocxEditorViewer({
38448
38993
  );
38449
38994
  const paragraphSegmentVisibleHeightPx = paragraphSegmentVisibleLineCount * paragraphSegmentLineHeightPx;
38450
38995
  const paragraphSegmentTranslateYPx = paragraphSegmentStartLine * paragraphSegmentLineHeightPx;
38451
- const paragraphSegmentClipBleed = resolveParagraphSegmentClipBleedPx(paragraphLineRange);
38452
- const paragraphSegmentClipBleedTopPx = paragraphSegmentClipBleed.topPx;
38453
- const paragraphSegmentClipBleedBottomPx = paragraphSegmentClipBleed.bottomPx;
38454
38996
  const paragraphSegmentIsActiveEditable = paragraphSegmentIdentityMatches(
38455
38997
  activeEditableParagraphSegment,
38456
38998
  nodeIndex,
@@ -38499,6 +39041,9 @@ function DocxEditorViewer({
38499
39041
  pretextParagraphSliceEndLine
38500
39042
  ) : void 0;
38501
39043
  const shouldRenderParagraphSegmentWithPretext = hasPartialLineRange && Boolean(pretextParagraphSource) && Boolean(pretextParagraphLayout) && pretextParagraphTotalLines > 0;
39044
+ const paragraphSegmentClipBleed = shouldRenderParagraphSegmentWithPretext ? resolveParagraphSegmentClipBleedPx(paragraphLineRange) : resolveFallbackParagraphSegmentClipBleedPx(node, paragraphLineRange);
39045
+ const paragraphSegmentClipBleedTopPx = paragraphSegmentClipBleed.topPx;
39046
+ const paragraphSegmentClipBleedBottomPx = paragraphSegmentClipBleed.bottomPx;
38502
39047
  const pretextSegmentNumberingMarkerBoxWidthPx = numberingLabel && paragraphSegmentStartLine === 0 ? resolveNumberingMarkerBoxWidthPx(
38503
39048
  node,
38504
39049
  editor.model.metadata.numberingDefinitions,
@@ -38523,8 +39068,8 @@ function DocxEditorViewer({
38523
39068
  node,
38524
39069
  editor.model.metadata.numberingDefinitions,
38525
39070
  numberingLabel,
38526
- numberingLabel.style ? runStyleToCss(numberingLabel.style, editor.documentTheme) : void 0,
38527
- editor.documentTheme
39071
+ numberingLabel.style ? runStyleToCss(numberingLabel.style, documentContentTheme) : void 0,
39072
+ documentContentTheme
38528
39073
  ),
38529
39074
  position: "absolute",
38530
39075
  left: -Math.round(
@@ -38548,7 +39093,8 @@ function DocxEditorViewer({
38548
39093
  verticalAlign: "text-bottom",
38549
39094
  width: numberingLabel.imageWidthPx ?? 12,
38550
39095
  height: numberingLabel.imageHeightPx ?? 12,
38551
- marginRight: 2
39096
+ marginRight: 2,
39097
+ filter: documentContentFilter
38552
39098
  }
38553
39099
  }
38554
39100
  ),
@@ -39696,7 +40242,7 @@ ${currentText.slice(end)}`;
39696
40242
  children: renderHeaderNode(
39697
40243
  cellContent,
39698
40244
  `active-cell-nested-table-${nodeIndex}-${rowIndex}-${cellIndex}-${contentIndex}`,
39699
- editor.documentTheme,
40245
+ documentContentTheme,
39700
40246
  editor.model.metadata.numberingDefinitions,
39701
40247
  headingStyles,
39702
40248
  spannedWidthPx > 0 ? spannedWidthPx : void 0,
@@ -40612,7 +41158,7 @@ ${currentText.slice(end)}`;
40612
41158
  return renderHeaderNode(
40613
41159
  cellContent,
40614
41160
  `body-cell-nested-table-${nodeIndex}-${rowIndex}-${cellIndex}-${contentIndex}`,
40615
- editor.documentTheme,
41161
+ documentContentTheme,
40616
41162
  editor.model.metadata.numberingDefinitions,
40617
41163
  headingStyles,
40618
41164
  spannedWidthPx > 0 ? spannedWidthPx : void 0,
@@ -41294,7 +41840,7 @@ ${currentText.slice(end)}`;
41294
41840
  style: {
41295
41841
  ...runStyleToCss(
41296
41842
  dropCapTextStyle,
41297
- editor.documentTheme
41843
+ documentContentTheme
41298
41844
  ),
41299
41845
  width: "100%",
41300
41846
  minHeight: dropCapHeightPx,
@@ -41311,7 +41857,7 @@ ${currentText.slice(end)}`;
41311
41857
  boxShadow: isSelectedDropCap ? "0 0 0 2px rgba(191, 219, 254, 0.65)" : void 0,
41312
41858
  color: themedRunColor(
41313
41859
  dropCapTextStyle.color,
41314
- editor.documentTheme
41860
+ documentContentTheme
41315
41861
  ) ?? void 0,
41316
41862
  fontFamily: cssFontFamily(dropCapTextStyle.fontFamily) ?? void 0
41317
41863
  }
@@ -41499,7 +42045,7 @@ ${currentText.slice(end)}`;
41499
42045
  style: {
41500
42046
  ...runStyleToCss(
41501
42047
  dropCapTextStyle,
41502
- editor.documentTheme
42048
+ documentContentTheme
41503
42049
  ),
41504
42050
  width: "100%",
41505
42051
  minHeight: dropCapHeightPx,
@@ -41516,7 +42062,7 @@ ${currentText.slice(end)}`;
41516
42062
  boxShadow: isSelectedDropCap ? "0 0 0 2px rgba(191, 219, 254, 0.65)" : void 0,
41517
42063
  color: themedRunColor(
41518
42064
  dropCapTextStyle.color,
41519
- editor.documentTheme
42065
+ documentContentTheme
41520
42066
  ) ?? void 0,
41521
42067
  fontFamily: cssFontFamily(
41522
42068
  dropCapTextStyle.fontFamily
@@ -41781,7 +42327,7 @@ ${currentText.slice(end)}`;
41781
42327
  renderParagraphRuns(
41782
42328
  paragraph,
41783
42329
  `${keyPrefix}-runs`,
41784
- editor.documentTheme,
42330
+ documentContentTheme,
41785
42331
  void 0,
41786
42332
  scrollToBookmark,
41787
42333
  void 0,
@@ -41799,7 +42345,7 @@ ${currentText.slice(end)}`;
41799
42345
  ));
41800
42346
  },
41801
42347
  [
41802
- editor.documentTheme,
42348
+ documentContentTheme,
41803
42349
  endnoteDisplayIndexById,
41804
42350
  footnoteDisplayIndexById,
41805
42351
  renderParagraphRuns,
@@ -41960,13 +42506,7 @@ ${currentText.slice(end)}`;
41960
42506
  "div",
41961
42507
  {
41962
42508
  "data-docx-page-placeholder": "true",
41963
- ref: (element) => {
41964
- if (element) {
41965
- pageElementsRef.current.set(pageIndex, element);
41966
- } else {
41967
- pageElementsRef.current.delete(pageIndex);
41968
- }
41969
- },
42509
+ ref: pagePlaceholderRefForIndex(pageIndex),
41970
42510
  style: {
41971
42511
  height: pageLayout.pageHeightPx,
41972
42512
  width: pageLayout.pageWidthPx
@@ -42058,18 +42598,21 @@ ${currentText.slice(end)}`;
42058
42598
  const isLastPage = pageIndex === pageCount - 1;
42059
42599
  const pageFootnotes = pageFootnotesByIndex[pageIndex] ?? [];
42060
42600
  const pageBottomFootnotes = isLastPage && remainingFootnotes.length > 0 ? [...pageFootnotes, ...remainingFootnotes] : pageFootnotes;
42061
- const pageBodyAvailableHeightPx = resolvePageContentHeightPxForPageSegments(
42062
- pageNodeSegments,
42601
+ const pageBodyAvailableHeightPx = resolveRenderPageContentHeightPxForPageSegments({
42602
+ pageSegments: pageNodeSegments,
42063
42603
  pageIndex,
42064
- Math.max(
42604
+ defaultPageContentHeightPx: Math.max(
42065
42605
  120,
42066
42606
  pageLayout.pageHeightPx - pageLayout.marginsPx.top - pageLayout.marginsPx.bottom
42067
42607
  ),
42068
- paginationSectionMetrics,
42069
- measuredPageContentHeightByIndex
42070
- );
42608
+ metricsBySection: paginationSectionMetrics,
42609
+ measuredPageContentHeightsPxByPageIndex: measuredPageContentHeightByIndex,
42610
+ measuredPageContentIdentityKeysByPageIndex: measuredPageContentIdentityKeysByIndex,
42611
+ pageIdentityKey: pageNodeSegmentIdentityKeysByPage[pageIndex],
42612
+ useMeasuredPageContentHeights: useMeasuredPageContentHeightsForRender
42613
+ });
42071
42614
  const headerFooterBodyDimmed = pageHeaderFooterEditActive;
42072
- const pageBackgroundColor = editor.model.metadata.documentBackgroundColor;
42615
+ const documentPageBackgroundColor = editor.model.metadata.documentBackgroundColor;
42073
42616
  const pageBorders = parseSectionPageBorders(
42074
42617
  pageInfo?.section.sectionPropertiesXml ?? editor.model.metadata.sectionPropertiesXml
42075
42618
  );
@@ -42092,7 +42635,7 @@ ${currentText.slice(end)}`;
42092
42635
  width: pageLayout.pageWidthPx,
42093
42636
  height: pageLayout.pageHeightPx,
42094
42637
  minHeight: pageLayout.pageHeightPx,
42095
- backgroundColor: pageBackgroundColor ?? pageSurfaceBaseStyle.backgroundColor,
42638
+ backgroundColor: pageBackgroundColor ?? documentPageBackgroundColor ?? pageSurfaceBaseStyle.backgroundColor,
42096
42639
  position: "relative",
42097
42640
  paddingTop: pageLayout.marginsPx.top,
42098
42641
  paddingRight: pageLayout.marginsPx.right,
@@ -42156,13 +42699,7 @@ ${currentText.slice(end)}`;
42156
42699
  "div",
42157
42700
  {
42158
42701
  "data-docx-page-surface": "true",
42159
- ref: (element) => {
42160
- if (element) {
42161
- pageElementsRef.current.set(pageIndex, element);
42162
- } else {
42163
- pageElementsRef.current.delete(pageIndex);
42164
- }
42165
- },
42702
+ ref: pageSurfaceRefForIndex(pageIndex),
42166
42703
  style: {
42167
42704
  ...pageSurfaceStyle,
42168
42705
  margin: 0
@@ -42180,7 +42717,8 @@ ${currentText.slice(end)}`;
42180
42717
  height: pageLayout.pageHeightPx,
42181
42718
  overflow: "clip",
42182
42719
  pointerEvents: "none",
42183
- zIndex: 0
42720
+ zIndex: 0,
42721
+ ...documentContentFilter ? { filter: documentContentFilter } : void 0
42184
42722
  },
42185
42723
  children: pageCoverBackgroundImages.map(({ key, image }) => {
42186
42724
  const renderableImageSrc = resolveRenderableImageSource(image);
@@ -42202,7 +42740,10 @@ ${currentText.slice(end)}`;
42202
42740
  height: "100%",
42203
42741
  display: "block",
42204
42742
  objectFit: "cover",
42205
- filter: image.cssFilter,
42743
+ filter: appendCssFilters(
42744
+ image.cssFilter,
42745
+ documentContentFilter
42746
+ ),
42206
42747
  opacity: image.cssOpacity,
42207
42748
  ...resolveImageRenderTransformStyle(image, {
42208
42749
  frameWidthPx: pageLayout.pageWidthPx,
@@ -42220,7 +42761,10 @@ ${currentText.slice(end)}`;
42220
42761
  "div",
42221
42762
  {
42222
42763
  "data-docx-page-border-overlay": "true",
42223
- style: pageBorderOverlayStyle
42764
+ style: {
42765
+ ...pageBorderOverlayStyle,
42766
+ ...documentContentFilter ? { filter: documentContentFilter } : void 0
42767
+ }
42224
42768
  }
42225
42769
  ) : null,
42226
42770
  pageSections.headerNodes.length > 0 ? /* @__PURE__ */ jsx(
@@ -42249,7 +42793,8 @@ ${currentText.slice(end)}`;
42249
42793
  transition: "opacity 120ms ease",
42250
42794
  outline: "none",
42251
42795
  boxShadow: "none",
42252
- zIndex: 1
42796
+ zIndex: 1,
42797
+ ...documentContentFilter ? { filter: documentContentFilter } : void 0
42253
42798
  },
42254
42799
  contentEditable: pageHeaderFooterEditActive && !isReadOnly,
42255
42800
  suppressContentEditableWarning: true,
@@ -42309,7 +42854,7 @@ ${currentText.slice(end)}`;
42309
42854
  (node, index) => renderHeaderNode(
42310
42855
  node,
42311
42856
  `header-${pageIndex}-${index}`,
42312
- editor.documentTheme,
42857
+ documentContentTheme,
42313
42858
  editor.model.metadata.numberingDefinitions,
42314
42859
  headingStyles,
42315
42860
  headerNeedsPageWideLayout ? pageLayout.pageWidthPx : pageContentWidthPx,
@@ -42357,7 +42902,8 @@ ${currentText.slice(end)}`;
42357
42902
  transition: "opacity 120ms ease",
42358
42903
  display: "flex",
42359
42904
  flexDirection: "column",
42360
- minHeight: pageBodyAvailableHeightPx
42905
+ minHeight: pageBodyAvailableHeightPx,
42906
+ ...documentContentFilter ? { filter: documentContentFilter } : void 0
42361
42907
  },
42362
42908
  children: [
42363
42909
  /* @__PURE__ */ jsx("div", { style: { minHeight: 0 }, children: (() => {
@@ -42786,7 +43332,7 @@ ${currentText.slice(end)}`;
42786
43332
  style: {
42787
43333
  marginTop: 8,
42788
43334
  paddingTop: 8,
42789
- borderTop: `1px solid ${editor.documentTheme === "dark" ? "#4b5563" : "#9ca3af"}`,
43335
+ borderTop: `1px solid ${documentContentTheme === "dark" ? "#4b5563" : "#9ca3af"}`,
42790
43336
  display: "grid",
42791
43337
  gap: 6,
42792
43338
  fontSize: 12
@@ -42819,7 +43365,7 @@ ${currentText.slice(end)}`;
42819
43365
  style: {
42820
43366
  marginTop: "auto",
42821
43367
  paddingTop: 8,
42822
- borderTop: `1px solid ${editor.documentTheme === "dark" ? "#4b5563" : "#9ca3af"}`,
43368
+ borderTop: `1px solid ${documentContentTheme === "dark" ? "#4b5563" : "#9ca3af"}`,
42823
43369
  display: "grid",
42824
43370
  gap: 6,
42825
43371
  fontSize: 12
@@ -42923,7 +43469,8 @@ ${currentText.slice(end)}`;
42923
43469
  transition: "opacity 120ms ease",
42924
43470
  outline: "none",
42925
43471
  boxShadow: "none",
42926
- zIndex: 1
43472
+ zIndex: 1,
43473
+ ...documentContentFilter ? { filter: documentContentFilter } : void 0
42927
43474
  },
42928
43475
  contentEditable: pageHeaderFooterEditActive && !isReadOnly,
42929
43476
  suppressContentEditableWarning: true,
@@ -42983,7 +43530,7 @@ ${currentText.slice(end)}`;
42983
43530
  (node, index) => renderHeaderNode(
42984
43531
  node,
42985
43532
  `footer-${pageIndex}-${index}`,
42986
- editor.documentTheme,
43533
+ documentContentTheme,
42987
43534
  editor.model.metadata.numberingDefinitions,
42988
43535
  headingStyles,
42989
43536
  footerNeedsPageWideLayout ? pageLayout.pageWidthPx : pageContentWidthPx,
@@ -45438,6 +45985,7 @@ export {
45438
45985
  resolveDocumentLayout,
45439
45986
  resolveDocumentPageSegmentStartNodeIndex,
45440
45987
  resolveDocumentSectionsFromMetadata2 as resolveDocumentSectionsFromMetadata,
45988
+ resolveDocxPageThumbnailResolution,
45441
45989
  resolvePaginationSectionMetricsIndexForNodeIndex2 as resolvePaginationSectionMetricsIndexForNodeIndex,
45442
45990
  resolveParagraphBeforeSpacingPx2 as resolveParagraphBeforeSpacingPx,
45443
45991
  resolveSectionIndexForNodeIndex2 as resolveSectionIndexForNodeIndex,
@@ -45469,6 +46017,7 @@ export {
45469
46017
  useDocxLineSpacing,
45470
46018
  useDocxModel,
45471
46019
  useDocxPageLayout,
46020
+ useDocxPageThumbnails,
45472
46021
  useDocxPagination,
45473
46022
  useDocxParagraphStyles,
45474
46023
  useDocxTrackChanges,