Bug 1031609 - Docshell getter shim (r=mconley)
authorBill McCloskey <wmccloskey@mozilla.com>
Mon, 14 Jul 2014 22:10:07 -0700
changeset 214780 58de0be65bc24a9206d3faa9e53bedbe87b1a704
parent 214779 dc0eb1d286f084fbe68a88dfbf31049f5c2d4231
child 214781 82e387c007e395345f28868a949db4a00b824423
push id3857
push userraliiev@mozilla.com
push dateTue, 02 Sep 2014 16:39:23 +0000
treeherdermozilla-beta@5638b907b505 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmconley
bugs1031609
milestone33.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1031609 - Docshell getter shim (r=mconley)
toolkit/components/addoncompat/RemoteAddonsParent.jsm
toolkit/components/addoncompat/multiprocessShims.js
--- a/toolkit/components/addoncompat/RemoteAddonsParent.jsm
+++ b/toolkit/components/addoncompat/RemoteAddonsParent.jsm
@@ -514,16 +514,29 @@ ContentDocumentInterposition.methods.imp
       // popupmenu to content.
       Cu.reportError("Calling contentDocument.importNode on a XUL node is not allowed.");
       return node;
     }
 
     return target.importNode(node, deep);
   };
 
+// This interposition ensures that calling browser.docShell from an
+// add-on returns a CPOW around the dochell.
+let RemoteBrowserElementInterposition = new Interposition(EventTargetInterposition);
+
+RemoteBrowserElementInterposition.getters.docShell = function(addon, target) {
+  let remoteChromeGlobal = RemoteAddonsParent.browserToGlobal.get(target);
+  if (!remoteChromeGlobal) {
+    // We may not have any messages from this tab yet.
+    return null;
+  }
+  return remoteChromeGlobal.docShell;
+};
+
 let RemoteAddonsParent = {
   init: function() {
     let mm = Cc["@mozilla.org/globalmessagemanager;1"].getService(Ci.nsIMessageListenerManager);
     mm.addMessageListener("Addons:RegisterGlobal", this);
 
     this.globalToBrowser = new WeakMap();
     this.browserToGlobal = new WeakMap();
   },
@@ -547,16 +560,17 @@ let RemoteAddonsParent = {
 
     function register(tag, interp) {
       result[tag] = interp;
     }
 
     register("EventTarget", EventTargetInterposition);
     register("ContentDocShellTreeItem", ContentDocShellTreeItemInterposition);
     register("ContentDocument", ContentDocumentInterposition);
+    register("RemoteBrowserElement", RemoteBrowserElementInterposition);
 
     return result;
   },
 
   receiveMessage: function(msg) {
     switch (msg.name) {
     case "Addons:RegisterGlobal":
       this.browserToGlobal.set(msg.target, msg.objects.global);
--- a/toolkit/components/addoncompat/multiprocessShims.js
+++ b/toolkit/components/addoncompat/multiprocessShims.js
@@ -84,18 +84,19 @@ AddonInterpositionService.prototype = {
       if (target instanceof Ci.nsIDOMDocument) {
         return "ContentDocument";
       }
     }
 
     const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
     if ((target instanceof Ci.nsIDOMXULElement) &&
         target.localName == "browser" &&
-        target.namespaceURI == XUL_NS) {
-      return "BrowserElement";
+        target.namespaceURI == XUL_NS &&
+        target.getAttribute("remote") == "true") {
+      return "RemoteBrowserElement";
     }
 
     if (target instanceof Ci.nsIDOMEventTarget) {
       return "EventTarget";
     }
 
     return "generic";
   },