From 3d598cd0c240210019344c97ba8c6b4e2a51bebc Mon Sep 17 00:00:00 2001 From: Wojciech Duda <69160975+wojd0@users.noreply.github.com> Date: Thu, 24 Apr 2025 17:18:11 +0200 Subject: [PATCH] AAE-34470 Ignore content type of fetched pdfjs worker (#10818) * AAE-34470 Ignore content type of fetched pdfjs worker * AAE-34470 Fix units * AAE-34470 Harness instances of pdfjs worker * AAE-34470 Harness instances of pdfjs worker * AAE-34470 Clean docs up * AAE-34470 Synchronize ngOnChanges * AAE-34470 Flush not tick * AAE-34470 Revert modern bundle for pdf_viewer.mjs --- docs/core/components/viewer.component.md | 9 +-- .../pdf-viewer/pdf-viewer.component.spec.ts | 2 + .../pdf-viewer/pdf-viewer.component.ts | 73 +++++++++++++------ 3 files changed, 56 insertions(+), 28 deletions(-) diff --git a/docs/core/components/viewer.component.md b/docs/core/components/viewer.component.md index c485c666d1..aaeda2f0bf 100644 --- a/docs/core/components/viewer.component.md +++ b/docs/core/components/viewer.component.md @@ -186,10 +186,9 @@ npm install pdfjs-dist ```ts // PDF.js -require('pdfjs-dist/web/compatibility.js'); const pdfjsLib = require('pdfjs-dist'); -pdfjsLib.PDFJS.workerSrc = './pdf.worker.js'; -require('pdfjs-dist/web/pdf_viewer.js'); +pdfjsLib.PDFJS.workerSrc = './pdf.worker.min.mjs'; +require('pdfjs-dist/web/pdf_viewer.mjs'); ``` - Update the `plugins` section of the `webpack.common.js` file with the following lines: @@ -198,8 +197,8 @@ require('pdfjs-dist/web/pdf_viewer.js'); new CopyWebpackPlugin([ ... { - from: 'node_modules/pdfjs-dist/build/pdf.worker.js', - to: 'pdf.worker.js' + from: 'node_modules/pdfjs-dist/build/pdf.worker.min.mjs', + to: 'pdf.worker.min.mjs' } ]) ``` diff --git a/lib/core/src/lib/viewer/components/pdf-viewer/pdf-viewer.component.spec.ts b/lib/core/src/lib/viewer/components/pdf-viewer/pdf-viewer.component.spec.ts index 6504df299a..44101957b1 100644 --- a/lib/core/src/lib/viewer/components/pdf-viewer/pdf-viewer.component.spec.ts +++ b/lib/core/src/lib/viewer/components/pdf-viewer/pdf-viewer.component.spec.ts @@ -451,6 +451,8 @@ describe('Test PdfViewer - User interaction', () => { const appConfig: AppConfigService = TestBed.inject(AppConfigService); appConfig.config['adf-viewer.pdf-viewer-scaling'] = 10; + component['setupPdfJsWorker'] = () => Promise.resolve(); + component.urlFile = './fake-test-file.pdf'; fixture.detectChanges(); component.ngOnChanges({ urlFile: { currentValue: './fake-test-file.pdf' } } as any); diff --git a/lib/core/src/lib/viewer/components/pdf-viewer/pdf-viewer.component.ts b/lib/core/src/lib/viewer/components/pdf-viewer/pdf-viewer.component.ts index 725b1b2cac..622685f465 100644 --- a/lib/core/src/lib/viewer/components/pdf-viewer/pdf-viewer.component.ts +++ b/lib/core/src/lib/viewer/components/pdf-viewer/pdf-viewer.component.ts @@ -47,7 +47,7 @@ import { RenderingQueueServices } from '../../services/rendering-queue.services' import { PdfPasswordDialogComponent } from '../pdf-viewer-password-dialog/pdf-viewer-password-dialog'; import { PdfThumbListComponent } from '../pdf-viewer-thumbnails/pdf-viewer-thumbnails.component'; import * as pdfjsLib from 'pdfjs-dist/build/pdf.min.mjs'; -import { PDFViewer, EventBus } from 'pdfjs-dist/web/pdf_viewer.mjs'; +import { EventBus, PDFViewer } from 'pdfjs-dist/web/pdf_viewer.mjs'; import { OnProgressParameters, PDFDocumentLoadingTask, PDFDocumentProxy } from 'pdfjs-dist/types/src/display/api'; export type PdfScaleMode = 'init' | 'page-actual' | 'page-width' | 'page-height' | 'page-fit' | 'auto'; @@ -115,6 +115,8 @@ export class PdfViewerComponent implements OnChanges, OnDestroy { totalPages: number; loadingPercent: number; pdfViewer: any; + pdfJsWorkerUrl: string; + pdfJsWorkerInstance: Worker; currentScaleMode: PdfScaleMode = 'init'; MAX_AUTO_SCALE: number = 1.25; @@ -159,7 +161,7 @@ export class PdfViewerComponent implements OnChanges, OnDestroy { this.pdfjsWorkerDestroy$ .pipe( catchError(() => null), - switchMap(() => from(this.destroyPdJsWorker())) + switchMap(() => from(this.destroyPfdJsWorker())) ) .subscribe(() => {}); } @@ -224,32 +226,49 @@ export class PdfViewerComponent implements OnChanges, OnDestroy { } executePdf(pdfOptions: any) { - this.pdfjsLib.GlobalWorkerOptions.workerSrc = 'pdf.worker.min.mjs'; + this.setupPdfJsWorker().then(() => { + this.loadingTask = this.pdfjsLib.getDocument(pdfOptions); - this.loadingTask = this.pdfjsLib.getDocument(pdfOptions); + this.loadingTask.onPassword = (callback, reason) => { + this.onPdfPassword(callback, reason); + }; - this.loadingTask.onPassword = (callback, reason) => { - this.onPdfPassword(callback, reason); - }; + this.loadingTask.onProgress = (progressData: OnProgressParameters) => { + const level = progressData.loaded / progressData.total; + this.loadingPercent = Math.round(level * 100); + }; - this.loadingTask.onProgress = (progressData: OnProgressParameters) => { - const level = progressData.loaded / progressData.total; - this.loadingPercent = Math.round(level * 100); - }; + this.isPanelDisabled = true; - this.isPanelDisabled = true; + this.loadingTask.promise + .then((pdfDocument) => { + this.totalPages = pdfDocument.numPages; + this.page = 1; + this.displayPage = 1; + this.initPDFViewer(pdfDocument); - this.loadingTask.promise - .then((pdfDocument) => { - this.totalPages = pdfDocument.numPages; - this.page = 1; - this.displayPage = 1; - this.initPDFViewer(pdfDocument); + return pdfDocument.getPage(1); + }) + .then(() => this.scalePage('init')) + .catch(() => this.error.emit()); + }); + } - return pdfDocument.getPage(1); - }) - .then(() => this.scalePage('init')) - .catch(() => this.error.emit()); + private async setupPdfJsWorker(): Promise { + if (this.pdfJsWorkerInstance) { + await this.destroyPfdJsWorker(); + } else if (!this.pdfJsWorkerUrl) { + this.pdfJsWorkerUrl = await this.getPdfJsWorker(); + } + this.pdfJsWorkerInstance = new Worker(this.pdfJsWorkerUrl, { type: 'module' }); + this.pdfjsLib.GlobalWorkerOptions.workerPort = this.pdfJsWorkerInstance; + } + + private async getPdfJsWorker(): Promise { + const response = await fetch('./pdf.worker.min.mjs'); + const workerScript = await response.text(); + const blob = new Blob([workerScript], { type: 'application/javascript' }); + return URL.createObjectURL(blob); } initPDFViewer(pdfDocument: PDFDocumentProxy) { @@ -297,15 +316,23 @@ export class PdfViewerComponent implements OnChanges, OnDestroy { this.pdfjsWorkerDestroy$.next(true); } this.pdfjsWorkerDestroy$.complete(); + this.revokePdfJsWorkerUrl(); } - private async destroyPdJsWorker() { + private async destroyPfdJsWorker() { if (this.loadingTask.destroy) { await this.loadingTask.destroy(); } + if (this.pdfJsWorkerInstance) { + this.pdfJsWorkerInstance.terminate(); + } this.loadingTask = null; } + private revokePdfJsWorkerUrl(): void { + URL.revokeObjectURL(this.pdfJsWorkerUrl); + } + toggleThumbnails() { this.showThumbnails = !this.showThumbnails; }