From 923bd52cdb94e0a0afa5a3d8261f64ad0e8e7e84 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Fri, 25 Mar 2022 14:10:22 +0100 Subject: [PATCH] Re-factor the `OverlayManager` class to use a `WeakMap` internally This way we're able to store the `` elements directly, which removes the need to use manually specified name-strings thus simplifying both the `OverlayManager` itself and its calling code. --- web/chromecom.js | 16 ++++++------ web/overlay_manager.js | 45 +++++++++++++++++----------------- web/password_prompt.js | 14 +++-------- web/pdf_document_properties.js | 17 ++++--------- web/pdf_print_service.js | 20 +++++++-------- web/viewer.js | 2 -- 6 files changed, 48 insertions(+), 66 deletions(-) diff --git a/web/chromecom.js b/web/chromecom.js index 61c2cb636..64b5ee042 100644 --- a/web/chromecom.js +++ b/web/chromecom.js @@ -162,13 +162,11 @@ function requestAccessToLocalFile(fileUrl, overlayManager, callback) { reloadIfRuntimeIsUnavailable(); }); } - if (!chromeFileAccessOverlayPromise) { - chromeFileAccessOverlayPromise = overlayManager.register( - "chromeFileAccessDialog", - dialog, - /* canForceClose = */ true - ); - } + chromeFileAccessOverlayPromise ||= overlayManager.register( + dialog, + /* canForceClose = */ true + ); + chromeFileAccessOverlayPromise.then(function () { const iconPath = chrome.runtime.getManifest().icons[48]; document.getElementById("chrome-pdfjs-logo-bg").style.backgroundImage = @@ -227,11 +225,11 @@ function requestAccessToLocalFile(fileUrl, overlayManager, callback) { originalUrl = "file:///fakepath/to/" + encodeURIComponent(file.name); } callback(URL.createObjectURL(file), file.size, originalUrl); - overlayManager.close("chromeFileAccessOverlay"); + overlayManager.close(dialog); } }; - overlayManager.open("chromeFileAccessDialog"); + overlayManager.open(dialog); }); } diff --git a/web/overlay_manager.js b/web/overlay_manager.js index d7d8ee2c8..233c9f594 100644 --- a/web/overlay_manager.js +++ b/web/overlay_manager.js @@ -14,7 +14,7 @@ */ class OverlayManager { - #overlays = Object.create(null); + #overlays = new WeakMap(); #active = null; @@ -23,20 +23,19 @@ class OverlayManager { } /** - * @param {string} name - The name of the overlay that is registered. * @param {HTMLDialogElement} dialog - The overlay's DOM element. * @param {boolean} [canForceClose] - Indicates if opening the overlay closes * an active overlay. The default is `false`. * @returns {Promise} A promise that is resolved when the overlay has been * registered. */ - async register(name, dialog, canForceClose = false) { - if (!name || !dialog) { + async register(dialog, canForceClose = false) { + if (typeof dialog !== "object") { throw new Error("Not enough parameters."); - } else if (this.#overlays[name]) { + } else if (this.#overlays.has(dialog)) { throw new Error("The overlay is already registered."); } - this.#overlays[name] = { dialog, canForceClose }; + this.#overlays.set(dialog, { canForceClose }); dialog.addEventListener("cancel", evt => { this.#active = null; @@ -44,54 +43,54 @@ class OverlayManager { } /** - * @param {string} name - The name of the overlay that is unregistered. + * @param {HTMLDialogElement} dialog - The overlay's DOM element. * @returns {Promise} A promise that is resolved when the overlay has been * unregistered. */ - async unregister(name) { - if (!this.#overlays[name]) { + async unregister(dialog) { + if (!this.#overlays.has(dialog)) { throw new Error("The overlay does not exist."); - } else if (this.#active === name) { + } else if (this.#active === dialog) { throw new Error("The overlay cannot be removed while it is active."); } - delete this.#overlays[name]; + this.#overlays.delete(dialog); } /** - * @param {string} name - The name of the overlay that should be opened. + * @param {HTMLDialogElement} dialog - The overlay's DOM element. * @returns {Promise} A promise that is resolved when the overlay has been * opened. */ - async open(name) { - if (!this.#overlays[name]) { + async open(dialog) { + if (!this.#overlays.has(dialog)) { throw new Error("The overlay does not exist."); } else if (this.#active) { - if (this.#active === name) { + if (this.#active === dialog) { throw new Error("The overlay is already active."); - } else if (this.#overlays[name].canForceClose) { + } else if (this.#overlays.get(dialog).canForceClose) { await this.close(); } else { throw new Error("Another overlay is currently active."); } } - this.#active = name; - this.#overlays[this.#active].dialog.showModal(); + this.#active = dialog; + dialog.showModal(); } /** - * @param {string} name - The name of the overlay that should be closed. + * @param {HTMLDialogElement} dialog - The overlay's DOM element. * @returns {Promise} A promise that is resolved when the overlay has been * closed. */ - async close(name = this.#active) { - if (!this.#overlays[name]) { + async close(dialog = this.#active) { + if (!this.#overlays.has(dialog)) { throw new Error("The overlay does not exist."); } else if (!this.#active) { throw new Error("The overlay is currently not active."); - } else if (this.#active !== name) { + } else if (this.#active !== dialog) { throw new Error("Another overlay is currently active."); } - this.#overlays[this.#active].dialog.close(); + dialog.close(); this.#active = null; } } diff --git a/web/password_prompt.js b/web/password_prompt.js index 1a8728553..2207b1a9d 100644 --- a/web/password_prompt.js +++ b/web/password_prompt.js @@ -17,7 +17,6 @@ import { PasswordResponses } from "pdfjs-lib"; /** * @typedef {Object} PasswordPromptOptions - * @property {string} dialogName - Name/identifier for the dialog. * @property {HTMLDialogElement} dialog - The overlay's DOM element. * @property {HTMLParagraphElement} label - Label containing instructions for * entering the password. @@ -41,7 +40,6 @@ class PasswordPrompt { * an