addon-sdk/source/lib/sdk/windows/loader.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4 'use strict';
michael@0 5
michael@0 6 module.metadata = {
michael@0 7 "stability": "unstable"
michael@0 8 };
michael@0 9
michael@0 10 const { Cc, Ci } = require('chrome'),
michael@0 11 { setTimeout } = require('../timers'),
michael@0 12 { Trait } = require('../deprecated/traits'),
michael@0 13 { openDialog } = require('../window/utils'),
michael@0 14
michael@0 15 ON_LOAD = 'load',
michael@0 16 ON_UNLOAD = 'unload',
michael@0 17 STATE_LOADED = 'complete';
michael@0 18
michael@0 19 /**
michael@0 20 * Trait provides private `_window` property and requires `_onLoad` property
michael@0 21 * that will be called when `_window` is loaded. If `_window` property value
michael@0 22 * is changed with already loaded window `_onLoad` still will be called.
michael@0 23 */
michael@0 24 const WindowLoader = Trait.compose({
michael@0 25 /**
michael@0 26 * Internal listener that is called when window is loaded.
michael@0 27 * Please keep in mind that this trait will not handle exceptions that may
michael@0 28 * be thrown by this method so method itself should take care of
michael@0 29 * handling them.
michael@0 30 * @param {nsIWindow} window
michael@0 31 */
michael@0 32 _onLoad: Trait.required,
michael@0 33 _tabOptions: Trait.required,
michael@0 34 /**
michael@0 35 * Internal listener that is called when `_window`'s DOM 'unload' event
michael@0 36 * is dispatched. Please note that this trait will not handle exceptions that
michael@0 37 * may be thrown by this method so method itself should take care of
michael@0 38 * handling them.
michael@0 39 */
michael@0 40 _onUnload: Trait.required,
michael@0 41 _load: function _load() {
michael@0 42 if (this.__window)
michael@0 43 return;
michael@0 44
michael@0 45 this._window = openDialog({
michael@0 46 private: this._isPrivate,
michael@0 47 args: this._tabOptions.map(function(options) options.url).join("|")
michael@0 48 });
michael@0 49 },
michael@0 50 /**
michael@0 51 * Private window who's load event is being tracked. Once window is loaded
michael@0 52 * `_onLoad` is called.
michael@0 53 * @type {nsIWindow}
michael@0 54 */
michael@0 55 get _window() this.__window,
michael@0 56 set _window(window) {
michael@0 57 let _window = this.__window;
michael@0 58 if (!window) window = null;
michael@0 59
michael@0 60 if (window !== _window) {
michael@0 61 if (_window) {
michael@0 62 _window.removeEventListener(ON_UNLOAD, this.__unloadListener, false);
michael@0 63 _window.removeEventListener(ON_LOAD, this.__loadListener, false);
michael@0 64 }
michael@0 65
michael@0 66 if (window) {
michael@0 67 window.addEventListener(
michael@0 68 ON_UNLOAD,
michael@0 69 this.__unloadListener ||
michael@0 70 (this.__unloadListener = this._unloadListener.bind(this))
michael@0 71 ,
michael@0 72 false
michael@0 73 );
michael@0 74
michael@0 75 this.__window = window;
michael@0 76
michael@0 77 // If window is not loaded yet setting up a listener.
michael@0 78 if (STATE_LOADED != window.document.readyState) {
michael@0 79 window.addEventListener(
michael@0 80 ON_LOAD,
michael@0 81 this.__loadListener ||
michael@0 82 (this.__loadListener = this._loadListener.bind(this))
michael@0 83 ,
michael@0 84 false
michael@0 85 );
michael@0 86 }
michael@0 87 else { // If window is loaded calling listener next turn of event loop.
michael@0 88 this._onLoad(window)
michael@0 89 }
michael@0 90 }
michael@0 91 else {
michael@0 92 this.__window = null;
michael@0 93 }
michael@0 94 }
michael@0 95 },
michael@0 96 __window: null,
michael@0 97 /**
michael@0 98 * Internal method used for listening 'load' event on the `_window`.
michael@0 99 * Method takes care of removing itself from 'load' event listeners once
michael@0 100 * event is being handled.
michael@0 101 */
michael@0 102 _loadListener: function _loadListener(event) {
michael@0 103 let window = this._window;
michael@0 104 if (!event.target || event.target.defaultView != window) return;
michael@0 105 window.removeEventListener(ON_LOAD, this.__loadListener, false);
michael@0 106 this._onLoad(window);
michael@0 107 },
michael@0 108 __loadListener: null,
michael@0 109 /**
michael@0 110 * Internal method used for listening 'unload' event on the `_window`.
michael@0 111 * Method takes care of removing itself from 'unload' event listeners once
michael@0 112 * event is being handled.
michael@0 113 */
michael@0 114 _unloadListener: function _unloadListener(event) {
michael@0 115 let window = this._window;
michael@0 116 if (!event.target
michael@0 117 || event.target.defaultView != window
michael@0 118 || STATE_LOADED != window.document.readyState
michael@0 119 ) return;
michael@0 120 window.removeEventListener(ON_UNLOAD, this.__unloadListener, false);
michael@0 121 this._onUnload(window);
michael@0 122 },
michael@0 123 __unloadListener: null
michael@0 124 });
michael@0 125 exports.WindowLoader = WindowLoader;
michael@0 126

mercurial