@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.cjs CHANGED
@@ -73,6 +73,7 @@ __export(index_exports, {
73
73
  resolveDocumentLayout: () => resolveDocumentLayout,
74
74
  resolveDocumentPageSegmentStartNodeIndex: () => resolveDocumentPageSegmentStartNodeIndex,
75
75
  resolveDocumentSectionsFromMetadata: () => resolveDocumentSectionsFromMetadata2,
76
+ resolveDocxPageThumbnailResolution: () => resolveDocxPageThumbnailResolution,
76
77
  resolvePaginationSectionMetricsIndexForNodeIndex: () => resolvePaginationSectionMetricsIndexForNodeIndex2,
77
78
  resolveParagraphBeforeSpacingPx: () => resolveParagraphBeforeSpacingPx2,
78
79
  resolveSectionIndexForNodeIndex: () => resolveSectionIndexForNodeIndex2,
@@ -104,6 +105,7 @@ __export(index_exports, {
104
105
  useDocxLineSpacing: () => useDocxLineSpacing,
105
106
  useDocxModel: () => useDocxModel,
106
107
  useDocxPageLayout: () => useDocxPageLayout,
108
+ useDocxPageThumbnails: () => useDocxPageThumbnails,
107
109
  useDocxPagination: () => useDocxPagination,
108
110
  useDocxParagraphStyles: () => useDocxParagraphStyles,
109
111
  useDocxTrackChanges: () => useDocxTrackChanges,
@@ -6609,7 +6611,6 @@ function resolveDocumentLayout(model) {
6609
6611
  }
6610
6612
 
6611
6613
  // src/image-render.ts
6612
- var import_emf_converter = require("emf-converter");
6613
6614
  var import_fast_png = require("fast-png");
6614
6615
  var import_utif = __toESM(require("utif"), 1);
6615
6616
  var TIFF_CONTENT_TYPES = /* @__PURE__ */ new Set(["image/tiff", "image/tif"]);
@@ -6624,9 +6625,6 @@ var EMF_DATA_URI_PREFIXES = ["data:image/emf", "data:image/x-emf"];
6624
6625
  var WMF_DATA_URI_PREFIXES = ["data:image/wmf", "data:image/x-wmf"];
6625
6626
  var UTIF = import_utif.default;
6626
6627
  var convertedTiffSrcCache = /* @__PURE__ */ new Map();
6627
- var convertedMetafileSrcCache = /* @__PURE__ */ new Map();
6628
- var pendingMetafileConversions = /* @__PURE__ */ new Map();
6629
- var renderableImageSourceListeners = /* @__PURE__ */ new Set();
6630
6628
  function normalizeImageContentType(image) {
6631
6629
  return image.contentType?.trim().toLowerCase();
6632
6630
  }
@@ -6667,45 +6665,15 @@ function imageUsesWmfContent(image) {
6667
6665
  const src = normalizeImageSrc(image)?.toLowerCase();
6668
6666
  return Boolean(src && WMF_DATA_URI_PREFIXES.some((prefix) => src.startsWith(prefix)));
6669
6667
  }
6670
- function metafileCacheKey(image) {
6671
- const src = normalizeImageSrc(image);
6672
- if (src) {
6673
- return src;
6674
- }
6675
- const bytes = image.data;
6676
- if (!bytes?.byteLength) {
6677
- return void 0;
6678
- }
6679
- const base64 = bytesToBase642(bytes);
6680
- const contentType = normalizeImageContentType(image) ?? "application/octet-stream";
6681
- return base64 ? `data:${contentType};base64,${base64}` : void 0;
6682
- }
6683
- function notifyRenderableImageSourceListeners() {
6684
- renderableImageSourceListeners.forEach((listener) => {
6685
- try {
6686
- listener();
6687
- } catch {
6688
- }
6689
- });
6690
- }
6691
6668
  function imageUsesPlaceholderFallback(image) {
6692
- const contentType = normalizeImageContentType(image);
6693
- if (!contentType || !PLACEHOLDER_FALLBACK_CONTENT_TYPES.has(contentType)) {
6694
- return false;
6695
- }
6696
- const cacheKey = metafileCacheKey(image);
6697
- if (!cacheKey) {
6698
- return true;
6699
- }
6700
- return convertedMetafileSrcCache.get(cacheKey) == null;
6669
+ return imageHasMetafileContent(image);
6701
6670
  }
6702
6671
  function unsupportedImageFallbackLabel(image, widthPx, heightPx) {
6703
6672
  const isSmallIcon = (widthPx ?? 0) <= 56 && (heightPx ?? 0) <= 56;
6704
- const contentType = normalizeImageContentType(image);
6705
- if (contentType === "image/x-emf" || contentType === "image/emf") {
6673
+ if (imageUsesEmfContent(image)) {
6706
6674
  return isSmallIcon ? "e" : "EMF";
6707
6675
  }
6708
- if (contentType === "image/x-wmf" || contentType === "image/wmf") {
6676
+ if (imageUsesWmfContent(image)) {
6709
6677
  return isSmallIcon ? "w" : "WMF";
6710
6678
  }
6711
6679
  return isSmallIcon ? "e" : "TIFF";
@@ -6751,13 +6719,6 @@ function toArrayBuffer(bytes) {
6751
6719
  }
6752
6720
  return buffer.slice(byteOffset, byteOffset + byteLength);
6753
6721
  }
6754
- function toStrictArrayBuffer(bytes) {
6755
- const arrayBuffer = toArrayBuffer(bytes);
6756
- if (arrayBuffer instanceof ArrayBuffer) {
6757
- return arrayBuffer;
6758
- }
6759
- return Uint8Array.from(bytes).buffer;
6760
- }
6761
6722
  function resolveTiffBytes(image) {
6762
6723
  if (image.data?.byteLength) {
6763
6724
  return image.data;
@@ -6819,37 +6780,6 @@ function resolveRenderableImageSource(image) {
6819
6780
  return void 0;
6820
6781
  }
6821
6782
  if (imageHasMetafileContent(image)) {
6822
- const cacheKey = metafileCacheKey(image);
6823
- if (!cacheKey) {
6824
- return void 0;
6825
- }
6826
- if (convertedMetafileSrcCache.has(cacheKey)) {
6827
- return convertedMetafileSrcCache.get(cacheKey) ?? void 0;
6828
- }
6829
- if (!pendingMetafileConversions.has(cacheKey)) {
6830
- const bytes = resolveTiffBytes(image);
6831
- if (bytes) {
6832
- const conversionPromise = (async () => {
6833
- try {
6834
- const arrayBuffer = toStrictArrayBuffer(bytes);
6835
- const converted2 = imageUsesEmfContent(image) ? await (0, import_emf_converter.convertEmfToDataUrl)(arrayBuffer, void 0, void 0, { dpiScale: 1 }) : imageUsesWmfContent(image) ? await (0, import_emf_converter.convertWmfToDataUrl)(arrayBuffer, void 0, void 0, { dpiScale: 1 }) : null;
6836
- const normalized = converted2 ?? void 0;
6837
- convertedMetafileSrcCache.set(cacheKey, normalized ?? null);
6838
- notifyRenderableImageSourceListeners();
6839
- return normalized;
6840
- } catch {
6841
- convertedMetafileSrcCache.set(cacheKey, null);
6842
- notifyRenderableImageSourceListeners();
6843
- return void 0;
6844
- } finally {
6845
- pendingMetafileConversions.delete(cacheKey);
6846
- }
6847
- })();
6848
- pendingMetafileConversions.set(cacheKey, conversionPromise);
6849
- } else {
6850
- convertedMetafileSrcCache.set(cacheKey, null);
6851
- }
6852
- }
6853
6783
  return void 0;
6854
6784
  }
6855
6785
  if (!imageHasTiffContent(image)) {
@@ -6872,9 +6802,8 @@ function resolveRenderableImageSource(image) {
6872
6802
  return converted;
6873
6803
  }
6874
6804
  function subscribeRenderableImageSourceUpdates(listener) {
6875
- renderableImageSourceListeners.add(listener);
6805
+ void listener;
6876
6806
  return () => {
6877
- renderableImageSourceListeners.delete(listener);
6878
6807
  };
6879
6808
  }
6880
6809
 
@@ -10306,6 +10235,9 @@ var LEADING_COVER_SPACER_EXTRA_HEIGHT_PX = 2;
10306
10235
  var PARAGRAPH_SEGMENT_TOP_BLEED_PX = 22;
10307
10236
  var PARAGRAPH_SEGMENT_DESCENDER_BLEED_PX = 6;
10308
10237
  var PARAGRAPH_SEGMENT_VISUAL_SAFETY_PX = 24;
10238
+ var PARAGRAPH_SEGMENT_FALLBACK_TOP_BLEED_MAX_PX = 4;
10239
+ var PARAGRAPH_SEGMENT_FALLBACK_BOTTOM_BLEED_MAX_PX = 0;
10240
+ var PARAGRAPH_SEGMENT_FALLBACK_VISUAL_SAFETY_PX = 4;
10309
10241
  var INITIAL_PAGINATION_PREMEASURE_PAGE_LIMIT = 8;
10310
10242
  var INITIAL_PAGINATION_PAGE_COUNT_OSCILLATION_DISTINCT_THRESHOLD = 2;
10311
10243
  var INITIAL_PAGINATION_PAGE_COUNT_OSCILLATION_CHANGE_THRESHOLD = 4;
@@ -10642,13 +10574,18 @@ var DOC_SURFACE_STYLE_BY_THEME = {
10642
10574
  boxShadow: "0 2px 10px rgba(15, 23, 42, 0.08), 0 1px 2px rgba(15, 23, 42, 0.05)"
10643
10575
  },
10644
10576
  dark: {
10645
- backgroundColor: "#111827",
10577
+ backgroundColor: "#0a0a0a",
10646
10578
  color: "#f3f4f6",
10647
10579
  colorScheme: "dark",
10648
10580
  border: "none",
10649
10581
  boxShadow: "0 2px 10px rgba(2, 6, 23, 0.55), 0 1px 2px rgba(2, 6, 23, 0.45)"
10650
10582
  }
10651
10583
  };
10584
+ var NIGHT_READER_INVERSION_FILTER = "invert(0.95) hue-rotate(180deg) saturate(0.9) brightness(0.9) contrast(0.94)";
10585
+ function appendCssFilters(...filters) {
10586
+ const resolvedFilters = filters.map((filter) => filter?.trim()).filter((filter) => Boolean(filter));
10587
+ return resolvedFilters.length > 0 ? resolvedFilters.join(" ") : void 0;
10588
+ }
10652
10589
  var TABLE_RESIZE_HANDLE_SIZE = 8;
10653
10590
  var TABLE_RESIZE_HANDLE_HIT_SIZE = 16;
10654
10591
  var TABLE_RESIZE_BORDER_SIZE = 1;
@@ -11579,7 +11516,7 @@ function resolveFooterPaginationReservePx(footerSections, layout) {
11579
11516
  floatingFooterBoundaryReservePx
11580
11517
  );
11581
11518
  }
11582
- function resolveMeasuredPageContentHeightPx(params) {
11519
+ function resolveMeasuredPageContentHeightDiagnostics(params) {
11583
11520
  const {
11584
11521
  pageLayout,
11585
11522
  fallbackHeightPx,
@@ -11619,34 +11556,41 @@ function resolveMeasuredPageContentHeightPx(params) {
11619
11556
  ) : 0;
11620
11557
  const correctedAllowedBodyBottomPx = Math.max(
11621
11558
  0,
11622
- guardedAllowedBodyBottomPx - renderedBodyOverrunPx - measuredFooterClearanceBufferPx
11559
+ guardedAllowedBodyBottomPx - measuredFooterClearanceBufferPx
11623
11560
  );
11624
- const iterativeMeasuredHeightPx = renderedBodyOverrunPx > 0 && Number.isFinite(effectiveCurrentMeasuredHeightPx) && effectiveCurrentMeasuredHeightPx > 0 ? Math.max(
11561
+ const iterativeMeasuredHeightPx = renderedBodyOverrunPx > 0 && !Number.isFinite(bodyTopPx) && Number.isFinite(effectiveCurrentMeasuredHeightPx) && effectiveCurrentMeasuredHeightPx > 0 ? Math.max(
11625
11562
  120,
11626
11563
  Math.round(
11627
11564
  effectiveCurrentMeasuredHeightPx - renderedBodyOverrunPx - measuredFooterClearanceBufferPx
11628
11565
  )
11629
11566
  ) : void 0;
11567
+ const bodyOverrunsFooter = renderedBodyOverrunPx > 0;
11630
11568
  if (Number.isFinite(bodyTopPx) && correctedAllowedBodyBottomPx > bodyTopPx) {
11631
11569
  const measuredHeaderClearanceBufferPx2 = headerHeightPx > 0 ? MEASURED_PAGE_HEADER_CLEARANCE_BUFFER_PX : 0;
11632
11570
  const correctedHeightPx = Math.max(
11633
11571
  120,
11634
11572
  Math.round(correctedAllowedBodyBottomPx - bodyTopPx)
11635
11573
  );
11636
- return Number.isFinite(iterativeMeasuredHeightPx) ? Math.min(
11637
- Math.max(120, correctedHeightPx - measuredHeaderClearanceBufferPx2),
11638
- Math.max(
11639
- 120,
11640
- iterativeMeasuredHeightPx - measuredHeaderClearanceBufferPx2
11641
- )
11642
- ) : Math.max(120, correctedHeightPx - measuredHeaderClearanceBufferPx2);
11574
+ return {
11575
+ heightPx: Number.isFinite(iterativeMeasuredHeightPx) ? Math.min(
11576
+ Math.max(120, correctedHeightPx - measuredHeaderClearanceBufferPx2),
11577
+ Math.max(
11578
+ 120,
11579
+ iterativeMeasuredHeightPx - measuredHeaderClearanceBufferPx2
11580
+ )
11581
+ ) : Math.max(120, correctedHeightPx - measuredHeaderClearanceBufferPx2),
11582
+ bodyOverrunsFooter
11583
+ };
11643
11584
  }
11644
11585
  const measuredHeaderClearanceBufferPx = headerHeightPx > 0 ? MEASURED_PAGE_HEADER_CLEARANCE_BUFFER_PX : 0;
11645
11586
  const correctedFallbackHeightPx = Math.max(
11646
11587
  120,
11647
11588
  fallbackHeightPx - headerHeightPx - measuredHeaderClearanceBufferPx - footerOverlapPx - renderedBodyOverrunPx - measuredFooterClearanceBufferPx
11648
11589
  );
11649
- return Number.isFinite(iterativeMeasuredHeightPx) ? Math.min(correctedFallbackHeightPx, iterativeMeasuredHeightPx) : correctedFallbackHeightPx;
11590
+ return {
11591
+ heightPx: Number.isFinite(iterativeMeasuredHeightPx) ? Math.min(correctedFallbackHeightPx, iterativeMeasuredHeightPx) : correctedFallbackHeightPx,
11592
+ bodyOverrunsFooter
11593
+ };
11650
11594
  }
11651
11595
  function resolveMeasuredBodyRenderedBottomPx(descendants) {
11652
11596
  let visualBottomPx;
@@ -11664,13 +11608,27 @@ function resolveMeasuredBodyRenderedBottomPx(descendants) {
11664
11608
  });
11665
11609
  return visualBottomPx;
11666
11610
  }
11667
- function stabilizeMeasuredPageContentHeights(current, next) {
11611
+ function stabilizeMeasuredPageContentHeights(current, next, options) {
11668
11612
  return next.map((heightPx, pageIndex) => {
11669
11613
  const roundedNextHeightPx = Math.round(heightPx);
11670
11614
  const currentHeightPx = current[pageIndex];
11671
- return Number.isFinite(currentHeightPx) ? Math.min(Math.round(currentHeightPx), roundedNextHeightPx) : roundedNextHeightPx;
11615
+ const currentPageIdentityKey = options?.currentPageIdentityKeys?.[pageIndex];
11616
+ const nextPageIdentityKey = options?.nextPageIdentityKeys?.[pageIndex];
11617
+ const canPreserveConservativeHeight = currentPageIdentityKey === void 0 || nextPageIdentityKey === void 0 || currentPageIdentityKey === nextPageIdentityKey;
11618
+ return Number.isFinite(currentHeightPx) ? canPreserveConservativeHeight ? Math.min(Math.round(currentHeightPx), roundedNextHeightPx) : roundedNextHeightPx : roundedNextHeightPx;
11672
11619
  });
11673
11620
  }
11621
+ function documentPageNodeSegmentIdentityKey(segment) {
11622
+ const tableRowRangeKey = segment.tableRowRange ? `${segment.tableRowRange.startRowIndex}-${segment.tableRowRange.endRowIndex}` : "none";
11623
+ const tableRowSliceKey = segment.tableRowSlice ? `${segment.tableRowSlice.rowIndex}-${Math.round(
11624
+ segment.tableRowSlice.startOffsetPx
11625
+ )}-${Math.round(segment.tableRowSlice.sliceHeightPx)}` : "none";
11626
+ const paragraphLineRangeKey = segment.paragraphLineRange ? `${segment.paragraphLineRange.startLineIndex}-${segment.paragraphLineRange.endLineIndex}-${segment.paragraphLineRange.totalLineCount}` : "none";
11627
+ return `${segment.nodeIndex}|${tableRowRangeKey}|${tableRowSliceKey}|${paragraphLineRangeKey}`;
11628
+ }
11629
+ function documentPageNodeSegmentsIdentityKey(pageSegments) {
11630
+ return pageSegments.map(documentPageNodeSegmentIdentityKey).join("::");
11631
+ }
11674
11632
  function buildPaginationSectionMetrics(sections, fallbackLayout) {
11675
11633
  const fallbackWidthPx = resolveSectionPaginationContentWidthPx(fallbackLayout);
11676
11634
  const fallbackHeightPx = Math.max(
@@ -11753,10 +11711,11 @@ function scaleMeasuredPageContentHeights(measuredPageContentHeightsPxByPageIndex
11753
11711
  (heightPx) => Math.max(120, Math.round(heightPx * heightScale))
11754
11712
  );
11755
11713
  }
11756
- function resolvePageContentHeightPxForPageSegments(pageSegments, pageIndex, defaultPageContentHeightPx, metricsBySection, measuredPageContentHeightsPxByPageIndex) {
11714
+ function resolvePageContentHeightPxForPageSegments(pageSegments, pageIndex, defaultPageContentHeightPx, metricsBySection, measuredPageContentHeightsPxByPageIndex, measuredPageContentIdentityKeysByPageIndex, pageIdentityKey) {
11757
11715
  const pageContainsOnlySplitParagraphSegments = documentPageContainsOnlySplitParagraphSegments(pageSegments);
11758
11716
  const measuredHeightPx = measuredPageContentHeightsPxByPageIndex?.[pageIndex];
11759
- if (Number.isFinite(measuredHeightPx) && !pageContainsOnlySplitParagraphSegments) {
11717
+ const measuredHeightMatchesCurrentPage = pageIdentityKey === void 0 || measuredPageContentIdentityKeysByPageIndex?.[pageIndex] === void 0 || measuredPageContentIdentityKeysByPageIndex?.[pageIndex] === pageIdentityKey;
11718
+ if (Number.isFinite(measuredHeightPx) && measuredHeightMatchesCurrentPage && !pageContainsOnlySplitParagraphSegments) {
11760
11719
  return Math.max(120, Math.round(measuredHeightPx));
11761
11720
  }
11762
11721
  const firstNodeIndex = pageSegments[0]?.nodeIndex ?? 0;
@@ -11772,6 +11731,17 @@ function resolvePageContentHeightPxForPageSegments(pageSegments, pageIndex, defa
11772
11731
  )
11773
11732
  );
11774
11733
  }
11734
+ function resolveRenderPageContentHeightPxForPageSegments(params) {
11735
+ return resolvePageContentHeightPxForPageSegments(
11736
+ params.pageSegments,
11737
+ params.pageIndex,
11738
+ params.defaultPageContentHeightPx,
11739
+ params.metricsBySection,
11740
+ params.useMeasuredPageContentHeights === false ? void 0 : params.measuredPageContentHeightsPxByPageIndex,
11741
+ params.useMeasuredPageContentHeights === false ? void 0 : params.measuredPageContentIdentityKeysByPageIndex,
11742
+ params.pageIdentityKey
11743
+ );
11744
+ }
11775
11745
  function documentPageContainsOnlySplitParagraphSegments(pageSegments) {
11776
11746
  return pageSegments.length > 0 && pageSegments.every(
11777
11747
  (segment) => !segment.tableRowRange && paragraphSegmentHasPartialLineRange(segment.paragraphLineRange)
@@ -12651,10 +12621,11 @@ function sectionNodesNeedPageWideLayout(nodes, pageWidthPx, contentWidthPx) {
12651
12621
  return false;
12652
12622
  }
12653
12623
  const horizontalRelativeTo = image.floating.horizontalRelativeTo?.toLowerCase();
12654
- if (image.floating.behindDocument || horizontalRelativeTo === "page") {
12624
+ const usesPageWidthAnchorOrigin = horizontalRelativeTo === "page" || horizontalRelativeTo === "margin";
12625
+ if (image.floating.behindDocument && usesPageWidthAnchorOrigin) {
12655
12626
  return true;
12656
12627
  }
12657
- if (shouldRenderAbsoluteFloatingImage(image)) {
12628
+ if (usesPageWidthAnchorOrigin && (shouldRenderAbsoluteFloatingImage(image) || shouldRenderWrappedFloatingImage(image))) {
12658
12629
  return true;
12659
12630
  }
12660
12631
  if (Number.isFinite(image.widthPx) && Number.isFinite(image.floating.xPx) && image.widthPx >= safeContentWidthPx - 12 && image.floating.xPx <= 12) {
@@ -13241,6 +13212,9 @@ function buildSyntheticPretextLayoutSource(text, style) {
13241
13212
  function pretextWordBreakModeForText(text) {
13242
13213
  return KEEP_ALL_SCRIPT_RE.test(text) ? "keep-all" : "normal";
13243
13214
  }
13215
+ function sanitizeRenderedPretextFragmentText(text) {
13216
+ return text.replace(/\r\n?|\n/g, "");
13217
+ }
13244
13218
  function buildParagraphPretextLayoutItems(paragraph, source) {
13245
13219
  const paragraphBaseFontPx = paragraphBaseFontSizePx(paragraph);
13246
13220
  const wordBreak = pretextWordBreakModeForText(source.text);
@@ -14353,6 +14327,20 @@ function paragraphBaseFontSizePx(paragraph) {
14353
14327
  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;
14354
14328
  return Math.max(10, Math.round(fontSizePt * 96 / 72));
14355
14329
  }
14330
+ function paragraphMaxFontSizePx(paragraph) {
14331
+ const paragraphBaseFontPx = paragraphBaseFontSizePx(paragraph);
14332
+ let maxFontSizePx = paragraphBaseFontPx;
14333
+ paragraph.children.forEach((child) => {
14334
+ if (child.type !== "text" && child.type !== "form-field") {
14335
+ return;
14336
+ }
14337
+ maxFontSizePx = Math.max(
14338
+ maxFontSizePx,
14339
+ resolveMeasureFontSizePx(child.style, paragraphBaseFontPx)
14340
+ );
14341
+ });
14342
+ return Math.max(1, Math.round(maxFontSizePx));
14343
+ }
14356
14344
  function normalizeFontFamilyToken(fontFamily) {
14357
14345
  if (!fontFamily) {
14358
14346
  return void 0;
@@ -15550,6 +15538,34 @@ function resolveParagraphSegmentClipBleedPx(paragraphLineRange) {
15550
15538
  bottomPx: Math.max(0, PARAGRAPH_SEGMENT_DESCENDER_BLEED_PX)
15551
15539
  };
15552
15540
  }
15541
+ function resolveFallbackParagraphSegmentClipBleedPx(paragraph, paragraphLineRange) {
15542
+ if (!paragraphSegmentHasPartialLineRange(paragraphLineRange)) {
15543
+ return {
15544
+ topPx: 0,
15545
+ bottomPx: 0
15546
+ };
15547
+ }
15548
+ const lineHeightPx = Math.max(1, paragraphLineRange?.lineHeightPx ?? 0);
15549
+ const maxFontSizePx = paragraphMaxFontSizePx(paragraph);
15550
+ const glyphOvershootPx = Math.max(
15551
+ 0,
15552
+ Math.ceil((maxFontSizePx - lineHeightPx) / 2)
15553
+ );
15554
+ const ascenderSafetyPx = Math.max(
15555
+ glyphOvershootPx,
15556
+ Math.ceil(lineHeightPx * 0.22)
15557
+ );
15558
+ return {
15559
+ topPx: paragraphLineRange && paragraphLineRange.startLineIndex > 0 ? Math.min(
15560
+ PARAGRAPH_SEGMENT_FALLBACK_TOP_BLEED_MAX_PX,
15561
+ ascenderSafetyPx
15562
+ ) : 0,
15563
+ bottomPx: paragraphLineRange && paragraphLineRange.endLineIndex < paragraphLineRange.totalLineCount ? Math.min(
15564
+ PARAGRAPH_SEGMENT_FALLBACK_BOTTOM_BLEED_MAX_PX,
15565
+ glyphOvershootPx
15566
+ ) : 0
15567
+ };
15568
+ }
15553
15569
  function resolveParagraphSegmentNonFlowReservePx(paragraphLineRange) {
15554
15570
  const bleed = resolveParagraphSegmentClipBleedPx(paragraphLineRange);
15555
15571
  if (bleed.topPx <= 0 && bleed.bottomPx <= 0) {
@@ -15561,6 +15577,20 @@ function resolveParagraphSegmentNonFlowReservePx(paragraphLineRange) {
15561
15577
  );
15562
15578
  return Math.max(0, bleed.topPx) + Math.max(0, bleed.bottomPx) + Math.max(0, PARAGRAPH_SEGMENT_VISUAL_SAFETY_PX, lineHeightSafetyPx);
15563
15579
  }
15580
+ function resolveFallbackParagraphSegmentNonFlowReservePx(paragraph, paragraphLineRange) {
15581
+ const bleed = resolveFallbackParagraphSegmentClipBleedPx(
15582
+ paragraph,
15583
+ paragraphLineRange
15584
+ );
15585
+ if (bleed.topPx <= 0 && bleed.bottomPx <= 0) {
15586
+ return 0;
15587
+ }
15588
+ const lineHeightSafetyPx = Math.max(
15589
+ 0,
15590
+ Math.ceil((paragraphLineRange?.lineHeightPx ?? 0) * 0.15)
15591
+ );
15592
+ return Math.max(0, bleed.topPx) + Math.max(0, bleed.bottomPx) + Math.max(1, PARAGRAPH_SEGMENT_FALLBACK_VISUAL_SAFETY_PX, lineHeightSafetyPx);
15593
+ }
15564
15594
  function paragraphSegmentIdentityMatches(segment, nodeIndex, paragraphLineRange) {
15565
15595
  if (!segment || !paragraphLineRange) {
15566
15596
  return false;
@@ -15900,13 +15930,17 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
15900
15930
  node,
15901
15931
  nodeMetrics.docGridLinePitchPx
15902
15932
  );
15933
+ const paragraphPretextSourceForSegmentRendering = buildParagraphPretextLayoutSource(node, {
15934
+ allowExplicitLineBreakText: true
15935
+ });
15936
+ const paragraphSupportsPretextSegmentRendering = Boolean(
15937
+ paragraphPretextSourceForSegmentRendering
15938
+ );
15903
15939
  const paragraphPretextLineCount = (() => {
15904
15940
  if (!paragraphContainsExplicitLineBreakText(node)) {
15905
15941
  return void 0;
15906
15942
  }
15907
- const pretextSource = buildParagraphPretextLayoutSource(node, {
15908
- allowExplicitLineBreakText: true
15909
- });
15943
+ const pretextSource = paragraphPretextSourceForSegmentRendering;
15910
15944
  if (!pretextSource) {
15911
15945
  return void 0;
15912
15946
  }
@@ -15924,11 +15958,7 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
15924
15958
  );
15925
15959
  return pretextLayout?.lineCount;
15926
15960
  })();
15927
- const supportsImageParagraphLineSplit = paragraphHasImage2(node) && Boolean(
15928
- buildParagraphPretextLayoutSource(node, {
15929
- allowExplicitLineBreakText: true
15930
- })
15931
- );
15961
+ const supportsImageParagraphLineSplit = paragraphHasImage2(node) && paragraphSupportsPretextSegmentRendering;
15932
15962
  const paragraphLineCount = paragraphLineCountWithinWidth(
15933
15963
  node,
15934
15964
  nodeMetrics.pageContentWidthPx,
@@ -15943,6 +15973,18 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
15943
15973
  allowImageParagraphSplit: supportsImageParagraphLineSplit
15944
15974
  }) && (!widowControlEnabled || resolvedParagraphLineCount > 3);
15945
15975
  if (canSplitParagraphAcrossPages && allowParagraphLineSplitting) {
15976
+ const resolveSegmentReservePx = (startLineIndex, endLineIndex) => {
15977
+ const paragraphSegmentRange = {
15978
+ startLineIndex,
15979
+ endLineIndex,
15980
+ totalLineCount: resolvedParagraphLineCount,
15981
+ lineHeightPx: paragraphLineHeightPx
15982
+ };
15983
+ return paragraphSupportsPretextSegmentRendering ? resolveParagraphSegmentNonFlowReservePx(paragraphSegmentRange) : resolveFallbackParagraphSegmentNonFlowReservePx(
15984
+ node,
15985
+ paragraphSegmentRange
15986
+ );
15987
+ };
15946
15988
  let lineCursor = 0;
15947
15989
  let isFirstSegment = true;
15948
15990
  while (lineCursor < resolvedParagraphLineCount) {
@@ -15954,12 +15996,10 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
15954
15996
  0,
15955
15997
  currentPageContentHeightPx - pageConsumedHeightPx
15956
15998
  );
15957
- const allRemainingSegmentReservePx = resolveParagraphSegmentNonFlowReservePx({
15958
- startLineIndex: lineCursor,
15959
- endLineIndex: resolvedParagraphLineCount,
15960
- totalLineCount: resolvedParagraphLineCount,
15961
- lineHeightPx: paragraphLineHeightPx
15962
- });
15999
+ const allRemainingSegmentReservePx = resolveSegmentReservePx(
16000
+ lineCursor,
16001
+ resolvedParagraphLineCount
16002
+ );
15963
16003
  const allRemainingHeightPx = topSpacingPx + linesRemaining * paragraphLineHeightPx + bottomSpacingPx;
15964
16004
  if (allRemainingHeightPx + allRemainingSegmentReservePx <= remainingHeightPx2) {
15965
16005
  currentPageSegments.push({
@@ -15980,15 +16020,10 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
15980
16020
  0,
15981
16021
  linesRemaining - minLinesPerSegment
15982
16022
  );
15983
- const continuingSegmentReservePx = resolveParagraphSegmentNonFlowReservePx({
15984
- startLineIndex: lineCursor,
15985
- endLineIndex: Math.min(
15986
- resolvedParagraphLineCount,
15987
- lineCursor + maxLinesThisPage
15988
- ),
15989
- totalLineCount: resolvedParagraphLineCount,
15990
- lineHeightPx: paragraphLineHeightPx
15991
- });
16023
+ const continuingSegmentReservePx = resolveSegmentReservePx(
16024
+ lineCursor,
16025
+ Math.min(resolvedParagraphLineCount, lineCursor + maxLinesThisPage)
16026
+ );
15992
16027
  const availableForLinesPx = Math.max(
15993
16028
  0,
15994
16029
  remainingHeightPx2 - topSpacingPx - continuingSegmentReservePx
@@ -16027,12 +16062,10 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
16027
16062
  lineCursor + linesThatFit
16028
16063
  );
16029
16064
  while (linesThatFit > minLinesPerSegment) {
16030
- const segmentReservePx = resolveParagraphSegmentNonFlowReservePx({
16031
- startLineIndex: lineCursor,
16032
- endLineIndex: segmentEndLineIndex,
16033
- totalLineCount: resolvedParagraphLineCount,
16034
- lineHeightPx: paragraphLineHeightPx
16035
- });
16065
+ const segmentReservePx = resolveSegmentReservePx(
16066
+ lineCursor,
16067
+ segmentEndLineIndex
16068
+ );
16036
16069
  if (topSpacingPx + (segmentEndLineIndex - lineCursor) * paragraphLineHeightPx + segmentReservePx <= remainingHeightPx2) {
16037
16070
  break;
16038
16071
  }
@@ -16533,17 +16566,18 @@ function wrappedFloatingImageStyle(image, options) {
16533
16566
  });
16534
16567
  const horizontalRelativeTo = floating.horizontalRelativeTo?.toLowerCase();
16535
16568
  const explicitHorizontalInsetPx = hasExplicitHorizontalOffset && !hasExplicitHorizontalAlign && (horizontalRelativeTo === "margin" || horizontalRelativeTo === "page" || horizontalRelativeTo === "column") ? side === "left" ? Math.max(0, leftOffsetPx) : Math.max(0, rightOffsetPx) : 0;
16569
+ const columnAnchoredExplicitInset = explicitHorizontalInsetPx > 0 && horizontalRelativeTo === "column";
16536
16570
  return {
16537
16571
  display: "block",
16538
16572
  ...intrinsicBlockWidthStyle,
16539
16573
  float: side,
16540
16574
  marginTop: topOffsetPx,
16541
16575
  marginBottom: distB,
16542
- marginLeft: side === "left" ? explicitHorizontalInsetPx > 0 ? 0 : hasExplicitHorizontalOffset ? leftOffsetPx : distL + leftOffsetPx : distL,
16543
- marginRight: side === "right" ? explicitHorizontalInsetPx > 0 ? 0 : hasExplicitHorizontalOffset ? rightOffsetPx : distR + rightOffsetPx : distR,
16544
- paddingLeft: side === "left" && explicitHorizontalInsetPx > 0 ? explicitHorizontalInsetPx : void 0,
16545
- paddingRight: side === "right" && explicitHorizontalInsetPx > 0 ? explicitHorizontalInsetPx : void 0,
16546
- boxSizing: explicitHorizontalInsetPx > 0 ? "content-box" : void 0
16576
+ marginLeft: side === "left" ? explicitHorizontalInsetPx > 0 ? columnAnchoredExplicitInset ? distL + explicitHorizontalInsetPx : 0 : hasExplicitHorizontalOffset ? leftOffsetPx : distL + leftOffsetPx : distL,
16577
+ marginRight: side === "right" ? explicitHorizontalInsetPx > 0 ? columnAnchoredExplicitInset ? distR + explicitHorizontalInsetPx : 0 : hasExplicitHorizontalOffset ? rightOffsetPx : distR + rightOffsetPx : distR,
16578
+ paddingLeft: side === "left" && explicitHorizontalInsetPx > 0 && !columnAnchoredExplicitInset ? explicitHorizontalInsetPx : void 0,
16579
+ paddingRight: side === "right" && explicitHorizontalInsetPx > 0 && !columnAnchoredExplicitInset ? explicitHorizontalInsetPx : void 0,
16580
+ boxSizing: explicitHorizontalInsetPx > 0 && !columnAnchoredExplicitInset ? "content-box" : void 0
16547
16581
  };
16548
16582
  }
16549
16583
  function wrappedFloatingImageDualExclusionLayout(image, options) {
@@ -19282,7 +19316,7 @@ function renderParagraphRuns(paragraph, keyPrefix, documentTheme = "light", numb
19282
19316
  (() => {
19283
19317
  const cropLayout = imageCropLayout(child, widthPx, heightPx);
19284
19318
  const imageVisualStyle = {
19285
- filter: child.cssFilter,
19319
+ filter: appendCssFilters(child.cssFilter, options?.imageFilterSuffix),
19286
19320
  opacity: child.cssOpacity
19287
19321
  };
19288
19322
  const imageTransformStyle = resolveImageRenderTransformStyle(child, {
@@ -26827,6 +26861,370 @@ function useDocxEditor(options = {}) {
26827
26861
  commitSectionParagraphText
26828
26862
  };
26829
26863
  }
26864
+ var docxViewerPageSurfaceRegistryByEditor = /* @__PURE__ */ new WeakMap();
26865
+ function docxViewerPageSurfaceRegistryOwner(editor) {
26866
+ return editor.syncPaginationInfo;
26867
+ }
26868
+ function ensureDocxViewerPageSurfaceRegistry(editor) {
26869
+ const owner = docxViewerPageSurfaceRegistryOwner(editor);
26870
+ let registry = docxViewerPageSurfaceRegistryByEditor.get(owner);
26871
+ if (!registry) {
26872
+ registry = {
26873
+ pageElements: /* @__PURE__ */ new Map(),
26874
+ listeners: /* @__PURE__ */ new Set()
26875
+ };
26876
+ docxViewerPageSurfaceRegistryByEditor.set(owner, registry);
26877
+ }
26878
+ return registry;
26879
+ }
26880
+ function subscribeDocxViewerPageSurfaces(editor, listener) {
26881
+ const registry = ensureDocxViewerPageSurfaceRegistry(editor);
26882
+ registry.listeners.add(listener);
26883
+ return () => {
26884
+ registry.listeners.delete(listener);
26885
+ };
26886
+ }
26887
+ function notifyDocxViewerPageSurfaceSubscribers(registry) {
26888
+ registry.listeners.forEach((listener) => {
26889
+ listener();
26890
+ });
26891
+ }
26892
+ function registerDocxViewerPageSurface(editor, pageIndex, element) {
26893
+ const registry = ensureDocxViewerPageSurfaceRegistry(editor);
26894
+ const normalizedPageIndex = Math.max(0, Math.round(pageIndex));
26895
+ const currentElement = registry.pageElements.get(normalizedPageIndex);
26896
+ if (element) {
26897
+ if (currentElement === element) {
26898
+ return;
26899
+ }
26900
+ registry.pageElements.set(normalizedPageIndex, element);
26901
+ notifyDocxViewerPageSurfaceSubscribers(registry);
26902
+ return;
26903
+ }
26904
+ if (!currentElement) {
26905
+ return;
26906
+ }
26907
+ registry.pageElements.delete(normalizedPageIndex);
26908
+ notifyDocxViewerPageSurfaceSubscribers(registry);
26909
+ }
26910
+ function resolveDocxViewerPageSurfaceSize(element, fallbackWidthPx, fallbackHeightPx) {
26911
+ if (element) {
26912
+ const rect = element.getBoundingClientRect();
26913
+ const rectWidthPx = Number.isFinite(rect.width) ? rect.width : 0;
26914
+ const rectHeightPx = Number.isFinite(rect.height) ? rect.height : 0;
26915
+ const offsetWidthPx = Number.isFinite(element.offsetWidth) ? element.offsetWidth : 0;
26916
+ const offsetHeightPx = Number.isFinite(element.offsetHeight) ? element.offsetHeight : 0;
26917
+ const clientWidthPx = Number.isFinite(element.clientWidth) ? element.clientWidth : 0;
26918
+ const clientHeightPx = Number.isFinite(element.clientHeight) ? element.clientHeight : 0;
26919
+ const resolvedWidthPx = Math.max(
26920
+ 0,
26921
+ rectWidthPx,
26922
+ offsetWidthPx,
26923
+ clientWidthPx
26924
+ );
26925
+ const resolvedHeightPx = Math.max(
26926
+ 0,
26927
+ rectHeightPx,
26928
+ offsetHeightPx,
26929
+ clientHeightPx
26930
+ );
26931
+ if (resolvedWidthPx > 0 && resolvedHeightPx > 0) {
26932
+ return {
26933
+ widthPx: Math.round(resolvedWidthPx),
26934
+ heightPx: Math.round(resolvedHeightPx)
26935
+ };
26936
+ }
26937
+ }
26938
+ return {
26939
+ widthPx: Math.max(1, Math.round(fallbackWidthPx)),
26940
+ heightPx: Math.max(1, Math.round(fallbackHeightPx))
26941
+ };
26942
+ }
26943
+ async function rasterizeDocxViewerPageSurfaceToCanvas(params) {
26944
+ if (typeof window === "undefined" || typeof XMLSerializer === "undefined") {
26945
+ throw new Error("DOCX thumbnails require a browser environment.");
26946
+ }
26947
+ const {
26948
+ pageElement,
26949
+ sourceWidthPx,
26950
+ sourceHeightPx,
26951
+ canvas,
26952
+ widthPx,
26953
+ heightPx,
26954
+ pixelWidthPx,
26955
+ pixelHeightPx
26956
+ } = params;
26957
+ const safeSourceWidthPx = Math.max(1, Math.round(sourceWidthPx));
26958
+ const safeSourceHeightPx = Math.max(1, Math.round(sourceHeightPx));
26959
+ const scaleX = widthPx / safeSourceWidthPx;
26960
+ const scaleY = heightPx / safeSourceHeightPx;
26961
+ const serializedPage = new XMLSerializer().serializeToString(
26962
+ pageElement.cloneNode(true)
26963
+ );
26964
+ const svgMarkup = `
26965
+ <svg xmlns="http://www.w3.org/2000/svg" width="${widthPx}" height="${heightPx}" viewBox="0 0 ${widthPx} ${heightPx}">
26966
+ <foreignObject x="0" y="0" width="100%" height="100%">
26967
+ <div xmlns="http://www.w3.org/1999/xhtml" style="width:${widthPx}px;height:${heightPx}px;overflow:hidden;">
26968
+ <div style="width:${safeSourceWidthPx}px;height:${safeSourceHeightPx}px;transform-origin:top left;transform:scale(${scaleX}, ${scaleY});">
26969
+ ${serializedPage}
26970
+ </div>
26971
+ </div>
26972
+ </foreignObject>
26973
+ </svg>
26974
+ `;
26975
+ const blob = new Blob([svgMarkup], {
26976
+ type: "image/svg+xml;charset=utf-8"
26977
+ });
26978
+ const objectUrl = URL.createObjectURL(blob);
26979
+ try {
26980
+ const image = await new Promise((resolve, reject) => {
26981
+ const nextImage = new Image();
26982
+ nextImage.decoding = "async";
26983
+ nextImage.onload = () => resolve(nextImage);
26984
+ nextImage.onerror = () => {
26985
+ reject(new Error("Failed to rasterize DOCX page thumbnail."));
26986
+ };
26987
+ nextImage.src = objectUrl;
26988
+ });
26989
+ canvas.width = Math.max(1, Math.round(pixelWidthPx));
26990
+ canvas.height = Math.max(1, Math.round(pixelHeightPx));
26991
+ canvas.style.width = `${Math.max(1, Math.round(widthPx))}px`;
26992
+ canvas.style.height = `${Math.max(1, Math.round(heightPx))}px`;
26993
+ const context = canvas.getContext("2d");
26994
+ if (!context) {
26995
+ throw new Error("2D canvas context is unavailable for DOCX thumbnails.");
26996
+ }
26997
+ context.setTransform(1, 0, 0, 1, 0, 0);
26998
+ context.clearRect(0, 0, canvas.width, canvas.height);
26999
+ context.imageSmoothingEnabled = true;
27000
+ context.imageSmoothingQuality = "high";
27001
+ context.drawImage(image, 0, 0, canvas.width, canvas.height);
27002
+ } finally {
27003
+ URL.revokeObjectURL(objectUrl);
27004
+ }
27005
+ }
27006
+ function resolveDocxPageThumbnailResolution(options) {
27007
+ const safeSourceWidthPx = Math.max(1, Math.round(options.sourceWidthPx));
27008
+ const safeSourceHeightPx = Math.max(1, Math.round(options.sourceHeightPx));
27009
+ const widthBoundPx = Number.isFinite(options.maxWidthPx) ? Math.max(1, Math.round(options.maxWidthPx)) : 180;
27010
+ const heightBoundPx = Number.isFinite(options.maxHeightPx) ? Math.max(1, Math.round(options.maxHeightPx)) : Number.POSITIVE_INFINITY;
27011
+ const scale = Math.min(
27012
+ 1,
27013
+ widthBoundPx / safeSourceWidthPx,
27014
+ heightBoundPx / safeSourceHeightPx
27015
+ );
27016
+ const pixelRatio = Number.isFinite(options.pixelRatio) ? Math.max(1, Number(options.pixelRatio)) : 1;
27017
+ const widthPx = Math.max(1, Math.round(safeSourceWidthPx * scale));
27018
+ const heightPx = Math.max(1, Math.round(safeSourceHeightPx * scale));
27019
+ return {
27020
+ widthPx,
27021
+ heightPx,
27022
+ pixelWidthPx: Math.max(1, Math.round(widthPx * pixelRatio)),
27023
+ pixelHeightPx: Math.max(1, Math.round(heightPx * pixelRatio)),
27024
+ scale
27025
+ };
27026
+ }
27027
+ function useDocxPageThumbnails(editor, options = {}) {
27028
+ const pageSurfaceRegistryOwner = docxViewerPageSurfaceRegistryOwner(editor);
27029
+ const pageSurfaceRegistryEditor = React.useMemo(
27030
+ () => ({ syncPaginationInfo: editor.syncPaginationInfo }),
27031
+ [pageSurfaceRegistryOwner]
27032
+ );
27033
+ const [pageSurfaceEpoch, setPageSurfaceEpoch] = React.useState(0);
27034
+ const [pageThumbnailStates, setPageThumbnailStates] = React.useState(() => /* @__PURE__ */ new Map());
27035
+ const attachedCanvasByPageRef = React.useRef(
27036
+ /* @__PURE__ */ new Map()
27037
+ );
27038
+ const canvasRefCallbacksRef = React.useRef(/* @__PURE__ */ new Map());
27039
+ const renderToCanvasCallbacksRef = React.useRef(/* @__PURE__ */ new Map());
27040
+ const fallbackLayout = React.useMemo(
27041
+ () => resolveDocumentLayout(editor.model),
27042
+ [editor.model]
27043
+ );
27044
+ const pageSurfaceRegistry = React.useMemo(
27045
+ () => ensureDocxViewerPageSurfaceRegistry(pageSurfaceRegistryEditor),
27046
+ [pageSurfaceRegistryEditor]
27047
+ );
27048
+ React.useEffect(
27049
+ () => subscribeDocxViewerPageSurfaces(
27050
+ pageSurfaceRegistryEditor,
27051
+ () => {
27052
+ setPageSurfaceEpoch((current) => current + 1);
27053
+ }
27054
+ ),
27055
+ [pageSurfaceRegistryEditor]
27056
+ );
27057
+ const mountedPageElements = React.useMemo(
27058
+ () => new Map(pageSurfaceRegistry.pageElements),
27059
+ [pageSurfaceEpoch, pageSurfaceRegistry.pageElements]
27060
+ );
27061
+ const updatePageThumbnailState = React.useCallback(
27062
+ (pageIndex, status, error) => {
27063
+ setPageThumbnailStates((current) => {
27064
+ const next = new Map(current);
27065
+ const previous = next.get(pageIndex);
27066
+ if (previous?.status === status && previous?.error?.message === error?.message) {
27067
+ return current;
27068
+ }
27069
+ next.set(pageIndex, { status, error });
27070
+ return next;
27071
+ });
27072
+ },
27073
+ []
27074
+ );
27075
+ const renderPageThumbnailToCanvas = React.useCallback(
27076
+ async (pageIndex, canvas) => {
27077
+ if (options.disabled) {
27078
+ return;
27079
+ }
27080
+ const targetCanvas = canvas ?? attachedCanvasByPageRef.current.get(pageIndex);
27081
+ if (!targetCanvas) {
27082
+ return;
27083
+ }
27084
+ const pageElement = mountedPageElements.get(pageIndex);
27085
+ if (!pageElement || !pageElement.isConnected) {
27086
+ updatePageThumbnailState(pageIndex, "unavailable");
27087
+ return;
27088
+ }
27089
+ const sourceSize = resolveDocxViewerPageSurfaceSize(
27090
+ pageElement,
27091
+ fallbackLayout.pageWidthPx,
27092
+ fallbackLayout.pageHeightPx
27093
+ );
27094
+ const resolution = resolveDocxPageThumbnailResolution({
27095
+ sourceWidthPx: sourceSize.widthPx,
27096
+ sourceHeightPx: sourceSize.heightPx,
27097
+ maxWidthPx: options.maxWidthPx,
27098
+ maxHeightPx: options.maxHeightPx,
27099
+ pixelRatio: options.pixelRatio
27100
+ });
27101
+ updatePageThumbnailState(pageIndex, "rendering");
27102
+ try {
27103
+ await rasterizeDocxViewerPageSurfaceToCanvas({
27104
+ pageElement,
27105
+ sourceWidthPx: sourceSize.widthPx,
27106
+ sourceHeightPx: sourceSize.heightPx,
27107
+ canvas: targetCanvas,
27108
+ widthPx: resolution.widthPx,
27109
+ heightPx: resolution.heightPx,
27110
+ pixelWidthPx: resolution.pixelWidthPx,
27111
+ pixelHeightPx: resolution.pixelHeightPx
27112
+ });
27113
+ updatePageThumbnailState(pageIndex, "ready");
27114
+ } catch (error) {
27115
+ updatePageThumbnailState(
27116
+ pageIndex,
27117
+ "error",
27118
+ error instanceof Error ? error : new Error("Failed to render DOCX page thumbnail.")
27119
+ );
27120
+ }
27121
+ },
27122
+ [
27123
+ fallbackLayout.pageHeightPx,
27124
+ fallbackLayout.pageWidthPx,
27125
+ mountedPageElements,
27126
+ options.disabled,
27127
+ options.maxHeightPx,
27128
+ options.maxWidthPx,
27129
+ options.pixelRatio,
27130
+ updatePageThumbnailState
27131
+ ]
27132
+ );
27133
+ const rerenderAttachedThumbnails = React.useCallback(async () => {
27134
+ const tasks = [...attachedCanvasByPageRef.current.keys()].map(
27135
+ (pageIndex) => renderPageThumbnailToCanvas(pageIndex)
27136
+ );
27137
+ await Promise.all(tasks);
27138
+ }, [renderPageThumbnailToCanvas]);
27139
+ const renderPageThumbnailToCanvasRef = React.useRef(renderPageThumbnailToCanvas);
27140
+ React.useEffect(() => {
27141
+ renderPageThumbnailToCanvasRef.current = renderPageThumbnailToCanvas;
27142
+ }, [renderPageThumbnailToCanvas]);
27143
+ React.useEffect(() => {
27144
+ canvasRefCallbacksRef.current.clear();
27145
+ renderToCanvasCallbacksRef.current.clear();
27146
+ }, [pageSurfaceRegistryOwner]);
27147
+ React.useEffect(() => {
27148
+ void rerenderAttachedThumbnails();
27149
+ }, [
27150
+ editor.documentLoadNonce,
27151
+ editor.documentTheme,
27152
+ editor.model,
27153
+ mountedPageElements,
27154
+ options.disabled,
27155
+ options.maxHeightPx,
27156
+ options.maxWidthPx,
27157
+ options.pixelRatio,
27158
+ rerenderAttachedThumbnails
27159
+ ]);
27160
+ const thumbnails = React.useMemo(() => {
27161
+ const totalPages = Math.max(1, editor.totalPages);
27162
+ return Array.from({ length: totalPages }, (_, pageIndex) => {
27163
+ const pageElement = mountedPageElements.get(pageIndex);
27164
+ const sourceSize = resolveDocxViewerPageSurfaceSize(
27165
+ pageElement,
27166
+ fallbackLayout.pageWidthPx,
27167
+ fallbackLayout.pageHeightPx
27168
+ );
27169
+ const resolution = resolveDocxPageThumbnailResolution({
27170
+ sourceWidthPx: sourceSize.widthPx,
27171
+ sourceHeightPx: sourceSize.heightPx,
27172
+ maxWidthPx: options.maxWidthPx,
27173
+ maxHeightPx: options.maxHeightPx,
27174
+ pixelRatio: options.pixelRatio
27175
+ });
27176
+ const state = pageThumbnailStates.get(pageIndex);
27177
+ return {
27178
+ pageIndex,
27179
+ pageNumber: pageIndex + 1,
27180
+ sourceWidthPx: sourceSize.widthPx,
27181
+ sourceHeightPx: sourceSize.heightPx,
27182
+ isMounted: Boolean(pageElement && pageElement.isConnected),
27183
+ status: state?.status ?? (pageElement ? "idle" : "unavailable"),
27184
+ error: state?.error,
27185
+ canvasRef: canvasRefCallbacksRef.current.get(pageIndex) ?? (() => {
27186
+ const nextCanvasRef = (canvas) => {
27187
+ if (canvas) {
27188
+ attachedCanvasByPageRef.current.set(pageIndex, canvas);
27189
+ void renderPageThumbnailToCanvasRef.current(pageIndex, canvas);
27190
+ return;
27191
+ }
27192
+ attachedCanvasByPageRef.current.delete(pageIndex);
27193
+ };
27194
+ canvasRefCallbacksRef.current.set(pageIndex, nextCanvasRef);
27195
+ return nextCanvasRef;
27196
+ })(),
27197
+ renderToCanvas: renderToCanvasCallbacksRef.current.get(pageIndex) ?? (() => {
27198
+ const nextRenderToCanvas = async (canvas) => {
27199
+ await renderPageThumbnailToCanvasRef.current(pageIndex, canvas);
27200
+ };
27201
+ renderToCanvasCallbacksRef.current.set(
27202
+ pageIndex,
27203
+ nextRenderToCanvas
27204
+ );
27205
+ return nextRenderToCanvas;
27206
+ })(),
27207
+ ...resolution
27208
+ };
27209
+ });
27210
+ }, [
27211
+ editor.totalPages,
27212
+ fallbackLayout.pageHeightPx,
27213
+ fallbackLayout.pageWidthPx,
27214
+ mountedPageElements,
27215
+ options.maxHeightPx,
27216
+ options.maxWidthPx,
27217
+ options.pixelRatio,
27218
+ pageThumbnailStates
27219
+ ]);
27220
+ return React.useMemo(
27221
+ () => ({
27222
+ thumbnails,
27223
+ rerenderAttachedThumbnails
27224
+ }),
27225
+ [rerenderAttachedThumbnails, thumbnails]
27226
+ );
27227
+ }
26830
27228
  function useDocxDocumentTheme(editor) {
26831
27229
  const setDocumentTheme = React.useCallback(
26832
27230
  (theme) => {
@@ -27888,6 +28286,7 @@ function DocxEditorViewer({
27888
28286
  editor,
27889
28287
  className,
27890
28288
  style,
28289
+ pageBackgroundColor,
27891
28290
  pageGapBackgroundColor,
27892
28291
  deferInitialPaginationPaint = true,
27893
28292
  loadingState,
@@ -27903,10 +28302,14 @@ function DocxEditorViewer({
27903
28302
  onFormFieldDoubleClick,
27904
28303
  mode = "edit"
27905
28304
  }) {
28305
+ const pageSurfaceRegistryOwner = docxViewerPageSurfaceRegistryOwner(editor);
27906
28306
  const trackedChangesEnabled = showTrackedChanges ?? editor.showTrackedChanges;
27907
28307
  const hasTrackedChanges = editor.trackedChanges.length > 0;
27908
28308
  const showTrackedChangeGutter = trackedChangesEnabled;
27909
28309
  const isReadOnly = mode === "read-only" || trackedChangesEnabled;
28310
+ const isNightReaderMode = isReadOnly && editor.documentTheme === "dark";
28311
+ const documentContentTheme = isNightReaderMode ? "light" : editor.documentTheme;
28312
+ const documentContentFilter = isNightReaderMode ? NIGHT_READER_INVERSION_FILTER : void 0;
27910
28313
  const canReplaceDocumentByDrop = mode !== "read-only";
27911
28314
  const formFieldLocationKey = React.useCallback(
27912
28315
  (location) => {
@@ -27922,9 +28325,11 @@ function DocxEditorViewer({
27922
28325
  () => ({
27923
28326
  showTrackedChanges: trackedChangesEnabled,
27924
28327
  numberingDefinitions: editor.model.metadata.numberingDefinitions,
27925
- tocLinkColorByLevel
28328
+ tocLinkColorByLevel,
28329
+ imageFilterSuffix: documentContentFilter
27926
28330
  }),
27927
28331
  [
28332
+ documentContentFilter,
27928
28333
  editor.model.metadata.numberingDefinitions,
27929
28334
  tocLinkColorByLevel,
27930
28335
  trackedChangesEnabled
@@ -27962,6 +28367,8 @@ function DocxEditorViewer({
27962
28367
  /* @__PURE__ */ new Map()
27963
28368
  );
27964
28369
  const pageElementsRef = React.useRef(/* @__PURE__ */ new Map());
28370
+ const pagePlaceholderRefCallbacksRef = React.useRef(/* @__PURE__ */ new Map());
28371
+ const pageSurfaceRefCallbacksRef = React.useRef(/* @__PURE__ */ new Map());
27965
28372
  const trackedChangeCardElementsRef = React.useRef(/* @__PURE__ */ new Map());
27966
28373
  const initialPaginationStableSignatureRef = React.useRef(
27967
28374
  void 0
@@ -28026,6 +28433,54 @@ function DocxEditorViewer({
28026
28433
  measuredPageContentHeightByIndex,
28027
28434
  setMeasuredPageContentHeightByIndex
28028
28435
  ] = React.useState([]);
28436
+ const pagePlaceholderRefForIndex = React.useCallback(
28437
+ (pageIndex) => {
28438
+ const normalizedPageIndex = Math.max(0, Math.round(pageIndex));
28439
+ const cached = pagePlaceholderRefCallbacksRef.current.get(normalizedPageIndex);
28440
+ if (cached) {
28441
+ return cached;
28442
+ }
28443
+ const nextRef = (element) => {
28444
+ if (element) {
28445
+ pageElementsRef.current.set(normalizedPageIndex, element);
28446
+ } else {
28447
+ pageElementsRef.current.delete(normalizedPageIndex);
28448
+ }
28449
+ registerDocxViewerPageSurface(editor, normalizedPageIndex, void 0);
28450
+ };
28451
+ pagePlaceholderRefCallbacksRef.current.set(normalizedPageIndex, nextRef);
28452
+ return nextRef;
28453
+ },
28454
+ [pageSurfaceRegistryOwner]
28455
+ );
28456
+ const pageSurfaceRefForIndex = React.useCallback(
28457
+ (pageIndex) => {
28458
+ const normalizedPageIndex = Math.max(0, Math.round(pageIndex));
28459
+ const cached = pageSurfaceRefCallbacksRef.current.get(normalizedPageIndex);
28460
+ if (cached) {
28461
+ return cached;
28462
+ }
28463
+ const nextRef = (element) => {
28464
+ if (element) {
28465
+ pageElementsRef.current.set(normalizedPageIndex, element);
28466
+ } else {
28467
+ pageElementsRef.current.delete(normalizedPageIndex);
28468
+ }
28469
+ registerDocxViewerPageSurface(editor, normalizedPageIndex, element);
28470
+ };
28471
+ pageSurfaceRefCallbacksRef.current.set(normalizedPageIndex, nextRef);
28472
+ return nextRef;
28473
+ },
28474
+ [pageSurfaceRegistryOwner]
28475
+ );
28476
+ React.useEffect(() => {
28477
+ pagePlaceholderRefCallbacksRef.current.clear();
28478
+ pageSurfaceRefCallbacksRef.current.clear();
28479
+ }, [pageSurfaceRegistryOwner]);
28480
+ const [
28481
+ measuredPageContentIdentityKeysByIndex,
28482
+ setMeasuredPageContentIdentityKeysByIndex
28483
+ ] = React.useState([]);
28029
28484
  const [, setRenderableImageSourceRevision] = React.useState(0);
28030
28485
  const [activeEditableParagraphSegment, setActiveEditableParagraphSegment] = React.useState(void 0);
28031
28486
  const wrappedParagraphTextareaRef = React.useRef(
@@ -28075,6 +28530,7 @@ function DocxEditorViewer({
28075
28530
  }, []);
28076
28531
  React.useEffect(() => {
28077
28532
  setMeasuredPageContentHeightByIndex([]);
28533
+ setMeasuredPageContentIdentityKeysByIndex([]);
28078
28534
  setTableMeasuredRowHeights({});
28079
28535
  setTableRowHeights({});
28080
28536
  setTableColumnWidths({});
@@ -28469,7 +28925,7 @@ function DocxEditorViewer({
28469
28925
  tableDraftLayoutEpoch,
28470
28926
  tableMeasuredRowHeights
28471
28927
  ]);
28472
- const pageNodeSegmentsByPage = React.useMemo(() => {
28928
+ const pageSegmentationPlan = React.useMemo(() => {
28473
28929
  const pageContentHeightPx = Math.max(
28474
28930
  120,
28475
28931
  documentLayout.pageHeightPx - documentLayout.marginsPx.top - documentLayout.marginsPx.bottom
@@ -28480,6 +28936,7 @@ function DocxEditorViewer({
28480
28936
  );
28481
28937
  const suppressSpacingBeforeAfterPageBreak = editor.model.metadata.compatibility?.suppressSpacingBeforeAfterPageBreak === true;
28482
28938
  const preferLastRenderedParagraphStartBreaks = !editor.canUndo && !editor.canRedo;
28939
+ const canUseMeasuredPageContentHeights = !editor.canUndo && !editor.canRedo && !disableMeasuredImportPagination && !floatingMovePreview && !dropCapMovePreview && (measuredPageContentHeightByIndex?.length ?? 0) > 0;
28483
28940
  const buildEstimatedPages = (measuredTableRowHeightsByNodeIndex, measuredPageContentHeightsOverride) => {
28484
28941
  const allowMeasuredPageContentHeights = !editor.canUndo && !editor.canRedo && !disableMeasuredImportPagination && !floatingMovePreview && !dropCapMovePreview;
28485
28942
  const baseMeasuredHeights = !allowMeasuredPageContentHeights || measuredPageContentHeightsOverride === null ? void 0 : measuredPageContentHeightsOverride ?? measuredPageContentHeightByIndex;
@@ -28525,14 +28982,13 @@ function DocxEditorViewer({
28525
28982
  minimumPageCount,
28526
28983
  Math.round(storedDocumentPageCount2)
28527
28984
  ) : void 0;
28528
- let estimatedPages = buildEstimatedPages(
28529
- tableMeasuredRowHeightsForPagination
28985
+ const pureEstimatedPages = buildEstimatedPages(
28986
+ tableMeasuredRowHeightsForPagination,
28987
+ null
28530
28988
  );
28989
+ let estimatedPages = buildEstimatedPages(tableMeasuredRowHeightsForPagination);
28990
+ let estimatedPagesUseMeasuredPageContentHeightsForRender = canUseMeasuredPageContentHeights;
28531
28991
  if (measuredPageContentHeightByIndex && measuredPageContentHeightByIndex.length > 0) {
28532
- const pureEstimatedPages = buildEstimatedPages(
28533
- tableMeasuredRowHeightsForPagination,
28534
- null
28535
- );
28536
28992
  const measuredPagesAreOnlySplitParagraphs = estimatedPages.length > 0 && estimatedPages.every(
28537
28993
  (pageSegments) => documentPageContainsOnlySplitParagraphSegments(pageSegments)
28538
28994
  );
@@ -28541,25 +28997,38 @@ function DocxEditorViewer({
28541
28997
  );
28542
28998
  if (measuredPagesAreOnlySplitParagraphs && purePagesAreOnlySplitParagraphs && pureEstimatedPages.length < estimatedPages.length) {
28543
28999
  estimatedPages = pureEstimatedPages;
29000
+ estimatedPagesUseMeasuredPageContentHeightsForRender = false;
28544
29001
  }
28545
29002
  }
28546
29003
  if (!editor.canUndo && !editor.canRedo && targetPageCount !== void 0 && tableMeasuredRowHeightsForPagination) {
28547
29004
  const candidatePages = [
28548
- estimatedPages,
28549
- buildEstimatedPages(void 0),
28550
- buildEstimatedPages(void 0, null)
29005
+ {
29006
+ pages: estimatedPages,
29007
+ useMeasuredPageContentHeightsForRender: estimatedPagesUseMeasuredPageContentHeightsForRender
29008
+ },
29009
+ {
29010
+ pages: buildEstimatedPages(void 0),
29011
+ useMeasuredPageContentHeightsForRender: canUseMeasuredPageContentHeights
29012
+ },
29013
+ {
29014
+ pages: buildEstimatedPages(void 0, null),
29015
+ useMeasuredPageContentHeightsForRender: false
29016
+ }
28551
29017
  ];
28552
- estimatedPages = candidatePages.reduce((bestCandidate, candidate) => {
28553
- const bestDifference = Math.abs(bestCandidate.length - targetPageCount);
29018
+ const bestCandidate = candidatePages.reduce((best, candidate) => {
29019
+ const bestDifference = Math.abs(best.pages.length - targetPageCount);
28554
29020
  const candidateDifference = Math.abs(
28555
- candidate.length - targetPageCount
29021
+ candidate.pages.length - targetPageCount
28556
29022
  );
28557
- return candidateDifference < bestDifference ? candidate : bestCandidate;
29023
+ return candidateDifference < bestDifference ? candidate : best;
28558
29024
  });
29025
+ estimatedPages = bestCandidate.pages;
29026
+ estimatedPagesUseMeasuredPageContentHeightsForRender = bestCandidate.useMeasuredPageContentHeightsForRender;
28559
29027
  } else if (!editor.canUndo && !editor.canRedo && targetPageCount !== void 0) {
28560
- const pureEstimatedPages = buildEstimatedPages(void 0, null);
28561
- if (Math.abs(pureEstimatedPages.length - targetPageCount) < Math.abs(estimatedPages.length - targetPageCount)) {
28562
- estimatedPages = pureEstimatedPages;
29028
+ const pureEstimatedPages2 = buildEstimatedPages(void 0, null);
29029
+ if (Math.abs(pureEstimatedPages2.length - targetPageCount) < Math.abs(estimatedPages.length - targetPageCount)) {
29030
+ estimatedPages = pureEstimatedPages2;
29031
+ estimatedPagesUseMeasuredPageContentHeightsForRender = false;
28563
29032
  }
28564
29033
  }
28565
29034
  const measuredPageHeightOverridesReduceContent = !editor.canUndo && !editor.canRedo && !floatingMovePreview && !dropCapMovePreview && estimatedPages.some((segments, pageIndex) => {
@@ -28584,7 +29053,10 @@ function DocxEditorViewer({
28584
29053
  )
28585
29054
  );
28586
29055
  if (!Number.isFinite(storedDocumentPageCount2) || storedDocumentPageCount2 <= 0) {
28587
- return estimatedPages;
29056
+ return {
29057
+ pages: estimatedPages,
29058
+ useMeasuredPageContentHeightsForRender: estimatedPagesUseMeasuredPageContentHeightsForRender
29059
+ };
28588
29060
  }
28589
29061
  const resolvedTargetPageCount = targetPageCount ?? minimumPageCount;
28590
29062
  const hasTableInternalPageBreaks = editor.model.nodes.some(
@@ -28600,10 +29072,16 @@ function DocxEditorViewer({
28600
29072
  renderedBreakHintPageCount
28601
29073
  }) && (!measuredPageHeightOverridesReduceContent || allowMeasuredReductionOverPaginationReconciliation);
28602
29074
  if (!allowStoredPageCountReconciliation) {
28603
- return estimatedPages;
29075
+ return {
29076
+ pages: estimatedPages,
29077
+ useMeasuredPageContentHeightsForRender: estimatedPagesUseMeasuredPageContentHeightsForRender
29078
+ };
28604
29079
  }
28605
29080
  if (estimatedPages.length === resolvedTargetPageCount) {
28606
- return estimatedPages;
29081
+ return {
29082
+ pages: estimatedPages,
29083
+ useMeasuredPageContentHeightsForRender: estimatedPagesUseMeasuredPageContentHeightsForRender
29084
+ };
28607
29085
  }
28608
29086
  const reconciliationScales = allowMeasuredReductionOverPaginationReconciliation ? [
28609
29087
  1.02,
@@ -28651,20 +29129,25 @@ function DocxEditorViewer({
28651
29129
  let reconciledPages = reconcileCandidatePages(
28652
29130
  estimatedPages,
28653
29131
  tableMeasuredRowHeightsForPagination,
28654
- measuredPageContentHeightByIndex
29132
+ estimatedPagesUseMeasuredPageContentHeightsForRender ? measuredPageContentHeightByIndex : null
28655
29133
  );
29134
+ let reconciledPagesUseMeasuredPageContentHeightsForRender = estimatedPagesUseMeasuredPageContentHeightsForRender;
28656
29135
  if (!editor.canUndo && !editor.canRedo) {
28657
- const pureEstimatedPages = buildEstimatedPages(void 0, null);
29136
+ const pureEstimatedPages2 = buildEstimatedPages(void 0, null);
28658
29137
  const pureReconciledPages = reconcileCandidatePages(
28659
- pureEstimatedPages,
29138
+ pureEstimatedPages2,
28660
29139
  void 0,
28661
29140
  null
28662
29141
  );
28663
29142
  if (Math.abs(pureReconciledPages.length - resolvedTargetPageCount) < Math.abs(reconciledPages.length - resolvedTargetPageCount)) {
28664
29143
  reconciledPages = pureReconciledPages;
29144
+ reconciledPagesUseMeasuredPageContentHeightsForRender = false;
28665
29145
  }
28666
29146
  }
28667
- return reconciledPages;
29147
+ return {
29148
+ pages: reconciledPages,
29149
+ useMeasuredPageContentHeightsForRender: reconciledPagesUseMeasuredPageContentHeightsForRender
29150
+ };
28668
29151
  }, [
28669
29152
  editor.canRedo,
28670
29153
  editor.canUndo,
@@ -28686,6 +29169,14 @@ function DocxEditorViewer({
28686
29169
  measuredPageContentHeightByIndex,
28687
29170
  tableMeasuredRowHeightsForPagination
28688
29171
  ]);
29172
+ const pageNodeSegmentsByPage = pageSegmentationPlan.pages;
29173
+ const useMeasuredPageContentHeightsForRender = pageSegmentationPlan.useMeasuredPageContentHeightsForRender;
29174
+ const pageNodeSegmentIdentityKeysByPage = React.useMemo(
29175
+ () => pageNodeSegmentsByPage.map(
29176
+ (pageSegments) => documentPageNodeSegmentsIdentityKey(pageSegments)
29177
+ ),
29178
+ [pageNodeSegmentsByPage]
29179
+ );
28689
29180
  const pageIndexByNodeIndex = React.useMemo(() => {
28690
29181
  const indexByNode = /* @__PURE__ */ new Map();
28691
29182
  pageNodeSegmentsByPage.forEach((segments, pageIndex) => {
@@ -29711,6 +30202,9 @@ function DocxEditorViewer({
29711
30202
  setMeasuredPageContentHeightByIndex(
29712
30203
  (current) => current.length === 0 ? current : []
29713
30204
  );
30205
+ setMeasuredPageContentIdentityKeysByIndex(
30206
+ (current) => current.length === 0 ? current : []
30207
+ );
29714
30208
  return;
29715
30209
  }
29716
30210
  if (!paginationMeasurementEnabled) {
@@ -29721,124 +30215,140 @@ function DocxEditorViewer({
29721
30215
  setMeasuredPageContentHeightByIndex(
29722
30216
  (current) => current.length === 0 ? current : []
29723
30217
  );
30218
+ setMeasuredPageContentIdentityKeysByIndex(
30219
+ (current) => current.length === 0 ? current : []
30220
+ );
29724
30221
  return;
29725
30222
  }
29726
30223
  if (Date.now() < paginationMeasurementSuspendUntilRef.current) {
29727
30224
  return;
29728
30225
  }
29729
30226
  const zoomScale = resolveEffectiveZoomScale(rootElement);
29730
- const nextMeasuredHeights = pageNodeSegmentsByPage.map((_, pageIndex) => {
29731
- const pageLayout = pageSectionInfoByIndex[pageIndex]?.layout ?? documentLayout;
29732
- const pageElement = pageElementsRef.current.get(pageIndex);
29733
- const fallbackHeightPx = Math.max(
29734
- 120,
29735
- pageLayout.pageHeightPx - pageLayout.marginsPx.top - pageLayout.marginsPx.bottom
29736
- );
29737
- if (!pageElement) {
29738
- return fallbackHeightPx;
29739
- }
29740
- const headerElement = pageHeaderElementsRef.current.get(pageIndex);
29741
- const bodyElement = pageBodyElementsRef.current.get(pageIndex);
29742
- const footerElement = pageFooterElementsRef.current.get(pageIndex);
29743
- const headerHeightPx = headerElement ? Math.max(
29744
- 0,
29745
- Math.round(headerElement.getBoundingClientRect().height / zoomScale)
29746
- ) : 0;
29747
- const docxFooterTopPx = resolveFooterNodesFloatingBoundaryTopPx(
29748
- pageHeaderAndFooterNodes[pageIndex]?.footerNodes ?? [],
29749
- pageLayout
29750
- );
29751
- let footerTopPx = Number.isFinite(docxFooterTopPx) ? Math.round(docxFooterTopPx) : void 0;
29752
- if (footerElement) {
29753
- const pageRect2 = pageElement.getBoundingClientRect();
29754
- const maxOverflowCapPx = Math.max(
29755
- 16,
29756
- Math.min(
29757
- Math.round(pageLayout.pageHeightPx * 0.12),
29758
- Math.round(
29759
- pageLayout.marginsPx.bottom + pageLayout.footerDistancePx + 24
29760
- )
29761
- )
30227
+ const nextMeasuredPageIdentityKeys = pageNodeSegmentIdentityKeysByPage;
30228
+ const nextMeasuredPageDiagnostics = pageNodeSegmentsByPage.map(
30229
+ (_, pageIndex) => {
30230
+ const pageLayout = pageSectionInfoByIndex[pageIndex]?.layout ?? documentLayout;
30231
+ const pageElement = pageElementsRef.current.get(pageIndex);
30232
+ const fallbackHeightPx = Math.max(
30233
+ 120,
30234
+ pageLayout.pageHeightPx - pageLayout.marginsPx.top - pageLayout.marginsPx.bottom
29762
30235
  );
29763
- const footerFlowBoundaryTopPx = Math.max(
30236
+ if (!pageElement) {
30237
+ return {
30238
+ heightPx: fallbackHeightPx,
30239
+ bodyOverrunsFooter: false
30240
+ };
30241
+ }
30242
+ const headerElement = pageHeaderElementsRef.current.get(pageIndex);
30243
+ const bodyElement = pageBodyElementsRef.current.get(pageIndex);
30244
+ const footerElement = pageFooterElementsRef.current.get(pageIndex);
30245
+ const headerHeightPx = headerElement ? Math.max(
29764
30246
  0,
29765
- pageLayout.pageHeightPx - Math.max(0, pageLayout.footerDistancePx)
30247
+ Math.round(headerElement.getBoundingClientRect().height / zoomScale)
30248
+ ) : 0;
30249
+ const docxFooterTopPx = resolveFooterNodesFloatingBoundaryTopPx(
30250
+ pageHeaderAndFooterNodes[pageIndex]?.footerNodes ?? [],
30251
+ pageLayout
29766
30252
  );
29767
- const minimumRelevantFooterTopPx = Number.isFinite(docxFooterTopPx) ? Math.max(
30253
+ let footerTopPx = Number.isFinite(docxFooterTopPx) ? Math.round(docxFooterTopPx) : void 0;
30254
+ if (footerElement) {
30255
+ const pageRect2 = pageElement.getBoundingClientRect();
30256
+ const maxOverflowCapPx = Math.max(
30257
+ 16,
30258
+ Math.min(
30259
+ Math.round(pageLayout.pageHeightPx * 0.12),
30260
+ Math.round(
30261
+ pageLayout.marginsPx.bottom + pageLayout.footerDistancePx + 24
30262
+ )
30263
+ )
30264
+ );
30265
+ const footerFlowBoundaryTopPx = Math.max(
30266
+ 0,
30267
+ pageLayout.pageHeightPx - Math.max(0, pageLayout.footerDistancePx)
30268
+ );
30269
+ const minimumRelevantFooterTopPx = Number.isFinite(docxFooterTopPx) ? Math.max(
30270
+ 0,
30271
+ Math.min(
30272
+ Math.max(0, footerFlowBoundaryTopPx - maxOverflowCapPx),
30273
+ Math.round(docxFooterTopPx - maxOverflowCapPx)
30274
+ )
30275
+ ) : Math.max(0, footerFlowBoundaryTopPx - maxOverflowCapPx);
30276
+ let visualTop = Number.POSITIVE_INFINITY;
30277
+ footerElement.querySelectorAll("*").forEach((element) => {
30278
+ if (!element.isConnected) {
30279
+ return;
30280
+ }
30281
+ const rect = element.getBoundingClientRect();
30282
+ if (rect.width <= 0 && rect.height <= 0) {
30283
+ return;
30284
+ }
30285
+ const relativeTopPx = (rect.top - pageRect2.top) / zoomScale;
30286
+ if (relativeTopPx < minimumRelevantFooterTopPx - 1) {
30287
+ return;
30288
+ }
30289
+ visualTop = Math.min(visualTop, rect.top);
30290
+ });
30291
+ if (Number.isFinite(visualTop)) {
30292
+ const measuredFooterTopPx = (visualTop - pageRect2.top) / zoomScale;
30293
+ footerTopPx = Number.isFinite(footerTopPx) ? Math.min(
30294
+ Math.round(footerTopPx),
30295
+ Math.round(measuredFooterTopPx)
30296
+ ) : Math.round(measuredFooterTopPx);
30297
+ }
30298
+ }
30299
+ const pageRect = pageElement.getBoundingClientRect();
30300
+ const bodyRect = bodyElement?.getBoundingClientRect();
30301
+ const bodyTopPx = bodyRect ? Math.max(0, Math.round((bodyRect.top - pageRect.top) / zoomScale)) : void 0;
30302
+ const bodyImageCount = bodyElement?.querySelectorAll("[data-docx-image-location]").length ?? 0;
30303
+ const bodyTextTrimmedLength = bodyElement?.textContent?.replace(/\s+/g, "").length ?? 0;
30304
+ const skipBodyBottomAdjustment = bodyImageCount > 0 && bodyTextTrimmedLength === 0;
30305
+ const visualBodyBottom = bodyElement && bodyRect ? resolveMeasuredBodyRenderedBottomPx(
30306
+ Array.from(bodyElement.querySelectorAll("*")).map(
30307
+ (element) => {
30308
+ const rect = element.getBoundingClientRect();
30309
+ return {
30310
+ bottomPx: rect.bottom,
30311
+ widthPx: rect.width,
30312
+ heightPx: rect.height,
30313
+ ignore: !element.isConnected || Boolean(element.closest("[data-docx-image-location]")) || Boolean(
30314
+ element.closest(
30315
+ `[${PAGE_CONTENT_MEASUREMENT_IGNORE_ATTRIBUTE}="true"]`
30316
+ )
30317
+ )
30318
+ };
30319
+ }
30320
+ )
30321
+ ) : void 0;
30322
+ const bodyRenderedBottomPx = bodyRect && Number.isFinite(visualBodyBottom) ? Math.max(
29768
30323
  0,
29769
- Math.min(
29770
- Math.max(0, footerFlowBoundaryTopPx - maxOverflowCapPx),
29771
- Math.round(docxFooterTopPx - maxOverflowCapPx)
30324
+ Math.round(
30325
+ (visualBodyBottom - pageRect.top) / zoomScale
29772
30326
  )
29773
- ) : Math.max(0, footerFlowBoundaryTopPx - maxOverflowCapPx);
29774
- let visualTop = Number.POSITIVE_INFINITY;
29775
- footerElement.querySelectorAll("*").forEach((element) => {
29776
- if (!element.isConnected) {
29777
- return;
29778
- }
29779
- const rect = element.getBoundingClientRect();
29780
- if (rect.width <= 0 && rect.height <= 0) {
29781
- return;
29782
- }
29783
- const relativeTopPx = (rect.top - pageRect2.top) / zoomScale;
29784
- if (relativeTopPx < minimumRelevantFooterTopPx - 1) {
29785
- return;
29786
- }
29787
- visualTop = Math.min(visualTop, rect.top);
30327
+ ) : void 0;
30328
+ return resolveMeasuredPageContentHeightDiagnostics({
30329
+ pageLayout,
30330
+ fallbackHeightPx,
30331
+ headerHeightPx,
30332
+ currentMeasuredHeightPx: measuredPageContentHeightByIndex?.[pageIndex],
30333
+ bodyTopPx,
30334
+ bodyRenderedBottomPx,
30335
+ footerTopPx,
30336
+ skipBodyBottomAdjustment
29788
30337
  });
29789
- if (Number.isFinite(visualTop)) {
29790
- const measuredFooterTopPx = (visualTop - pageRect2.top) / zoomScale;
29791
- footerTopPx = Number.isFinite(footerTopPx) ? Math.min(
29792
- Math.round(footerTopPx),
29793
- Math.round(measuredFooterTopPx)
29794
- ) : Math.round(measuredFooterTopPx);
29795
- }
29796
30338
  }
29797
- const pageRect = pageElement.getBoundingClientRect();
29798
- const bodyRect = bodyElement?.getBoundingClientRect();
29799
- const bodyTopPx = bodyRect ? Math.max(0, Math.round((bodyRect.top - pageRect.top) / zoomScale)) : void 0;
29800
- const bodyImageCount = bodyElement?.querySelectorAll("[data-docx-image-location]").length ?? 0;
29801
- const bodyTextTrimmedLength = bodyElement?.textContent?.replace(/\s+/g, "").length ?? 0;
29802
- const skipBodyBottomAdjustment = bodyImageCount > 0 && bodyTextTrimmedLength === 0;
29803
- const visualBodyBottom = bodyElement && bodyRect ? resolveMeasuredBodyRenderedBottomPx(
29804
- Array.from(bodyElement.querySelectorAll("*")).map(
29805
- (element) => {
29806
- const rect = element.getBoundingClientRect();
29807
- return {
29808
- bottomPx: rect.bottom,
29809
- widthPx: rect.width,
29810
- heightPx: rect.height,
29811
- ignore: !element.isConnected || Boolean(element.closest("[data-docx-image-location]")) || Boolean(
29812
- element.closest(
29813
- `[${PAGE_CONTENT_MEASUREMENT_IGNORE_ATTRIBUTE}="true"]`
29814
- )
29815
- )
29816
- };
29817
- }
29818
- )
29819
- ) : void 0;
29820
- const bodyRenderedBottomPx = bodyRect && Number.isFinite(visualBodyBottom) ? Math.max(
29821
- 0,
29822
- Math.round(
29823
- (visualBodyBottom - pageRect.top) / zoomScale
29824
- )
29825
- ) : void 0;
29826
- return resolveMeasuredPageContentHeightPx({
29827
- pageLayout,
29828
- fallbackHeightPx,
29829
- headerHeightPx,
29830
- currentMeasuredHeightPx: measuredPageContentHeightByIndex?.[pageIndex],
29831
- bodyTopPx,
29832
- bodyRenderedBottomPx,
29833
- footerTopPx,
29834
- skipBodyBottomAdjustment
29835
- });
29836
- });
30339
+ );
30340
+ const nextMeasuredHeights = nextMeasuredPageDiagnostics.map(
30341
+ (diagnostics) => diagnostics.heightPx
30342
+ );
29837
30343
  const frameId = window.requestAnimationFrame(() => {
29838
30344
  setMeasuredPageContentHeightByIndex((current) => {
29839
30345
  const stabilizedHeights = stabilizeMeasuredPageContentHeights(
29840
30346
  current,
29841
- nextMeasuredHeights
30347
+ nextMeasuredHeights,
30348
+ {
30349
+ currentPageIdentityKeys: measuredPageContentIdentityKeysByIndex,
30350
+ nextPageIdentityKeys: nextMeasuredPageIdentityKeys
30351
+ }
29842
30352
  );
29843
30353
  if (current.length === stabilizedHeights.length) {
29844
30354
  let equal = true;
@@ -29856,6 +30366,21 @@ function DocxEditorViewer({
29856
30366
  }
29857
30367
  return stabilizedHeights;
29858
30368
  });
30369
+ setMeasuredPageContentIdentityKeysByIndex((current) => {
30370
+ if (current.length === nextMeasuredPageIdentityKeys.length) {
30371
+ let equal = true;
30372
+ for (let pageIndex = 0; pageIndex < nextMeasuredPageIdentityKeys.length; pageIndex += 1) {
30373
+ if (current[pageIndex] !== nextMeasuredPageIdentityKeys[pageIndex]) {
30374
+ equal = false;
30375
+ break;
30376
+ }
30377
+ }
30378
+ if (equal) {
30379
+ return current;
30380
+ }
30381
+ }
30382
+ return nextMeasuredPageIdentityKeys;
30383
+ });
29859
30384
  });
29860
30385
  return () => {
29861
30386
  window.cancelAnimationFrame(frameId);
@@ -29864,10 +30389,12 @@ function DocxEditorViewer({
29864
30389
  disableMeasuredImportPagination,
29865
30390
  documentLayout,
29866
30391
  measuredPageContentHeightByIndex,
30392
+ measuredPageContentIdentityKeysByIndex,
29867
30393
  paginationMeasurementEnabled,
29868
30394
  paginationMeasurementEpoch,
29869
30395
  pageCount,
29870
30396
  pageNodeSegmentsByPage,
30397
+ pageNodeSegmentIdentityKeysByPage,
29871
30398
  pageSectionInfoByIndex,
29872
30399
  pageHeaderAndFooterNodes
29873
30400
  ]);
@@ -35700,7 +36227,10 @@ function DocxEditorViewer({
35700
36227
  height: run.image.heightPx ? `${run.image.heightPx}px` : void 0,
35701
36228
  verticalAlign: "middle",
35702
36229
  display: "inline-block",
35703
- filter: run.image.cssFilter,
36230
+ filter: appendCssFilters(
36231
+ run.image.cssFilter,
36232
+ documentContentFilter
36233
+ ),
35704
36234
  opacity: run.image.cssOpacity
35705
36235
  }
35706
36236
  },
@@ -35711,14 +36241,15 @@ function DocxEditorViewer({
35711
36241
  overlapStart - run.startOffset,
35712
36242
  overlapEnd - run.startOffset
35713
36243
  );
35714
- if (!slice) {
36244
+ const renderedSlice = sanitizeRenderedPretextFragmentText(slice);
36245
+ if (!renderedSlice) {
35715
36246
  return void 0;
35716
36247
  }
35717
36248
  const textStyle = run.link ? {
35718
- ...linkStyleToCss(run.style, editor.documentTheme),
36249
+ ...linkStyleToCss(run.style, documentContentTheme),
35719
36250
  whiteSpace: "pre"
35720
36251
  } : {
35721
- ...runStyleToCss(run.style, editor.documentTheme),
36252
+ ...runStyleToCss(run.style, documentContentTheme),
35722
36253
  whiteSpace: "pre"
35723
36254
  };
35724
36255
  if (activeSession) {
@@ -35726,7 +36257,7 @@ function DocxEditorViewer({
35726
36257
  "span",
35727
36258
  {
35728
36259
  style: textStyle,
35729
- children: slice
36260
+ children: renderedSlice
35730
36261
  },
35731
36262
  `${keyPrefix}-active-${lineIndex}-${run.key}-${overlapStart}`
35732
36263
  );
@@ -35753,14 +36284,14 @@ function DocxEditorViewer({
35753
36284
  scrollToBookmark(run.link.slice(1));
35754
36285
  },
35755
36286
  style: textStyle,
35756
- children: slice
36287
+ children: renderedSlice
35757
36288
  },
35758
36289
  `${keyPrefix}-fragment-${lineIndex}-${run.key}-${overlapStart}`
35759
36290
  ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
35760
36291
  "span",
35761
36292
  {
35762
36293
  style: textStyle,
35763
- children: slice
36294
+ children: renderedSlice
35764
36295
  },
35765
36296
  `${keyPrefix}-fragment-${lineIndex}-${run.key}-${overlapStart}`
35766
36297
  );
@@ -36452,7 +36983,7 @@ function DocxEditorViewer({
36452
36983
  return renderParagraphRuns(
36453
36984
  paragraph,
36454
36985
  keyPrefix,
36455
- editor.documentTheme,
36986
+ documentContentTheme,
36456
36987
  numberingLabel,
36457
36988
  scrollToBookmark,
36458
36989
  interactiveBodyFloatingPageOriginPx,
@@ -36520,7 +37051,10 @@ function DocxEditorViewer({
36520
37051
  height: run.image.heightPx ? `${run.image.heightPx}px` : void 0,
36521
37052
  verticalAlign: "middle",
36522
37053
  display: "inline-block",
36523
- filter: run.image.cssFilter,
37054
+ filter: appendCssFilters(
37055
+ run.image.cssFilter,
37056
+ documentContentFilter
37057
+ ),
36524
37058
  opacity: run.image.cssOpacity
36525
37059
  }
36526
37060
  },
@@ -36535,10 +37069,10 @@ function DocxEditorViewer({
36535
37069
  return void 0;
36536
37070
  }
36537
37071
  const textStyle = run.link ? {
36538
- ...linkStyleToCss(run.style, editor.documentTheme),
37072
+ ...linkStyleToCss(run.style, documentContentTheme),
36539
37073
  whiteSpace: "pre"
36540
37074
  } : {
36541
- ...runStyleToCss(run.style, editor.documentTheme),
37075
+ ...runStyleToCss(run.style, documentContentTheme),
36542
37076
  whiteSpace: "pre"
36543
37077
  };
36544
37078
  return run.link ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
@@ -36675,7 +37209,10 @@ function DocxEditorViewer({
36675
37209
  heightPx
36676
37210
  );
36677
37211
  const imageVisualStyle = {
36678
- filter: manualImage.cssFilter,
37212
+ filter: appendCssFilters(
37213
+ manualImage.cssFilter,
37214
+ documentContentFilter
37215
+ ),
36679
37216
  opacity: manualImage.cssOpacity
36680
37217
  };
36681
37218
  const imageTransformStyle = resolveImageRenderTransformStyle(
@@ -36949,7 +37486,10 @@ function DocxEditorViewer({
36949
37486
  verticalAlign: "middle",
36950
37487
  display: "block",
36951
37488
  cursor: isReadOnly ? "default" : "move",
36952
- filter: manualImage.cssFilter,
37489
+ filter: appendCssFilters(
37490
+ manualImage.cssFilter,
37491
+ documentContentFilter
37492
+ ),
36953
37493
  opacity: manualImage.cssOpacity
36954
37494
  }
36955
37495
  }
@@ -37161,7 +37701,10 @@ function DocxEditorViewer({
37161
37701
  verticalAlign: "middle",
37162
37702
  display: "block",
37163
37703
  cursor: isReadOnly ? "default" : "move",
37164
- filter: manualImage.cssFilter,
37704
+ filter: appendCssFilters(
37705
+ manualImage.cssFilter,
37706
+ documentContentFilter
37707
+ ),
37165
37708
  opacity: manualImage.cssOpacity
37166
37709
  }
37167
37710
  }
@@ -37313,7 +37856,7 @@ function DocxEditorViewer({
37313
37856
  });
37314
37857
  }
37315
37858
  if (numberingLabel) {
37316
- const numberingTextStyle = numberingLabel.style ? runStyleToCss(numberingLabel.style, editor.documentTheme) : void 0;
37859
+ const numberingTextStyle = numberingLabel.style ? runStyleToCss(numberingLabel.style, documentContentTheme) : void 0;
37317
37860
  nodes.push(
37318
37861
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
37319
37862
  "span",
@@ -37325,7 +37868,7 @@ function DocxEditorViewer({
37325
37868
  editor.model.metadata.numberingDefinitions,
37326
37869
  numberingLabel,
37327
37870
  numberingTextStyle,
37328
- editor.documentTheme
37871
+ documentContentTheme
37329
37872
  ),
37330
37873
  children: numberingLabel.imageSrc ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
37331
37874
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
@@ -37642,7 +38185,7 @@ function DocxEditorViewer({
37642
38185
  {
37643
38186
  style: segment.style ? runStyleToCss(
37644
38187
  segment.style,
37645
- editor.documentTheme
38188
+ documentContentTheme
37646
38189
  ) : void 0,
37647
38190
  children: segment.text
37648
38191
  },
@@ -37656,7 +38199,10 @@ function DocxEditorViewer({
37656
38199
  ) : renderableImageSrc && !showsUnsupportedFallback ? (() => {
37657
38200
  const cropLayout = imageCropLayout(child, widthPx, heightPx);
37658
38201
  const imageVisualStyle = {
37659
- filter: child.cssFilter,
38202
+ filter: appendCssFilters(
38203
+ child.cssFilter,
38204
+ documentContentFilter
38205
+ ),
37660
38206
  opacity: child.cssOpacity
37661
38207
  };
37662
38208
  const imageTransformStyle = resolveImageRenderTransformStyle(
@@ -37922,10 +38468,10 @@ function DocxEditorViewer({
37922
38468
  const compactFieldLayout = compactTabStopFieldLayout || child.sourceKind === "legacy";
37923
38469
  const isTextLikeFormField = child.fieldType === "text" || child.fieldType === "date";
37924
38470
  const inputStyle = {
37925
- ...runStyleToCss(child.style, editor.documentTheme),
38471
+ ...runStyleToCss(child.style, documentContentTheme),
37926
38472
  fontFamily: cssFontFamily(child.style?.fontFamily) ?? "inherit",
37927
38473
  fontSize: child.style?.fontSizePt ? `${child.style.fontSizePt}pt` : "inherit",
37928
- color: themedRunColor(child.style?.color, editor.documentTheme) ?? "inherit",
38474
+ color: themedRunColor(child.style?.color, documentContentTheme) ?? "inherit",
37929
38475
  backgroundColor: isTextLikeFormField ? "rgba(148, 163, 184, 0.16)" : compactFieldLayout ? "transparent" : "#ffffff",
37930
38476
  border: isTextLikeFormField ? "1px solid rgba(148, 163, 184, 0.6)" : compactFieldLayout ? "none" : "1px solid #d4d4d8",
37931
38477
  borderRadius: isTextLikeFormField ? 4 : compactFieldLayout ? 0 : 6,
@@ -38007,7 +38553,7 @@ function DocxEditorViewer({
38007
38553
  cursor: isReadOnly ? "default" : "pointer",
38008
38554
  userSelect: "none",
38009
38555
  outline: "none",
38010
- ...runStyleToCss(child.style, editor.documentTheme)
38556
+ ...runStyleToCss(child.style, documentContentTheme)
38011
38557
  },
38012
38558
  children: checkboxSymbol
38013
38559
  },
@@ -38221,7 +38767,7 @@ function DocxEditorViewer({
38221
38767
  "span",
38222
38768
  {
38223
38769
  style: {
38224
- ...runStyleToCss(child.style, editor.documentTheme),
38770
+ ...runStyleToCss(child.style, documentContentTheme),
38225
38771
  verticalAlign: "super",
38226
38772
  fontSize: "0.75em"
38227
38773
  },
@@ -38266,7 +38812,7 @@ function DocxEditorViewer({
38266
38812
  const bookmarkName = linkHref.slice(1);
38267
38813
  scrollToBookmark(bookmarkName);
38268
38814
  },
38269
- style: linkStyleToCss(child.style, editor.documentTheme),
38815
+ style: linkStyleToCss(child.style, documentContentTheme),
38270
38816
  children: child.text
38271
38817
  },
38272
38818
  runKey
@@ -38281,7 +38827,7 @@ function DocxEditorViewer({
38281
38827
  );
38282
38828
  return;
38283
38829
  }
38284
- const runStyle = runStyleToCss(child.style, editor.documentTheme);
38830
+ const runStyle = runStyleToCss(child.style, documentContentTheme);
38285
38831
  const renderedText = attachTextToPreviousCheckbox(
38286
38832
  paragraph,
38287
38833
  childIndex,
@@ -38361,7 +38907,8 @@ function DocxEditorViewer({
38361
38907
  resizePreview,
38362
38908
  selectedImage,
38363
38909
  setSelectedSectionImageKey,
38364
- editor.documentTheme,
38910
+ documentContentFilter,
38911
+ documentContentTheme,
38365
38912
  editor.selectFormField,
38366
38913
  editor.setFormFieldValue,
38367
38914
  editor.toggleFormCheckbox,
@@ -38556,9 +39103,6 @@ function DocxEditorViewer({
38556
39103
  );
38557
39104
  const paragraphSegmentVisibleHeightPx = paragraphSegmentVisibleLineCount * paragraphSegmentLineHeightPx;
38558
39105
  const paragraphSegmentTranslateYPx = paragraphSegmentStartLine * paragraphSegmentLineHeightPx;
38559
- const paragraphSegmentClipBleed = resolveParagraphSegmentClipBleedPx(paragraphLineRange);
38560
- const paragraphSegmentClipBleedTopPx = paragraphSegmentClipBleed.topPx;
38561
- const paragraphSegmentClipBleedBottomPx = paragraphSegmentClipBleed.bottomPx;
38562
39106
  const paragraphSegmentIsActiveEditable = paragraphSegmentIdentityMatches(
38563
39107
  activeEditableParagraphSegment,
38564
39108
  nodeIndex,
@@ -38607,6 +39151,9 @@ function DocxEditorViewer({
38607
39151
  pretextParagraphSliceEndLine
38608
39152
  ) : void 0;
38609
39153
  const shouldRenderParagraphSegmentWithPretext = hasPartialLineRange && Boolean(pretextParagraphSource) && Boolean(pretextParagraphLayout) && pretextParagraphTotalLines > 0;
39154
+ const paragraphSegmentClipBleed = shouldRenderParagraphSegmentWithPretext ? resolveParagraphSegmentClipBleedPx(paragraphLineRange) : resolveFallbackParagraphSegmentClipBleedPx(node, paragraphLineRange);
39155
+ const paragraphSegmentClipBleedTopPx = paragraphSegmentClipBleed.topPx;
39156
+ const paragraphSegmentClipBleedBottomPx = paragraphSegmentClipBleed.bottomPx;
38610
39157
  const pretextSegmentNumberingMarkerBoxWidthPx = numberingLabel && paragraphSegmentStartLine === 0 ? resolveNumberingMarkerBoxWidthPx(
38611
39158
  node,
38612
39159
  editor.model.metadata.numberingDefinitions,
@@ -38631,8 +39178,8 @@ function DocxEditorViewer({
38631
39178
  node,
38632
39179
  editor.model.metadata.numberingDefinitions,
38633
39180
  numberingLabel,
38634
- numberingLabel.style ? runStyleToCss(numberingLabel.style, editor.documentTheme) : void 0,
38635
- editor.documentTheme
39181
+ numberingLabel.style ? runStyleToCss(numberingLabel.style, documentContentTheme) : void 0,
39182
+ documentContentTheme
38636
39183
  ),
38637
39184
  position: "absolute",
38638
39185
  left: -Math.round(
@@ -38656,7 +39203,8 @@ function DocxEditorViewer({
38656
39203
  verticalAlign: "text-bottom",
38657
39204
  width: numberingLabel.imageWidthPx ?? 12,
38658
39205
  height: numberingLabel.imageHeightPx ?? 12,
38659
- marginRight: 2
39206
+ marginRight: 2,
39207
+ filter: documentContentFilter
38660
39208
  }
38661
39209
  }
38662
39210
  ),
@@ -39804,7 +40352,7 @@ ${currentText.slice(end)}`;
39804
40352
  children: renderHeaderNode(
39805
40353
  cellContent,
39806
40354
  `active-cell-nested-table-${nodeIndex}-${rowIndex}-${cellIndex}-${contentIndex}`,
39807
- editor.documentTheme,
40355
+ documentContentTheme,
39808
40356
  editor.model.metadata.numberingDefinitions,
39809
40357
  headingStyles,
39810
40358
  spannedWidthPx > 0 ? spannedWidthPx : void 0,
@@ -40720,7 +41268,7 @@ ${currentText.slice(end)}`;
40720
41268
  return renderHeaderNode(
40721
41269
  cellContent,
40722
41270
  `body-cell-nested-table-${nodeIndex}-${rowIndex}-${cellIndex}-${contentIndex}`,
40723
- editor.documentTheme,
41271
+ documentContentTheme,
40724
41272
  editor.model.metadata.numberingDefinitions,
40725
41273
  headingStyles,
40726
41274
  spannedWidthPx > 0 ? spannedWidthPx : void 0,
@@ -41402,7 +41950,7 @@ ${currentText.slice(end)}`;
41402
41950
  style: {
41403
41951
  ...runStyleToCss(
41404
41952
  dropCapTextStyle,
41405
- editor.documentTheme
41953
+ documentContentTheme
41406
41954
  ),
41407
41955
  width: "100%",
41408
41956
  minHeight: dropCapHeightPx,
@@ -41419,7 +41967,7 @@ ${currentText.slice(end)}`;
41419
41967
  boxShadow: isSelectedDropCap ? "0 0 0 2px rgba(191, 219, 254, 0.65)" : void 0,
41420
41968
  color: themedRunColor(
41421
41969
  dropCapTextStyle.color,
41422
- editor.documentTheme
41970
+ documentContentTheme
41423
41971
  ) ?? void 0,
41424
41972
  fontFamily: cssFontFamily(dropCapTextStyle.fontFamily) ?? void 0
41425
41973
  }
@@ -41607,7 +42155,7 @@ ${currentText.slice(end)}`;
41607
42155
  style: {
41608
42156
  ...runStyleToCss(
41609
42157
  dropCapTextStyle,
41610
- editor.documentTheme
42158
+ documentContentTheme
41611
42159
  ),
41612
42160
  width: "100%",
41613
42161
  minHeight: dropCapHeightPx,
@@ -41624,7 +42172,7 @@ ${currentText.slice(end)}`;
41624
42172
  boxShadow: isSelectedDropCap ? "0 0 0 2px rgba(191, 219, 254, 0.65)" : void 0,
41625
42173
  color: themedRunColor(
41626
42174
  dropCapTextStyle.color,
41627
- editor.documentTheme
42175
+ documentContentTheme
41628
42176
  ) ?? void 0,
41629
42177
  fontFamily: cssFontFamily(
41630
42178
  dropCapTextStyle.fontFamily
@@ -41889,7 +42437,7 @@ ${currentText.slice(end)}`;
41889
42437
  renderParagraphRuns(
41890
42438
  paragraph,
41891
42439
  `${keyPrefix}-runs`,
41892
- editor.documentTheme,
42440
+ documentContentTheme,
41893
42441
  void 0,
41894
42442
  scrollToBookmark,
41895
42443
  void 0,
@@ -41907,7 +42455,7 @@ ${currentText.slice(end)}`;
41907
42455
  ));
41908
42456
  },
41909
42457
  [
41910
- editor.documentTheme,
42458
+ documentContentTheme,
41911
42459
  endnoteDisplayIndexById,
41912
42460
  footnoteDisplayIndexById,
41913
42461
  renderParagraphRuns,
@@ -42068,13 +42616,7 @@ ${currentText.slice(end)}`;
42068
42616
  "div",
42069
42617
  {
42070
42618
  "data-docx-page-placeholder": "true",
42071
- ref: (element) => {
42072
- if (element) {
42073
- pageElementsRef.current.set(pageIndex, element);
42074
- } else {
42075
- pageElementsRef.current.delete(pageIndex);
42076
- }
42077
- },
42619
+ ref: pagePlaceholderRefForIndex(pageIndex),
42078
42620
  style: {
42079
42621
  height: pageLayout.pageHeightPx,
42080
42622
  width: pageLayout.pageWidthPx
@@ -42166,18 +42708,21 @@ ${currentText.slice(end)}`;
42166
42708
  const isLastPage = pageIndex === pageCount - 1;
42167
42709
  const pageFootnotes = pageFootnotesByIndex[pageIndex] ?? [];
42168
42710
  const pageBottomFootnotes = isLastPage && remainingFootnotes.length > 0 ? [...pageFootnotes, ...remainingFootnotes] : pageFootnotes;
42169
- const pageBodyAvailableHeightPx = resolvePageContentHeightPxForPageSegments(
42170
- pageNodeSegments,
42711
+ const pageBodyAvailableHeightPx = resolveRenderPageContentHeightPxForPageSegments({
42712
+ pageSegments: pageNodeSegments,
42171
42713
  pageIndex,
42172
- Math.max(
42714
+ defaultPageContentHeightPx: Math.max(
42173
42715
  120,
42174
42716
  pageLayout.pageHeightPx - pageLayout.marginsPx.top - pageLayout.marginsPx.bottom
42175
42717
  ),
42176
- paginationSectionMetrics,
42177
- measuredPageContentHeightByIndex
42178
- );
42718
+ metricsBySection: paginationSectionMetrics,
42719
+ measuredPageContentHeightsPxByPageIndex: measuredPageContentHeightByIndex,
42720
+ measuredPageContentIdentityKeysByPageIndex: measuredPageContentIdentityKeysByIndex,
42721
+ pageIdentityKey: pageNodeSegmentIdentityKeysByPage[pageIndex],
42722
+ useMeasuredPageContentHeights: useMeasuredPageContentHeightsForRender
42723
+ });
42179
42724
  const headerFooterBodyDimmed = pageHeaderFooterEditActive;
42180
- const pageBackgroundColor = editor.model.metadata.documentBackgroundColor;
42725
+ const documentPageBackgroundColor = editor.model.metadata.documentBackgroundColor;
42181
42726
  const pageBorders = parseSectionPageBorders(
42182
42727
  pageInfo?.section.sectionPropertiesXml ?? editor.model.metadata.sectionPropertiesXml
42183
42728
  );
@@ -42200,7 +42745,7 @@ ${currentText.slice(end)}`;
42200
42745
  width: pageLayout.pageWidthPx,
42201
42746
  height: pageLayout.pageHeightPx,
42202
42747
  minHeight: pageLayout.pageHeightPx,
42203
- backgroundColor: pageBackgroundColor ?? pageSurfaceBaseStyle.backgroundColor,
42748
+ backgroundColor: pageBackgroundColor ?? documentPageBackgroundColor ?? pageSurfaceBaseStyle.backgroundColor,
42204
42749
  position: "relative",
42205
42750
  paddingTop: pageLayout.marginsPx.top,
42206
42751
  paddingRight: pageLayout.marginsPx.right,
@@ -42264,13 +42809,7 @@ ${currentText.slice(end)}`;
42264
42809
  "div",
42265
42810
  {
42266
42811
  "data-docx-page-surface": "true",
42267
- ref: (element) => {
42268
- if (element) {
42269
- pageElementsRef.current.set(pageIndex, element);
42270
- } else {
42271
- pageElementsRef.current.delete(pageIndex);
42272
- }
42273
- },
42812
+ ref: pageSurfaceRefForIndex(pageIndex),
42274
42813
  style: {
42275
42814
  ...pageSurfaceStyle,
42276
42815
  margin: 0
@@ -42288,7 +42827,8 @@ ${currentText.slice(end)}`;
42288
42827
  height: pageLayout.pageHeightPx,
42289
42828
  overflow: "clip",
42290
42829
  pointerEvents: "none",
42291
- zIndex: 0
42830
+ zIndex: 0,
42831
+ ...documentContentFilter ? { filter: documentContentFilter } : void 0
42292
42832
  },
42293
42833
  children: pageCoverBackgroundImages.map(({ key, image }) => {
42294
42834
  const renderableImageSrc = resolveRenderableImageSource(image);
@@ -42310,7 +42850,10 @@ ${currentText.slice(end)}`;
42310
42850
  height: "100%",
42311
42851
  display: "block",
42312
42852
  objectFit: "cover",
42313
- filter: image.cssFilter,
42853
+ filter: appendCssFilters(
42854
+ image.cssFilter,
42855
+ documentContentFilter
42856
+ ),
42314
42857
  opacity: image.cssOpacity,
42315
42858
  ...resolveImageRenderTransformStyle(image, {
42316
42859
  frameWidthPx: pageLayout.pageWidthPx,
@@ -42328,7 +42871,10 @@ ${currentText.slice(end)}`;
42328
42871
  "div",
42329
42872
  {
42330
42873
  "data-docx-page-border-overlay": "true",
42331
- style: pageBorderOverlayStyle
42874
+ style: {
42875
+ ...pageBorderOverlayStyle,
42876
+ ...documentContentFilter ? { filter: documentContentFilter } : void 0
42877
+ }
42332
42878
  }
42333
42879
  ) : null,
42334
42880
  pageSections.headerNodes.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
@@ -42357,7 +42903,8 @@ ${currentText.slice(end)}`;
42357
42903
  transition: "opacity 120ms ease",
42358
42904
  outline: "none",
42359
42905
  boxShadow: "none",
42360
- zIndex: 1
42906
+ zIndex: 1,
42907
+ ...documentContentFilter ? { filter: documentContentFilter } : void 0
42361
42908
  },
42362
42909
  contentEditable: pageHeaderFooterEditActive && !isReadOnly,
42363
42910
  suppressContentEditableWarning: true,
@@ -42417,7 +42964,7 @@ ${currentText.slice(end)}`;
42417
42964
  (node, index) => renderHeaderNode(
42418
42965
  node,
42419
42966
  `header-${pageIndex}-${index}`,
42420
- editor.documentTheme,
42967
+ documentContentTheme,
42421
42968
  editor.model.metadata.numberingDefinitions,
42422
42969
  headingStyles,
42423
42970
  headerNeedsPageWideLayout ? pageLayout.pageWidthPx : pageContentWidthPx,
@@ -42465,7 +43012,8 @@ ${currentText.slice(end)}`;
42465
43012
  transition: "opacity 120ms ease",
42466
43013
  display: "flex",
42467
43014
  flexDirection: "column",
42468
- minHeight: pageBodyAvailableHeightPx
43015
+ minHeight: pageBodyAvailableHeightPx,
43016
+ ...documentContentFilter ? { filter: documentContentFilter } : void 0
42469
43017
  },
42470
43018
  children: [
42471
43019
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { minHeight: 0 }, children: (() => {
@@ -42894,7 +43442,7 @@ ${currentText.slice(end)}`;
42894
43442
  style: {
42895
43443
  marginTop: 8,
42896
43444
  paddingTop: 8,
42897
- borderTop: `1px solid ${editor.documentTheme === "dark" ? "#4b5563" : "#9ca3af"}`,
43445
+ borderTop: `1px solid ${documentContentTheme === "dark" ? "#4b5563" : "#9ca3af"}`,
42898
43446
  display: "grid",
42899
43447
  gap: 6,
42900
43448
  fontSize: 12
@@ -42927,7 +43475,7 @@ ${currentText.slice(end)}`;
42927
43475
  style: {
42928
43476
  marginTop: "auto",
42929
43477
  paddingTop: 8,
42930
- borderTop: `1px solid ${editor.documentTheme === "dark" ? "#4b5563" : "#9ca3af"}`,
43478
+ borderTop: `1px solid ${documentContentTheme === "dark" ? "#4b5563" : "#9ca3af"}`,
42931
43479
  display: "grid",
42932
43480
  gap: 6,
42933
43481
  fontSize: 12
@@ -43031,7 +43579,8 @@ ${currentText.slice(end)}`;
43031
43579
  transition: "opacity 120ms ease",
43032
43580
  outline: "none",
43033
43581
  boxShadow: "none",
43034
- zIndex: 1
43582
+ zIndex: 1,
43583
+ ...documentContentFilter ? { filter: documentContentFilter } : void 0
43035
43584
  },
43036
43585
  contentEditable: pageHeaderFooterEditActive && !isReadOnly,
43037
43586
  suppressContentEditableWarning: true,
@@ -43091,7 +43640,7 @@ ${currentText.slice(end)}`;
43091
43640
  (node, index) => renderHeaderNode(
43092
43641
  node,
43093
43642
  `footer-${pageIndex}-${index}`,
43094
- editor.documentTheme,
43643
+ documentContentTheme,
43095
43644
  editor.model.metadata.numberingDefinitions,
43096
43645
  headingStyles,
43097
43646
  footerNeedsPageWideLayout ? pageLayout.pageWidthPx : pageContentWidthPx,
@@ -45547,6 +46096,7 @@ function ReactDocxViewer({
45547
46096
  resolveDocumentLayout,
45548
46097
  resolveDocumentPageSegmentStartNodeIndex,
45549
46098
  resolveDocumentSectionsFromMetadata,
46099
+ resolveDocxPageThumbnailResolution,
45550
46100
  resolvePaginationSectionMetricsIndexForNodeIndex,
45551
46101
  resolveParagraphBeforeSpacingPx,
45552
46102
  resolveSectionIndexForNodeIndex,
@@ -45578,6 +46128,7 @@ function ReactDocxViewer({
45578
46128
  useDocxLineSpacing,
45579
46129
  useDocxModel,
45580
46130
  useDocxPageLayout,
46131
+ useDocxPageThumbnails,
45581
46132
  useDocxPagination,
45582
46133
  useDocxParagraphStyles,
45583
46134
  useDocxTrackChanges,