@anaralabs/lector 3.12.3 → 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.
- package/dist/index.js +125 -56
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1285,18 +1285,36 @@ var useCanvasLayer = ({ background }) => {
|
|
|
1285
1285
|
baseCanvas.style.visibility = "hidden";
|
|
1286
1286
|
let cancelled = false;
|
|
1287
1287
|
const viewport = pdfPageProxy.getViewport({ scale: baseScale });
|
|
1288
|
+
const buffer = document.createElement("canvas");
|
|
1289
|
+
buffer.width = baseCanvas.width;
|
|
1290
|
+
buffer.height = baseCanvas.height;
|
|
1291
|
+
const bufferCtx = buffer.getContext("2d");
|
|
1292
|
+
const useBuffer = bufferCtx !== null;
|
|
1293
|
+
const renderCanvas = useBuffer ? buffer : baseCanvas;
|
|
1294
|
+
const renderCtx = bufferCtx ?? context;
|
|
1288
1295
|
const renderingTask = pdfPageProxy.render({
|
|
1289
|
-
canvas:
|
|
1290
|
-
canvasContext:
|
|
1296
|
+
canvas: renderCanvas,
|
|
1297
|
+
canvasContext: renderCtx,
|
|
1291
1298
|
viewport,
|
|
1292
1299
|
background
|
|
1293
1300
|
});
|
|
1301
|
+
const releaseBuffer = () => {
|
|
1302
|
+
buffer.width = 0;
|
|
1303
|
+
buffer.height = 0;
|
|
1304
|
+
};
|
|
1294
1305
|
renderingTask.promise.then(() => {
|
|
1295
|
-
if (cancelled)
|
|
1306
|
+
if (cancelled) {
|
|
1307
|
+
releaseBuffer();
|
|
1308
|
+
return;
|
|
1309
|
+
}
|
|
1310
|
+
if (useBuffer) {
|
|
1311
|
+
context.clearRect(0, 0, baseCanvas.width, baseCanvas.height);
|
|
1312
|
+
context.drawImage(buffer, 0, 0);
|
|
1313
|
+
}
|
|
1296
1314
|
baseCanvas.style.visibility = "";
|
|
1297
1315
|
markPageRendered(pageNumber);
|
|
1298
1316
|
if (typeof createImageBitmap !== "undefined") {
|
|
1299
|
-
createImageBitmap(
|
|
1317
|
+
createImageBitmap(renderCanvas).then((bitmap) => {
|
|
1300
1318
|
if (cancelled) {
|
|
1301
1319
|
bitmap.close();
|
|
1302
1320
|
return;
|
|
@@ -1309,9 +1327,12 @@ var useCanvasLayer = ({ background }) => {
|
|
|
1309
1327
|
bitmap
|
|
1310
1328
|
);
|
|
1311
1329
|
}).catch(() => {
|
|
1312
|
-
});
|
|
1330
|
+
}).finally(releaseBuffer);
|
|
1331
|
+
} else {
|
|
1332
|
+
releaseBuffer();
|
|
1313
1333
|
}
|
|
1314
1334
|
}).catch((error) => {
|
|
1335
|
+
releaseBuffer();
|
|
1315
1336
|
if (cancelled) return;
|
|
1316
1337
|
if (error?.name === "RenderingCancelledException") return;
|
|
1317
1338
|
baseCanvas.style.visibility = "";
|
|
@@ -1418,6 +1439,7 @@ var useDetailCanvasLayer = ({
|
|
|
1418
1439
|
const detailCanvasRef = useRef(null);
|
|
1419
1440
|
const pageNumber = usePDFPageNumber();
|
|
1420
1441
|
const dpr = useDpr();
|
|
1442
|
+
const store = PDFStore.useContext();
|
|
1421
1443
|
const bouncyZoom = usePdf((state) => state.zoom);
|
|
1422
1444
|
const isPinching = usePdf((state) => state.isPinching);
|
|
1423
1445
|
const pdfPageProxy = usePdf((state) => state.getPdfPageProxy(pageNumber));
|
|
@@ -1452,12 +1474,29 @@ var useDetailCanvasLayer = ({
|
|
|
1452
1474
|
container.style.cssText = "";
|
|
1453
1475
|
};
|
|
1454
1476
|
const renderDetailCanvas = () => {
|
|
1477
|
+
const virtualizer = store.getState().virtualizer;
|
|
1478
|
+
if (virtualizer?.isScrolling) {
|
|
1479
|
+
scheduleRender(160);
|
|
1480
|
+
return;
|
|
1481
|
+
}
|
|
1455
1482
|
const pageContainer = baseCanvasRef.current?.parentElement ?? null;
|
|
1456
1483
|
if (!pageContainer) {
|
|
1457
1484
|
hideDetailCanvas();
|
|
1458
1485
|
return;
|
|
1459
1486
|
}
|
|
1460
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
|
+
}
|
|
1461
1500
|
const scrollX = scrollContainer.scrollLeft / zoom;
|
|
1462
1501
|
const scrollY = scrollContainer.scrollTop / zoom;
|
|
1463
1502
|
const viewportWidth = scrollContainer.clientWidth / zoom;
|
|
@@ -1478,15 +1517,7 @@ var useDetailCanvasLayer = ({
|
|
|
1478
1517
|
);
|
|
1479
1518
|
const visibleWidth = Math.max(0, visibleRight - visibleLeft);
|
|
1480
1519
|
const visibleHeight = Math.max(0, visibleBottom - visibleTop);
|
|
1481
|
-
|
|
1482
|
-
const baseTargetScale = dpr * Math.min(zoom, 1);
|
|
1483
|
-
const baseScale = clampScaleForPage(
|
|
1484
|
-
baseTargetScale,
|
|
1485
|
-
pageWidth,
|
|
1486
|
-
pageHeight
|
|
1487
|
-
);
|
|
1488
|
-
const needsDetail = zoom > 1 && targetDetailScale - baseScale > 1e-3;
|
|
1489
|
-
if (isPinching || !needsDetail || visibleWidth <= 0 || visibleHeight <= 0) {
|
|
1520
|
+
if (visibleWidth <= 0 || visibleHeight <= 0) {
|
|
1490
1521
|
hideDetailCanvas();
|
|
1491
1522
|
return;
|
|
1492
1523
|
}
|
|
@@ -1579,7 +1610,8 @@ var useDetailCanvasLayer = ({
|
|
|
1579
1610
|
background,
|
|
1580
1611
|
dpr,
|
|
1581
1612
|
viewportRef,
|
|
1582
|
-
baseCanvasRef
|
|
1613
|
+
baseCanvasRef,
|
|
1614
|
+
store
|
|
1583
1615
|
]);
|
|
1584
1616
|
useEffect(() => {
|
|
1585
1617
|
const canvas = detailCanvasRef.current;
|
|
@@ -2612,51 +2644,51 @@ var createTextSelectionManager = () => {
|
|
|
2612
2644
|
return bindMouseEvents2;
|
|
2613
2645
|
};
|
|
2614
2646
|
var bindMouseEvents = createTextSelectionManager();
|
|
2647
|
+
var TEXT_BUILD_IDLE_MS = 300;
|
|
2615
2648
|
var useTextLayer = () => {
|
|
2616
2649
|
const textContainerRef = useRef(null);
|
|
2617
2650
|
const textLayerRef = useRef(null);
|
|
2618
|
-
const isRenderingRef = useRef(false);
|
|
2619
2651
|
const pageNumber = usePDFPageNumber();
|
|
2620
2652
|
const pdfPageProxy = usePdf((state) => state.getPdfPageProxy(pageNumber));
|
|
2621
2653
|
useEffect(() => {
|
|
2622
2654
|
const textContainer = textContainerRef.current;
|
|
2623
|
-
if (!textContainer
|
|
2655
|
+
if (!textContainer) {
|
|
2624
2656
|
return;
|
|
2625
2657
|
}
|
|
2626
2658
|
let isCancelled = false;
|
|
2627
|
-
|
|
2628
|
-
textContainer.innerHTML = "";
|
|
2629
|
-
if (textLayerRef.current) {
|
|
2630
|
-
textLayerRef.current.cancel();
|
|
2631
|
-
textLayerRef.current = null;
|
|
2632
|
-
}
|
|
2633
|
-
void import('pdfjs-dist/legacy/build/pdf.mjs').then(({ TextLayer: TextLayer2 }) => {
|
|
2659
|
+
const buildTimer = setTimeout(() => {
|
|
2634
2660
|
if (isCancelled || textContainerRef.current !== textContainer) return;
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
});
|
|
2640
|
-
textLayerRef.current = textLayer;
|
|
2641
|
-
return textLayer.render();
|
|
2642
|
-
}).then(() => {
|
|
2643
|
-
if (isCancelled || textContainerRef.current !== textContainer) {
|
|
2644
|
-
return;
|
|
2645
|
-
}
|
|
2646
|
-
const endOfContent = document.createElement("div");
|
|
2647
|
-
endOfContent.className = "endOfContent";
|
|
2648
|
-
textContainer.appendChild(endOfContent);
|
|
2649
|
-
bindMouseEvents(textContainer, endOfContent);
|
|
2650
|
-
}).catch((error) => {
|
|
2651
|
-
if (error instanceof Error && error.name !== "AbortException") {
|
|
2652
|
-
console.error("TextLayer rendering error:", error);
|
|
2661
|
+
textContainer.innerHTML = "";
|
|
2662
|
+
if (textLayerRef.current) {
|
|
2663
|
+
textLayerRef.current.cancel();
|
|
2664
|
+
textLayerRef.current = null;
|
|
2653
2665
|
}
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
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);
|
|
2657
2689
|
return () => {
|
|
2658
2690
|
isCancelled = true;
|
|
2659
|
-
|
|
2691
|
+
clearTimeout(buildTimer);
|
|
2660
2692
|
if (textLayerRef.current) {
|
|
2661
2693
|
textLayerRef.current.cancel();
|
|
2662
2694
|
textLayerRef.current = null;
|
|
@@ -2683,7 +2715,11 @@ var TextLayer = memo(
|
|
|
2683
2715
|
...style,
|
|
2684
2716
|
position: "absolute",
|
|
2685
2717
|
top: 0,
|
|
2686
|
-
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"
|
|
2687
2723
|
},
|
|
2688
2724
|
...props,
|
|
2689
2725
|
...{
|
|
@@ -3036,18 +3072,32 @@ var useScrollFn = () => {
|
|
|
3036
3072
|
);
|
|
3037
3073
|
return { scrollToFn };
|
|
3038
3074
|
};
|
|
3039
|
-
var useVisiblePage = ({
|
|
3075
|
+
var useVisiblePage = ({
|
|
3076
|
+
items,
|
|
3077
|
+
scrollOffset
|
|
3078
|
+
}) => {
|
|
3040
3079
|
const zoomLevel = usePdf((state) => state.zoom);
|
|
3041
3080
|
const isPinching = usePdf((state) => state.isPinching);
|
|
3042
3081
|
const setCurrentPage = usePdf((state) => state.setCurrentPage);
|
|
3043
3082
|
const scrollElement = usePdf((state) => state.viewportRef?.current);
|
|
3044
3083
|
const lastPageRef = useRef(0);
|
|
3084
|
+
const [viewportHeight, setViewportHeight] = useState(0);
|
|
3085
|
+
useEffect(() => {
|
|
3086
|
+
if (!scrollElement) return;
|
|
3087
|
+
const measure = () => setViewportHeight(scrollElement.clientHeight);
|
|
3088
|
+
measure();
|
|
3089
|
+
if (typeof ResizeObserver === "undefined") {
|
|
3090
|
+
window.addEventListener("resize", measure);
|
|
3091
|
+
return () => window.removeEventListener("resize", measure);
|
|
3092
|
+
}
|
|
3093
|
+
const observer = new ResizeObserver(measure);
|
|
3094
|
+
observer.observe(scrollElement);
|
|
3095
|
+
return () => observer.disconnect();
|
|
3096
|
+
}, [scrollElement]);
|
|
3045
3097
|
const calculateVisiblePageIndex = useCallback(
|
|
3046
3098
|
(virtualItems) => {
|
|
3047
|
-
if (
|
|
3048
|
-
const
|
|
3049
|
-
const viewportHeight = scrollElement.clientHeight / zoomLevel;
|
|
3050
|
-
const viewportCenter = scrollTop + viewportHeight / 2;
|
|
3099
|
+
if (virtualItems.length === 0 || scrollOffset == null) return 0;
|
|
3100
|
+
const viewportCenter = scrollOffset + viewportHeight / zoomLevel / 2;
|
|
3051
3101
|
let closestIndex = 0;
|
|
3052
3102
|
let smallestDistance = Infinity;
|
|
3053
3103
|
for (const item of virtualItems) {
|
|
@@ -3060,10 +3110,17 @@ var useVisiblePage = ({ items }) => {
|
|
|
3060
3110
|
}
|
|
3061
3111
|
return closestIndex;
|
|
3062
3112
|
},
|
|
3063
|
-
[
|
|
3113
|
+
[scrollOffset, zoomLevel, viewportHeight]
|
|
3064
3114
|
);
|
|
3065
3115
|
useEffect(() => {
|
|
3066
|
-
if (
|
|
3116
|
+
if (viewportHeight === 0 && scrollElement) {
|
|
3117
|
+
const h = scrollElement.clientHeight;
|
|
3118
|
+
if (h > 0) {
|
|
3119
|
+
setViewportHeight(h);
|
|
3120
|
+
return;
|
|
3121
|
+
}
|
|
3122
|
+
}
|
|
3123
|
+
if (!isPinching && items.length > 0 && viewportHeight > 0 && scrollOffset != null) {
|
|
3067
3124
|
const mostVisibleIndex = calculateVisiblePageIndex(items);
|
|
3068
3125
|
const page = mostVisibleIndex + 1;
|
|
3069
3126
|
if (page !== lastPageRef.current) {
|
|
@@ -3071,7 +3128,15 @@ var useVisiblePage = ({ items }) => {
|
|
|
3071
3128
|
setCurrentPage?.(page);
|
|
3072
3129
|
}
|
|
3073
3130
|
}
|
|
3074
|
-
}, [
|
|
3131
|
+
}, [
|
|
3132
|
+
items,
|
|
3133
|
+
isPinching,
|
|
3134
|
+
calculateVisiblePageIndex,
|
|
3135
|
+
setCurrentPage,
|
|
3136
|
+
viewportHeight,
|
|
3137
|
+
scrollOffset,
|
|
3138
|
+
scrollElement
|
|
3139
|
+
]);
|
|
3075
3140
|
return null;
|
|
3076
3141
|
};
|
|
3077
3142
|
|
|
@@ -5267,7 +5332,11 @@ var Pages = ({
|
|
|
5267
5332
|
const virtualizerItems = virtualizer?.getVirtualItems() ?? [];
|
|
5268
5333
|
const items = tempItems.length ? tempItems : virtualizerItems;
|
|
5269
5334
|
useVisiblePage({
|
|
5270
|
-
items
|
|
5335
|
+
items,
|
|
5336
|
+
// Pass through nullish (pre-measure) rather than coercing to 0, so the
|
|
5337
|
+
// hook doesn't publish a top-of-document page before the real offset
|
|
5338
|
+
// (incl. a restored/deep-linked one) arrives.
|
|
5339
|
+
scrollOffset: virtualizer.scrollOffset ?? null
|
|
5271
5340
|
});
|
|
5272
5341
|
useFitWidth({ viewportRef: containerRef });
|
|
5273
5342
|
const largestPageWidth = usePdf(selectLargestPageWidth);
|