overlay_manager.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /* Copyright 2014 Mozilla Foundation
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. class OverlayManager {
  16. #overlays = new WeakMap();
  17. #active = null;
  18. get active() {
  19. return this.#active;
  20. }
  21. /**
  22. * @param {HTMLDialogElement} dialog - The overlay's DOM element.
  23. * @param {boolean} [canForceClose] - Indicates if opening the overlay closes
  24. * an active overlay. The default is `false`.
  25. * @returns {Promise} A promise that is resolved when the overlay has been
  26. * registered.
  27. */
  28. async register(dialog, canForceClose = false) {
  29. if (typeof dialog !== "object") {
  30. throw new Error("Not enough parameters.");
  31. } else if (this.#overlays.has(dialog)) {
  32. throw new Error("The overlay is already registered.");
  33. }
  34. this.#overlays.set(dialog, { canForceClose });
  35. if (
  36. typeof PDFJSDev !== "undefined" &&
  37. PDFJSDev.test("GENERIC && !SKIP_BABEL") &&
  38. !dialog.showModal
  39. ) {
  40. const dialogPolyfill = require("dialog-polyfill/dist/dialog-polyfill.js");
  41. dialogPolyfill.registerDialog(dialog);
  42. if (!this._dialogPolyfillCSS) {
  43. this._dialogPolyfillCSS = true;
  44. const style = document.createElement("style");
  45. style.textContent = PDFJSDev.eval("DIALOG_POLYFILL_CSS");
  46. document.head.prepend(style);
  47. }
  48. }
  49. dialog.addEventListener("cancel", evt => {
  50. this.#active = null;
  51. });
  52. }
  53. /**
  54. * @param {HTMLDialogElement} dialog - The overlay's DOM element.
  55. * @returns {Promise} A promise that is resolved when the overlay has been
  56. * unregistered.
  57. */
  58. async unregister(dialog) {
  59. if (!this.#overlays.has(dialog)) {
  60. throw new Error("The overlay does not exist.");
  61. } else if (this.#active === dialog) {
  62. throw new Error("The overlay cannot be removed while it is active.");
  63. }
  64. this.#overlays.delete(dialog);
  65. }
  66. /**
  67. * @param {HTMLDialogElement} dialog - The overlay's DOM element.
  68. * @returns {Promise} A promise that is resolved when the overlay has been
  69. * opened.
  70. */
  71. async open(dialog) {
  72. if (!this.#overlays.has(dialog)) {
  73. throw new Error("The overlay does not exist.");
  74. } else if (this.#active) {
  75. if (this.#active === dialog) {
  76. throw new Error("The overlay is already active.");
  77. } else if (this.#overlays.get(dialog).canForceClose) {
  78. await this.close();
  79. } else {
  80. throw new Error("Another overlay is currently active.");
  81. }
  82. }
  83. this.#active = dialog;
  84. dialog.showModal();
  85. }
  86. /**
  87. * @param {HTMLDialogElement} dialog - The overlay's DOM element.
  88. * @returns {Promise} A promise that is resolved when the overlay has been
  89. * closed.
  90. */
  91. async close(dialog = this.#active) {
  92. if (!this.#overlays.has(dialog)) {
  93. throw new Error("The overlay does not exist.");
  94. } else if (!this.#active) {
  95. throw new Error("The overlay is currently not active.");
  96. } else if (this.#active !== dialog) {
  97. throw new Error("Another overlay is currently active.");
  98. }
  99. dialog.close();
  100. this.#active = null;
  101. }
  102. }
  103. export { OverlayManager };