From 14c569368b4ec840ce1e8843cf46135a44d95611 Mon Sep 17 00:00:00 2001 From: TaTo30 Date: Wed, 15 Nov 2023 14:31:39 -0600 Subject: [PATCH] feat: make usePDF reactivity --- src/components/types.ts | 14 ++++++- src/components/usePDF.ts | 87 +++++++++++++++++++++++----------------- 2 files changed, 64 insertions(+), 37 deletions(-) diff --git a/src/components/types.ts b/src/components/types.ts index 730c222..c1dc9b2 100644 --- a/src/components/types.ts +++ b/src/components/types.ts @@ -1,5 +1,10 @@ import type { PageViewport } from 'pdfjs-dist' -import type { OnProgressParameters } from 'pdfjs-dist/types/src/display/api' +import type { + DocumentInitParameters, + OnProgressParameters, + PDFDataRangeTransport, + TypedArray, +} from 'pdfjs-dist/types/src/display/api' import type { Metadata } from 'pdfjs-dist/types/src/display/metadata' export type LoadedEventPayload = PageViewport @@ -14,6 +19,13 @@ export type UpdatePasswordFn = (newPassword: string) => void export type OnPasswordCallback = (updatePassword: UpdatePasswordFn, reason: any) => void export type OnErrorCallback = (error: any) => void +export type UsePDFSrc = + | string + | URL + | TypedArray + | PDFDataRangeTransport + | DocumentInitParameters + export interface UsePDFOptions { onProgress?: OnProgressCallback onPassword?: OnPasswordCallback diff --git a/src/components/usePDF.ts b/src/components/usePDF.ts index af7c3d0..647f634 100644 --- a/src/components/usePDF.ts +++ b/src/components/usePDF.ts @@ -1,10 +1,10 @@ import * as PDFJS from 'pdfjs-dist' import PDFWorker from 'pdfjs-dist/build/pdf.worker.min?url' -import { shallowRef } from 'vue' +import { isRef, shallowRef, watch } from 'vue' import type { PDFDocumentLoadingTask } from 'pdfjs-dist' -import type { DocumentInitParameters, PDFDataRangeTransport, TypedArray } from 'pdfjs-dist/types/src/display/api' -import type { OnPasswordCallback, UsePDFInfo, UsePDFOptions } from './types' +import type { Ref } from 'vue' +import type { OnPasswordCallback, UsePDFInfo, UsePDFOptions, UsePDFSrc } from './types' // Could not find a way to make this work with vite, importing the worker entry bundle the whole worker to the the final output // https://erindoyle.dev/using-pdfjs-with-vite/ @@ -32,12 +32,14 @@ function configWorker(wokerSrc: string) { * @param {UsePDFParameters} options * UsePDF object parameters */ -export function usePDF(src: string | URL | TypedArray | PDFDataRangeTransport | DocumentInitParameters, options: UsePDFOptions = { - onProgress: undefined, - onPassword: undefined, - onError: undefined, - password: '', -}) { +export function usePDF(src: UsePDFSrc | Ref, + options: UsePDFOptions = { + onProgress: undefined, + onPassword: undefined, + onError: undefined, + password: '', + }, +) { if (!PDFJS.GlobalWorkerOptions?.workerSrc) configWorker(PDFWorker) @@ -45,38 +47,51 @@ export function usePDF(src: string | URL | TypedArray | PDFDataRangeTransport | const pages = shallowRef(0) const info = shallowRef({}) - const loadingTask = PDFJS.getDocument(src) - if (options.onProgress) - loadingTask.onProgress = options.onProgress + function processLoadingTask(source: UsePDFSrc) { + const loadingTask = PDFJS.getDocument(source) + if (options.onProgress) + loadingTask.onProgress = options.onProgress - if (options.onPassword) { - loadingTask.onPassword = options.onPassword - } - else if (options.password) { - const onPassword: OnPasswordCallback = (updatePassword, _) => { - updatePassword(options.password ?? '') + if (options.onPassword) { + loadingTask.onPassword = options.onPassword + } + else if (options.password) { + const onPassword: OnPasswordCallback = (updatePassword, _) => { + updatePassword(options.password ?? '') + } + loadingTask.onPassword = onPassword } - loadingTask.onPassword = onPassword - } - loadingTask.promise.then(async (doc) => { - pdf.value = doc.loadingTask - pages.value = doc.numPages + loadingTask.promise.then( + async (doc) => { + pdf.value = doc.loadingTask + pages.value = doc.numPages - const metadata = await doc.getMetadata() - const attachments = (await doc.getAttachments()) as Record - const javascript = await doc.getJavaScript() + const metadata = await doc.getMetadata() + const attachments = (await doc.getAttachments()) as Record + const javascript = await doc.getJavaScript() - info.value = { - metadata, - attachments, - javascript, - } - }, (error) => { - // PDF loading error - if (typeof options.onError === 'function') - options.onError(error) - }) + info.value = { + metadata, + attachments, + javascript, + } + }, + (error) => { + // PDF loading error + if (typeof options.onError === 'function') + options.onError(error) + }, + ) + } + + if (isRef(src)) { + processLoadingTask(src.value) + watch(src, () => processLoadingTask(src.value)) + } + else { + processLoadingTask(src) + } return { pdf,