@file-viewer/renderer-pdf 2.1.29 → 2.2.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/README.en.md +1 -1
- package/README.md +1 -1
- package/dist/pdf.js +82 -33
- package/dist/pdfWorkerGlobal.d.ts +27 -0
- package/dist/pdfWorkerGlobal.js +58 -0
- package/dist/pdfWorkerVersion.d.ts +9 -0
- package/dist/pdfWorkerVersion.js +23 -0
- package/package.json +2 -2
package/README.en.md
CHANGED
|
@@ -42,7 +42,7 @@ const options = {
|
|
|
42
42
|
}
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
-
When no explicit PDF asset URL is configured, the renderer first uses the public base exposed by build tools such as Vite and can fall back to the page entry script. An app deployed under `/workspace/` therefore still requests `/workspace/vendor/pdf/pdf.worker.mjs` while its current SPA route is `/workspace/c/`. UMI, custom proxies, and builds whose public path cannot be detected can set `pdf.assetBaseUrl: '/workspace/'` to pin the base for every PDF offline asset. If the host app did not run `file-viewer-copy-assets`, does not use `@file-viewer/vite-plugin`, or a local dev server falls back to HTML for that path, the
|
|
45
|
+
When no explicit PDF asset URL is configured, the renderer first uses the public base exposed by build tools such as Vite and can fall back to the page entry script. An app deployed under `/workspace/` therefore still requests `/workspace/vendor/pdf/pdf.worker.mjs` while its current SPA route is `/workspace/c/`. UMI, custom proxies, and builds whose public path cannot be detected can set `pdf.assetBaseUrl: '/workspace/'` to pin the base for every PDF offline asset. Before creating a static Worker, the renderer reads the official PDF.js version marker; a stale Worker from an older deployment is rejected and the packaged same-version handler is used instead. If the host app did not run `file-viewer-copy-assets`, does not use `@file-viewer/vite-plugin`, or a local dev server falls back to HTML for that path, the same fallback prevents `Setting up fake worker failed`. For best performance, complete cMap/standard-font/WASM decoding, or strict offline deployments, still copy viewer assets and point these URLs at real static files. The pinned PDF.js 5.4 stable line loads local JBIG2, JPEG 2000, color-management, and related helpers through `wasmUrl`; viewer assets and the Vite plugin copy them without relying on the public internet.
|
|
46
46
|
|
|
47
47
|
`cjkFontFallback` is enabled by default. When a PDF references `MicrosoftYaHei-Bold`, SimSun, SimHei, or another CJK font without embedding the font program, the renderer prefers an installed system font and otherwise aliases the original PDF font name to the bundled Noto Sans SC variable font. Only WOFF2 shards needed by the current page text are loaded. The first page waits for the font before rendering, and later pages are redrawn when they introduce new glyphs. Set the option to `false` to disable this behavior, or point `cjkFontFallbackPath` at a self-hosted directory with the same structure.
|
|
48
48
|
|
package/README.md
CHANGED
|
@@ -42,7 +42,7 @@ const options = {
|
|
|
42
42
|
}
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
-
默认未显式配置时,渲染器优先使用 Vite 等构建器提供的公开基址,并可从页面入口脚本回退识别部署子路径。因此应用部署在 `/workspace/`、当前 SPA 路由为 `/workspace/c/` 时,仍会请求 `/workspace/vendor/pdf/pdf.worker.mjs`。UMI、自定义代理或无法自动识别的构建环境可以设置 `pdf.assetBaseUrl: '/workspace/'` 固定全部 PDF
|
|
45
|
+
默认未显式配置时,渲染器优先使用 Vite 等构建器提供的公开基址,并可从页面入口脚本回退识别部署子路径。因此应用部署在 `/workspace/`、当前 SPA 路由为 `/workspace/c/` 时,仍会请求 `/workspace/vendor/pdf/pdf.worker.mjs`。UMI、自定义代理或无法自动识别的构建环境可以设置 `pdf.assetBaseUrl: '/workspace/'` 固定全部 PDF 离线资源的基址。创建静态 Worker 前会先读取 PDF.js 官方版本标记;若部署目录残留的旧 Worker 与当前 API 不一致,会拒绝旧文件并自动使用包内同版本 handler。项目未执行 `file-viewer-copy-assets`、未使用 `@file-viewer/vite-plugin`,或本地临时服务器把该路径回退成 HTML 时,也会使用同一兜底,避免 `Setting up fake worker failed` 直接中断预览。需要最佳性能、完整 cMap/standard fonts/WASM 解码或严格离线部署时,仍建议复制 viewer assets 并配置真实静态地址。当前锁定的 PDF.js 5.4 稳定线会通过 `wasmUrl` 本地加载 JBIG2、JPEG 2000、颜色管理等辅助资源;这些资源由 viewer assets 和 Vite 插件统一复制,不依赖公网。
|
|
46
46
|
|
|
47
47
|
`cjkFontFallback` 默认开启。PDF 引用了 `MicrosoftYaHei-Bold`、宋体、黑体或其他中文字体但没有嵌入字体数据时,渲染器优先使用本机字体;本机缺失时,会把原 PDF 字体名映射到本地 Noto Sans SC 可变字体,并根据当前页实际文字只加载需要的 WOFF2 分片。首屏会在字体就绪后再渲染,后续页发现新字形时会自动重绘。可设为 `false` 完全关闭,或用 `cjkFontFallbackPath` 指向同结构的自托管字体目录。
|
|
48
48
|
|
package/dist/pdf.js
CHANGED
|
@@ -1,21 +1,30 @@
|
|
|
1
|
-
import { getDocument, GlobalWorkerOptions, PDFWorker as PdfJsWorker, PixelsPerInch, } from 'pdfjs-dist/legacy/build/pdf.mjs';
|
|
1
|
+
import { getDocument, GlobalWorkerOptions, PDFWorker as PdfJsWorker, PixelsPerInch, version as pdfJsVersion, } from 'pdfjs-dist/legacy/build/pdf.mjs';
|
|
2
2
|
import { EventBus, GenericL10n, PDFFindController, PDFLinkService, PDFViewer, } from 'pdfjs-dist/legacy/web/pdf_viewer.mjs';
|
|
3
3
|
import { registerFileViewerSearchProvider, registerFileViewerZoomProvider, unregisterFileViewerSearchProvider, unregisterFileViewerZoomProvider, registerFileViewerViewStateProvider, unregisterFileViewerViewStateProvider, createFileViewerZoomChangeEmitter, createFileViewerViewStateChange, createFileViewerViewStateChangeEmitter, createFileViewerTranslator, buildPrintPageStyle, formatCssPixels, DEFAULT_PDF_RANGE_CHUNK_SIZE, resolveFileViewerLocale, resolveFileViewerFitScale, } from '@file-viewer/core';
|
|
4
4
|
import { DEFAULT_FILE_VIEWER_PDF_WORKER_PATH, resolveFileViewerPdfAssetUrls, resolveFileViewerRuntimeAssetBaseUrl, } from '@file-viewer/core/assets';
|
|
5
5
|
import { pdfViewerStyle } from './pdfStyles.js';
|
|
6
6
|
import { collectMalformedIdentityFontNames, createPdfCjkFontFallbackManager, detectMalformedIdentityCjkFontFamilies, } from './pdfFontFallback.js';
|
|
7
7
|
import { PDF_FIT_HORIZONTAL_PADDING, PDF_PAGE_BORDER_WIDTH, resolvePdfFitViewportSize, } from './pdfFit.js';
|
|
8
|
+
import { capturePdfJsWorkerGlobal, scopePdfJsWorkerMessageHandler, } from './pdfWorkerGlobal.js';
|
|
9
|
+
import { readPdfJsWorkerVersion } from './pdfWorkerVersion.js';
|
|
8
10
|
export const DEFAULT_FILE_VIEWER_PDF_WORKER_URL = DEFAULT_FILE_VIEWER_PDF_WORKER_PATH;
|
|
9
11
|
const MIN_SCALE = 0.2;
|
|
10
12
|
const MAX_SCALE = 3;
|
|
11
13
|
const SCALE_STEP = 0.1;
|
|
12
14
|
const PDF_EXPORT_MAX_PAGE_PIXELS = 8000000;
|
|
13
15
|
const PDF_WORKER_PROBE_TIMEOUT_MS = 1200;
|
|
16
|
+
const PDF_WORKER_VERSION_PROBE_BYTES = 4096;
|
|
14
17
|
const PDF_JS_DESTROY_CONSOLE_SUPPRESSION_MS = 1500;
|
|
15
18
|
let bundledPdfWorkerModulePromise = null;
|
|
19
|
+
const scopePdfJsRootVariables = (style) => style.replace(/:root(\s*\{)/g, ':root,\n.pdf-shell$1');
|
|
16
20
|
// PDF.js viewer CSS references image assets that are not shipped with the
|
|
17
21
|
// on-demand renderer chunk, so keep the preview self-contained and 404-free.
|
|
18
|
-
|
|
22
|
+
// Its root custom properties also need a local scope: a :root selector inside
|
|
23
|
+
// Shadow DOM does not match the document root or the custom-element host.
|
|
24
|
+
const normalizedPdfViewerStyle = `${scopePdfJsRootVariables(pdfViewerStyle)}
|
|
25
|
+
.pdf-shell{background:var(--file-viewer-render-surface-background,#edf2f7)}
|
|
26
|
+
.pdf-wrapper{background:var(--file-viewer-render-surface-background,#e8edf4)}
|
|
27
|
+
`
|
|
19
28
|
.replace(/--page-border-image:\s*url\(images\/shadow\.png\)\s*9 9 repeat;/g, '--page-border-image:none;')
|
|
20
29
|
.replace(/background:\s*url\("\.\/images\/loading-icon\.gif"\)\s*center no-repeat;/g, 'background:none;');
|
|
21
30
|
const pdfJsConsoleErrorSuppressions = new WeakMap();
|
|
@@ -234,21 +243,33 @@ const isJavaScriptLikeResponse = (response) => {
|
|
|
234
243
|
contentType.includes('application/octet-stream') ||
|
|
235
244
|
contentType.includes('text/plain');
|
|
236
245
|
};
|
|
246
|
+
const readResponsePrefix = async (response, maximumBytes = PDF_WORKER_VERSION_PROBE_BYTES) => {
|
|
247
|
+
// Consume the response even when a server ignores Range. Cancelling after the
|
|
248
|
+
// prefix creates a browser-level ERR_ABORTED event that strict hosts treat as
|
|
249
|
+
// a failed asset request, despite the compatibility probe succeeding.
|
|
250
|
+
return (await response.text()).slice(0, maximumBytes);
|
|
251
|
+
};
|
|
237
252
|
const loadBundledPdfWorkerModule = async () => {
|
|
238
253
|
bundledPdfWorkerModulePromise !== null && bundledPdfWorkerModulePromise !== void 0 ? bundledPdfWorkerModulePromise : (bundledPdfWorkerModulePromise = import('pdfjs-dist/legacy/build/pdf.worker.mjs'));
|
|
239
254
|
return bundledPdfWorkerModulePromise;
|
|
240
255
|
};
|
|
241
|
-
const
|
|
242
|
-
var _a;
|
|
256
|
+
const createBundledPdfFakeWorker = async () => {
|
|
243
257
|
const workerGlobal = globalThis;
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
258
|
+
// pdf.worker.mjs assigns globalThis.pdfjsWorker as a module side effect, so
|
|
259
|
+
// capture the host namespace before importing it and restore that snapshot.
|
|
260
|
+
const hostWorkerGlobal = capturePdfJsWorkerGlobal(workerGlobal);
|
|
247
261
|
const workerModule = await loadBundledPdfWorkerModule();
|
|
248
|
-
workerGlobal.
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
262
|
+
const workerHandlerScope = scopePdfJsWorkerMessageHandler(workerGlobal, workerModule.WorkerMessageHandler, hostWorkerGlobal);
|
|
263
|
+
try {
|
|
264
|
+
const worker = new PdfJsWorker({
|
|
265
|
+
name: 'file-viewer-pdf-worker',
|
|
266
|
+
});
|
|
267
|
+
await worker.promise;
|
|
268
|
+
return worker;
|
|
269
|
+
}
|
|
270
|
+
finally {
|
|
271
|
+
workerHandlerScope.restore();
|
|
272
|
+
}
|
|
252
273
|
};
|
|
253
274
|
const resolvePdfWorkerUrl = (options, documentBaseUrl) => {
|
|
254
275
|
return resolveFileViewerPdfAssetUrls(options, documentBaseUrl).workerUrl;
|
|
@@ -688,57 +709,78 @@ export default async function renderPdf(buffer, target, context) {
|
|
|
688
709
|
targetWindow.requestAnimationFrame(writeLegacyCompatiblePageDimensions);
|
|
689
710
|
});
|
|
690
711
|
};
|
|
691
|
-
const
|
|
712
|
+
const probeResolvedPdfWorkerUrl = async (workerUrl) => {
|
|
692
713
|
var _a, _b;
|
|
693
714
|
const fetcher = ((_a = targetWindow.fetch) === null || _a === void 0 ? void 0 : _a.bind(targetWindow)) || ((_b = globalThis.fetch) === null || _b === void 0 ? void 0 : _b.bind(globalThis));
|
|
694
715
|
const AbortControllerCtor = targetWindow.AbortController || globalThis.AbortController;
|
|
695
716
|
if (!fetcher || !AbortControllerCtor) {
|
|
696
|
-
return
|
|
717
|
+
return { status: 'unavailable', workerVersion: null };
|
|
697
718
|
}
|
|
698
719
|
try {
|
|
699
720
|
const parsed = new URL(workerUrl, documentRef.baseURI || targetWindow.location.href);
|
|
700
721
|
if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
|
|
701
|
-
return
|
|
722
|
+
return { status: 'unavailable', workerVersion: null };
|
|
702
723
|
}
|
|
703
724
|
}
|
|
704
725
|
catch {
|
|
705
|
-
return
|
|
726
|
+
return { status: 'unavailable', workerVersion: null };
|
|
706
727
|
}
|
|
707
728
|
const controller = new AbortControllerCtor();
|
|
708
729
|
const timer = targetWindow.setTimeout(() => controller.abort(), PDF_WORKER_PROBE_TIMEOUT_MS);
|
|
709
730
|
try {
|
|
710
731
|
const response = await fetcher(workerUrl, {
|
|
711
|
-
method: '
|
|
732
|
+
method: 'GET',
|
|
712
733
|
cache: 'no-cache',
|
|
734
|
+
headers: {
|
|
735
|
+
Range: `bytes=0-${PDF_WORKER_VERSION_PROBE_BYTES - 1}`,
|
|
736
|
+
},
|
|
713
737
|
signal: controller.signal,
|
|
714
738
|
});
|
|
715
|
-
if (response.ok) {
|
|
716
|
-
return
|
|
739
|
+
if ((!response.ok && response.status !== 206) || !isJavaScriptLikeResponse(response)) {
|
|
740
|
+
return { status: 'unavailable', workerVersion: null };
|
|
717
741
|
}
|
|
718
|
-
|
|
719
|
-
|
|
742
|
+
const workerVersion = readPdfJsWorkerVersion(await readResponsePrefix(response));
|
|
743
|
+
if (!workerVersion) {
|
|
744
|
+
return { status: 'unknown', workerVersion: null };
|
|
720
745
|
}
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
signal: controller.signal,
|
|
726
|
-
});
|
|
727
|
-
return (fallbackResponse.ok || fallbackResponse.status === 206) &&
|
|
728
|
-
isJavaScriptLikeResponse(fallbackResponse);
|
|
746
|
+
return {
|
|
747
|
+
status: workerVersion === pdfJsVersion ? 'compatible' : 'incompatible',
|
|
748
|
+
workerVersion,
|
|
749
|
+
};
|
|
729
750
|
}
|
|
730
751
|
catch {
|
|
731
|
-
return
|
|
752
|
+
return { status: 'unavailable', workerVersion: null };
|
|
732
753
|
}
|
|
733
754
|
finally {
|
|
734
755
|
targetWindow.clearTimeout(timer);
|
|
735
756
|
}
|
|
736
757
|
};
|
|
737
758
|
const createPdfWorker = async () => {
|
|
759
|
+
var _a;
|
|
738
760
|
const workerUrl = resolvePdfWorkerUrl(options, pdfRuntimeAssetBaseUrl);
|
|
761
|
+
const workerGlobal = globalThis;
|
|
762
|
+
if ((_a = workerGlobal.pdfjsWorker) === null || _a === void 0 ? void 0 : _a.WorkerMessageHandler) {
|
|
763
|
+
try {
|
|
764
|
+
// PDF.js prefers a preinstalled main-thread handler over workerSrc.
|
|
765
|
+
// Scope our bundled handler only until this PDFWorker captures it, so
|
|
766
|
+
// a vue-office/PDF.js 3.x global cannot hijack this renderer and the
|
|
767
|
+
// host can still use its original handler afterwards.
|
|
768
|
+
return await createBundledPdfFakeWorker();
|
|
769
|
+
}
|
|
770
|
+
catch (error) {
|
|
771
|
+
console.warn('[file-viewer] PDF.js 全局 Worker handler 隔离失败,继续探测静态 Worker。', error);
|
|
772
|
+
}
|
|
773
|
+
}
|
|
739
774
|
const hasExplicitWorkerUrl = isConfiguredUrl(options === null || options === void 0 ? void 0 : options.workerUrl);
|
|
740
|
-
const
|
|
741
|
-
|
|
775
|
+
const workerProbe = (targetWindow === null || targetWindow === void 0 ? void 0 : targetWindow.Worker)
|
|
776
|
+
? await probeResolvedPdfWorkerUrl(workerUrl)
|
|
777
|
+
: { status: 'unavailable', workerVersion: null };
|
|
778
|
+
if (workerProbe.status === 'incompatible') {
|
|
779
|
+
console.warn(`[file-viewer] PDF Worker ${workerProbe.workerVersion} 与 PDF.js API ${pdfJsVersion} 不匹配,` +
|
|
780
|
+
'改用包内同版本 PDF.js handler。');
|
|
781
|
+
}
|
|
782
|
+
const shouldUseRealWorker = !!(targetWindow === null || targetWindow === void 0 ? void 0 : targetWindow.Worker) && (workerProbe.status === 'compatible' ||
|
|
783
|
+
(hasExplicitWorkerUrl && workerProbe.status !== 'incompatible'));
|
|
742
784
|
if (shouldUseRealWorker) {
|
|
743
785
|
GlobalWorkerOptions.workerSrc = workerUrl;
|
|
744
786
|
try {
|
|
@@ -753,7 +795,7 @@ export default async function renderPdf(buffer, target, context) {
|
|
|
753
795
|
}
|
|
754
796
|
}
|
|
755
797
|
try {
|
|
756
|
-
await
|
|
798
|
+
return await createBundledPdfFakeWorker();
|
|
757
799
|
}
|
|
758
800
|
catch (error) {
|
|
759
801
|
console.warn('[file-viewer] PDF.js 包内 worker 兜底加载失败,继续使用 PDF.js 默认策略。', error);
|
|
@@ -1762,9 +1804,16 @@ export default async function renderPdf(buffer, target, context) {
|
|
|
1762
1804
|
container.addEventListener('keydown', recordUserScrollIntent);
|
|
1763
1805
|
container.addEventListener('scroll', scheduleScrollViewStateChange, { passive: true });
|
|
1764
1806
|
if (targetWindow.ResizeObserver) {
|
|
1765
|
-
resizeObserver = new targetWindow.ResizeObserver(() =>
|
|
1807
|
+
resizeObserver = new targetWindow.ResizeObserver(() => {
|
|
1808
|
+
root.style.setProperty('--viewer-container-height', `${container.clientHeight}px`);
|
|
1809
|
+
scheduleFitAfterResize();
|
|
1810
|
+
});
|
|
1766
1811
|
resizeObserver.observe(container);
|
|
1767
1812
|
}
|
|
1813
|
+
// PDFViewer writes this value to documentElement, which cannot safely model
|
|
1814
|
+
// multiple differently-sized viewers. Keep a live shell-local value as well
|
|
1815
|
+
// so Shadow DOM and multi-instance layouts both resolve the dummy-page height.
|
|
1816
|
+
root.style.setProperty('--viewer-container-height', `${container.clientHeight}px`);
|
|
1768
1817
|
syncUi();
|
|
1769
1818
|
void loadFile();
|
|
1770
1819
|
return {
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export type PdfJsWorkerNamespace = {
|
|
2
|
+
WorkerMessageHandler?: unknown;
|
|
3
|
+
[key: string]: unknown;
|
|
4
|
+
};
|
|
5
|
+
export type PdfJsWorkerGlobal = {
|
|
6
|
+
pdfjsWorker?: PdfJsWorkerNamespace;
|
|
7
|
+
};
|
|
8
|
+
export type PdfJsWorkerHandlerInstallResult = 'installed' | 'replaced' | 'unchanged';
|
|
9
|
+
export type PdfJsWorkerHandlerScope = {
|
|
10
|
+
installResult: PdfJsWorkerHandlerInstallResult;
|
|
11
|
+
restore: () => boolean;
|
|
12
|
+
};
|
|
13
|
+
export type PdfJsWorkerGlobalSnapshot = {
|
|
14
|
+
hadOwnNamespace: boolean;
|
|
15
|
+
namespace: PdfJsWorkerNamespace | undefined;
|
|
16
|
+
};
|
|
17
|
+
export declare const capturePdfJsWorkerGlobal: (workerGlobal: PdfJsWorkerGlobal) => PdfJsWorkerGlobalSnapshot;
|
|
18
|
+
/**
|
|
19
|
+
* Temporarily own the fake-worker handler used by this renderer.
|
|
20
|
+
*
|
|
21
|
+
* Host applications can load another PDF.js build before File Viewer. Reusing
|
|
22
|
+
* that global handler is unsafe because PDF.js requires its API and worker
|
|
23
|
+
* versions to match exactly. The original namespace is restored after our
|
|
24
|
+
* PDFWorker has captured and initialized the bundled handler, so a host PDF.js
|
|
25
|
+
* build can continue using its own global afterwards.
|
|
26
|
+
*/
|
|
27
|
+
export declare const scopePdfJsWorkerMessageHandler: (workerGlobal: PdfJsWorkerGlobal, WorkerMessageHandler: unknown, restoreSnapshot?: PdfJsWorkerGlobalSnapshot) => PdfJsWorkerHandlerScope;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export const capturePdfJsWorkerGlobal = (workerGlobal) => ({
|
|
2
|
+
hadOwnNamespace: Object.prototype.hasOwnProperty.call(workerGlobal, 'pdfjsWorker'),
|
|
3
|
+
namespace: workerGlobal.pdfjsWorker,
|
|
4
|
+
});
|
|
5
|
+
/**
|
|
6
|
+
* Temporarily own the fake-worker handler used by this renderer.
|
|
7
|
+
*
|
|
8
|
+
* Host applications can load another PDF.js build before File Viewer. Reusing
|
|
9
|
+
* that global handler is unsafe because PDF.js requires its API and worker
|
|
10
|
+
* versions to match exactly. The original namespace is restored after our
|
|
11
|
+
* PDFWorker has captured and initialized the bundled handler, so a host PDF.js
|
|
12
|
+
* build can continue using its own global afterwards.
|
|
13
|
+
*/
|
|
14
|
+
export const scopePdfJsWorkerMessageHandler = (workerGlobal, WorkerMessageHandler, restoreSnapshot = capturePdfJsWorkerGlobal(workerGlobal)) => {
|
|
15
|
+
const currentNamespace = workerGlobal.pdfjsWorker;
|
|
16
|
+
const installResult = (currentNamespace === null || currentNamespace === void 0 ? void 0 : currentNamespace.WorkerMessageHandler) === WorkerMessageHandler
|
|
17
|
+
? 'unchanged'
|
|
18
|
+
: (currentNamespace === null || currentNamespace === void 0 ? void 0 : currentNamespace.WorkerMessageHandler)
|
|
19
|
+
? 'replaced'
|
|
20
|
+
: 'installed';
|
|
21
|
+
const installedNamespace = installResult === 'unchanged'
|
|
22
|
+
? currentNamespace
|
|
23
|
+
: {
|
|
24
|
+
...currentNamespace,
|
|
25
|
+
WorkerMessageHandler,
|
|
26
|
+
};
|
|
27
|
+
if (!installedNamespace) {
|
|
28
|
+
return {
|
|
29
|
+
installResult: 'unchanged',
|
|
30
|
+
restore: () => false,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
if (installResult !== 'unchanged') {
|
|
34
|
+
workerGlobal.pdfjsWorker = installedNamespace;
|
|
35
|
+
}
|
|
36
|
+
const restorationIsNoop = restoreSnapshot.hadOwnNamespace &&
|
|
37
|
+
restoreSnapshot.namespace === installedNamespace;
|
|
38
|
+
let restoreAttempted = false;
|
|
39
|
+
return {
|
|
40
|
+
installResult,
|
|
41
|
+
restore: () => {
|
|
42
|
+
if (restorationIsNoop || restoreAttempted) {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
restoreAttempted = true;
|
|
46
|
+
if (workerGlobal.pdfjsWorker !== installedNamespace) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
if (restoreSnapshot.hadOwnNamespace) {
|
|
50
|
+
workerGlobal.pdfjsWorker = restoreSnapshot.namespace;
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
delete workerGlobal.pdfjsWorker;
|
|
54
|
+
}
|
|
55
|
+
return true;
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read the version marker emitted by official PDF.js worker bundles.
|
|
3
|
+
*
|
|
4
|
+
* The marker is intentionally read from a small source prefix before a Worker
|
|
5
|
+
* is constructed. PDF.js does not reject an API/worker mismatch until the
|
|
6
|
+
* first document request, which is too late for `PDFWorker.promise` to be a
|
|
7
|
+
* useful compatibility probe.
|
|
8
|
+
*/
|
|
9
|
+
export declare const readPdfJsWorkerVersion: (sourcePrefix: string) => string | null;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
const PDF_JS_SEMVER_PATTERN = '(\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?)';
|
|
2
|
+
const PDF_JS_WORKER_VERSION_PATTERNS = [
|
|
3
|
+
new RegExp(`\\bpdfjsVersion\\s*=\\s*["']?${PDF_JS_SEMVER_PATTERN}`, 'i'),
|
|
4
|
+
new RegExp(`\\bworkerVersion\\s*=\\s*["']${PDF_JS_SEMVER_PATTERN}["']`, 'i'),
|
|
5
|
+
new RegExp(`\\bPDF\\.js\\s+v${PDF_JS_SEMVER_PATTERN}`, 'i'),
|
|
6
|
+
];
|
|
7
|
+
/**
|
|
8
|
+
* Read the version marker emitted by official PDF.js worker bundles.
|
|
9
|
+
*
|
|
10
|
+
* The marker is intentionally read from a small source prefix before a Worker
|
|
11
|
+
* is constructed. PDF.js does not reject an API/worker mismatch until the
|
|
12
|
+
* first document request, which is too late for `PDFWorker.promise` to be a
|
|
13
|
+
* useful compatibility probe.
|
|
14
|
+
*/
|
|
15
|
+
export const readPdfJsWorkerVersion = (sourcePrefix) => {
|
|
16
|
+
for (const pattern of PDF_JS_WORKER_VERSION_PATTERNS) {
|
|
17
|
+
const match = pattern.exec(sourcePrefix);
|
|
18
|
+
if (match === null || match === void 0 ? void 0 : match[1]) {
|
|
19
|
+
return match[1];
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return null;
|
|
23
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@file-viewer/renderer-pdf",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Standalone PDF renderer plugin for Flyfish File Viewer powered by PDF.js.",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"LICENSE"
|
|
55
55
|
],
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"@file-viewer/core": "2.
|
|
57
|
+
"@file-viewer/core": "2.2.0",
|
|
58
58
|
"@fontsource-variable/noto-sans-sc": "5.2.10",
|
|
59
59
|
"pdf-lib": "1.17.1",
|
|
60
60
|
"pdfjs-dist": "5.4.624"
|