diff --git a/src/display/api.js b/src/display/api.js index 20d8226fc..ef2511fdb 100644 --- a/src/display/api.js +++ b/src/display/api.js @@ -2124,103 +2124,105 @@ class PDFWorker { // support, create a new web worker and test if it/the browser fulfills // all requirements to run parts of pdf.js in a web worker. // Right now, the requirement is, that an Uint8Array is still an - // Uint8Array as it arrives on the worker. (Chrome added this with v.15.) + // Uint8Array as it arrives on the worker. if ( - !PDFWorkerUtil.isWorkerDisabled && - !PDFWorker.#mainThreadWorkerMessageHandler + PDFWorkerUtil.isWorkerDisabled || + PDFWorker.#mainThreadWorkerMessageHandler ) { - let { workerSrc } = PDFWorker; + this._setupFakeWorker(); + return; + } + let { workerSrc } = PDFWorker; - try { - // Wraps workerSrc path into blob URL, if the former does not belong - // to the same origin. - if ( - typeof PDFJSDev !== "undefined" && - PDFJSDev.test("GENERIC") && - !PDFWorkerUtil.isSameOrigin(window.location.href, workerSrc) - ) { - workerSrc = PDFWorkerUtil.createCDNWrapper( - new URL(workerSrc, window.location).href - ); + try { + // Wraps workerSrc path into blob URL, if the former does not belong + // to the same origin. + if ( + typeof PDFJSDev !== "undefined" && + PDFJSDev.test("GENERIC") && + !PDFWorkerUtil.isSameOrigin(window.location.href, workerSrc) + ) { + workerSrc = PDFWorkerUtil.createCDNWrapper( + new URL(workerSrc, window.location).href + ); + } + + const worker = new Worker(workerSrc, { type: "module" }); + const messageHandler = new MessageHandler("main", "worker", worker); + const terminateEarly = () => { + worker.removeEventListener("error", onWorkerError); + messageHandler.destroy(); + worker.terminate(); + if (this.destroyed) { + this._readyCapability.reject(new Error("Worker was destroyed")); + } else { + // Fall back to fake worker if the termination is caused by an + // error (e.g. NetworkError / SecurityError). + this._setupFakeWorker(); } + }; - const worker = new Worker(workerSrc, { type: "module" }); - const messageHandler = new MessageHandler("main", "worker", worker); - const terminateEarly = () => { - worker.removeEventListener("error", onWorkerError); + const onWorkerError = () => { + if (!this._webWorker) { + // Worker failed to initialize due to an error. Clean up and fall + // back to the fake worker. + terminateEarly(); + } + }; + worker.addEventListener("error", onWorkerError); + + messageHandler.on("test", data => { + worker.removeEventListener("error", onWorkerError); + if (this.destroyed) { + terminateEarly(); + return; // worker was destroyed + } + if (data) { + this._messageHandler = messageHandler; + this._port = worker; + this._webWorker = worker; + + this._readyCapability.resolve(); + // Send global setting, e.g. verbosity level. + messageHandler.send("configure", { + verbosity: this.verbosity, + }); + } else { + this._setupFakeWorker(); messageHandler.destroy(); worker.terminate(); - if (this.destroyed) { - this._readyCapability.reject(new Error("Worker was destroyed")); - } else { - // Fall back to fake worker if the termination is caused by an - // error (e.g. NetworkError / SecurityError). - this._setupFakeWorker(); - } - }; + } + }); - const onWorkerError = () => { - if (!this._webWorker) { - // Worker failed to initialize due to an error. Clean up and fall - // back to the fake worker. - terminateEarly(); - } - }; - worker.addEventListener("error", onWorkerError); + messageHandler.on("ready", data => { + worker.removeEventListener("error", onWorkerError); + if (this.destroyed) { + terminateEarly(); + return; // worker was destroyed + } + try { + sendTest(); + } catch { + // We need fallback to a faked worker. + this._setupFakeWorker(); + } + }); - messageHandler.on("test", data => { - worker.removeEventListener("error", onWorkerError); - if (this.destroyed) { - terminateEarly(); - return; // worker was destroyed - } - if (data) { - this._messageHandler = messageHandler; - this._port = worker; - this._webWorker = worker; + const sendTest = () => { + const testObj = new Uint8Array(); + // Ensure that we can use `postMessage` transfers. + messageHandler.send("test", testObj, [testObj.buffer]); + }; - this._readyCapability.resolve(); - // Send global setting, e.g. verbosity level. - messageHandler.send("configure", { - verbosity: this.verbosity, - }); - } else { - this._setupFakeWorker(); - messageHandler.destroy(); - worker.terminate(); - } - }); - - messageHandler.on("ready", data => { - worker.removeEventListener("error", onWorkerError); - if (this.destroyed) { - terminateEarly(); - return; // worker was destroyed - } - try { - sendTest(); - } catch { - // We need fallback to a faked worker. - this._setupFakeWorker(); - } - }); - - const sendTest = () => { - const testObj = new Uint8Array(); - // Ensure that we can use `postMessage` transfers. - messageHandler.send("test", testObj, [testObj.buffer]); - }; - - // It might take time for the worker to initialize. We will try to send - // the "test" message immediately, and once the "ready" message arrives. - // The worker shall process only the first received "test" message. - sendTest(); - return; - } catch { - info("The worker has been disabled."); - } + // It might take time for the worker to initialize. We will try to send + // the "test" message immediately, and once the "ready" message arrives. + // The worker shall process only the first received "test" message. + sendTest(); + return; + } catch { + info("The worker has been disabled."); } - // Either workers are disabled, not supported or have thrown an exception. + // Either workers are not supported or have thrown an exception. // Thus, we fallback to a faked worker. this._setupFakeWorker(); }