@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/README.md CHANGED
@@ -158,7 +158,7 @@ export function EditorExample() {
158
158
 
159
159
  ## Thumbnail Hook
160
160
 
161
- The library can expose page thumbnails from mounted viewer surfaces so you can build your own page strip, mini-map, or navigation UI.
161
+ The library can expose page thumbnails so you can build your own page strip, mini-map, or navigation UI. Thumbnail painting can render from the live page surface when it is mounted, or from an offscreen one-page surface when viewer virtualization has unmounted that page.
162
162
 
163
163
  ```tsx
164
164
  import * as React from "react";
@@ -194,10 +194,7 @@ export function ThumbnailExample() {
194
194
  ))}
195
195
  </div>
196
196
 
197
- <DocxEditorViewer
198
- editor={editor}
199
- pageVirtualization={{ enabled: false }}
200
- />
197
+ <DocxEditorViewer editor={editor} />
201
198
  </div>
202
199
  );
203
200
  }
@@ -205,10 +202,9 @@ export function ThumbnailExample() {
205
202
 
206
203
  Notes:
207
204
 
208
- - Thumbnails are produced from mounted page DOM.
205
+ - Thumbnail canvases can stay attached in a virtualized sidebar; only canvases you mount request paint work.
209
206
  - Thumbnail sizing is bounded by `maxWidthPx` and `maxHeightPx`, so downstream UIs can bias toward portrait thumbnail rails.
210
- - If page virtualization is enabled, offscreen pages can report `status: "unavailable"`.
211
- - For a full thumbnail rail, disable virtualization or manage the visible page range yourself.
207
+ - If the main viewer has virtualized a page away, thumbnail rendering mounts an isolated offscreen page surface long enough to rasterize that page.
212
208
 
213
209
  ## Useful Hooks
214
210
 
package/dist/index.cjs CHANGED
@@ -5235,6 +5235,10 @@ function resolveEffectiveZoomScale(element) {
5235
5235
  }
5236
5236
  return Number.isFinite(scale) && scale > 0 ? scale : 1;
5237
5237
  }
5238
+ function normalizePageVirtualizationZoomScale(value) {
5239
+ const scale = Number(value);
5240
+ return Number.isFinite(scale) && scale > 0 ? scale : void 0;
5241
+ }
5238
5242
  var DOC_SURFACE_STYLE_BY_THEME = {
5239
5243
  light: {
5240
5244
  backgroundColor: "#ffffff",
@@ -23678,13 +23682,14 @@ function ensureDocxViewerPageSurfaceRegistry(editor) {
23678
23682
  registry = {
23679
23683
  pageElements: /* @__PURE__ */ new Map(),
23680
23684
  pageContentKeys: /* @__PURE__ */ new Map(),
23685
+ pageSizes: /* @__PURE__ */ new Map(),
23681
23686
  listeners: /* @__PURE__ */ new Set()
23682
23687
  };
23683
23688
  docxViewerPageSurfaceRegistryByEditor.set(owner, registry);
23684
23689
  }
23685
23690
  return registry;
23686
23691
  }
23687
- function syncDocxViewerPageSurfaceContentKeys(editor, contentKeysByPage) {
23692
+ function syncDocxViewerPageSurfaceContentKeys(editor, contentKeysByPage, pageSizesByPage = []) {
23688
23693
  const registry = ensureDocxViewerPageSurfaceRegistry(editor);
23689
23694
  let changed = false;
23690
23695
  contentKeysByPage.forEach((contentKey, pageIndex) => {
@@ -23693,12 +23698,27 @@ function syncDocxViewerPageSurfaceContentKeys(editor, contentKeysByPage) {
23693
23698
  changed = true;
23694
23699
  }
23695
23700
  });
23701
+ pageSizesByPage.forEach((pageSize, pageIndex) => {
23702
+ const widthPx = Math.max(1, Math.round(pageSize.widthPx));
23703
+ const heightPx = Math.max(1, Math.round(pageSize.heightPx));
23704
+ const previous = registry.pageSizes.get(pageIndex);
23705
+ if (previous?.widthPx !== widthPx || previous?.heightPx !== heightPx) {
23706
+ registry.pageSizes.set(pageIndex, { widthPx, heightPx });
23707
+ changed = true;
23708
+ }
23709
+ });
23696
23710
  registry.pageContentKeys.forEach((_, pageIndex) => {
23697
23711
  if (pageIndex >= contentKeysByPage.length) {
23698
23712
  registry.pageContentKeys.delete(pageIndex);
23699
23713
  changed = true;
23700
23714
  }
23701
23715
  });
23716
+ registry.pageSizes.forEach((_, pageIndex) => {
23717
+ if (pageIndex >= pageSizesByPage.length) {
23718
+ registry.pageSizes.delete(pageIndex);
23719
+ changed = true;
23720
+ }
23721
+ });
23702
23722
  if (changed) {
23703
23723
  notifyDocxViewerPageSurfaceSubscribers(registry);
23704
23724
  }
@@ -23715,7 +23735,7 @@ function notifyDocxViewerPageSurfaceSubscribers(registry) {
23715
23735
  listener();
23716
23736
  });
23717
23737
  }
23718
- function registerDocxViewerPageSurface(editor, pageIndex, element) {
23738
+ function registerDocxViewerPageSurface(editor, pageIndex, element, previousElement) {
23719
23739
  const registry = ensureDocxViewerPageSurfaceRegistry(editor);
23720
23740
  const normalizedPageIndex = Math.max(0, Math.round(pageIndex));
23721
23741
  const currentElement = registry.pageElements.get(normalizedPageIndex);
@@ -23730,9 +23750,22 @@ function registerDocxViewerPageSurface(editor, pageIndex, element) {
23730
23750
  if (!currentElement) {
23731
23751
  return;
23732
23752
  }
23753
+ if (previousElement && currentElement !== previousElement) {
23754
+ return;
23755
+ }
23733
23756
  registry.pageElements.delete(normalizedPageIndex);
23734
23757
  notifyDocxViewerPageSurfaceSubscribers(registry);
23735
23758
  }
23759
+ function resolveDocxViewerRegisteredPageSurfaceSize(registry, pageIndex, fallbackWidthPx, fallbackHeightPx) {
23760
+ const registeredSize = registry.pageSizes.get(pageIndex);
23761
+ if (registeredSize) {
23762
+ return registeredSize;
23763
+ }
23764
+ return {
23765
+ widthPx: Math.max(1, Math.round(fallbackWidthPx)),
23766
+ heightPx: Math.max(1, Math.round(fallbackHeightPx))
23767
+ };
23768
+ }
23736
23769
  function resolveDocxViewerPageSurfaceSize(element, fallbackWidthPx, fallbackHeightPx) {
23737
23770
  if (element) {
23738
23771
  const rect = element.getBoundingClientRect();
@@ -23766,6 +23799,104 @@ function resolveDocxViewerPageSurfaceSize(element, fallbackWidthPx, fallbackHeig
23766
23799
  heightPx: Math.max(1, Math.round(fallbackHeightPx))
23767
23800
  };
23768
23801
  }
23802
+ function DocxDetachedThumbnailPageSurface({
23803
+ editor,
23804
+ pageIndex
23805
+ }) {
23806
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
23807
+ DocxEditorViewer,
23808
+ {
23809
+ editor,
23810
+ mode: "read-only",
23811
+ visiblePageRange: { startPageIndex: pageIndex, endPageIndex: pageIndex },
23812
+ pageVirtualization: { enabled: false },
23813
+ showTrackedChanges: editor.showTrackedChanges,
23814
+ showComments: editor.showComments,
23815
+ style: {
23816
+ background: "transparent",
23817
+ padding: 0,
23818
+ margin: 0
23819
+ }
23820
+ }
23821
+ );
23822
+ }
23823
+ var DocxDetachedThumbnailSurfaceRenderer = class {
23824
+ host;
23825
+ root;
23826
+ activePageIndex;
23827
+ async renderPageSurface(params) {
23828
+ if (typeof document === "undefined" || typeof window === "undefined") {
23829
+ return void 0;
23830
+ }
23831
+ const { editor, registry, pageIndex } = params;
23832
+ await this.ensureRoot();
23833
+ if (!this.root) {
23834
+ return void 0;
23835
+ }
23836
+ if (this.activePageIndex !== pageIndex) {
23837
+ this.activePageIndex = pageIndex;
23838
+ this.root.render(
23839
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
23840
+ DocxDetachedThumbnailPageSurface,
23841
+ {
23842
+ editor,
23843
+ pageIndex
23844
+ }
23845
+ )
23846
+ );
23847
+ }
23848
+ return this.waitForPageSurface(registry, pageIndex);
23849
+ }
23850
+ clear() {
23851
+ if (this.root) {
23852
+ this.root.unmount();
23853
+ this.root = void 0;
23854
+ }
23855
+ if (this.host?.parentNode) {
23856
+ this.host.parentNode.removeChild(this.host);
23857
+ }
23858
+ this.host = void 0;
23859
+ this.activePageIndex = void 0;
23860
+ }
23861
+ async ensureRoot() {
23862
+ if (this.root) {
23863
+ return;
23864
+ }
23865
+ if (typeof document === "undefined") {
23866
+ return;
23867
+ }
23868
+ const host = document.createElement("div");
23869
+ host.setAttribute("data-docx-thumbnail-detached-renderer", "true");
23870
+ Object.assign(host.style, {
23871
+ position: "fixed",
23872
+ left: "-100000px",
23873
+ top: "0",
23874
+ width: "1px",
23875
+ height: "1px",
23876
+ overflow: "visible",
23877
+ opacity: "0",
23878
+ pointerEvents: "none",
23879
+ zIndex: "-1"
23880
+ });
23881
+ document.body.appendChild(host);
23882
+ this.host = host;
23883
+ const { createRoot } = await import("react-dom/client");
23884
+ this.root = createRoot(host);
23885
+ }
23886
+ async waitForPageSurface(registry, pageIndex) {
23887
+ for (let attempt = 0; attempt < 8; attempt += 1) {
23888
+ const pageElement2 = registry.pageElements.get(pageIndex);
23889
+ if (pageElement2?.isConnected) {
23890
+ return pageElement2;
23891
+ }
23892
+ await new Promise((resolve) => {
23893
+ window.requestAnimationFrame(() => resolve());
23894
+ });
23895
+ }
23896
+ const pageElement = registry.pageElements.get(pageIndex);
23897
+ return pageElement?.isConnected ? pageElement : void 0;
23898
+ }
23899
+ };
23769
23900
  var DOCX_THUMBNAIL_SURFACE_CACHE_MAX_ENTRIES = 32;
23770
23901
  var DOCX_THUMBNAIL_MIN_RASTER_INTERVAL_MS = 200;
23771
23902
  function resolveDocxPageThumbnailResolution(options) {
@@ -23843,6 +23974,7 @@ function useDocxPageThumbnails(editor, options = {}) {
23843
23974
  );
23844
23975
  const thumbnailSurfaceCacheRef = React.useRef(void 0);
23845
23976
  const thumbnailRasterQueueRef = React.useRef(void 0);
23977
+ const detachedThumbnailSurfaceRendererRef = React.useRef(void 0);
23846
23978
  const lastPaintedThumbnailKeyByCanvasRef = React.useRef(
23847
23979
  /* @__PURE__ */ new WeakMap()
23848
23980
  );
@@ -23865,8 +23997,17 @@ function useDocxPageThumbnails(editor, options = {}) {
23865
23997
  React.useEffect(() => {
23866
23998
  thumbnailSurfaceCacheRef.current?.clear();
23867
23999
  thumbnailRasterQueueRef.current?.clear();
24000
+ detachedThumbnailSurfaceRendererRef.current?.clear();
24001
+ detachedThumbnailSurfaceRendererRef.current = void 0;
23868
24002
  lastPaintedThumbnailKeyByCanvasRef.current = /* @__PURE__ */ new WeakMap();
23869
24003
  }, [editor.documentLoadNonce, pageSurfaceRegistryOwner]);
24004
+ React.useEffect(
24005
+ () => () => {
24006
+ detachedThumbnailSurfaceRendererRef.current?.clear();
24007
+ detachedThumbnailSurfaceRendererRef.current = void 0;
24008
+ },
24009
+ []
24010
+ );
23870
24011
  const thumbnailResolutionOptionsKey = React.useMemo(() => {
23871
24012
  const bounds = options.resolution;
23872
24013
  const boundsKey = typeof bounds === "number" ? `n${bounds}` : bounds ? `b${bounds.maxWidth ?? ""}x${bounds.maxHeight ?? ""}` : "";
@@ -23894,11 +24035,6 @@ function useDocxPageThumbnails(editor, options = {}) {
23894
24035
  return;
23895
24036
  }
23896
24037
  const requiresAttachedTarget = canvas === void 0;
23897
- const pageElement = pageSurfaceRegistry.pageElements.get(pageIndex);
23898
- if (!pageElement || !pageElement.isConnected) {
23899
- updatePageThumbnailState(pageIndex, "unavailable");
23900
- return;
23901
- }
23902
24038
  const force = renderOptions?.force === true;
23903
24039
  const lastPaintedKey = lastPaintedThumbnailKeyByCanvasRef.current.get(targetCanvas);
23904
24040
  if (!force && lastPaintedKey !== void 0 && lastPaintedKey === thumbnailSkipKeyForPage(pageIndex)) {
@@ -23910,41 +24046,67 @@ function useDocxPageThumbnails(editor, options = {}) {
23910
24046
  if (requiresAttachedTarget && attachedCanvasByPageRef.current.get(pageIndex) !== targetCanvas) {
23911
24047
  return;
23912
24048
  }
23913
- const livePageElement = pageSurfaceRegistry.pageElements.get(pageIndex);
23914
- if (!livePageElement || !livePageElement.isConnected) {
23915
- updatePageThumbnailState(pageIndex, "unavailable");
23916
- return;
23917
- }
23918
24049
  const runSkipKey = thumbnailSkipKeyForPage(pageIndex);
23919
- const sourceSize = resolveDocxViewerPageSurfaceSize(
23920
- livePageElement,
24050
+ const fallbackSourceSize = resolveDocxViewerRegisteredPageSurfaceSize(
24051
+ pageSurfaceRegistry,
24052
+ pageIndex,
23921
24053
  fallbackLayout.pageWidthPx,
23922
24054
  fallbackLayout.pageHeightPx
23923
24055
  );
23924
24056
  const resolution = resolveDocxPageThumbnailResolution({
23925
- sourceWidthPx: sourceSize.widthPx,
23926
- sourceHeightPx: sourceSize.heightPx,
24057
+ sourceWidthPx: fallbackSourceSize.widthPx,
24058
+ sourceHeightPx: fallbackSourceSize.heightPx,
23927
24059
  resolution: options.resolution,
23928
24060
  maxWidthPx: options.maxWidthPx,
23929
24061
  maxHeightPx: options.maxHeightPx,
23930
24062
  pixelRatio: options.pixelRatio
23931
24063
  });
23932
- const surfaceKey = runSkipKey === void 0 ? void 0 : `${runSkipKey}|${sourceSize.widthPx}x${sourceSize.heightPx}|${resolution.pixelWidthPx}x${resolution.pixelHeightPx}`;
24064
+ const surfaceKey = runSkipKey === void 0 ? void 0 : `${runSkipKey}|${fallbackSourceSize.widthPx}x${fallbackSourceSize.heightPx}|${resolution.pixelWidthPx}x${resolution.pixelHeightPx}`;
23933
24065
  const surfaceCache = ensureThumbnailSurfaceCache();
23934
24066
  try {
23935
24067
  let surface = !force && surfaceKey !== void 0 ? surfaceCache.get(surfaceKey) : void 0;
23936
24068
  if (!surface) {
23937
- surface = await rasterizeDocxThumbnailSurface({
23938
- pageElement: livePageElement,
23939
- sourceWidthPx: sourceSize.widthPx,
23940
- sourceHeightPx: sourceSize.heightPx,
23941
- widthPx: resolution.widthPx,
23942
- heightPx: resolution.heightPx,
23943
- pixelWidthPx: resolution.pixelWidthPx,
23944
- pixelHeightPx: resolution.pixelHeightPx
23945
- });
23946
- if (surfaceKey !== void 0) {
23947
- surfaceCache.set(surfaceKey, surface);
24069
+ let livePageElement = pageSurfaceRegistry.pageElements.get(pageIndex);
24070
+ let renderedDetachedSurface = false;
24071
+ try {
24072
+ if (!livePageElement || !livePageElement.isConnected) {
24073
+ if (!detachedThumbnailSurfaceRendererRef.current) {
24074
+ detachedThumbnailSurfaceRendererRef.current = new DocxDetachedThumbnailSurfaceRenderer();
24075
+ }
24076
+ livePageElement = await detachedThumbnailSurfaceRendererRef.current.renderPageSurface(
24077
+ {
24078
+ editor,
24079
+ registry: pageSurfaceRegistry,
24080
+ pageIndex
24081
+ }
24082
+ );
24083
+ renderedDetachedSurface = true;
24084
+ }
24085
+ if (!livePageElement || !livePageElement.isConnected) {
24086
+ updatePageThumbnailState(pageIndex, "unavailable");
24087
+ return;
24088
+ }
24089
+ const sourceSize = resolveDocxViewerPageSurfaceSize(
24090
+ livePageElement,
24091
+ fallbackSourceSize.widthPx,
24092
+ fallbackSourceSize.heightPx
24093
+ );
24094
+ surface = await rasterizeDocxThumbnailSurface({
24095
+ pageElement: livePageElement,
24096
+ sourceWidthPx: sourceSize.widthPx,
24097
+ sourceHeightPx: sourceSize.heightPx,
24098
+ widthPx: resolution.widthPx,
24099
+ heightPx: resolution.heightPx,
24100
+ pixelWidthPx: resolution.pixelWidthPx,
24101
+ pixelHeightPx: resolution.pixelHeightPx
24102
+ });
24103
+ if (surfaceKey !== void 0) {
24104
+ surfaceCache.set(surfaceKey, surface);
24105
+ }
24106
+ } finally {
24107
+ if (renderedDetachedSurface) {
24108
+ detachedThumbnailSurfaceRendererRef.current?.clear();
24109
+ }
23948
24110
  }
23949
24111
  }
23950
24112
  blitDocxThumbnailSurface(surface, targetCanvas, resolution);
@@ -23976,7 +24138,8 @@ function useDocxPageThumbnails(editor, options = {}) {
23976
24138
  options.pixelRatio,
23977
24139
  pageSurfaceRegistry,
23978
24140
  thumbnailSkipKeyForPage,
23979
- updatePageThumbnailState
24141
+ updatePageThumbnailState,
24142
+ editor
23980
24143
  ]
23981
24144
  );
23982
24145
  const requestAttachedThumbnailRenders = React.useCallback(
@@ -24020,10 +24183,15 @@ function useDocxPageThumbnails(editor, options = {}) {
24020
24183
  const totalPages = Math.max(1, editor.totalPages);
24021
24184
  return Array.from({ length: totalPages }, (_, pageIndex) => {
24022
24185
  const pageElement = mountedPageElements.get(pageIndex);
24023
- const sourceSize = resolveDocxViewerPageSurfaceSize(
24186
+ const sourceSize = pageElement && pageElement.isConnected ? resolveDocxViewerPageSurfaceSize(
24024
24187
  pageElement,
24025
24188
  fallbackLayout.pageWidthPx,
24026
24189
  fallbackLayout.pageHeightPx
24190
+ ) : resolveDocxViewerRegisteredPageSurfaceSize(
24191
+ pageSurfaceRegistry,
24192
+ pageIndex,
24193
+ fallbackLayout.pageWidthPx,
24194
+ fallbackLayout.pageHeightPx
24027
24195
  );
24028
24196
  const resolution = resolveDocxPageThumbnailResolution({
24029
24197
  sourceWidthPx: sourceSize.widthPx,
@@ -24093,6 +24261,7 @@ function useDocxPageThumbnails(editor, options = {}) {
24093
24261
  options.maxHeightPx,
24094
24262
  options.maxWidthPx,
24095
24263
  options.pixelRatio,
24264
+ pageSurfaceRegistry,
24096
24265
  pageThumbnailStates
24097
24266
  ]);
24098
24267
  const paintThumbnail = React.useCallback(
@@ -25389,13 +25558,23 @@ function DocxEditorViewer({
25389
25558
  if (cached) {
25390
25559
  return cached;
25391
25560
  }
25561
+ let registeredElement = null;
25392
25562
  const nextRef = (element) => {
25393
25563
  if (element) {
25564
+ registeredElement = element;
25394
25565
  pageElementsRef.current.set(normalizedPageIndex, element);
25395
25566
  } else {
25396
25567
  pageElementsRef.current.delete(normalizedPageIndex);
25397
25568
  }
25398
- registerDocxViewerPageSurface(editor, normalizedPageIndex, element);
25569
+ registerDocxViewerPageSurface(
25570
+ editor,
25571
+ normalizedPageIndex,
25572
+ element,
25573
+ registeredElement
25574
+ );
25575
+ if (!element) {
25576
+ registeredElement = null;
25577
+ }
25399
25578
  };
25400
25579
  pageSurfaceRefCallbacksRef.current.set(normalizedPageIndex, nextRef);
25401
25580
  return nextRef;
@@ -26458,12 +26637,27 @@ function DocxEditorViewer({
26458
26637
  pageSectionInfoByIndex,
26459
26638
  trackedChangesEnabled
26460
26639
  ]);
26640
+ const pageThumbnailSurfaceSizesByPage = React.useMemo(
26641
+ () => pageNodeSegmentsByPage.map((_, pageIndex) => {
26642
+ const pageLayout = pageSectionInfoByIndex[pageIndex]?.layout ?? documentLayout;
26643
+ return {
26644
+ widthPx: pageLayout.pageWidthPx,
26645
+ heightPx: pageLayout.pageHeightPx
26646
+ };
26647
+ }),
26648
+ [documentLayout, pageNodeSegmentsByPage, pageSectionInfoByIndex]
26649
+ );
26461
26650
  React.useEffect(() => {
26462
26651
  syncDocxViewerPageSurfaceContentKeys(
26463
26652
  editor,
26464
- pageThumbnailContentKeysByPage
26653
+ pageThumbnailContentKeysByPage,
26654
+ pageThumbnailSurfaceSizesByPage
26465
26655
  );
26466
- }, [pageSurfaceRegistryOwner, pageThumbnailContentKeysByPage]);
26656
+ }, [
26657
+ pageSurfaceRegistryOwner,
26658
+ pageThumbnailContentKeysByPage,
26659
+ pageThumbnailSurfaceSizesByPage
26660
+ ]);
26467
26661
  const resolveStyleRefFieldValueForPage = React.useMemo(() => {
26468
26662
  const valueCache = /* @__PURE__ */ new Map();
26469
26663
  const nodes = editor.model.nodes;
@@ -26643,6 +26837,17 @@ function DocxEditorViewer({
26643
26837
  const pageVirtualizationOverscan = hasLargeTableLayoutSurface && !Number.isFinite(pageVirtualization?.overscan) ? LARGE_TABLE_PAGE_VIRTUALIZATION_OVERSCAN : rawPageVirtualizationOverscan;
26644
26838
  const webdriverActive = typeof navigator !== "undefined" && navigator.webdriver === true;
26645
26839
  const internalPageVirtualizationRequested = pageVirtualization?.enabled !== false && !hasExternalVisiblePageRange && !hideDocumentUntilPaginationSettled && isInitialPaginationSettled && !deferInternalPageVirtualization && !webdriverActive && pageCount > 1;
26840
+ const explicitPageVirtualizationScrollElement = pageVirtualization?.scrollElement ?? null;
26841
+ const explicitPageVirtualizationZoomScale = normalizePageVirtualizationZoomScale(pageVirtualization?.zoomScale);
26842
+ const resolveViewerMeasurementZoomScale = React.useCallback(
26843
+ (rootElement, fallback = 1) => {
26844
+ if (explicitPageVirtualizationZoomScale !== void 0) {
26845
+ return explicitPageVirtualizationZoomScale;
26846
+ }
26847
+ return rootElement ? resolveEffectiveZoomScale(rootElement) : fallback;
26848
+ },
26849
+ [explicitPageVirtualizationZoomScale]
26850
+ );
26646
26851
  React.useEffect(() => {
26647
26852
  setDeferInternalPageVirtualization(!hasLargeTableLayoutSurface);
26648
26853
  }, [editor.documentLoadNonce, hasLargeTableLayoutSurface]);
@@ -26673,9 +26878,14 @@ function DocxEditorViewer({
26673
26878
  return;
26674
26879
  }
26675
26880
  setInternalVirtualScrollElement(
26676
- nearestScrollableAncestor(viewerRootRef.current)
26881
+ explicitPageVirtualizationScrollElement instanceof HTMLElement ? explicitPageVirtualizationScrollElement : nearestScrollableAncestor(viewerRootRef.current)
26677
26882
  );
26678
- }, [editor.documentLoadNonce, pageCount, trackedChangesEnabled]);
26883
+ }, [
26884
+ editor.documentLoadNonce,
26885
+ explicitPageVirtualizationScrollElement,
26886
+ pageCount,
26887
+ trackedChangesEnabled
26888
+ ]);
26679
26889
  const [zoomProbeNonce, setZoomProbeNonce] = React.useState(0);
26680
26890
  React.useEffect(() => {
26681
26891
  if (typeof window === "undefined") {
@@ -26704,11 +26914,22 @@ function DocxEditorViewer({
26704
26914
  if (!rootElement) {
26705
26915
  return;
26706
26916
  }
26707
- const nextScale = Math.round(resolveEffectiveZoomScale(rootElement) * 100) / 100;
26917
+ const nextScale = Math.round(
26918
+ resolveViewerMeasurementZoomScale(
26919
+ rootElement,
26920
+ virtualizerMeasurementScale
26921
+ ) * 100
26922
+ ) / 100;
26708
26923
  setVirtualizerMeasurementScale(
26709
26924
  (current) => Math.abs(current - nextScale) < 5e-3 ? current : nextScale
26710
26925
  );
26711
- }, [editor.documentLoadNonce, pageCount, zoomProbeNonce]);
26926
+ }, [
26927
+ editor.documentLoadNonce,
26928
+ pageCount,
26929
+ resolveViewerMeasurementZoomScale,
26930
+ virtualizerMeasurementScale,
26931
+ zoomProbeNonce
26932
+ ]);
26712
26933
  const internalPageVirtualizationEnabled = internalPageVirtualizationRequested && internalVirtualScrollElement !== null;
26713
26934
  const internalPageVirtualizationPending = typeof window !== "undefined" && internalPageVirtualizationRequested && internalVirtualScrollElement === null;
26714
26935
  const internalVirtualScrollUsesWindow = typeof document !== "undefined" && internalVirtualScrollElement !== null && (internalVirtualScrollElement === document.scrollingElement || internalVirtualScrollElement === document.documentElement || internalVirtualScrollElement === document.body);
@@ -27110,7 +27331,7 @@ function DocxEditorViewer({
27110
27331
  const next = new Map(current);
27111
27332
  let changed = false;
27112
27333
  const rootElement = viewerRootRef.current;
27113
- const zoomScale = rootElement ? resolveEffectiveZoomScale(rootElement) : 1;
27334
+ const zoomScale = resolveViewerMeasurementZoomScale(rootElement, 1);
27114
27335
  paragraphElementsRef.current.forEach((element, nodeIndex) => {
27115
27336
  if (!element.isConnected || element.dataset.docxParagraphPartialLineRange === "true" || element.closest('[data-docx-header-footer-region="footer"]') || element.closest('[data-docx-header-footer-region="header"]')) {
27116
27337
  return;
@@ -27139,6 +27360,7 @@ function DocxEditorViewer({
27139
27360
  }, [
27140
27361
  editor.documentLoadNonce,
27141
27362
  pageNodeSegmentIdentityKeysByPage,
27363
+ resolveViewerMeasurementZoomScale,
27142
27364
  visiblePageEndIndex,
27143
27365
  visiblePageStartIndex
27144
27366
  ]);
@@ -27660,7 +27882,7 @@ function DocxEditorViewer({
27660
27882
  );
27661
27883
  return;
27662
27884
  }
27663
- const zoomScale = resolveEffectiveZoomScale(rootElement);
27885
+ const zoomScale = resolveViewerMeasurementZoomScale(rootElement, 1);
27664
27886
  const next = {};
27665
27887
  for (let pageIndex = 0; pageIndex < pageCount; pageIndex += 1) {
27666
27888
  if (!isPageVisible(pageIndex)) {
@@ -27747,6 +27969,7 @@ function DocxEditorViewer({
27747
27969
  pageCount,
27748
27970
  pageHeaderAndFooterNodes,
27749
27971
  pageSectionInfoByIndex,
27972
+ resolveViewerMeasurementZoomScale,
27750
27973
  visiblePageEndIndex,
27751
27974
  visiblePageStartIndex
27752
27975
  ]);
@@ -27776,7 +27999,7 @@ function DocxEditorViewer({
27776
27999
  if (Date.now() < paginationMeasurementSuspendUntilRef.current) {
27777
28000
  return;
27778
28001
  }
27779
- const zoomScale = resolveEffectiveZoomScale(rootElement);
28002
+ const zoomScale = resolveViewerMeasurementZoomScale(rootElement, 1);
27780
28003
  const nextMeasuredPageIdentityKeys = pageNodeSegmentIdentityKeysByPage;
27781
28004
  const nextMeasuredPageDiagnostics = pageNodeSegmentsByPage.map(
27782
28005
  (_, pageIndex) => {
@@ -27991,6 +28214,7 @@ function DocxEditorViewer({
27991
28214
  pageNodeSegmentIdentityKeysByPage,
27992
28215
  pageSectionInfoByIndex,
27993
28216
  pageHeaderAndFooterNodes,
28217
+ resolveViewerMeasurementZoomScale,
27994
28218
  visiblePageEndIndex,
27995
28219
  visiblePageStartIndex
27996
28220
  ]);
@@ -32425,7 +32649,10 @@ function DocxEditorViewer({
32425
32649
  return;
32426
32650
  }
32427
32651
  const rootElement = viewerRootRef.current;
32428
- const zoomScale = rootElement ? resolveEffectiveZoomScale(rootElement) : virtualizerMeasurementScale;
32652
+ const zoomScale = resolveViewerMeasurementZoomScale(
32653
+ rootElement,
32654
+ virtualizerMeasurementScale
32655
+ );
32429
32656
  const nextMeasuredHeights = {};
32430
32657
  editor.model.nodes.forEach((node, nodeIndex) => {
32431
32658
  if (node.type !== "table") {
@@ -32567,6 +32794,7 @@ function DocxEditorViewer({
32567
32794
  pageContentWidthPxByNodeIndex,
32568
32795
  paginationMeasurementEnabled,
32569
32796
  paginationMeasurementEpoch,
32797
+ resolveViewerMeasurementZoomScale,
32570
32798
  tableMeasuredRowHeights,
32571
32799
  tableColumnWidths,
32572
32800
  tableRowHeights,