@anaralabs/lector 3.12.7 → 3.12.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +118 -7
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2668,26 +2668,36 @@ var createTextSelectionManager = () => {
|
|
|
2668
2668
|
};
|
|
2669
2669
|
var bindMouseEvents = createTextSelectionManager();
|
|
2670
2670
|
var TEXT_BUILD_IDLE_MS = 300;
|
|
2671
|
+
var TEXT_SCROLL_SETTLE_MS = 160;
|
|
2672
|
+
var VIEWPORT_ATTACH_MAX_FRAMES = 300;
|
|
2671
2673
|
var useTextLayer = () => {
|
|
2672
2674
|
const textContainerRef = useRef(null);
|
|
2673
2675
|
const textLayerRef = useRef(null);
|
|
2674
2676
|
const pageNumber = usePDFPageNumber();
|
|
2675
2677
|
const pdfPageProxy = usePdf((state) => state.getPdfPageProxy(pageNumber));
|
|
2678
|
+
const viewportRef = usePdf((state) => state.viewportRef);
|
|
2676
2679
|
useEffect(() => {
|
|
2677
2680
|
const textContainer = textContainerRef.current;
|
|
2678
2681
|
if (!textContainer) {
|
|
2679
2682
|
return;
|
|
2680
2683
|
}
|
|
2681
2684
|
let isCancelled = false;
|
|
2682
|
-
|
|
2683
|
-
|
|
2685
|
+
let buildTimer = null;
|
|
2686
|
+
let unsubscribe = null;
|
|
2687
|
+
let built = false;
|
|
2688
|
+
let building = false;
|
|
2689
|
+
let buildGen = 0;
|
|
2690
|
+
const build = () => {
|
|
2691
|
+
building = true;
|
|
2692
|
+
const gen = ++buildGen;
|
|
2684
2693
|
textContainer.innerHTML = "";
|
|
2685
2694
|
if (textLayerRef.current) {
|
|
2686
2695
|
textLayerRef.current.cancel();
|
|
2687
2696
|
textLayerRef.current = null;
|
|
2688
2697
|
}
|
|
2689
2698
|
void import('pdfjs-dist/legacy/build/pdf.mjs').then(({ TextLayer: TextLayer2 }) => {
|
|
2690
|
-
if (isCancelled || textContainerRef.current !== textContainer)
|
|
2699
|
+
if (isCancelled || gen !== buildGen || textContainerRef.current !== textContainer)
|
|
2700
|
+
return;
|
|
2691
2701
|
const textLayer = new TextLayer2({
|
|
2692
2702
|
textContentSource: pdfPageProxy.streamTextContent(),
|
|
2693
2703
|
container: textContainer,
|
|
@@ -2696,22 +2706,61 @@ var useTextLayer = () => {
|
|
|
2696
2706
|
textLayerRef.current = textLayer;
|
|
2697
2707
|
return textLayer.render();
|
|
2698
2708
|
}).then(() => {
|
|
2699
|
-
if (isCancelled || textContainerRef.current !== textContainer) {
|
|
2709
|
+
if (isCancelled || gen !== buildGen || textContainerRef.current !== textContainer) {
|
|
2700
2710
|
return;
|
|
2701
2711
|
}
|
|
2702
2712
|
const endOfContent = document.createElement("div");
|
|
2703
2713
|
endOfContent.className = "endOfContent";
|
|
2704
2714
|
textContainer.appendChild(endOfContent);
|
|
2705
2715
|
bindMouseEvents(textContainer, endOfContent);
|
|
2716
|
+
built = true;
|
|
2717
|
+
building = false;
|
|
2718
|
+
unsubscribe?.();
|
|
2719
|
+
unsubscribe = null;
|
|
2706
2720
|
}).catch((error) => {
|
|
2721
|
+
if (gen === buildGen) building = false;
|
|
2707
2722
|
if (error instanceof Error && error.name !== "AbortException") {
|
|
2708
2723
|
console.error("TextLayer rendering error:", error);
|
|
2709
2724
|
}
|
|
2710
2725
|
});
|
|
2711
|
-
}
|
|
2726
|
+
};
|
|
2727
|
+
const schedule = () => {
|
|
2728
|
+
if (built) return;
|
|
2729
|
+
if (building) {
|
|
2730
|
+
buildGen++;
|
|
2731
|
+
building = false;
|
|
2732
|
+
if (textLayerRef.current) {
|
|
2733
|
+
textLayerRef.current.cancel();
|
|
2734
|
+
textLayerRef.current = null;
|
|
2735
|
+
}
|
|
2736
|
+
textContainer.innerHTML = "";
|
|
2737
|
+
}
|
|
2738
|
+
if (buildTimer) clearTimeout(buildTimer);
|
|
2739
|
+
buildTimer = setTimeout(() => {
|
|
2740
|
+
buildTimer = null;
|
|
2741
|
+
if (isCancelled || textContainerRef.current !== textContainer) return;
|
|
2742
|
+
build();
|
|
2743
|
+
}, TEXT_BUILD_IDLE_MS);
|
|
2744
|
+
};
|
|
2745
|
+
let attachRaf = null;
|
|
2746
|
+
let attachAttempts = 0;
|
|
2747
|
+
const attachScrollSubscription = () => {
|
|
2748
|
+
attachRaf = null;
|
|
2749
|
+
const scrollViewport = viewportRef?.current;
|
|
2750
|
+
if (!scrollViewport) {
|
|
2751
|
+
if (++attachAttempts > VIEWPORT_ATTACH_MAX_FRAMES) return;
|
|
2752
|
+
attachRaf = requestAnimationFrame(attachScrollSubscription);
|
|
2753
|
+
return;
|
|
2754
|
+
}
|
|
2755
|
+
unsubscribe = subscribeToViewportInvalidation(scrollViewport, schedule);
|
|
2756
|
+
};
|
|
2757
|
+
attachScrollSubscription();
|
|
2758
|
+
schedule();
|
|
2712
2759
|
return () => {
|
|
2713
2760
|
isCancelled = true;
|
|
2714
|
-
clearTimeout(buildTimer);
|
|
2761
|
+
if (buildTimer) clearTimeout(buildTimer);
|
|
2762
|
+
if (attachRaf !== null) cancelAnimationFrame(attachRaf);
|
|
2763
|
+
unsubscribe?.();
|
|
2715
2764
|
if (textLayerRef.current) {
|
|
2716
2765
|
textLayerRef.current.cancel();
|
|
2717
2766
|
textLayerRef.current = null;
|
|
@@ -2721,7 +2770,69 @@ var useTextLayer = () => {
|
|
|
2721
2770
|
delete textContainer._cleanupTextSelection;
|
|
2722
2771
|
}
|
|
2723
2772
|
};
|
|
2724
|
-
}, [pdfPageProxy.streamTextContent, pdfPageProxy.getViewport]);
|
|
2773
|
+
}, [pdfPageProxy.streamTextContent, pdfPageProxy.getViewport, viewportRef]);
|
|
2774
|
+
useEffect(() => {
|
|
2775
|
+
const textContainer = textContainerRef.current;
|
|
2776
|
+
if (!textContainer) return;
|
|
2777
|
+
let settleTimer = null;
|
|
2778
|
+
let pointerDown = false;
|
|
2779
|
+
let selecting = false;
|
|
2780
|
+
const show = () => {
|
|
2781
|
+
textContainer.style.visibility = "";
|
|
2782
|
+
};
|
|
2783
|
+
const onScroll = () => {
|
|
2784
|
+
if (selecting) return;
|
|
2785
|
+
textContainer.style.visibility = "hidden";
|
|
2786
|
+
if (settleTimer) clearTimeout(settleTimer);
|
|
2787
|
+
settleTimer = setTimeout(show, TEXT_SCROLL_SETTLE_MS);
|
|
2788
|
+
};
|
|
2789
|
+
const onPointerDown = () => {
|
|
2790
|
+
pointerDown = true;
|
|
2791
|
+
selecting = false;
|
|
2792
|
+
if (settleTimer) {
|
|
2793
|
+
clearTimeout(settleTimer);
|
|
2794
|
+
settleTimer = null;
|
|
2795
|
+
}
|
|
2796
|
+
show();
|
|
2797
|
+
};
|
|
2798
|
+
const onSelectionChange = () => {
|
|
2799
|
+
if (pointerDown) selecting = true;
|
|
2800
|
+
};
|
|
2801
|
+
const clearPointer = () => {
|
|
2802
|
+
pointerDown = false;
|
|
2803
|
+
selecting = false;
|
|
2804
|
+
};
|
|
2805
|
+
let unsubscribe = null;
|
|
2806
|
+
let attachRaf = null;
|
|
2807
|
+
let attachAttempts = 0;
|
|
2808
|
+
const attachScrollSubscription = () => {
|
|
2809
|
+
attachRaf = null;
|
|
2810
|
+
const scrollViewport = viewportRef?.current;
|
|
2811
|
+
if (!scrollViewport) {
|
|
2812
|
+
if (++attachAttempts > VIEWPORT_ATTACH_MAX_FRAMES) return;
|
|
2813
|
+
attachRaf = requestAnimationFrame(attachScrollSubscription);
|
|
2814
|
+
return;
|
|
2815
|
+
}
|
|
2816
|
+
unsubscribe = subscribeToViewportInvalidation(scrollViewport, onScroll);
|
|
2817
|
+
};
|
|
2818
|
+
attachScrollSubscription();
|
|
2819
|
+
document.addEventListener("pointerdown", onPointerDown, true);
|
|
2820
|
+
document.addEventListener("pointerup", clearPointer, true);
|
|
2821
|
+
document.addEventListener("pointercancel", clearPointer, true);
|
|
2822
|
+
document.addEventListener("selectionchange", onSelectionChange);
|
|
2823
|
+
window.addEventListener("blur", clearPointer);
|
|
2824
|
+
return () => {
|
|
2825
|
+
if (attachRaf !== null) cancelAnimationFrame(attachRaf);
|
|
2826
|
+
unsubscribe?.();
|
|
2827
|
+
document.removeEventListener("pointerdown", onPointerDown, true);
|
|
2828
|
+
document.removeEventListener("pointerup", clearPointer, true);
|
|
2829
|
+
document.removeEventListener("pointercancel", clearPointer, true);
|
|
2830
|
+
document.removeEventListener("selectionchange", onSelectionChange);
|
|
2831
|
+
window.removeEventListener("blur", clearPointer);
|
|
2832
|
+
if (settleTimer) clearTimeout(settleTimer);
|
|
2833
|
+
show();
|
|
2834
|
+
};
|
|
2835
|
+
}, [viewportRef]);
|
|
2725
2836
|
return {
|
|
2726
2837
|
textContainerRef,
|
|
2727
2838
|
pageNumber: pdfPageProxy.pageNumber
|