Merge the last PGO-green inbound changeset to m-c. FIREFOX_AURORA_17_BASE
authorRyan VanderMeulen <ryanvm@gmail.com>
Mon, 27 Aug 2012 15:01:44 -0400
changeset 103565 fd72dbbd692012224145be1bf13df1d7675fd277
parent 103543 257e181b2a96d2afbd1bfa82c7ee27333dd4d920 (current diff)
parent 103564 f400c8e5cea46069f4e68b2b801eb34ba810a250 (diff)
child 103566 690d31dc6d3284e7bb0051492eceeebffaae04d9
push id23359
push userryanvm@gmail.com
push dateMon, 27 Aug 2012 19:01:50 +0000
treeherdermozilla-central@fd72dbbd6920 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone17.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
Merge the last PGO-green inbound changeset to m-c.
browser/themes/gnomestripe/share-button-active.png
browser/themes/gnomestripe/share-button-shared.png
browser/themes/gnomestripe/share-button.png
browser/themes/pinstripe/share-button-active.png
browser/themes/pinstripe/share-button-shared.png
browser/themes/pinstripe/share-button.png
browser/themes/winstripe/share-button-active.png
browser/themes/winstripe/share-button-shared.png
browser/themes/winstripe/share-button.png
content/base/public/nsIFrameMessageManager.idl
js/src/jsreops.tbl
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -44,17 +44,17 @@ XPCOMUtils.defineLazyServiceGetter(Servi
 
 XPCOMUtils.defineLazyGetter(this, 'DebuggerServer', function() {
   Cu.import('resource://gre/modules/devtools/dbg-server.jsm');
   return DebuggerServer;
 });
 
 XPCOMUtils.defineLazyGetter(this, "ppmm", function() {
   return Cc["@mozilla.org/parentprocessmessagemanager;1"]
-         .getService(Ci.nsIFrameMessageManager);
+         .getService(Ci.nsIMessageListenerManager);
 });
 
 function getContentWindow() {
   return shell.contentBrowser.contentWindow;
 }
 
 var shell = {
 
--- a/b2g/components/ContentHandler.js
+++ b/b2g/components/ContentHandler.js
@@ -9,17 +9,18 @@ const Cr = Components.results;
 const Cu = Components.utils;
 
 const PDF_CONTENT_TYPE = "application/pdf";
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "cpmm", function() {
-  return Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci.nsIFrameMessageManager);
+  return Cc["@mozilla.org/childprocessmessagemanager;1"]
+           .getService(Ci.nsIMessageSender);
 });
 
 function log(aMsg) {
   let msg = "ContentHandler.js: " + (aMsg.join ? aMsg.join("") : aMsg);
   Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService)
                                      .logStringMessage(msg);
   dump(msg + "\n");
 }
--- a/b2g/components/MozKeyboard.js
+++ b/b2g/components/MozKeyboard.js
@@ -9,17 +9,17 @@ const Ci = Components.interfaces;
 const Cu = Components.utils;
 const kFormsFrameScript = "chrome://browser/content/forms.js";
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/ObjectWrapper.jsm");
 
 const messageManager = Cc["@mozilla.org/globalmessagemanager;1"]
-                         .getService(Ci.nsIChromeFrameMessageManager);
+                         .getService(Ci.nsIMessageBroadcaster);
 
 
 // -----------------------------------------------------------------------
 // MozKeyboard
 // -----------------------------------------------------------------------
 
 function MozKeyboard() { } 
 
@@ -65,29 +65,29 @@ MozKeyboard.prototype = {
   sendKey: function mozKeyboardSendKey(keyCode, charCode) {
     charCode = (charCode == undefined) ? keyCode : charCode;
     ["keydown", "keypress", "keyup"].forEach((function sendKey(type) {
       this._utils.sendKeyEvent(type, keyCode, charCode, null);
     }).bind(this));
   },
 
   setSelectedOption: function mozKeyboardSetSelectedOption(index) {
-    messageManager.sendAsyncMessage("Forms:Select:Choice", {
+    messageManager.broadcastAsyncMessage("Forms:Select:Choice", {
       "index": index
     });
   },
 
   setValue: function mozKeyboardSetValue(value) {
-    messageManager.sendAsyncMessage("Forms:Input:Value", {
+    messageManager.broadcastAsyncMessage("Forms:Input:Value", {
       "value": value
     });
   },
 
   setSelectedOptions: function mozKeyboardSetSelectedOptions(indexes) {
-    messageManager.sendAsyncMessage("Forms:Select:Choice", {
+    messageManager.broadcastAsyncMessage("Forms:Select:Choice", {
       "indexes": indexes || []
     });
   },
 
   set onfocuschange(val) {
     this._focusHandler = val;
   },
 
--- a/browser/base/content/browser-social.js
+++ b/browser/base/content/browser-social.js
@@ -288,16 +288,22 @@ let SocialFlyout = {
 
     sizeSocialPanelToContent(iframe);
     let anchor = document.getElementById("social-sidebar-browser");
     panel.openPopup(anchor, "start_before", 0, yOffset, false, false);
   }
 }
 
 let SocialShareButton = {
+  // promptImages and promptMessages being null means we are yet to get the
+  // message back from the provider with the images and icons (or that we got
+  // the response but determined it was invalid.)
+  promptImages: null,
+  promptMessages: null,
+
   // Called once, after window load, when the Social.provider object is initialized
   init: function SSB_init() {
     this.updateButtonHiddenState();
     this.updateProfileInfo();
   },
 
   updateProfileInfo: function SSB_updateProfileInfo() {
     let profileRow = document.getElementById("editSharePopupHeader");
@@ -306,33 +312,88 @@ let SocialShareButton = {
       profileRow.hidden = false;
       let portrait = document.getElementById("socialUserPortrait");
       portrait.setAttribute("src", profile.portrait || "chrome://browser/skin/social/social.png");
       let displayName = document.getElementById("socialUserDisplayName");
       displayName.setAttribute("label", profile.displayName);
     } else {
       profileRow.hidden = true;
     }
+    // XXX - this shouldn't be done as part of updateProfileInfo, but instead
+    // whenever we notice the provider has changed - but the concept of
+    // "provider changed" will only exist once bug 774520 lands. 
+    this.promptImages = null;
+    this.promptMessages = null;
+    // get the recommend-prompt info.
+    let port = Social.provider._getWorkerPort();
+    if (port) {
+      port.onmessage = function(evt) {
+        if (evt.data.topic == "social.user-recommend-prompt-response") {
+          port.close();
+          this.acceptRecommendInfo(evt.data.data);
+          this.updateButtonHiddenState();
+          this.updateShareState();
+        }
+      }.bind(this);
+      port.postMessage({topic: "social.user-recommend-prompt"});
+    }
+  },
+
+  acceptRecommendInfo: function SSB_acceptRecommendInfo(data) {
+    // Accept *and validate* the user-recommend-prompt-response message.
+    let promptImages = {};
+    let promptMessages = {};
+    function reportError(reason) {
+      Cu.reportError("Invalid recommend data from provider: " + reason + ": sharing is disabled for this provider");
+      return false;
+    }
+    if (!data ||
+        !data.images || typeof data.images != "object" ||
+        !data.messages || typeof data.messages != "object") {
+      return reportError("data is missing valid 'images' or 'messages' elements");
+    }
+    for (let sub of ["share", "unshare"]) {
+      let url = data.images[sub];
+      if (!url || typeof url != "string" || url.length == 0) {
+        return reportError('images["' + sub + '"] is missing or not a non-empty string');
+      }
+      // resolve potentially relative URLs then check the scheme is acceptable.
+      url = Services.io.newURI(Social.provider.origin, null, null).resolve(url);
+      let uri = Services.io.newURI(url, null, null);
+      if (!uri.schemeIs("http") && !uri.schemeIs("https") && !uri.schemeIs("data")) {
+        return reportError('images["' + sub + '"] does not have a valid scheme');
+      }
+      promptImages[sub] = url;
+    }
+    for (let sub of ["shareTooltip", "unshareTooltip", "sharedLabel", "unsharedLabel"]) {
+      if (typeof data.messages[sub] != "string" || data.messages[sub].length == 0) {
+        return reportError('messages["' + sub + '"] is not a valid string');
+      }
+      promptMessages[sub] = data.messages[sub];
+    }
+    this.promptImages = promptImages;
+    this.promptMessages = promptMessages;
+    return true;
   },
 
   get shareButton() {
     return document.getElementById("share-button");
   },
   get sharePopup() {
     return document.getElementById("editSharePopup");
   },
 
   dismissSharePopup: function SSB_dismissSharePopup() {
     this.sharePopup.hidePopup();
   },
 
   updateButtonHiddenState: function SSB_updateButtonHiddenState() {
     let shareButton = this.shareButton;
     if (shareButton)
-      shareButton.hidden = !Social.uiVisible;
+      shareButton.hidden = !Social.uiVisible || this.promptImages == null;
   },
 
   onClick: function SSB_onClick(aEvent) {
     if (aEvent.button != 0)
       return;
 
     // Don't bubble to the textbox, to avoid unwanted selection of the address.
     aEvent.stopPropagation();
@@ -365,33 +426,43 @@ let SocialShareButton = {
   },
 
   updateShareState: function SSB_updateShareState() {
     let currentPageShared = Social.isPageShared(gBrowser.currentURI);
 
     // Provide a11y-friendly notification of share.
     let status = document.getElementById("share-button-status");
     if (status) {
+      // XXX - this should also be capable of reflecting that the page was
+      // unshared (ie, it needs to manage three-states: (1) nothing done, (2)
+      // shared, (3) shared then unshared)
+      // Note that we *do* have an appropriate string from the provider for
+      // this (promptMessages['unsharedLabel'] but currently lack a way of
+      // tracking this state)
       let statusString = currentPageShared ?
-                           gNavigatorBundle.getString("social.pageShared.label") : "";
+                           this.promptMessages['sharedLabel'] : "";
       status.setAttribute("value", statusString);
     }
 
     // Update the share button, if present
     let shareButton = this.shareButton;
-    if (!shareButton)
+    if (!shareButton || shareButton.hidden)
       return;
 
+    let imageURL;
     if (currentPageShared) {
       shareButton.setAttribute("shared", "true");
-      shareButton.setAttribute("tooltiptext", gNavigatorBundle.getString("social.shareButton.sharedtooltip"));
+      shareButton.setAttribute("tooltiptext", this.promptMessages['unshareTooltip']);
+      imageURL = this.promptImages["unshare"]
     } else {
       shareButton.removeAttribute("shared");
-      shareButton.setAttribute("tooltiptext", gNavigatorBundle.getString("social.shareButton.tooltip"));
+      shareButton.setAttribute("tooltiptext", this.promptMessages['shareTooltip']);
+      imageURL = this.promptImages["share"]
     }
+    shareButton.style.backgroundImage = 'url("' + encodeURI(imageURL) + '")';
   }
 };
 
 var SocialToolbar = {
   // Called once, after window load, when the Social.provider object is initialized
   init: function SocialToolbar_init() {
     document.getElementById("social-provider-image").setAttribute("image", Social.provider.iconURL);
 
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -355,17 +355,17 @@ const gSessionHistoryObserver = {
       return;
 
     var backCommand = document.getElementById("Browser:Back");
     backCommand.setAttribute("disabled", "true");
     var fwdCommand = document.getElementById("Browser:Forward");
     fwdCommand.setAttribute("disabled", "true");
 
     // Hide session restore button on about:home
-    window.messageManager.sendAsyncMessage("Browser:HideSessionRestoreButton");
+    window.messageManager.broadcastAsyncMessage("Browser:HideSessionRestoreButton");
 
     if (gURLBar) {
       // Clear undo history of the URL bar
       gURLBar.editor.transactionManager.clear()
     }
   }
 };
 
--- a/browser/base/content/test/Makefile.in
+++ b/browser/base/content/test/Makefile.in
@@ -263,16 +263,17 @@ endif
                  browser_social_toolbar.js \
                  browser_social_shareButton.js \
                  browser_social_sidebar.js \
                  browser_social_flyout.js \
                  browser_social_mozSocial_API.js \
                  browser_social_isVisible.js \
                  browser_social_chatwindow.js \
                  social_panel.html \
+                 social_share_image.png \
                  social_sidebar.html \
                  social_chat.html \
                  social_flyout.html \
                  social_window.html \
                  social_worker.js \
                  $(NULL)
 
 ifneq (cocoa,$(MOZ_WIDGET_TOOLKIT))
--- a/browser/base/content/test/browser_social_shareButton.js
+++ b/browser/base/content/test/browser_social_shareButton.js
@@ -43,37 +43,48 @@ function testInitial(finishcb) {
   ok(Social.provider.port, "Social provider has a port to its FrameWorker");
 
   let {shareButton, sharePopup} = SocialShareButton;
   ok(shareButton, "share button exists");
   ok(sharePopup, "share popup exists");
 
   let okButton = document.getElementById("editSharePopupOkButton");
   let undoButton = document.getElementById("editSharePopupUndoButton");
+  let shareStatusLabel = document.getElementById("share-button-status");
 
   // ensure the worker initialization and handshakes are all done and we
-  // have a profile.
-  waitForCondition(function() Social.provider.profile, function() {
-    is(shareButton.hidden, false, "share button should be visible");
+  // have a profile and the worker has responsed to the recommend-prompt msg.
+  waitForCondition(function() Social.provider.profile && SocialShareButton.promptImages != null, function() {
+    is(shareButton.hasAttribute("shared"), false, "Share button should not have 'shared' attribute before share button is clicked");
     // check dom values
     let profile = Social.provider.profile;
     let portrait = document.getElementById("socialUserPortrait").getAttribute("src");
     is(profile.portrait, portrait, "portrait is set");
     let displayName = document.getElementById("socialUserDisplayName");
     is(displayName.label, profile.displayName, "display name is set");
     ok(!document.getElementById("editSharePopupHeader").hidden, "user profile is visible");
   
+    // Check the strings from our worker actually ended up on the button.
+    is(shareButton.getAttribute("tooltiptext"), "Share this page", "check tooltip text is correct");
+    is(shareStatusLabel.getAttribute("value"), "", "check status label text is blank");
+    // Check the relative URL was resolved correctly (note this image has offsets of zero...)
+    is(shareButton.style.backgroundImage, 'url("https://example.com/browser/browser/base/content/test/social_share_image.png")', "check image url is correct");
+
     // Test clicking the share button
     shareButton.addEventListener("click", function listener() {
       shareButton.removeEventListener("click", listener);
       is(shareButton.hasAttribute("shared"), true, "Share button should have 'shared' attribute after share button is clicked");
+      is(shareButton.getAttribute("tooltiptext"), "Unshare this page", "check tooltip text is correct");
+      is(shareStatusLabel.getAttribute("value"), "This page has been shared", "check status label text is correct");
+      // Check the URL and offsets were applied correctly
+      is(shareButton.style.backgroundImage, 'url("https://example.com/browser/browser/base/content/test/social_share_image.png")', "check image url is correct");
       executeSoon(testSecondClick.bind(window, testPopupOKButton));
     });
     EventUtils.synthesizeMouseAtCenter(shareButton, {});
-  }, "provider didn't provide a profile");
+  }, "provider didn't provide user-recommend-prompt response");
 }
 
 function testSecondClick(nextTest) {
   let {shareButton, sharePopup} = SocialShareButton;
   sharePopup.addEventListener("popupshown", function listener() {
     sharePopup.removeEventListener("popupshown", listener);
     ok(true, "popup was shown after second click");
     executeSoon(nextTest);
--- a/browser/base/content/test/head.js
+++ b/browser/base/content/test/head.js
@@ -129,16 +129,25 @@ function runSocialTestWithProvider(manif
     info("runSocialTestWithProvider: provider added");
     oldProvider = Social.provider;
     Social.provider = provider;
 
     // Now that we've set the UI's provider, enable the social functionality
     Services.prefs.setBoolPref("social.enabled", true);
 
     registerCleanupFunction(function () {
+      // if one test happens to fail, it is likely finishSocialTest will not
+      // be called, causing most future social tests to also fail as they
+      // attempt to add a provider which already exists - so work
+      // around that by also attempting to remove the test provider.
+      try {
+        SocialService.removeProvider(provider.origin, finish);
+      } catch (ex) {
+        ;
+      }
       Social.provider = oldProvider;
       Services.prefs.clearUserPref("social.enabled");
     });
 
     function finishSocialTest() {
       SocialService.removeProvider(provider.origin, finish);
     }
     callback(finishSocialTest);
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..fa1f8fb0e23b9689e51f667a5745898f929c0960
GIT binary patch
literal 934
zc$@*I16lluP)<h;3K|Lk000e1NJLTq001BW000mO0ssI2_+sh~00001b5ch_0Itp)
z=>Px#1ZP1_K>z@;j|==^1poj532;bRa{vGmbN~PnbOGLGA9w%&13O7XK~y+Tl~h?w
z6HyeMX{VqdxP&#JML>gzF^WngX*5D0u|Y_zMiP}w{Nn>rQGbz7P5f-4KNwn+O$AF>
zgVKtXvK0svEfujSv``QVEiLUV-kGsuAw}@@HhD91-#O>r^WH<~?G2J7H9f<d<x(^S
zLC^$25iY{@Soa9#T(SV!#&9@Y4ei=7lR026jnMF(LMVW<I4yTO@3fd(V9q6PO)zbp
zf7PN{b~tI8+Khm!V8A+XTU~4>%ov98nOhJH8ceDV?e4Hp5)gc%_{E?d0-#BRtRAg?
z*i-7p+yYcU5r3s@O5i1k=1!fqe<WgWxCj%vTyBb5R{`G{r`J)YE_?a)1r~&%6zX+)
zuO{bjQNf~prKa)ygn2qVEHouaJo&@IIp(jO?|V_}twFmU(7^}qs`rvuhM&Mu6y4N=
zZ&Nc>s*Z(4dvK5_OLD4PKMLBp0c*InFr8st)ta@owK*XwL`W7rL58Q|C<5?-2w=gd
z{t;DsmuJl*6rj0T68(sAb=AdM$cC@!OYWryP4}e=>9}pY;qu$un7rKRJk^y({3I?w
z1j>E|*T8kV$i3!y)1ua~dV%S}`Sj%#r*Xo}%jZ2X+Kh#Dg`@KZPALSQhC^_wD|#y`
zdKEr=-!`4K{ZiC5PfpEnaFWx<VxuD3H9CKEj-ca9hg>aB+>@BOKQlWayK11y-xy_&
zver<Gi7>tb6vTcuO%55xcLWE8hU^4$hQ~}d^K&swIAgU9jv9Yj=6HyEh1Yp+0RoO|
z$?KBT_|$?k1@K;}Q#Kiz9F&73$hN{Z3}sFO^FMOvAOwd3e6zL%pp1`=YVGVkm!2v~
zJN`kZ_osm_(~K}$go=vJ78N%XGkb<Y`o8y7;+12TvGR}Q{4Qb=H=IvsSJS&LX@=x^
zjS4==q#1{k#8cB&jZS|<Cgp4AOUZeb1M?6hM1D;kxhs-!g8hMxz*j|d<UVm+tbN4+
z+)3hiK!>~oaWQ}n6W&;Mu>c;!1Yw95DZN<AptFN}|3`Pg3v$il(e@2Jd8$}uY5sAE
zk~FC?YU=g%aF2o|zU|EHLv93U5yuP%%`$5{nv%Ssf&csX8$88<_@TT+ApigX07*qo
IM6N<$f?A)aGynhq
--- a/browser/base/content/test/social_worker.js
+++ b/browser/base/content/test/social_worker.js
@@ -86,11 +86,30 @@ onconnect = function(e) {
         port.postMessage({topic: "social.ambient-notification", data: icon});
         break;
       case "test-isVisible":
         sidebarPort.postMessage({topic: "test-isVisible"});
         break;
       case "test-isVisible-response":
         testPort.postMessage({topic: "got-isVisible-response", result: event.data.result});
         break;
+      case "social.user-recommend-prompt":
+        port.postMessage({
+          topic: "social.user-recommend-prompt-response",
+          data: {
+            images: {
+              // this one is relative to test we handle relative ones.
+              share: "browser/browser/base/content/test/social_share_image.png",
+              // absolute to check we handle them too.
+              unshare: "https://example.com/browser/browser/base/content/test/social_share_image.png"
+            },
+            messages: {
+              shareTooltip: "Share this page",
+              unshareTooltip: "Unshare this page",
+              sharedLabel: "This page has been shared",
+              unsharedLabel: "This page is no longer shared",
+            }
+          }
+        });
+        break;
     }
   }
 }
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -367,20 +367,16 @@ webapps.uninstall.label = Uninstall App
 # brandFullName, and %2$S by the value of the toolkit.telemetry.server_owner preference.
 telemetryOptOutPrompt = %1$S sends information about performance, hardware, usage and customizations back to %2$S to help improve %3$S.
 
 # LOCALIZATION NOTE (fullscreen.entered): displayed when we enter HTML5 fullscreen mode, %S is the domain name of the focused website (e.g. mozilla.com).
 fullscreen.entered=%S is now fullscreen.
 # LOCALIZATION NOTE (fullscreen.rememberDecision): displayed when we enter HTML5 fullscreen mode, %S is the domain name of the focused website (e.g. mozilla.com).
 fullscreen.rememberDecision=Remember decision for %S
 
-social.shareButton.tooltip=Share this
-social.shareButton.sharedtooltip=You shared this
-social.pageShared.label=Page shared
-
 # LOCALIZATION NOTE (social.toggle.label): %1$S is the name of the social provider, %2$S is brandShortName (e.g. Firefox)
 social.toggle.label=%1$S for %2$S
 social.toggle.accesskey=f
 
 # LOCALIZATION NOTE (social.activated.description): %1$S is the name of the social provider, %2$S is brandShortName (e.g. Firefox)
 social.activated.description=You've turned on %1$S for %2$S.
 
 # LOCALIZATION NOTE (social.error.message): %1$S is brandShortName (e.g. Firefox), %2$S is the name of the social provider
--- a/browser/themes/gnomestripe/browser.css
+++ b/browser/themes/gnomestripe/browser.css
@@ -1368,25 +1368,18 @@ richlistitem[type~="action"][actiontype=
 /* Popup blocker button */
 #page-report-button {
   list-style-image: url("chrome://browser/skin/Info.png");
 }
 
 /* social recommending panel */
 
 #share-button {
-  list-style-image: url(chrome://browser/skin/share-button.png);
-}
-
-#share-button:not([shared]):not([disabled]):hover {
-  list-style-image: url(chrome://browser/skin/share-button-active.png);
-}
-
-#share-button[shared] {
-  list-style-image: url(chrome://browser/skin/share-button-shared.png);
+  width: 16px;
+  height: 16px;
 }
 
 #socialUserPortrait {
   width: 48px;
   height: 48px;
 }
 
 #socialUserDisplayName,
--- a/browser/themes/gnomestripe/jar.mn
+++ b/browser/themes/gnomestripe/jar.mn
@@ -34,19 +34,16 @@ browser.jar:
   skin/classic/browser/pageInfo.png
   skin/classic/browser/page-livemarks.png
   skin/classic/browser/Privacy-16.png
   skin/classic/browser/Privacy-48.png
   skin/classic/browser/searchbar.css                  (searchbar.css)
   skin/classic/browser/Secure.png
   skin/classic/browser/Security-broken.png
   skin/classic/browser/setDesktopBackground.css
-  skin/classic/browser/share-button.png
-  skin/classic/browser/share-button-active.png
-  skin/classic/browser/share-button-shared.png
   skin/classic/browser/Toolbar.png
   skin/classic/browser/Toolbar-small.png
   skin/classic/browser/urlbar-arrow.png
   skin/classic/browser/downloads/buttons.png          (downloads/buttons.png)
   skin/classic/browser/downloads/download-glow.png    (downloads/download-glow.png)
   skin/classic/browser/downloads/download-notification.png (downloads/download-notification.png)
   skin/classic/browser/downloads/downloads.css        (downloads/downloads.css)
   skin/classic/browser/feeds/feedIcon.png             (feeds/feedIcon.png)
deleted file mode 100644
index a87501e89b3112b507b9385d43d021e7700fb150..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index cb8a11e81d899117cc02c924525c99182b7b8166..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 86bd5ec70add448cfa5647e9448d9bb2ea5349a9..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
--- a/browser/themes/pinstripe/browser.css
+++ b/browser/themes/pinstripe/browser.css
@@ -1240,25 +1240,18 @@ window[tabsontop="false"] richlistitem[t
 #page-report-button:hover:active,
 #page-report-button[open="true"] {
   -moz-image-region: rect(0, 32px, 16px, 16px);
 }
 
 /* social recommending panel */
 
 #share-button {
-  list-style-image: url(chrome://browser/skin/share-button.png);
-}
-
-#share-button:not([shared]):not([disabled]):hover {
-  list-style-image: url(chrome://browser/skin/share-button-active.png);
-}
-
-#share-button[shared] {
-  list-style-image: url(chrome://browser/skin/share-button-shared.png);
+  width: 16px;
+  height: 16px;
 }
 
 #socialUserPortrait {
   width: 48px;
   height: 48px;
 }
 
 #socialUserDisplayName,
--- a/browser/themes/pinstripe/jar.mn
+++ b/browser/themes/pinstripe/jar.mn
@@ -59,19 +59,16 @@ browser.jar:
   skin/classic/browser/feeds/videoFeedIcon.png              (feeds/feedIcon.png)
   skin/classic/browser/feeds/videoFeedIcon16.png            (feeds/feedIcon16.png)
   skin/classic/browser/feeds/audioFeedIcon.png              (feeds/feedIcon.png)
   skin/classic/browser/feeds/audioFeedIcon16.png            (feeds/feedIcon16.png)
   skin/classic/browser/newtab/newTab.css                    (newtab/newTab.css)
   skin/classic/browser/newtab/controls.png                  (newtab/controls.png)
   skin/classic/browser/newtab/noise.png                     (newtab/noise.png)
   skin/classic/browser/setDesktopBackground.css
-  skin/classic/browser/share-button.png
-  skin/classic/browser/share-button-active.png
-  skin/classic/browser/share-button-shared.png
   skin/classic/browser/monitor.png
   skin/classic/browser/monitor_16-10.png
   skin/classic/browser/places/allBookmarks.png              (places/allBookmarks.png)
 * skin/classic/browser/places/places.css                    (places/places.css)
 * skin/classic/browser/places/organizer.css                 (places/organizer.css)
   skin/classic/browser/places/query.png                     (places/query.png)
   skin/classic/browser/places/bookmarksMenu.png             (places/bookmarksMenu.png)
   skin/classic/browser/places/bookmarksToolbar.png          (places/bookmarksToolbar.png)
deleted file mode 100644
index a87501e89b3112b507b9385d43d021e7700fb150..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index cb8a11e81d899117cc02c924525c99182b7b8166..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 86bd5ec70add448cfa5647e9448d9bb2ea5349a9..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
--- a/browser/themes/winstripe/browser.css
+++ b/browser/themes/winstripe/browser.css
@@ -1631,25 +1631,18 @@ richlistitem[type~="action"][actiontype=
 #page-report-button:hover:active,
 #page-report-button[open="true"] {
   -moz-image-region: rect(0, 48px, 16px, 32px);
 }
 
 /* social recommending panel */
 
 #share-button {
-  list-style-image: url(chrome://browser/skin/share-button.png);
-}
-
-#share-button:not([shared]):not([disabled]):hover {
-  list-style-image: url(chrome://browser/skin/share-button-active.png);
-}
-
-#share-button[shared] {
-  list-style-image: url(chrome://browser/skin/share-button-shared.png);
+  width: 16px;
+  height: 16px;
 }
 
 #socialUserPortrait {
   width: 48px;
   height: 48px;
 }
 
 #socialUserDisplayName,
--- a/browser/themes/winstripe/jar.mn
+++ b/browser/themes/winstripe/jar.mn
@@ -45,19 +45,16 @@ browser.jar:
         skin/classic/browser/Secure24.png                            (Secure24.png)
         skin/classic/browser/Toolbar.png                             (Toolbar.png)
         skin/classic/browser/Toolbar-inverted.png
         skin/classic/browser/toolbarbutton-dropdown-arrow.png
         skin/classic/browser/toolbarbutton-dropdown-arrow-inverted.png
         skin/classic/browser/searchbar.css                           (searchbar.css)
         skin/classic/browser/searchbar-dropdown-arrow.png
         skin/classic/browser/setDesktopBackground.css
-        skin/classic/browser/share-button.png
-        skin/classic/browser/share-button-active.png
-        skin/classic/browser/share-button-shared.png
         skin/classic/browser/menu-back.png                           (menu-back.png)
         skin/classic/browser/menu-forward.png                        (menu-forward.png)
         skin/classic/browser/monitor.png
         skin/classic/browser/monitor_16-10.png
         skin/classic/browser/urlbar-arrow.png
         skin/classic/browser/urlbar-popup-blocked.png
         skin/classic/browser/urlbar-history-dropmarker.png
         skin/classic/browser/downloads/buttons.png                   (downloads/buttons.png)
@@ -249,19 +246,16 @@ browser.jar:
         skin/classic/aero/browser/Secure24.png                       (Secure24-aero.png)
         skin/classic/aero/browser/Toolbar.png
         skin/classic/aero/browser/Toolbar-inverted.png
         skin/classic/aero/browser/toolbarbutton-dropdown-arrow.png
         skin/classic/aero/browser/toolbarbutton-dropdown-arrow-inverted.png
         skin/classic/aero/browser/searchbar.css                      (searchbar.css)
         skin/classic/aero/browser/searchbar-dropdown-arrow.png       (searchbar-dropdown-arrow-aero.png)
         skin/classic/aero/browser/setDesktopBackground.css
-        skin/classic/aero/browser/share-button.png
-        skin/classic/aero/browser/share-button-active.png
-        skin/classic/aero/browser/share-button-shared.png
         skin/classic/aero/browser/menu-back.png                      (menu-back-aero.png)
         skin/classic/aero/browser/menu-forward.png                   (menu-forward-aero.png)
         skin/classic/aero/browser/monitor.png
         skin/classic/aero/browser/monitor_16-10.png
         skin/classic/aero/browser/urlbar-arrow.png
         skin/classic/aero/browser/urlbar-popup-blocked.png
         skin/classic/aero/browser/urlbar-history-dropmarker.png
         skin/classic/aero/browser/downloads/buttons.png              (downloads/buttons-aero.png)
deleted file mode 100644
index a87501e89b3112b507b9385d43d021e7700fb150..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index cb8a11e81d899117cc02c924525c99182b7b8166..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 86bd5ec70add448cfa5647e9448d9bb2ea5349a9..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
--- a/build/unix/build-clang/build-clang.py
+++ b/build/unix/build-clang/build-clang.py
@@ -65,32 +65,33 @@ llvm_source_dir = source_dir + "/llvm"
 clang_source_dir = source_dir + "/clang"
 compiler_rt_source_dir = source_dir + "/compiler-rt"
 
 def build_one_stage(env, stage_dir, is_stage_one):
     def f():
         build_one_stage_aux(stage_dir, is_stage_one)
     with_env(env, f)
 
+isDarwin = platform.system() == "Darwin"
+
 def build_one_stage_aux(stage_dir, is_stage_one):
     os.mkdir(stage_dir)
 
     build_dir = stage_dir + "/build"
     inst_dir = stage_dir + "/clang"
 
     configure_opts = ["--enable-optimized",
                       "--disable-assertions",
                       "--prefix=%s" % inst_dir,
                       "--with-gcc-toolchain=/tools/gcc-4.5-0moz3"]
-    if is_stage_one:
+    if is_stage_one and not isDarwin:
         configure_opts.append("--with-optimize-option=-O0")
 
     build_package(llvm_source_dir, build_dir, configure_opts)
 
-isDarwin = platform.system() == "Darwin"
 if isDarwin:
     os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.7'
 
 if not os.path.exists(source_dir):
     os.makedirs(source_dir)
     svn_co("http://llvm.org/svn/llvm-project/llvm/trunk",
            llvm_source_dir, llvm_revision)
     svn_co("http://llvm.org/svn/llvm-project/cfe/trunk",
--- a/content/base/public/Makefile.in
+++ b/content/base/public/Makefile.in
@@ -76,15 +76,15 @@ XPIDLSRCS	= \
 		nsISelectionPrivate.idl  \
 		nsIScriptLoaderObserver.idl  \
 		nsIDroppedLinkHandler.idl \
 		nsIImageLoadingContent.idl \
 		nsIObjectLoadingContent.idl \
 		nsIFrameLoader.idl \
 		nsIXMLHttpRequest.idl \
 		nsIContentSecurityPolicy.idl \
-		nsIFrameMessageManager.idl \
+		nsIMessageManager.idl \
 		nsIWebSocket.idl \
 		nsIEventSource.idl \
 		$(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
--- a/content/base/public/nsIFrameLoader.idl
+++ b/content/base/public/nsIFrameLoader.idl
@@ -3,17 +3,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
 interface nsIDocShell;
 interface nsIURI;
 interface nsIFrame;
-interface nsIChromeFrameMessageManager;
+interface nsIMessageSender;
 interface nsIVariant;
 interface nsIDOMElement;
 
 typedef unsigned long long nsContentViewId;
 
 /**
  * These interfaces do *not* scroll or scale the content document;
  * instead they set a "goal" scroll/scale wrt the current content
@@ -103,17 +103,17 @@ interface nsIContentViewManager : nsISup
                          [retval, array, size_is(aLength)] out nsIContentView aResult);
 
   /**
    * The root content view.
    */
   readonly attribute nsIContentView rootContentView;
 };
 
-[scriptable, uuid(fc338eea-47dc-475e-add7-a3933fcfa07c)]
+[scriptable, uuid(f234c232-bb17-4450-b324-bf1ef5ccfd34)]
 interface nsIFrameLoader : nsISupports
 {
   /**
    * Get the docshell from the frame loader.
    */
   readonly attribute nsIDocShell docShell;
 
   /**
@@ -172,17 +172,17 @@ interface nsIFrameLoader : nsISupports
                                   [optional] in boolean aIgnoreRootScrollFrame);
 
   /**
    * Activate event forwarding from client (remote frame) to parent.
    */
   void activateFrameEvent(in AString aType, in boolean capture);
 
   // Note, when frameloaders are swapped, also messageManagers are swapped.
-  readonly attribute nsIChromeFrameMessageManager messageManager;
+  readonly attribute nsIMessageSender messageManager;
 
   /**
    * @see nsIDOMWindowUtils sendKeyEvent.
    */
   void sendCrossProcessKeyEvent(in AString aType,
                                 in long aKeyCode,
                                 in long aCharCode,
                                 in long aModifiers,
rename from content/base/public/nsIFrameMessageManager.idl
rename to content/base/public/nsIMessageManager.idl
--- a/content/base/public/nsIFrameMessageManager.idl
+++ b/content/base/public/nsIMessageManager.idl
@@ -4,64 +4,282 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
 interface nsIDOMWindow;
 interface nsIDocShell;
 interface nsIContent;
 
-[scriptable, function, uuid(938fcb95-3d63-46be-aa72-94d08fd3b418)]
-interface nsIFrameMessageListener : nsISupports
+/**
+ * Message managers provide a way for chrome-privileged JS code to
+ * communicate with each other, even across process boundaries.
+ *
+ * Message managers are separated into "parent side" and "child side".
+ * These don't always correspond to process boundaries, but can.  For
+ * each child-side message manager, there is always exactly one
+ * corresponding parent-side message manager that it sends messages
+ * to.  However, for each parent-side message manager, there may be
+ * either one or many child-side managers it can message.
+ *
+ * Message managers that always have exactly one "other side" are of
+ * type nsIMessageSender.  Parent-side message managers that have many
+ * "other sides" are of type nsIMessageBroadcaster.
+ *
+ * Child-side message managers can send synchronous messages to their
+ * parent side, but not the other way around.
+ *
+ * There are two realms of message manager hierarchies.  One realm
+ * approximately corresponds to DOM elements, the other corresponds to
+ * process boundaries.
+ *
+ * Message managers corresponding to DOM elements
+ * ==============================================
+ *
+ * In this realm of message managers, there are
+ *  - "frame message managers" which correspond to frame elements
+ *  - "window message managers" which correspond to top-level chrome
+ *    windows
+ *  - the "global message manager", on the parent side.  See below.
+ *
+ * The DOM-realm message managers can communicate in the ways shown by
+ * the following diagram.  The parent side and child side can
+ * correspond to process boundaries, but don't always.
+ *
+ *  Parent side                         Child side
+ * -------------                       ------------
+ *  global MMg
+ *   |
+ *   +-->window MMw1
+ *   |    |
+ *   |    +-->frame MMp1_1<------------>frame MMc1_1
+ *   |    |
+ *   |    +-->frame MMp1_2<------------>frame MMc1_2
+ *   |    ...
+ *   |
+ *   +-->window MMw2
+ *   ...
+ *
+ * For example: a message sent from MMc1_1, from the child side, is
+ * sent only to MMp1_1 on the parent side.  However, note that all
+ * message managers in the hierarchy above MMp1_1, in this diagram
+ * MMw1 and MMg, will also notify their message listeners when the
+ * message arrives.
+
+ * For example: a message broadcast through the global MMg on the
+ * parent side would be broadcast to MMw1, which would transitively
+ * broadcast it to MMp1_1, MM1p_2".  The message would next be
+ * broadcast to MMw2, and so on down the hierarchy.
+ *
+ *   ***** PERFORMANCE AND SECURITY WARNING *****
+ * Messages broadcast through the global MM and window MMs can result
+ * in messages being dispatched across many OS processes, and to many
+ * processes with different permissions.  Great care should be taken
+ * when broadcasting.
+ *
+ * Interfaces
+ * ----------
+ *
+ * The global MMg and window MMw's are message broadcasters implementing
+ * nsIMessageBroadcaster while the frame MMp's are simple message senders
+ * (nsIMessageSender). Their counterparts in the content processes are
+ * message senders implementing nsIContentFrameMessageManager.
+ *
+ *                    nsIMessageListenerManager
+ *                  /                           \
+ * nsIMessageSender                               nsIMessageBroadcaster
+ *       |
+ * nsISyncMessageSender (content process/in-process only)
+ *       |
+ * nsIContentFrameMessageManager (content process/in-process only)
+ *       |
+ * nsIInProcessContentFrameMessageManager (in-process only)
+ *
+ *
+ * Message managers in the chrome process can also be QI'ed to nsIFrameScriptLoader.
+ *
+ *
+ * Message managers corresponding to process boundaries
+ * ====================================================
+ *
+ * The second realm of message managers is the "process message
+ * managers".  With one exception, these always correspond to process
+ * boundaries.  The picture looks like
+ *
+ *  Parent process                      Child processes
+ * ----------------                    -----------------
+ *  global PPMM
+ *   |
+ *   +<----> child PPMM
+ *   |
+ *   +-->parent PMM1<------------------>child process CMM1
+ *   |
+ *   +-->parent PMM2<------------------>child process PMM2
+ *   ...
+ *
+ * For example: the parent-process PMM1 sends messages directly to
+ * only the child-process CMM1.
+ *
+ * For example: CMM1 sends messages directly to PMM1.  The global PPMM
+ * will also notify their message listeners when the message arrives.
+ *
+ * For example: messages sent through the global PPMM will be
+ * dispatched to the listeners of the same-process, "child PPMM".
+ * They will also be broadcast to PPM1, PPM2, etc.
+ *
+ *   ***** PERFORMANCE AND SECURITY WARNING *****
+ * Messages broadcast through the global PPMM can result in messages
+ * being dispatched across many OS processes, and to many processes
+ * with different permissions.  Great care should be taken when
+ * broadcasting.
+ *
+ * Requests sent to parent-process message listeners should usually
+ * have replies scoped to the requesting CPMM.  The following pattern
+ * is common
+ *
+ *  const ParentProcessListener = {
+ *    receiveMessage: function(aMessage) {
+ *      let childMM = aMessage.target.QueryInterface(Ci.nsIMessageSender);
+ *      switch (aMessage.name) {
+ *      case "Foo:Request":
+ *        // service request
+ *        childMM.sendAsyncMessage("Foo:Response", { data });
+ *      }
+ *    }
+ *  };
+ */
+
+[scriptable, function, uuid(2b44eb57-a9c6-4773-9a1e-fe0818739a4c)]
+interface nsIMessageListener : nsISupports
 {
   /**
    * This is for JS only.
    * receiveMessage is called with one parameter, which has the following
    * properties:
    *   {
    *     target:  %the target of the message. Either an element owning
    *               the message manager, or message manager itself if no
    *               element owns it%
    *     name:    %message name%,
    *     sync:    %true or false%.
-   *     json:    %structured clone of the sent message data%,
+   *     data:    %structured clone of the sent message data%,
    *     json:    %same as .data, deprecated%,
    *     objects: %array of handles or null, always null if sync is false%
    *   }
    * @note objects property isn't implemented yet.
    *
-   * if the message is synchronous, possible return value is sent back
-   * as JSON (will be changed to use structured clones).
+   * Each listener is invoked with its own copy of the message
+   * parameter.
    *
    * When the listener is called, 'this' value is the target of the message.
+   *
+   * If the message is synchronous, the possible return value is
+   * returned as JSON (will be changed to use structured clones).
+   * When there are multiple listeners to sync messages, each
+   * listener's return value is sent back as an array.  |undefined|
+   * return values show up as undefined values in the array.
    */
   void receiveMessage();
 };
 
-[scriptable, builtinclass, uuid(9be42627-a5db-456f-8de2-9097da45a8c3)]
-interface nsIFrameMessageManager : nsISupports
+[scriptable, builtinclass, uuid(9c37a142-3de3-4902-a1a4-133f37d5980a)]
+interface nsIMessageListenerManager : nsISupports
 {
-  void addMessageListener(in AString aMessage, in nsIFrameMessageListener aListener);
-  void removeMessageListener(in AString aMessage, in nsIFrameMessageListener aListener);
-  [implicit_jscontext,optional_argc]
-  void sendAsyncMessage([optional] in AString messageName, [optional] in jsval obj);
+  /**
+   * Register |listener| to receive |messageName|.  All listener
+   * callbacks for a particular message are invoked when that message
+   * is received.
+   *
+   * The message manager holds a strong ref to |listener|.
+   *
+   * If the same listener registers twice for the same message, the
+   * second registration is ignored.
+   */
+  void addMessageListener(in AString messageName,
+                          in nsIMessageListener listener);
+
+  /**
+   * No longer invoke |listener| when |messageName| is received, after
+   * the first time removeMessageListener() is called.
+   */
+  void removeMessageListener(in AString messageName,
+                             in nsIMessageListener listener);
+
   [notxpcom] boolean markForCC();
 };
 
-[scriptable, builtinclass, uuid(28a36ac7-2868-4fa0-ae24-be957d7dce10)]
-interface nsISyncMessageSender : nsIFrameMessageManager
+/**
+ * Message "senders" have a single "other side" to which messages are
+ * sent.  For example, a child-process message manager will send
+ * messages that are only delivered to its one parent-process message
+ * manager.
+ */
+[scriptable, builtinclass, uuid(7f23767d-0f39-40c1-a22d-d3ab8a481f9d)]
+interface nsIMessageSender : nsIMessageListenerManager
+{
+  /**
+   * Send |messageName| and |obj| to the "other side" of this message
+   * manager.  This invokes listeners who registered for
+   * |messageName|.
+   *
+   * See nsIMessageListener::receiveMessage() for the format of the
+   * data delivered to listeners.
+   */
+  [implicit_jscontext, optional_argc]
+  void sendAsyncMessage([optional] in AString messageName,
+                        [optional] in jsval obj);
+};
+
+/**
+ * Message "broadcasters" don't have a single "other side" that they
+ * send messages to, but rather a set of subordinate message managers.
+ * For example, broadcasting a message through a window message
+ * manager will broadcast the message to all frame message managers
+ * within its window.
+ */
+[scriptable, builtinclass, uuid(d36346b9-5d3b-497d-9c28-ffbc3e4f6d0d)]
+interface nsIMessageBroadcaster : nsIMessageListenerManager
 {
   /**
-   * Returns an array of JSON objects.
+   * Like |sendAsyncMessage()|, but also broadcasts this message to
+   * all "child" message managers of this message manager.  See long
+   * comment above for details.
+   *
+   * WARNING: broadcasting messages can be very expensive and leak
+   * sensitive data.  Use with extreme caution.
    */
-  [implicit_jscontext,optional_argc]
-  jsval sendSyncMessage([optional] in AString messageName, [optional] in jsval obj);
+  [implicit_jscontext, optional_argc]
+  void broadcastAsyncMessage([optional] in AString messageName,
+                             [optional] in jsval obj);
+
+  /**
+   * Number of subordinate message managers.
+   */
+  readonly attribute unsigned long childCount;
+
+  /**
+   * Return a single subordinate message manager.
+   */
+  nsIMessageListenerManager getChildAt(in unsigned long aIndex);
 };
 
-[scriptable, builtinclass, uuid(a83f4393-e3cf-44da-8867-1f9174c2c595)]
+[scriptable, builtinclass, uuid(83be5862-2996-4685-ae7d-ae25bd795d50)]
+interface nsISyncMessageSender : nsIMessageSender
+{
+  /**
+   * Like |sendAsyncMessage()|, except blocks the sender until all
+   * listeners of the message have been invoked.  Returns an array
+   * containing return values from each listener invoked.
+   */
+  [implicit_jscontext, optional_argc]
+  jsval sendSyncMessage([optional] in AString messageName,
+                        [optional] in jsval obj);
+};
+
+[scriptable, builtinclass, uuid(894ff2d4-39a3-4df8-9d76-8ee329975488)]
 interface nsIContentFrameMessageManager : nsISyncMessageSender
 {
   /**
    * The current top level window in the frame or null.
    */
   readonly attribute nsIDOMWindow content;
 
   /**
@@ -82,39 +300,31 @@ interface nsIContentFrameMessageManager 
 
    /**
     * Ascii base64 data to binary data and vice versa
     */
    DOMString atob(in DOMString aAsciiString);
    DOMString btoa(in DOMString aBase64Data);
 };
 
-[uuid(f0936c56-e92c-4927-a85b-e289c3d4a01c)]
+[uuid(a2325927-9c0c-437d-9215-749c79235031)]
 interface nsIInProcessContentFrameMessageManager : nsIContentFrameMessageManager
 {
   [notxpcom] nsIContent getOwnerContent();
 };
 
-[scriptable, builtinclass, uuid(09f79e8c-101b-432b-a494-02f9b5e111c0)]
-interface nsITreeItemFrameMessageManager : nsIFrameMessageManager
-{
-  readonly attribute unsigned long childCount;
-  nsITreeItemFrameMessageManager getChildAt(in unsigned long aIndex);
-};
-
-[scriptable, builtinclass, uuid(a51597f0-d669-4260-83e6-1d426a8ac802)]
-interface nsIChromeFrameMessageManager : nsITreeItemFrameMessageManager
+[scriptable, builtinclass, uuid(a54acd34-4141-46f5-b71b-e2ca32879b08)]
+interface nsIFrameScriptLoader : nsISupports
 {
   /**
    * Load a script in the (remote) frame. aURL must be the absolute URL.
    * data: URLs are also supported. For example data:,dump("foo\n");
    * If aAllowDelayedLoad is true, script will be loaded when the
    * remote frame becomes available. Otherwise the script will be loaded
    * only if the frame is already available.
    */
   void loadFrameScript(in AString aURL, in boolean aAllowDelayedLoad);
 
   /**
    * Removes aURL from the list of scripts which support delayed load.
    */
   void removeDelayedFrameScript(in AString aURL);
 };
-
--- a/content/base/src/messageWakeupService.js
+++ b/content/base/src/messageWakeupService.js
@@ -16,17 +16,17 @@ MessageWakeupService.prototype =
   classID:          Components.ID("{f9798742-4f7b-4188-86ba-48b116412b29}"),
   QueryInterface:   XPCOMUtils.generateQI([Ci.nsIObserver]),
 
   messagesData: [],
 
   get messageManager() {
     if (!this._messageManager)
       this._messageManager = Cc["@mozilla.org/parentprocessmessagemanager;1"].
-                             getService(Ci.nsIFrameMessageManager);
+                             getService(Ci.nsIMessageListenerManager);
     return this._messageManager;
   },
 
   requestWakeup: function(aMessageName, aCid, aIid, aMethod) {
     this.messagesData[aMessageName] = {
       cid: aCid,
       iid: aIid,
       method: aMethod,
@@ -34,17 +34,17 @@ MessageWakeupService.prototype =
 
     this.messageManager.addMessageListener(aMessageName, this);
   },
 
   receiveMessage: function(aMessage) {
     let data = this.messagesData[aMessage.name];
     // TODO: When bug 593407 is ready, stop doing the wrappedJSObject hack
     //       and use this line instead:
-    //                  QueryInterface(Ci.nsIFrameMessageListener);
+    //                  QueryInterface(Ci.nsIMessageListener);
     let service = Cc[data.cid][data.method](Ci[data.iid]).
                   wrappedJSObject;
 
     // The receiveMessage() call itself may spin an event loop, and we
     // do not want to swap listeners in that - it would cause the current
     // message to be answered by two listeners. So, we call that first,
     // then queue the swap for the next event loop
     let ret = service.receiveMessage(aMessage);
--- a/content/base/src/nsCCUncollectableMarker.cpp
+++ b/content/base/src/nsCCUncollectableMarker.cpp
@@ -87,40 +87,42 @@ MarkUserDataHandler(void* aNode, nsIAtom
   if (d && nsCCUncollectableMarker::InGeneration(d->GetMarkedCCGeneration())) {
     nsGenericElement::MarkUserDataHandler(aNode, aKey, aValue, aData);
   }
 }
 
 static void
 MarkMessageManagers()
 {
-  nsCOMPtr<nsIChromeFrameMessageManager> globalMM =
+  nsCOMPtr<nsIMessageBroadcaster> globalMM =
     do_GetService("@mozilla.org/globalmessagemanager;1");
   if (!globalMM) {
     return;
   }
 
   globalMM->MarkForCC();
   uint32_t childCount = 0;
   globalMM->GetChildCount(&childCount);
   for (uint32_t i = 0; i < childCount; ++i) {
-    nsCOMPtr<nsITreeItemFrameMessageManager> windowMM;
-    globalMM->GetChildAt(i, getter_AddRefs(windowMM));
-    if (!windowMM) {
+    nsCOMPtr<nsIMessageListenerManager> childMM;
+    globalMM->GetChildAt(i, getter_AddRefs(childMM));
+    if (!childMM) {
       continue;
     }
+    nsCOMPtr<nsIMessageBroadcaster> windowMM = do_QueryInterface(childMM);
     windowMM->MarkForCC();
     uint32_t tabChildCount = 0;
     windowMM->GetChildCount(&tabChildCount);
     for (uint32_t j = 0; j < tabChildCount; ++j) {
-      nsCOMPtr<nsITreeItemFrameMessageManager> tabMM;
-      windowMM->GetChildAt(j, getter_AddRefs(tabMM));
-      if (!tabMM) {
+      nsCOMPtr<nsIMessageListenerManager> childMM;
+      windowMM->GetChildAt(j, getter_AddRefs(childMM));
+      if (!childMM) {
         continue;
       }
+      nsCOMPtr<nsIMessageSender> tabMM = do_QueryInterface(childMM);
       tabMM->MarkForCC();
       //XXX hack warning, but works, since we know that
       //    callback data is frameloader.
       void* cb = static_cast<nsFrameMessageManager*>(tabMM.get())->
         GetCallbackData();
       nsFrameLoader* fl = static_cast<nsFrameLoader*>(cb);
       if (fl) {
         nsIDOMEventTarget* et = fl->GetTabChildGlobalAsEventTarget();
--- a/content/base/src/nsFrameLoader.cpp
+++ b/content/base/src/nsFrameLoader.cpp
@@ -2239,17 +2239,17 @@ bool SendAsyncMessageToChild(void* aCall
   nsRefPtr<nsIRunnable> ev =
     new nsAsyncMessageToChild(static_cast<nsFrameLoader*>(aCallbackData),
                                     aMessage, aData);
   NS_DispatchToCurrentThread(ev);
   return true;
 }
 
 NS_IMETHODIMP
-nsFrameLoader::GetMessageManager(nsIChromeFrameMessageManager** aManager)
+nsFrameLoader::GetMessageManager(nsIMessageSender** aManager)
 {
   EnsureMessageManager();
   if (mMessageManager) {
     CallQueryInterface(mMessageManager, aManager);
   }
   return NS_OK;
 }
 
@@ -2331,31 +2331,31 @@ nsFrameLoader::EnsureMessageManager()
   nsIScriptContext* sctx = mOwnerContent->GetContextForEventHandlers(&rv);
   NS_ENSURE_SUCCESS(rv, rv);
   NS_ENSURE_STATE(sctx);
   JSContext* cx = sctx->GetNativeContext();
   NS_ENSURE_STATE(cx);
 
   nsCOMPtr<nsIDOMChromeWindow> chromeWindow =
     do_QueryInterface(GetOwnerDoc()->GetWindow());
-  nsCOMPtr<nsIChromeFrameMessageManager> parentManager;
+  nsCOMPtr<nsIMessageBroadcaster> parentManager;
   if (chromeWindow) {
     chromeWindow->GetMessageManager(getter_AddRefs(parentManager));
   }
 
   if (ShouldUseRemoteProcess()) {
-    mMessageManager = new nsFrameMessageManager(true,
+    mMessageManager = new nsFrameMessageManager(true, /* aChrome */
                                                 nullptr,
                                                 SendAsyncMessageToChild,
                                                 LoadScript,
                                                 mRemoteBrowserShown ? this : nullptr,
                                                 static_cast<nsFrameMessageManager*>(parentManager.get()),
                                                 cx);
   } else {
-    mMessageManager = new nsFrameMessageManager(true,
+    mMessageManager = new nsFrameMessageManager(true, /* aChrome */
                                                 nullptr,
                                                 SendAsyncMessageToChild,
                                                 LoadScript,
                                                 nullptr,
                                                 static_cast<nsFrameMessageManager*>(parentManager.get()),
                                                 cx);
     mChildMessageManager =
       new nsInProcessTabChildGlobal(mDocShell, mOwnerContent, mMessageManager);
--- a/content/base/src/nsFrameMessageManager.cpp
+++ b/content/base/src/nsFrameMessageManager.cpp
@@ -19,16 +19,17 @@
 #include "nsScriptLoader.h"
 #include "nsIJSContextStack.h"
 #include "nsIXULRuntime.h"
 #include "nsIScriptError.h"
 #include "nsIConsoleService.h"
 #include "nsIProtocolHandler.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIJSRuntimeService.h"
+#include "nsIDOMClassInfo.h"
 #include "nsIDOMFile.h"
 #include "xpcpublic.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/dom/StructuredCloneUtils.h"
 
 #ifdef ANDROID
 #include <android/log.h>
 #endif
@@ -59,50 +60,68 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(
     NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mListeners[i] mListener");
     cb.NoteXPCOMChild(tmp->mListeners[i].mListener.get());
   }
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mChildManagers)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsFrameMessageManager)
   tmp->mListeners.Clear();
-  for (int32_t i = tmp->mChildManagers.Count(); i > 0; --i) {
+  for (PRInt32 i = tmp->mChildManagers.Count(); i > 0; --i) {
     static_cast<nsFrameMessageManager*>(tmp->mChildManagers[i - 1])->
       Disconnect(false);
   }
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mChildManagers)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsFrameMessageManager)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIContentFrameMessageManager)
-  NS_INTERFACE_MAP_ENTRY_AGGREGATED(nsIFrameMessageManager,
-                                    (mChrome ?
-                                       static_cast<nsIFrameMessageManager*>(
-                                         static_cast<nsIChromeFrameMessageManager*>(this)) :
-                                       static_cast<nsIFrameMessageManager*>(
-                                         static_cast<nsIContentFrameMessageManager*>(this))))
+
+  /* nsFrameMessageManager implements nsIMessageSender and nsIMessageBroadcaster,
+   * both of which descend from nsIMessageListenerManager. QI'ing to
+   * nsIMessageListenerManager is therefore ambiguous and needs explicit casts
+   * depending on which child interface applies. */
+  NS_INTERFACE_MAP_ENTRY_AGGREGATED(nsIMessageListenerManager,
+                                    (mIsBroadcaster ?
+                                       static_cast<nsIMessageListenerManager*>(
+                                         static_cast<nsIMessageBroadcaster*>(this)) :
+                                       static_cast<nsIMessageListenerManager*>(
+                                         static_cast<nsIMessageSender*>(this))))
+
+  /* Message managers in child process implement nsIMessageSender and
+     nsISyncMessageSender.  Message managers in the chrome process are
+     either broadcasters (if they have subordinate/child message
+     managers) or they're simple message senders. */
+  NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsISyncMessageSender, !mChrome)
+  NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIMessageSender, !mChrome || !mIsBroadcaster)
+  NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIMessageBroadcaster, mChrome && mIsBroadcaster)
+
   /* nsIContentFrameMessageManager is accessible only in TabChildGlobal. */
   NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIContentFrameMessageManager,
                                      !mChrome && !mIsProcessManager)
-  /* Message managers in child process support nsISyncMessageSender. */
-  NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsISyncMessageSender, !mChrome)
-  /* Message managers in chrome process support nsITreeItemFrameMessageManager. */
-  NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsITreeItemFrameMessageManager, mChrome)
-  /* Process message manager doesn't support nsIChromeFrameMessageManager. */
-  NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIChromeFrameMessageManager,
+
+  /* Frame message managers (non-process message managers) support nsIFrameScriptLoader. */
+  NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIFrameScriptLoader,
                                      mChrome && !mIsProcessManager)
+
+  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO_CONDITIONAL(ChromeMessageBroadcaster,
+                                                   mChrome && mIsBroadcaster)
+  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO_CONDITIONAL(ChromeMessageSender,
+                                                   mChrome && !mIsBroadcaster)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsFrameMessageManager)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsFrameMessageManager)
 
+// nsIMessageListenerManager
+
 NS_IMETHODIMP
 nsFrameMessageManager::AddMessageListener(const nsAString& aMessage,
-                                          nsIFrameMessageListener* aListener)
+                                          nsIMessageListener* aListener)
 {
   nsCOMPtr<nsIAtom> message = do_GetAtom(aMessage);
   uint32_t len = mListeners.Length();
   for (uint32_t i = 0; i < len; ++i) {
     if (mListeners[i].mMessage == message &&
       mListeners[i].mListener == aListener) {
       return NS_OK;
     }
@@ -111,30 +130,32 @@ nsFrameMessageManager::AddMessageListene
   NS_ENSURE_TRUE(entry, NS_ERROR_OUT_OF_MEMORY);
   entry->mMessage = message;
   entry->mListener = aListener;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsFrameMessageManager::RemoveMessageListener(const nsAString& aMessage,
-                                             nsIFrameMessageListener* aListener)
+                                             nsIMessageListener* aListener)
 {
   nsCOMPtr<nsIAtom> message = do_GetAtom(aMessage);
   uint32_t len = mListeners.Length();
   for (uint32_t i = 0; i < len; ++i) {
     if (mListeners[i].mMessage == message &&
       mListeners[i].mListener == aListener) {
       mListeners.RemoveElementAt(i);
       return NS_OK;
     }
   }
   return NS_OK;
 }
 
+// nsIFrameScriptLoader
+
 NS_IMETHODIMP
 nsFrameMessageManager::LoadFrameScript(const nsAString& aURL,
                                        bool aAllowDelayedLoad)
 {
   if (aAllowDelayedLoad) {
     if (IsGlobal() || IsWindowLevel()) {
       // Cache for future windows or frames
       mPendingScripts.AppendElement(aURL);
@@ -147,17 +168,17 @@ nsFrameMessageManager::LoadFrameScript(c
 
   if (mCallbackData) {
 #ifdef DEBUG_smaug
     printf("Will load %s \n", NS_ConvertUTF16toUTF8(aURL).get());
 #endif
     NS_ENSURE_TRUE(mLoadScriptCallback(mCallbackData, aURL), NS_ERROR_FAILURE);
   }
 
-  for (int32_t i = 0; i < mChildManagers.Count(); ++i) {
+  for (PRInt32 i = 0; i < mChildManagers.Count(); ++i) {
     nsRefPtr<nsFrameMessageManager> mm =
       static_cast<nsFrameMessageManager*>(mChildManagers[i]);
     if (mm) {
       // Use false here, so that child managers don't cache the script, which
       // is already cached in the parent.
       mm->LoadFrameScript(aURL, false);
     }
   }
@@ -203,16 +224,19 @@ GetParamsForMessage(JSContext* aCx,
 
   jsval val = JSVAL_NULL;
   NS_ENSURE_TRUE(JS_ParseJSON(aCx, static_cast<const jschar*>(PromiseFlatString(json).get()),
                               json.Length(), &val), false);
 
   return WriteStructuredClone(aCx, val, aBuffer, aClosure);
 }
 
+
+// nsISyncMessageSender
+
 NS_IMETHODIMP
 nsFrameMessageManager::SendSyncMessage(const nsAString& aMessageName,
                                        const jsval& aObject,
                                        JSContext* aCx,
                                        uint8_t aArgc,
                                        jsval* aRetval)
 {
   NS_ASSERTION(!IsGlobal(), "Should not call SendSyncMessage in chrome");
@@ -252,51 +276,100 @@ nsFrameMessageManager::SendSyncMessage(c
 
       *aRetval = OBJECT_TO_JSVAL(dataArray);
     }
   }
   return NS_OK;
 }
 
 nsresult
-nsFrameMessageManager::SendAsyncMessageInternal(const nsAString& aMessage,
-                                                const StructuredCloneData& aData)
+nsFrameMessageManager::DispatchAsyncMessageInternal(const nsAString& aMessage,
+                                                    const StructuredCloneData& aData,
+                                                    ShouldBroadcast aBroadcast)
 {
   if (mAsyncCallback) {
     NS_ENSURE_TRUE(mCallbackData, NS_ERROR_NOT_INITIALIZED);
     mAsyncCallback(mCallbackData, aMessage, aData);
   }
-  int32_t len = mChildManagers.Count();
-  for (int32_t i = 0; i < len; ++i) {
-    static_cast<nsFrameMessageManager*>(mChildManagers[i])->
-      SendAsyncMessageInternal(aMessage, aData);
+  if (aBroadcast == BROADCAST) {
+    PRInt32 len = mChildManagers.Count();
+    for (PRInt32 i = 0; i < len; ++i) {
+      static_cast<nsFrameMessageManager*>(mChildManagers[i])->
+         DispatchAsyncMessageInternal(aMessage, aData, aBroadcast);
+    }
   }
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsFrameMessageManager::SendAsyncMessage(const nsAString& aMessageName,
-                                        const jsval& aObject,
-                                        JSContext* aCx,
-                                        uint8_t aArgc)
+nsresult
+nsFrameMessageManager::DispatchAsyncMessage(const nsAString& aMessageName,
+                                            const jsval& aObject,
+                                            JSContext* aCx,
+                                            uint8_t aArgc,
+                                            ShouldBroadcast aBroadcast)
 {
   StructuredCloneData data;
   JSAutoStructuredCloneBuffer buffer;
 
   if (aArgc >= 2 &&
       !GetParamsForMessage(aCx, aObject, buffer, data.mClosure)) {
     return NS_ERROR_DOM_DATA_CLONE_ERR;
   }
 
   data.mData = buffer.data();
   data.mDataLength = buffer.nbytes();
 
-  return SendAsyncMessageInternal(aMessageName, data);
+  return DispatchAsyncMessageInternal(aMessageName, data, aBroadcast);
+}
+
+
+// nsIMessageSender
+
+NS_IMETHODIMP
+nsFrameMessageManager::SendAsyncMessage(const nsAString& aMessageName,
+                                        const jsval& aObject,
+                                        JSContext* aCx,
+                                        uint8_t aArgc)
+{
+  return DispatchAsyncMessage(aMessageName, aObject, aCx, aArgc, DONT_BROADCAST);
 }
 
+
+// nsIMessageBroadcaster
+
+NS_IMETHODIMP
+nsFrameMessageManager::BroadcastAsyncMessage(const nsAString& aMessageName,
+                                             const jsval& aObject,
+                                             JSContext* aCx,
+                                             uint8_t aArgc)
+{
+  return DispatchAsyncMessage(aMessageName, aObject, aCx, aArgc, BROADCAST);
+}
+
+NS_IMETHODIMP
+nsFrameMessageManager::GetChildCount(uint32_t* aChildCount)
+{
+  *aChildCount = static_cast<uint32_t>(mChildManagers.Count()); 
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsFrameMessageManager::GetChildAt(uint32_t aIndex, 
+                                  nsIMessageListenerManager** aMM)
+{
+  *aMM = nullptr;
+  nsCOMPtr<nsIMessageListenerManager> mm =
+    do_QueryInterface(mChildManagers.SafeObjectAt(static_cast<uint32_t>(aIndex)));
+  mm.swap(*aMM);
+  return NS_OK;
+}
+
+
+// nsIContentFrameMessageManager
+
 NS_IMETHODIMP
 nsFrameMessageManager::Dump(const nsAString& aStr)
 {
 #ifdef ANDROID
   __android_log_print(ANDROID_LOG_INFO, "Gecko", "%s", NS_ConvertUTF16toUTF8(aStr).get());
 #endif
 #ifdef XP_WIN
   if (IsDebuggerPresent()) {
@@ -324,47 +397,30 @@ nsFrameMessageManager::GetContent(nsIDOM
 NS_IMETHODIMP
 nsFrameMessageManager::GetDocShell(nsIDocShell** aDocShell)
 {
   *aDocShell = nullptr;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsFrameMessageManager::GetChildCount(uint32_t* aChildCount)
-{
-  *aChildCount = static_cast<uint32_t>(mChildManagers.Count()); 
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsFrameMessageManager::GetChildAt(uint32_t aIndex, 
-                                  nsITreeItemFrameMessageManager** aMM)
-{
-  *aMM = nullptr;
-  nsCOMPtr<nsITreeItemFrameMessageManager> mm =
-    do_QueryInterface(mChildManagers.SafeObjectAt(static_cast<uint32_t>(aIndex)));
-  mm.swap(*aMM);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
 nsFrameMessageManager::Btoa(const nsAString& aBinaryData,
                             nsAString& aAsciiBase64String)
 {
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsFrameMessageManager::Atob(const nsAString& aAsciiString,
                             nsAString& aBinaryData)
 {
   return NS_OK;
 }
 
+
 class MMListenerRemover
 {
 public:
   MMListenerRemover(nsFrameMessageManager* aMM)
     : mWasHandlingMessage(aMM->mHandlingMessage)
     , mMM(aMM)
   {
     mMM->mHandlingMessage = true;
@@ -378,16 +434,19 @@ public:
       }
     }
   }
 
   bool mWasHandlingMessage;
   nsRefPtr<nsFrameMessageManager> mMM;
 };
 
+
+// nsIMessageListener
+
 nsresult
 nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
                                       const nsAString& aMessage,
                                       bool aSync,
                                       const StructuredCloneData* aCloneData,
                                       JSObject* aObjectsArray,
                                       InfallibleTArray<nsString>* aJSONRetVal,
                                       JSContext* aContext)
@@ -586,27 +645,29 @@ nsFrameMessageManager::Disconnect(bool a
   mCallbackData = nullptr;
   mContext = nullptr;
   if (!mHandlingMessage) {
     mListeners.Clear();
   }
 }
 
 nsresult
-NS_NewGlobalMessageManager(nsIChromeFrameMessageManager** aResult)
+NS_NewGlobalMessageManager(nsIMessageBroadcaster** aResult)
 {
   NS_ENSURE_TRUE(IsChromeProcess(), NS_ERROR_NOT_AVAILABLE);
-  nsFrameMessageManager* mm = new nsFrameMessageManager(true,
+  nsFrameMessageManager* mm = new nsFrameMessageManager(true /* aChrome */,
                                                         nullptr,
                                                         nullptr,
                                                         nullptr,
                                                         nullptr,
                                                         nullptr,
                                                         nullptr,
-                                                        true);
+                                                        true /* aGlobal */,
+                                                        false /* aProcessManager */,
+                                                        true /* aBroadcaster */);
   NS_ENSURE_TRUE(mm, NS_ERROR_OUT_OF_MEMORY);
   return CallQueryInterface(mm, aResult);
 }
 
 void
 ContentScriptErrorReporter(JSContext* aCx,
                            const char* aMessage,
                            JSErrorReport* aReport)
@@ -822,27 +883,23 @@ nsFrameScriptExecutor::LoadFrameScriptIn
     {
       // Need to scope JSAutoRequest to happen after Push but before Pop,
       // at least for now. See bug 584673.
       JSAutoRequest ar(mCx);
       JSObject* global = nullptr;
       mGlobal->GetJSObject(&global);
       if (global) {
         JSAutoCompartment ac(mCx, global);
-        uint32_t oldopts = JS_GetOptions(mCx);
-        JS_SetOptions(mCx, oldopts | JSOPTION_NO_SCRIPT_RVAL);
-
-        JSScript* script =
-          JS_CompileUCScriptForPrincipals(mCx, nullptr,
-                                          nsJSPrincipals::get(mPrincipal),
-                                          static_cast<const jschar*>(dataString.get()),
-                                          dataString.Length(),
-                                          url.get(), 1);
-
-        JS_SetOptions(mCx, oldopts);
+        JS::CompileOptions options(mCx);
+        options.setNoScriptRval(true)
+               .setFileAndLine(url.get(), 1)
+               .setPrincipals(nsJSPrincipals::get(mPrincipal));
+        JS::RootedObject empty(mCx, NULL);
+        JSScript* script = JS::Compile(mCx, empty, options,
+                                       dataString.get(), dataString.Length());
 
         if (script) {
           nsCAutoString scheme;
           uri->GetScheme(scheme);
           // We don't cache data: scripts!
           if (!scheme.EqualsLiteral("data")) {
             nsFrameJSScriptExecutorHolder* holder =
               new nsFrameJSScriptExecutorHolder(script);
@@ -1133,78 +1190,79 @@ bool SendAsyncMessageToSameProcessParent
     new nsAsyncMessageToSameProcessParent(aMessage, aData);
   nsFrameMessageManager::sPendingSameProcessAsyncMessages->AppendElement(ev);
   NS_DispatchToCurrentThread(ev);
   return true;
 }
 
 // This creates the global parent process message manager.
 nsresult
-NS_NewParentProcessMessageManager(nsIFrameMessageManager** aResult)
+NS_NewParentProcessMessageManager(nsIMessageBroadcaster** aResult)
 {
   NS_ASSERTION(!nsFrameMessageManager::sParentProcessManager,
                "Re-creating sParentProcessManager");
   NS_ENSURE_TRUE(IsChromeProcess(), NS_ERROR_NOT_AVAILABLE);
-  nsRefPtr<nsFrameMessageManager> mm = new nsFrameMessageManager(true,
+  nsRefPtr<nsFrameMessageManager> mm = new nsFrameMessageManager(true /* aChrome */,
                                                                  nullptr,
                                                                  nullptr,
                                                                  nullptr,
                                                                  nullptr,
                                                                  nullptr,
                                                                  nullptr,
-                                                                 false,
-                                                                 true);
+                                                                 false, /* aGlobal */
+                                                                 true /* aProcessManager */,
+                                                                 true /* aBroadcaster */);
   NS_ENSURE_TRUE(mm, NS_ERROR_OUT_OF_MEMORY);
   nsFrameMessageManager::sParentProcessManager = mm;
   nsFrameMessageManager::NewProcessMessageManager(nullptr); // Create same process message manager.
   return CallQueryInterface(mm, aResult);
 }
 
 nsFrameMessageManager*
 nsFrameMessageManager::NewProcessMessageManager(mozilla::dom::ContentParent* aProcess)
 {
   if (!nsFrameMessageManager::sParentProcessManager) {
-     nsCOMPtr<nsIFrameMessageManager> dummy;
+     nsCOMPtr<nsIMessageBroadcaster> dummy;
      NS_NewParentProcessMessageManager(getter_AddRefs(dummy));
   }
 
-  nsFrameMessageManager* mm = new nsFrameMessageManager(true,
+  nsFrameMessageManager* mm = new nsFrameMessageManager(true /* aChrome */,
                                                         nullptr,
                                                         aProcess ? SendAsyncMessageToChildProcess
                                                                  : SendAsyncMessageToSameProcessChild,
                                                         nullptr,
                                                         aProcess ? static_cast<void*>(aProcess)
                                                                  : static_cast<void*>(&nsFrameMessageManager::sChildProcessManager),
                                                         nsFrameMessageManager::sParentProcessManager,
                                                         nullptr,
-                                                        false,
-                                                        true);
+                                                        false, /* aGlobal */
+                                                        true /* aProcessManager */);
   if (!aProcess) {
     sSameProcessParentManager = mm;
   }
   return mm;
 }
 
 nsresult
 NS_NewChildProcessMessageManager(nsISyncMessageSender** aResult)
 {
   NS_ASSERTION(!nsFrameMessageManager::sChildProcessManager,
                "Re-creating sChildProcessManager");
   bool isChrome = IsChromeProcess();
-  nsFrameMessageManager* mm = new nsFrameMessageManager(false,
+  nsFrameMessageManager* mm = new nsFrameMessageManager(false /* aChrome */,
                                                         isChrome ? SendSyncMessageToSameProcessParent
                                                                  : SendSyncMessageToParentProcess,
                                                         isChrome ? SendAsyncMessageToSameProcessParent
                                                                  : SendAsyncMessageToParentProcess,
                                                         nullptr,
                                                         &nsFrameMessageManager::sChildProcessManager,
                                                         nullptr,
                                                         nullptr,
-                                                        false,
-                                                        true);
+                                                        false /* aGlobal */,
+                                                        true /* aProcessManager */);
   NS_ENSURE_TRUE(mm, NS_ERROR_OUT_OF_MEMORY);
   nsFrameMessageManager::sChildProcessManager = mm;
   return CallQueryInterface(mm, aResult);
 }
 
 bool
 nsFrameMessageManager::MarkForCC()
 {
--- a/content/base/src/nsFrameMessageManager.h
+++ b/content/base/src/nsFrameMessageManager.h
@@ -1,16 +1,16 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #ifndef nsFrameMessageManager_h__
 #define nsFrameMessageManager_h__
 
-#include "nsIFrameMessageManager.h"
+#include "nsIMessageManager.h"
 #include "nsIObserver.h"
 #include "nsCOMPtr.h"
 #include "nsAutoPtr.h"
 #include "nsCOMArray.h"
 #include "nsTArray.h"
 #include "nsIAtom.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsTArray.h"
@@ -30,46 +30,54 @@ struct StructuredCloneData;
 }
 
 class nsAXPCNativeCallContext;
 struct JSContext;
 struct JSObject;
 
 struct nsMessageListenerInfo
 {
-  nsCOMPtr<nsIFrameMessageListener> mListener;
+  nsCOMPtr<nsIMessageListener> mListener;
   nsCOMPtr<nsIAtom> mMessage;
 };
 
 typedef bool (*nsLoadScriptCallback)(void* aCallbackData, const nsAString& aURL);
 typedef bool (*nsSyncMessageCallback)(void* aCallbackData,
                                       const nsAString& aMessage,
                                       const mozilla::dom::StructuredCloneData& aData,
                                       InfallibleTArray<nsString>* aJSONRetVal);
 typedef bool (*nsAsyncMessageCallback)(void* aCallbackData,
                                        const nsAString& aMessage,
                                              const mozilla::dom::StructuredCloneData& aData);
 
 class nsFrameMessageManager MOZ_FINAL : public nsIContentFrameMessageManager,
-                                        public nsIChromeFrameMessageManager
+                                        public nsIMessageBroadcaster,
+                                        public nsIFrameScriptLoader
 {
   typedef mozilla::dom::StructuredCloneData StructuredCloneData;
 public:
   nsFrameMessageManager(bool aChrome,
                         nsSyncMessageCallback aSyncCallback,
                         nsAsyncMessageCallback aAsyncCallback,
                         nsLoadScriptCallback aLoadScriptCallback,
                         void* aCallbackData,
                         nsFrameMessageManager* aParentManager,
                         JSContext* aContext,
                         bool aGlobal = false,
-                        bool aProcessManager = false)
-  : mChrome(aChrome), mGlobal(aGlobal), mIsProcessManager(aProcessManager),
-    mHandlingMessage(false), mDisconnected(false), mParentManager(aParentManager),
-    mSyncCallback(aSyncCallback), mAsyncCallback(aAsyncCallback),
+                        bool aProcessManager = false,
+                        bool aBroadcaster = false)
+  : mChrome(aChrome),
+    mGlobal(aGlobal),
+    mIsProcessManager(aProcessManager),
+    mIsBroadcaster(aBroadcaster),
+    mHandlingMessage(false),
+    mDisconnected(false),
+    mParentManager(aParentManager),
+    mSyncCallback(aSyncCallback),
+    mAsyncCallback(aAsyncCallback),
     mLoadScriptCallback(aLoadScriptCallback),
     mCallbackData(aCallbackData),
     mContext(aContext)
   {
     NS_ASSERTION(mContext || (aChrome && !aParentManager) || aProcessManager,
                  "Should have mContext in non-global/non-process manager!");
     NS_ASSERTION(aChrome || !aParentManager, "Should not set parent manager!");
     // This is a bit hackish. When parent manager is global, we want
@@ -100,21 +108,22 @@ public:
         sSameProcessParentManager = nullptr;
       }
     }
   }
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsFrameMessageManager,
                                            nsIContentFrameMessageManager)
-  NS_DECL_NSIFRAMEMESSAGEMANAGER
+  NS_DECL_NSIMESSAGELISTENERMANAGER
+  NS_DECL_NSIMESSAGESENDER
+  NS_DECL_NSIMESSAGEBROADCASTER
   NS_DECL_NSISYNCMESSAGESENDER
   NS_DECL_NSICONTENTFRAMEMESSAGEMANAGER
-  NS_DECL_NSICHROMEFRAMEMESSAGEMANAGER
-  NS_DECL_NSITREEITEMFRAMEMESSAGEMANAGER
+  NS_DECL_NSIFRAMESCRIPTLOADER
 
   static nsFrameMessageManager*
   NewProcessMessageManager(mozilla::dom::ContentParent* aProcess);
 
   nsresult ReceiveMessage(nsISupports* aTarget, const nsAString& aMessage,
                           bool aSync, const StructuredCloneData* aCloneData,
                           JSObject* aObjectsArray,
                           InfallibleTArray<nsString>* aJSONRetVal,
@@ -125,18 +134,25 @@ public:
   void RemoveChildManager(nsFrameMessageManager* aManager)
   {
     mChildManagers.RemoveObject(aManager);
   }
 
   void Disconnect(bool aRemoveFromParent = true);
   void SetCallbackData(void* aData, bool aLoadScripts = true);
   void* GetCallbackData() { return mCallbackData; }
-  nsresult SendAsyncMessageInternal(const nsAString& aMessage,
-                                          const StructuredCloneData& aData);
+  enum ShouldBroadcast { BROADCAST, DONT_BROADCAST };
+  nsresult DispatchAsyncMessage(const nsAString& aMessageName,
+                                const jsval& aObject,
+                                JSContext* aCx,
+                                PRUint8 aArgc,
+                                ShouldBroadcast aBroadcast);
+  nsresult DispatchAsyncMessageInternal(const nsAString& aMessage,
+                                        const StructuredCloneData& aData,
+                                        ShouldBroadcast aBroadcast);
   JSContext* GetJSContext() { return mContext; }
   void SetJSContext(JSContext* aCx) { mContext = aCx; }
   void RemoveFromParent();
   nsFrameMessageManager* GetParentManager() { return mParentManager; }
   void SetParentManager(nsFrameMessageManager* aParent)
   {
     NS_ASSERTION(!mParentManager, "We have parent manager already!");
     NS_ASSERTION(mChrome, "Should not set parent manager!");
@@ -152,19 +168,20 @@ public:
   static nsFrameMessageManager* GetChildProcessManager()
   {
     return sChildProcessManager;
   }
 protected:
   friend class MMListenerRemover;
   nsTArray<nsMessageListenerInfo> mListeners;
   nsCOMArray<nsIContentFrameMessageManager> mChildManagers;
-  bool mChrome;
-  bool mGlobal;
-  bool mIsProcessManager;
+  bool mChrome;     // true if we're in the chrome process
+  bool mGlobal;     // true if 
+  bool mIsProcessManager; // true if the message manager belongs to the process realm
+  bool mIsBroadcaster; // true if the message manager is a broadcaster
   bool mHandlingMessage;
   bool mDisconnected;
   nsFrameMessageManager* mParentManager;
   nsSyncMessageCallback mSyncCallback;
   nsAsyncMessageCallback mAsyncCallback;
   nsLoadScriptCallback mLoadScriptCallback;
   void* mCallbackData;
   JSContext* mContext;
--- a/content/base/src/nsInProcessTabChildGlobal.cpp
+++ b/content/base/src/nsInProcessTabChildGlobal.cpp
@@ -121,17 +121,17 @@ nsresult
 nsInProcessTabChildGlobal::Init()
 {
 #ifdef DEBUG
   nsresult rv =
 #endif
   InitTabChildGlobal();
   NS_WARN_IF_FALSE(NS_SUCCEEDED(rv),
                    "Couldn't initialize nsInProcessTabChildGlobal");
-  mMessageManager = new nsFrameMessageManager(false,
+  mMessageManager = new nsFrameMessageManager(false, /* aChrome */
                                               SendSyncMessageToParent,
                                               SendAsyncMessageToParent,
                                               nullptr,
                                               this,
                                               nullptr,
                                               mCx);
 
   // Set the location information for the new global, so that tools like
@@ -155,17 +155,18 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsInProcessTabChildGlobal,
                                                   nsDOMEventTargetHelper)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mMessageManager)
   nsFrameScriptExecutor::Traverse(tmp, cb);
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsInProcessTabChildGlobal)
-  NS_INTERFACE_MAP_ENTRY(nsIFrameMessageManager)
+  NS_INTERFACE_MAP_ENTRY(nsIMessageListenerManager)
+  NS_INTERFACE_MAP_ENTRY(nsIMessageSender)
   NS_INTERFACE_MAP_ENTRY(nsISyncMessageSender)
   NS_INTERFACE_MAP_ENTRY(nsIContentFrameMessageManager)
   NS_INTERFACE_MAP_ENTRY(nsIInProcessContentFrameMessageManager)
   NS_INTERFACE_MAP_ENTRY(nsIScriptContextPrincipal)
   NS_INTERFACE_MAP_ENTRY(nsIScriptObjectPrincipal)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(ContentFrameMessageManager)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
 
--- a/content/base/src/nsInProcessTabChildGlobal.h
+++ b/content/base/src/nsInProcessTabChildGlobal.h
@@ -28,17 +28,18 @@ class nsInProcessTabChildGlobal : public
 {
 public:
   nsInProcessTabChildGlobal(nsIDocShell* aShell, nsIContent* aOwner,
                             nsFrameMessageManager* aChrome);
   virtual ~nsInProcessTabChildGlobal();
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsInProcessTabChildGlobal,
                                            nsDOMEventTargetHelper)
-  NS_FORWARD_SAFE_NSIFRAMEMESSAGEMANAGER(mMessageManager)
+  NS_FORWARD_SAFE_NSIMESSAGELISTENERMANAGER(mMessageManager)
+  NS_FORWARD_SAFE_NSIMESSAGESENDER(mMessageManager)
   NS_IMETHOD SendSyncMessage(const nsAString& aMessageName,
                              const jsval& aObject,
                              JSContext* aCx,
                              uint8_t aArgc,
                              jsval* aRetval)
   {
     return mMessageManager
       ? mMessageManager->SendSyncMessage(aMessageName, aObject, aCx, aArgc, aRetval)
--- a/content/base/test/chrome/file_bug549682.xul
+++ b/content/base/test/chrome/file_bug549682.xul
@@ -8,19 +8,22 @@ https://bugzilla.mozilla.org/show_bug.cg
 <window title="Mozilla Bug 549682"
   xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
   onload="run()">
   <label value="Mozilla Bug 549682"/>
   <!-- test code goes here -->
   <script type="application/javascript"><![CDATA[
   var didRunAsync = false;
   var didRunLocal = false;
-  var global = Components.classes["@mozilla.org/globalmessagemanager;1"].getService(Components.interfaces.nsIChromeFrameMessageManager);
-  var ppm = Components.classes["@mozilla.org/parentprocessmessagemanager;1"].getService(Components.interfaces.nsIFrameMessageManager);
-  var cpm = Components.classes["@mozilla.org/childprocessmessagemanager;1"].getService(Components.interfaces.nsISyncMessageSender);
+  var global = Components.classes["@mozilla.org/globalmessagemanager;1"]
+                         .getService(Components.interfaces.nsIMessageBroadcaster);
+  var ppm = Components.classes["@mozilla.org/parentprocessmessagemanager;1"]
+                      .getService(Components.interfaces.nsIMessageBroadcaster);
+  var cpm = Components.classes["@mozilla.org/childprocessmessagemanager;1"]
+                      .getService(Components.interfaces.nsISyncMessageSender);
 
   var asyncPPML = false;
   function ppmASL(m) {
     asyncPPML = true;
   }
   var syncPPML = false;
   function ppmSL(m) {
     syncPPML = true;
@@ -31,17 +34,17 @@ https://bugzilla.mozilla.org/show_bug.cg
   cpm.sendAsyncMessage("processmessageAsync", "");
   cpm.sendSyncMessage("processmessageSync", "");
 
   var asyncCPML = false;
   function cpmASL(m) {
     asyncCPML = true;
   }
   cpm.addMessageListener("childprocessmessage", cpmASL);
-  ppm.sendAsyncMessage("childprocessmessage", "");
+  ppm.broadcastAsyncMessage("childprocessmessage", "");
   
   function checkPMMMessages() {
     opener.wrappedJSObject.ok(asyncPPML, "should have handled async message");
     opener.wrappedJSObject.ok(syncPPML, "should have handled sync message");
     opener.wrappedJSObject.ok(asyncCPML, "should have handled async message");
     ppm.removeMessageListener("processmessageAsync", ppmASL);
     ppm.removeMessageListener("processmessageSync", ppmSL);
     cpm.removeMessageListener("childprocessmessage", cpmASL);
--- a/content/base/test/chrome/file_bug616841.xul
+++ b/content/base/test/chrome/file_bug616841.xul
@@ -25,18 +25,18 @@ https://bugzilla.mozilla.org/show_bug.cg
                       [ "D", "C" ],
                       [ "\u010C", "D" ],
                       [ "D", "\u010C" ] ];
     var nCmps = 0;
 
     function recvContentReady(m) {
       for (var i = 0; i < toCompare.length; ++i) {
         var pair = toCompare[i];
-        messageManager.sendAsyncMessage("cmp",
-                                        { i: i, a: pair[0], b: pair[1] });
+        messageManager.broadcastAsyncMessage("cmp",
+                                             { i: i, a: pair[0], b: pair[1] });
       }
     }
 
     function recvCmp(m) {
       var i = m.json.i, cmp = m.json.cmp;
       var pair = toCompare[i];
       opener.wrappedJSObject.is(pair[0].localeCompare(pair[1]), cmp, "localeCompare returned same result in frame script");
 
--- a/content/html/content/src/nsHTMLMediaElement.cpp
+++ b/content/html/content/src/nsHTMLMediaElement.cpp
@@ -3424,17 +3424,17 @@ nsHTMLMediaElement::CopyInnerTo(nsGeneri
     }
   }
   return rv;
 }
 
 nsresult nsHTMLMediaElement::GetBuffered(nsIDOMTimeRanges** aBuffered)
 {
   nsRefPtr<nsTimeRanges> ranges = new nsTimeRanges();
-  if (mReadyState >= nsIDOMHTMLMediaElement::HAVE_CURRENT_DATA && mDecoder) {
+  if (mReadyState > nsIDOMHTMLMediaElement::HAVE_NOTHING && mDecoder) {
     // If GetBuffered fails we ignore the error result and just return the
     // time ranges we found up till the error.
     mDecoder->GetBuffered(ranges);
   }
   ranges.forget(aBuffered);
   return NS_OK;
 }
 
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -185,17 +185,16 @@
 #include "nsIContentSecurityPolicy.h"
 #include "nsSandboxFlags.h"
 
 #include "nsXULAppAPI.h"
 
 #include "nsDOMNavigationTiming.h"
 #include "nsITimedChannel.h"
 #include "mozilla/StartupTimeline.h"
-#include "nsIFrameMessageManager.h"
 
 #include "mozilla/Telemetry.h"
 #include "nsISecurityUITelemetry.h"
 
 static NS_DEFINE_CID(kDOMScriptObjectFactoryCID,
                      NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
 static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
 
--- a/dom/activities/src/ActivitiesService.jsm
+++ b/dom/activities/src/ActivitiesService.jsm
@@ -7,20 +7,19 @@
 const Cu = Components.utils; 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/IndexedDBHelper.jsm");
 
-XPCOMUtils.defineLazyGetter(this, "ppmm", function() {
-  return Cc["@mozilla.org/parentprocessmessagemanager;1"]
-           .getService(Ci.nsIFrameMessageManager);
-});
+XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
+                                   "@mozilla.org/parentprocessmessagemanager;1",
+                                   "nsIMessageBroadcaster");
 
 const EXPORTED_SYMBOLS = [];
 
 let idbGlobal = this;
 
 function debug(aMsg) { 
   //dump("-- ActivitiesService.jsm " + Date.now() + " " + aMsg + "\n");
 }
@@ -189,29 +188,29 @@ let Activities = {
   startActivity: function activities_startActivity(aMsg) {
     debug("StartActivity: " + JSON.stringify(aMsg));
 
     let successCb = function successCb(aResults) {
       debug(JSON.stringify(aResults));
 
       // We have no matching activity registered, let's fire an error.
       if (aResults.options.length === 0) {
-        ppmm.sendAsyncMessage("Activity:FireError", {
+        ppmm.broadcastAsyncMessage("Activity:FireError", {
           "id": aMsg.id,
           "error": "NO_PROVIDER"
         });
         return;
       }
 
       function getActivityChoice(aChoice) {
         debug("Activity choice: " + aChoice);
 
         // The user has cancelled the choice, fire an error.
         if (aChoice === -1) {
-          ppmm.sendAsyncMessage("Activity:FireError", {
+          ppmm.broadcastAsyncMessage("Activity:FireError", {
             "id": aMsg.id,
             "error": "USER_ABORT"
           });
           return;
         }
 
         let sysmm = Cc["@mozilla.org/system-message-internal;1"]
                       .getService(Ci.nsISystemMessagesInternal);
@@ -226,17 +225,17 @@ let Activities = {
             "id": aMsg.id,
             "payload": aMsg.options,
             "target": result.description
           },
           Services.io.newURI(result.description.href, null, null),
           Services.io.newURI(result.manifest, null, null));
 
         if (!result.description.returnValue) {
-          ppmm.sendAsyncMessage("Activity:FireSuccess", {
+          ppmm.broadcastAsyncMessage("Activity:FireSuccess", {
             "id": aMsg.id,
             "result": null
           });
         }
       };
 
       let glue = Cc["@mozilla.org/dom/activities/ui-glue;1"]
                    .createInstance(Ci.nsIActivityUIGlue);
@@ -261,28 +260,28 @@ let Activities = {
       }
       return true;
     };
 
     this.db.find(aMsg, successCb, errorCb, matchFunc);
   },
 
   receiveMessage: function activities_receiveMessage(aMessage) {
-    let mm = aMessage.target.QueryInterface(Ci.nsIFrameMessageManager);
+    let mm = aMessage.target;
     let msg = aMessage.json;
     switch(aMessage.name) {
       case "Activity:Start":
         this.startActivity(msg);
         break;
 
       case "Activity:PostResult":
-        ppmm.sendAsyncMessage("Activity:FireSuccess", msg);
+        ppmm.broadcastAsyncMessage("Activity:FireSuccess", msg);
         break;
       case "Activity:PostError":
-        ppmm.sendAsyncMessage("Activity:FireError", msg);
+        ppmm.broadcastAsyncMessage("Activity:FireError", msg);
         break;
 
       case "Activities:Register":
         this.db.add(msg, function onSuccess(aEvent) {
           mm.sendAsyncMessage("Activities:Register:OK", msg);
         },
         function onError(aEvent) {
           msg.error = "REGISTER_ERROR";
--- a/dom/activities/src/ActivityProxy.js
+++ b/dom/activities/src/ActivityProxy.js
@@ -7,21 +7,19 @@
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/ObjectWrapper.jsm");
 
-XPCOMUtils.defineLazyGetter(this, "cpmm", function() {
-  return Cc["@mozilla.org/childprocessmessagemanager;1"]
-           .getService(Ci.nsIFrameMessageManager)
-           .QueryInterface(Ci.nsISyncMessageSender);
-});
+XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
+                                   "@mozilla.org/childprocessmessagemanager;1",
+                                   "nsISyncMessageSender");
 
 function debug(aMsg) {
   //dump("-- ActivityProxy " + Date.now() + " : " + aMsg + "\n");
 }
 
 /**
   * nsIActivityProxy implementation
   * We keep a reference to the C++ Activity object, and
--- a/dom/activities/src/ActivityRequestHandler.js
+++ b/dom/activities/src/ActivityRequestHandler.js
@@ -5,21 +5,19 @@
 "use strict";
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
-XPCOMUtils.defineLazyGetter(this, "cpmm", function() {
-  return Cc["@mozilla.org/childprocessmessagemanager;1"]
-           .getService(Ci.nsIFrameMessageManager)
-           .QueryInterface(Ci.nsISyncMessageSender);
-});
+XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
+                                   "@mozilla.org/childprocessmessagemanager;1",
+                                   "nsISyncMessageSender");
 
 function debug(aMsg) {
   //dump("-- ActivityRequestHandler.js " + Date.now() + " : " + aMsg + "\n");
 }
 
 /**
   * nsIDOMMozActivityRequestHandler implementation.
   */
--- a/dom/alarm/AlarmService.jsm
+++ b/dom/alarm/AlarmService.jsm
@@ -15,19 +15,19 @@ function debug(aStr) {
 const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/AlarmDB.jsm");
 
 let EXPORTED_SYMBOLS = ["AlarmService"];
 
-XPCOMUtils.defineLazyGetter(this, "ppmm", function() {
-  return Cc["@mozilla.org/parentprocessmessagemanager;1"].getService(Ci.nsIFrameMessageManager);
-});
+XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
+                                   "@mozilla.org/parentprocessmessagemanager;1",
+                                   "nsIMessageListenerManager");
 
 XPCOMUtils.defineLazyGetter(this, "messenger", function() {
   return Cc["@mozilla.org/system-message-internal;1"].getService(Ci.nsISystemMessagesInternal);
 });
 
 let myGlobal = this;
 
 let AlarmService = {
@@ -70,17 +70,17 @@ let AlarmService = {
 
     if (!this._alarmHalService.setAlarm(this._getAlarmTime(aAlarm) / 1000, 0))
       throw Components.results.NS_ERROR_FAILURE;
   },
 
   receiveMessage: function receiveMessage(aMessage) {
     debug("receiveMessage(): " + aMessage.name);
 
-    let mm = aMessage.target.QueryInterface(Ci.nsIFrameMessageManager);
+    let mm = aMessage.target.QueryInterface(Ci.nsIMessageSender);
     let json = aMessage.json;
     switch (aMessage.name) {
       case "AlarmsManager:GetAll":
         this._db.getAll(
           json.manifestURL,
           function getAllSuccessCb(aAlarms) {
             debug("Callback after getting alarms from database: " + JSON.stringify(aAlarms));
             this._sendAsyncMessage(mm, "GetAll", true, json.requestId, aAlarms);
--- a/dom/apps/src/AppsService.js
+++ b/dom/apps/src/AppsService.js
@@ -21,18 +21,17 @@ function AppsService()
   debug("AppsService Constructor");
   this.inParent = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime)
                   .processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
   debug("inParent: " + this.inParent);
   if (this.inParent) {
     Cu.import("resource://gre/modules/Webapps.jsm");
   } else {
     this.cpmm = Cc["@mozilla.org/childprocessmessagemanager;1"]
-                .getService(Ci.nsIFrameMessageManager)
-                .QueryInterface(Ci.nsISyncMessageSender);
+                .getService(Ci.nsISyncMessageSender);
   }
 }
 
 AppsService.prototype = {
   getAppByManifestURL: function getAppByManifestURL(aManifestURL) {
     debug("GetAppByManifestURL( " + aManifestURL + " )");
     if (this.inParent) {
       return DOMApplicationRegistry.getAppByManifestURL(aManifestURL);
--- a/dom/apps/src/Webapps.js
+++ b/dom/apps/src/Webapps.js
@@ -7,19 +7,19 @@ const Ci = Components.interfaces;
 const Cu = Components.utils;
 const Cr = Components.results;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
 Cu.import("resource://gre/modules/ObjectWrapper.jsm");
 
-XPCOMUtils.defineLazyGetter(this, "cpmm", function() {
-  return Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci.nsIFrameMessageManager);
-});
+XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
+                                   "@mozilla.org/childprocessmessagemanager;1",
+                                   "nsIMessageSender");
 
 function convertAppsArray(aApps, aWindow) {
   let apps = Cu.createArrayIn(aWindow);
   for (let i = 0; i < aApps.length; i++) {
     let app = aApps[i];
     apps.push(createApplicationObject(aWindow, app.origin, app.manifest, app.manifestURL, 
                                       app.receipts, app.installOrigin, app.installTime));
   }
--- a/dom/apps/src/Webapps.jsm
+++ b/dom/apps/src/Webapps.jsm
@@ -18,24 +18,23 @@ Cu.import('resource://gre/modules/Activi
 
 const WEBAPP_RUNTIME = Services.appinfo.ID == "webapprt@mozilla.org";
 
 XPCOMUtils.defineLazyGetter(this, "NetUtil", function() {
   Cu.import("resource://gre/modules/NetUtil.jsm");
   return NetUtil;
 });
 
-XPCOMUtils.defineLazyGetter(this, "ppmm", function() {
-  return Cc["@mozilla.org/parentprocessmessagemanager;1"]
-         .getService(Ci.nsIFrameMessageManager);
-});
+XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
+                                   "@mozilla.org/parentprocessmessagemanager;1",
+                                   "nsIMessageBroadcaster");
 
 XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
                                    "@mozilla.org/childprocessmessagemanager;1",
-                                   "nsIFrameMessageManager");
+                                   "nsIMessageSender");
 
 XPCOMUtils.defineLazyGetter(this, "msgmgr", function() {
   return Cc["@mozilla.org/system-message-internal;1"]
          .getService(Ci.nsISystemMessagesInternal);
 });
 
 #ifdef MOZ_WIDGET_GONK
   const DIRECTORY_NAME = "webappsDir";
@@ -238,17 +237,17 @@ let DOMApplicationRegistry = {
         break;
       case "Webapps:GetNotInstalled":
         this.getNotInstalled(msg);
         break;
       case "Webapps:GetAll":
         if (msg.hasPrivileges)
           this.getAll(msg);
         else
-          ppmm.sendAsyncMessage("Webapps:GetAll:Return:KO", msg);
+          ppmm.broadcastAsyncMessage("Webapps:GetAll:Return:KO", msg);
         break;
       case "Webapps:InstallPackage":
         this.installPackage(msg);
         break;
       case "Webapps:GetBasePath":
         return FileUtils.getFile(DIRECTORY_NAME, ["webapps"], true).path;
         break;
       case "WebApps:GetAppByManifestURL":
@@ -302,17 +301,17 @@ let DOMApplicationRegistry = {
     if (packageId) {
       let dir = FileUtils.getDir("TmpD", ["webapps", packageId],
                                  true, true);
       try {
         dir.remove(true);
       } catch(e) {
       }
     }
-    ppmm.sendAsyncMessage("Webapps:Install:Return:KO", aData);
+    ppmm.broadcastAsyncMessage("Webapps:Install:Return:KO", aData);
   },
 
   confirmInstall: function(aData, aFromSync, aProfileDir, aOfflineCacheObserver) {
     let app = aData.app;
     let id = app.syncId || this._appId(app.origin);
     let localId = this.getAppLocalIdByManifestURL(app.manifestURL);
 
     // Installing an application again is considered as an update.
@@ -360,17 +359,17 @@ let DOMApplicationRegistry = {
     this.webapps[id] = appObject;
 
     appObject.status = "installed";
     
     let manifest = new DOMApplicationManifest(app.manifest, app.origin);
 
     if (!aFromSync)
       this._saveApps((function() {
-        ppmm.sendAsyncMessage("Webapps:Install:Return:OK", aData);
+        ppmm.broadcastAsyncMessage("Webapps:Install:Return:OK", aData);
         Services.obs.notifyObservers(this, "webapps-sync-install", appNote);
       }).bind(this));
 
 #ifdef MOZ_SYS_MSG
     this._registerSystemMessages(id, app);
 #endif
 
     // if the manifest has an appcache_path property, use it to populate the appcache
@@ -487,17 +486,17 @@ let DOMApplicationRegistry = {
       return true;
     }
 
     // Removes the directory we created, and sends an error to the DOM side.
     function cleanup(aError) {
       try {
         dir.remove(true);
       } catch (e) { }
-      ppmm.sendAsyncMessage("Webapps:Install:Return:KO",
+      ppmm.broadcastAsyncMessage("Webapps:Install:Return:KO",
                             { oid: aData.oid,
                               requestID: aData.requestID,
                               error: aError });
     }
 
     NetUtil.asyncFetch(aData.url, function(aInput, aResult, aRequest) {
       if (!Components.isSuccessCode(aResult)) {
         // We failed to fetch the zip.
@@ -579,23 +578,23 @@ let DOMApplicationRegistry = {
       let dir = FileUtils.getDir(DIRECTORY_NAME, ["webapps", id], true, true);
       try {
         dir.remove(true);
       } catch (e) {}
 
       delete this.webapps[id];
 
       this._saveApps((function() {
-        ppmm.sendAsyncMessage("Webapps:Uninstall:Return:OK", aData);
+        ppmm.broadcastAsyncMessage("Webapps:Uninstall:Return:OK", aData);
         Services.obs.notifyObservers(this, "webapps-sync-uninstall", appNote);
       }).bind(this));
     }
 
     if (!found) {
-      ppmm.sendAsyncMessage("Webapps:Uninstall:Return:KO", aData);
+      ppmm.broadcastAsyncMessage("Webapps:Uninstall:Return:KO", aData);
     }
   },
 
   getSelf: function(aData) {
     aData.apps = [];
     let tmp = [];
     let id = this._appId(aData.origin);
 
@@ -603,17 +602,17 @@ let DOMApplicationRegistry = {
       let app = this._cloneAppObject(this.webapps[id]);
       aData.apps.push(app);
       tmp.push({ id: id });
     }
 
     this._readManifests(tmp, (function(aResult) {
       for (let i = 0; i < aResult.length; i++)
         aData.apps[i].manifest = aResult[i].manifest;
-      ppmm.sendAsyncMessage("Webapps:GetSelf:Return:OK", aData);
+      ppmm.broadcastAsyncMessage("Webapps:GetSelf:Return:OK", aData);
     }).bind(this));
   },
 
   getInstalled: function(aData) {
     aData.apps = [];
     let tmp = [];
 
     for (let id in this.webapps) {
@@ -622,17 +621,17 @@ let DOMApplicationRegistry = {
         aData.apps.push(this._cloneAppObject(this.webapps[id]));
         tmp.push({ id: id });
       }
     }
 
     this._readManifests(tmp, (function(aResult) {
       for (let i = 0; i < aResult.length; i++)
         aData.apps[i].manifest = aResult[i].manifest;
-      ppmm.sendAsyncMessage("Webapps:GetInstalled:Return:OK", aData);
+      ppmm.broadcastAsyncMessage("Webapps:GetInstalled:Return:OK", aData);
     }).bind(this));
   },
 
   getNotInstalled: function(aData) {
     aData.apps = [];
     let tmp = [];
 
     for (let id in this.webapps) {
@@ -640,17 +639,17 @@ let DOMApplicationRegistry = {
         aData.apps.push(this._cloneAppObject(this.webapps[id]));
         tmp.push({ id: id });
       }
     }
 
     this._readManifests(tmp, (function(aResult) {
       for (let i = 0; i < aResult.length; i++)
         aData.apps[i].manifest = aResult[i].manifest;
-      ppmm.sendAsyncMessage("Webapps:GetNotInstalled:Return:OK", aData);
+      ppmm.broadcastAsyncMessage("Webapps:GetNotInstalled:Return:OK", aData);
     }).bind(this));
   },
 
   getAll: function(aData) {
     aData.apps = [];
     let tmp = [];
 
     for (let id in this.webapps) {
@@ -660,17 +659,17 @@ let DOMApplicationRegistry = {
 
       aData.apps.push(app);
       tmp.push({ id: id });
     }
 
     this._readManifests(tmp, (function(aResult) {
       for (let i = 0; i < aResult.length; i++)
         aData.apps[i].manifest = aResult[i].manifest;
-      ppmm.sendAsyncMessage("Webapps:GetAll:Return:OK", aData);
+      ppmm.broadcastAsyncMessage("Webapps:GetAll:Return:OK", aData);
     }).bind(this));
   },
 
   getManifestFor: function(aOrigin, aCallback) {
     if (!aCallback)
       return;
 
     let id = this._appId(aOrigin);
@@ -778,25 +777,25 @@ let DOMApplicationRegistry = {
           continue;
         let origin = this.webapps[record.id].origin;
         delete this.webapps[record.id];
         let dir = FileUtils.getDir(DIRECTORY_NAME, ["webapps", record.id], true, true);
         try {
           dir.remove(true);
         } catch (e) {
         }
-        ppmm.sendAsyncMessage("Webapps:Uninstall:Return:OK", { origin: origin });
+        ppmm.broadcastAsyncMessage("Webapps:Uninstall:Return:OK", { origin: origin });
       } else {
         if (this.webapps[record.id]) {
           this.webapps[record.id] = record.value;
           delete this.webapps[record.id].manifest;
         } else {
           let data = { app: record.value };
           this.confirmInstall(data, true);
-          ppmm.sendAsyncMessage("Webapps:Install:Return:OK", data);
+          ppmm.broadcastAsyncMessage("Webapps:Install:Return:OK", data);
         }
       }
     }
     this._saveApps(aCallback);
   },
 
   getAllIDs: function() {
     let apps = {};
@@ -888,17 +887,17 @@ AppcacheObserver.prototype = {
   // nsIOfflineCacheUpdateObserver implementation
   updateStateChanged: function appObs_Update(aUpdate, aState) {
     let mustSave = false;
     let app = this.app;
 
     let setStatus = function appObs_setStatus(aStatus) {
       mustSave = (app.status != aStatus);
       app.status = aStatus;
-      ppmm.sendAsyncMessage("Webapps:OfflineCache", { manifest: app.manifestURL, status: aStatus });
+      ppmm.broadcastAsyncMessage("Webapps:OfflineCache", { manifest: app.manifestURL, status: aStatus });
     }
 
     switch (aState) {
       case Ci.nsIOfflineCacheUpdateObserver.STATE_ERROR:
         aUpdate.removeObserver(this);
         setStatus("cache-error");
         break;
       case Ci.nsIOfflineCacheUpdateObserver.STATE_NOUPDATE:
--- a/dom/base/DOMRequestHelper.jsm
+++ b/dom/base/DOMRequestHelper.jsm
@@ -10,19 +10,19 @@ const Cu = Components.utils;
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 
 let EXPORTED_SYMBOLS = ["DOMRequestIpcHelper"];
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
-XPCOMUtils.defineLazyGetter(this, "cpmm", function() {
-  return Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci.nsIFrameMessageManager);
-});
+XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
+                                   "@mozilla.org/childprocessmessagemanager;1",
+                                   "nsIMessageListenerManager");
 
 function DOMRequestIpcHelper() {
 }
 
 DOMRequestIpcHelper.prototype = {
   getRequestId: function(aRequest) {
     let id = "id" + this._getRandomId();
     this._requests[id] = aRequest;
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -456,17 +456,17 @@
 #include "nsPluginArray.h"
 #include "nsMimeTypeArray.h"
 
 // Simple gestures include
 #include "nsIDOMSimpleGestureEvent.h"
 #include "nsIDOMMozTouchEvent.h"
 
 #include "nsIEventListenerService.h"
-#include "nsIFrameMessageManager.h"
+#include "nsIMessageManager.h"
 #include "mozilla/dom/Element.h"
 #include "nsHTMLSelectElement.h"
 #include "nsHTMLLegendElement.h"
 
 #include "DOMSVGStringList.h"
 
 #include "mozilla/dom/indexedDB/IDBWrapperCache.h"
 #include "mozilla/dom/indexedDB/IDBFactory.h"
@@ -635,16 +635,18 @@ static const char kDOMStringBundleURL[] 
 #define DOMCI_DATA_NO_CLASS(_dom_class)                                       \
 const uint32_t kDOMClassInfo_##_dom_class##_interfaces =                      \
   0;
 
 DOMCI_DATA_NO_CLASS(Crypto)
 DOMCI_DATA_NO_CLASS(CRMFObject)
 DOMCI_DATA_NO_CLASS(SmartCardEvent)
 DOMCI_DATA_NO_CLASS(ContentFrameMessageManager)
+DOMCI_DATA_NO_CLASS(ChromeMessageBroadcaster)
+DOMCI_DATA_NO_CLASS(ChromeMessageSender)
 
 DOMCI_DATA_NO_CLASS(DOMPrototype)
 DOMCI_DATA_NO_CLASS(DOMConstructor)
 
 #define NS_DEFINE_CLASSINFO_DATA_WITH_NAME(_class, _name, _helper,            \
                                            _flags)                            \
   { #_name,                                                                   \
     nullptr,                                                                   \
@@ -1590,18 +1592,23 @@ static nsDOMClassInfoData sClassInfoData
   NS_DEFINE_CLASSINFO_DATA(ScrollAreaEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(EventListenerInfo, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(TransitionEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(AnimationEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(ContentFrameMessageManager, nsEventTargetSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS | nsIXPCScriptable::IS_GLOBAL_OBJECT)
+  NS_DEFINE_CHROME_ONLY_CLASSINFO_DATA(ContentFrameMessageManager, nsEventTargetSH,
+                                       DOM_DEFAULT_SCRIPTABLE_FLAGS |
+                                       nsIXPCScriptable::IS_GLOBAL_OBJECT)
+  NS_DEFINE_CHROME_ONLY_CLASSINFO_DATA(ChromeMessageBroadcaster, nsDOMGenericSH,
+                                       DOM_DEFAULT_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CHROME_ONLY_CLASSINFO_DATA(ChromeMessageSender, nsDOMGenericSH,
+                                       DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(FormData, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(DesktopNotification, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(DesktopNotificationCenter, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
@@ -4300,23 +4307,36 @@ nsDOMClassInfo::Init()
     DOM_CLASSINFO_EVENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(AnimationEvent, nsIDOMAnimationEvent)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMAnimationEvent)
     DOM_CLASSINFO_EVENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
-  DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(ContentFrameMessageManager, nsIContentFrameMessageManager)
+  DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(ContentFrameMessageManager, nsISupports)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
-    DOM_CLASSINFO_MAP_ENTRY(nsIFrameMessageManager)
+    DOM_CLASSINFO_MAP_ENTRY(nsIMessageListenerManager)
+    DOM_CLASSINFO_MAP_ENTRY(nsIMessageSender)
     DOM_CLASSINFO_MAP_ENTRY(nsISyncMessageSender)
     DOM_CLASSINFO_MAP_ENTRY(nsIContentFrameMessageManager)
   DOM_CLASSINFO_MAP_END
 
+  DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(ChromeMessageBroadcaster, nsISupports)
+    DOM_CLASSINFO_MAP_ENTRY(nsIFrameScriptLoader)
+    DOM_CLASSINFO_MAP_ENTRY(nsIMessageListenerManager)
+    DOM_CLASSINFO_MAP_ENTRY(nsIMessageBroadcaster)
+  DOM_CLASSINFO_MAP_END
+
+  DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(ChromeMessageSender, nsISupports)
+    DOM_CLASSINFO_MAP_ENTRY(nsIFrameScriptLoader)
+    DOM_CLASSINFO_MAP_ENTRY(nsIMessageListenerManager)
+    DOM_CLASSINFO_MAP_ENTRY(nsIMessageSender)
+  DOM_CLASSINFO_MAP_END
+
   DOM_CLASSINFO_MAP_BEGIN(FormData, nsIDOMFormData)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMFormData)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(DesktopNotification, nsIDOMDesktopNotification)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMDesktopNotification)
   DOM_CLASSINFO_MAP_END
 
@@ -7192,17 +7212,18 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
 
     return NS_OK;
   }
 
   // Hmm, we do an awful lot of QIs here; maybe we should add a
   // method on an interface that would let us just call into the
   // window code directly...
 
-  if (!ObjectIsNativeWrapper(cx, obj)) {
+  if (!ObjectIsNativeWrapper(cx, obj) ||
+      xpc::WrapperFactory::XrayWrapperNotShadowing(obj, id)) {
     nsCOMPtr<nsIDocShellTreeNode> dsn(do_QueryInterface(win->GetDocShell()));
 
     int32_t count = 0;
 
     if (dsn) {
       dsn->GetChildCount(&count);
     }
 
@@ -9216,17 +9237,18 @@ nsHTMLDocumentSH::NewResolve(nsIXPConnec
   // nsDocumentSH::NewResolve() we're ok, since once those properties
   // are accessed, we'll do the necessary security check.
 
   if (!(flags & JSRESOLVE_ASSIGNING)) {
     // For native wrappers, do not resolve random names on document
 
     JSAutoRequest ar(cx);
 
-    if (!ObjectIsNativeWrapper(cx, obj)) {
+    if (!ObjectIsNativeWrapper(cx, obj) ||
+        xpc::WrapperFactory::XrayWrapperNotShadowing(obj, id)) {
       nsCOMPtr<nsISupports> result;
       nsWrapperCache *cache;
       nsresult rv = ResolveImpl(cx, wrapper, id, getter_AddRefs(result),
                                 &cache);
       NS_ENSURE_SUCCESS(rv, rv);
 
       if (result) {
         JSBool ok = *_retval =
@@ -9308,33 +9330,30 @@ nsHTMLDocumentSH::NewResolve(nsIXPConnec
   return nsDocumentSH::NewResolve(wrapper, cx, obj, id, flags, objp, _retval);
 }
 
 NS_IMETHODIMP
 nsHTMLDocumentSH::GetProperty(nsIXPConnectWrappedNative *wrapper,
                               JSContext *cx, JSObject *obj, jsid id,
                               jsval *vp, bool *_retval)
 {
-  // For native wrappers, do not get random names on document
-  if (!ObjectIsNativeWrapper(cx, obj)) {
-    nsCOMPtr<nsISupports> result;
-
-    JSAutoRequest ar(cx);
-
-    nsWrapperCache *cache;
-    nsresult rv = ResolveImpl(cx, wrapper, id, getter_AddRefs(result), &cache);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    if (result) {
-      rv = WrapNative(cx, obj, result, cache, true, vp);
-      if (NS_SUCCEEDED(rv)) {
-        rv = NS_SUCCESS_I_DID_SOMETHING;
-      }
-      return rv;
-    }
+  nsCOMPtr<nsISupports> result;
+
+  JSAutoRequest ar(cx);
+
+  nsWrapperCache *cache;
+  nsresult rv = ResolveImpl(cx, wrapper, id, getter_AddRefs(result), &cache);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  if (result) {
+    rv = WrapNative(cx, obj, result, cache, true, vp);
+    if (NS_SUCCEEDED(rv)) {
+      rv = NS_SUCCESS_I_DID_SOMETHING;
+    }
+    return rv;
   }
 
   return NS_OK;
 }
 
 // HTMLFormElement helper
 
 // static
@@ -9366,17 +9385,18 @@ nsHTMLFormElementSH::FindNamedItem(nsIFo
 NS_IMETHODIMP
 nsHTMLFormElementSH::NewResolve(nsIXPConnectWrappedNative *wrapper,
                                 JSContext *cx, JSObject *obj, jsid id,
                                 uint32_t flags, JSObject **objp,
                                 bool *_retval)
 {
   // For native wrappers, do not resolve random names on form
   if ((!(JSRESOLVE_ASSIGNING & flags)) && JSID_IS_STRING(id) &&
-      !ObjectIsNativeWrapper(cx, obj)) {
+      (!ObjectIsNativeWrapper(cx, obj) ||
+       xpc::WrapperFactory::XrayWrapperNotShadowing(obj, id))) {
     nsCOMPtr<nsIForm> form(do_QueryWrappedNative(wrapper, obj));
     nsCOMPtr<nsISupports> result;
     nsWrapperCache *cache;
 
     FindNamedItem(form, id, getter_AddRefs(result), &cache);
 
     if (result) {
       JSAutoRequest ar(cx);
@@ -9397,28 +9417,26 @@ NS_IMETHODIMP
 nsHTMLFormElementSH::GetProperty(nsIXPConnectWrappedNative *wrapper,
                                  JSContext *cx, JSObject *obj, jsid id,
                                  jsval *vp, bool *_retval)
 {
   nsCOMPtr<nsIForm> form(do_QueryWrappedNative(wrapper, obj));
 
   if (JSID_IS_STRING(id)) {
     // For native wrappers, do not get random names on form
-    if (!ObjectIsNativeWrapper(cx, obj)) {
-      nsCOMPtr<nsISupports> result;
-      nsWrapperCache *cache;
-
-      FindNamedItem(form, id, getter_AddRefs(result), &cache);
-
-      if (result) {
-        // Wrap result, result can be either an element or a list of
-        // elements
-        nsresult rv = WrapNative(cx, obj, result, cache, true, vp);
-        return NS_FAILED(rv) ? rv : NS_SUCCESS_I_DID_SOMETHING;
-      }
+    nsCOMPtr<nsISupports> result;
+    nsWrapperCache *cache;
+
+    FindNamedItem(form, id, getter_AddRefs(result), &cache);
+
+    if (result) {
+      // Wrap result, result can be either an element or a list of
+      // elements
+      nsresult rv = WrapNative(cx, obj, result, cache, true, vp);
+      return NS_FAILED(rv) ? rv : NS_SUCCESS_I_DID_SOMETHING;
     }
   } else {
     int32_t n = GetArrayIndexFromId(cx, id);
 
     if (n >= 0) {
       nsIFormControl* control = form->GetElementAt(n);
 
       if (control) {
--- a/dom/base/nsDOMClassInfo.h
+++ b/dom/base/nsDOMClassInfo.h
@@ -127,16 +127,21 @@ public:
    * work. In order to allow scriptable helpers to define non-IDL defined but
    * still "safe" properties for Xray wrappers, we call into the scriptable
    * helper with |obj| being the wrapper.
    *
    * Ideally, that would be the end of the story, however due to complications
    * dealing with document.domain, it's possible to end up in a scriptable
    * helper with a wrapper, even though we should be treating the lookup as a
    * transparent one.
+   *
+   * Note: So ObjectIsNativeWrapper(cx, obj) check usually means "through xray
+   * wrapper this part is not visible" while combined with
+   * || xpc::WrapperFactory::XrayWrapperNotShadowing(obj) it means "through
+   * xray wrapper it is visible only if it does not hide any native property."
    */
   static bool ObjectIsNativeWrapper(JSContext* cx, JSObject* obj);
 
   static nsISupports *GetNative(nsIXPConnectWrappedNative *wrapper, JSObject *obj);
 
   static nsIXPConnect *XPConnect()
   {
     return sXPConnect;
--- a/dom/base/nsDOMClassInfoClasses.h
+++ b/dom/base/nsDOMClassInfoClasses.h
@@ -470,16 +470,18 @@ DOMCI_CLASS(PaintRequestList)
 DOMCI_CLASS(ScrollAreaEvent)
 
 DOMCI_CLASS(EventListenerInfo)
 
 DOMCI_CLASS(TransitionEvent)
 DOMCI_CLASS(AnimationEvent)
 
 DOMCI_CLASS(ContentFrameMessageManager)
+DOMCI_CLASS(ChromeMessageBroadcaster)
+DOMCI_CLASS(ChromeMessageSender)
 
 DOMCI_CLASS(FormData)
 
 DOMCI_CLASS(DesktopNotification)
 DOMCI_CLASS(DesktopNotificationCenter)
 
 // WebSocket
 DOMCI_CLASS(WebSocket)
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -10952,34 +10952,37 @@ nsGlobalChromeWindow::NotifyDefaultButto
     return NS_OK;
   return rv;
 #else
   return NS_ERROR_NOT_IMPLEMENTED;
 #endif
 }
 
 NS_IMETHODIMP
-nsGlobalChromeWindow::GetMessageManager(nsIChromeFrameMessageManager** aManager)
+nsGlobalChromeWindow::GetMessageManager(nsIMessageBroadcaster** aManager)
 {
   FORWARD_TO_INNER_CHROME(GetMessageManager, (aManager), NS_ERROR_FAILURE);
   if (!mMessageManager) {
     nsIScriptContext* scx = GetContextInternal();
     NS_ENSURE_STATE(scx);
     JSContext* cx = scx->GetNativeContext();
     NS_ENSURE_STATE(cx);
-    nsCOMPtr<nsIChromeFrameMessageManager> globalMM =
+    nsCOMPtr<nsIMessageBroadcaster> globalMM =
       do_GetService("@mozilla.org/globalmessagemanager;1");
     mMessageManager =
-      new nsFrameMessageManager(true,
+      new nsFrameMessageManager(true, /* aChrome */
                                 nullptr,
                                 nullptr,
                                 nullptr,
                                 nullptr,
                                 static_cast<nsFrameMessageManager*>(globalMM.get()),
-                                cx);
+                                cx,
+                                false, /* aGlobal */
+                                false, /* aProcessManager */
+                                true /* aBroadcaster */);
     NS_ENSURE_TRUE(mMessageManager, NS_ERROR_OUT_OF_MEMORY);
   }
   CallQueryInterface(mMessageManager, aManager);
   return NS_OK;
 }
 
 // nsGlobalModalWindow implementation
 
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -1130,17 +1130,17 @@ public:
 
     mCleanMessageManager = false;
   }
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsGlobalChromeWindow,
                                            nsGlobalWindow)
 
   nsCOMPtr<nsIBrowserDOMWindow> mBrowserDOMWindow;
-  nsCOMPtr<nsIChromeFrameMessageManager> mMessageManager;
+  nsCOMPtr<nsIMessageBroadcaster> mMessageManager;
 };
 
 /*
  * nsGlobalModalWindow inherits from nsGlobalWindow. It is the global
  * object created for a modal content windows only (i.e. not modal
  * chrome dialogs).
  */
 class nsGlobalModalWindow : public nsGlobalWindow,
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -1288,25 +1288,23 @@ nsJSContext::EvaluateStringWithValue(con
   // check it isn't JSVERSION_UNKNOWN.
   if (ok && ((JSVersion)aVersion) != JSVERSION_UNKNOWN) {
 
     XPCAutoRequest ar(mContext);
     JSAutoCompartment ac(mContext, aScopeObject);
 
     ++mExecuteDepth;
 
-    ok = ::JS_EvaluateUCScriptForPrincipalsVersion(mContext,
-                                                   aScopeObject,
-                                                   nsJSPrincipals::get(principal),
-                                                   static_cast<const jschar*>(PromiseFlatString(aScript).get()),
-                                                   aScript.Length(),
-                                                   aURL,
-                                                   aLineNo,
-                                                   &val,
-                                                   JSVersion(aVersion));
+    JS::CompileOptions options(mContext);
+    options.setFileAndLine(aURL, aLineNo)
+           .setVersion(JSVersion(aVersion))
+           .setPrincipals(nsJSPrincipals::get(principal));
+    JS::RootedObject rootedScope(mContext, aScopeObject);
+    ok = JS::Evaluate(mContext, rootedScope, options, PromiseFlatString(aScript).get(),
+                      aScript.Length(), &val);
 
     --mExecuteDepth;
 
     if (!ok) {
       // Tell XPConnect about any pending exceptions. This is needed
       // to avoid dropping JS exceptions in case we got here through
       // nested calls through XPConnect.
 
@@ -1485,21 +1483,25 @@ nsJSContext::EvaluateString(const nsAStr
 
   // SecurityManager said "ok", but don't compile if aVersion is unknown.
   // Since the caller is responsible for parsing the version strings, we just
   // check it isn't JSVERSION_UNKNOWN.
   if (ok && JSVersion(aVersion) != JSVERSION_UNKNOWN) {
     XPCAutoRequest ar(mContext);
     JSAutoCompartment ac(mContext, aScopeObject);
 
-    ok = JS_EvaluateUCScriptForPrincipalsVersionOrigin(
-      mContext, aScopeObject,
-      nsJSPrincipals::get(principal), nsJSPrincipals::get(aOriginPrincipal),
-      static_cast<const jschar*>(PromiseFlatString(aScript).get()),
-      aScript.Length(), aURL, aLineNo, vp, JSVersion(aVersion));
+    JS::RootedObject rootedScope(mContext, aScopeObject);
+    JS::CompileOptions options(mContext);
+    options.setFileAndLine(aURL, aLineNo)
+           .setPrincipals(nsJSPrincipals::get(principal))
+           .setOriginPrincipals(nsJSPrincipals::get(aOriginPrincipal))
+           .setVersion(JSVersion(aVersion));
+    ok = JS::Evaluate(mContext, rootedScope, options,
+                      PromiseFlatString(aScript).get(),
+                      aScript.Length(), vp);
 
     if (!ok) {
       // Tell XPConnect about any pending exceptions. This is needed
       // to avoid dropping JS exceptions in case we got here through
       // nested calls through XPConnect.
 
       ReportPendingException();
     }
@@ -1746,27 +1748,26 @@ nsJSContext::CompileEventHandler(nsIAtom
   }
 
 #ifdef DEBUG
   JSContext* top = nsContentUtils::GetCurrentJSContext();
   NS_ASSERTION(mContext == top, "Context not properly pushed!");
 #endif
 
   // Event handlers are always shared, and must be bound before use.
-  // Therefore we never bother compiling with principals.
-  // (that probably means we should avoid JS_CompileUCFunctionForPrincipals!)
+  // Therefore we don't bother compiling with principals.
   XPCAutoRequest ar(mContext);
 
-  JSFunction* fun =
-      ::JS_CompileUCFunctionForPrincipalsVersion(mContext,
-                                                 nullptr, nullptr,
-                                                 nsAtomCString(aName).get(), aArgCount, aArgNames,
-                                                 (jschar*)PromiseFlatString(aBody).get(),
-                                                 aBody.Length(),
-                                                 aURL, aLineNo, JSVersion(aVersion));
+  JS::CompileOptions options(mContext);
+  options.setVersion(JSVersion(aVersion))
+         .setFileAndLine(aURL, aLineNo);
+  JS::RootedObject empty(mContext, NULL);
+  JSFunction* fun = JS::CompileFunction(mContext, empty, options, nsAtomCString(aName).get(),
+                                        aArgCount, aArgNames,
+                                        PromiseFlatString(aBody).get(), aBody.Length());
 
   if (!fun) {
     ReportPendingException();
     return NS_ERROR_ILLEGAL_VALUE;
   }
 
   JSObject *handler = ::JS_GetFunctionObject(fun);
   return aHandler.set(handler);
@@ -1809,30 +1810,28 @@ nsJSContext::CompileFunction(JSObject* a
     nsCOMPtr<nsIScriptObjectPrincipal> globalData = do_QueryInterface(global);
     if (globalData) {
       principal = globalData->GetPrincipal();
       if (!principal)
         return NS_ERROR_FAILURE;
     }
   }
 
-  JSObject *target = aTarget;
+  JS::RootedObject target(mContext, aShared ? NULL : aTarget);
 
   XPCAutoRequest ar(mContext);
 
-  JSFunction* fun =
-      ::JS_CompileUCFunctionForPrincipalsVersion(mContext,
-                                                 aShared ? nullptr : target,
-                                                 nsJSPrincipals::get(principal),
-                                                 PromiseFlatCString(aName).get(),
-                                                 aArgCount, aArgArray,
-                                                 static_cast<const jschar*>(PromiseFlatString(aBody).get()),
-                                                 aBody.Length(),
-                                                 aURL, aLineNo,
-                                                 JSVersion(aVersion));
+  JS::CompileOptions options(mContext);
+  options.setPrincipals(nsJSPrincipals::get(principal))
+         .setVersion(JSVersion(aVersion))
+         .setFileAndLine(aURL, aLineNo);
+  JSFunction* fun = JS::CompileFunction(mContext, target,
+                                        options, PromiseFlatCString(aName).get(),
+                                        aArgCount, aArgArray,
+                                        PromiseFlatString(aBody).get(), aBody.Length());
 
   if (!fun)
     return NS_ERROR_FAILURE;
 
   *aFunctionObject = JS_GetFunctionObject(fun);
   return NS_OK;
 }
 
--- a/dom/contacts/ContactManager.js
+++ b/dom/contacts/ContactManager.js
@@ -14,19 +14,19 @@ const Cu = Components.utils;
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
 
 XPCOMUtils.defineLazyGetter(Services, "DOMRequest", function() {
   return Cc["@mozilla.org/dom/dom-request-service;1"].getService(Ci.nsIDOMRequestService);
 });
 
-XPCOMUtils.defineLazyGetter(this, "cpmm", function() {
-  return Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci.nsIFrameMessageManager);
-});
+XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
+                                   "@mozilla.org/childprocessmessagemanager;1",
+                                   "nsIMessageSender");
 
 XPCOMUtils.defineLazyGetter(this, "mRIL", function () {
   return Cc["@mozilla.org/telephony/system-worker-manager;1"].getService(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIRadioInterfaceLayer);
 });
 
 const nsIClassInfo            = Ci.nsIClassInfo;
 const CONTACTPROPERTIES_CID   = Components.ID("{f5181640-89e8-11e1-b0c4-0800200c9a66}");
 const nsIDOMContactProperties = Ci.nsIDOMContactProperties;
--- a/dom/contacts/fallback/ContactService.jsm
+++ b/dom/contacts/fallback/ContactService.jsm
@@ -12,19 +12,19 @@ const Cc = Components.classes;
 const Ci = Components.interfaces;
 
 let EXPORTED_SYMBOLS = ["DOMContactManager"];
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/ContactDB.jsm");
 
-XPCOMUtils.defineLazyGetter(this, "ppmm", function() {
-  return Cc["@mozilla.org/parentprocessmessagemanager;1"].getService(Ci.nsIFrameMessageManager);
-});
+XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
+                                   "@mozilla.org/parentprocessmessagemanager;1",
+                                   "nsIMessageListenerManager");
 
 let myGlobal = this;
 
 let DOMContactManager = {
   init: function() {
     if (DEBUG) debug("Init");
     this._messages = ["Contacts:Find", "Contacts:Clear", "Contact:Save", "Contact:Remove"];
     this._messages.forEach((function(msgName) {
@@ -49,17 +49,17 @@ let DOMContactManager = {
     this._messages = null;
     if (this._db)
       this._db.close();
     this._db = null;
   },
 
   receiveMessage: function(aMessage) {
     if (DEBUG) debug("Fallback DOMContactManager::receiveMessage " + aMessage.name);
-    let mm = aMessage.target.QueryInterface(Ci.nsIFrameMessageManager);
+    let mm = aMessage.target;
     let msg = aMessage.data;
 
     /*
      * Sorting the contacts by sortBy field. sortBy can either be familyName or givenName.
      * If 2 entries have the same sortyBy field or no sortBy field is present, we continue 
      * sorting with the other sortyBy field.
      */
     function sortfunction(a, b){
--- a/dom/devicestorage/ipc/test_ipc.html
+++ b/dom/devicestorage/ipc/test_ipc.html
@@ -95,17 +95,17 @@
         iframe.addEventListener("mozbrowserloadend", iframeLoadSecond);
 
         let mm = SpecialPowers.getBrowserFrameMessageManager(iframe);
 
         let comp = SpecialPowers.wrap(Components);
 
         let spObserver =
           comp.classes["@mozilla.org/special-powers-observer;1"]
-              .getService(comp.interfaces.nsIFrameMessageListener);
+              .getService(comp.interfaces.nsIMessageListener);
 
         mm.addMessageListener("SPPrefService", spObserver);
         mm.addMessageListener("SPProcessCrashService", spObserver);
         mm.addMessageListener("SPPingService", spObserver);
         mm.addMessageListener("SpecialPowers.Quit", spObserver);
         mm.addMessageListener("SPPermissionManager", spObserver);
 
         mm.addMessageListener("test:DeviceStorage:ipcTestMessage", onTestMessage);
--- a/dom/identity/DOMIdentity.jsm
+++ b/dom/identity/DOMIdentity.jsm
@@ -111,17 +111,17 @@ RPWatchContext.prototype = {
   },
 
   doError: function RPWatchContext_onerror(aMessage) {
     log("doError: " + aMessage);
   }
 };
 
 let DOMIdentity = {
-  // nsIFrameMessageListener
+  // nsIMessageListener
   receiveMessage: function DOMIdentity_receiveMessage(aMessage) {
     let msg = aMessage.json;
 
     // Target is the frame message manager that called us and is
     // used to send replies back to the proper window.
     let targetMM = aMessage.target
                            .QueryInterface(Ci.nsIFrameLoaderOwner)
                            .frameLoader.messageManager;
@@ -195,17 +195,17 @@ let DOMIdentity = {
   _configureMessages: function DOMIdentity__configureMessages(aWindow, aRegister) {
     if (!aWindow.messageManager)
       return;
 
     let func = aWindow.messageManager[aRegister ? "addMessageListener"
                                                 : "removeMessageListener"];
 
     for (let message of this.messages) {
-      func(message, this);
+      func.call(aWindow.messageManager, message, this);
     }
   },
 
   _resetFrameState: function(aContext) {
     log("_resetFrameState: ", aContext.id);
     if (!aContext._mm) {
       throw new Error("ERROR: Trying to reset an invalid context");
     }
--- a/dom/identity/nsDOMIdentity.js
+++ b/dom/identity/nsDOMIdentity.js
@@ -415,17 +415,17 @@ nsDOMIdentity.prototype = {
 
 /**
  * Internal functions that shouldn't be exposed to content.
  */
 function nsDOMIdentityInternal() {
 }
 nsDOMIdentityInternal.prototype = {
 
-  // nsIFrameMessageListener
+  // nsIMessageListener
   receiveMessage: function nsDOMIdentityInternal_receiveMessage(aMessage) {
     let msg = aMessage.json;
     // Is this message intended for this window?
     if (msg.id != this._id) {
       return;
     }
     this._identity._receiveMessage(aMessage);
   },
@@ -510,17 +510,17 @@ nsDOMIdentityInternal.prototype = {
     }
     dump("nsDOMIdentity (" + this._id + "): " + msg + "\n");
   },
 
   // Component setup.
   classID: Components.ID("{8bcac6a3-56a4-43a4-a44c-cdf42763002f}"),
 
   QueryInterface: XPCOMUtils.generateQI(
-    [Ci.nsIDOMGlobalPropertyInitializer, Ci.nsIFrameMessageListener]
+    [Ci.nsIDOMGlobalPropertyInitializer, Ci.nsIMessageListener]
   ),
 
   classInfo: XPCOMUtils.generateCI({
     classID: Components.ID("{8bcac6a3-56a4-43a4-a44c-cdf42763002f}"),
     contractID: "@mozilla.org/dom/identity;1",
     interfaces: [],
     classDescription: "Identity DOM Implementation"
   })
--- a/dom/indexedDB/ipc/test_ipc.html
+++ b/dom/indexedDB/ipc/test_ipc.html
@@ -109,17 +109,17 @@
         iframe.addEventListener("mozbrowserloadend", iframeLoadSecond);
 
         let mm = SpecialPowers.getBrowserFrameMessageManager(iframe);
 
         let comp = SpecialPowers.wrap(Components);
 
         let spObserver =
           comp.classes["@mozilla.org/special-powers-observer;1"]
-              .getService(comp.interfaces.nsIFrameMessageListener);
+              .getService(comp.interfaces.nsIMessageListener);
 
         mm.addMessageListener("SPPrefService", spObserver);
         mm.addMessageListener("SPProcessCrashService", spObserver);
         mm.addMessageListener("SPPingService", spObserver);
         mm.addMessageListener("SpecialPowers.Quit", spObserver);
         mm.addMessageListener("SPPermissionManager", spObserver);
 
         mm.addMessageListener("test:indexedDB:ipcTestMessage", onTestMessage);
--- a/dom/interfaces/base/nsIDOMChromeWindow.idl
+++ b/dom/interfaces/base/nsIDOMChromeWindow.idl
@@ -3,19 +3,19 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "domstubs.idl"
 
 interface nsIBrowserDOMWindow;
 interface nsIDOMElement;
 interface nsIDOMEvent;
-interface nsIChromeFrameMessageManager;
+interface nsIMessageBroadcaster;
 
-[scriptable, uuid(7cfbc355-cbf9-4408-8e4c-a3c603ff1428)]
+[scriptable, uuid(6ff5df67-22da-4379-bf57-da775dad19f8)]
 interface nsIDOMChromeWindow : nsISupports
 {
   const unsigned short STATE_MAXIMIZED = 1;
   const unsigned short STATE_MINIMIZED = 2;
   const unsigned short STATE_NORMAL = 3;
   const unsigned short STATE_FULLSCREEN = 4;
 
   readonly attribute unsigned short              windowState;
@@ -38,17 +38,17 @@ interface nsIDOMChromeWindow : nsISuppor
   void                      restore();
 
   /**
    * Notify a default button is loaded on a dialog or a wizard.
    * defaultButton is the default button.
    */
   void notifyDefaultButtonLoaded(in nsIDOMElement defaultButton);
 
-  readonly attribute nsIChromeFrameMessageManager messageManager;
+  readonly attribute nsIMessageBroadcaster messageManager;
 
   /**
    * On some operating systems, we must allow the window manager to
    * handle window dragging. This function tells the window manager to
    * start dragging the window. This function will fail unless called
    * while the left mouse button is held down, callers must check this.
    *
    * The optional panel argument should be set when moving a panel.
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -1367,17 +1367,17 @@ TabChildGlobal::TabChildGlobal(TabChild*
 : mTabChild(aTabChild)
 {
 }
 
 void
 TabChildGlobal::Init()
 {
   NS_ASSERTION(!mMessageManager, "Re-initializing?!?");
-  mMessageManager = new nsFrameMessageManager(false,
+  mMessageManager = new nsFrameMessageManager(false, /* aChrome */
                                               SendSyncMessageToParent,
                                               SendAsyncMessageToParent,
                                               nullptr,
                                               mTabChild,
                                               nullptr,
                                               mTabChild->GetJSContext());
 }
 
@@ -1389,17 +1389,18 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_IN
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(TabChildGlobal,
                                                   nsDOMEventTargetHelper)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mMessageManager)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TabChildGlobal)
-  NS_INTERFACE_MAP_ENTRY(nsIFrameMessageManager)
+  NS_INTERFACE_MAP_ENTRY(nsIMessageListenerManager)
+  NS_INTERFACE_MAP_ENTRY(nsIMessageSender)
   NS_INTERFACE_MAP_ENTRY(nsISyncMessageSender)
   NS_INTERFACE_MAP_ENTRY(nsIContentFrameMessageManager)
   NS_INTERFACE_MAP_ENTRY(nsIScriptContextPrincipal)
   NS_INTERFACE_MAP_ENTRY(nsIScriptObjectPrincipal)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(ContentFrameMessageManager)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
 
 NS_IMPL_ADDREF_INHERITED(TabChildGlobal, nsDOMEventTargetHelper)
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -67,17 +67,18 @@ class TabChildGlobal : public nsDOMEvent
                        public nsIScriptObjectPrincipal,
                        public nsIScriptContextPrincipal
 {
 public:
   TabChildGlobal(TabChild* aTabChild);
   void Init();
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(TabChildGlobal, nsDOMEventTargetHelper)
-  NS_FORWARD_SAFE_NSIFRAMEMESSAGEMANAGER(mMessageManager)
+  NS_FORWARD_SAFE_NSIMESSAGELISTENERMANAGER(mMessageManager)
+  NS_FORWARD_SAFE_NSIMESSAGESENDER(mMessageManager)
   NS_IMETHOD SendSyncMessage(const nsAString& aMessageName,
                              const jsval& aObject,
                              JSContext* aCx,
                              uint8_t aArgc,
                              jsval* aRetval)
   {
     return mMessageManager
       ? mMessageManager->SendSyncMessage(aMessageName, aObject, aCx, aArgc, aRetval)
--- a/dom/ipc/test.xul
+++ b/dom/ipc/test.xul
@@ -92,27 +92,26 @@
     function closeWindow() {
       window.close();
     }
 
     function initRemoteFrameScript() {
       // 1. Test that loading a script works, and that accessing process level mm and
       //     global mm works.
       var ppm = Components.classes["@mozilla.org/parentprocessmessagemanager;1"]
-                          .getService(Components.interfaces.nsIFrameMessageManager);
+                          .getService(Components.interfaces.nsIMessageBroadcaster);
       var gm = Components.classes["@mozilla.org/globalmessagemanager;1"]
-                         .getService(Components.interfaces.nsIChromeFrameMessageManager);
+                         .getService(Components.interfaces.nsIMessageBroadcaster);
       var cpm = Components.classes["@mozilla.org/childprocessmessagemanager;1"]
-                            .getService(Components.interfaces.nsISyncMessageSender);  
+                            .getService(Components.interfaces.nsISyncMessageSender);
 
-      var tppm = ppm.QueryInterface(Components.interfaces.nsITreeItemFrameMessageManager);
-      if (tppm.childCount != 2) {
+      if (ppm.childCount != 2) {
         alert("Should have two child processes!");
       }
-      var childprocessmm = tppm.getChildAt(1); // 0 is the in-process child process mm
+      var childprocessmm = ppm.getChildAt(1); // 0 is the in-process child process mm
       
       childprocessmm.addMessageListener("ppm-sync",
         function(m) {
           if (m.target != childprocessmm) alert("Wrong target!");
           document.getElementById("messageLog").value += "[SYNC1 PPM]"; 
         }
       );
       
@@ -156,17 +155,17 @@
       // 4. Test that receiving an async message works.
       //    Test also that sending async message to content works.
       //    Test also that { receiveMessage: function(m) {} } works.
       messageManager.addMessageListener("linkclick-reply-object",
         { foobarObjectVar: true,
           receiveMessage: function(m) {
             var s = (m.json.message == "linkclick-received") &amp;&amp;
                     (this.foobarObjectVar) ? "PASS" : "FAIL";
-            messageManager.sendAsyncMessage("chrome-message", { ok : s } );
+            messageManager.broadcastAsyncMessage("chrome-message", { ok : s } );
           }
         }
         );
 
       // 5. Final test to check that everything went ok.
       messageManager.addMessageListener("chrome-message-reply",
         function(m) {
           // Check that 'this' and .target values are handled correctly
@@ -192,17 +191,17 @@
         });
     }
 
     var speedTestStartTime = 0;
     var speedTestCount = 0;
     function messageSpeed() {
       speedTestCount = 0;
       messageManager.addMessageListener("speed-test", speedHandler);
-      messageManager.sendAsyncMessage("speed-test-start");
+      messageManager.broadcastAsyncMessage("speed-test-start");
     }
 
     function speedHandler() {
       if (!speedTestCount) {
         speedTestStartTime = new Date().getTime();
       }
       if (++speedTestCount == 1000) {
         setTimeout("alert('" + speedTestCount + " in "  + (new Date().getTime() - speedTestStartTime) +  "ms')", 0);
@@ -212,26 +211,26 @@
     }
 
     var addRemoveTestCount = 0;
 
     function echoListener() {
       if (++addRemoveTestCount == 1) {
         alert("Expected echo message");
         messageManager.removeMessageListener("async-echo", echoListener);
-        messageManager.sendAsyncMessage("async-echo");
+        messageManager.broadcastAsyncMessage("async-echo");
         return;
       }
       alert("Unexpected echo message");
     }
 
     function listenerAddRemove() {
       addRemoveTestCount = 0;
       messageManager.addMessageListener("async-echo", echoListener);
-      messageManager.sendAsyncMessage("async-echo");
+      messageManager.broadcastAsyncMessage("async-echo");
     }
 
     var MozAfterPaintCount = 0;
     function enableMozAfterPaint() {
       messageManager.addMessageListener("MozAfterPaint",
         function(m) {
           document.getElementById("messageLog").value = m.name + "[" + (++MozAfterPaintCount) + "]";
         });
@@ -281,18 +280,20 @@
     <toolbarbutton onclick="messageSpeed()" label="test message handling speed"/>
     <toolbarbutton onclick="listenerAddRemove()" label="test listener add/remove"/>
     <toolbarbutton onclick="enableMozAfterPaint()" label="MozAfterPaint"/>
     <toolbarbutton onclick="openWindow()" label="open new window"/>
     <toolbarbutton onclick="closeWindow()" label="close this window"/>
   </toolbar>
   <toolbar><label value="Load a script (URL) to content process:"/>
     <textbox flex="1" id="script"/><button
-      label="send" oncommand="document.getElementById('page').QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader.
-                              messageManager.loadFrameScript(this.previousSibling.value, false);"/>
+      label="send" oncommand="document.getElementById('page')
+                                      .QueryInterface(Components.interfaces.nsIFrameLoaderOwner)
+                                      .frameLoader.messageManager
+                                      .loadFrameScript(this.previousSibling.value, false);"/>
   </toolbar>
   <toolbar>
     <label value="Eval script in chrome context"/>
     <textbox flex="1"/><button label="run" oncommand="eval(this.previousSibling.value);"/>
   </toolbar>
   <toolbar>
     <checkbox label="allow dialogs from remote content"
                oncommand="document.getElementById('page').QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader.delayRemoteDialogs = this.checked;"/>
--- a/dom/ipc/tests/process_error.xul
+++ b/dom/ipc/tests/process_error.xul
@@ -44,14 +44,15 @@
         removeFile(minidumpDirectory, dumpID + '.extra');
       }
 
       Services.obs.removeObserver(crashObserver, 'ipc:content-shutdown');
       done();
     }
     Services.obs.addObserver(crashObserver, 'ipc:content-shutdown', false);
 
-    document.getElementById('thebrowser').
-      QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader.
-      messageManager.loadFrameScript('chrome://mochitests/content/chrome/dom/ipc/tests/process_error_contentscript.js', true);
+    document.getElementById('thebrowser')
+            .QueryInterface(Components.interfaces.nsIFrameLoaderOwner)
+            .frameLoader.messageManager
+            .loadFrameScript('chrome://mochitests/content/chrome/dom/ipc/tests/process_error_contentscript.js', true);
   ]]></script>
 
 </window>
--- a/dom/messages/SystemMessageInternal.js
+++ b/dom/messages/SystemMessageInternal.js
@@ -7,19 +7,19 @@
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 const Cr = Components.results;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
-XPCOMUtils.defineLazyGetter(this, "ppmm", function() {
-  return Cc["@mozilla.org/parentprocessmessagemanager;1"].getService(Ci.nsIFrameMessageManager);
-});
+XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
+                                   "@mozilla.org/parentprocessmessagemanager;1",
+                                   "nsIMessageBroadcaster");
 
 // Limit the number of pending messages for a given page.
 let kMaxPendingMessages;
 try {
   kMaxPendingMessages = Services.prefs.getIntPref("dom.messages.maxPendingMessages");
 } catch(e) {
   // getIntPref throws when the pref is not set.
   kMaxPendingMessages = 5;
@@ -37,19 +37,19 @@ function SystemMessageInternal() {
   this._pages = [];
   Services.obs.addObserver(this, "xpcom-shutdown", false);
   ppmm.addMessageListener("SystemMessageManager:GetPending", this);
 }
 
 SystemMessageInternal.prototype = {
   sendMessage: function sendMessage(aType, aMessage, aPageURI, aManifestURI) {
     debug("Broadcasting " + aType + " " + JSON.stringify(aMessage));
-    ppmm.sendAsyncMessage("SystemMessageManager:Message" , { type: aType,
-                                                             msg: aMessage,
-                                                             manifest: aManifestURI.spec });
+    ppmm.broadcastAsyncMessage("SystemMessageManager:Message" , { type: aType,
+                                                                  msg: aMessage,
+                                                                  manifest: aManifestURI.spec });
 
     // Queue the message for pages that registered an handler for this type.
     this._pages.forEach(function sendMess_openPage(aPage) {
       if (aPage.type != aType ||
           aPage.manifest != aManifestURI.spec ||
           aPage.uri != aPageURI.spec) {
         return;
       }
--- a/dom/messages/SystemMessageManager.js
+++ b/dom/messages/SystemMessageManager.js
@@ -8,21 +8,19 @@ const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/ObjectWrapper.jsm");
 
-XPCOMUtils.defineLazyGetter(this, "cpmm", function() {
-  return Cc["@mozilla.org/childprocessmessagemanager;1"]
-         .getService(Ci.nsIFrameMessageManager)
-         .QueryInterface(Ci.nsISyncMessageSender);
-});
+XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
+                                   "@mozilla.org/childprocessmessagemanager;1",
+                                   "nsISyncMessageSender");
 
 // Limit the number of pending messages for a given type.
 let kMaxPendingMessages;
 try {
   kMaxPendingMessages = Services.prefs.getIntPref("dom.messages.maxPendingMessages");
 } catch(e) {
   // getIntPref throws when the pref is not set.
   kMaxPendingMessages = 5;
--- a/dom/permission/PermissionPromptHelper.jsm
+++ b/dom/permission/PermissionPromptHelper.jsm
@@ -29,19 +29,19 @@ const Cu = Components.utils;
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 
 let EXPORTED_SYMBOLS = ["PermissionPromptHelper"];
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
-XPCOMUtils.defineLazyGetter(this, "ppmm", function() {
-  return Cc["@mozilla.org/parentprocessmessagemanager;1"].getService(Ci.nsIFrameMessageManager);
-});
+XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
+                                   "@mozilla.org/parentprocessmessagemanager;1",
+                                   "nsIMessageListenerManager");
 
 var permissionManager = Cc["@mozilla.org/permissionmanager;1"].getService(Ci.nsIPermissionManager);
 var secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptSecurityManager);
 var appsService = Cc["@mozilla.org/AppsService;1"].getService(Ci.nsIAppsService);
 
 let PermissionPromptHelper = {
   init: function() {
     debug("Init");
@@ -72,17 +72,17 @@ let PermissionPromptHelper = {
   observe: function(aSubject, aTopic, aData) {
     ppmm.removeMessageListener("PermissionPromptHelper:AskPermission", this);
     Services.obs.removeObserver(this, "profile-before-change");
     ppmm = null;
   },
 
   receiveMessage: function(aMessage) {
     debug("PermissionPromptHelper::receiveMessage " + aMessage.name);
-    let mm = aMessage.target.QueryInterface(Ci.nsIFrameMessageManager);
+    let mm = aMessage.target;
     let msg = aMessage.data;
 
     let result;
     if (aMessage.name == "PermissionPromptHelper:AskPermission") {
       this.askPermission(aMessage, {
         cancel: function() {
           mm.sendAsyncMessage("PermissionPromptHelper:AskPermission:OK", {result: Ci.nsIPermissionManager.DENY_ACTION, requestID: msg.requestID});
         },
--- a/dom/settings/SettingsChangeNotifier.jsm
+++ b/dom/settings/SettingsChangeNotifier.jsm
@@ -12,19 +12,19 @@ const Cu = Components.utils;
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 
 let EXPORTED_SYMBOLS = ["SettingsChangeNotifier"];
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
-XPCOMUtils.defineLazyGetter(this, "ppmm", function() {
-  return Cc["@mozilla.org/parentprocessmessagemanager;1"].getService(Ci.nsIFrameMessageManager);
-});
+XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
+                                   "@mozilla.org/parentprocessmessagemanager;1",
+                                   "nsIMessageBroadcaster");
 
 
 let SettingsChangeNotifier = {
   init: function() {
     debug("init");
     ppmm.addMessageListener("Settings:Changed", this);
     Services.obs.addObserver(this, "xpcom-shutdown", false);
   },
@@ -36,17 +36,17 @@ let SettingsChangeNotifier = {
     ppmm = null;
   },
 
   receiveMessage: function(aMessage) {
     debug("receiveMessage");
     let msg = aMessage.json;
     switch (aMessage.name) {
       case "Settings:Changed":
-        ppmm.sendAsyncMessage("Settings:Change:Return:OK", { key: msg.key, value: msg.value });
+        ppmm.broadcastAsyncMessage("Settings:Change:Return:OK", { key: msg.key, value: msg.value });
         Services.obs.notifyObservers(this, "mozsettings-changed", JSON.stringify({
           key: msg.key,
           value: msg.value
         }));
         break;
       default: 
         debug("Wrong message: " + aMessage.name);
     }
--- a/dom/settings/SettingsManager.js
+++ b/dom/settings/SettingsManager.js
@@ -12,19 +12,19 @@ const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 
 Cu.import("resource://gre/modules/SettingsQueue.jsm");
 Cu.import("resource://gre/modules/SettingsDB.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
-XPCOMUtils.defineLazyGetter(this, "cpmm", function() {
-  return Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci.nsIFrameMessageManager);
-});
+XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
+                                   "@mozilla.org/childprocessmessagemanager;1",
+                                   "nsIMessageSender");
 
 const nsIClassInfo            = Ci.nsIClassInfo;
 const SETTINGSLOCK_CONTRACTID = "@mozilla.org/settingsLock;1";
 const SETTINGSLOCK_CID        = Components.ID("{ef95ddd0-6308-11e1-b86c-0800200c9a66}");
 const nsIDOMSettingsLock      = Ci.nsIDOMSettingsLock;
 
 function SettingsLock(aSettingsManager)
 {
--- a/dom/system/gonk/RILContentHelper.js
+++ b/dom/system/gonk/RILContentHelper.js
@@ -61,17 +61,17 @@ const RIL_IPC_MSG_NAMES = [
 
 const kVoiceChangedTopic     = "mobile-connection-voice-changed";
 const kDataChangedTopic      = "mobile-connection-data-changed";
 const kCardStateChangedTopic = "mobile-connection-cardstate-changed";
 const kUssdReceivedTopic     = "mobile-connection-ussd-received";
 
 XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
                                    "@mozilla.org/childprocessmessagemanager;1",
-                                   "nsIFrameMessageManager");
+                                   "nsISyncMessageSender");
 
 XPCOMUtils.defineLazyServiceGetter(this, "gUUIDGenerator",
                                    "@mozilla.org/uuid-generator;1",
                                    "nsIUUIDGenerator");
 
 function MobileConnectionInfo() {}
 MobileConnectionInfo.prototype = {
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMMozMobileConnectionInfo]),
@@ -156,18 +156,17 @@ function RILContentHelper() {
   this.voiceConnectionInfo = new MobileConnectionInfo();
   this.dataConnectionInfo = new MobileConnectionInfo();
 
   this.initRequests();
   this.initMessageListener(RIL_IPC_MSG_NAMES);
   Services.obs.addObserver(this, "xpcom-shutdown", false);
 
   // Request initial context.
-  let rilContext = cpmm.QueryInterface(Ci.nsISyncMessageSender)
-                       .sendSyncMessage("RIL:GetRilContext")[0];
+  let rilContext = cpmm.sendSyncMessage("RIL:GetRilContext")[0];
 
   if (!rilContext) {
     debug("Received null rilContext from chrome process.");
     return;
   }
   this.cardState = rilContext.cardState;
   this.updateConnectionInfo(rilContext.voice, this.voiceConnectionInfo);
   this.updateConnectionInfo(rilContext.data, this.dataConnectionInfo);
@@ -503,17 +502,17 @@ RILContentHelper.prototype = {
   observe: function observe(subject, topic, data) {
     if (topic == "xpcom-shutdown") {
       this.removeMessageListener();
       Services.obs.removeObserver(this, "xpcom-shutdown");
       cpmm = null;
     }
   },
 
-  // nsIFrameMessageListener
+  // nsIMessageListener
 
   fireRequestSuccess: function fireRequestSuccess(requestId, result) {
     let request = this.takeRequest(requestId);
     if (!request) {
       if (DEBUG) {
         debug("not firing success for id: " + requestId +
               ", result: " + JSON.stringify(result));
       }
--- a/dom/system/gonk/RadioInterfaceLayer.js
+++ b/dom/system/gonk/RadioInterfaceLayer.js
@@ -74,17 +74,17 @@ XPCOMUtils.defineLazyServiceGetter(this,
                                    "nsISmsRequestManager");
 
 XPCOMUtils.defineLazyServiceGetter(this, "gSmsDatabaseService",
                                    "@mozilla.org/sms/rilsmsdatabaseservice;1",
                                    "nsISmsDatabaseService");
 
 XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
                                    "@mozilla.org/parentprocessmessagemanager;1",
-                                   "nsIFrameMessageManager");
+                                   "nsIMessageBroadcaster");
 
 XPCOMUtils.defineLazyServiceGetter(this, "gSettingsService",
                                    "@mozilla.org/settingsService;1",
                                    "nsISettingsService");
 
 XPCOMUtils.defineLazyGetter(this, "WAP", function () {
   let WAP = {};
   Cu.import("resource://gre/modules/WapPushManager.js", WAP);
@@ -371,17 +371,17 @@ RadioInterfaceLayer.prototype = {
       case "operatorchange":
         this.handleOperatorChange(message);
         break;
       case "radiostatechange":
         this.handleRadioStateChange(message);
         break;
       case "cardstatechange":
         this.rilContext.cardState = message.cardState;
-        ppmm.sendAsyncMessage("RIL:CardStateChanged", message);
+        ppmm.broadcastAsyncMessage("RIL:CardStateChanged", message);
         break;
       case "sms-received":
         this.handleSmsReceived(message);
         return;
       case "sms-sent":
         this.handleSmsSent(message);
         return;
       case "sms-delivered":
@@ -423,17 +423,17 @@ RadioInterfaceLayer.prototype = {
         }
         let callback = this._contactsCallbacks[message.requestId];
         if (callback) {
           delete this._contactsCallbacks[message.requestId];
           callback.receiveContactsList(message.contactType, message.contacts);
         }
         break;
       case "iccmbdn":
-        ppmm.sendAsyncMessage("RIL:VoicemailNumberChanged", message);
+        ppmm.broadcastAsyncMessage("RIL:VoicemailNumberChanged", message);
         break;
       case "ussdreceived":
         debug("ussdreceived " + JSON.stringify(message));
         this.handleUSSDReceived(message);
         break;
       case "sendussd":
         this.handleSendUSSD(message);
         break;
@@ -449,29 +449,28 @@ RadioInterfaceLayer.prototype = {
   _messageManagerByRequest: null,
   saveRequestTarget: function saveRequestTarget(msg) {
     let requestId = msg.json.requestId;
     if (!requestId) {
       // The content is not interested in a response;
       return;
     }
 
-    let mm = msg.target.QueryInterface(Ci.nsIFrameMessageManager);
-    this._messageManagerByRequest[requestId] = mm;
+    this._messageManagerByRequest[requestId] = msg.target;
   },
 
   _sendRequestResults: function _sendRequestResults(requestType, options) {
     let target = this._messageManagerByRequest[options.requestId];
     delete this._messageManagerByRequest[options.requestId];
 
     if (!target) {
       return;
     }
 
-    target.sendAsyncMessage(requestType, options);
+    target.syncAsyncMessage(requestType, options);
   },
 
   updateNetworkInfo: function updateNetworkInfo(message) {
     let voiceMessage = message[RIL.NETWORK_INFO_VOICE_REGISTRATION_STATE];
     let dataMessage = message[RIL.NETWORK_INFO_DATA_REGISTRATION_STATE];
     let operatorMessage = message[RIL.NETWORK_INFO_OPERATOR];
     let selectionMessage = message[RIL.NETWORK_INFO_NETWORK_SELECTION_MODE];
 
@@ -494,20 +493,20 @@ RadioInterfaceLayer.prototype = {
         voice.network = operatorMessage;
       }
       if (this.networkChanged(operatorMessage, data.network)) {
         data.network = operatorMessage;
       }
     }
 
     if (voiceMessage || operatorMessage) {
-      ppmm.sendAsyncMessage("RIL:VoiceInfoChanged", voice);
+      ppmm.broadcastAsyncMessage("RIL:VoiceInfoChanged", voice);
     }
     if (dataMessage || operatorMessage) {
-      ppmm.sendAsyncMessage("RIL:DataInfoChanged", data);
+      ppmm.broadcastAsyncMessage("RIL:DataInfoChanged", data);
     }
 
     if (selectionMessage) {
       this.updateNetworkSelectionMode(selectionMessage);
     }
   },
 
   /**
@@ -539,17 +538,17 @@ RadioInterfaceLayer.prototype = {
     let newCell = newInfo.cell;
     if ((newCell.gsmLocationAreaCode < 0) || (newCell.gsmCellId < 0)) {
       voiceInfo.cell = null;
     } else {
       voiceInfo.cell = newCell;
     }
 
     if (!newInfo.batch) {
-      ppmm.sendAsyncMessage("RIL:VoiceInfoChanged", voiceInfo);
+      ppmm.broadcastAsyncMessage("RIL:VoiceInfoChanged", voiceInfo);
     }
   },
 
   updateDataConnection: function updateDataConnection(newInfo) {
     let dataInfo = this.rilContext.data;
     dataInfo.state = newInfo.state;
     dataInfo.roaming = newInfo.roaming;
     dataInfo.emergencyCallsOnly = newInfo.emergencyCallsOnly;
@@ -569,17 +568,17 @@ RadioInterfaceLayer.prototype = {
     let newCell = newInfo.cell;
     if ((newCell.gsmLocationAreaCode < 0) || (newCell.gsmCellId < 0)) {
       dataInfo.cell = null;
     } else {
       dataInfo.cell = newCell;
     }
 
     if (!newInfo.batch) {
-      ppmm.sendAsyncMessage("RIL:DataInfoChanged", dataInfo);
+      ppmm.broadcastAsyncMessage("RIL:DataInfoChanged", dataInfo);
     }
 
     if (!this.dataCallSettings["enabled"]) {
       return;
     }
 
     let isRegistered =
       newInfo.state == RIL.GECKO_MOBILE_CONNECTION_STATE_REGISTERED &&
@@ -595,25 +594,25 @@ RadioInterfaceLayer.prototype = {
 
   handleSignalStrengthChange: function handleSignalStrengthChange(message) {
     let voiceInfo = this.rilContext.voice;
     // TODO CDMA, EVDO, LTE, etc. (see bug 726098)
     if (voiceInfo.signalStrength != message.gsmDBM ||
         voiceInfo.relSignalStrength != message.gsmRelative) {
       voiceInfo.signalStrength = message.gsmDBM;
       voiceInfo.relSignalStrength = message.gsmRelative;
-      ppmm.sendAsyncMessage("RIL:VoiceInfoChanged", voiceInfo);
+      ppmm.broadcastAsyncMessage("RIL:VoiceInfoChanged", voiceInfo);
     }
 
     let dataInfo = this.rilContext.data;
     if (dataInfo.signalStrength != message.gsmDBM ||
         dataInfo.relSignalStrength != message.gsmRelative) {
       dataInfo.signalStrength = message.gsmDBM;
       dataInfo.relSignalStrength = message.gsmRelative;
-      ppmm.sendAsyncMessage("RIL:DataInfoChanged", dataInfo);
+      ppmm.broadcastAsyncMessage("RIL:DataInfoChanged", dataInfo);
     }
   },
 
   networkChanged: function networkChanged(srcNetwork, destNetwork) {
     return !destNetwork ||
       destNetwork.longName != srcNetwork.longName ||
       destNetwork.shortName != srcNetwork.shortName ||
       destNetwork.mnc != srcNetwork.mnc ||
@@ -621,22 +620,22 @@ RadioInterfaceLayer.prototype = {
   },
 
   handleOperatorChange: function handleOperatorChange(message) {
     let voice = this.rilContext.voice;
     let data = this.rilContext.data;
 
     if (this.networkChanged(message, voice.network)) {
       voice.network = message;
-      ppmm.sendAsyncMessage("RIL:VoiceInfoChanged", voice);
+      ppmm.broadcastAsyncMessage("RIL:VoiceInfoChanged", voice);
     }
 
     if (this.networkChanged(message, data.network)) {
       data.network = message;
-      ppmm.sendAsyncMessage("RIL:DataInfoChanged", data);
+      ppmm.broadcastAsyncMessage("RIL:DataInfoChanged", data);
     }
   },
 
   handleRadioStateChange: function handleRadioStateChange(message) {
     let newState = message.radioState;
     if (this.rilContext.radioState == newState) {
       return;
     }
@@ -743,30 +742,30 @@ RadioInterfaceLayer.prototype = {
     if (call.isActive) {
       this._activeCall = call;
     } else if (this._activeCall &&
                this._activeCall.callIndex == call.callIndex) {
       // Previously active call is not active now.
       this._activeCall = null;
     }
     this.updateCallAudioState();
-    ppmm.sendAsyncMessage("RIL:CallStateChanged", call);
+    ppmm.broadcastAsyncMessage("RIL:CallStateChanged", call);
   },
 
   /**
    * Handle call disconnects by updating our current state and the audio system.
    */
   handleCallDisconnected: function handleCallDisconnected(call) {
     debug("handleCallDisconnected: " + JSON.stringify(call));
     if (call.isActive) {
       this._activeCall = null;
     }
     this.updateCallAudioState();
     call.state = nsIRadioInterfaceLayer.CALL_STATE_DISCONNECTED;
-    ppmm.sendAsyncMessage("RIL:CallStateChanged", call);
+    ppmm.broadcastAsyncMessage("RIL:CallStateChanged", call);
   },
 
   /**
    * Handle calls delivered in response to a 'enumerateCalls' request.
    */
   handleEnumerateCalls: function handleEnumerateCalls(options) {
     debug("handleEnumerateCalls: " + JSON.stringify(options));
     for (let i in options.calls) {
@@ -784,17 +783,17 @@ RadioInterfaceLayer.prototype = {
     this._sendRequestResults("RIL:GetAvailableNetworks", message);
   },
 
   /**
    * Update network selection mode
    */
   updateNetworkSelectionMode: function updateNetworkSelectionMode(message) {
     debug("updateNetworkSelectionMode: " + JSON.stringify(message));
-    ppmm.sendAsyncMessage("RIL:NetworkSelectionModeChanged", message);
+    ppmm.broadcastAsyncMessage("RIL:NetworkSelectionModeChanged", message);
   },
 
   /**
    * Handle "manual" network selection request.
    */
   handleSelectNetwork: function handleSelectNetwork(message) {
     debug("handleSelectNetwork: " + JSON.stringify(message));
     this._sendRequestResults("RIL:SelectNetwork", message);
@@ -807,17 +806,17 @@ RadioInterfaceLayer.prototype = {
     debug("handleSelectNetworkAuto: " + JSON.stringify(message));
     this._sendRequestResults("RIL:SelectNetworkAuto", message);
   },
 
   /**
    * Handle call error.
    */
   handleCallError: function handleCallError(message) {
-    ppmm.sendAsyncMessage("RIL:CallError", message);   
+    ppmm.broadcastAsyncMessage("RIL:CallError", message);   
   },
 
   /**
    * Handle WDP port push PDU. Constructor WDP bearer information and deliver
    * to WapPushManager.
    *
    * @param message
    *        A SMS message.
@@ -868,17 +867,17 @@ RadioInterfaceLayer.prototype = {
     // For now we don't store indicators persistently. When the mwi.discard
     // flag is false, we'll need to persist the indicator to EFmwis.
     // See TS 23.040 9.2.3.24.2
 
     let mwi = message.mwi;
     if (mwi) {
       mwi.returnNumber = message.sender || null;
       mwi.returnMessage = message.fullBody || null;
-      ppmm.sendAsyncMessage("RIL:VoicemailNotification", mwi);
+      ppmm.broadcastAsyncMessage("RIL:VoicemailNotification", mwi);
       return;
     }
 
     let id = gSmsDatabaseService.saveReceivedMessage(message.sender || null,
                                                      message.fullBody || null,
                                                      message.timestamp);
     let sms = gSmsService.createSmsMessage(id,
                                            DOM_SMS_DELIVERY_RECEIVED,
@@ -970,17 +969,17 @@ RadioInterfaceLayer.prototype = {
   /**
    * Handle data call state changes.
    */
   handleDataCallState: function handleDataCallState(datacall) {
     let data = this.rilContext.data;
 
     if (datacall.ifname) {
       data.connected = (datacall.state == RIL.GECKO_NETWORK_STATE_CONNECTED);
-      ppmm.sendAsyncMessage("RIL:DataInfoChanged", data);    
+      ppmm.broadcastAsyncMessage("RIL:DataInfoChanged", data);    
     }
 
     this._deliverDataCallCallback("dataCallStateChanged",
                                   [datacall]);
   },
 
   /**
    * Handle data call list.
@@ -991,17 +990,17 @@ RadioInterfaceLayer.prototype = {
   },
 
   handleICCCardLockResult: function handleICCCardLockResult(message) {
     this._sendRequestResults("RIL:CardLockResult", message);
   },
 
   handleUSSDReceived: function handleUSSDReceived(ussd) {
     debug("handleUSSDReceived " + JSON.stringify(ussd));
-    ppmm.sendAsyncMessage("RIL:UssdReceived", ussd);
+    ppmm.broadcastAsyncMessage("RIL:UssdReceived", ussd);
   },
 
   handleSendUSSD: function handleSendUSSD(message) {
     debug("handleSendUSSD " + JSON.stringify(message));
     let messageType = message.success ? "RIL:SendUssd:Return:OK" :
                                         "RIL:SendUssd:Return:KO";
     this._sendRequestResults(messageType, message);
   },
--- a/dom/tests/mochitest/general/test_interfaces.html
+++ b/dom/tests/mochitest/general/test_interfaces.html
@@ -291,17 +291,16 @@ var interfaceNamesInGlobalScope =
     "CSSPrimitiveValue",
     "SVGStopElement",
     "WebGLExtensionCompressedTextureS3TC",
     "XULCommandEvent",
     "HTMLMediaElement",
     "SVGPathSegLinetoHorizontalAbs",
     "SVGAnimatedRect",
     "SVGTextContentElement",
-    "SyncMessageSender",
     "WebGLRenderbuffer",
     "TreeColumn",
     "WebGLExtensionStandardDerivatives",
     "WebGLShaderPrecisionFormat",
     "XPathNamespace",
     "FontFace",
     "SVGPathSegCurvetoCubicSmoothRel",
     "HTMLMapElement",
@@ -397,17 +396,16 @@ var interfaceNamesInGlobalScope =
     "MozTouchEvent",
     "MozWakeLockListener",
     "Selection",
     "XULTreeBuilder",
     "ScrollAreaEvent",
     "SVGStyleElement",
     "XULContainerElement",
     "DOMTokenList",
-    "FrameMessageManager",
     "HTMLHRElement",
     "HTMLFontElement",
     "SVGFEFloodElement",
     "HTMLDListElement",
     "SVGSymbolElement",
     "SVGLengthList",
     "TreeColumns",
     "PaintRequestList",
@@ -485,17 +483,16 @@ var interfaceNamesInGlobalScope =
     "GeoPositionCallback",
     "XULCommandDispatcher",
     "DocumentTouch",
     "XULSelectControlItemElement",
     "SVGPathSegCurvetoQuadraticAbs",
     "MutationObserver",
     "RequestService",
     "Counter",
-    "ContentFrameMessageManager",
     "SVGAnimatedAngle",
     "SVGPathSegList",
     "SVGFEFuncAElement",
     "WebSocket",
     "ElementTimeControl",
     "HTMLLegendElement",
     "SVGFEGaussianBlurElement",
     "SVGEllipseElement",
--- a/dom/wifi/WifiWorker.js
+++ b/dom/wifi/WifiWorker.js
@@ -1321,17 +1321,18 @@ let WifiNetworkInterface = {
 // TODO Make the difference between a DOM-based network object and our
 // networks objects much clearer.
 let netToDOM;
 let netFromDOM;
 
 function WifiWorker() {
   var self = this;
 
-  this._mm = Cc["@mozilla.org/parentprocessmessagemanager;1"].getService(Ci.nsIFrameMessageManager);
+  this._mm = Cc["@mozilla.org/parentprocessmessagemanager;1"]
+               .getService(Ci.nsIMessageListenerManager);
   const messages = ["WifiManager:setEnabled", "WifiManager:getNetworks",
                     "WifiManager:associate", "WifiManager:forget",
                     "WifiManager:wps", "WifiManager:getState",
                     "WifiManager:managerFinished"];
 
   messages.forEach((function(msgName) {
     this._mm.addMessageListener(msgName, this);
   }).bind(this));
@@ -1884,17 +1885,17 @@ WifiWorker.prototype = {
 
   _sendMessage: function(message, success, data, msg) {
     msg.manager.sendAsyncMessage(message + (success ? ":OK" : ":NO"),
                                  { data: data, rid: msg.rid, mid: msg.mid });
   },
 
   receiveMessage: function MessageManager_receiveMessage(aMessage) {
     let msg = aMessage.json || {};
-    msg.manager = aMessage.target.QueryInterface(Ci.nsIFrameMessageManager);
+    msg.manager = aMessage.target;
 
     switch (aMessage.name) {
       case "WifiManager:setEnabled":
         this.setWifiEnabled(msg);
         break;
       case "WifiManager:getNetworks":
         this.getNetworks(msg);
         break;
--- a/dom/workers/ScriptLoader.cpp
+++ b/dom/workers/ScriptLoader.cpp
@@ -571,17 +571,17 @@ ScriptExecutorRunnable::WorkerRun(JSCont
     NS_ASSERTION(!loadInfo.mChannel, "Should no longer have a channel!");
     NS_ASSERTION(loadInfo.mExecutionScheduled, "Should be scheduled!");
 
     if (!loadInfo.mExecutionResult) {
       return true;
     }
   }
 
-  JSObject* global = JS_GetGlobalObject(aCx);
+  JS::RootedObject global(aCx, JS_GetGlobalObject(aCx));
   NS_ASSERTION(global, "Must have a global by now!");
 
   JSPrincipals* principal = GetWorkerPrincipal();
   NS_ASSERTION(principal, "This should never be null!");
 
   for (uint32_t index = mFirstIndex; index <= mLastIndex; index++) {
     ScriptLoadInfo& loadInfo = loadInfos.ElementAt(index);
 
@@ -610,20 +610,21 @@ ScriptExecutorRunnable::WorkerRun(JSCont
           JS_ReportError(aCx, "Failed to load script: %s (nsresult = 0x%x)",
                          url.get(), loadInfo.mLoadResult);
       }
       return true;
     }
 
     NS_ConvertUTF16toUTF8 filename(loadInfo.mURL);
 
-    if (!JS_EvaluateUCScriptForPrincipals(aCx, global, principal,
-                                          loadInfo.mScriptText.get(),
-                                          loadInfo.mScriptText.Length(),
-                                          filename.get(), 1, nullptr)) {
+    JS::CompileOptions options(aCx);
+    options.setPrincipals(principal)
+           .setFileAndLine(filename.get(), 1);
+    if (!JS::Evaluate(aCx, global, options, loadInfo.mScriptText.get(),
+                      loadInfo.mScriptText.Length(), nullptr)) {
       return true;
     }
 
     loadInfo.mExecutionResult = true;
   }
 
   return true;
 }
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -3755,17 +3755,17 @@ WorkerPrivate::RunExpiredTimeouts(JSCont
   }
 
   NS_ASSERTION(mTimer, "Must have a timer!");
   NS_ASSERTION(!mTimeouts.IsEmpty(), "Should have some work to do!");
 
   bool retval = true;
 
   AutoPtrComparator<TimeoutInfo> comparator = GetAutoPtrComparator(mTimeouts);
-  JSObject* global = JS_GetGlobalObject(aCx);
+  JS::RootedObject global(aCx, JS_GetGlobalObject(aCx));
   JSPrincipals* principal = GetWorkerPrincipal();
 
   // We want to make sure to run *something*, even if the timer fired a little
   // early. Fudge the value of now to at least include the first timeout.
   const TimeStamp now = NS_MAX(TimeStamp::Now(), mTimeouts[0]->mTargetTime);
 
   nsAutoTArray<TimeoutInfo*, 10> expiredTimeouts;
   for (uint32_t index = 0; index < mTimeouts.Length(); index++) {
@@ -3789,25 +3789,24 @@ WorkerPrivate::RunExpiredTimeouts(JSCont
 
     // Always call JS_ReportPendingException if something fails, and if
     // JS_ReportPendingException returns false (i.e. uncatchable exception) then
     // break out of the loop.
 
     if (info->mTimeoutVal.isString()) {
       JSString* expression = info->mTimeoutVal.toString();
 
+      JS::CompileOptions options(aCx);
+      options.setPrincipals(principal)
+        .setFileAndLine(info->mFilename.get(), info->mLineNumber);
+
       size_t stringLength;
       const jschar* string = JS_GetStringCharsAndLength(aCx, expression,
                                                         &stringLength);
-
-      if ((!string ||
-           !JS_EvaluateUCScriptForPrincipals(aCx, global, principal, string,
-                                             stringLength,
-                                             info->mFilename.get(),
-                                             info->mLineNumber, nullptr)) &&
+      if ((!string || !JS::Evaluate(aCx, global, options, string, stringLength, nullptr)) &&
           !JS_ReportPendingException(aCx)) {
         retval = false;
         break;
       }
     }
     else {
       jsval rval;
       if (!JS_CallFunctionValue(aCx, global, info->mTimeoutVal,
--- a/extensions/cookie/test/unit_ipc/test_parent.js
+++ b/extensions/cookie/test/unit_ipc/test_parent.js
@@ -22,27 +22,27 @@ function run_test() {
     var pm = Cc["@mozilla.org/permissionmanager;1"].getService(Ci.nsIPermissionManager);
 
     // Permissions created before the child is present
     pm.addFromPrincipal(getPrincipalForURI("http://mozilla.org"), "cookie1", pm.ALLOW_ACTION, pm.EXPIRE_NEVER, 0);
     pm.addFromPrincipal(getPrincipalForURI("http://mozilla.com"), "cookie2", pm.DENY_ACTION, pm.EXPIRE_SESSION, 0);
     pm.addFromPrincipal(getPrincipalForURI("http://mozilla.net"), "cookie3", pm.ALLOW_ACTION, pm.EXPIRE_TIME, Date.now() + 1000*60*60*24);
 
     var mM = Cc["@mozilla.org/parentprocessmessagemanager;1"].
-             getService(Ci.nsIFrameMessageManager);
+             getService(Ci.nsIMessageBroadcaster);
 
     var messageListener = {
       receiveMessage: function(aMessage) {
         switch(aMessage.name) {
           case "TESTING:Stage2":
             // Permissions created after the child is present
             pm.addFromPrincipal(getPrincipalForURI("http://firefox.org"), "cookie1", pm.ALLOW_ACTION, pm.EXPIRE_NEVER, 0);
             pm.addFromPrincipal(getPrincipalForURI("http://firefox.com"), "cookie2", pm.DENY_ACTION, pm.EXPIRE_SESSION, 0);
             pm.addFromPrincipal(getPrincipalForURI("http://firefox.net"), "cookie3", pm.ALLOW_ACTION, pm.EXPIRE_TIME, Date.now() + 1000*60*60*24);
-            mM.sendAsyncMessage("TESTING:Stage2A");
+            mM.broadcastAsyncMessage("TESTING:Stage2A");
             break;
 
           case "TESTING:Stage3":
             do_test_finished();
             break;
         }
         return true;
       },
--- a/extensions/pref/autoconfig/src/nsJSConfigTriggers.cpp
+++ b/extensions/pref/autoconfig/src/nsJSConfigTriggers.cpp
@@ -190,19 +190,21 @@ nsresult EvaluateAdminConfigScript(const
     if (NS_FAILED(rv)) {
         NS_ERROR("coudn't push the context on the stack");
         return rv;
     }
 
     JS_BeginRequest(autoconfig_cx);
     nsCOMPtr<nsIPrincipal> principal;
     nsContentUtils::GetSecurityManager()->GetSystemPrincipal(getter_AddRefs(principal));
-    ok = JS_EvaluateScriptForPrincipals(autoconfig_cx, autoconfig_glob, 
-                                        nsJSPrincipals::get(principal),
-                                        js_buffer, length, filename, 0, nullptr);
+    JS::CompileOptions options(autoconfig_cx);
+    options.setPrincipals(nsJSPrincipals::get(principal))
+           .setFileAndLine(filename, 1);
+    JS::RootedObject glob(autoconfig_cx, autoconfig_glob);
+    ok = JS::Evaluate(autoconfig_cx, glob, options, js_buffer, length, nullptr);
     JS_EndRequest(autoconfig_cx);
 
     JS_MaybeGC(autoconfig_cx);
 
     JSContext *cx;
     cxstack->Pop(&cx);
     NS_ASSERTION(cx == autoconfig_cx, "AutoConfig JS contexts didn't match");
 
deleted file mode 100644
--- a/js/src/jsreops.tbl
+++ /dev/null
@@ -1,111 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sw=4 et tw=0 ft=C: */
- 
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* Note : contiguity of 'simple opcodes' is important for SimpleMatch() */
-
-/* match rest of input against rest of r.e. */
-REOP_DEF(REOP_EMPTY,         "empty")
-/* beginning of input (or line if multiline) */
-REOP_DEF(REOP_BOL,           "bol")
-/* end of input (or line if multiline) */
-REOP_DEF(REOP_EOL,           "eol")
-/* match "" at word boundary */
-REOP_DEF(REOP_WBDRY,         "wbdry")
-/* match "" at word non-boundary */
-REOP_DEF(REOP_WNONBDRY,      "wnonbdry")
-/* stands for any character */
-REOP_DEF(REOP_DOT,           "dot")
-/* match a digit char: [0-9] */
-REOP_DEF(REOP_DIGIT,         "digit")
-/* match a non-digit char: [^0-9] */
-REOP_DEF(REOP_NONDIGIT,      "nondigit")
-/* match an alphanumeric char: [0-9a-z_A-Z] */
-REOP_DEF(REOP_ALNUM,         "alnum")
-/* match a non-alphanumeric char: [^0-9a-z_A-Z] */
-REOP_DEF(REOP_NONALNUM,      "nonalnum")
-/* match a whitespace char */
-REOP_DEF(REOP_SPACE,         "space")
-/* match a non-whitespace char */
-REOP_DEF(REOP_NONSPACE,      "nonspace")
-/* back-reference (e.g., \1) to a parenthetical */
-REOP_DEF(REOP_BACKREF,       "backref")
-/* match a flat string */
-REOP_DEF(REOP_FLAT,          "flat")
-/* match a single char */
-REOP_DEF(REOP_FLAT1,         "flat1")
-/* case-independent REOP_FLAT */
-REOP_DEF(REOP_FLATi,         "flati")
-/* case-independent REOP_FLAT1 */
-REOP_DEF(REOP_FLAT1i,        "flat1i")
-/* single Unicode char */
-REOP_DEF(REOP_UCFLAT1,       "ucflat1")
-/* case-independent REOP_UCFLAT1 */
-REOP_DEF(REOP_UCFLAT1i,      "ucflat1i")
-/* flat Unicode string; len immediate counts chars */
-REOP_DEF(REOP_UCFLAT,        "ucflat")
-/* case-independent REOP_UCFLAT */
-REOP_DEF(REOP_UCFLATi,       "ucflati")
-/* character class with index */
-REOP_DEF(REOP_CLASS,         "class")
-/* negated character class with index */
-REOP_DEF(REOP_NCLASS,        "nclass")
-
-/* NCLASS is considered to be the last "simple" op-code */
-
-
-/* alternative subexpressions in kid and next */
-REOP_DEF(REOP_ALT,           "alt")
-/* quantified atom: atom{1,2} */
-REOP_DEF(REOP_QUANT,         "quant")
-/* zero or more occurrences of kid */
-REOP_DEF(REOP_STAR,          "star")
-/* one or more occurrences of kid */
-REOP_DEF(REOP_PLUS,          "plus")
-/* optional subexpression in kid */
-REOP_DEF(REOP_OPT,           "opt")
-/* left paren bytecode: kid is u.num'th sub-regexp */
-REOP_DEF(REOP_LPAREN,        "lparen")
-/* right paren bytecode */
-REOP_DEF(REOP_RPAREN,        "rparen")
-/* for deoptimized closure loops */
-REOP_DEF(REOP_JUMP,          "jump")
-/* optimize .* to use a single opcode */
-REOP_DEF(REOP_DOTSTAR,       "dotstar")
-/* non-capturing version of REOP_LPAREN */
-REOP_DEF(REOP_LPARENNON,     "lparennon")
-/* zero width positive lookahead assertion */
-REOP_DEF(REOP_ASSERT,        "assert")
-/* zero width negative lookahead assertion */
-REOP_DEF(REOP_ASSERT_NOT,    "assert_not")
-/* sentinel at end of assertion child */
-REOP_DEF(REOP_ASSERTTEST,    "asserttest")
-/* sentinel at end of !assertion child */
-REOP_DEF(REOP_ASSERTNOTTEST, "assertnottest")
-/* non-greedy version of * */
-REOP_DEF(REOP_MINIMALSTAR,   "minimalstar")
-/* non-greedy version of + */
-REOP_DEF(REOP_MINIMALPLUS,   "minimalplus")
-/* non-greedy version of ? */
-REOP_DEF(REOP_MINIMALOPT,    "minimalopt")
-/* non-greedy version of {} */
-REOP_DEF(REOP_MINIMALQUANT,  "minimalquant")
-/* sentinel at end of quantifier child */
-REOP_DEF(REOP_ENDCHILD,      "endchild")
-/* directs execution of greedy quantifier */
-REOP_DEF(REOP_REPEAT,        "repeat")
-/* directs execution of non-greedy quantifier */
-REOP_DEF(REOP_MINIMALREPEAT, "minimalrepeat")
-/* prerequisite for ALT, either of two chars */
-REOP_DEF(REOP_ALTPREREQ,     "altprereq")
-/* prerequisite for ALT, a char or a class */
-REOP_DEF(REOP_ALTPREREQ2,    "altprereq2")
-/* end of final alternate */
-REOP_DEF(REOP_ENDALT,        "endalt")
-/* concatenation of terms (parse time only) */
-REOP_DEF(REOP_CONCAT,        "concat")
-/* end of expression */
-REOP_DEF(REOP_END,           "end")
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -3910,23 +3910,22 @@ xpc_EvalInSandbox(JSContext *cx, JSObjec
     nsresult rv = NS_OK;
 
     {
         JSAutoRequest req(sandcx->GetJSContext());
         JSAutoCompartment ac(sandcx->GetJSContext(), sandbox);
 
         jsval v;
         JSString *str = nullptr;
-        JSBool ok =
-            JS_EvaluateUCScriptForPrincipals(sandcx->GetJSContext(), sandbox,
-                                             nsJSPrincipals::get(prin),
-                                             reinterpret_cast<const jschar *>
-                                                             (PromiseFlatString(source).get()),
-                                             source.Length(), filename, lineNo,
-                                             &v);
+        JS::CompileOptions options(sandcx->GetJSContext());
+        options.setPrincipals(nsJSPrincipals::get(prin))
+               .setFileAndLine(filename, lineNo);
+        JS::RootedObject rootedSandbox(sandcx->GetJSContext(), sandbox);
+        bool ok = JS::Evaluate(sandcx->GetJSContext(), rootedSandbox, options,
+                               PromiseFlatString(source).get(), source.Length(), &v);
         if (ok && returnStringOnly && !(JSVAL_IS_VOID(v))) {
             ok = !!(str = JS_ValueToString(sandcx->GetJSContext(), v));
         }
 
         if (!ok) {
             // The sandbox threw an exception, convert it to a string (if
             // asked) or convert it to a SJOW.
 
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -60,17 +60,18 @@ const char* XPCJSRuntime::mStrings[] = {
     "createInstance",       // IDX_CREATE_INSTANCE
     "item",                 // IDX_ITEM
     "__proto__",            // IDX_PROTO
     "__iterator__",         // IDX_ITERATOR
     "__exposedProps__",     // IDX_EXPOSEDPROPS
     "__scriptOnly__",       // IDX_SCRIPTONLY
     "baseURIObject",        // IDX_BASEURIOBJECT
     "nodePrincipal",        // IDX_NODEPRINCIPAL
-    "documentURIObject"     // IDX_DOCUMENTURIOBJECT
+    "documentURIObject",    // IDX_DOCUMENTURIOBJECT
+    "mozMatchesSelector"    // IDX_MOZMATCHESSELECTOR
 };
 
 /***************************************************************************/
 
 struct CX_AND_XPCRT_Data
 {
     JSContext* cx;
     XPCJSRuntime* rt;
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -725,16 +725,17 @@ public:
         IDX_ITEM                    ,
         IDX_PROTO                   ,
         IDX_ITERATOR                ,
         IDX_EXPOSEDPROPS            ,
         IDX_SCRIPTONLY              ,
         IDX_BASEURIOBJECT           ,
         IDX_NODEPRINCIPAL           ,
         IDX_DOCUMENTURIOBJECT       ,
+        IDX_MOZMATCHESSELECTOR      ,
         IDX_TOTAL_COUNT // just a count of the above
     };
 
     jsid GetStringID(unsigned index) const
     {
         NS_ASSERTION(index < IDX_TOTAL_COUNT, "index out of range");
         return mStrIDs[index];
     }
--- a/js/xpconnect/tests/chrome/Makefile.in
+++ b/js/xpconnect/tests/chrome/Makefile.in
@@ -27,16 +27,17 @@ MOCHITEST_CHROME_FILES = \
 		test_bug618176.xul \
 		file_bug618176.xul \
 		test_bug654370.xul \
 		test_bug658560.xul \
 		test_bug664689.xul \
 		test_bug679861.xul \
 		test_bug706301.xul \
 		test_bug726949.xul \
+		test_bug738244.xul \
 		test_bug743843.xul \
 		test_bug760076.xul \
 		test_bug760109.xul \
 		test_bug763343.xul \
 		test_bug771429.xul \
 		test_bug773962.xul \
 		test_APIExposer.xul \
 		test_chrometoSource.xul \
@@ -46,16 +47,17 @@ MOCHITEST_CHROME_FILES = \
 		test_documentdomain.xul \
 		test_doublewrappedcompartments.xul \
 		test_evalInSandbox.xul \
 		file_evalInSandbox.html \
 		test_exnstack.xul \
 		test_expandosharing.xul \
 		file_expandosharing.jsm \
 		test_getweakmapkeys.xul \
+		test_mozMatchesSelector.xul \
 		test_nodelists.xul \
 		test_precisegc.xul \
 		test_sandboxImport.xul \
 		test_weakmaps.xul \
 		test_weakref.xul \
 		test_wrappers.xul \
 		$(NULL)
 
new file mode 100644
--- /dev/null
+++ b/js/xpconnect/tests/chrome/test_bug738244.xul
@@ -0,0 +1,50 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
+                 type="text/css"?>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=533596
+-->
+<window title="Mozilla Bug 533596"
+  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+
+  <!-- test results are displayed in the html:body -->
+  <body xmlns="http://www.w3.org/1999/xhtml">
+
+  <iframe src="http://example.org/tests/js/xpconnect/tests/mochitest/file_bug738244.html"
+          onload="xrayTest(this)">
+  </iframe>
+  </body>
+
+  <!-- test code goes here -->
+  <script type="application/javascript"><![CDATA[
+
+      SimpleTest.waitForExplicitFinish();
+
+      function xrayTest(ifr) {
+        var win = ifr.contentWindow;
+        var doc = ifr.contentDocument;
+
+        doc.getElementById = 42;
+        is(doc.getElementById, 42,
+           "Native property cannot be shadowed on the xray");
+
+        is(doc.form1.name, "form1",
+           "Form elements cannot be found by name on the document through xray");
+
+        is(doc.form1.input1.name, "input1",
+           "Input element cannot be found by name on a form element through xray");
+
+        is(typeof doc.form1.appendChild, "function",
+           "Input element shadows native property with its name through xray");
+
+        is(win.frame1.name, "frame1",
+           "IFrames cannot be found by name on the window through xray");
+
+        SimpleTest.finish();
+      }
+
+  ]]></script>
+</window>
new file mode 100644
--- /dev/null
+++ b/js/xpconnect/tests/chrome/test_mozMatchesSelector.xul
@@ -0,0 +1,50 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
+                 type="text/css"?>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=533596
+-->
+<window title="Mozilla Bug 533596"
+  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+
+  <!-- test results are displayed in the html:body -->
+  <body xmlns="http://www.w3.org/1999/xhtml">
+
+  <iframe src="http://example.org/tests/js/xpconnect/tests/mochitest/file_mozMatchesSelector.html"
+          onload="runTest(this)">
+  </iframe>
+  </body>
+
+  <!-- test code goes here -->
+  <script type="application/javascript"><![CDATA[
+      SimpleTest.waitForExplicitFinish();
+      function runTest(ifr)
+      {
+        var doc = ifr.contentDocument;
+        var docElem = doc.documentElement;
+        
+        var res = doc.createElement('div').mozMatchesSelector('div');
+        is(res, true, "mozMatchesSelector call through xray, regular case");
+        
+        res = docElem.mozMatchesSelector.call(
+          doc.createElement('div'), 'div');
+        is(res, true, "mozMatchesSelector call through xray, with .call");
+                        
+        var sb = new Components.utils.Sandbox(ifr.contentWindow);
+        sb.doc = doc;
+        var str = "doc.documentElement.mozMatchesSelector.call(doc.createElement( 'div' ),'div')";
+        res = Components.utils.evalInSandbox(str, sb);
+        is(res, true, "mozMatchesSelector call through xray (same origin), with .call");
+        
+        docElem.mozMatchesSelector = function(){return false};
+        res = docElem.mozMatchesSelector.call(doc.createElement( 'div' ),'div');
+        is(res, false, "shadowing mozMatchesSelector with an expando on the xray wrapper");
+        
+        SimpleTest.finish();
+      }
+
+  ]]></script>
+</window>
--- a/js/xpconnect/tests/mochitest/Makefile.in
+++ b/js/xpconnect/tests/mochitest/Makefile.in
@@ -67,16 +67,18 @@ MOCHITEST_FILES =	bug500931_helper.html 
 		test_bug781476.html \
 		file_bug781476.html \
 		file_nodelists.html \
 		file_exnstack.html \
 		file_expandosharing.html \
 		file_empty.html \
 		file_documentdomain.html \
 		test_lookupMethod.html \
+		file_bug738244.html \
+		file_mozMatchesSelector.html \
 		$(NULL)
 
 MOCHITEST_CHROME_FILES	= \
 		test_bug361111.xul \
 		test_bug760131.html \
 		$(NULL)
 
 ifneq ($(OS_TARGET),Android)
new file mode 100644
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/file_bug738244.html
@@ -0,0 +1,10 @@
+<html>
+<body>
+<form name="form1">
+  <input name="input1" />
+  <input name="appendChild" />
+</form>
+<iframe name="frame1">
+</iframe>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/file_mozMatchesSelector.html
@@ -0,0 +1,1 @@
+<html><body></body></html>
--- a/js/xpconnect/wrappers/WrapperFactory.cpp
+++ b/js/xpconnect/wrappers/WrapperFactory.cpp
@@ -620,16 +620,24 @@ WrapperFactory::WrapForSameCompartmentXr
         JSObject *xrayHolder = XrayUtils::createHolder(cx, obj, parent);
         if (!xrayHolder)
             return nullptr;
         js::SetProxyExtra(wrapperObj, 0, js::ObjectValue(*xrayHolder));
     }
     return wrapperObj;
 }
 
+
+bool
+WrapperFactory::XrayWrapperNotShadowing(JSObject *wrapper, jsid id)
+{
+    ResolvingId *rid = ResolvingId::getResolvingIdFromWrapper(wrapper);
+    return rid->isXrayShadowing(id);
+}
+
 /*
  * Calls to JS_TransplantObject* should go through these helpers here so that
  * waivers get fixed up properly.
  */
 
 static bool
 FixWaiverAfterTransplant(JSContext *cx, JSObject *oldWaiver, JSObject *newobj)
 {
--- a/js/xpconnect/wrappers/WrapperFactory.h
+++ b/js/xpconnect/wrappers/WrapperFactory.h
@@ -88,15 +88,18 @@ class WrapperFactory {
     // Return true if this is a Components object.
     static bool IsComponentsObject(JSObject *obj);
 
     // Wrap a (same compartment) Components object.
     static JSObject *WrapComponentsObject(JSContext *cx, JSObject *obj);
 
     // Wrap a same-compartment object for Xray inspection.
     static JSObject *WrapForSameCompartmentXray(JSContext *cx, JSObject *obj);
+
+    // Returns true if the wrapper is in not shadowing mode for the id.
+    static bool XrayWrapperNotShadowing(JSObject *wrapper, jsid id);
 };
 
 extern js::DirectWrapper XrayWaiver;
 
 }
 
 #endif /* _xpc_WRAPPERFACTORY_H */
--- a/js/xpconnect/wrappers/XrayWrapper.cpp
+++ b/js/xpconnect/wrappers/XrayWrapper.cpp
@@ -13,16 +13,17 @@
 
 #include "nsINode.h"
 #include "nsIDocument.h"
 
 #include "XPCWrapper.h"
 #include "xpcprivate.h"
 
 #include "jsapi.h"
+#include "nsJSUtils.h"
 
 #include "mozilla/dom/BindingUtils.h"
 
 using namespace mozilla::dom;
 
 namespace xpc {
 
 using namespace js;
@@ -274,16 +275,78 @@ createHolder(JSContext *cx, JSObject *wr
     js::SetReservedSlot(holder, JSSLOT_RESOLVING, PrivateValue(NULL));
     return holder;
 }
 
 }
 
 using namespace XrayUtils;
 
+ResolvingId::ResolvingId(JSObject *wrapper, jsid id)
+    : mId(id),
+    mHolder(getHolderObject(wrapper)),
+    mPrev(getResolvingId(mHolder)),
+    mXrayShadowing(false)
+{
+    js::SetReservedSlot(mHolder, JSSLOT_RESOLVING, js::PrivateValue(this));
+}
+
+ResolvingId::~ResolvingId()
+{
+    MOZ_ASSERT(getResolvingId(mHolder) == this, "unbalanced ResolvingIds");
+    js::SetReservedSlot(mHolder, JSSLOT_RESOLVING, js::PrivateValue(mPrev));
+}
+
+bool
+ResolvingId::isXrayShadowing(jsid id)
+{
+    if (!mXrayShadowing)
+        return false;
+
+    return mId == id;
+}
+
+bool
+ResolvingId::isResolving(jsid id)
+{
+    for (ResolvingId *cur = this; cur; cur = cur->mPrev) {
+        if (cur->mId == id)
+            return true;
+    }
+
+    return false;
+}
+
+ResolvingId *
+ResolvingId::getResolvingId(JSObject *holder)
+{
+    MOZ_ASSERT(strcmp(JS_GetClass(holder)->name, "NativePropertyHolder") == 0);
+    return (ResolvingId *)js::GetReservedSlot(holder, JSSLOT_RESOLVING).toPrivate();
+}
+
+JSObject *
+ResolvingId::getHolderObject(JSObject *wrapper)
+{
+    return &js::GetProxyExtra(wrapper, 0).toObject();
+}
+
+ResolvingId *
+ResolvingId::getResolvingIdFromWrapper(JSObject *wrapper)
+{
+    return getResolvingId(getHolderObject(wrapper));
+}
+
+class ResolvingIdDummy
+{
+public:
+    ResolvingIdDummy(JSObject *wrapper, jsid id)
+    {
+    }
+};
+
 class XPCWrappedNativeXrayTraits
 {
 public:
     static bool resolveNativeProperty(JSContext *cx, JSObject *wrapper, JSObject *holder, jsid id,
                                       bool set, JSPropertyDescriptor *desc);
     static bool resolveOwnProperty(JSContext *cx, js::Wrapper &jsWrapper, JSObject *wrapper,
                                    JSObject *holder, jsid id, bool set,
                                    JSPropertyDescriptor *desc);
@@ -293,40 +356,28 @@ public:
     static bool enumerateNames(JSContext *cx, JSObject *wrapper, unsigned flags,
                                JS::AutoIdVector &props);
     static JSObject* getHolderObject(JSContext *cx, JSObject *wrapper)
     {
         return getHolderObject(wrapper);
     }
     static JSObject* getInnerObject(JSObject *wrapper);
 
-    class ResolvingId
-    {
-    public:
-        ResolvingId(JSObject *holder, jsid id);
-        ~ResolvingId();
+    static bool isResolving(JSContext *cx, JSObject *holder, jsid id);
 
-    private:
-        friend class XPCWrappedNativeXrayTraits;
+    static bool resolveDOMCollectionProperty(JSContext *cx, JSObject *wrapper, JSObject *holder,
+                                             jsid id, bool set, PropertyDescriptor *desc);
 
-        jsid mId;
-        JSObject *mHolder;
-        ResolvingId *mPrev;
-    };
-    static bool isResolving(JSContext *cx, JSObject *holder, jsid id);
+    typedef ResolvingId ResolvingIdImpl;
 
 private:
     static JSObject* getHolderObject(JSObject *wrapper)
     {
         return &js::GetProxyExtra(wrapper, 0).toObject();
     }
-    static ResolvingId* getResolvingId(JSObject *holder)
-    {
-        return (ResolvingId *)js::GetReservedSlot(holder, JSSLOT_RESOLVING).toPrivate();
-    }
 };
 
 class ProxyXrayTraits
 {
 public:
     static bool resolveNativeProperty(JSContext *cx, JSObject *wrapper, JSObject *holder, jsid id,
                                       bool set, JSPropertyDescriptor *desc);
     static bool resolveOwnProperty(JSContext *cx, js::Wrapper &jsWrapper, JSObject *wrapper,
@@ -341,28 +392,23 @@ public:
     {
         return getHolderObject(cx, wrapper, true);
     }
     static JSObject* getInnerObject(JSObject *wrapper)
     {
         return &js::GetProxyPrivate(wrapper).toObject();
     }
 
-    class ResolvingId
-    {
-    public:
-        ResolvingId(JSObject *holder, jsid id)
-        {
-        }
-    };
     static bool isResolving(JSContext *cx, JSObject *holder, jsid id)
     {
-      return false;
+        return false;
     }
 
+    typedef ResolvingIdDummy ResolvingIdImpl;
+
 private:
     static JSObject* getHolderObject(JSContext *cx, JSObject *wrapper,
                                      bool createHolder)
     {
         if (!js::GetProxyExtra(wrapper, 0).isUndefined())
             return &js::GetProxyExtra(wrapper, 0).toObject();
 
         if (!createHolder)
@@ -390,28 +436,23 @@ public:
     {
         return getHolderObject(cx, wrapper, true);
     }
     static JSObject* getInnerObject(JSObject *wrapper)
     {
         return &js::GetProxyPrivate(wrapper).toObject();
     }
 
-    class ResolvingId
-    {
-    public:
-        ResolvingId(JSObject *holder, jsid id)
-        {
-        }
-    };
     static bool isResolving(JSContext *cx, JSObject *holder, jsid id)
     {
-      return false;
+        return false;
     }
 
+    typedef ResolvingIdDummy ResolvingIdImpl;
+
 private:
     static JSObject* getHolderObject(JSContext *cx, JSObject *wrapper,
                                      bool createHolder)
     {
         if (!js::GetProxyExtra(wrapper, 0).isUndefined())
             return &js::GetProxyExtra(wrapper, 0).toObject();
 
         if (!createHolder)
@@ -467,40 +508,21 @@ FindWrapper(JSObject *wrapper)
 }
 
 JSObject*
 XPCWrappedNativeXrayTraits::getInnerObject(JSObject *wrapper)
 {
     return GetWrappedNativeObjectFromHolder(getHolderObject(wrapper));
 }
 
-XPCWrappedNativeXrayTraits::ResolvingId::ResolvingId(JSObject *wrapper, jsid id)
-  : mId(id),
-    mHolder(getHolderObject(wrapper)),
-    mPrev(getResolvingId(mHolder))
-{
-    js::SetReservedSlot(mHolder, JSSLOT_RESOLVING, PrivateValue(this));
-}
-
-XPCWrappedNativeXrayTraits::ResolvingId::~ResolvingId()
-{
-    NS_ASSERTION(getResolvingId(mHolder) == this, "unbalanced ResolvingIds");
-    js::SetReservedSlot(mHolder, JSSLOT_RESOLVING, PrivateValue(mPrev));
-}
-
 bool
 XPCWrappedNativeXrayTraits::isResolving(JSContext *cx, JSObject *holder,
                                         jsid id)
 {
-    for (ResolvingId *cur = getResolvingId(holder); cur; cur = cur->mPrev) {
-        if (cur->mId == id)
-            return true;
-    }
-
-    return false;
+    return ResolvingId::getResolvingId(holder)->isResolving(id);
 }
 
 // Some DOM objects have shared properties that don't have an explicit
 // getter/setter and rely on the class getter/setter. We install a
 // class getter/setter on the holder object to trigger them.
 JSBool
 holder_get(JSContext *cx, JSHandleObject wrapper_, JSHandleId id, JSMutableHandleValue vp)
 {
@@ -543,45 +565,194 @@ holder_set(JSContext *cx, JSHandleObject
             if (retval)
                 XPCThrower::Throw(rv, cx);
             return false;
         }
     }
     return true;
 }
 
+class AutoSetWrapperNotShadowing
+{
+public:
+    AutoSetWrapperNotShadowing(JSObject *wrapper MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
+    {
+        MOZ_GUARD_OBJECT_NOTIFIER_INIT;
+        MOZ_ASSERT(wrapper);
+        mResolvingId = ResolvingId::getResolvingIdFromWrapper(wrapper);
+        MOZ_ASSERT(mResolvingId);
+        mResolvingId->mXrayShadowing = true;
+    }
+
+    ~AutoSetWrapperNotShadowing()
+    {
+        mResolvingId->mXrayShadowing = false;
+    }
+
+private:
+    MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
+    ResolvingId *mResolvingId;
+};
+
+// This is called after the resolveNativeProperty could not find any property
+// with the given id. At this point we can check for DOM specific collections
+// like document["formName"] because we already know that it is not shadowing
+// any native property.
+bool
+XPCWrappedNativeXrayTraits::resolveDOMCollectionProperty(JSContext *cx, JSObject *wrapper,
+                                                         JSObject *holder, jsid id, bool set,
+                                                         PropertyDescriptor *desc)
+{
+    // If we are not currently resolving this id and resolveNative is called
+    // we don't do anything. (see defineProperty in case of shadowing is forbidden).
+    ResolvingId *rid = ResolvingId::getResolvingId(holder);
+    if (!rid || rid->mId != id)
+        return true;
+
+    XPCWrappedNative *wn = GetWrappedNativeFromHolder(holder);
+    if (!NATIVE_HAS_FLAG(wn, WantNewResolve))
+        return true;
+
+    // Setting the current ResolvingId in non-shadowing mode. So for this id
+    // Xray won't ignore DOM specific collection properties temporarily.
+    AutoSetWrapperNotShadowing asw(wrapper);
+
+    bool retval = true;
+    JSObject *pobj = NULL;
+    unsigned flags = (set ? JSRESOLVE_ASSIGNING : 0) | JSRESOLVE_QUALIFIED;
+    nsresult rv = wn->GetScriptableInfo()->GetCallback()->NewResolve(wn, cx, wrapper, id,
+                                                                     flags, &pobj, &retval);
+    if (NS_FAILED(rv)) {
+        if (retval)
+            XPCThrower::Throw(rv, cx);
+        return false;
+    }
+
+    if (pobj && !JS_GetPropertyDescriptorById(cx, holder, id,
+                                              JSRESOLVE_QUALIFIED, desc))
+    {
+        return false;
+    }
+
+    return true;
+}
+
+template <typename T>
+static bool
+Is(JSObject *wrapper)
+{
+    JSObject *holder = GetHolder(wrapper);
+    XPCWrappedNative *wn = GetWrappedNativeFromHolder(holder);
+    nsCOMPtr<T> native = do_QueryWrappedNative(wn);
+    return !!native;
+}
+
+// Helper function to work around some limitations of the current XPC 
+// calling mechanism. See: bug 763897.
+// The idea is that we unwrap the 'this' object, and find the wrapped
+// native that belongs to it. Then we simply make the call directly
+// on it after a Query Interface.
+static JSBool
+mozMatchesSelectorStub(JSContext *cx, unsigned argc, jsval *vp)
+{
+    if (argc < 1)
+        JS_ReportError(cx, "Not enough arguments");
+    
+    JSObject *wrapper = JS_THIS_OBJECT(cx, vp);
+    JSString *selector = JS_ValueToString(cx, JS_ARGV(cx, vp)[0]);
+    nsDependentJSString selectorStr;
+    NS_ENSURE_TRUE(selectorStr.init(cx, selector), false);
+
+    nsCOMPtr<nsIDOMElement> element;
+    if (IsWrapper(wrapper) && WrapperFactory::IsXrayWrapper(wrapper)) {       
+        // If it's xray wrapped we can get the wn directly.
+        JSObject *holder = GetHolder(wrapper);
+        XPCWrappedNative *wn = GetWrappedNativeFromHolder(holder);
+        element = do_QueryWrappedNative(wn);
+    } else {
+        // Else we can use the XPC utility function for unwrapping it.
+        nsCOMPtr<nsIXPConnectWrappedNative> iwn;  
+        nsIXPConnect *xpc = nsXPConnect::GetXPConnect();
+        nsresult rv = xpc->GetWrappedNativeOfJSObject(cx, wrapper, 
+                                                      getter_AddRefs(iwn));
+        if (NS_FAILED(rv) || !iwn) {
+            JS_ReportError(cx, "Unexpected object");
+            return false;
+        }
+        element = do_QueryWrappedNative(iwn);
+    }
+
+    if (!element) {
+        JS_ReportError(cx, "Unexpected object");
+        return false;
+    }
+
+    bool ret;
+    nsresult rv = element->MozMatchesSelector(selectorStr, &ret);
+    if (NS_FAILED(rv)) {
+        XPCThrower::Throw(rv, cx);
+        return false;
+    }
+
+    JS_SET_RVAL(cx, vp, BOOLEAN_TO_JSVAL(ret));
+    return true;
+}
+
 bool
 XPCWrappedNativeXrayTraits::resolveNativeProperty(JSContext *cx, JSObject *wrapper,
                                                   JSObject *holder, jsid id, bool set,
                                                   JSPropertyDescriptor *desc)
 {
+    MOZ_ASSERT(js::GetObjectJSClass(holder) == &HolderClass);
+    XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance();
+    if (!set &&
+        id == rt->GetStringID(XPCJSRuntime::IDX_MOZMATCHESSELECTOR) &&
+        Is<nsIDOMElement>(wrapper))
+    {
+        // XPC calling mechanism cannot handle call/bind properly in some cases
+        // especially through xray wrappers. This is a temoorary work around for
+        // this problem for mozMatchesSelector. See: bug 763897.
+        desc->obj = wrapper;
+        desc->attrs = JSPROP_ENUMERATE;
+        JSFunction *fun = JS_NewFunction(cx, mozMatchesSelectorStub, 
+                                         1, 0, JS_GetPrototype(wrapper), 
+                                         "mozMatchesSelector");
+        NS_ENSURE_TRUE(fun, false);
+        desc->value = OBJECT_TO_JSVAL(JS_GetFunctionObject(fun));
+        desc->getter = NULL;
+        desc->setter = NULL;
+        desc->shortid = 0;
+        return true;
+    }
+
     desc->obj = NULL;
 
-    MOZ_ASSERT(js::GetObjectJSClass(holder) == &HolderClass);
     JSObject *wnObject = GetWrappedNativeObjectFromHolder(holder);
     XPCWrappedNative *wn = GetWrappedNative(wnObject);
 
     // This will do verification and the method lookup for us.
     XPCCallContext ccx(JS_CALLER, cx, wnObject, nullptr, id);
 
-    // There are no native numeric properties, so we can shortcut here. We will not
-    // find the property.
+    // There are no native numeric properties, so we can shortcut here. We will
+    // not find the property. However we want to support non shadowing dom
+    // specific collection properties like window.frames, so we still have to
+    // check for those.
     if (!JSID_IS_STRING(id)) {
         /* Not found */
-        return true;
+        return resolveDOMCollectionProperty(cx, wrapper, holder, id, set, desc);
     }
 
     XPCNativeInterface *iface;
     XPCNativeMember *member;
     if (ccx.GetWrapper() != wn ||
         !wn->IsValid()  ||
         !(iface = ccx.GetInterface()) ||
         !(member = ccx.GetMember())) {
         /* Not found */
-        return true;
+        return resolveDOMCollectionProperty(cx, wrapper, holder, id, set, desc);
     }
 
     desc->obj = holder;
     desc->attrs = JSPROP_ENUMERATE;
     desc->getter = NULL;
     desc->setter = NULL;
     desc->shortid = 0;
     desc->value = JSVAL_VOID;
@@ -642,26 +813,16 @@ wrappedJSObject_getter(JSContext *cx, JS
         return false;
     }
 
     vp.set(OBJECT_TO_JSVAL(wrapper));
 
     return WrapperFactory::WaiveXrayAndWrap(cx, vp.address());
 }
 
-template <typename T>
-static bool
-Is(JSObject *wrapper)
-{
-    JSObject *holder = GetHolder(wrapper);
-    XPCWrappedNative *wn = GetWrappedNativeFromHolder(holder);
-    nsCOMPtr<T> native = do_QueryWrappedNative(wn);
-    return !!native;
-}
-
 static JSBool
 WrapURI(JSContext *cx, nsIURI *uri, jsval *vp)
 {
     JSObject *scope = JS_GetGlobalForScopeChain(cx);
     nsresult rv =
         nsXPConnect::FastGetXPConnect()->WrapNativeToJSVal(cx, scope, uri, nullptr,
                                                            &NS_GET_IID(nsIURI), true,
                                                            vp, nullptr);
@@ -840,23 +1001,19 @@ XPCWrappedNativeXrayTraits::resolveOwnPr
         nsresult rv = wn->GetScriptableInfo()->GetCallback()->NewResolve(wn, cx, wrapper, id,
                                                                          flags, &pobj, &retval);
         if (NS_FAILED(rv)) {
             if (retval)
                 XPCThrower::Throw(rv, cx);
             return false;
         }
 
-        if (!pobj) {
-            return true;
-        }
-
 #ifdef DEBUG
-        NS_ASSERTION(JS_HasPropertyById(cx, holder, id, &hasProp) &&
-                     hasProp, "id got defined somewhere else?");
+        NS_ASSERTION(!pobj || (JS_HasPropertyById(cx, holder, id, &hasProp) &&
+                     hasProp), "id got defined somewhere else?");
 #endif
     }
 
     return true;
 }
 
 bool
 XPCWrappedNativeXrayTraits::defineProperty(JSContext *cx, JSObject *wrapper, jsid id,
@@ -1230,17 +1387,17 @@ XrayWrapper<Base, Traits>::getPropertyDe
     }
 
     bool status;
     Wrapper::Action action = set ? Wrapper::SET : Wrapper::GET;
     desc->obj = NULL; // default value
     if (!this->enter(cx, wrapper, id, action, &status))
         return status;
 
-    typename Traits::ResolvingId resolving(wrapper, id);
+    typename Traits::ResolvingIdImpl resolving(wrapper, id);
 
     // Redirect access straight to the wrapper if we should be transparent.
     if (XrayUtils::IsTransparent(cx, wrapper)) {
         JSObject *obj = Traits::getInnerObject(wrapper);
         {
             JSAutoCompartment ac(cx, obj);
             if (!JS_GetPropertyDescriptorById(cx, obj, id,
                                               (set ? JSRESOLVE_ASSIGNING : 0) | JSRESOLVE_QUALIFIED,
@@ -1329,17 +1486,17 @@ XrayWrapper<Base, Traits>::getOwnPropert
     }
 
     bool status;
     Wrapper::Action action = set ? Wrapper::SET : Wrapper::GET;
     desc->obj = NULL; // default value
     if (!this->enter(cx, wrapper, id, action, &status))
         return status;
 
-    typename Traits::ResolvingId resolving(wrapper, id);
+    typename Traits::ResolvingIdImpl resolving(wrapper, id);
 
     // NB: Nothing we do here acts on the wrapped native itself, so we don't
     // enter our policy.
     // Redirect access straight to the wrapper if we should be transparent.
     if (XrayUtils::IsTransparent(cx, wrapper)) {
         JSObject *obj = Traits::getInnerObject(wrapper);
         {
             JSAutoCompartment ac(cx, obj);
--- a/js/xpconnect/wrappers/XrayWrapper.h
+++ b/js/xpconnect/wrappers/XrayWrapper.h
@@ -2,16 +2,17 @@
  * vim: set ts=4 sw=4 et tw=99 ft=cpp:
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "jsapi.h"
 #include "jswrapper.h"
+#include "mozilla/GuardObjects.h"
 
 // Xray wrappers re-resolve the original native properties on the native
 // object and always directly access to those properties.
 // Because they work so differently from the rest of the wrapper hierarchy,
 // we pull them out of the Wrapper inheritance hierarchy and create a
 // little world around them.
 
 class XPCWrappedNative;
@@ -95,9 +96,35 @@ public:
     virtual bool getPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id,
                                        bool set, js::PropertyDescriptor *desc);
     virtual bool getOwnPropertyDescriptor(JSContext *cx, JSObject *proxy,
                                           jsid id, bool set,
                                           js::PropertyDescriptor *desc);
 };
 
 extern SandboxProxyHandler sandboxProxyHandler;
+
+class AutoSetWrapperNotShadowing;
+class XPCWrappedNativeXrayTraits;
+
+class ResolvingId {
+public:
+    ResolvingId(JSObject *wrapper, jsid id);
+    ~ResolvingId();
+
+    bool isXrayShadowing(jsid id);
+    bool isResolving(jsid id);
+    static ResolvingId* getResolvingId(JSObject *holder);
+    static JSObject* getHolderObject(JSObject *wrapper);
+    static ResolvingId *getResolvingIdFromWrapper(JSObject *wrapper);
+
+private:
+    friend class AutoSetWrapperNotShadowing;
+    friend class XPCWrappedNativeXrayTraits;
+
+    jsid mId;
+    JSObject *mHolder;
+    ResolvingId *mPrev;
+    bool mXrayShadowing;
+};
+
 }
+
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -53,17 +53,17 @@
 #include "nsStyleStructInlines.h"
 #include "nsIAppShell.h"
 #include "prenv.h"
 #include "nsIDOMEventTarget.h"
 #include "nsObjectFrame.h"
 #include "nsTransitionManager.h"
 #include "nsAnimationManager.h"
 #include "mozilla/dom/Element.h"
-#include "nsIFrameMessageManager.h"
+#include "nsIMessageManager.h"
 #include "FrameLayerBuilder.h"
 #include "nsDOMMediaQueryList.h"
 #include "nsSMILAnimationController.h"
 #include "mozilla/css/ImageLoader.h"
 
 #ifdef IBMBIDI
 #include "nsBidiPresUtils.h"
 #endif // IBMBIDI
--- a/layout/build/nsLayoutModule.cpp
+++ b/layout/build/nsLayoutModule.cpp
@@ -49,17 +49,17 @@
 #include "nsStyleSheetService.h"
 #include "nsFocusManager.h"
 #include "ThirdPartyUtil.h"
 #include "mozilla/Services.h"
 #include "nsStructuredCloneContainer.h"
 #include "mozilla/Attributes.h"
 
 #include "nsIEventListenerService.h"
-#include "nsIFrameMessageManager.h"
+#include "nsIMessageManager.h"
 
 // Transformiix stuff
 #include "nsXPathEvaluator.h"
 #include "txMozillaXSLTProcessor.h"
 #include "txNodeSetAdaptor.h"
 
 #include "nsDOMParser.h"
 #include "nsDOMSerializer.h"
@@ -417,18 +417,18 @@ nsresult NS_NewContentViewer(nsIContentV
 nsresult NS_NewGenRegularIterator(nsIContentIterator** aResult);
 nsresult NS_NewGenSubtreeIterator(nsIContentIterator** aInstancePtrResult);
 nsresult NS_NewContentDocumentLoaderFactory(nsIDocumentLoaderFactory** aResult);
 nsresult NS_NewHTMLCopyTextEncoder(nsIDocumentEncoder** aResult);
 nsresult NS_NewTextEncoder(nsIDocumentEncoder** aResult);
 nsresult NS_NewContentPolicy(nsIContentPolicy** aResult);
 
 nsresult NS_NewEventListenerService(nsIEventListenerService** aResult);
-nsresult NS_NewGlobalMessageManager(nsIChromeFrameMessageManager** aResult);
-nsresult NS_NewParentProcessMessageManager(nsIFrameMessageManager** aResult);
+nsresult NS_NewGlobalMessageManager(nsIMessageBroadcaster** aResult);
+nsresult NS_NewParentProcessMessageManager(nsIMessageBroadcaster** aResult);
 nsresult NS_NewChildProcessMessageManager(nsISyncMessageSender** aResult);
 
 nsresult NS_NewXULControllers(nsISupports* aOuter, REFNSIID aIID, void** aResult);
 
 #define MAKE_CTOR(ctor_, iface_, func_)                   \
 static nsresult                                           \
 ctor_(nsISupports* aOuter, REFNSIID aIID, void** aResult) \
 {                                                         \
@@ -514,19 +514,19 @@ MAKE_CTOR(CreateXULDocument,            
 // NS_NewXULControllers
 #endif
 #ifdef MOZ_XTF
 MAKE_CTOR(CreateXTFService,               nsIXTFService,               NS_NewXTFService)
 MAKE_CTOR(CreateXMLContentBuilder,        nsIXMLContentBuilder,        NS_NewXMLContentBuilder)
 #endif
 MAKE_CTOR(CreateContentDLF,               nsIDocumentLoaderFactory,    NS_NewContentDocumentLoaderFactory)
 MAKE_CTOR(CreateEventListenerService,     nsIEventListenerService,     NS_NewEventListenerService)
-MAKE_CTOR(CreateGlobalMessageManager,     nsIChromeFrameMessageManager,NS_NewGlobalMessageManager)
-MAKE_CTOR(CreateParentMessageManager,     nsIFrameMessageManager,NS_NewParentProcessMessageManager)
-MAKE_CTOR(CreateChildMessageManager,     nsISyncMessageSender,NS_NewChildProcessMessageManager)
+MAKE_CTOR(CreateGlobalMessageManager,     nsIMessageBroadcaster,       NS_NewGlobalMessageManager)
+MAKE_CTOR(CreateParentMessageManager,     nsIMessageBroadcaster,       NS_NewParentProcessMessageManager)
+MAKE_CTOR(CreateChildMessageManager,      nsISyncMessageSender,        NS_NewChildProcessMessageManager)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsDataDocumentContentPolicy)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsNoDataProtocolContentPolicy)
 MAKE_CTOR(CreatePluginDocument,           nsIDocument,                 NS_NewPluginDocument)
 #ifdef MOZ_MEDIA
 MAKE_CTOR(CreateVideoDocument,            nsIDocument,                 NS_NewVideoDocument)
 #endif
 MAKE_CTOR(CreateFocusManager,             nsIFocusManager,      NS_NewFocusManager)
 
--- a/layout/ipc/test-ipcbrowser-chrome.js
+++ b/layout/ipc/test-ipcbrowser-chrome.js
@@ -31,39 +31,39 @@ function enableAsyncScrolling() {
 
 // Functions affecting the content window.
 
 function loadURL(url) {
     browser().setAttribute('src', url);
 }
 
 function scrollContentBy(dx, dy) {
-    messageManager.sendAsyncMessage("scrollBy",
-                                    { dx: dx, dy: dy });
+    messageManager.broadcastAsyncMessage("scrollBy",
+                                         { dx: dx, dy: dy });
 
 }
 
 function scrollContentTo(x, y) {
-    messageManager.sendAsyncMessage("scrollTo",
-                                    { x: x, y: y });
+    messageManager.broadcastAsyncMessage("scrollTo",
+                                         { x: x, y: y });
 }
 
 function setContentViewport(w, h) {
-    messageManager.sendAsyncMessage("setViewport",
-                                    { w: w, h: h });
+    messageManager.broadcastAsyncMessage("setViewport",
+                                         { w: w, h: h });
 }
 
 function setContentDisplayPort(x, y, w, h) {
-    messageManager.sendAsyncMessage("setDisplayPort",
-                                    { x: x, y: y, w: w, h: h });
+    messageManager.broadcastAsyncMessage("setDisplayPort",
+                                         { x: x, y: y, w: w, h: h });
 }
 
 function setContentResolution(xres, yres) {
-    messageManager.sendAsyncMessage("setResolution",
-                                    { xres: xres, yres: yres });
+    messageManager.broadcastAsyncMessage("setResolution",
+                                         { xres: xres, yres: yres });
 }
 
 // Functions affecting <browser>.
 
 function scrollViewportBy(dx, dy) {
     rootView().scrollBy(dx, dy);
 }
 
@@ -102,18 +102,18 @@ function startAnimatedScrollBy(dx, dy) {
         ddx = Math.min(dx - accumDx, ddx);
         ddy = Math.min(dy - accumDy, ddy);
         accumDx += ddx;
         accumDy += ddy;
 
         rootView().scrollBy(ddx, ddy);
 
         if (!sentScrollBy && 100 <= (now - start)) {
-            messageManager.sendAsyncMessage("scrollBy",
-                                            { dx: dx, dy: dy });
+            messageManager.broadcastAsyncMessage("scrollBy",
+                                                 { dx: dx, dy: dy });
             sentScrollBy = true;
         }
 
         if (now >= end || (accumDx >= dx && accumDy >= dy)) {
             var fixupDx = Math.max(dx - accumDx, 0);
             var fixupDy = Math.max(dy - accumDy, 0);
             rootView().scrollBy(fixupDx, fixupDy);
 
--- a/layout/svg/base/src/nsSVGUtils.cpp
+++ b/layout/svg/base/src/nsSVGUtils.cpp
@@ -728,17 +728,17 @@ nsSVGUtils::ScheduleReflowSVG(nsIFrame *
 
   // If this is triggered, the callers should be fixed to call us before
   // ReflowSVG is called. If we try to mark dirty bits on frames while we're
   // in the process of removing them, things will get messed up.
   NS_ASSERTION(!OuterSVGIsCallingReflowSVG(aFrame),
                "Do not call under nsISVGChildFrame::ReflowSVG!");
 
   // We don't call nsSVGEffects::InvalidateRenderingObservers here because
-  // we should only be called under InvalidateAndScheduleBoundsUpdate (which
+  // we should only be called under InvalidateAndScheduleReflowSVG (which
   // calls InvalidateBounds) or nsSVGDisplayContainerFrame::InsertFrames
   // (at which point the frame has no observers).
 
   if (aFrame->GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD) {
     return;
   }
 
   if (aFrame->GetStateBits() &
--- a/layout/tools/reftest/reftest.js
+++ b/layout/tools/reftest/reftest.js
@@ -257,17 +257,17 @@ function OnRefTestLoad(win)
       doc.removeChild(doc.firstChild);
     }
     doc.appendChild(gBrowser);
 #else
     document.getElementById("reftest-window").appendChild(gBrowser);
 #endif
 
     gBrowserMessageManager = gBrowser.QueryInterface(CI.nsIFrameLoaderOwner)
-                             .frameLoader.messageManager;
+                                     .frameLoader.messageManager;
     // The content script waits for the initial onload, then notifies
     // us.
     RegisterMessageListenersAndLoadContentScript();
 }
 
 function InitAndStartRefTests()
 {
     /* These prefs are optional, so we don't need to spit an error to the log */
--- a/mobile/xul/chrome/content/CapturePickerUI.js
+++ b/mobile/xul/chrome/content/CapturePickerUI.js
@@ -1,15 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 var CapturePickerUI = {
   init: function() {
-    this.messageManager = Cc["@mozilla.org/parentprocessmessagemanager;1"].getService(Ci.nsIFrameMessageManager);
+    this.messageManager = Cc["@mozilla.org/parentprocessmessagemanager;1"]
+                            .getService(Ci.nsIMessageListenerManager);
     this.messageManager.addMessageListener("CapturePicker:Show", this);
   },
   
   receiveMessage: function(aMessage) {
     switch (aMessage.name) {
       case "CapturePicker:Show":
         let params = { result: true };
         let dialog = importDialog(null, "chrome://browser/content/CaptureDialog.xul", params);
--- a/mobile/xul/chrome/content/WebappsUI.js
+++ b/mobile/xul/chrome/content/WebappsUI.js
@@ -6,17 +6,18 @@ var WebappsUI = {
   _dialog: null,
   _manifest: null,
   _perms: [],
   _application: null,
   _browser: null,
 
   init: function() {
     Cu.import("resource://gre/modules/OpenWebapps.jsm");
-    this.messageManager = Cc["@mozilla.org/parentprocessmessagemanager;1"].getService(Ci.nsIFrameMessageManager);
+    this.messageManager = Cc["@mozilla.org/parentprocessmessagemanager;1"]
+                            .getService(Ci.nsIMessageBroadcaster);
     this.messageManager.addMessageListener("OpenWebapps:Install", this);
     this.messageManager.addMessageListener("OpenWebapps:GetInstalledBy", this);
     this.messageManager.addMessageListener("OpenWebapps:AmInstalled", this);
     this.messageManager.addMessageListener("OpenWebapps:MgmtLaunch", this);
     this.messageManager.addMessageListener("OpenWebapps:MgmtList", this);
     this.messageManager.addMessageListener("OpenWebapps:MgmtUninstall", this);
   },
 
@@ -91,61 +92,61 @@ var WebappsUI = {
       allow: function() {
         Services.perms.addFromPrincipal(principal, aType, Ci.nsIPermissionManager.ALLOW_ACTION);
         aCallbacks.allow();
       }
     });
   },
 
   receiveMessage: function(aMessage) {
-    this._browser = aMessage.target.QueryInterface(Ci.nsIFrameMessageManager);
+    this._browser = aMessage.target.QueryInterface(Ci.nsIMessageSender);
     switch(aMessage.name) {
       case "OpenWebapps:Install":
         WebappsUI.show(WebappsUI.convertManifest(aMessage.json));
         break;
       case "OpenWebapps:GetInstalledBy":
         let apps = OpenWebapps.getInstalledBy(aMessage.json.storeURI);
-        this._browser.sendAsyncMessage("OpenWebapps:GetInstalledBy:Return",
+        this._browser.broadcastAsyncMessage("OpenWebapps:GetInstalledBy:Return",
             { apps: apps, callbackID: aMessage.json.callbackID });
         break;
       case "OpenWebapps:AmInstalled":
         let app = OpenWebapps.amInstalled(aMessage.json.appURI);
-        this._browser.sendAsyncMessage("OpenWebapps:AmInstalled:Return",
+        this._browser.broadcastAsyncMessage("OpenWebapps:AmInstalled:Return",
             { installed: app != null, app: app, callbackID: aMessage.json.callbackID });
         break;
       case "OpenWebapps:MgmtList":
         this.askPermission(aMessage, "openWebappsManage", {
           cancel: function() {
-            WebappsUI.messageManager.sendAsyncMessage("OpenWebapps:MgmtList:Return",
+            WebappsUI.messageManager.broadcastAsyncMessage("OpenWebapps:MgmtList:Return",
               { ok: false, callbackID: aMessage.json.callbackID });
           },
 
           allow: function() {
             let list = OpenWebapps.mgmtList();
-            WebappsUI.messageManager.sendAsyncMessage("OpenWebapps:MgmtList:Return",
+            WebappsUI.messageManager.broadcastAsyncMessage("OpenWebapps:MgmtList:Return",
               { ok: true, apps: list, callbackID: aMessage.json.callbackID });
           }
         });
         break;
       case "OpenWebapps:MgmtLaunch":
         let res = OpenWebapps.mgmtLaunch(aMessage.json.origin);
-        this._browser.sendAsyncMessage("OpenWebapps:MgmtLaunch:Return",
+        this._browser.broadcastAsyncMessage("OpenWebapps:MgmtLaunch:Return",
             { ok: res, callbackID: aMessage.json.callbackID });
         break;
       case "OpenWebapps:MgmtUninstall":
         this.askPermission(aMessage, "openWebappsManage", {
           cancel: function() {
-            WebappsUI.messageManager.sendAsyncMessage("OpenWebapps:MgmtUninstall:Return",
+            WebappsUI.messageManager.broadcastAsyncMessage("OpenWebapps:MgmtUninstall:Return",
               { ok: false, callbackID: aMessage.json.callbackID });
           },
 
           allow: function() {
             let app = OpenWebapps.amInstalled(aMessage.json.origin);
             let uninstalled = OpenWebapps.mgmtUninstall(aMessage.json.origin);
-            WebappsUI.messageManager.sendAsyncMessage("OpenWebapps:MgmtUninstall:Return",
+            WebappsUI.messageManager.broadcastAsyncMessage("OpenWebapps:MgmtUninstall:Return",
               { ok: uninstalled, app: app, callbackID: aMessage.json.callbackID });
           }
         });
         break;
     }
   },
 
   checkBox: function(aEvent) {
@@ -191,17 +192,17 @@ var WebappsUI = {
 
     // Force a modal dialog
     this._dialog.waitForClose();
   },
 
   hide: function hide() {
     this.close();
 
-    this._browser.sendAsyncMessage("OpenWebapps:InstallAborted", { callbackID: this._application.callbackID });
+    this._browser.broadcastAsyncMessage("OpenWebapps:InstallAborted", { callbackID: this._application.callbackID });
   },
   
   close: function close() {
     this._dialog.close();
     this._dialog = null;
     BrowserUI.popPopup(this);
   },
 
@@ -234,14 +235,14 @@ var WebappsUI = {
 
     if (document.getElementById("webapps-homescreen-checkbox").checked)
       WebappsUI.addToHome(this._application);
 
     this.close();
     try {
       OpenWebapps.install(this._application);
       let app = OpenWebapps.amInstalled(this._application.appURI);
-      this.messageManager.sendAsyncMessage("OpenWebapps:InstallDone", { app: app, callbackID: this._application.callbackID });
+      this.messageManager.broadcastAsyncMessage("OpenWebapps:InstallDone", { app: app, callbackID: this._application.callbackID });
     } catch(e) {
       Cu.reportError(e);
     }
   }
 };
--- a/mobile/xul/chrome/content/bindings/browser.xml
+++ b/mobile/xul/chrome/content/bindings/browser.xml
@@ -9,17 +9,17 @@
   %findBarDTD;
 ]>
 
 <bindings id="remoteBrowserBindings"
           xmlns="http://www.mozilla.org/xbl"
           xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
   <binding id="local-browser" extends="chrome://global/content/bindings/browser.xml#browser">
-    <implementation type="application/javascript" implements="nsIAccessibleProvider, nsIObserver, nsIDOMEventListener, nsIFrameMessageListener">
+    <implementation type="application/javascript" implements="nsIAccessibleProvider, nsIObserver, nsIDOMEventListener, nsIMessageListener">
       <field name="_securityUI">null</field>
       <property name="securityUI">
         <getter><![CDATA[
           return this._securityUI || {};
         ]]></getter>
         <setter><![CDATA[
           this._securityUI = val;
         ]]></setter>
@@ -589,17 +589,17 @@
           return;
         ]]></body>
       </method>
 
     </implementation>
   </binding>
 
   <binding id="remote-browser" extends="#local-browser">
-    <implementation type="application/javascript" implements="nsIAccessibleProvider, nsIObserver, nsIDOMEventListener, nsIFrameMessageListener">
+    <implementation type="application/javascript" implements="nsIAccessibleProvider, nsIObserver, nsIDOMEventListener, nsIMessageListener">
       <property name="accessibleType" readonly="true">
         <getter>
           <![CDATA[
             throw "accessibleType: Supports Remote?";
           ]]>
         </getter>
       </property>
 
--- a/mobile/xul/components/LoginManager.js
+++ b/mobile/xul/components/LoginManager.js
@@ -66,17 +66,17 @@ LoginManager.prototype = {
      * is created.
      *
      * Note: Service created in /browser/base/content/browser.js,
      *       delayedStartup()
      */
     init : function () {
         // Add content listener.
         var messageManager = Cc["@mozilla.org/globalmessagemanager;1"].
-                             getService(Ci.nsIChromeFrameMessageManager);
+                             getService(Ci.nsIMessageListenerManager);
         messageManager.loadFrameScript("chrome://browser/content/LoginManagerChild.js", true);
         messageManager.addMessageListener("PasswordMgr:FormSubmitted", this);
         messageManager.addMessageListener("PasswordMgr:GetPasswords", this);
 
         // Get constructor for nsILoginInfo
         this._nsLoginInfo = new Components.Constructor(
             "@mozilla.org/login-manager/loginInfo;1", Ci.nsILoginInfo);
 
--- a/netwerk/protocol/app/AppProtocolHandler.js
+++ b/netwerk/protocol/app/AppProtocolHandler.js
@@ -6,21 +6,19 @@
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
-XPCOMUtils.defineLazyGetter(this, "cpmm", function() {
-  return Cc["@mozilla.org/childprocessmessagemanager;1"]
-         .getService(Ci.nsIFrameMessageManager)
-         .QueryInterface(Ci.nsISyncMessageSender);
-});
+XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
+                                   "@mozilla.org/childprocessmessagemanager;1",
+                                   "nsISyncMessageSender");
 
 function AppProtocolHandler() {
   this._basePath = null;
 }
 
 AppProtocolHandler.prototype = {
   classID: Components.ID("{b7ad6144-d344-4687-b2d0-b6b9dce1f07f}"),
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIProtocolHandler]),
--- a/testing/marionette/marionette-actors.js
+++ b/testing/marionette/marionette-actors.js
@@ -110,17 +110,17 @@ MarionetteRootActor.prototype.requestTyp
  */
 function MarionetteDriverActor(aConnection)
 {
   this.uuidGen = Cc["@mozilla.org/uuid-generator;1"]
                    .getService(Ci.nsIUUIDGenerator);
 
   this.conn = aConnection;
   this.messageManager = Cc["@mozilla.org/globalmessagemanager;1"]
-                          .getService(Ci.nsIChromeFrameMessageManager);
+                          .getService(Ci.nsIMessageBroadcaster);
   this.browsers = {}; //holds list of BrowserObjs
   this.curBrowser = null; // points to current browser
   this.context = "content";
   this.scriptTimeout = null;
   this.timer = null;
   this.marionetteLog = new MarionetteLogObj();
   this.marionettePerf = new MarionettePerfData();
   this.command_id = null;
@@ -148,17 +148,17 @@ MarionetteDriverActor.prototype = {
    * Helper method to send async messages to the content listener
    *
    * @param string name
    *        Suffix of the targetted message listener (Marionette:<suffix>)
    * @param object values
    *        Object to send to the listener
    */
   sendAsync: function MDA_sendAsync(name, values) {
-    this.messageManager.sendAsyncMessage("Marionette:" + name + this.curBrowser.curFrameId, values);
+    this.messageManager.broadcastAsyncMessage("Marionette:" + name + this.curBrowser.curFrameId, values);
   },
 
   /**
    * Helper methods:
    */
 
   /**
    * Generic method to pass a response to the client
@@ -362,17 +362,17 @@ MarionetteDriverActor.prototype = {
 
     if (!Services.prefs.getBoolPref("marionette.contentListener")) {
       waitForWindow.call(this);
     }
     else if ((appName == "B2G") && (this.curBrowser == null)) {
       //if there is a content listener, then we just wake it up
       this.addBrowser(this.getCurrentWindow());
       this.curBrowser.startSession(false);
-      this.messageManager.sendAsyncMessage("Marionette:restart", {});
+      this.messageManager.broadcastAsyncMessage("Marionette:restart", {});
     }
     else {
       this.sendError("Session already running", 500, null);
     }
   },
 
   getSessionCapabilities: function MDA_getSessionCapabilities(){
     let rotatable = appName == "B2G" ? true : false;
@@ -1294,28 +1294,28 @@ MarionetteDriverActor.prototype = {
    *
    * If it is a B2G environment, it will make the main content listener sleep, and close
    * all other listeners. The main content listener persists after disconnect (it's the homescreen),
    * and can safely be reused.
    */
   deleteSession: function MDA_deleteSession() {
     if (this.curBrowser != null) {
       if (appName == "B2G") {
-        this.messageManager.sendAsyncMessage("Marionette:sleepSession" + this.curBrowser.mainContentId, {});
+        this.messageManager.broadcastAsyncMessage("Marionette:sleepSession" + this.curBrowser.mainContentId, {});
         this.curBrowser.knownFrames.splice(this.curBrowser.knownFrames.indexOf(this.curBrowser.mainContentId), 1);
       }
       else {
         //don't set this pref for B2G since the framescript can be safely reused
         Services.prefs.setBoolPref("marionette.contentListener", false);
       }
       this.curBrowser.closeTab();
       //delete session in each frame in each browser
       for (let win in this.browsers) {
         for (let i in this.browsers[win].knownFrames) {
-          this.messageManager.sendAsyncMessage("Marionette:deleteSession" + this.browsers[win].knownFrames[i], {});
+          this.messageManager.broadcastAsyncMessage("Marionette:deleteSession" + this.browsers[win].knownFrames[i], {});
         }
       }
       let winEnum = this.getWinEnumerator();
       while (winEnum.hasMoreElements()) {
         winEnum.getNext().messageManager.removeDelayedFrameScript("chrome://marionette/content/marionette-listener.js"); 
       }
     }
     this.sendOk();
@@ -1514,18 +1514,18 @@ function BrowserObj(win) {
   this.DESKTOP = "desktop";
   this.B2G = "B2G";
   this.browser;
   this.tab = null;
   this.knownFrames = [];
   this.curFrameId = null;
   this.startPage = "about:blank";
   this.mainContentId = null; // used in B2G to identify the homescreen content page
-  this.messageManager = Cc["@mozilla.org/globalmessagemanager;1"].
-                             getService(Ci.nsIChromeFrameMessageManager);
+  this.messageManager = Cc["@mozilla.org/globalmessagemanager;1"]
+                          .getService(Ci.nsIMessageBroadcaster);
   this.newSession = true; //used to set curFrameId upon new session
   this.elementManager = new ElementManager([SELECTOR, NAME, LINK_TEXT, PARTIAL_LINK_TEXT]);
   this.setBrowser(win);
 }
 
 BrowserObj.prototype = {
   /**
    * Set the browser if the application is not B2G
--- a/testing/mochitest/specialpowers/components/SpecialPowersObserver.js
+++ b/testing/mochitest/specialpowers/components/SpecialPowersObserver.js
@@ -25,17 +25,17 @@ var loader = Components.classes["@mozill
                        .getService(Components.interfaces.mozIJSSubScriptLoader);
 loader.loadSubScript("chrome://specialpowers/content/SpecialPowersObserverAPI.js");
 
 
 /* XPCOM gunk */
 function SpecialPowersObserver() {
   this._isFrameScriptLoaded = false;
   this._messageManager = Cc["@mozilla.org/globalmessagemanager;1"].
-                         getService(Ci.nsIChromeFrameMessageManager);
+                         getService(Ci.nsIMessageBroadcaster);
 }
 
 
 SpecialPowersObserver.prototype = new SpecialPowersObserverAPI();
 
   SpecialPowersObserver.prototype.classDescription = "Special powers Observer for use in testing.";
   SpecialPowersObserver.prototype.classID = Components.ID("{59a52458-13e0-4d93-9d85-a637344f29a1}");
   SpecialPowersObserver.prototype.contractID = "@mozilla.org/special-powers-observer;1";
@@ -72,17 +72,17 @@ SpecialPowersObserver.prototype = new Sp
       default:
         this._observe(aSubject, aTopic, aData);
         break;
     }
   };
 
   SpecialPowersObserver.prototype._sendAsyncMessage = function(msgname, msg)
   {
-    this._messageManager.sendAsyncMessage(msgname, msg);
+    this._messageManager.broadcastAsyncMessage(msgname, msg);
   };
 
   SpecialPowersObserver.prototype._receiveMessage = function(aMessage) {
     return this._receiveMessageAPI(aMessage);
   };
 
   SpecialPowersObserver.prototype.init = function()
   {
--- a/toolkit/components/contentprefs/nsContentPrefService.js
+++ b/toolkit/components/contentprefs/nsContentPrefService.js
@@ -162,17 +162,17 @@ var inMemoryPrefsProto = {
 };
 
 ContentPrefService.prototype = {
   //**************************************************************************//
   // XPCOM Plumbing
 
   classID:          Components.ID("{e6a3f533-4ffa-4615-8eb4-d4e72d883fa7}"),
   QueryInterface:   XPCOMUtils.generateQI([Ci.nsIContentPrefService,
-                                           Ci.nsIFrameMessageListener]),
+                                           Ci.nsIMessageListener]),
 
 
   //**************************************************************************//
   // Convenience Getters
 
   // Observer Service
   __observerSvc: null,
   get _observerSvc() {
--- a/toolkit/components/contentprefs/tests/unit_ipc/test_contentPrefs_parentipc.js
+++ b/toolkit/components/contentprefs/tests/unit_ipc/test_contentPrefs_parentipc.js
@@ -6,17 +6,17 @@ function run_test() {
             createInstance(Ci.nsIContentPrefService).
             wrappedJSObject;
 
   var messageHandler = cps;
   // FIXME: For now, use the wrappedJSObject hack, until bug
   //        593407 which will clean that up. After that, use
   //        the commented out line below it.
   messageHandler = cps.wrappedJSObject;
-  //messageHandler = cps.QueryInterface(Ci.nsIFrameMessageListener);
+  //messageHandler = cps.QueryInterface(Ci.nsIMessageListener);
 
   // Cannot get values
   do_check_false(messageHandler.receiveMessage({
     name: "ContentPref:getPref",
     json: { group: 'group2', name: 'name' } }).succeeded);
 
   // Cannot set general values
   messageHandler.receiveMessage({ name: "ContentPref:setPref",
@@ -50,17 +50,17 @@ function run_test() {
         return true;
       } else {
         return messageHandler.receiveMessage(aMessage);
       }
     },
   };
 
   var mM = Cc["@mozilla.org/parentprocessmessagemanager;1"].
-           getService(Ci.nsIFrameMessageManager);
+           getService(Ci.nsIMessageListenerManager);
   mM.addMessageListener("ContentPref:setPref", messageProxy);
   mM.addMessageListener("ContentPref:getPref", messageProxy);
   mM.addMessageListener("ContentPref:QUIT", messageProxy);
 
   // Mock storage. This is necessary because
   // the IPC xpcshell setup doesn't do well with the normal storage
   // engine.
 
--- a/toolkit/components/satchel/nsFormHistory.js
+++ b/toolkit/components/satchel/nsFormHistory.js
@@ -16,17 +16,17 @@ const DAY_IN_MS  = 86400000; // 1 day in
 function FormHistory() {
     this.init();
 }
 
 FormHistory.prototype = {
     classID          : Components.ID("{0c1bb408-71a2-403f-854a-3a0659829ded}"),
     QueryInterface   : XPCOMUtils.generateQI([Ci.nsIFormHistory2,
                                               Ci.nsIObserver,
-                                              Ci.nsIFrameMessageListener,
+                                              Ci.nsIMessageListener,
                                               Ci.nsISupportsWeakReference,
                                               ]),
 
     debug          : true,
     enabled        : true,
     saveHttpsForms : true,
 
     // The current database schema.
@@ -99,17 +99,17 @@ FormHistory.prototype = {
     init : function init() {
         Services.prefs.addObserver("browser.formfill.", this, true);
 
         this.updatePrefs();
 
         this.dbStmts = {};
 
         this.messageManager = Cc["@mozilla.org/globalmessagemanager;1"].
-                              getService(Ci.nsIChromeFrameMessageManager);
+                              getService(Ci.nsIMessageListenerManager);
         this.messageManager.loadFrameScript("chrome://satchel/content/formSubmitListener.js", true);
         this.messageManager.addMessageListener("FormHistory:FormSubmitEntries", this);
 
         // Add observers
         Services.obs.addObserver(this, "profile-before-change", true);
         Services.obs.addObserver(this, "idle-daily", true);
         Services.obs.addObserver(this, "formhistory-expire-now", true);
     },
--- a/toolkit/mozapps/extensions/ChromeManifestParser.jsm
+++ b/toolkit/mozapps/extensions/ChromeManifestParser.jsm
@@ -20,18 +20,18 @@ const MSG_JAR_FLUSH = "AddonJarFlush";
 /**
  * Sends local and remote notifications to flush a JAR file cache entry
  *
  * @param aJarFile
  *        The ZIP/XPI/JAR file as a nsIFile
  */
 function flushJarCache(aJarFile) {
   Services.obs.notifyObservers(aJarFile, "flush-cache-entry", null);
-  Cc["@mozilla.org/globalmessagemanager;1"].getService(Ci.nsIChromeFrameMessageManager)
-    .sendAsyncMessage(MSG_JAR_FLUSH, aJarFile.path);
+  Cc["@mozilla.org/globalmessagemanager;1"].getService(Ci.nsIMessageBroadcaster)
+    .broadcastAsyncMessage(MSG_JAR_FLUSH, aJarFile.path);
 }
 
 
 /**
  * Parses chrome manifest files.
  */
 var ChromeManifestParser = {
 
--- a/toolkit/mozapps/extensions/XPIProvider.jsm
+++ b/toolkit/mozapps/extensions/XPIProvider.jsm
@@ -1020,18 +1020,18 @@ function buildJarURI(aJarfile, aPath) {
 /**
  * Sends local and remote notifications to flush a JAR file cache entry
  *
  * @param aJarFile
  *        The ZIP/XPI/JAR file as a nsIFile
  */
 function flushJarCache(aJarFile) {
   Services.obs.notifyObservers(aJarFile, "flush-cache-entry", null);
-  Cc["@mozilla.org/globalmessagemanager;1"].getService(Ci.nsIChromeFrameMessageManager)
-    .sendAsyncMessage(MSG_JAR_FLUSH, aJarFile.path);
+  Cc["@mozilla.org/globalmessagemanager;1"].getService(Ci.nsIMessageBroadcaster)
+    .broadcastAsyncMessage(MSG_JAR_FLUSH, aJarFile.path);
 }
 
 function flushStartupCache() {
   // Init this, so it will get the notification.
   Services.obs.notifyObservers(null, "startupcache-invalidate", null);
 }
 
 /**
--- a/toolkit/mozapps/extensions/addonManager.js
+++ b/toolkit/mozapps/extensions/addonManager.js
@@ -35,17 +35,17 @@ Components.utils.import("resource://gre/
 Components.utils.import("resource://gre/modules/Services.jsm");
 
 var gSingleton = null;
 
 function amManager() {
   Components.utils.import("resource://gre/modules/AddonManager.jsm");
 
   var messageManager = Cc["@mozilla.org/globalmessagemanager;1"].
-                       getService(Ci.nsIChromeFrameMessageManager);
+                       getService(Ci.nsIMessageListenerManager);
 
   messageManager.addMessageListener(MSG_INSTALL_ENABLED, this);
   messageManager.addMessageListener(MSG_INSTALL_ADDONS, this);
   messageManager.loadFrameScript(CHILD_SCRIPT, true, true);
 }
 
 amManager.prototype = {
   observe: function AMC_observe(aSubject, aTopic, aData) {
--- a/toolkit/themes/pinstripe/global/media/videocontrols.css
+++ b/toolkit/themes/pinstripe/global/media/videocontrols.css
@@ -72,24 +72,24 @@
 }
 
 /* .scale-thumb is an element inside the <scale> implementation. */
 .volumeControl .scale-thumb {
   /* Override the default thumb appearance with a custom image. */
   -moz-appearance: none;
   background: url(chrome://global/skin/media/volumeThumb.png) no-repeat center;
   border: none;
-  min-width: 16px;
-  min-height: 11px;
+  min-width: 21px;
+  min-height: 10px;
 }
 
 .volumeBackgroundBar {
   /* margin left/right: make bar 8px wide (control width = 28, minus 2 * 10 margin) */
   margin: 0 10px;
-  background-color: rgba(255,255,255,.5);
+  background-color: rgba(255,255,255,.75);
   border-radius: 2.5px;
 }
 
 .durationBox {
   -moz-box-pack: center;
 }
 
 .durationLabel {
index 75ab7fb282ad3a867d64a03dba49694c0f319d26..cfd77f65045564e2db5ee7c6c5dcf82067594f64
GIT binary patch
literal 210
zc%17D@N?(olHy`uVBq!ia0vp^qCm{W!3HFwr;FYIQY`6?zK#qG8~eHcB(eheoCO|{
z#S9F52SAuH>slu#P*AGGHKHUqKdq!Zu_%=xATcwqM9<GPM4`-B&s5LQz~D>KLZB)?
zPZ!4!3;*OF|Nq-Fa|DYnkX*%JGDnD~P<ocOXxO@lkMm`CN_onhZ%0M{pWN)u%j#+%
zdsrkR)I{hWXUgNlC$b86iKy})xMZLw72d|kV8o!Jv8_(W2xu~cr>mdKI;Vst0Jxz$
As{jB1
--- a/toolkit/themes/winstripe/global/media/videocontrols.css
+++ b/toolkit/themes/winstripe/global/media/videocontrols.css
@@ -74,24 +74,24 @@
 }
 
 /* .scale-thumb is an element inside the <scale> implementation. */
 .volumeControl .scale-thumb {
   /* Override the default thumb appearance with a custom image. */
   -moz-appearance: none;
   background: url(chrome://global/skin/media/volumeThumb.png) no-repeat center;
   border: none;
-  min-width: 16px;
-  min-height: 11px;
+  min-width: 21px;
+  min-height: 10px;
 }
 
 .volumeBackgroundBar {
   /* margin left/right: make bar 8px wide (control width = 28, minus 2 * 10 margin) */
   margin: 0 10px;
-  background-color: rgba(255,255,255,.5);
+  background-color: rgba(255,255,255,.75);
   border-radius: 2.5px;
 }
 
 .durationBox {
   -moz-box-pack: center;
 }
 
 .durationLabel {
index 75ab7fb282ad3a867d64a03dba49694c0f319d26..cfd77f65045564e2db5ee7c6c5dcf82067594f64
GIT binary patch
literal 210
zc%17D@N?(olHy`uVBq!ia0vp^qCm{W!3HFwr;FYIQY`6?zK#qG8~eHcB(eheoCO|{
z#S9F52SAuH>slu#P*AGGHKHUqKdq!Zu_%=xATcwqM9<GPM4`-B&s5LQz~D>KLZB)?
zPZ!4!3;*OF|Nq-Fa|DYnkX*%JGDnD~P<ocOXxO@lkMm`CN_onhZ%0M{pWN)u%j#+%
zdsrkR)I{hWXUgNlC$b86iKy})xMZLw72d|kV8o!Jv8_(W2xu~cr>mdKI;Vst0Jxz$
As{jB1