dom/browser-element/BrowserElementParent.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/dom/browser-element/BrowserElementParent.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,129 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     1.6 + * You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +
     1.8 +"use strict";
     1.9 +
    1.10 +const {utils: Cu, interfaces: Ci} = Components;
    1.11 +
    1.12 +Cu.import("resource://gre/modules/Services.jsm");
    1.13 +Cu.import("resource://gre/modules/XPCOMUtils.jsm");
    1.14 +
    1.15 +const NS_PREFBRANCH_PREFCHANGE_TOPIC_ID = "nsPref:changed";
    1.16 +const BROWSER_FRAMES_ENABLED_PREF = "dom.mozBrowserFramesEnabled";
    1.17 +
    1.18 +XPCOMUtils.defineLazyModuleGetter(this, "BrowserElementParentBuilder",
    1.19 +                                  "resource://gre/modules/BrowserElementParent.jsm",
    1.20 +                                  "BrowserElementParentBuilder");
    1.21 +
    1.22 +function debug(msg) {
    1.23 +  //dump("BrowserElementParent.js - " + msg + "\n");
    1.24 +}
    1.25 +
    1.26 +/**
    1.27 + * BrowserElementParent implements one half of <iframe mozbrowser>.  (The other
    1.28 + * half is, unsurprisingly, BrowserElementChild.)
    1.29 + *
    1.30 + * BrowserElementParentFactory detects when we create a windows or docshell
    1.31 + * contained inside a <iframe mozbrowser> and creates a BrowserElementParent
    1.32 + * object for that window.
    1.33 + *
    1.34 + * It creates a BrowserElementParent that injects script to listen for
    1.35 + * certain event.
    1.36 + */
    1.37 +
    1.38 +function BrowserElementParentFactory() {
    1.39 +  this._initialized = false;
    1.40 +}
    1.41 +
    1.42 +BrowserElementParentFactory.prototype = {
    1.43 +  classID: Components.ID("{ddeafdac-cb39-47c4-9cb8-c9027ee36d26}"),
    1.44 +  QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
    1.45 +                                         Ci.nsISupportsWeakReference]),
    1.46 +
    1.47 +  /**
    1.48 +   * Called on app startup, and also when the browser frames enabled pref is
    1.49 +   * changed.
    1.50 +   */
    1.51 +  _init: function() {
    1.52 +    if (this._initialized) {
    1.53 +      return;
    1.54 +    }
    1.55 +
    1.56 +    // If the pref is disabled, do nothing except wait for the pref to change.
    1.57 +    // (This is important for tests, if nothing else.)
    1.58 +    if (!this._browserFramesPrefEnabled()) {
    1.59 +      Services.prefs.addObserver(BROWSER_FRAMES_ENABLED_PREF, this, /* ownsWeak = */ true);
    1.60 +      return;
    1.61 +    }
    1.62 +
    1.63 +    debug("_init");
    1.64 +    this._initialized = true;
    1.65 +
    1.66 +    // Maps frame elements to BrowserElementParent objects.  We never look up
    1.67 +    // anything in this map; the purpose is to keep the BrowserElementParent
    1.68 +    // alive for as long as its frame element lives.
    1.69 +    this._bepMap = new WeakMap();
    1.70 +
    1.71 +    Services.obs.addObserver(this, 'remote-browser-pending', /* ownsWeak = */ true);
    1.72 +    Services.obs.addObserver(this, 'inprocess-browser-shown', /* ownsWeak = */ true);
    1.73 +  },
    1.74 +
    1.75 +  _browserFramesPrefEnabled: function() {
    1.76 +    try {
    1.77 +      return Services.prefs.getBoolPref(BROWSER_FRAMES_ENABLED_PREF);
    1.78 +    }
    1.79 +    catch(e) {
    1.80 +      return false;
    1.81 +    }
    1.82 +  },
    1.83 +
    1.84 +  _observeInProcessBrowserFrameShown: function(frameLoader) {
    1.85 +    // Ignore notifications that aren't from a BrowserOrApp
    1.86 +    if (!frameLoader.QueryInterface(Ci.nsIFrameLoader).ownerIsBrowserOrAppFrame) {
    1.87 +      return;
    1.88 +    }
    1.89 +    debug("In-process browser frame shown " + frameLoader);
    1.90 +    this._createBrowserElementParent(frameLoader,
    1.91 +                                     /* hasRemoteFrame = */ false,
    1.92 +                                     /* pending frame */ false);
    1.93 +  },
    1.94 +
    1.95 +  _observeRemoteBrowserFramePending: function(frameLoader) {
    1.96 +    // Ignore notifications that aren't from a BrowserOrApp
    1.97 +    if (!frameLoader.QueryInterface(Ci.nsIFrameLoader).ownerIsBrowserOrAppFrame) {
    1.98 +      return;
    1.99 +    }
   1.100 +    debug("Remote browser frame shown " + frameLoader);
   1.101 +    this._createBrowserElementParent(frameLoader,
   1.102 +                                     /* hasRemoteFrame = */ true,
   1.103 +                                     /* pending frame */ true);
   1.104 +  },
   1.105 +
   1.106 +  _createBrowserElementParent: function(frameLoader, hasRemoteFrame, isPendingFrame) {
   1.107 +    let frameElement = frameLoader.QueryInterface(Ci.nsIFrameLoader).ownerElement;
   1.108 +    this._bepMap.set(frameElement, BrowserElementParentBuilder.create(
   1.109 +      frameLoader, hasRemoteFrame, isPendingFrame));
   1.110 +  },
   1.111 +
   1.112 +  observe: function(subject, topic, data) {
   1.113 +    switch(topic) {
   1.114 +    case 'app-startup':
   1.115 +      this._init();
   1.116 +      break;
   1.117 +    case NS_PREFBRANCH_PREFCHANGE_TOPIC_ID:
   1.118 +      if (data == BROWSER_FRAMES_ENABLED_PREF) {
   1.119 +        this._init();
   1.120 +      }
   1.121 +      break;
   1.122 +    case 'remote-browser-pending':
   1.123 +      this._observeRemoteBrowserFramePending(subject);
   1.124 +      break;
   1.125 +    case 'inprocess-browser-shown':
   1.126 +      this._observeInProcessBrowserFrameShown(subject);
   1.127 +      break;
   1.128 +    }
   1.129 +  },
   1.130 +};
   1.131 +
   1.132 +this.NSGetFactory = XPCOMUtils.generateNSGetFactory([BrowserElementParentFactory]);

mercurial