@extend-ai/react-docx 0.7.0-alpha.5 → 0.7.0-alpha.7

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.d.cts CHANGED
@@ -968,6 +968,22 @@ interface DocxPageVirtualizationOptions {
968
968
  * @defaultValue `0`
969
969
  */
970
970
  settleDelayMs?: number;
971
+ /**
972
+ * Explicit scroll container for internal page virtualization.
973
+ *
974
+ * Omit this to let the viewer discover the nearest scrollable ancestor.
975
+ * Provide it when the host app owns scrolling, such as when the viewer is
976
+ * mounted inside a custom scroll-area viewport.
977
+ */
978
+ scrollElement?: HTMLElement | null;
979
+ /**
980
+ * Effective visual scale applied around the viewer.
981
+ *
982
+ * Omit this to let the viewer infer CSS `zoom` from its ancestor chain.
983
+ * Provide it when toolbar zoom is controlled outside the viewer so virtual
984
+ * page offsets update synchronously with the selected zoom.
985
+ */
986
+ zoomScale?: number;
971
987
  }
972
988
  /**
973
989
  * Externally controlled visible page window.
package/dist/index.d.ts CHANGED
@@ -968,6 +968,22 @@ interface DocxPageVirtualizationOptions {
968
968
  * @defaultValue `0`
969
969
  */
970
970
  settleDelayMs?: number;
971
+ /**
972
+ * Explicit scroll container for internal page virtualization.
973
+ *
974
+ * Omit this to let the viewer discover the nearest scrollable ancestor.
975
+ * Provide it when the host app owns scrolling, such as when the viewer is
976
+ * mounted inside a custom scroll-area viewport.
977
+ */
978
+ scrollElement?: HTMLElement | null;
979
+ /**
980
+ * Effective visual scale applied around the viewer.
981
+ *
982
+ * Omit this to let the viewer infer CSS `zoom` from its ancestor chain.
983
+ * Provide it when toolbar zoom is controlled outside the viewer so virtual
984
+ * page offsets update synchronously with the selected zoom.
985
+ */
986
+ zoomScale?: number;
971
987
  }
972
988
  /**
973
989
  * Externally controlled visible page window.
package/dist/index.js CHANGED
@@ -3992,6 +3992,10 @@ function resolveEffectiveZoomScale(element) {
3992
3992
  }
3993
3993
  return Number.isFinite(scale) && scale > 0 ? scale : 1;
3994
3994
  }
3995
+ function normalizePageVirtualizationZoomScale(value) {
3996
+ const scale = Number(value);
3997
+ return Number.isFinite(scale) && scale > 0 ? scale : void 0;
3998
+ }
3995
3999
  var DOC_SURFACE_STYLE_BY_THEME = {
3996
4000
  light: {
3997
4001
  backgroundColor: "#ffffff",
@@ -22435,13 +22439,14 @@ function ensureDocxViewerPageSurfaceRegistry(editor) {
22435
22439
  registry = {
22436
22440
  pageElements: /* @__PURE__ */ new Map(),
22437
22441
  pageContentKeys: /* @__PURE__ */ new Map(),
22442
+ pageSizes: /* @__PURE__ */ new Map(),
22438
22443
  listeners: /* @__PURE__ */ new Set()
22439
22444
  };
22440
22445
  docxViewerPageSurfaceRegistryByEditor.set(owner, registry);
22441
22446
  }
22442
22447
  return registry;
22443
22448
  }
22444
- function syncDocxViewerPageSurfaceContentKeys(editor, contentKeysByPage) {
22449
+ function syncDocxViewerPageSurfaceContentKeys(editor, contentKeysByPage, pageSizesByPage = []) {
22445
22450
  const registry = ensureDocxViewerPageSurfaceRegistry(editor);
22446
22451
  let changed = false;
22447
22452
  contentKeysByPage.forEach((contentKey, pageIndex) => {
@@ -22450,12 +22455,27 @@ function syncDocxViewerPageSurfaceContentKeys(editor, contentKeysByPage) {
22450
22455
  changed = true;
22451
22456
  }
22452
22457
  });
22458
+ pageSizesByPage.forEach((pageSize, pageIndex) => {
22459
+ const widthPx = Math.max(1, Math.round(pageSize.widthPx));
22460
+ const heightPx = Math.max(1, Math.round(pageSize.heightPx));
22461
+ const previous = registry.pageSizes.get(pageIndex);
22462
+ if (previous?.widthPx !== widthPx || previous?.heightPx !== heightPx) {
22463
+ registry.pageSizes.set(pageIndex, { widthPx, heightPx });
22464
+ changed = true;
22465
+ }
22466
+ });
22453
22467
  registry.pageContentKeys.forEach((_, pageIndex) => {
22454
22468
  if (pageIndex >= contentKeysByPage.length) {
22455
22469
  registry.pageContentKeys.delete(pageIndex);
22456
22470
  changed = true;
22457
22471
  }
22458
22472
  });
22473
+ registry.pageSizes.forEach((_, pageIndex) => {
22474
+ if (pageIndex >= pageSizesByPage.length) {
22475
+ registry.pageSizes.delete(pageIndex);
22476
+ changed = true;
22477
+ }
22478
+ });
22459
22479
  if (changed) {
22460
22480
  notifyDocxViewerPageSurfaceSubscribers(registry);
22461
22481
  }
@@ -22472,7 +22492,7 @@ function notifyDocxViewerPageSurfaceSubscribers(registry) {
22472
22492
  listener();
22473
22493
  });
22474
22494
  }
22475
- function registerDocxViewerPageSurface(editor, pageIndex, element) {
22495
+ function registerDocxViewerPageSurface(editor, pageIndex, element, previousElement) {
22476
22496
  const registry = ensureDocxViewerPageSurfaceRegistry(editor);
22477
22497
  const normalizedPageIndex = Math.max(0, Math.round(pageIndex));
22478
22498
  const currentElement = registry.pageElements.get(normalizedPageIndex);
@@ -22487,9 +22507,22 @@ function registerDocxViewerPageSurface(editor, pageIndex, element) {
22487
22507
  if (!currentElement) {
22488
22508
  return;
22489
22509
  }
22510
+ if (previousElement && currentElement !== previousElement) {
22511
+ return;
22512
+ }
22490
22513
  registry.pageElements.delete(normalizedPageIndex);
22491
22514
  notifyDocxViewerPageSurfaceSubscribers(registry);
22492
22515
  }
22516
+ function resolveDocxViewerRegisteredPageSurfaceSize(registry, pageIndex, fallbackWidthPx, fallbackHeightPx) {
22517
+ const registeredSize = registry.pageSizes.get(pageIndex);
22518
+ if (registeredSize) {
22519
+ return registeredSize;
22520
+ }
22521
+ return {
22522
+ widthPx: Math.max(1, Math.round(fallbackWidthPx)),
22523
+ heightPx: Math.max(1, Math.round(fallbackHeightPx))
22524
+ };
22525
+ }
22493
22526
  function resolveDocxViewerPageSurfaceSize(element, fallbackWidthPx, fallbackHeightPx) {
22494
22527
  if (element) {
22495
22528
  const rect = element.getBoundingClientRect();
@@ -22523,6 +22556,104 @@ function resolveDocxViewerPageSurfaceSize(element, fallbackWidthPx, fallbackHeig
22523
22556
  heightPx: Math.max(1, Math.round(fallbackHeightPx))
22524
22557
  };
22525
22558
  }
22559
+ function DocxDetachedThumbnailPageSurface({
22560
+ editor,
22561
+ pageIndex
22562
+ }) {
22563
+ return /* @__PURE__ */ jsx(
22564
+ DocxEditorViewer,
22565
+ {
22566
+ editor,
22567
+ mode: "read-only",
22568
+ visiblePageRange: { startPageIndex: pageIndex, endPageIndex: pageIndex },
22569
+ pageVirtualization: { enabled: false },
22570
+ showTrackedChanges: editor.showTrackedChanges,
22571
+ showComments: editor.showComments,
22572
+ style: {
22573
+ background: "transparent",
22574
+ padding: 0,
22575
+ margin: 0
22576
+ }
22577
+ }
22578
+ );
22579
+ }
22580
+ var DocxDetachedThumbnailSurfaceRenderer = class {
22581
+ host;
22582
+ root;
22583
+ activePageIndex;
22584
+ async renderPageSurface(params) {
22585
+ if (typeof document === "undefined" || typeof window === "undefined") {
22586
+ return void 0;
22587
+ }
22588
+ const { editor, registry, pageIndex } = params;
22589
+ await this.ensureRoot();
22590
+ if (!this.root) {
22591
+ return void 0;
22592
+ }
22593
+ if (this.activePageIndex !== pageIndex) {
22594
+ this.activePageIndex = pageIndex;
22595
+ this.root.render(
22596
+ /* @__PURE__ */ jsx(
22597
+ DocxDetachedThumbnailPageSurface,
22598
+ {
22599
+ editor,
22600
+ pageIndex
22601
+ }
22602
+ )
22603
+ );
22604
+ }
22605
+ return this.waitForPageSurface(registry, pageIndex);
22606
+ }
22607
+ clear() {
22608
+ if (this.root) {
22609
+ this.root.unmount();
22610
+ this.root = void 0;
22611
+ }
22612
+ if (this.host?.parentNode) {
22613
+ this.host.parentNode.removeChild(this.host);
22614
+ }
22615
+ this.host = void 0;
22616
+ this.activePageIndex = void 0;
22617
+ }
22618
+ async ensureRoot() {
22619
+ if (this.root) {
22620
+ return;
22621
+ }
22622
+ if (typeof document === "undefined") {
22623
+ return;
22624
+ }
22625
+ const host = document.createElement("div");
22626
+ host.setAttribute("data-docx-thumbnail-detached-renderer", "true");
22627
+ Object.assign(host.style, {
22628
+ position: "fixed",
22629
+ left: "-100000px",
22630
+ top: "0",
22631
+ width: "1px",
22632
+ height: "1px",
22633
+ overflow: "visible",
22634
+ opacity: "0",
22635
+ pointerEvents: "none",
22636
+ zIndex: "-1"
22637
+ });
22638
+ document.body.appendChild(host);
22639
+ this.host = host;
22640
+ const { createRoot } = await import("react-dom/client");
22641
+ this.root = createRoot(host);
22642
+ }
22643
+ async waitForPageSurface(registry, pageIndex) {
22644
+ for (let attempt = 0; attempt < 8; attempt += 1) {
22645
+ const pageElement2 = registry.pageElements.get(pageIndex);
22646
+ if (pageElement2?.isConnected) {
22647
+ return pageElement2;
22648
+ }
22649
+ await new Promise((resolve) => {
22650
+ window.requestAnimationFrame(() => resolve());
22651
+ });
22652
+ }
22653
+ const pageElement = registry.pageElements.get(pageIndex);
22654
+ return pageElement?.isConnected ? pageElement : void 0;
22655
+ }
22656
+ };
22526
22657
  var DOCX_THUMBNAIL_SURFACE_CACHE_MAX_ENTRIES = 32;
22527
22658
  var DOCX_THUMBNAIL_MIN_RASTER_INTERVAL_MS = 200;
22528
22659
  function resolveDocxPageThumbnailResolution(options) {
@@ -22600,6 +22731,7 @@ function useDocxPageThumbnails(editor, options = {}) {
22600
22731
  );
22601
22732
  const thumbnailSurfaceCacheRef = React.useRef(void 0);
22602
22733
  const thumbnailRasterQueueRef = React.useRef(void 0);
22734
+ const detachedThumbnailSurfaceRendererRef = React.useRef(void 0);
22603
22735
  const lastPaintedThumbnailKeyByCanvasRef = React.useRef(
22604
22736
  /* @__PURE__ */ new WeakMap()
22605
22737
  );
@@ -22622,8 +22754,17 @@ function useDocxPageThumbnails(editor, options = {}) {
22622
22754
  React.useEffect(() => {
22623
22755
  thumbnailSurfaceCacheRef.current?.clear();
22624
22756
  thumbnailRasterQueueRef.current?.clear();
22757
+ detachedThumbnailSurfaceRendererRef.current?.clear();
22758
+ detachedThumbnailSurfaceRendererRef.current = void 0;
22625
22759
  lastPaintedThumbnailKeyByCanvasRef.current = /* @__PURE__ */ new WeakMap();
22626
22760
  }, [editor.documentLoadNonce, pageSurfaceRegistryOwner]);
22761
+ React.useEffect(
22762
+ () => () => {
22763
+ detachedThumbnailSurfaceRendererRef.current?.clear();
22764
+ detachedThumbnailSurfaceRendererRef.current = void 0;
22765
+ },
22766
+ []
22767
+ );
22627
22768
  const thumbnailResolutionOptionsKey = React.useMemo(() => {
22628
22769
  const bounds = options.resolution;
22629
22770
  const boundsKey = typeof bounds === "number" ? `n${bounds}` : bounds ? `b${bounds.maxWidth ?? ""}x${bounds.maxHeight ?? ""}` : "";
@@ -22651,11 +22792,6 @@ function useDocxPageThumbnails(editor, options = {}) {
22651
22792
  return;
22652
22793
  }
22653
22794
  const requiresAttachedTarget = canvas === void 0;
22654
- const pageElement = pageSurfaceRegistry.pageElements.get(pageIndex);
22655
- if (!pageElement || !pageElement.isConnected) {
22656
- updatePageThumbnailState(pageIndex, "unavailable");
22657
- return;
22658
- }
22659
22795
  const force = renderOptions?.force === true;
22660
22796
  const lastPaintedKey = lastPaintedThumbnailKeyByCanvasRef.current.get(targetCanvas);
22661
22797
  if (!force && lastPaintedKey !== void 0 && lastPaintedKey === thumbnailSkipKeyForPage(pageIndex)) {
@@ -22667,41 +22803,67 @@ function useDocxPageThumbnails(editor, options = {}) {
22667
22803
  if (requiresAttachedTarget && attachedCanvasByPageRef.current.get(pageIndex) !== targetCanvas) {
22668
22804
  return;
22669
22805
  }
22670
- const livePageElement = pageSurfaceRegistry.pageElements.get(pageIndex);
22671
- if (!livePageElement || !livePageElement.isConnected) {
22672
- updatePageThumbnailState(pageIndex, "unavailable");
22673
- return;
22674
- }
22675
22806
  const runSkipKey = thumbnailSkipKeyForPage(pageIndex);
22676
- const sourceSize = resolveDocxViewerPageSurfaceSize(
22677
- livePageElement,
22807
+ const fallbackSourceSize = resolveDocxViewerRegisteredPageSurfaceSize(
22808
+ pageSurfaceRegistry,
22809
+ pageIndex,
22678
22810
  fallbackLayout.pageWidthPx,
22679
22811
  fallbackLayout.pageHeightPx
22680
22812
  );
22681
22813
  const resolution = resolveDocxPageThumbnailResolution({
22682
- sourceWidthPx: sourceSize.widthPx,
22683
- sourceHeightPx: sourceSize.heightPx,
22814
+ sourceWidthPx: fallbackSourceSize.widthPx,
22815
+ sourceHeightPx: fallbackSourceSize.heightPx,
22684
22816
  resolution: options.resolution,
22685
22817
  maxWidthPx: options.maxWidthPx,
22686
22818
  maxHeightPx: options.maxHeightPx,
22687
22819
  pixelRatio: options.pixelRatio
22688
22820
  });
22689
- const surfaceKey = runSkipKey === void 0 ? void 0 : `${runSkipKey}|${sourceSize.widthPx}x${sourceSize.heightPx}|${resolution.pixelWidthPx}x${resolution.pixelHeightPx}`;
22821
+ const surfaceKey = runSkipKey === void 0 ? void 0 : `${runSkipKey}|${fallbackSourceSize.widthPx}x${fallbackSourceSize.heightPx}|${resolution.pixelWidthPx}x${resolution.pixelHeightPx}`;
22690
22822
  const surfaceCache = ensureThumbnailSurfaceCache();
22691
22823
  try {
22692
22824
  let surface = !force && surfaceKey !== void 0 ? surfaceCache.get(surfaceKey) : void 0;
22693
22825
  if (!surface) {
22694
- surface = await rasterizeDocxThumbnailSurface({
22695
- pageElement: livePageElement,
22696
- sourceWidthPx: sourceSize.widthPx,
22697
- sourceHeightPx: sourceSize.heightPx,
22698
- widthPx: resolution.widthPx,
22699
- heightPx: resolution.heightPx,
22700
- pixelWidthPx: resolution.pixelWidthPx,
22701
- pixelHeightPx: resolution.pixelHeightPx
22702
- });
22703
- if (surfaceKey !== void 0) {
22704
- surfaceCache.set(surfaceKey, surface);
22826
+ let livePageElement = pageSurfaceRegistry.pageElements.get(pageIndex);
22827
+ let renderedDetachedSurface = false;
22828
+ try {
22829
+ if (!livePageElement || !livePageElement.isConnected) {
22830
+ if (!detachedThumbnailSurfaceRendererRef.current) {
22831
+ detachedThumbnailSurfaceRendererRef.current = new DocxDetachedThumbnailSurfaceRenderer();
22832
+ }
22833
+ livePageElement = await detachedThumbnailSurfaceRendererRef.current.renderPageSurface(
22834
+ {
22835
+ editor,
22836
+ registry: pageSurfaceRegistry,
22837
+ pageIndex
22838
+ }
22839
+ );
22840
+ renderedDetachedSurface = true;
22841
+ }
22842
+ if (!livePageElement || !livePageElement.isConnected) {
22843
+ updatePageThumbnailState(pageIndex, "unavailable");
22844
+ return;
22845
+ }
22846
+ const sourceSize = resolveDocxViewerPageSurfaceSize(
22847
+ livePageElement,
22848
+ fallbackSourceSize.widthPx,
22849
+ fallbackSourceSize.heightPx
22850
+ );
22851
+ surface = await rasterizeDocxThumbnailSurface({
22852
+ pageElement: livePageElement,
22853
+ sourceWidthPx: sourceSize.widthPx,
22854
+ sourceHeightPx: sourceSize.heightPx,
22855
+ widthPx: resolution.widthPx,
22856
+ heightPx: resolution.heightPx,
22857
+ pixelWidthPx: resolution.pixelWidthPx,
22858
+ pixelHeightPx: resolution.pixelHeightPx
22859
+ });
22860
+ if (surfaceKey !== void 0) {
22861
+ surfaceCache.set(surfaceKey, surface);
22862
+ }
22863
+ } finally {
22864
+ if (renderedDetachedSurface) {
22865
+ detachedThumbnailSurfaceRendererRef.current?.clear();
22866
+ }
22705
22867
  }
22706
22868
  }
22707
22869
  blitDocxThumbnailSurface(surface, targetCanvas, resolution);
@@ -22733,7 +22895,8 @@ function useDocxPageThumbnails(editor, options = {}) {
22733
22895
  options.pixelRatio,
22734
22896
  pageSurfaceRegistry,
22735
22897
  thumbnailSkipKeyForPage,
22736
- updatePageThumbnailState
22898
+ updatePageThumbnailState,
22899
+ editor
22737
22900
  ]
22738
22901
  );
22739
22902
  const requestAttachedThumbnailRenders = React.useCallback(
@@ -22777,10 +22940,15 @@ function useDocxPageThumbnails(editor, options = {}) {
22777
22940
  const totalPages = Math.max(1, editor.totalPages);
22778
22941
  return Array.from({ length: totalPages }, (_, pageIndex) => {
22779
22942
  const pageElement = mountedPageElements.get(pageIndex);
22780
- const sourceSize = resolveDocxViewerPageSurfaceSize(
22943
+ const sourceSize = pageElement && pageElement.isConnected ? resolveDocxViewerPageSurfaceSize(
22781
22944
  pageElement,
22782
22945
  fallbackLayout.pageWidthPx,
22783
22946
  fallbackLayout.pageHeightPx
22947
+ ) : resolveDocxViewerRegisteredPageSurfaceSize(
22948
+ pageSurfaceRegistry,
22949
+ pageIndex,
22950
+ fallbackLayout.pageWidthPx,
22951
+ fallbackLayout.pageHeightPx
22784
22952
  );
22785
22953
  const resolution = resolveDocxPageThumbnailResolution({
22786
22954
  sourceWidthPx: sourceSize.widthPx,
@@ -22850,6 +23018,7 @@ function useDocxPageThumbnails(editor, options = {}) {
22850
23018
  options.maxHeightPx,
22851
23019
  options.maxWidthPx,
22852
23020
  options.pixelRatio,
23021
+ pageSurfaceRegistry,
22853
23022
  pageThumbnailStates
22854
23023
  ]);
22855
23024
  const paintThumbnail = React.useCallback(
@@ -24146,13 +24315,23 @@ function DocxEditorViewer({
24146
24315
  if (cached) {
24147
24316
  return cached;
24148
24317
  }
24318
+ let registeredElement = null;
24149
24319
  const nextRef = (element) => {
24150
24320
  if (element) {
24321
+ registeredElement = element;
24151
24322
  pageElementsRef.current.set(normalizedPageIndex, element);
24152
24323
  } else {
24153
24324
  pageElementsRef.current.delete(normalizedPageIndex);
24154
24325
  }
24155
- registerDocxViewerPageSurface(editor, normalizedPageIndex, element);
24326
+ registerDocxViewerPageSurface(
24327
+ editor,
24328
+ normalizedPageIndex,
24329
+ element,
24330
+ registeredElement
24331
+ );
24332
+ if (!element) {
24333
+ registeredElement = null;
24334
+ }
24156
24335
  };
24157
24336
  pageSurfaceRefCallbacksRef.current.set(normalizedPageIndex, nextRef);
24158
24337
  return nextRef;
@@ -25215,12 +25394,27 @@ function DocxEditorViewer({
25215
25394
  pageSectionInfoByIndex,
25216
25395
  trackedChangesEnabled
25217
25396
  ]);
25397
+ const pageThumbnailSurfaceSizesByPage = React.useMemo(
25398
+ () => pageNodeSegmentsByPage.map((_, pageIndex) => {
25399
+ const pageLayout = pageSectionInfoByIndex[pageIndex]?.layout ?? documentLayout;
25400
+ return {
25401
+ widthPx: pageLayout.pageWidthPx,
25402
+ heightPx: pageLayout.pageHeightPx
25403
+ };
25404
+ }),
25405
+ [documentLayout, pageNodeSegmentsByPage, pageSectionInfoByIndex]
25406
+ );
25218
25407
  React.useEffect(() => {
25219
25408
  syncDocxViewerPageSurfaceContentKeys(
25220
25409
  editor,
25221
- pageThumbnailContentKeysByPage
25410
+ pageThumbnailContentKeysByPage,
25411
+ pageThumbnailSurfaceSizesByPage
25222
25412
  );
25223
- }, [pageSurfaceRegistryOwner, pageThumbnailContentKeysByPage]);
25413
+ }, [
25414
+ pageSurfaceRegistryOwner,
25415
+ pageThumbnailContentKeysByPage,
25416
+ pageThumbnailSurfaceSizesByPage
25417
+ ]);
25224
25418
  const resolveStyleRefFieldValueForPage = React.useMemo(() => {
25225
25419
  const valueCache = /* @__PURE__ */ new Map();
25226
25420
  const nodes = editor.model.nodes;
@@ -25400,6 +25594,17 @@ function DocxEditorViewer({
25400
25594
  const pageVirtualizationOverscan = hasLargeTableLayoutSurface && !Number.isFinite(pageVirtualization?.overscan) ? LARGE_TABLE_PAGE_VIRTUALIZATION_OVERSCAN : rawPageVirtualizationOverscan;
25401
25595
  const webdriverActive = typeof navigator !== "undefined" && navigator.webdriver === true;
25402
25596
  const internalPageVirtualizationRequested = pageVirtualization?.enabled !== false && !hasExternalVisiblePageRange && !hideDocumentUntilPaginationSettled && isInitialPaginationSettled && !deferInternalPageVirtualization && !webdriverActive && pageCount > 1;
25597
+ const explicitPageVirtualizationScrollElement = pageVirtualization?.scrollElement ?? null;
25598
+ const explicitPageVirtualizationZoomScale = normalizePageVirtualizationZoomScale(pageVirtualization?.zoomScale);
25599
+ const resolveViewerMeasurementZoomScale = React.useCallback(
25600
+ (rootElement, fallback = 1) => {
25601
+ if (explicitPageVirtualizationZoomScale !== void 0) {
25602
+ return explicitPageVirtualizationZoomScale;
25603
+ }
25604
+ return rootElement ? resolveEffectiveZoomScale(rootElement) : fallback;
25605
+ },
25606
+ [explicitPageVirtualizationZoomScale]
25607
+ );
25403
25608
  React.useEffect(() => {
25404
25609
  setDeferInternalPageVirtualization(!hasLargeTableLayoutSurface);
25405
25610
  }, [editor.documentLoadNonce, hasLargeTableLayoutSurface]);
@@ -25430,9 +25635,14 @@ function DocxEditorViewer({
25430
25635
  return;
25431
25636
  }
25432
25637
  setInternalVirtualScrollElement(
25433
- nearestScrollableAncestor(viewerRootRef.current)
25638
+ explicitPageVirtualizationScrollElement instanceof HTMLElement ? explicitPageVirtualizationScrollElement : nearestScrollableAncestor(viewerRootRef.current)
25434
25639
  );
25435
- }, [editor.documentLoadNonce, pageCount, trackedChangesEnabled]);
25640
+ }, [
25641
+ editor.documentLoadNonce,
25642
+ explicitPageVirtualizationScrollElement,
25643
+ pageCount,
25644
+ trackedChangesEnabled
25645
+ ]);
25436
25646
  const [zoomProbeNonce, setZoomProbeNonce] = React.useState(0);
25437
25647
  React.useEffect(() => {
25438
25648
  if (typeof window === "undefined") {
@@ -25461,11 +25671,22 @@ function DocxEditorViewer({
25461
25671
  if (!rootElement) {
25462
25672
  return;
25463
25673
  }
25464
- const nextScale = Math.round(resolveEffectiveZoomScale(rootElement) * 100) / 100;
25674
+ const nextScale = Math.round(
25675
+ resolveViewerMeasurementZoomScale(
25676
+ rootElement,
25677
+ virtualizerMeasurementScale
25678
+ ) * 100
25679
+ ) / 100;
25465
25680
  setVirtualizerMeasurementScale(
25466
25681
  (current) => Math.abs(current - nextScale) < 5e-3 ? current : nextScale
25467
25682
  );
25468
- }, [editor.documentLoadNonce, pageCount, zoomProbeNonce]);
25683
+ }, [
25684
+ editor.documentLoadNonce,
25685
+ pageCount,
25686
+ resolveViewerMeasurementZoomScale,
25687
+ virtualizerMeasurementScale,
25688
+ zoomProbeNonce
25689
+ ]);
25469
25690
  const internalPageVirtualizationEnabled = internalPageVirtualizationRequested && internalVirtualScrollElement !== null;
25470
25691
  const internalPageVirtualizationPending = typeof window !== "undefined" && internalPageVirtualizationRequested && internalVirtualScrollElement === null;
25471
25692
  const internalVirtualScrollUsesWindow = typeof document !== "undefined" && internalVirtualScrollElement !== null && (internalVirtualScrollElement === document.scrollingElement || internalVirtualScrollElement === document.documentElement || internalVirtualScrollElement === document.body);
@@ -25867,7 +26088,7 @@ function DocxEditorViewer({
25867
26088
  const next = new Map(current);
25868
26089
  let changed = false;
25869
26090
  const rootElement = viewerRootRef.current;
25870
- const zoomScale = rootElement ? resolveEffectiveZoomScale(rootElement) : 1;
26091
+ const zoomScale = resolveViewerMeasurementZoomScale(rootElement, 1);
25871
26092
  paragraphElementsRef.current.forEach((element, nodeIndex) => {
25872
26093
  if (!element.isConnected || element.dataset.docxParagraphPartialLineRange === "true" || element.closest('[data-docx-header-footer-region="footer"]') || element.closest('[data-docx-header-footer-region="header"]')) {
25873
26094
  return;
@@ -25896,6 +26117,7 @@ function DocxEditorViewer({
25896
26117
  }, [
25897
26118
  editor.documentLoadNonce,
25898
26119
  pageNodeSegmentIdentityKeysByPage,
26120
+ resolveViewerMeasurementZoomScale,
25899
26121
  visiblePageEndIndex,
25900
26122
  visiblePageStartIndex
25901
26123
  ]);
@@ -26417,7 +26639,7 @@ function DocxEditorViewer({
26417
26639
  );
26418
26640
  return;
26419
26641
  }
26420
- const zoomScale = resolveEffectiveZoomScale(rootElement);
26642
+ const zoomScale = resolveViewerMeasurementZoomScale(rootElement, 1);
26421
26643
  const next = {};
26422
26644
  for (let pageIndex = 0; pageIndex < pageCount; pageIndex += 1) {
26423
26645
  if (!isPageVisible(pageIndex)) {
@@ -26504,6 +26726,7 @@ function DocxEditorViewer({
26504
26726
  pageCount,
26505
26727
  pageHeaderAndFooterNodes,
26506
26728
  pageSectionInfoByIndex,
26729
+ resolveViewerMeasurementZoomScale,
26507
26730
  visiblePageEndIndex,
26508
26731
  visiblePageStartIndex
26509
26732
  ]);
@@ -26533,7 +26756,7 @@ function DocxEditorViewer({
26533
26756
  if (Date.now() < paginationMeasurementSuspendUntilRef.current) {
26534
26757
  return;
26535
26758
  }
26536
- const zoomScale = resolveEffectiveZoomScale(rootElement);
26759
+ const zoomScale = resolveViewerMeasurementZoomScale(rootElement, 1);
26537
26760
  const nextMeasuredPageIdentityKeys = pageNodeSegmentIdentityKeysByPage;
26538
26761
  const nextMeasuredPageDiagnostics = pageNodeSegmentsByPage.map(
26539
26762
  (_, pageIndex) => {
@@ -26748,6 +26971,7 @@ function DocxEditorViewer({
26748
26971
  pageNodeSegmentIdentityKeysByPage,
26749
26972
  pageSectionInfoByIndex,
26750
26973
  pageHeaderAndFooterNodes,
26974
+ resolveViewerMeasurementZoomScale,
26751
26975
  visiblePageEndIndex,
26752
26976
  visiblePageStartIndex
26753
26977
  ]);
@@ -31182,7 +31406,10 @@ function DocxEditorViewer({
31182
31406
  return;
31183
31407
  }
31184
31408
  const rootElement = viewerRootRef.current;
31185
- const zoomScale = rootElement ? resolveEffectiveZoomScale(rootElement) : virtualizerMeasurementScale;
31409
+ const zoomScale = resolveViewerMeasurementZoomScale(
31410
+ rootElement,
31411
+ virtualizerMeasurementScale
31412
+ );
31186
31413
  const nextMeasuredHeights = {};
31187
31414
  editor.model.nodes.forEach((node, nodeIndex) => {
31188
31415
  if (node.type !== "table") {
@@ -31324,6 +31551,7 @@ function DocxEditorViewer({
31324
31551
  pageContentWidthPxByNodeIndex,
31325
31552
  paginationMeasurementEnabled,
31326
31553
  paginationMeasurementEpoch,
31554
+ resolveViewerMeasurementZoomScale,
31327
31555
  tableMeasuredRowHeights,
31328
31556
  tableColumnWidths,
31329
31557
  tableRowHeights,