diff options
Diffstat (limited to 'tools/addon-sdk-1.7/packages/api-utils/lib/windows/loader.js')
-rw-r--r-- | tools/addon-sdk-1.7/packages/api-utils/lib/windows/loader.js | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/tools/addon-sdk-1.7/packages/api-utils/lib/windows/loader.js b/tools/addon-sdk-1.7/packages/api-utils/lib/windows/loader.js new file mode 100644 index 0000000..b596e73 --- /dev/null +++ b/tools/addon-sdk-1.7/packages/api-utils/lib/windows/loader.js @@ -0,0 +1,120 @@ +/* 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 { Cc, Ci } = require('chrome'), + { setTimeout } = require("../timer"), + { Trait } = require('../traits'), + + WM = Cc['@mozilla.org/appshell/window-mediator;1']. + getService(Ci.nsIWindowMediator), + + URI_BROWSER = 'chrome://browser/content/browser.xul', + NAME = '_blank', + FEATURES = 'chrome,all,dialog=no', + PARAMS = [ URI_BROWSER, NAME, FEATURES ], + ON_LOAD = 'load', + ON_UNLOAD = 'unload', + STATE_LOADED = 'complete', + BROWSER = 'navigator:browser'; + +/** + * Trait provides private `_window` property and requires `_onLoad` property + * that will be called when `_window` is loaded. If `_window` property value + * is changed with already loaded window `_onLoad` still will be called. + */ +const WindowLoader = Trait.compose({ + /** + * Internal listener that is called when window is loaded. + * Please keep in mind that this trait will not handle exceptions that may + * be thrown by this method so method itself should take care of + * handling them. + * @param {nsIWindow} window + */ + _onLoad: Trait.required, + _tabOptions: Trait.required, + /** + * Internal listener that is called when `_window`'s DOM 'unload' event + * is dispatched. Please note that this trait will not handle exceptions that + * may be thrown by this method so method itself should take care of + * handling them. + */ + _onUnload: Trait.required, + _load: function _load() { + if (this.__window) return; + let params = PARAMS.slice() + params.push(this._tabOptions.map(function(options) options.url).join("|")) + let browser = WM.getMostRecentWindow(BROWSER); + this._window = browser.openDialog.apply(browser, params); + }, + /** + * Private window who's load event is being tracked. Once window is loaded + * `_onLoad` is called. + * @type {nsIWindow} + */ + get _window() this.__window, + set _window(window) { + let _window = this.__window; + if (!window) window = null; + if (window !== _window) { + if (_window) { + _window.removeEventListener(ON_UNLOAD, this.__unloadListener, false); + _window.removeEventListener(ON_LOAD, this.__loadListener, false); + } + if (window) { + window.addEventListener( + ON_UNLOAD, + this.__unloadListener || + (this.__unloadListener = this._unloadListener.bind(this)) + , + false + ); + this.__window = window; + // If window is not loaded yet setting up a listener. + if (STATE_LOADED != window.document.readyState) { + window.addEventListener( + ON_LOAD, + this.__loadListener || + (this.__loadListener = this._loadListener.bind(this)) + , + false + ); + } + else { // If window is loaded calling listener next turn of event loop. + this._onLoad(window) + } + } + } + }, + __window: null, + /** + * Internal method used for listening 'load' event on the `_window`. + * Method takes care of removing itself from 'load' event listeners once + * event is being handled. + */ + _loadListener: function _loadListener(event) { + let window = this._window; + if (!event.target || event.target.defaultView != window) return; + window.removeEventListener(ON_LOAD, this.__loadListener, false); + this._onLoad(window); + }, + __loadListener: null, + /** + * Internal method used for listening 'unload' event on the `_window`. + * Method takes care of removing itself from 'unload' event listeners once + * event is being handled. + */ + _unloadListener: function _unloadListener(event) { + let window = this._window; + if (!event.target + || event.target.defaultView != window + || STATE_LOADED != window.document.readyState + ) return; + window.removeEventListener(ON_UNLOAD, this.__unloadListener, false); + this._onUnload(window); + }, + __unloadListener: null +}); +exports.WindowLoader = WindowLoader; + |