diff --git a/web/chromecom.js b/web/chromecom.js index 823251221..61c2cb636 100644 --- a/web/chromecom.js +++ b/web/chromecom.js @@ -147,7 +147,7 @@ function reloadIfRuntimeIsUnavailable() { let chromeFileAccessOverlayPromise; function requestAccessToLocalFile(fileUrl, overlayManager, callback) { - let onCloseOverlay = null; + const dialog = document.getElementById("chromeFileAccessDialog"); if (top !== window) { // When the extension reloads after receiving new permissions, the pages // have to be reloaded to restore the extension runtime. Auto-reload @@ -157,18 +157,16 @@ function requestAccessToLocalFile(fileUrl, overlayManager, callback) { // for detecting unload of the top-level frame. Should this ever change // (crbug.com/511670), then the user can just reload the tab. window.addEventListener("focus", reloadIfRuntimeIsUnavailable); - onCloseOverlay = function () { + dialog.addEventListener("close", function () { window.removeEventListener("focus", reloadIfRuntimeIsUnavailable); reloadIfRuntimeIsUnavailable(); - overlayManager.close("chromeFileAccessOverlay"); - }; + }); } if (!chromeFileAccessOverlayPromise) { chromeFileAccessOverlayPromise = overlayManager.register( - "chromeFileAccessOverlay", - document.getElementById("chromeFileAccessOverlay"), - onCloseOverlay, - true + "chromeFileAccessDialog", + dialog, + /* canForceClose = */ true ); } chromeFileAccessOverlayPromise.then(function () { @@ -233,7 +231,7 @@ function requestAccessToLocalFile(fileUrl, overlayManager, callback) { } }; - overlayManager.open("chromeFileAccessOverlay"); + overlayManager.open("chromeFileAccessDialog"); }); } diff --git a/web/overlay_manager.js b/web/overlay_manager.js index b77f4a61a..d7d8ee2c8 100644 --- a/web/overlay_manager.js +++ b/web/overlay_manager.js @@ -18,43 +18,29 @@ class OverlayManager { #active = null; - #keyDownBound = null; - get active() { return this.#active; } /** * @param {string} name - The name of the overlay that is registered. - * @param {HTMLDivElement} element - The overlay's DOM element. - * @param {function} [callerCloseMethod] - The method that, if present, calls - * `OverlayManager.close` from the object registering the - * overlay. Access to this method is necessary in order to - * run cleanup code when e.g. the overlay is force closed. - * The default is `null`. + * @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, - element, - callerCloseMethod = null, - canForceClose = false - ) { - let container; - if (!name || !element || !(container = element.parentNode)) { + async register(name, dialog, canForceClose = false) { + if (!name || !dialog) { throw new Error("Not enough parameters."); } else if (this.#overlays[name]) { throw new Error("The overlay is already registered."); } - this.#overlays[name] = { - element, - container, - callerCloseMethod, - canForceClose, - }; + this.#overlays[name] = { dialog, canForceClose }; + + dialog.addEventListener("cancel", evt => { + this.#active = null; + }); } /** @@ -83,17 +69,13 @@ class OverlayManager { if (this.#active === name) { throw new Error("The overlay is already active."); } else if (this.#overlays[name].canForceClose) { - this.#closeThroughCaller(); + await this.close(); } else { throw new Error("Another overlay is currently active."); } } this.#active = name; - this.#overlays[this.#active].element.classList.remove("hidden"); - this.#overlays[this.#active].container.classList.remove("hidden"); - - this.#keyDownBound = this.#keyDown.bind(this); - window.addEventListener("keydown", this.#keyDownBound); + this.#overlays[this.#active].dialog.showModal(); } /** @@ -101,7 +83,7 @@ class OverlayManager { * @returns {Promise} A promise that is resolved when the overlay has been * closed. */ - async close(name) { + async close(name = this.#active) { if (!this.#overlays[name]) { throw new Error("The overlay does not exist."); } else if (!this.#active) { @@ -109,28 +91,8 @@ class OverlayManager { } else if (this.#active !== name) { throw new Error("Another overlay is currently active."); } - this.#overlays[this.#active].container.classList.add("hidden"); - this.#overlays[this.#active].element.classList.add("hidden"); + this.#overlays[this.#active].dialog.close(); this.#active = null; - - window.removeEventListener("keydown", this.#keyDownBound); - this.#keyDownBound = null; - } - - #keyDown(evt) { - if (this.#active && evt.keyCode === /* Esc = */ 27) { - this.#closeThroughCaller(); - evt.preventDefault(); - } - } - - #closeThroughCaller() { - if (this.#overlays[this.#active].callerCloseMethod) { - this.#overlays[this.#active].callerCloseMethod(); - } - if (this.#active) { - this.close(this.#active); - } } } diff --git a/web/password_prompt.js b/web/password_prompt.js index 6631783c7..1a8728553 100644 --- a/web/password_prompt.js +++ b/web/password_prompt.js @@ -17,8 +17,8 @@ import { PasswordResponses } from "pdfjs-lib"; /** * @typedef {Object} PasswordPromptOptions - * @property {string} overlayName - Name of the overlay for the overlay manager. - * @property {HTMLDivElement} container - Div container for the overlay. + * @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. * @property {HTMLInputElement} input - Input field for entering the password. @@ -29,6 +29,10 @@ import { PasswordResponses } from "pdfjs-lib"; */ class PasswordPrompt { + #updateCallback = null; + + #reason = null; + /** * @param {PasswordPromptOptions} options * @param {OverlayManager} overlayManager - Manager for the viewer overlays. @@ -37,8 +41,8 @@ class PasswordPrompt { * an