diff --git a/example/webpack.config.js b/example/webpack.config.js index 62e956d..339bee8 100644 --- a/example/webpack.config.js +++ b/example/webpack.config.js @@ -44,6 +44,11 @@ module.exports = { }, // We are importing this worker as a string by using asset/source otherwise it will default to loading via an HTTPS request later. // This causes issues if we have gone offline before the pdfjs web worker is set up as we won't be able to load it from the server. + { + // eslint-disable-next-line prefer-regex-literals + test: new RegExp('node_modules/pdfjs-dist/build/pdf.worker.min.mjs'), + type: 'asset/source', + }, { // eslint-disable-next-line prefer-regex-literals test: new RegExp('node_modules/pdfjs-dist/legacy/build/pdf.worker.min.mjs'), diff --git a/src/PDFPreviewer.tsx b/src/PDFPreviewer.tsx index f5f44b1..a36ab93 100644 --- a/src/PDFPreviewer.tsx +++ b/src/PDFPreviewer.tsx @@ -1,6 +1,7 @@ -// @ts-expect-error - This line imports a module from 'pdfjs-dist' package which lacks TypeScript typings. // eslint-disable-next-line import/extensions -import pdfWorkerSource from 'pdfjs-dist/legacy/build/pdf.worker.mjs'; +import pdfWorkerSource from 'pdfjs-dist/build/pdf.worker.min.mjs'; +// eslint-disable-next-line import/extensions +import pdfWorkerLegacySource from 'pdfjs-dist/legacy/build/pdf.worker.mjs'; import React, {memo, useCallback, useLayoutEffect, useRef, useState} from 'react'; import type {CSSProperties, ReactNode} from 'react'; import times from 'lodash/times'; @@ -14,7 +15,7 @@ import {pdfPreviewerStyles as styles} from './styles'; import PDFPasswordForm, {type PDFPasswordFormProps} from './PDFPasswordForm'; import PageRenderer from './PageRenderer'; import {PAGE_BORDER, LARGE_SCREEN_SIDE_SPACING, DEFAULT_DOCUMENT_OPTIONS, DEFAULT_EXTERNAL_LINK_TARGET, PDF_PASSWORD_FORM_RESPONSES} from './constants'; -import {setListAttributes} from './helpers'; +import {isMobileSafari, isModernSafari, setListAttributes} from './helpers'; type Props = { file: string; @@ -34,7 +35,11 @@ type Props = { type OnPasswordCallback = (password: string | null) => void; -pdfjs.GlobalWorkerOptions.workerSrc = URL.createObjectURL(new Blob([pdfWorkerSource], {type: 'text/javascript'})); +const shouldUseLegacyWorker = isMobileSafari() && !isModernSafari(); +// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment +const pdfWorker = shouldUseLegacyWorker ? pdfWorkerLegacySource : pdfWorkerSource; + +pdfjs.GlobalWorkerOptions.workerSrc = URL.createObjectURL(new Blob([pdfWorker], {type: 'text/javascript'})); const DefaultLoadingComponent =

Loading...

; const DefaultErrorComponent =

Failed to load the PDF file :(

; diff --git a/src/helpers.ts b/src/helpers.ts index 0249b61..9cc57ba 100644 --- a/src/helpers.ts +++ b/src/helpers.ts @@ -39,6 +39,13 @@ const isMobileSafari = (): boolean => { const isSafari = () => getBrowser() === 'safari' || isMobileSafari(); +const isModernSafari = (): boolean => { + const version = navigator.userAgent.match(/OS (\d+_\d+)/); + const iosVersion = version ? version[1].replace('_', '.') : ''; + + return parseFloat(iosVersion) >= 18; +}; + type ListRef = { tabIndex: number; }; @@ -60,4 +67,4 @@ const setListAttributes = (ref: ListRef | undefined) => { ref.tabIndex = -1; }; -export {getBrowser, isMobileSafari, isSafari, setListAttributes}; +export {getBrowser, isMobileSafari, isSafari, isModernSafari, setListAttributes}; diff --git a/src/pdf.worker.d.ts b/src/pdf.worker.d.ts new file mode 100644 index 0000000..ca34ffa --- /dev/null +++ b/src/pdf.worker.d.ts @@ -0,0 +1,2 @@ +declare module 'pdfjs-dist/build/pdf.worker.min.mjs'; +declare module 'pdfjs-dist/legacy/build/pdf.worker.mjs';