From 8158628a9085c6c989e82c9b2631c8ecc819e0a7 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Thu, 28 Sep 2023 10:07:26 +0200 Subject: [PATCH 1/3] [api-minor] Stop building a minified default viewer The minified default viewer has never been distributed in either official releases or through pdfjs-dist, which means that it's most likely unused, and it's has never been tested nor actively maintained. --- gulpfile.mjs | 39 -------------------------------- web/viewer-snippet-minified.html | 3 --- web/viewer.html | 4 +--- 3 files changed, 1 insertion(+), 45 deletions(-) delete mode 100644 web/viewer-snippet-minified.html diff --git a/gulpfile.mjs b/gulpfile.mjs index 8cc36bd2e6757..d47533cbc19e8 100644 --- a/gulpfile.mjs +++ b/gulpfile.mjs @@ -1154,38 +1154,9 @@ function buildMinified(defines, dir) { createMainBundle(defines).pipe(gulp.dest(dir + "build")), createWorkerBundle(defines).pipe(gulp.dest(dir + "build")), createSandboxBundle(defines).pipe(gulp.dest(dir + "build")), - createWebBundle(defines, { - defaultPreferencesDir: defines.SKIP_BABEL - ? "minified/" - : "minified-legacy/", - }).pipe(gulp.dest(dir + "web")), createImageDecodersBundle( builder.merge(defines, { IMAGE_DECODERS: true }) ).pipe(gulp.dest(dir + "image_decoders")), - gulp.src(COMMON_WEB_FILES, { base: "web/" }).pipe(gulp.dest(dir + "web")), - gulp - .src(["web/locale/*/viewer.properties", "web/locale/locale.properties"], { - base: "web/", - }) - .pipe(gulp.dest(dir + "web")), - createCMapBundle().pipe(gulp.dest(dir + "web/cmaps")), - createStandardFontBundle().pipe(gulp.dest(dir + "web/standard_fonts")), - - preprocessHTML("web/viewer.html", defines).pipe(gulp.dest(dir + "web")), - preprocessCSS("web/viewer.css", defines) - .pipe( - postcss([ - postcssDirPseudoClass(), - discardCommentsCSS(), - postcssNesting(), - autoprefixer(AUTOPREFIXER_CONFIG), - ]) - ) - .pipe(gulp.dest(dir + "web")), - - gulp - .src("web/compressed.tracemonkey-pldi-09.pdf") - .pipe(gulp.dest(dir + "web")), ]); } @@ -1200,10 +1171,6 @@ async function parseMinified(dir) { const pdfImageDecodersFile = fs .readFileSync(dir + "/image_decoders/pdf.image_decoders.js") .toString(); - const viewerFiles = { - "pdf.js": pdfFile, - "viewer.js": fs.readFileSync(dir + "/web/viewer.js").toString(), - }; console.log(); console.log("### Minifying js files"); @@ -1218,10 +1185,6 @@ async function parseMinified(dir) { keep_fnames: true, }; - fs.writeFileSync( - dir + "/web/pdf.viewer.js", - (await minify(viewerFiles, options)).code - ); fs.writeFileSync( dir + "/build/pdf.min.js", (await minify(pdfFile, options)).code @@ -1242,8 +1205,6 @@ async function parseMinified(dir) { console.log(); console.log("### Cleaning js files"); - fs.unlinkSync(dir + "/web/viewer.js"); - fs.unlinkSync(dir + "/web/debugger.js"); fs.unlinkSync(dir + "/build/pdf.js"); fs.unlinkSync(dir + "/build/pdf.worker.js"); fs.unlinkSync(dir + "/build/pdf.sandbox.js"); diff --git a/web/viewer-snippet-minified.html b/web/viewer-snippet-minified.html deleted file mode 100644 index 4529f189c3610..0000000000000 --- a/web/viewer-snippet-minified.html +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/web/viewer.html b/web/viewer.html index cd1f6f50e6a02..95382b72704e9 100644 --- a/web/viewer.html +++ b/web/viewer.html @@ -33,8 +33,6 @@ - - @@ -47,7 +45,7 @@ - + From 0a970ee4434e62ed9ab5f134a9fc86ba8da81247 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Sat, 30 Sep 2023 13:25:47 +0200 Subject: [PATCH 2/3] [api-major] Remove the `fallbackWorkerSrc` functionality in browsers The user should *always* provide a correct `GlobalWorkerOptions.workerSrc` value when using the PDF.js library in browser environments. Note that the fallback: - Has been deprecated ever since PR 11418, first released in version `2.4.456` over three years ago. - Was always a best-effort solution, with no guarantees that it'd actually work correctly. - With upcoming changes, w.r.t. outputting JavaScript modules, it'd now be more diffiult to determine the correct value. --- src/display/api.js | 27 ++++----------------------- 1 file changed, 4 insertions(+), 23 deletions(-) diff --git a/src/display/api.js b/src/display/api.js index 43300b05279be..14382074f381d 100644 --- a/src/display/api.js +++ b/src/display/api.js @@ -45,7 +45,6 @@ import { SerializableEmpty, } from "./annotation_storage.js"; import { - deprecated, DOMCanvasFactory, DOMCMapReaderFactory, DOMFilterFactory, @@ -1984,7 +1983,6 @@ class LoopbackPort { const PDFWorkerUtil = { isWorkerDisabled: false, - fallbackWorkerSrc: null, fakeWorkerId: 0, }; if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) { @@ -1993,17 +1991,9 @@ if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) { // Workers aren't supported in Node.js, force-disabling them there. PDFWorkerUtil.isWorkerDisabled = true; - PDFWorkerUtil.fallbackWorkerSrc = PDFJSDev.test("LIB") + GlobalWorkerOptions.workerSrc ||= PDFJSDev.test("LIB") ? "../pdf.worker.js" : "./pdf.worker.js"; - } else if (typeof document === "object") { - const pdfjsFilePath = document?.currentScript?.src; - if (pdfjsFilePath) { - PDFWorkerUtil.fallbackWorkerSrc = pdfjsFilePath.replace( - /(\.(?:min\.)?js)(\?.*)?$/i, - ".worker$1$2" - ); - } } // Check if URLs have the same origin. For non-HTTP based URLs, returns false. @@ -2119,7 +2109,7 @@ class PDFWorker { // Uint8Array as it arrives on the worker. (Chrome added this with v.15.) if ( !PDFWorkerUtil.isWorkerDisabled && - !PDFWorker._mainThreadWorkerMessageHandler + !PDFWorker.#mainThreadWorkerMessageHandler ) { let { workerSrc } = PDFWorker; @@ -2308,19 +2298,10 @@ class PDFWorker { if (GlobalWorkerOptions.workerSrc) { return GlobalWorkerOptions.workerSrc; } - if ( - (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) && - PDFWorkerUtil.fallbackWorkerSrc !== null - ) { - if (!isNodeJS) { - deprecated('No "GlobalWorkerOptions.workerSrc" specified.'); - } - return PDFWorkerUtil.fallbackWorkerSrc; - } throw new Error('No "GlobalWorkerOptions.workerSrc" specified.'); } - static get _mainThreadWorkerMessageHandler() { + static get #mainThreadWorkerMessageHandler() { try { return globalThis.pdfjsWorker?.WorkerMessageHandler || null; } catch { @@ -2331,7 +2312,7 @@ class PDFWorker { // Loads worker code into the main-thread. static get _setupFakeWorkerGlobal() { const loader = async () => { - const mainWorkerMessageHandler = this._mainThreadWorkerMessageHandler; + const mainWorkerMessageHandler = this.#mainThreadWorkerMessageHandler; if (mainWorkerMessageHandler) { // The worker was already loaded using e.g. a ` - + + diff --git a/test/unit/api_spec.js b/test/unit/api_spec.js index f569a6dd2dde9..0396325c080b3 100644 --- a/test/unit/api_spec.js +++ b/test/unit/api_spec.js @@ -56,6 +56,8 @@ import { GlobalImageCache } from "../../src/core/image_utils.js"; import { GlobalWorkerOptions } from "../../src/display/worker_options.js"; import { Metadata } from "../../src/display/metadata.js"; +const WORKER_SRC = "../../build/generic/build/pdf.worker.mjs"; + describe("api", function () { const basicApiFileName = "basicapi.pdf"; const basicApiFileLength = 105779; // bytes @@ -914,7 +916,8 @@ describe("api", function () { } GlobalWorkerOptions.workerPort = new Worker( - new URL("../../build/generic/build/pdf.worker.js", window.location) + new URL(WORKER_SRC, window.location), + { type: "module" } ); const loadingTask1 = getDocument(basicApiGetDocumentParams); @@ -934,7 +937,8 @@ describe("api", function () { } GlobalWorkerOptions.workerPort = new Worker( - new URL("../../build/generic/build/pdf.worker.js", window.location) + new URL(WORKER_SRC, window.location), + { type: "module" } ); const loadingTask1 = getDocument(basicApiGetDocumentParams); @@ -963,7 +967,8 @@ describe("api", function () { } GlobalWorkerOptions.workerPort = new Worker( - new URL("../../build/generic/build/pdf.worker.js", window.location) + new URL(WORKER_SRC, window.location), + { type: "module" } ); const loadingTask = getDocument(basicApiGetDocumentParams); diff --git a/test/unit/jasmine-boot.js b/test/unit/jasmine-boot.js index 96d48558de55c..5852ae6daa8f6 100644 --- a/test/unit/jasmine-boot.js +++ b/test/unit/jasmine-boot.js @@ -108,7 +108,7 @@ async function initializePDFJS(callback) { ); } // Configure the worker. - GlobalWorkerOptions.workerSrc = "../../build/generic/build/pdf.worker.js"; + GlobalWorkerOptions.workerSrc = "../../build/generic/build/pdf.worker.mjs"; callback(); } diff --git a/test/unit/pdf_spec.js b/test/unit/pdf_spec.js index 413b9708dd45a..d647f5ced7313 100644 --- a/test/unit/pdf_spec.js +++ b/test/unit/pdf_spec.js @@ -49,7 +49,6 @@ import { getXfaPageViewport, isDataScheme, isPdfFile, - loadScript, noContextMenu, PDFDateString, PixelsPerInch, @@ -88,7 +87,6 @@ const expectedAPI = Object.freeze({ InvalidPDFException, isDataScheme, isPdfFile, - loadScript, MissingPDFException, noContextMenu, normalizeUnicode, @@ -132,10 +130,9 @@ describe("web_pdfjsLib", function () { if (isNodeJS) { pending("loadScript is not supported in Node.js."); } - await loadScript( - "../../build/generic/build/pdf.js", - /* removeScriptElement = */ true - ); + const apiPath = "../../build/generic/build/pdf.mjs"; + await import(apiPath); + const webPdfjsLib = await import("../../web/pdfjs.js"); expect(Object.keys(webPdfjsLib).sort()).toEqual( diff --git a/test/unit/scripting_spec.js b/test/unit/scripting_spec.js index bfcc10a567a84..dbeb58d9b8f9d 100644 --- a/test/unit/scripting_spec.js +++ b/test/unit/scripting_spec.js @@ -13,9 +13,7 @@ * limitations under the License. */ -import { loadScript } from "../../src/display/display_utils.js"; - -const sandboxBundleSrc = "../../build/generic/build/pdf.sandbox.js"; +const sandboxBundleSrc = "../../build/generic/build/pdf.sandbox.mjs"; describe("Scripting", function () { let sandbox, send_queue, test_id, ref, windowAlert; @@ -53,8 +51,9 @@ describe("Scripting", function () { const command = "alert"; send_queue.set(command, { command, value }); }; - const promise = loadScript(sandboxBundleSrc).then(() => { - return window.pdfjsSandbox.QuickJSSandbox(); + // eslint-disable-next-line no-unsanitized/method + const promise = import(sandboxBundleSrc).then(pdfjsSandbox => { + return pdfjsSandbox.QuickJSSandbox(); }); sandbox = { createSandbox(data) { diff --git a/web/app.js b/web/app.js index 560fb784b705a..d5675e5785281 100644 --- a/web/app.js +++ b/web/app.js @@ -44,7 +44,6 @@ import { InvalidPDFException, isDataScheme, isPdfFile, - loadScript, MissingPDFException, PDFWorker, PromiseCapability, @@ -2264,10 +2263,10 @@ async function loadFakeWorker() { GlobalWorkerOptions.workerSrc ||= AppOptions.get("workerSrc"); if (typeof PDFJSDev === "undefined") { - window.pdfjsWorker = await import("pdfjs/pdf.worker.js"); + globalThis.pdfjsWorker = await import("pdfjs/pdf.worker.js"); return; } - await loadScript(PDFWorker.workerSrc); + await __non_webpack_import__(PDFWorker.workerSrc); // eslint-disable-line no-undef } async function loadPDFBug(self) { diff --git a/web/app_options.js b/web/app_options.js index 13de9889854cf..e461f3910e85e 100644 --- a/web/app_options.js +++ b/web/app_options.js @@ -300,8 +300,8 @@ const defaultOptions = { typeof PDFJSDev === "undefined" ? "../src/pdf.worker.js" : PDFJSDev.test("MOZCENTRAL") - ? "resource://pdf.js/build/pdf.worker.js" - : "../build/pdf.worker.js", + ? "resource://pdf.js/build/pdf.worker.mjs" + : "../build/pdf.worker.mjs", kind: OptionKind.WORKER, }, }; @@ -325,8 +325,8 @@ if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) { /** @type {string} */ value: typeof PDFJSDev === "undefined" - ? "../build/dev-sandbox/pdf.sandbox.js" - : "../build/pdf.sandbox.js", + ? "../build/dev-sandbox/pdf.sandbox.mjs" + : "../build/pdf.sandbox.mjs", kind: OptionKind.VIEWER, }; } else if (PDFJSDev.test("CHROME")) { diff --git a/web/generic_scripting.js b/web/generic_scripting.js index 0c0aa8024df78..8b7f33305c1cb 100644 --- a/web/generic_scripting.js +++ b/web/generic_scripting.js @@ -13,7 +13,7 @@ * limitations under the License. */ -import { getPdfFilenameFromUrl, loadScript } from "pdfjs-lib"; +import { getPdfFilenameFromUrl } from "pdfjs-lib"; async function docProperties(pdfDocument) { const url = "", @@ -41,11 +41,16 @@ async function docProperties(pdfDocument) { class GenericScripting { constructor(sandboxBundleSrc) { - this._ready = loadScript( - sandboxBundleSrc, - /* removeScriptElement = */ true - ).then(() => { - return window.pdfjsSandbox.QuickJSSandbox(); + this._ready = new Promise((resolve, reject) => { + const sandbox = + typeof PDFJSDev === "undefined" + ? import(sandboxBundleSrc) // eslint-disable-line no-unsanitized/method + : __non_webpack_import__(sandboxBundleSrc); // eslint-disable-line no-undef + sandbox + .then(pdfjsSandbox => { + resolve(pdfjsSandbox.QuickJSSandbox()); + }) + .catch(reject); }); } diff --git a/web/pdfjs.js b/web/pdfjs.js index cb9f39d74d4fb..3ca9b549072f7 100644 --- a/web/pdfjs.js +++ b/web/pdfjs.js @@ -35,7 +35,6 @@ const { InvalidPDFException, isDataScheme, isPdfFile, - loadScript, MissingPDFException, noContextMenu, normalizeUnicode, @@ -81,7 +80,6 @@ export { InvalidPDFException, isDataScheme, isPdfFile, - loadScript, MissingPDFException, noContextMenu, normalizeUnicode, diff --git a/web/viewer-geckoview.html b/web/viewer-geckoview.html index 6f42a2f560293..b6ebd15d61588 100644 --- a/web/viewer-geckoview.html +++ b/web/viewer-geckoview.html @@ -76,7 +76,7 @@ - + diff --git a/web/viewer-snippet-chrome-extension.html b/web/viewer-snippet-chrome-extension.html index dcf2ed59800c3..6cd81812e09a8 100644 --- a/web/viewer-snippet-chrome-extension.html +++ b/web/viewer-snippet-chrome-extension.html @@ -1,4 +1,4 @@ - + diff --git a/web/viewer-snippet-firefox-extension.html b/web/viewer-snippet-firefox-extension.html index c7c416d503b57..aa6cf5d9b10a9 100644 --- a/web/viewer-snippet-firefox-extension.html +++ b/web/viewer-snippet-firefox-extension.html @@ -1,2 +1,2 @@ - + diff --git a/web/viewer-snippet.html b/web/viewer-snippet.html index f0bea7080a8eb..56864bf6769fa 100644 --- a/web/viewer-snippet.html +++ b/web/viewer-snippet.html @@ -1,3 +1,3 @@ - + diff --git a/web/viewer.html b/web/viewer.html index 95382b72704e9..0b0d9d1527365 100644 --- a/web/viewer.html +++ b/web/viewer.html @@ -44,9 +44,9 @@ - + - +