diff --git a/src/lib/components/common/DocxPreview.svelte b/src/lib/components/common/DocxPreview.svelte index ce0624adf3..3e07ae8504 100644 --- a/src/lib/components/common/DocxPreview.svelte +++ b/src/lib/components/common/DocxPreview.svelte @@ -148,7 +148,7 @@
diff --git a/src/lib/components/common/PDFViewer.svelte b/src/lib/components/common/PDFViewer.svelte index 8026c53fba..b4120358b5 100644 --- a/src/lib/components/common/PDFViewer.svelte +++ b/src/lib/components/common/PDFViewer.svelte @@ -8,18 +8,32 @@ export let data: ArrayBuffer | Uint8Array | null = null; export let className = 'w-full h-[70vh]'; + type PdfDocument = import('pdfjs-dist').PDFDocumentProxy; + type PdfTextLayer = InstanceType; + let outerContainer: HTMLDivElement; let sceneElement: HTMLDivElement; let loading = true; let error = ''; - let pdfDoc: any = null; + let pdfDoc: PdfDocument | null = null; let pzInstance: PanZoom | null = null; let zoomLevel = 1; let rerenderTimer: ReturnType | null = null; let lastRenderedZoom = 1; // Keep a reference to TextLayer instances so we can update/cancel them - let textLayerInstances: any[] = []; + let textLayerInstances: PdfTextLayer[] = []; + + const cancelTextLayers = () => { + for (const tl of textLayerInstances) { + try { + tl.cancel(); + } catch { + // Text layers can already be resolved or canceled during rerenders. + } + } + textLayerInstances = []; + }; const initPanzoom = () => { if (pzInstance) { @@ -37,7 +51,7 @@ } return false; }, - beforeMouseDown: (e) => { + beforeMouseDown: () => { // Only allow drag-to-pan when zoomed in (not at default scale) const transform = pzInstance?.getTransform(); if (transform && Math.abs(transform.scale - 1) < 0.01) { @@ -93,13 +107,7 @@ const pageWrappers = sceneElement.querySelectorAll('.pdf-page-wrapper'); - // Cancel old text layers - for (const tl of textLayerInstances) { - try { - tl.cancel(); - } catch (_) {} - } - textLayerInstances = []; + cancelTextLayers(); for (let i = 0; i < pageWrappers.length; i++) { const page = await pdfDoc.getPage(i + 1); @@ -119,7 +127,7 @@ const ctx = canvas.getContext('2d'); if (ctx) { - await page.render({ canvasContext: ctx, viewport: scaledViewport }).promise; + await page.render({ canvas, canvasContext: ctx, viewport: scaledViewport }).promise; } // Rebuild text layer @@ -146,13 +154,7 @@ // Clear previous content sceneElement.innerHTML = ''; - // Cancel old text layers - for (const tl of textLayerInstances) { - try { - tl.cancel(); - } catch (_) {} - } - textLayerInstances = []; + cancelTextLayers(); const pdfjs = await import('pdfjs-dist'); const dpr = window.devicePixelRatio || 1; @@ -194,7 +196,10 @@ wrapper.appendChild(canvas); const ctx = canvas.getContext('2d'); + if (!ctx) continue; + await page.render({ + canvas, canvasContext: ctx, viewport: scaledViewport }).promise; @@ -256,12 +261,7 @@ onDestroy(() => { if (rerenderTimer) clearTimeout(rerenderTimer); pzInstance?.dispose(); - for (const tl of textLayerInstances) { - try { - tl.cancel(); - } catch (_) {} - } - textLayerInstances = []; + cancelTextLayers(); if (pdfDoc) { pdfDoc.destroy(); pdfDoc = null;