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

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     4 'use strict';
     6 const { Cc, Ci, Cr } = require('chrome'),
     7       { Trait } = require('../deprecated/traits'),
     8       { List } = require('../deprecated/list'),
     9       { EventEmitter } = require('../deprecated/events'),
    10       { WindowTabs, WindowTabTracker } = require('./tabs-firefox'),
    11       { WindowDom } = require('./dom'),
    12       { WindowLoader } = require('./loader'),
    13       { isBrowser, getWindowDocShell, windows: windowIterator } = require('../window/utils'),
    14       { Options } = require('../tabs/common'),
    15       apiUtils = require('../deprecated/api-utils'),
    16       unload = require('../system/unload'),
    17       windowUtils = require('../deprecated/window-utils'),
    18       { WindowTrackerTrait } = windowUtils,
    19       { ns } = require('../core/namespace'),
    20       { observer: windowObserver } = require('./observer'),
    21       { getOwnerWindow } = require('../private-browsing/window/utils');
    22 const { windowNS } = require('../window/namespace');
    23 const { isPrivateBrowsingSupported } = require('../self');
    24 const { ignoreWindow } = require('sdk/private-browsing/utils');
    25 const { viewFor } = require('../view/core');
    27 /**
    28  * Window trait composes safe wrappers for browser window that are E10S
    29  * compatible.
    30  */
    31 const BrowserWindowTrait = Trait.compose(
    32   EventEmitter,
    33   WindowDom.resolve({ close: '_close' }),
    34   WindowTabs,
    35   WindowTabTracker,
    36   WindowLoader,
    37   /* WindowSidebars, */
    38   Trait.compose({
    39     _emit: Trait.required,
    40     _close: Trait.required,
    41     _load: Trait.required,
    42     /**
    43      * Constructor returns wrapper of the specified chrome window.
    44      * @param {nsIWindow} window
    45      */
    46     constructor: function BrowserWindow(options) {
    47       // Register this window ASAP, in order to avoid loop that would try
    48       // to create this window instance over and over (see bug 648244)
    49       windows.push(this);
    51       // make sure we don't have unhandled errors
    52       this.on('error', console.exception.bind(console));
    54       if ('onOpen' in options)
    55         this.on('open', options.onOpen);
    56       if ('onClose' in options)
    57         this.on('close', options.onClose);
    58       if ('onActivate' in options)
    59         this.on('activate', options.onActivate);
    60       if ('onDeactivate' in options)
    61         this.on('deactivate', options.onDeactivate);
    62       if ('window' in options)
    63         this._window = options.window;
    65       if ('tabs' in options) {
    66         this._tabOptions = Array.isArray(options.tabs) ?
    67                            options.tabs.map(Options) :
    68                            [ Options(options.tabs) ];
    69       }
    70       else if ('url' in options) {
    71         this._tabOptions = [ Options(options.url) ];
    72       }
    74       this._isPrivate = isPrivateBrowsingSupported && !!options.isPrivate;
    76       this._load();
    78       windowNS(this._public).window = this._window;
    79       getOwnerWindow.implement(this._public, getChromeWindow);
    80       viewFor.implement(this._public, getChromeWindow);
    82       return this;
    83     },
    84     destroy: function () this._onUnload(),
    85     _tabOptions: [],
    86     _onLoad: function() {
    87       try {
    88         this._initWindowTabTracker();
    89         this._loaded = true;
    90       }
    91       catch(e) {
    92         this._emit('error', e);
    93       }
    95       this._emitOnObject(browserWindows, 'open', this._public);
    96     },
    97     _onUnload: function() {
    98       if (!this._window)
    99         return;
   100       if (this._loaded)
   101         this._destroyWindowTabTracker();
   103       this._emitOnObject(browserWindows, 'close', this._public);
   104       this._window = null;
   105       windowNS(this._public).window = null;
   106       // Removing reference from the windows array.
   107       windows.splice(windows.indexOf(this), 1);
   108       this._removeAllListeners();
   109     },
   110     close: function close(callback) {
   111       // maybe we should deprecate this with message ?
   112       if (callback) this.on('close', callback);
   113       return this._close();
   114     }
   115   })
   116 );
   118 /**
   119  * Gets a `BrowserWindowTrait` for the given `chromeWindow` if previously
   120  * registered, `null` otherwise.
   121  */
   122 function getRegisteredWindow(chromeWindow) {
   123   for each (let window in windows) {
   124     if (chromeWindow === window._window)
   125       return window;
   126   }
   128   return null;
   129 }
   131 /**
   132  * Wrapper for `BrowserWindowTrait`. Creates new instance if wrapper for
   133  * window doesn't exists yet. If wrapper already exists then returns it
   134  * instead.
   135  * @params {Object} options
   136  *    Options that are passed to the the `BrowserWindowTrait`
   137  * @returns {BrowserWindow}
   138  * @see BrowserWindowTrait
   139  */
   140 function BrowserWindow(options) {
   141   let window = null;
   143   if ("window" in options)
   144     window = getRegisteredWindow(options.window);
   146   return (window || BrowserWindowTrait(options))._public;
   147 }
   148 // to have proper `instanceof` behavior will go away when #596248 is fixed.
   149 BrowserWindow.prototype = BrowserWindowTrait.prototype;
   150 exports.BrowserWindow = BrowserWindow;
   152 const windows = [];
   154 const browser = ns();
   156 function onWindowActivation (chromeWindow, event) {
   157   if (!isBrowser(chromeWindow)) return; // Ignore if it's not a browser window.
   159   let window = getRegisteredWindow(chromeWindow);
   161   if (window)
   162     window._emit(event.type, window._public);
   163   else
   164     window = BrowserWindowTrait({ window: chromeWindow });
   166   browser(browserWindows).internals._emit(event.type, window._public);
   167 }
   169 windowObserver.on("activate", onWindowActivation);
   170 windowObserver.on("deactivate", onWindowActivation);
   172 /**
   173  * `BrowserWindows` trait is composed out of `List` trait and it represents
   174  * "live" list of currently open browser windows. Instance mutates itself
   175  * whenever new browser window gets opened / closed.
   176  */
   177 // Very stupid to resolve all `toStrings` but this will be fixed by #596248
   178 const browserWindows = Trait.resolve({ toString: null }).compose(
   179   List.resolve({ constructor: '_initList' }),
   180   EventEmitter.resolve({ toString: null }),
   181   WindowTrackerTrait.resolve({ constructor: '_initTracker', toString: null }),
   182   Trait.compose({
   183     _emit: Trait.required,
   184     _add: Trait.required,
   185     _remove: Trait.required,
   187     // public API
   189     /**
   190      * Constructor creates instance of `Windows` that represents live list of open
   191      * windows.
   192      */
   193     constructor: function BrowserWindows() {
   194       browser(this._public).internals = this;
   196       this._trackedWindows = [];
   197       this._initList();
   198       this._initTracker();
   199       unload.ensure(this, "_destructor");
   200     },
   201     _destructor: function _destructor() {
   202       this._removeAllListeners('open');
   203       this._removeAllListeners('close');
   204       this._removeAllListeners('activate');
   205       this._removeAllListeners('deactivate');
   206       this._clear();
   208       delete browser(this._public).internals;
   209     },
   210     /**
   211      * This property represents currently active window.
   212      * Property is non-enumerable, in order to preserve array like enumeration.
   213      * @type {Window|null}
   214      */
   215     get activeWindow() {
   216       let window = windowUtils.activeBrowserWindow;
   217       // Bug 834961: ignore private windows when they are not supported
   218       if (ignoreWindow(window))
   219         window = windowIterator()[0];
   220       return window ? BrowserWindow({window: window}) : null;
   221     },
   222     open: function open(options) {
   223       if (typeof options === "string") {
   224         // `tabs` option is under review and may be removed.
   225         options = {
   226           tabs: [Options(options)],
   227           isPrivate: isPrivateBrowsingSupported && options.isPrivate
   228         };
   229       }
   230       return BrowserWindow(options);
   231     },
   233      /**
   234       * Internal listener which is called whenever new window gets open.
   235       * Creates wrapper and adds to this list.
   236       * @param {nsIWindow} chromeWindow
   237       */
   238     _onTrack: function _onTrack(chromeWindow) {
   239       if (!isBrowser(chromeWindow)) return;
   240       let window = BrowserWindow({ window: chromeWindow });
   241       this._add(window);
   242       this._emit('open', window);
   243     },
   245     /**
   246      * Internal listener which is called whenever window gets closed.
   247      * Cleans up references and removes wrapper from this list.
   248      * @param {nsIWindow} window
   249      */
   250     _onUntrack: function _onUntrack(chromeWindow) {
   251       if (!isBrowser(chromeWindow)) return;
   252       let window = BrowserWindow({ window: chromeWindow });
   253       this._remove(window);
   254       this._emit('close', window);
   256       // Bug 724404: do not leak this module and linked windows:
   257       // We have to do it on untrack and not only when `_onUnload` is called
   258       // when windows are closed, otherwise, we will leak on addon disabling.
   259       window.destroy();
   260     }
   261   }).resolve({ toString: null })
   262 )();
   264 function getChromeWindow(window) {
   265   return windowNS(window).window;
   266 }
   268 exports.browserWindows = browserWindows;

mercurial