Wed, 31 Dec 2014 06:09:35 +0100
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 |