Merge pull request #123 from richardr1126/fix/issue-119

Restore PDF Text Highlights After Viewport Resize (Fixes #119)
This commit is contained in:
Richard R 2026-06-13 15:15:01 -06:00 committed by GitHub
commit b322339580
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 27 additions and 0 deletions

View file

@ -39,6 +39,7 @@ interface PDFOnLinkClickArgs {
export function PDFViewer({ zoomLevel, onDocumentReady, pdfState }: PDFViewerProps) {
const containerRef = useRef<HTMLDivElement>(null);
const [isPageRendering, setIsPageRendering] = useState(false);
const [textLayerRenderRevision, setTextLayerRenderRevision] = useState(0);
const hasSignaledReadyRef = useRef(false);
const scaleRef = useRef<number>(1);
const { containerWidth, containerHeight } = usePDFResize(containerRef);
@ -107,6 +108,10 @@ export function PDFViewer({ zoomLevel, onDocumentReady, pdfState }: PDFViewerPro
onDocumentReady?.();
}, [onDocumentReady]);
const handleTextLayerRenderSuccess = useCallback(() => {
setTextLayerRenderRevision((revision) => revision + 1);
}, []);
useEffect(() => {
hasSignaledReadyRef.current = false;
}, [currDocId, currDocData]);
@ -228,6 +233,7 @@ export function PDFViewer({ zoomLevel, onDocumentReady, pdfState }: PDFViewerPro
parsedDocument,
resolvedLanguage,
layoutKey,
textLayerRenderRevision,
isPageRendering,
clearSentenceHighlightTimeouts,
scheduleSentenceTimeout
@ -309,6 +315,7 @@ export function PDFViewer({ zoomLevel, onDocumentReady, pdfState }: PDFViewerPro
clearWordHighlights,
highlightWordIndex,
layoutKey,
textLayerRenderRevision,
clearWordHighlightTimeouts,
scheduleWordTimeout,
isPageRendering
@ -546,6 +553,7 @@ export function PDFViewer({ zoomLevel, onDocumentReady, pdfState }: PDFViewerPro
setIsPageRendering(false);
markViewerReady();
}}
onRenderTextLayerSuccess={handleTextLayerRenderSuccess}
onLoadSuccess={(page) => {
setPageWidth(page.originalWidth);
setPageHeight(page.originalHeight);
@ -572,6 +580,7 @@ export function PDFViewer({ zoomLevel, onDocumentReady, pdfState }: PDFViewerPro
setIsPageRendering(false);
markViewerReady();
}}
onRenderTextLayerSuccess={handleTextLayerRenderSuccess}
onLoadSuccess={(page) => {
setPageWidth(page.originalWidth);
setPageHeight(page.originalHeight);
@ -594,6 +603,7 @@ export function PDFViewer({ zoomLevel, onDocumentReady, pdfState }: PDFViewerPro
setIsPageRendering(false);
markViewerReady();
}}
onRenderTextLayerSuccess={handleTextLayerRenderSuccess}
onLoadSuccess={(page) => {
setPageWidth(page.originalWidth);
setPageHeight(page.originalHeight);

View file

@ -65,6 +65,23 @@ test.describe('PDF view modes and Navigator', () => {
await setupTest(page, testInfo);
});
test('restores the active PDF text highlight after narrowing the viewport', async ({ page }) => {
test.setTimeout(120_000);
await playTTSAndWaitForASecond(page, 'sample.pdf');
const textLayer = page.locator('.react-pdf__Page__textContent');
const textHighlight = page.locator('.pdf-text-highlight-overlay');
await expect(textLayer).toHaveCount(1);
await expect(textLayer.locator('span')).not.toHaveCount(0);
await expect(textHighlight).not.toHaveCount(0);
await triggerViewportResize(page, 615, 796);
await expect(textLayer).toHaveCount(1);
await expect(textLayer.locator('span')).not.toHaveCount(0);
await expect(textHighlight).not.toHaveCount(0);
});
test('switches Single/Dual/Scroll modes and uses Navigator to change page', async ({ page }) => {
test.setTimeout(120_000);
// Open PDF viewer