diff options
Diffstat (limited to 'testing/marionette/modal.js')
-rw-r--r-- | testing/marionette/modal.js | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/testing/marionette/modal.js b/testing/marionette/modal.js new file mode 100644 index 000000000..3c1b46437 --- /dev/null +++ b/testing/marionette/modal.js @@ -0,0 +1,113 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +const {utils: Cu} = Components; + +Cu.import("resource://gre/modules/Services.jsm"); + +this.EXPORTED_SYMBOLS = ["modal"]; + +const isFirefox = () => Services.appinfo.name == "Firefox"; + +this.modal = {}; +modal = { + COMMON_DIALOG_LOADED: "common-dialog-loaded", + TABMODAL_DIALOG_LOADED: "tabmodal-dialog-loaded", + handlers: { + "common-dialog-loaded": new Set(), + "tabmodal-dialog-loaded": new Set() + } +}; + +/** + * Add handler that will be called when a global- or tab modal dialogue + * appears. + * + * This is achieved by installing observers for common- + * and tab modal loaded events. + * + * This function is a no-op if called on any other product than Firefox. + * + * @param {function(Object, string)} handler + * The handler to be called, which is passed the + * subject (e.g. ChromeWindow) and the topic (one of + * {@code modal.COMMON_DIALOG_LOADED} or + * {@code modal.TABMODAL_DIALOG_LOADED}. + */ +modal.addHandler = function (handler) { + if (!isFirefox()) { + return; + } + + Object.keys(this.handlers).map(topic => { + this.handlers[topic].add(handler); + Services.obs.addObserver(handler, topic, false); + }); +}; + +/** + * Remove modal dialogue handler by function reference. + * + * This function is a no-op if called on any other product than Firefox. + * + * @param {function} toRemove + * The handler previously passed to modal.addHandler which will now + * be removed. + */ +modal.removeHandler = function (toRemove) { + if (!isFirefox()) { + return; + } + + for (let topic of Object.keys(this.handlers)) { + let handlers = this.handlers[topic]; + for (let handler of handlers) { + if (handler == toRemove) { + Services.obs.removeObserver(handler, topic); + handlers.delete(handler); + } + } + } +}; + +/** + * Represents the current modal dialogue. + * + * @param {function(): browser.Context} curBrowserFn + * Function that returns the current |browser.Context|. + * @param {nsIWeakReference=} winRef + * A weak reference to the current |ChromeWindow|. + */ +modal.Dialog = class { + constructor(curBrowserFn, winRef = undefined) { + this.curBrowserFn_ = curBrowserFn; + this.win_ = winRef; + } + + get curBrowser_() { return this.curBrowserFn_(); } + + /** + * Returns the ChromeWindow associated with an open dialog window if + * it is currently attached to the DOM. + */ + get window() { + if (this.win_) { + let win = this.win_.get(); + if (win && win.parent) { + return win; + } + } + return null; + } + + get ui() { + let win = this.window; + if (win) { + return win.Dialog.ui; + } + return this.curBrowser_.getTabModalUI(); + } +}; |