@anaralabs/lector 3.9.1 → 3.10.0
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/_tsup-dts-rollup.d.ts +25 -16
- package/dist/index.js +497 -334
- package/package.json +3 -3
|
@@ -4,11 +4,12 @@ import type { DocumentInitParameters } from 'pdfjs-dist/types/src/display/api';
|
|
|
4
4
|
import { ForwardRefExoticComponent } from 'react';
|
|
5
5
|
import { FunctionComponent } from 'react';
|
|
6
6
|
import { HTMLProps } from 'react';
|
|
7
|
-
import type { IPDFLinkService } from 'pdfjs-dist/types/web/interfaces';
|
|
8
7
|
import { JSX } from 'react/jsx-runtime';
|
|
9
|
-
import
|
|
8
|
+
import { JSX as JSX_2 } from 'react';
|
|
9
|
+
import { MemoExoticComponent } from 'react';
|
|
10
10
|
import type { PageViewport } from 'pdfjs-dist';
|
|
11
|
-
import { PDFDocumentProxy } from 'pdfjs-dist';
|
|
11
|
+
import type { PDFDocumentProxy } from 'pdfjs-dist';
|
|
12
|
+
import { pdfjsDist } from 'pdfjs-dist';
|
|
12
13
|
import type { PDFPageProxy } from 'pdfjs-dist';
|
|
13
14
|
import type { default as React_2 } from 'react';
|
|
14
15
|
import { ReactElement } from 'react';
|
|
@@ -68,7 +69,7 @@ declare interface AnnotationHighlightLayerProps {
|
|
|
68
69
|
* @param jumpOptions - Options for page navigation behavior when clicking internal links.
|
|
69
70
|
* See `usePdfJump` hook for available options.
|
|
70
71
|
*/
|
|
71
|
-
export declare const AnnotationLayer: ({ renderForms, externalLinksEnabled, jumpOptions, className, style, ...props }: AnnotationLayerParams & HTMLProps<HTMLDivElement>) => JSX.Element
|
|
72
|
+
export declare const AnnotationLayer: MemoExoticComponent<({ renderForms, externalLinksEnabled, jumpOptions, className, style, ...props }: AnnotationLayerParams & HTMLProps<HTMLDivElement>) => JSX.Element>;
|
|
72
73
|
|
|
73
74
|
declare interface AnnotationLayerParams {
|
|
74
75
|
/**
|
|
@@ -142,9 +143,9 @@ export declare const cancellable: <T extends Promise<unknown>>(promise: T) => {
|
|
|
142
143
|
cancel: () => void;
|
|
143
144
|
};
|
|
144
145
|
|
|
145
|
-
export declare const CanvasLayer: ({ style, background, ...props }: HTMLProps<HTMLCanvasElement> & {
|
|
146
|
-
|
|
147
|
-
}) => JSX.Element
|
|
146
|
+
export declare const CanvasLayer: MemoExoticComponent<({ style, background, ...props }: HTMLProps<HTMLCanvasElement> & {
|
|
147
|
+
background?: string;
|
|
148
|
+
}) => JSX.Element>;
|
|
148
149
|
|
|
149
150
|
export declare const clamp: (value: number, minimum: number, maximum: number) => number;
|
|
150
151
|
|
|
@@ -175,9 +176,11 @@ export declare const CurrentPage: ({ ...props }: HTMLProps<HTMLInputElement>) =>
|
|
|
175
176
|
|
|
176
177
|
export declare const CurrentZoom: ({ ...props }: HTMLProps<HTMLInputElement>) => JSX.Element;
|
|
177
178
|
|
|
178
|
-
export declare const CustomLayer: ({ children
|
|
179
|
-
|
|
180
|
-
}) => JSX_2.Element
|
|
179
|
+
export declare const CustomLayer: MemoExoticComponent<({ children }: {
|
|
180
|
+
children: (pageNumber: number) => JSX_2.Element;
|
|
181
|
+
}) => JSX_2.Element>;
|
|
182
|
+
|
|
183
|
+
export declare const ensureAnnotationLayerStyles: () => void;
|
|
181
184
|
|
|
182
185
|
export declare const firstMemo: <T>(first: boolean, memo: unknown, initializer: () => T) => T;
|
|
183
186
|
|
|
@@ -225,7 +228,7 @@ export declare interface InitialPDFState {
|
|
|
225
228
|
zoomOptions?: ZoomOptions;
|
|
226
229
|
}
|
|
227
230
|
|
|
228
|
-
export declare class LinkService
|
|
231
|
+
export declare class LinkService {
|
|
229
232
|
_pdfDocumentProxy?: PDFDocumentProxy;
|
|
230
233
|
externalLinkEnabled: boolean;
|
|
231
234
|
isInPresentationMode: boolean;
|
|
@@ -252,6 +255,8 @@ export declare class LinkService implements IPDFLinkService {
|
|
|
252
255
|
unregisterPageNavigationCallback(): void;
|
|
253
256
|
}
|
|
254
257
|
|
|
258
|
+
export declare const loadPdfJs: () => Promise<pdfjsDist>;
|
|
259
|
+
|
|
255
260
|
export declare const NextPage: () => void;
|
|
256
261
|
|
|
257
262
|
export declare const Outline: ({ children, ...props }: HTMLProps<HTMLUListElement> & {
|
|
@@ -273,10 +278,10 @@ declare interface OutlineItemProps extends HTMLProps<HTMLDivElement> {
|
|
|
273
278
|
|
|
274
279
|
declare type OutlineItemType = NonNullable<ReturnType<typeof usePDFOutline>>[number];
|
|
275
280
|
|
|
276
|
-
export declare const Page: ({ children, pageNumber, style, ...props }: HTMLProps<HTMLDivElement> & {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
}) => JSX.Element
|
|
281
|
+
export declare const Page: MemoExoticComponent<({ children, pageNumber, style, ...props }: HTMLProps<HTMLDivElement> & {
|
|
282
|
+
children: ReactNode;
|
|
283
|
+
pageNumber?: number;
|
|
284
|
+
}) => JSX.Element>;
|
|
280
285
|
|
|
281
286
|
export declare const Pages: ({ children, gap, virtualizerOptions, initialOffset, onOffsetChange, ...props }: HTMLProps<HTMLDivElement> & {
|
|
282
287
|
virtualizerOptions?: {
|
|
@@ -371,12 +376,14 @@ declare interface SelectionTooltipProps {
|
|
|
371
376
|
|
|
372
377
|
export declare type Source = string | URL | TypedArray | ArrayBuffer | DocumentInitParameters;
|
|
373
378
|
|
|
379
|
+
export declare const subscribeToViewportInvalidation: (viewport: HTMLDivElement, callback: ViewportCallback) => () => void;
|
|
380
|
+
|
|
374
381
|
declare type TextContent = {
|
|
375
382
|
pageNumber: number;
|
|
376
383
|
text: string;
|
|
377
384
|
};
|
|
378
385
|
|
|
379
|
-
export declare const TextLayer: ({ className, style, ...props }: HTMLProps<HTMLDivElement>) => JSX.Element
|
|
386
|
+
export declare const TextLayer: MemoExoticComponent<({ className, style, ...props }: HTMLProps<HTMLDivElement>) => JSX.Element>;
|
|
380
387
|
|
|
381
388
|
declare interface TextPosition {
|
|
382
389
|
pageNumber: number;
|
|
@@ -494,6 +501,8 @@ export declare const useSelectionDimensions: () => {
|
|
|
494
501
|
} | undefined;
|
|
495
502
|
};
|
|
496
503
|
|
|
504
|
+
declare type ViewportCallback = () => void;
|
|
505
|
+
|
|
497
506
|
export declare const ZoomIn: ({ ...props }: HTMLProps<HTMLButtonElement>) => JSX.Element;
|
|
498
507
|
|
|
499
508
|
export declare interface ZoomOptions {
|
package/dist/index.js
CHANGED
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import React, { createContext, forwardRef, useRef, useState, useCallback, useContext, useEffect,
|
|
3
|
+
import React, { createContext, memo, forwardRef, cloneElement, useRef, useState, useCallback, useContext, useEffect, useMemo, useLayoutEffect, createRef } from 'react';
|
|
4
4
|
import { createPortal } from 'react-dom';
|
|
5
5
|
import { useFloating, autoUpdate, offset, shift, useDismiss, useInteractions, inline, flip } from '@floating-ui/react';
|
|
6
6
|
import { create, useStore, createStore } from 'zustand';
|
|
7
|
-
import { jsx,
|
|
8
|
-
import { AnnotationLayer, TextLayer, getDocument } from 'pdfjs-dist';
|
|
7
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
9
8
|
import { useDebounce } from 'use-debounce';
|
|
10
9
|
import { v4 } from 'uuid';
|
|
11
10
|
import { Slot } from '@radix-ui/react-slot';
|
|
12
11
|
import { useVirtualizer, elementScroll, debounce } from '@tanstack/react-virtual';
|
|
13
12
|
|
|
14
|
-
// src/components/annotation-tooltip.tsx
|
|
15
|
-
|
|
16
13
|
// src/lib/clamp.ts
|
|
17
14
|
var clamp = (value, minimum, maximum) => {
|
|
18
15
|
return Math.min(Math.max(value, minimum), maximum);
|
|
@@ -615,6 +612,56 @@ function clsx() {
|
|
|
615
612
|
}
|
|
616
613
|
var clsx_default = clsx;
|
|
617
614
|
|
|
615
|
+
// src/lib/annotation-layer-styles.ts
|
|
616
|
+
var ANNOTATION_LAYER_STYLE_ID = "lector-annotation-layer-styles";
|
|
617
|
+
var annotationLayerStyles = `
|
|
618
|
+
.annotationLayer {
|
|
619
|
+
position: absolute;
|
|
620
|
+
left: 0;
|
|
621
|
+
top: 0;
|
|
622
|
+
right: 0;
|
|
623
|
+
bottom: 0;
|
|
624
|
+
overflow: hidden;
|
|
625
|
+
opacity: 1;
|
|
626
|
+
z-index: 3;
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
.annotationLayer section {
|
|
630
|
+
position: absolute;
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
.annotationLayer .linkAnnotation > a,
|
|
634
|
+
.annotationLayer .buttonWidgetAnnotation.pushButton > a {
|
|
635
|
+
position: absolute;
|
|
636
|
+
font-size: 1em;
|
|
637
|
+
top: 0;
|
|
638
|
+
left: 0;
|
|
639
|
+
width: 100%;
|
|
640
|
+
height: 100%;
|
|
641
|
+
background: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7") 0 0 repeat;
|
|
642
|
+
cursor: pointer;
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
.annotationLayer .linkAnnotation > a:hover,
|
|
646
|
+
.annotationLayer .buttonWidgetAnnotation.pushButton > a:hover {
|
|
647
|
+
opacity: 0.2;
|
|
648
|
+
background: rgba(255, 255, 0, 1);
|
|
649
|
+
box-shadow: 0 2px 10px rgba(255, 255, 0, 1);
|
|
650
|
+
}
|
|
651
|
+
`;
|
|
652
|
+
var ensureAnnotationLayerStyles = () => {
|
|
653
|
+
if (typeof document === "undefined") {
|
|
654
|
+
return;
|
|
655
|
+
}
|
|
656
|
+
if (document.getElementById(ANNOTATION_LAYER_STYLE_ID)) {
|
|
657
|
+
return;
|
|
658
|
+
}
|
|
659
|
+
const style = document.createElement("style");
|
|
660
|
+
style.id = ANNOTATION_LAYER_STYLE_ID;
|
|
661
|
+
style.textContent = annotationLayerStyles;
|
|
662
|
+
document.head.appendChild(style);
|
|
663
|
+
};
|
|
664
|
+
|
|
618
665
|
// src/lib/cancellable.ts
|
|
619
666
|
var cancellable = (promise) => {
|
|
620
667
|
let isCancelled = false;
|
|
@@ -639,6 +686,15 @@ var cancellable = (promise) => {
|
|
|
639
686
|
}
|
|
640
687
|
};
|
|
641
688
|
};
|
|
689
|
+
|
|
690
|
+
// src/lib/pdfjs.ts
|
|
691
|
+
var pdfJsPromise = null;
|
|
692
|
+
var loadPdfJs = () => {
|
|
693
|
+
if (!pdfJsPromise) {
|
|
694
|
+
pdfJsPromise = import('pdfjs-dist');
|
|
695
|
+
}
|
|
696
|
+
return pdfJsPromise;
|
|
697
|
+
};
|
|
642
698
|
var usePdfJump = () => {
|
|
643
699
|
const virtualizer = usePdf((state) => state.virtualizer);
|
|
644
700
|
const setHighlight = usePdf((state) => state.setHighlight);
|
|
@@ -931,46 +987,7 @@ var useAnnotationLayer = (params) => {
|
|
|
931
987
|
};
|
|
932
988
|
}, [jumpToPage, linkService, mergedParams.jumpOptions]);
|
|
933
989
|
useEffect(() => {
|
|
934
|
-
|
|
935
|
-
style.textContent = `
|
|
936
|
-
.annotationLayer {
|
|
937
|
-
position: absolute;
|
|
938
|
-
left: 0;
|
|
939
|
-
top: 0;
|
|
940
|
-
right: 0;
|
|
941
|
-
bottom: 0;
|
|
942
|
-
overflow: hidden;
|
|
943
|
-
opacity: 1;
|
|
944
|
-
z-index: 3;
|
|
945
|
-
}
|
|
946
|
-
|
|
947
|
-
.annotationLayer section {
|
|
948
|
-
position: absolute;
|
|
949
|
-
}
|
|
950
|
-
|
|
951
|
-
.annotationLayer .linkAnnotation > a,
|
|
952
|
-
.annotationLayer .buttonWidgetAnnotation.pushButton > a {
|
|
953
|
-
position: absolute;
|
|
954
|
-
font-size: 1em;
|
|
955
|
-
top: 0;
|
|
956
|
-
left: 0;
|
|
957
|
-
width: 100%;
|
|
958
|
-
height: 100%;
|
|
959
|
-
background: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7") 0 0 repeat;
|
|
960
|
-
cursor: pointer;
|
|
961
|
-
}
|
|
962
|
-
|
|
963
|
-
.annotationLayer .linkAnnotation > a:hover,
|
|
964
|
-
.annotationLayer .buttonWidgetAnnotation.pushButton > a:hover {
|
|
965
|
-
opacity: 0.2;
|
|
966
|
-
background: rgba(255, 255, 0, 1);
|
|
967
|
-
box-shadow: 0 2px 10px rgba(255, 255, 0, 1);
|
|
968
|
-
}
|
|
969
|
-
`;
|
|
970
|
-
document.head.appendChild(style);
|
|
971
|
-
return () => {
|
|
972
|
-
document.head.removeChild(style);
|
|
973
|
-
};
|
|
990
|
+
ensureAnnotationLayerStyles();
|
|
974
991
|
}, []);
|
|
975
992
|
useEffect(() => {
|
|
976
993
|
if (!annotationLayerRef.current) return;
|
|
@@ -1011,22 +1028,27 @@ var useAnnotationLayer = (params) => {
|
|
|
1011
1028
|
}
|
|
1012
1029
|
annotationLayerRef.current.innerHTML = "";
|
|
1013
1030
|
annotationLayerRef.current.className = "annotationLayer";
|
|
1014
|
-
const viewport = pdfPageProxy.getViewport({ scale: 1 })
|
|
1031
|
+
const viewport = pdfPageProxy.getViewport({ scale: 1 }).clone({
|
|
1032
|
+
dontFlip: true
|
|
1033
|
+
});
|
|
1015
1034
|
const annotationLayerConfig = {
|
|
1016
1035
|
div: annotationLayerRef.current,
|
|
1017
1036
|
viewport,
|
|
1018
1037
|
page: pdfPageProxy,
|
|
1019
1038
|
linkService,
|
|
1039
|
+
annotationStorage: void 0,
|
|
1020
1040
|
accessibilityManager: void 0,
|
|
1021
1041
|
annotationCanvasMap: void 0,
|
|
1022
1042
|
annotationEditorUIManager: void 0,
|
|
1023
|
-
structTreeLayer: void 0
|
|
1043
|
+
structTreeLayer: void 0,
|
|
1044
|
+
commentManager: void 0
|
|
1024
1045
|
};
|
|
1025
|
-
const annotationLayer = new AnnotationLayer(annotationLayerConfig);
|
|
1026
|
-
annotationLayerObjectRef.current = annotationLayer;
|
|
1027
1046
|
const { cancel } = cancellable(
|
|
1028
1047
|
(async () => {
|
|
1029
1048
|
try {
|
|
1049
|
+
const { AnnotationLayer: AnnotationLayer2 } = await loadPdfJs();
|
|
1050
|
+
const annotationLayer = new AnnotationLayer2(annotationLayerConfig);
|
|
1051
|
+
annotationLayerObjectRef.current = annotationLayer;
|
|
1030
1052
|
const annotations = await pdfPageProxy.getAnnotations();
|
|
1031
1053
|
await annotationLayer.render({
|
|
1032
1054
|
...annotationLayerConfig,
|
|
@@ -1046,34 +1068,37 @@ var useAnnotationLayer = (params) => {
|
|
|
1046
1068
|
annotationLayerRef
|
|
1047
1069
|
};
|
|
1048
1070
|
};
|
|
1049
|
-
var
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1071
|
+
var AnnotationLayer = memo(
|
|
1072
|
+
({
|
|
1073
|
+
renderForms = true,
|
|
1074
|
+
externalLinksEnabled = true,
|
|
1075
|
+
jumpOptions = { behavior: "smooth", align: "start" },
|
|
1076
|
+
className,
|
|
1077
|
+
style,
|
|
1078
|
+
...props
|
|
1079
|
+
}) => {
|
|
1080
|
+
const { annotationLayerRef } = useAnnotationLayer({
|
|
1081
|
+
renderForms,
|
|
1082
|
+
externalLinksEnabled,
|
|
1083
|
+
jumpOptions
|
|
1084
|
+
});
|
|
1085
|
+
return /* @__PURE__ */ jsx(
|
|
1086
|
+
"div",
|
|
1087
|
+
{
|
|
1088
|
+
className: clsx_default("annotationLayer", className),
|
|
1089
|
+
style: {
|
|
1090
|
+
...style,
|
|
1091
|
+
position: "absolute",
|
|
1092
|
+
top: 0,
|
|
1093
|
+
left: 0
|
|
1094
|
+
},
|
|
1095
|
+
...props,
|
|
1096
|
+
ref: annotationLayerRef
|
|
1097
|
+
}
|
|
1098
|
+
);
|
|
1099
|
+
}
|
|
1100
|
+
);
|
|
1101
|
+
AnnotationLayer.displayName = "AnnotationLayer";
|
|
1077
1102
|
var useDpr = () => {
|
|
1078
1103
|
const [dpr, setDPR] = useState(
|
|
1079
1104
|
typeof window === "undefined" ? 1 : Math.min(window.devicePixelRatio, 2)
|
|
@@ -1146,6 +1171,7 @@ var useCanvasLayer = ({ background }) => {
|
|
|
1146
1171
|
baseCanvas.style.transform = "translate(0px, 0px)";
|
|
1147
1172
|
baseCanvas.style.zIndex = "0";
|
|
1148
1173
|
baseCanvas.style.pointerEvents = "none";
|
|
1174
|
+
baseCanvas.style.backgroundColor = background ?? "white";
|
|
1149
1175
|
const context = baseCanvas.getContext("2d");
|
|
1150
1176
|
if (!context) {
|
|
1151
1177
|
return;
|
|
@@ -1154,6 +1180,7 @@ var useCanvasLayer = ({ background }) => {
|
|
|
1154
1180
|
context.clearRect(0, 0, baseCanvas.width, baseCanvas.height);
|
|
1155
1181
|
const viewport = pdfPageProxy.getViewport({ scale: baseScale });
|
|
1156
1182
|
const renderingTask = pdfPageProxy.render({
|
|
1183
|
+
canvas: baseCanvas,
|
|
1157
1184
|
canvasContext: context,
|
|
1158
1185
|
viewport,
|
|
1159
1186
|
background
|
|
@@ -1172,8 +1199,74 @@ var useCanvasLayer = ({ background }) => {
|
|
|
1172
1199
|
canvasRef
|
|
1173
1200
|
};
|
|
1174
1201
|
};
|
|
1202
|
+
|
|
1203
|
+
// src/lib/viewport-invalidation.ts
|
|
1204
|
+
var viewportInvalidationRegistry = /* @__PURE__ */ new WeakMap();
|
|
1205
|
+
var notifyCallbacks = (entry) => {
|
|
1206
|
+
entry.rafId = null;
|
|
1207
|
+
entry.callbacks.forEach((callback) => {
|
|
1208
|
+
callback();
|
|
1209
|
+
});
|
|
1210
|
+
};
|
|
1211
|
+
var scheduleInvalidation = (entry) => {
|
|
1212
|
+
if (entry.rafId !== null) {
|
|
1213
|
+
return;
|
|
1214
|
+
}
|
|
1215
|
+
entry.rafId = requestAnimationFrame(() => {
|
|
1216
|
+
notifyCallbacks(entry);
|
|
1217
|
+
});
|
|
1218
|
+
};
|
|
1219
|
+
var subscribeToViewportInvalidation = (viewport, callback) => {
|
|
1220
|
+
let entry = viewportInvalidationRegistry.get(viewport);
|
|
1221
|
+
if (!entry) {
|
|
1222
|
+
const callbacks = /* @__PURE__ */ new Set();
|
|
1223
|
+
const schedule = () => {
|
|
1224
|
+
const currentEntry = viewportInvalidationRegistry.get(viewport);
|
|
1225
|
+
if (!currentEntry) {
|
|
1226
|
+
return;
|
|
1227
|
+
}
|
|
1228
|
+
scheduleInvalidation(currentEntry);
|
|
1229
|
+
};
|
|
1230
|
+
entry = {
|
|
1231
|
+
callbacks,
|
|
1232
|
+
scrollListener: schedule,
|
|
1233
|
+
windowResizeListener: schedule,
|
|
1234
|
+
resizeObserver: typeof ResizeObserver === "undefined" ? void 0 : new ResizeObserver(schedule),
|
|
1235
|
+
rafId: null
|
|
1236
|
+
};
|
|
1237
|
+
viewport.addEventListener("scroll", entry.scrollListener, {
|
|
1238
|
+
passive: true
|
|
1239
|
+
});
|
|
1240
|
+
window.addEventListener("resize", entry.windowResizeListener, {
|
|
1241
|
+
passive: true
|
|
1242
|
+
});
|
|
1243
|
+
entry.resizeObserver?.observe(viewport);
|
|
1244
|
+
viewportInvalidationRegistry.set(viewport, entry);
|
|
1245
|
+
}
|
|
1246
|
+
entry.callbacks.add(callback);
|
|
1247
|
+
return () => {
|
|
1248
|
+
const currentEntry = viewportInvalidationRegistry.get(viewport);
|
|
1249
|
+
if (!currentEntry) {
|
|
1250
|
+
return;
|
|
1251
|
+
}
|
|
1252
|
+
currentEntry.callbacks.delete(callback);
|
|
1253
|
+
if (currentEntry.callbacks.size > 0) {
|
|
1254
|
+
return;
|
|
1255
|
+
}
|
|
1256
|
+
if (currentEntry.rafId !== null) {
|
|
1257
|
+
cancelAnimationFrame(currentEntry.rafId);
|
|
1258
|
+
}
|
|
1259
|
+
viewport.removeEventListener("scroll", currentEntry.scrollListener);
|
|
1260
|
+
window.removeEventListener("resize", currentEntry.windowResizeListener);
|
|
1261
|
+
currentEntry.resizeObserver?.disconnect();
|
|
1262
|
+
viewportInvalidationRegistry.delete(viewport);
|
|
1263
|
+
};
|
|
1264
|
+
};
|
|
1265
|
+
|
|
1266
|
+
// src/hooks/layers/useDetailCanvasLayer.tsx
|
|
1175
1267
|
var MAX_CANVAS_PIXELS2 = 16777216;
|
|
1176
1268
|
var MAX_CANVAS_DIMENSION2 = 32767;
|
|
1269
|
+
var DETAIL_RENDER_IDLE_MS = 80;
|
|
1177
1270
|
var useDetailCanvasLayer = ({
|
|
1178
1271
|
background,
|
|
1179
1272
|
baseCanvasRef
|
|
@@ -1183,29 +1276,23 @@ var useDetailCanvasLayer = ({
|
|
|
1183
1276
|
const pageNumber = usePDFPageNumber();
|
|
1184
1277
|
const dpr = useDpr();
|
|
1185
1278
|
const bouncyZoom = usePdf((state) => state.zoom);
|
|
1279
|
+
const isPinching = usePdf((state) => state.isPinching);
|
|
1186
1280
|
const pdfPageProxy = usePdf((state) => state.getPdfPageProxy(pageNumber));
|
|
1187
1281
|
const viewportRef = usePdf((state) => state.viewportRef);
|
|
1188
1282
|
const [zoom] = useDebounce(bouncyZoom, 200);
|
|
1189
|
-
const
|
|
1190
|
-
|
|
1191
|
-
const ensureDetailCanvas = useCallback(() => {
|
|
1192
|
-
let detailCanvas = detailCanvasRef.current;
|
|
1283
|
+
const getDetailCanvas = useCallback(() => {
|
|
1284
|
+
const detailCanvas = detailCanvasRef.current;
|
|
1193
1285
|
if (!detailCanvas) {
|
|
1194
|
-
|
|
1195
|
-
if (!parent) {
|
|
1196
|
-
return null;
|
|
1197
|
-
}
|
|
1198
|
-
detailCanvas = document.createElement("canvas");
|
|
1199
|
-
parent.appendChild(detailCanvas);
|
|
1200
|
-
detailCanvasRef.current = detailCanvas;
|
|
1286
|
+
return null;
|
|
1201
1287
|
}
|
|
1202
1288
|
detailCanvas.style.position = "absolute";
|
|
1203
1289
|
detailCanvas.style.top = "0";
|
|
1204
1290
|
detailCanvas.style.left = "0";
|
|
1205
1291
|
detailCanvas.style.pointerEvents = "none";
|
|
1206
|
-
detailCanvas.style.zIndex = "
|
|
1292
|
+
detailCanvas.style.zIndex = "1";
|
|
1293
|
+
detailCanvas.style.backgroundColor = background ?? "white";
|
|
1207
1294
|
return detailCanvas;
|
|
1208
|
-
}, [
|
|
1295
|
+
}, [background]);
|
|
1209
1296
|
const clampScaleForPage = useCallback(
|
|
1210
1297
|
(targetScale, pageWidth, pageHeight) => {
|
|
1211
1298
|
if (!targetScale) {
|
|
@@ -1228,151 +1315,183 @@ var useDetailCanvasLayer = ({
|
|
|
1228
1315
|
);
|
|
1229
1316
|
useLayoutEffect(() => {
|
|
1230
1317
|
const scrollContainer = viewportRef?.current;
|
|
1231
|
-
if (!scrollContainer)
|
|
1232
|
-
const handleScroll = () => {
|
|
1233
|
-
setScrollTick((prev) => prev + 1);
|
|
1234
|
-
};
|
|
1235
|
-
scrollContainer.addEventListener("scroll", handleScroll, { passive: true });
|
|
1236
|
-
return () => {
|
|
1237
|
-
scrollContainer.removeEventListener("scroll", handleScroll);
|
|
1238
|
-
};
|
|
1239
|
-
}, [viewportRef?.current]);
|
|
1240
|
-
useLayoutEffect(() => {
|
|
1241
|
-
if (!viewportRef?.current) {
|
|
1318
|
+
if (!scrollContainer) {
|
|
1242
1319
|
return;
|
|
1243
1320
|
}
|
|
1244
|
-
const detailCanvas =
|
|
1321
|
+
const detailCanvas = getDetailCanvas();
|
|
1245
1322
|
const container = containerRef.current;
|
|
1246
1323
|
if (!detailCanvas || !container) {
|
|
1247
1324
|
return;
|
|
1248
1325
|
}
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
detailCanvas.
|
|
1254
|
-
detailCanvas.
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
const
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
const viewportWidth = scrollContainer.clientWidth / zoom;
|
|
1263
|
-
const viewportHeight = scrollContainer.clientHeight / zoom;
|
|
1264
|
-
const pageRect = pageContainer.getBoundingClientRect();
|
|
1265
|
-
const containerRect = scrollContainer.getBoundingClientRect();
|
|
1266
|
-
const pageLeft = (pageRect.left - containerRect.left) / zoom + scrollX;
|
|
1267
|
-
const pageTop = (pageRect.top - containerRect.top) / zoom + scrollY;
|
|
1268
|
-
const visibleLeft = Math.max(0, scrollX - pageLeft);
|
|
1269
|
-
const visibleTop = Math.max(0, scrollY - pageTop);
|
|
1270
|
-
const visibleRight = Math.min(
|
|
1271
|
-
pageWidth,
|
|
1272
|
-
scrollX + viewportWidth - pageLeft
|
|
1273
|
-
);
|
|
1274
|
-
const visibleBottom = Math.min(
|
|
1275
|
-
pageHeight,
|
|
1276
|
-
scrollY + viewportHeight - pageTop
|
|
1277
|
-
);
|
|
1278
|
-
const visibleWidth = Math.max(0, visibleRight - visibleLeft);
|
|
1279
|
-
const visibleHeight = Math.max(0, visibleBottom - visibleTop);
|
|
1280
|
-
const targetDetailScale = dpr * zoom * 1.3;
|
|
1281
|
-
const baseTargetScale = dpr * Math.min(zoom, 1);
|
|
1282
|
-
const baseScale = clampScaleForPage(baseTargetScale, pageWidth, pageHeight);
|
|
1283
|
-
const needsDetail = zoom > 1 && targetDetailScale - baseScale > 1e-3;
|
|
1284
|
-
if (!needsDetail || visibleWidth <= 0 || visibleHeight <= 0) {
|
|
1285
|
-
detailCanvas.style.display = "none";
|
|
1286
|
-
detailCanvas.width = 0;
|
|
1287
|
-
detailCanvas.height = 0;
|
|
1288
|
-
return;
|
|
1289
|
-
}
|
|
1290
|
-
detailCanvas.style.display = "block";
|
|
1291
|
-
const pdfOffsetX = visibleLeft;
|
|
1292
|
-
const pdfOffsetY = visibleTop;
|
|
1293
|
-
const pdfWidth = visibleWidth * targetDetailScale;
|
|
1294
|
-
const pdfHeight = visibleHeight * targetDetailScale;
|
|
1295
|
-
const effectiveScale = targetDetailScale;
|
|
1296
|
-
const actualWidth = pdfWidth;
|
|
1297
|
-
const actualHeight = pdfHeight;
|
|
1298
|
-
detailCanvas.width = actualWidth;
|
|
1299
|
-
detailCanvas.height = actualHeight;
|
|
1300
|
-
const scaledWidth = visibleWidth * zoom;
|
|
1301
|
-
const scaledHeight = visibleHeight * zoom;
|
|
1302
|
-
detailCanvas.style.width = `${scaledWidth}px`;
|
|
1303
|
-
detailCanvas.style.height = `${scaledHeight}px`;
|
|
1304
|
-
detailCanvas.style.transformOrigin = "center center";
|
|
1305
|
-
detailCanvas.style.transform = `translate(${visibleLeft * zoom}px, ${visibleTop * zoom}px) `;
|
|
1306
|
-
container.style.transform = `scale3d(${1 / zoom}, ${1 / zoom}, 1)`;
|
|
1307
|
-
container.style.transformOrigin = `0 0`;
|
|
1308
|
-
const context = detailCanvas.getContext("2d");
|
|
1309
|
-
if (!context) {
|
|
1310
|
-
return;
|
|
1311
|
-
}
|
|
1312
|
-
context.setTransform(1, 0, 0, 1, 0, 0);
|
|
1313
|
-
context.clearRect(0, 0, detailCanvas.width, detailCanvas.height);
|
|
1314
|
-
const transform = [
|
|
1315
|
-
1,
|
|
1316
|
-
0,
|
|
1317
|
-
0,
|
|
1318
|
-
1,
|
|
1319
|
-
-pdfOffsetX * effectiveScale,
|
|
1320
|
-
-pdfOffsetY * effectiveScale
|
|
1321
|
-
];
|
|
1322
|
-
const detailViewport = pdfPageProxy.getViewport({ scale: effectiveScale });
|
|
1323
|
-
const renderingTask = pdfPageProxy.render({
|
|
1324
|
-
canvasContext: context,
|
|
1325
|
-
viewport: detailViewport,
|
|
1326
|
-
background,
|
|
1327
|
-
transform
|
|
1328
|
-
});
|
|
1329
|
-
renderingTask.promise.catch((error) => {
|
|
1330
|
-
if (error.name === "RenderingCancelledException") {
|
|
1326
|
+
let renderingTask = null;
|
|
1327
|
+
let renderTimeoutId = null;
|
|
1328
|
+
const hideDetailCanvas = () => {
|
|
1329
|
+
renderingTask?.cancel();
|
|
1330
|
+
detailCanvas.style.display = "block";
|
|
1331
|
+
detailCanvas.style.opacity = "0";
|
|
1332
|
+
container.style.transform = "";
|
|
1333
|
+
container.style.transformOrigin = "";
|
|
1334
|
+
};
|
|
1335
|
+
const renderDetailCanvas = () => {
|
|
1336
|
+
const pageContainer = baseCanvasRef.current?.parentElement ?? null;
|
|
1337
|
+
if (!pageContainer) {
|
|
1338
|
+
hideDetailCanvas();
|
|
1331
1339
|
return;
|
|
1332
1340
|
}
|
|
1333
|
-
|
|
1334
|
-
|
|
1341
|
+
const baseViewport = pdfPageProxy.getViewport({ scale: 1 });
|
|
1342
|
+
const pageWidth = baseViewport.width;
|
|
1343
|
+
const pageHeight = baseViewport.height;
|
|
1344
|
+
const scrollX = scrollContainer.scrollLeft / zoom;
|
|
1345
|
+
const scrollY = scrollContainer.scrollTop / zoom;
|
|
1346
|
+
const viewportWidth = scrollContainer.clientWidth / zoom;
|
|
1347
|
+
const viewportHeight = scrollContainer.clientHeight / zoom;
|
|
1348
|
+
const pageRect = pageContainer.getBoundingClientRect();
|
|
1349
|
+
const containerRect = scrollContainer.getBoundingClientRect();
|
|
1350
|
+
const pageLeft = (pageRect.left - containerRect.left) / zoom + scrollX;
|
|
1351
|
+
const pageTop = (pageRect.top - containerRect.top) / zoom + scrollY;
|
|
1352
|
+
const visibleLeft = Math.max(0, scrollX - pageLeft);
|
|
1353
|
+
const visibleTop = Math.max(0, scrollY - pageTop);
|
|
1354
|
+
const visibleRight = Math.min(
|
|
1355
|
+
pageWidth,
|
|
1356
|
+
scrollX + viewportWidth - pageLeft
|
|
1357
|
+
);
|
|
1358
|
+
const visibleBottom = Math.min(
|
|
1359
|
+
pageHeight,
|
|
1360
|
+
scrollY + viewportHeight - pageTop
|
|
1361
|
+
);
|
|
1362
|
+
const visibleWidth = Math.max(0, visibleRight - visibleLeft);
|
|
1363
|
+
const visibleHeight = Math.max(0, visibleBottom - visibleTop);
|
|
1364
|
+
const targetDetailScale = dpr * zoom * 1.3;
|
|
1365
|
+
const baseTargetScale = dpr * Math.min(zoom, 1);
|
|
1366
|
+
const baseScale = clampScaleForPage(
|
|
1367
|
+
baseTargetScale,
|
|
1368
|
+
pageWidth,
|
|
1369
|
+
pageHeight
|
|
1370
|
+
);
|
|
1371
|
+
const needsDetail = zoom > 1 && targetDetailScale - baseScale > 1e-3;
|
|
1372
|
+
if (isPinching || !needsDetail || visibleWidth <= 0 || visibleHeight <= 0) {
|
|
1373
|
+
hideDetailCanvas();
|
|
1374
|
+
return;
|
|
1375
|
+
}
|
|
1376
|
+
renderingTask?.cancel();
|
|
1377
|
+
detailCanvas.style.display = "block";
|
|
1378
|
+
detailCanvas.style.opacity = "0";
|
|
1379
|
+
const pdfOffsetX = visibleLeft;
|
|
1380
|
+
const pdfOffsetY = visibleTop;
|
|
1381
|
+
const effectiveScale = targetDetailScale;
|
|
1382
|
+
const actualWidth = visibleWidth * effectiveScale;
|
|
1383
|
+
const actualHeight = visibleHeight * effectiveScale;
|
|
1384
|
+
detailCanvas.width = actualWidth;
|
|
1385
|
+
detailCanvas.height = actualHeight;
|
|
1386
|
+
detailCanvas.style.width = `${visibleWidth * zoom}px`;
|
|
1387
|
+
detailCanvas.style.height = `${visibleHeight * zoom}px`;
|
|
1388
|
+
detailCanvas.style.transformOrigin = "center center";
|
|
1389
|
+
detailCanvas.style.transform = `translate(${visibleLeft * zoom}px, ${visibleTop * zoom}px)`;
|
|
1390
|
+
container.style.transform = `scale3d(${1 / zoom}, ${1 / zoom}, 1)`;
|
|
1391
|
+
container.style.transformOrigin = "0 0";
|
|
1392
|
+
const context = detailCanvas.getContext("2d");
|
|
1393
|
+
if (!context) {
|
|
1394
|
+
return;
|
|
1395
|
+
}
|
|
1396
|
+
context.setTransform(1, 0, 0, 1, 0, 0);
|
|
1397
|
+
context.clearRect(0, 0, detailCanvas.width, detailCanvas.height);
|
|
1398
|
+
const transform = [
|
|
1399
|
+
1,
|
|
1400
|
+
0,
|
|
1401
|
+
0,
|
|
1402
|
+
1,
|
|
1403
|
+
-pdfOffsetX * effectiveScale,
|
|
1404
|
+
-pdfOffsetY * effectiveScale
|
|
1405
|
+
];
|
|
1406
|
+
const detailViewport = pdfPageProxy.getViewport({
|
|
1407
|
+
scale: effectiveScale
|
|
1408
|
+
});
|
|
1409
|
+
const currentRenderingTask = pdfPageProxy.render({
|
|
1410
|
+
canvas: detailCanvas,
|
|
1411
|
+
canvasContext: context,
|
|
1412
|
+
viewport: detailViewport,
|
|
1413
|
+
background,
|
|
1414
|
+
transform
|
|
1415
|
+
});
|
|
1416
|
+
renderingTask = currentRenderingTask;
|
|
1417
|
+
currentRenderingTask.promise.then(() => {
|
|
1418
|
+
if (renderingTask === currentRenderingTask) {
|
|
1419
|
+
detailCanvas.style.opacity = "1";
|
|
1420
|
+
}
|
|
1421
|
+
}).catch((error) => {
|
|
1422
|
+
if (error.name === "RenderingCancelledException") {
|
|
1423
|
+
return;
|
|
1424
|
+
}
|
|
1425
|
+
throw error;
|
|
1426
|
+
}).finally(() => {
|
|
1427
|
+
if (renderingTask === currentRenderingTask) {
|
|
1428
|
+
renderingTask = null;
|
|
1429
|
+
}
|
|
1430
|
+
});
|
|
1431
|
+
};
|
|
1432
|
+
const scheduleRender = (delay = DETAIL_RENDER_IDLE_MS) => {
|
|
1433
|
+
if (renderTimeoutId !== null) {
|
|
1434
|
+
clearTimeout(renderTimeoutId);
|
|
1435
|
+
}
|
|
1436
|
+
hideDetailCanvas();
|
|
1437
|
+
renderTimeoutId = setTimeout(() => {
|
|
1438
|
+
renderTimeoutId = null;
|
|
1439
|
+
renderDetailCanvas();
|
|
1440
|
+
}, delay);
|
|
1441
|
+
};
|
|
1442
|
+
const unsubscribe = subscribeToViewportInvalidation(
|
|
1443
|
+
scrollContainer,
|
|
1444
|
+
scheduleRender
|
|
1445
|
+
);
|
|
1446
|
+
scheduleRender(isPinching ? DETAIL_RENDER_IDLE_MS * 2 : 0);
|
|
1335
1447
|
return () => {
|
|
1336
|
-
|
|
1448
|
+
unsubscribe();
|
|
1449
|
+
if (renderTimeoutId !== null) {
|
|
1450
|
+
clearTimeout(renderTimeoutId);
|
|
1451
|
+
}
|
|
1452
|
+
void renderingTask?.cancel();
|
|
1337
1453
|
};
|
|
1338
1454
|
}, [
|
|
1339
1455
|
pdfPageProxy,
|
|
1340
1456
|
zoom,
|
|
1457
|
+
isPinching,
|
|
1341
1458
|
background,
|
|
1342
1459
|
dpr,
|
|
1343
1460
|
viewportRef,
|
|
1344
|
-
|
|
1461
|
+
getDetailCanvas,
|
|
1345
1462
|
clampScaleForPage,
|
|
1346
|
-
baseCanvasRef
|
|
1347
|
-
debouncedScrollTick
|
|
1463
|
+
baseCanvasRef
|
|
1348
1464
|
]);
|
|
1349
1465
|
return {
|
|
1350
1466
|
detailCanvasRef,
|
|
1351
1467
|
containerRef
|
|
1352
1468
|
};
|
|
1353
1469
|
};
|
|
1354
|
-
var CanvasLayer = (
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
...props
|
|
1358
|
-
}) => {
|
|
1359
|
-
const { canvasRef } = useCanvasLayer({ background });
|
|
1360
|
-
const { detailCanvasRef, containerRef } = useDetailCanvasLayer({
|
|
1470
|
+
var CanvasLayer = memo(
|
|
1471
|
+
({
|
|
1472
|
+
style,
|
|
1361
1473
|
background,
|
|
1362
|
-
|
|
1363
|
-
})
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1474
|
+
...props
|
|
1475
|
+
}) => {
|
|
1476
|
+
const { canvasRef } = useCanvasLayer({ background });
|
|
1477
|
+
const { detailCanvasRef, containerRef } = useDetailCanvasLayer({
|
|
1478
|
+
background,
|
|
1479
|
+
baseCanvasRef: canvasRef
|
|
1480
|
+
});
|
|
1481
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1482
|
+
/* @__PURE__ */ jsx("canvas", { ...props, ref: canvasRef, style }),
|
|
1483
|
+
/* @__PURE__ */ jsx(
|
|
1484
|
+
"div",
|
|
1485
|
+
{
|
|
1486
|
+
ref: containerRef,
|
|
1487
|
+
className: "absolute top-0 left-0 w-full h-full flex items-center justify-center",
|
|
1488
|
+
children: /* @__PURE__ */ jsx("canvas", { ref: detailCanvasRef })
|
|
1489
|
+
}
|
|
1490
|
+
)
|
|
1491
|
+
] });
|
|
1492
|
+
}
|
|
1493
|
+
);
|
|
1494
|
+
CanvasLayer.displayName = "CanvasLayer";
|
|
1376
1495
|
|
|
1377
1496
|
// src/hooks/useSelectionDimensions.tsx
|
|
1378
1497
|
var MERGE_THRESHOLD = 2;
|
|
@@ -2118,14 +2237,13 @@ var ColoredHighlightLayer = ({
|
|
|
2118
2237
|
)
|
|
2119
2238
|
] });
|
|
2120
2239
|
};
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
}
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
};
|
|
2240
|
+
var CustomLayer = memo(
|
|
2241
|
+
({ children }) => {
|
|
2242
|
+
const pageNumber = usePDFPageNumber();
|
|
2243
|
+
return children(pageNumber);
|
|
2244
|
+
}
|
|
2245
|
+
);
|
|
2246
|
+
CustomLayer.displayName = "CustomLayer";
|
|
2129
2247
|
var convertToPercentString = (rect) => {
|
|
2130
2248
|
return {
|
|
2131
2249
|
top: `${rect.top}%`,
|
|
@@ -2319,25 +2437,33 @@ var useTextLayer = () => {
|
|
|
2319
2437
|
if (!textContainer || isRenderingRef.current) {
|
|
2320
2438
|
return;
|
|
2321
2439
|
}
|
|
2440
|
+
let isCancelled = false;
|
|
2322
2441
|
isRenderingRef.current = true;
|
|
2323
2442
|
textContainer.innerHTML = "";
|
|
2324
2443
|
if (textLayerRef.current) {
|
|
2325
2444
|
textLayerRef.current.cancel();
|
|
2326
2445
|
textLayerRef.current = null;
|
|
2327
2446
|
}
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2447
|
+
void loadPdfJs().then(({ TextLayer: TextLayer2 }) => {
|
|
2448
|
+
if (isCancelled || textContainerRef.current !== textContainer) {
|
|
2449
|
+
return;
|
|
2450
|
+
}
|
|
2451
|
+
const textLayer = new TextLayer2({
|
|
2452
|
+
textContentSource: pdfPageProxy.streamTextContent(),
|
|
2453
|
+
container: textContainer,
|
|
2454
|
+
viewport: pdfPageProxy.getViewport({ scale: 1 })
|
|
2455
|
+
});
|
|
2456
|
+
textLayerRef.current = textLayer;
|
|
2457
|
+
return textLayer.render();
|
|
2458
|
+
}).then(() => {
|
|
2459
|
+
const textLayer = textLayerRef.current;
|
|
2460
|
+
if (!textLayer || isCancelled || textContainerRef.current !== textContainer) {
|
|
2461
|
+
return;
|
|
2340
2462
|
}
|
|
2463
|
+
const endOfContent = document.createElement("div");
|
|
2464
|
+
endOfContent.className = "endOfContent";
|
|
2465
|
+
textContainer.appendChild(endOfContent);
|
|
2466
|
+
bindMouseEvents(textContainer, endOfContent);
|
|
2341
2467
|
}).catch((error) => {
|
|
2342
2468
|
if (error.name !== "AbortException") {
|
|
2343
2469
|
console.error("TextLayer rendering error:", error);
|
|
@@ -2346,6 +2472,7 @@ var useTextLayer = () => {
|
|
|
2346
2472
|
isRenderingRef.current = false;
|
|
2347
2473
|
});
|
|
2348
2474
|
return () => {
|
|
2475
|
+
isCancelled = true;
|
|
2349
2476
|
isRenderingRef.current = false;
|
|
2350
2477
|
if (textLayerRef.current) {
|
|
2351
2478
|
textLayerRef.current.cancel();
|
|
@@ -2362,30 +2489,29 @@ var useTextLayer = () => {
|
|
|
2362
2489
|
pageNumber: pdfPageProxy.pageNumber
|
|
2363
2490
|
};
|
|
2364
2491
|
};
|
|
2365
|
-
var
|
|
2366
|
-
className,
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
};
|
|
2492
|
+
var TextLayer = memo(
|
|
2493
|
+
({ className, style, ...props }) => {
|
|
2494
|
+
const { textContainerRef, pageNumber } = useTextLayer();
|
|
2495
|
+
return /* @__PURE__ */ jsx(
|
|
2496
|
+
"div",
|
|
2497
|
+
{
|
|
2498
|
+
className: clsx_default("textLayer", className),
|
|
2499
|
+
style: {
|
|
2500
|
+
...style,
|
|
2501
|
+
position: "absolute",
|
|
2502
|
+
top: 0,
|
|
2503
|
+
left: 0
|
|
2504
|
+
},
|
|
2505
|
+
...props,
|
|
2506
|
+
...{
|
|
2507
|
+
"data-page-number": pageNumber
|
|
2508
|
+
},
|
|
2509
|
+
ref: textContainerRef
|
|
2510
|
+
}
|
|
2511
|
+
);
|
|
2512
|
+
}
|
|
2513
|
+
);
|
|
2514
|
+
TextLayer.displayName = "TextLayer";
|
|
2389
2515
|
var usePDFOutline = () => {
|
|
2390
2516
|
const pdfDocumentProxy = usePdf((state) => state.pdfDocumentProxy);
|
|
2391
2517
|
const [outline, setOutline] = useState();
|
|
@@ -2523,40 +2649,44 @@ var Outline = ({
|
|
|
2523
2649
|
});
|
|
2524
2650
|
}) });
|
|
2525
2651
|
};
|
|
2526
|
-
var Page = (
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
}
|
|
2652
|
+
var Page = memo(
|
|
2653
|
+
({
|
|
2654
|
+
children,
|
|
2655
|
+
pageNumber = 1,
|
|
2656
|
+
style,
|
|
2657
|
+
...props
|
|
2658
|
+
}) => {
|
|
2659
|
+
const pdfPageProxy = usePdf((state) => state.getPdfPageProxy(pageNumber));
|
|
2660
|
+
const viewport = usePdf((state) => state.viewports[pageNumber - 1]);
|
|
2661
|
+
const width = viewport?.width ?? (pdfPageProxy.view[2] ?? 0) - (pdfPageProxy.view[0] ?? 0);
|
|
2662
|
+
const height = viewport?.height ?? (pdfPageProxy.view[3] ?? 0) - (pdfPageProxy.view[1] ?? 0);
|
|
2663
|
+
return /* @__PURE__ */ jsx(PDFPageNumberContext.Provider, { value: pdfPageProxy.pageNumber, children: /* @__PURE__ */ jsx(
|
|
2664
|
+
Primitive.div,
|
|
2665
|
+
{
|
|
2666
|
+
style: {
|
|
2667
|
+
display: "block"
|
|
2668
|
+
},
|
|
2669
|
+
children: /* @__PURE__ */ jsx(
|
|
2670
|
+
"div",
|
|
2671
|
+
{
|
|
2672
|
+
style: {
|
|
2673
|
+
"--scale-factor": 1,
|
|
2674
|
+
"--total-scale-factor": 1,
|
|
2675
|
+
backgroundColor: "white",
|
|
2676
|
+
position: "relative",
|
|
2677
|
+
width,
|
|
2678
|
+
height,
|
|
2679
|
+
...style
|
|
2680
|
+
},
|
|
2681
|
+
...props,
|
|
2682
|
+
children
|
|
2683
|
+
}
|
|
2684
|
+
)
|
|
2685
|
+
}
|
|
2686
|
+
) });
|
|
2687
|
+
}
|
|
2688
|
+
);
|
|
2689
|
+
Page.displayName = "Page";
|
|
2560
2690
|
var NextPage = () => {
|
|
2561
2691
|
};
|
|
2562
2692
|
var PreviousPage = () => {
|
|
@@ -3177,10 +3307,10 @@ var Engine = class {
|
|
|
3177
3307
|
const config = this.config;
|
|
3178
3308
|
if (!state._active) this.clean();
|
|
3179
3309
|
if ((state._blocked || !state.intentional) && !state._force && !config.triggerAllEvents) return;
|
|
3180
|
-
const
|
|
3310
|
+
const memo7 = this.handler(_objectSpread2(_objectSpread2(_objectSpread2({}, shared), state), {}, {
|
|
3181
3311
|
[this.aliasKey]: state.values
|
|
3182
3312
|
}));
|
|
3183
|
-
if (
|
|
3313
|
+
if (memo7 !== void 0) state.memo = memo7;
|
|
3184
3314
|
}
|
|
3185
3315
|
clean() {
|
|
3186
3316
|
this.eventStore.clean();
|
|
@@ -4529,11 +4659,11 @@ Please add \`${key}Action\` when creating your handler.`);
|
|
|
4529
4659
|
const startKey = handlerKey + "Start";
|
|
4530
4660
|
const endKey = handlerKey + "End";
|
|
4531
4661
|
const fn = (state) => {
|
|
4532
|
-
let
|
|
4662
|
+
let memo7 = void 0;
|
|
4533
4663
|
if (state.first && startKey in handlers) handlers[startKey](state);
|
|
4534
|
-
if (handlerKey in handlers)
|
|
4664
|
+
if (handlerKey in handlers) memo7 = handlers[handlerKey](state);
|
|
4535
4665
|
if (state.last && endKey in handlers) handlers[endKey](state);
|
|
4536
|
-
return
|
|
4666
|
+
return memo7;
|
|
4537
4667
|
};
|
|
4538
4668
|
internalHandlers[key] = fn;
|
|
4539
4669
|
config[key] = config[key] || {};
|
|
@@ -4585,8 +4715,8 @@ function useGesture(handlers, config) {
|
|
|
4585
4715
|
}
|
|
4586
4716
|
|
|
4587
4717
|
// src/lib/memo.ts
|
|
4588
|
-
var firstMemo = (first,
|
|
4589
|
-
if (!first && !
|
|
4718
|
+
var firstMemo = (first, memo7, initializer) => {
|
|
4719
|
+
if (!first && !memo7) {
|
|
4590
4720
|
throw new Error(
|
|
4591
4721
|
"Missing memo initialization. You likely forgot to return the result of `firstMemo` in the event function"
|
|
4592
4722
|
);
|
|
@@ -4594,7 +4724,7 @@ var firstMemo = (first, memo, initializer) => {
|
|
|
4594
4724
|
if (first) {
|
|
4595
4725
|
return initializer();
|
|
4596
4726
|
}
|
|
4597
|
-
return
|
|
4727
|
+
return memo7;
|
|
4598
4728
|
};
|
|
4599
4729
|
|
|
4600
4730
|
// src/hooks/viewport/useViewportContainer.tsx
|
|
@@ -4726,13 +4856,13 @@ var useViewportContainer = ({
|
|
|
4726
4856
|
useGesture(
|
|
4727
4857
|
{
|
|
4728
4858
|
onPinch: (state) => {
|
|
4729
|
-
const { origin: origin2, first, movement, delta, event, memo } = state;
|
|
4859
|
+
const { origin: origin2, first, movement, delta, event, memo: memo7 } = state;
|
|
4730
4860
|
const [ms] = movement;
|
|
4731
4861
|
const [deltaScale] = delta;
|
|
4732
4862
|
const currentElement = elementRef.current;
|
|
4733
4863
|
const currentContainer = containerRef.current;
|
|
4734
4864
|
if (!currentElement || !currentContainer) return;
|
|
4735
|
-
const newMemo = firstMemo(first,
|
|
4865
|
+
const newMemo = firstMemo(first, memo7, () => {
|
|
4736
4866
|
const elementRect = currentElement.getBoundingClientRect();
|
|
4737
4867
|
const containerRect = currentContainer.getBoundingClientRect();
|
|
4738
4868
|
const currentZoom = transformations.current.zoom;
|
|
@@ -4801,10 +4931,39 @@ var useViewportContainer = ({
|
|
|
4801
4931
|
};
|
|
4802
4932
|
var DEFAULT_HEIGHT = 600;
|
|
4803
4933
|
var EXTRA_HEIGHT = 0;
|
|
4934
|
+
var VirtualizedPageItem = memo(
|
|
4935
|
+
({ child, virtualItem, innerBoxWidth }) => {
|
|
4936
|
+
return /* @__PURE__ */ jsx(
|
|
4937
|
+
"div",
|
|
4938
|
+
{
|
|
4939
|
+
style: {
|
|
4940
|
+
width: innerBoxWidth,
|
|
4941
|
+
height: "0px"
|
|
4942
|
+
},
|
|
4943
|
+
children: /* @__PURE__ */ jsx(
|
|
4944
|
+
"div",
|
|
4945
|
+
{
|
|
4946
|
+
style: {
|
|
4947
|
+
height: `${virtualItem.size}px`,
|
|
4948
|
+
transform: `translateY(${virtualItem.start}px)`
|
|
4949
|
+
},
|
|
4950
|
+
children: cloneElement(child, {
|
|
4951
|
+
key: virtualItem.key,
|
|
4952
|
+
//@ts-expect-error pageNumber is not a valid react key
|
|
4953
|
+
pageNumber: virtualItem.index + 1
|
|
4954
|
+
})
|
|
4955
|
+
}
|
|
4956
|
+
)
|
|
4957
|
+
}
|
|
4958
|
+
);
|
|
4959
|
+
},
|
|
4960
|
+
(prev, next) => prev.child === next.child && prev.innerBoxWidth === next.innerBoxWidth && prev.virtualItem.key === next.virtualItem.key && prev.virtualItem.index === next.virtualItem.index && prev.virtualItem.size === next.virtualItem.size && prev.virtualItem.start === next.virtualItem.start
|
|
4961
|
+
);
|
|
4962
|
+
VirtualizedPageItem.displayName = "VirtualizedPageItem";
|
|
4804
4963
|
var Pages = ({
|
|
4805
4964
|
children,
|
|
4806
4965
|
gap = 10,
|
|
4807
|
-
virtualizerOptions = { overscan:
|
|
4966
|
+
virtualizerOptions = { overscan: 1 },
|
|
4808
4967
|
initialOffset,
|
|
4809
4968
|
onOffsetChange,
|
|
4810
4969
|
...props
|
|
@@ -4870,7 +5029,9 @@ var Pages = ({
|
|
|
4870
5029
|
});
|
|
4871
5030
|
useFitWidth({ viewportRef: containerRef });
|
|
4872
5031
|
const largestPageWidth = usePdf(
|
|
4873
|
-
(state) =>
|
|
5032
|
+
(state) => state.viewports.reduce((largestWidth, viewport) => {
|
|
5033
|
+
return Math.max(largestWidth, viewport.width);
|
|
5034
|
+
}, 0)
|
|
4874
5035
|
);
|
|
4875
5036
|
useEffect(() => {
|
|
4876
5037
|
virtualizer.getOffsetForAlignment = (toOffset, align, itemSize = 0) => {
|
|
@@ -4931,26 +5092,11 @@ var Pages = ({
|
|
|
4931
5092
|
const innerBoxWidth = viewports?.[virtualItem.index] ? viewports[virtualItem.index]?.width : 0;
|
|
4932
5093
|
if (!innerBoxWidth) return null;
|
|
4933
5094
|
return /* @__PURE__ */ jsx(
|
|
4934
|
-
|
|
5095
|
+
VirtualizedPageItem,
|
|
4935
5096
|
{
|
|
4936
|
-
|
|
4937
|
-
|
|
4938
|
-
|
|
4939
|
-
},
|
|
4940
|
-
children: /* @__PURE__ */ jsx(
|
|
4941
|
-
"div",
|
|
4942
|
-
{
|
|
4943
|
-
style: {
|
|
4944
|
-
height: `${virtualItem.size}px`,
|
|
4945
|
-
transform: `translateY(${virtualItem.start}px)`
|
|
4946
|
-
},
|
|
4947
|
-
children: cloneElement(children, {
|
|
4948
|
-
key: virtualItem.key,
|
|
4949
|
-
//@ts-expect-error pageNumber is not a valid react key
|
|
4950
|
-
pageNumber: virtualItem.index + 1
|
|
4951
|
-
})
|
|
4952
|
-
}
|
|
4953
|
-
)
|
|
5097
|
+
child: children,
|
|
5098
|
+
virtualItem,
|
|
5099
|
+
innerBoxWidth
|
|
4954
5100
|
},
|
|
4955
5101
|
virtualItem.key
|
|
4956
5102
|
);
|
|
@@ -5006,28 +5152,44 @@ var usePDFDocumentContext = ({
|
|
|
5006
5152
|
const loadDocument = () => {
|
|
5007
5153
|
setInitialState(null);
|
|
5008
5154
|
setProgress(0);
|
|
5009
|
-
|
|
5010
|
-
|
|
5011
|
-
|
|
5155
|
+
let loadingTask = null;
|
|
5156
|
+
let isDisposed = false;
|
|
5157
|
+
void loadPdfJs().then(({ getDocument }) => {
|
|
5158
|
+
if (isDisposed) {
|
|
5012
5159
|
return;
|
|
5013
5160
|
}
|
|
5014
|
-
|
|
5015
|
-
|
|
5016
|
-
|
|
5017
|
-
|
|
5018
|
-
|
|
5019
|
-
|
|
5161
|
+
loadingTask = getDocument(source);
|
|
5162
|
+
loadingTask.onProgress = (progressEvent) => {
|
|
5163
|
+
if (progressEvent.loaded === progressEvent.total) {
|
|
5164
|
+
return;
|
|
5165
|
+
}
|
|
5166
|
+
setProgress(progressEvent.loaded / progressEvent.total);
|
|
5167
|
+
};
|
|
5168
|
+
return loadingTask.promise.then((proxy) => {
|
|
5169
|
+
if (isDisposed || loadingTask?.destroyed) {
|
|
5170
|
+
return;
|
|
5171
|
+
}
|
|
5172
|
+
onDocumentLoad?.({ proxy, source });
|
|
5173
|
+
setProgress(1);
|
|
5174
|
+
return generateViewports(proxy);
|
|
5175
|
+
}).catch((error) => {
|
|
5176
|
+
if (isDisposed || loadingTask?.destroyed) {
|
|
5177
|
+
return;
|
|
5178
|
+
}
|
|
5179
|
+
console.error("Error loading PDF document", error);
|
|
5180
|
+
});
|
|
5020
5181
|
}).catch((error) => {
|
|
5021
|
-
if (
|
|
5182
|
+
if (isDisposed) {
|
|
5022
5183
|
return;
|
|
5023
5184
|
}
|
|
5024
|
-
console.error("Error loading PDF
|
|
5185
|
+
console.error("Error loading PDF.js", error);
|
|
5025
5186
|
});
|
|
5026
5187
|
return () => {
|
|
5027
|
-
|
|
5188
|
+
isDisposed = true;
|
|
5189
|
+
void loadingTask?.destroy();
|
|
5028
5190
|
};
|
|
5029
5191
|
};
|
|
5030
|
-
loadDocument();
|
|
5192
|
+
return loadDocument();
|
|
5031
5193
|
}, [source]);
|
|
5032
5194
|
return {
|
|
5033
5195
|
initialState
|
|
@@ -5118,6 +5280,7 @@ var useThumbnail = (pageNumber, config = {}) => {
|
|
|
5118
5280
|
const context = canvas.getContext("2d");
|
|
5119
5281
|
if (!context) return;
|
|
5120
5282
|
const renderTask = pageProxy.render({
|
|
5283
|
+
canvas,
|
|
5121
5284
|
canvasContext: context,
|
|
5122
5285
|
viewport: scaledViewport
|
|
5123
5286
|
});
|
|
@@ -5468,4 +5631,4 @@ function mergeAdjacentRects(rects) {
|
|
|
5468
5631
|
return merged;
|
|
5469
5632
|
}
|
|
5470
5633
|
|
|
5471
|
-
export { AnnotationHighlightLayer,
|
|
5634
|
+
export { AnnotationHighlightLayer, AnnotationLayer, AnnotationTooltip, CanvasLayer, ColoredHighlightLayer, CurrentPage, CurrentZoom, CustomLayer, HighlightLayer, LinkService, NextPage, Outline, OutlineChildItems, OutlineItem, PDFLinkServiceContext, Page, Pages, PreviousPage, Root, Search, SelectionTooltip, TextLayer, Thumbnail, Thumbnails, TotalPages, ZoomIn, ZoomOut, calculateHighlightRects, useAnnotations, useCreatePDFLinkService, usePDFLinkService, usePDFPageNumber, usePdf, usePdfJump, useSearch, useSelectionDimensions };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anaralabs/lector",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.10.0",
|
|
4
4
|
"description": "Headless PDF viewer for React",
|
|
5
5
|
"author": "andrewdr (https://github.com/andrewdoro)",
|
|
6
6
|
"license": "MIT",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"@vitejs/plugin-react": "^4.3.4",
|
|
45
45
|
"@vitest/browser": "^2.0.4",
|
|
46
46
|
"clsx": "^2.1.1",
|
|
47
|
-
"pdfjs-dist": "^
|
|
47
|
+
"pdfjs-dist": "^5.5.207",
|
|
48
48
|
"playwright": "^1.45.3",
|
|
49
49
|
"react": "^19.1.1",
|
|
50
50
|
"size-limit": "^11.1.6",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"webdriverio": "^8.39.1"
|
|
58
58
|
},
|
|
59
59
|
"peerDependencies": {
|
|
60
|
-
"pdfjs-dist": "^
|
|
60
|
+
"pdfjs-dist": "^5.5.207",
|
|
61
61
|
"react": ">=19"
|
|
62
62
|
},
|
|
63
63
|
"dependencies": {
|