@anaralabs/lector 3.12.4 → 3.12.5

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.
Files changed (2) hide show
  1. package/dist/index.js +57 -42
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1439,6 +1439,7 @@ var useDetailCanvasLayer = ({
1439
1439
  const detailCanvasRef = useRef(null);
1440
1440
  const pageNumber = usePDFPageNumber();
1441
1441
  const dpr = useDpr();
1442
+ const store = PDFStore.useContext();
1442
1443
  const bouncyZoom = usePdf((state) => state.zoom);
1443
1444
  const isPinching = usePdf((state) => state.isPinching);
1444
1445
  const pdfPageProxy = usePdf((state) => state.getPdfPageProxy(pageNumber));
@@ -1473,12 +1474,29 @@ var useDetailCanvasLayer = ({
1473
1474
  container.style.cssText = "";
1474
1475
  };
1475
1476
  const renderDetailCanvas = () => {
1477
+ const virtualizer = store.getState().virtualizer;
1478
+ if (virtualizer?.isScrolling) {
1479
+ scheduleRender(160);
1480
+ return;
1481
+ }
1476
1482
  const pageContainer = baseCanvasRef.current?.parentElement ?? null;
1477
1483
  if (!pageContainer) {
1478
1484
  hideDetailCanvas();
1479
1485
  return;
1480
1486
  }
1481
1487
  const { width: pageWidth, height: pageHeight } = pageDimsRef.current;
1488
+ const targetDetailScale = dpr * zoom * 1.3;
1489
+ const baseTargetScale = dpr * Math.min(zoom, 1);
1490
+ const baseScale = clampScaleForPage(
1491
+ baseTargetScale,
1492
+ pageWidth,
1493
+ pageHeight
1494
+ );
1495
+ const needsDetail = zoom > 1 && targetDetailScale - baseScale > 1e-3;
1496
+ if (isPinching || !needsDetail) {
1497
+ hideDetailCanvas();
1498
+ return;
1499
+ }
1482
1500
  const scrollX = scrollContainer.scrollLeft / zoom;
1483
1501
  const scrollY = scrollContainer.scrollTop / zoom;
1484
1502
  const viewportWidth = scrollContainer.clientWidth / zoom;
@@ -1499,15 +1517,7 @@ var useDetailCanvasLayer = ({
1499
1517
  );
1500
1518
  const visibleWidth = Math.max(0, visibleRight - visibleLeft);
1501
1519
  const visibleHeight = Math.max(0, visibleBottom - visibleTop);
1502
- const targetDetailScale = dpr * zoom * 1.3;
1503
- const baseTargetScale = dpr * Math.min(zoom, 1);
1504
- const baseScale = clampScaleForPage(
1505
- baseTargetScale,
1506
- pageWidth,
1507
- pageHeight
1508
- );
1509
- const needsDetail = zoom > 1 && targetDetailScale - baseScale > 1e-3;
1510
- if (isPinching || !needsDetail || visibleWidth <= 0 || visibleHeight <= 0) {
1520
+ if (visibleWidth <= 0 || visibleHeight <= 0) {
1511
1521
  hideDetailCanvas();
1512
1522
  return;
1513
1523
  }
@@ -1600,7 +1610,8 @@ var useDetailCanvasLayer = ({
1600
1610
  background,
1601
1611
  dpr,
1602
1612
  viewportRef,
1603
- baseCanvasRef
1613
+ baseCanvasRef,
1614
+ store
1604
1615
  ]);
1605
1616
  useEffect(() => {
1606
1617
  const canvas = detailCanvasRef.current;
@@ -2633,51 +2644,51 @@ var createTextSelectionManager = () => {
2633
2644
  return bindMouseEvents2;
2634
2645
  };
2635
2646
  var bindMouseEvents = createTextSelectionManager();
2647
+ var TEXT_BUILD_IDLE_MS = 300;
2636
2648
  var useTextLayer = () => {
2637
2649
  const textContainerRef = useRef(null);
2638
2650
  const textLayerRef = useRef(null);
2639
- const isRenderingRef = useRef(false);
2640
2651
  const pageNumber = usePDFPageNumber();
2641
2652
  const pdfPageProxy = usePdf((state) => state.getPdfPageProxy(pageNumber));
2642
2653
  useEffect(() => {
2643
2654
  const textContainer = textContainerRef.current;
2644
- if (!textContainer || isRenderingRef.current) {
2655
+ if (!textContainer) {
2645
2656
  return;
2646
2657
  }
2647
2658
  let isCancelled = false;
2648
- isRenderingRef.current = true;
2649
- textContainer.innerHTML = "";
2650
- if (textLayerRef.current) {
2651
- textLayerRef.current.cancel();
2652
- textLayerRef.current = null;
2653
- }
2654
- void import('pdfjs-dist/legacy/build/pdf.mjs').then(({ TextLayer: TextLayer2 }) => {
2659
+ const buildTimer = setTimeout(() => {
2655
2660
  if (isCancelled || textContainerRef.current !== textContainer) return;
2656
- const textLayer = new TextLayer2({
2657
- textContentSource: pdfPageProxy.streamTextContent(),
2658
- container: textContainer,
2659
- viewport: pdfPageProxy.getViewport({ scale: 1 })
2660
- });
2661
- textLayerRef.current = textLayer;
2662
- return textLayer.render();
2663
- }).then(() => {
2664
- if (isCancelled || textContainerRef.current !== textContainer) {
2665
- return;
2666
- }
2667
- const endOfContent = document.createElement("div");
2668
- endOfContent.className = "endOfContent";
2669
- textContainer.appendChild(endOfContent);
2670
- bindMouseEvents(textContainer, endOfContent);
2671
- }).catch((error) => {
2672
- if (error instanceof Error && error.name !== "AbortException") {
2673
- console.error("TextLayer rendering error:", error);
2661
+ textContainer.innerHTML = "";
2662
+ if (textLayerRef.current) {
2663
+ textLayerRef.current.cancel();
2664
+ textLayerRef.current = null;
2674
2665
  }
2675
- }).finally(() => {
2676
- isRenderingRef.current = false;
2677
- });
2666
+ void import('pdfjs-dist/legacy/build/pdf.mjs').then(({ TextLayer: TextLayer2 }) => {
2667
+ if (isCancelled || textContainerRef.current !== textContainer) return;
2668
+ const textLayer = new TextLayer2({
2669
+ textContentSource: pdfPageProxy.streamTextContent(),
2670
+ container: textContainer,
2671
+ viewport: pdfPageProxy.getViewport({ scale: 1 })
2672
+ });
2673
+ textLayerRef.current = textLayer;
2674
+ return textLayer.render();
2675
+ }).then(() => {
2676
+ if (isCancelled || textContainerRef.current !== textContainer) {
2677
+ return;
2678
+ }
2679
+ const endOfContent = document.createElement("div");
2680
+ endOfContent.className = "endOfContent";
2681
+ textContainer.appendChild(endOfContent);
2682
+ bindMouseEvents(textContainer, endOfContent);
2683
+ }).catch((error) => {
2684
+ if (error instanceof Error && error.name !== "AbortException") {
2685
+ console.error("TextLayer rendering error:", error);
2686
+ }
2687
+ });
2688
+ }, TEXT_BUILD_IDLE_MS);
2678
2689
  return () => {
2679
2690
  isCancelled = true;
2680
- isRenderingRef.current = false;
2691
+ clearTimeout(buildTimer);
2681
2692
  if (textLayerRef.current) {
2682
2693
  textLayerRef.current.cancel();
2683
2694
  textLayerRef.current = null;
@@ -2704,7 +2715,11 @@ var TextLayer = memo(
2704
2715
  ...style,
2705
2716
  position: "absolute",
2706
2717
  top: 0,
2707
- left: 0
2718
+ left: 0,
2719
+ // Isolate the span subtree's layout so a getBoundingClientRect on
2720
+ // an ancestor (e.g. renderDetailCanvas) doesn't reflow every text
2721
+ // span on this page during scroll.
2722
+ contain: "layout style"
2708
2723
  },
2709
2724
  ...props,
2710
2725
  ...{
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anaralabs/lector",
3
- "version": "3.12.4",
3
+ "version": "3.12.5",
4
4
  "description": "A headless PDF viewer for React",
5
5
  "author": "andrewdr (https://github.com/andrewdoro)",
6
6
  "license": "MIT",