Merge m-c to b2g-inbound. a=merge
authorRyan VanderMeulen <ryanvm@gmail.com>
Mon, 23 Jun 2014 10:58:47 -0400
changeset 190206 c65bf5a0595c5bf43fde1250bc5d459669a2cce4
parent 190205 df3fc195770ffc096f0607dc1e96a1f1909793aa (current diff)
parent 190107 31de1a84b27f7bf1a15d3dc9ea8a01f4acd7bd75 (diff)
child 190207 41e817fb25f06c92f61502541c27f7bfd8c6738d
push id27003
push userkwierso@gmail.com
push dateTue, 24 Jun 2014 01:56:11 +0000
treeherdermozilla-central@e86b84998b18 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone33.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge m-c to b2g-inbound. a=merge
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfoClasses.h
dom/bindings/Bindings.conf
dom/webidl/moz.build
dom/xslt/xpath/nsXPathResult.cpp
dom/xslt/xpath/nsXPathResult.h
layout/style/nsCSSStyleSheet.cpp
layout/style/nsCSSStyleSheet.h
mobile/android/base/home/LastTabsPanel.java
mobile/android/base/home/MostRecentPanel.java
mobile/android/base/resources/drawable-large-land-v11/home_history_tabs_indicator.xml
mobile/android/base/resources/drawable-xlarge-v11/home_history_tabs_indicator.xml
mobile/android/base/resources/drawable/home_history_tabs_indicator.xml
mobile/android/base/resources/layout-large-land-v11/home_history_panel.xml
mobile/android/base/resources/layout-large-land-v11/home_history_tabs_indicator.xml
mobile/android/base/resources/layout-xlarge-v11/home_history_panel.xml
mobile/android/base/resources/layout-xlarge-v11/home_history_tabs_indicator.xml
mobile/android/base/resources/layout/home_history_tabs_indicator.xml
mobile/android/base/resources/layout/home_last_tabs_panel.xml
mobile/android/base/resources/layout/home_most_recent_panel.xml
mobile/android/base/resources/values-large-land-v11/dimens.xml
mobile/android/base/resources/values-xlarge-land-v11/dimens.xml
--- a/accessible/src/generic/DocAccessible.cpp
+++ b/accessible/src/generic/DocAccessible.cpp
@@ -1298,17 +1298,17 @@ DocAccessible::GetAccessibleByUniqueIDIn
   }
 
   return nullptr;
 }
 
 Accessible*
 DocAccessible::GetAccessibleOrContainer(nsINode* aNode) const
 {
-  if (!aNode || !aNode->IsInDoc())
+  if (!aNode || !aNode->GetCrossShadowCurrentDoc())
     return nullptr;
 
   nsINode* currNode = aNode;
   Accessible* accessible = nullptr;
   while (!(accessible = GetAccessible(currNode)) &&
          (currNode = currNode->GetParentNode()));
 
   return accessible;
--- a/accessible/src/jsat/ContentControl.jsm
+++ b/accessible/src/jsat/ContentControl.jsm
@@ -70,16 +70,19 @@ this.ContentControl.prototype = {
 
   receiveMessage: function cc_receiveMessage(aMessage) {
     Logger.debug(() => {
       return ['ContentControl.receiveMessage',
         aMessage.name,
         JSON.stringify(aMessage.json)];
     });
 
+    // If we get an explicit message, we should immediately cancel any autoMove
+    this.cancelAutoMove();
+
     try {
       let func = this['handle' + aMessage.name.slice(9)]; // 'AccessFu:'.length
       if (func) {
         func.bind(this)(aMessage);
       } else {
         Logger.warning('ContentControl: Unhandled message:', aMessage.name);
       }
     } catch (x) {
@@ -376,18 +379,17 @@ this.ContentControl.prototype = {
    *    focus move. Default 0.
    * - noOpIfOnScreen: if accessible is alive and visible, don't do anything.
    * - forcePresent: present cursor location, whether we move or don't.
    * - moveToFocused: if there is a focused accessible move to that. This takes
    *    precedence over given anchor.
    * - moveMethod: pivot move method to use, default is 'moveNext',
    */
   autoMove: function cc_autoMove(aAnchor, aOptions = {}) {
-    let win = this.window;
-    win.clearTimeout(this._autoMove);
+    this.cancelAutoMove();
 
     let moveFunc = () => {
       let vc = this.vc;
       let acc = aAnchor;
       let rule = aOptions.onScreenOnly ?
         TraversalRules.SimpleOnScreen : TraversalRules.Simple;
       let forcePresentFunc = () => {
         if (aOptions.forcePresent) {
@@ -427,18 +429,23 @@ this.ContentControl.prototype = {
       });
 
       if (!moved && !sentToChild) {
         forcePresentFunc();
       }
     };
 
     if (aOptions.delay) {
-      this._autoMove = win.setTimeout(moveFunc, aOptions.delay);
+      this._autoMove = this.window.setTimeout(moveFunc, aOptions.delay);
     } else {
       moveFunc();
     }
   },
 
+  cancelAutoMove: function cc_cancelAutoMove() {
+    this.window.clearTimeout(this._autoMove);
+    this._autoMove = 0;
+  },
+
   QueryInterface: XPCOMUtils.generateQI([Ci.nsISupportsWeakReference,
     Ci.nsIMessageListener
   ])
 };
--- a/accessible/src/windows/msaa/AccessibleWrap.h
+++ b/accessible/src/windows/msaa/AccessibleWrap.h
@@ -213,11 +213,12 @@ protected:
 } // namespace mozilla
 
 #ifdef XP_WIN
 // Undo the windows.h damage
 #undef GetMessage
 #undef CreateEvent
 #undef GetClassName
 #undef GetBinaryType
+#undef RemoveDirectory
 #endif
 
 #endif
--- a/accessible/tests/mochitest/elm/test_shadowroot.html
+++ b/accessible/tests/mochitest/elm/test_shadowroot.html
@@ -9,32 +9,30 @@
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
 
   <script type="application/javascript"
           src="../common.js"></script>
   <script type="application/javascript"
           src="../role.js"></script>
 
   <script type="application/javascript">
-    SpecialPowers.setBoolPref("dom.webcomponents.enabled", true);
     function doTest()
     {
       testElm("component", {
         role: ROLE_GROUPING,
         children: [
         {
           role: ROLE_PUSHBUTTON,
         },
         {
           role: ROLE_LINK,
         },
         ]
       });
 
-      SpecialPowers.clearUserPref("dom.webcomponents.enabled");
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   </script>
 </head>
 <body>
--- a/accessible/tests/mochitest/hittest/a11y.ini
+++ b/accessible/tests/mochitest/hittest/a11y.ini
@@ -1,11 +1,12 @@
 [DEFAULT]
 support-files = zoom_tree.xul
 
 [test_browser.html]
 [test_canvas_hitregion.html]
 skip-if = (os == "android" || appname == "b2g")
 [test_general.html]
 [test_menu.xul]
+[test_shadowroot.html]
 [test_zoom.html]
 [test_zoom_text.html]
 [test_zoom_tree.xul]
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/hittest/test_shadowroot.html
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>ShadowRoot hit tests</title>
+  <link rel="stylesheet" type="text/css"
+        href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+
+  <script type="application/javascript"
+          src="../common.js"></script>
+  <script type="application/javascript"
+          src="../layout.js"></script>
+
+  <script type="application/javascript">
+    function doTest()
+    {
+      var componentAcc = getAccessible('component1');
+      testChildAtPoint(componentAcc, 1, 1, componentAcc.firstChild,
+                       componentAcc.firstChild);
+
+      componentAcc = getAccessible('component2');
+      testChildAtPoint(componentAcc, 1, 1, componentAcc.firstChild,
+                       componentAcc.firstChild);
+      SimpleTest.finish();
+    }
+
+    SimpleTest.waitForExplicitFinish();
+    addA11yLoadEvent(doTest);
+  </script>
+</head>
+<body>
+
+  <a target="_blank"
+     title="Test getChildAtPoint works for shadow DOM content"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=1027315">
+    Mozilla Bug 1027315
+  </a><br/>
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test">
+  </pre>
+
+  <div role="group" class="components" id="component1" style="display: inline-block;">
+  <!--
+    <div role="button" id="component-child"
+         style="width: 100px; height: 100px; background-color: pink;">
+    </div>
+  -->
+  </div>
+  <div role="group" class="components"  id="component2" style="display: inline-block;">
+  <!--
+    <button>Hello world</button>
+  -->
+  </div>
+  <script>
+    // This routine adds the comment children of each 'component' to its
+    // shadow root.
+    var components = document.querySelectorAll('.components');
+    for (var i = 0; i < components.length; i++) {
+      var component = components[i];
+      var shadow = component.createShadowRoot();
+      for (var child = component.firstChild; child; child = child.nextSibling) {
+        if (child.nodeType === 8)
+          shadow.innerHTML = child.data;
+      }
+    }
+  </script>
+
+</body>
+</html>
--- a/browser/app/blocklist.xml
+++ b/browser/app/blocklist.xml
@@ -1,10 +1,10 @@
 <?xml version="1.0"?>
-<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1402612020000">
+<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1403216209000">
   <emItems>
       <emItem  blockID="i454" id="sqlmoz@facebook.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
                                 <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
                     <prefs>
               </prefs>
@@ -84,16 +84,22 @@
               </prefs>
     </emItem>
       <emItem  blockID="i105" id="{95ff02bc-ffc6-45f0-a5c8-619b8226a9de}">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
+      <emItem  blockID="i626" id="{20AD702C-661E-4534-8CE9-BA4EC9AD6ECC}">
+                        <versionRange  minVersion="0" maxVersion="*" severity="3">
+                    </versionRange>
+                    <prefs>
+              </prefs>
+    </emItem>
       <emItem  blockID="i20" id="{AB2CE124-6272-4b12-94A9-7303C7397BD1}">
                         <versionRange  minVersion="0.1" maxVersion="5.2.0.7164" severity="1">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i506" id="/^ext@bettersurfplus/">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
@@ -299,20 +305,18 @@
               </prefs>
     </emItem>
       <emItem  blockID="i467" id="plugin@analytic-s.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
-      <emItem  blockID="i496" id="{ACAA314B-EEBA-48e4-AD47-84E31C44796C}">
-                        <versionRange  minVersion="0" maxVersion="*" severity="1">
-                    </versionRange>
-                    <prefs>
+      <emItem  blockID="i47" id="youtube@youtube2.com">
+                          <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i360" id="ytd@mybrowserbar.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
@@ -360,18 +364,18 @@
               </prefs>
     </emItem>
       <emItem  blockID="i62" id="jid0-EcdqvFOgWLKHNJPuqAnawlykCGZ@jetpack">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
-      <emItem  blockID="i584" id="{52b0f3db-f988-4788-b9dc-861d016f4487}">
-                        <versionRange  minVersion="0" maxVersion="0.1.9999999" severity="1">
+      <emItem  blockID="i624" id="/^({b95faac1-a3d7-4d69-8943-ddd5a487d966}|{ecce0073-a837-45a2-95b9-600420505f7e}|{2713b394-286f-4d7c-89ea-4174eeab9f5a}|{da7a20cf-bef4-4342-ad78-0240fdf87055})$/">
+                        <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i472" id="linksicle@linksicle.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
                     <prefs>
@@ -692,33 +696,39 @@
     </emItem>
       <emItem  blockID="i479" id="mbrsepone@facebook.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i620" id="{21EAF666-26B3-4A3C-ABD0-CA2F5A326744}">
-                        <versionRange  minVersion="0" maxVersion="*" severity="1">
+                        <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i552" id="jid0-O6MIff3eO5dIGf5Tcv8RsJDKxrs@jetpack">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i256" id="/^[0-9a-f]+@[0-9a-f]+\.info/">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
+      <emItem  blockID="i584" id="{52b0f3db-f988-4788-b9dc-861d016f4487}">
+                        <versionRange  minVersion="0" maxVersion="0.1.9999999" severity="1">
+                    </versionRange>
+                    <prefs>
+              </prefs>
+    </emItem>
       <emItem  blockID="i370" id="happylyrics@hpyproductions.net">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i440" id="{2d069a16-fca1-4e81-81ea-5d5086dcbd0c}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
@@ -1206,18 +1216,20 @@
               </prefs>
     </emItem>
       <emItem  blockID="i334" id="{0F827075-B026-42F3-885D-98981EE7B1AE}">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
-      <emItem  blockID="i47" id="youtube@youtube2.com">
-                          <prefs>
+      <emItem  blockID="i622" id="/^({ebd898f8-fcf6-4694-bc3b-eabc7271eeb1}|{46008e0d-47ac-4daa-a02a-5eb69044431a}|{213c8ed6-1d78-4d8f-8729-25006aa86a76}|{fa23121f-ee7c-4bd8-8c06-123d087282c5}|{19803860-b306-423c-bbb5-f60a7d82cde5})$/">
+                        <versionRange  minVersion="0" maxVersion="*" severity="1">
+                    </versionRange>
+                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i518" id="/^({d6e79525-4524-4707-9b97-1d70df8e7e59}|{ddb4644d-1a37-4e6d-8b6e-8e35e2a8ea6c}|{e55007f4-80c5-418e-ac33-10c4d60db01e}|{e77d8ca6-3a60-4ae9-8461-53b22fa3125b}|{e89a62b7-248e-492f-9715-43bf8c507a2f}|{5ce3e0cb-aa83-45cb-a7da-a2684f05b8f3})$/">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
@@ -1503,16 +1515,22 @@
               </prefs>
     </emItem>
       <emItem  blockID="i372" id="5nc3QHFgcb@r06Ws9gvNNVRfH.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
+      <emItem  blockID="i496" id="{ACAA314B-EEBA-48e4-AD47-84E31C44796C}">
+                        <versionRange  minVersion="0" maxVersion="*" severity="1">
+                    </versionRange>
+                    <prefs>
+              </prefs>
+    </emItem>
       <emItem  blockID="i67" id="youtube2@youtube2.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i476" id="mbroctone@facebook.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -213,18 +213,20 @@ pref("app.update.showInstalledUI", false
 //     to newer versions of installed addons that resolve them.
 // 1 = suppress prompting for incompatibilities only if there are VersionInfo
 //     updates available to installed addons that resolve them, not newer
 //     versions.
 pref("app.update.incompatible.mode", 0);
 
 // Whether or not to attempt using the service for updates.
 #ifdef MOZ_MAINTENANCE_SERVICE
+#ifndef HAVE_64BIT_OS
 pref("app.update.service.enabled", true);
 #endif
+#endif
 
 // Symmetric (can be overridden by individual extensions) update preferences.
 // e.g.
 //  extensions.{GUID}.update.enabled
 //  extensions.{GUID}.update.url
 //  .. etc ..
 //
 pref("extensions.update.enabled", true);
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -752,23 +752,16 @@ var gBrowserInit = {
     gMultiProcessBrowser =
       window.QueryInterface(Ci.nsIInterfaceRequestor)
       .getInterface(Ci.nsIWebNavigation)
       .QueryInterface(Ci.nsILoadContext)
       .useRemoteTabs;
 
     var mustLoadSidebar = false;
 
-    if (!gMultiProcessBrowser) {
-      // There is a Content:Click message manually sent from content.
-      Cc["@mozilla.org/eventlistenerservice;1"]
-        .getService(Ci.nsIEventListenerService)
-        .addSystemEventListener(gBrowser, "click", contentAreaClick, true);
-    }
-
     gBrowser.addEventListener("DOMUpdatePageReport", gPopupBlockerObserver, false);
 
     // Note that the XBL binding is untrusted
     gBrowser.addEventListener("PluginBindingAttached", gPluginHandler, true, true);
     gBrowser.addEventListener("PluginCrashed",         gPluginHandler, true);
     gBrowser.addEventListener("PluginOutdated",        gPluginHandler, true);
     gBrowser.addEventListener("PluginInstantiated",    gPluginHandler, true);
     gBrowser.addEventListener("PluginRemoved",         gPluginHandler, true);
@@ -797,16 +790,25 @@ var gBrowserInit = {
           .getInterface(nsIWebNavigation)
           .QueryInterface(Ci.nsIDocShellTreeItem).treeOwner
           .QueryInterface(Ci.nsIInterfaceRequestor)
           .getInterface(Ci.nsIXULWindow)
           .XULBrowserWindow = window.XULBrowserWindow;
     window.QueryInterface(Ci.nsIDOMChromeWindow).browserDOMWindow =
       new nsBrowserAccess();
 
+    if (!gMultiProcessBrowser) {
+      // There is a Content:Click message manually sent from content.
+      Cc["@mozilla.org/eventlistenerservice;1"]
+        .getService(Ci.nsIEventListenerService)
+        .addSystemEventListener(gBrowser, "click", contentAreaClick, true);
+    } else {
+      gBrowser.updateBrowserRemoteness(gBrowser.mCurrentBrowser, true);
+    }
+
     // hook up UI through progress listener
     gBrowser.addProgressListener(window.XULBrowserWindow);
     gBrowser.addTabsProgressListener(window.TabsProgressListener);
 
     // setup simple gestures support
     gGestureSupport.init(true);
 
     // setup history swipe animation
@@ -2618,17 +2620,17 @@ function onMozEnteredDomFullscreen(event
 
 function getWebNavigation()
 {
   return gBrowser.webNavigation;
 }
 
 function BrowserReloadWithFlags(reloadFlags) {
   let url = gBrowser.currentURI.spec;
-  if (gBrowser.updateBrowserRemoteness(gBrowser.selectedBrowser, url)) {
+  if (gBrowser.updateBrowserRemotenessByURL(gBrowser.selectedBrowser, url)) {
     // If the remoteness has changed, the new browser doesn't have any
     // information of what was loaded before, so we need to load the previous
     // URL again.
     gBrowser.loadURIWithFlags(url, reloadFlags);
     return;
   }
 
   /* First, we'll try to use the session history object to reload so
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -1369,58 +1369,67 @@
               this.selectedTab = firstTabAdded;
             }
             else
               this.selectedBrowser.focus();
           }
         ]]></body>
       </method>
 
-#ifdef MAKE_E10S_WORK
       <method name="updateBrowserRemoteness">
         <parameter name="aBrowser"/>
-        <parameter name="aURL"/>
+        <parameter name="aShouldBeRemote"/>
         <body>
           <![CDATA[
-            let shouldBeRemote = this._shouldBrowserBeRemote(aURL);
-
             let isRemote = aBrowser.getAttribute("remote") == "true";
-            if (isRemote == shouldBeRemote)
+            if (isRemote == aShouldBeRemote)
               return false;
 
             let wasActive = document.activeElement == aBrowser;
 
             // Unhook our progress listener.
             let tab = this._getTabForBrowser(aBrowser);
             let index = tab._tPos;
             let filter = this.mTabFilters[index];
             aBrowser.webProgress.removeProgressListener(filter);
 
             // Change the "remote" attribute.
             let parent = aBrowser.parentNode;
             parent.removeChild(aBrowser);
-            aBrowser.setAttribute("remote", shouldBeRemote ? "true" : "false");
+            aBrowser.setAttribute("remote", aShouldBeRemote ? "true" : "false");
             parent.appendChild(aBrowser);
 
             // Restore the progress listener.
             aBrowser.webProgress.addProgressListener(filter, Ci.nsIWebProgress.NOTIFY_ALL);
 
-            if (shouldBeRemote)
+            if (aShouldBeRemote)
               tab.setAttribute("remote", "true");
             else
               tab.removeAttribute("remote");
 
             if (wasActive)
               aBrowser.focus();
 
             return true;
           ]]>
         </body>
       </method>
 
+#ifdef MAKE_E10S_WORK
+      <method name="updateBrowserRemotenessByURL">
+        <parameter name="aBrowser"/>
+        <parameter name="aURL"/>
+        <body>
+          <![CDATA[
+            let shouldBeRemote = this._shouldBrowserBeRemote(aURL);
+            return this.updateBrowserRemoteness(aBrowser, shouldBeRemote);
+          ]]>
+        </body>
+      </method>
+
       <!--
         Returns true if we want to load the content for this URL in a
         remote process. Eventually this should just check whether aURL
         is unprivileged. Right now, though, we would like to load
         some unprivileged URLs (like about:neterror) in the main
         process since they interact with chrome code through
         BrowserOnClick.
       -->
@@ -2721,24 +2730,24 @@
       <!-- throws exception for unknown schemes -->
       <method name="loadURI">
         <parameter name="aURI"/>
         <parameter name="aReferrerURI"/>
         <parameter name="aCharset"/>
         <body>
           <![CDATA[
 #ifdef MAKE_E10S_WORK
-            this.updateBrowserRemoteness(this.mCurrentBrowser, aURI);
+            this.updateBrowserRemotenessByURL(this.mCurrentBrowser, aURI);
             try {
 #endif
             return this.mCurrentBrowser.loadURI(aURI, aReferrerURI, aCharset);
 #ifdef MAKE_E10S_WORK
             } catch (e) {
               let url = this.mCurrentBrowser.currentURI.spec;
-              this.updateBrowserRemoteness(this.mCurrentBrowser, url);
+              this.updateBrowserRemotenessByURL(this.mCurrentBrowser, url);
               throw e;
             }
 #endif
           ]]>
         </body>
       </method>
 
       <!-- throws exception for unknown schemes -->
@@ -2746,24 +2755,24 @@
         <parameter name="aURI"/>
         <parameter name="aFlags"/>
         <parameter name="aReferrerURI"/>
         <parameter name="aCharset"/>
         <parameter name="aPostData"/>
         <body>
           <![CDATA[
 #ifdef MAKE_E10S_WORK
-            this.updateBrowserRemoteness(this.mCurrentBrowser, aURI);
+            this.updateBrowserRemotenessByURL(this.mCurrentBrowser, aURI);
             try {
 #endif
             return this.mCurrentBrowser.loadURIWithFlags(aURI, aFlags, aReferrerURI, aCharset, aPostData);
 #ifdef MAKE_E10S_WORK
             } catch (e) {
               let url = this.mCurrentBrowser.currentURI.spec;
-              this.updateBrowserRemoteness(this.mCurrentBrowser, url);
+              this.updateBrowserRemotenessByURL(this.mCurrentBrowser, url);
               throw e;
             }
 #endif
           ]]>
         </body>
       </method>
 
       <method name="goHome">
@@ -3276,17 +3285,17 @@
           if (!event.isTrusted)
             return;
 
           let browser = event.originalTarget;
           let title = browser.contentTitle;
           let uri = browser.currentURI;
           let icon = browser.mIconURL;
 
-          this.updateBrowserRemoteness(browser, "about:tabcrashed");
+          this.updateBrowserRemotenessByURL(browser, "about:tabcrashed");
 
           browser.setAttribute("crashedPageTitle", title);
           browser.docShell.displayLoadError(Cr.NS_ERROR_CONTENT_CRASHED, uri, null);
           browser.removeAttribute("crashedPageTitle");
           let tab = this._getTabForBrowser(browser);
           this.setIcon(tab, icon);
         ]]>
       </handler>
--- a/browser/components/loop/content/conversation.html
+++ b/browser/components/loop/content/conversation.html
@@ -1,16 +1,17 @@
 <!DOCTYPE html>
 <!-- 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/.  -->
 <html>
   <head>
     <meta charset="utf-8">
-    <title>Conversation</title>
+    <!-- Title is set in conversation.js -->
+    <title></title>
     <link rel="stylesheet" type="text/css" href="loop/shared/css/common.css">
     <link rel="stylesheet" type="text/css" href="loop/shared/css/conversation.css">
  </head>
   <body onload="loop.conversation.init();">
 
     <div id="messages"></div>
 
     <div id="main"></div>
--- a/browser/components/loop/content/js/conversation.js
+++ b/browser/components/loop/content/js/conversation.js
@@ -3,19 +3,17 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* global loop:true */
 
 var loop = loop || {};
 loop.conversation = (function(OT, mozL10n) {
   "use strict";
 
-  var sharedViews = loop.shared.views,
-      // aliasing translation function as __ for concision
-      __ = mozL10n.get;
+  var sharedViews = loop.shared.views;
 
   /**
    * App router.
    * @type {loop.desktopRouter.DesktopConversationRouter}
    */
   var router;
 
   /**
@@ -169,16 +167,18 @@ loop.conversation = (function(OT, mozL10
   /**
    * Panel initialisation.
    */
   function init() {
     // Do the initial L10n setup, we do this before anything
     // else to ensure the L10n environment is setup correctly.
     mozL10n.initialize(window.navigator.mozLoop);
 
+    document.title = mozL10n.get("incoming_call_title");
+
     router = new ConversationRouter({
       conversation: new loop.shared.models.ConversationModel({}, {sdk: OT}),
       notifier: new sharedViews.NotificationListView({el: "#messages"})
     });
     Backbone.history.start();
   }
 
   return {
--- a/browser/components/loop/test/desktop-local/conversation_test.js
+++ b/browser/components/loop/test/desktop-local/conversation_test.js
@@ -30,16 +30,67 @@ describe("loop.conversation", function()
     };
   });
 
   afterEach(function() {
     delete window.navigator.mozLoop;
     sandbox.restore();
   });
 
+  describe("#init", function() {
+    var conversation, oldTitle;
+
+    beforeEach(function() {
+      oldTitle = document.title;
+
+      sandbox.stub(document.mozL10n, "initialize");
+      sandbox.stub(document.mozL10n, "get").returns("Fake title");
+
+      sandbox.stub(loop.conversation.ConversationRouter.prototype,
+        "initialize");
+      sandbox.stub(loop.shared.models.ConversationModel.prototype,
+        "initialize");
+      sandbox.stub(loop.shared.views.NotificationListView.prototype,
+        "initialize");
+
+      sandbox.stub(Backbone.history, "start");
+    });
+
+    afterEach(function() {
+      document.title = oldTitle;
+    });
+
+    it("should initalize L10n", function() {
+      loop.conversation.init();
+
+      sinon.assert.calledOnce(document.mozL10n.initialize);
+      sinon.assert.calledWithExactly(document.mozL10n.initialize,
+        window.navigator.mozLoop);
+    });
+
+    it("should set the document title", function() {
+      loop.conversation.init();
+
+      expect(document.title).to.be.equal("Fake title");
+    });
+
+    it("should create the router", function() {
+      loop.conversation.init();
+
+      sinon.assert.calledOnce(
+        loop.conversation.ConversationRouter.prototype.initialize);
+    });
+
+    it("should start Backbone history", function() {
+      loop.conversation.init();
+
+      sinon.assert.calledOnce(Backbone.history.start);
+    });
+  });
+
   describe("ConversationRouter", function() {
     var conversation;
 
     beforeEach(function() {
       conversation = new loop.shared.models.ConversationModel({}, {sdk: {}});
       sandbox.stub(conversation, "initiate");
     });
 
--- a/browser/components/preferences/content.js
+++ b/browser/components/preferences/content.js
@@ -183,10 +183,16 @@ var gContentPane = {
    * Displays the translation exceptions dialog where specific site and language
    * translation preferences can be set.
    */
   showTranslationExceptions: function ()
   {
     document.documentElement.openWindow("Browser:TranslationExceptions",
                                         "chrome://browser/content/preferences/translation.xul",
                                         "", null);
+  },
+
+  openTranslationProviderAttribution: function ()
+  {
+    Components.utils.import("resource:///modules/translation/Translation.jsm");
+    Translation.openProviderAttribution();
   }
 };
--- a/browser/components/preferences/content.xul
+++ b/browser/components/preferences/content.xul
@@ -139,20 +139,26 @@
           <row id="preferredLanguageRow">
             <label flex="1" control="chooseLanguage">&chooseLanguage.label;</label>
             <button id="chooseLanguage"
                     label="&chooseButton.label;"
                     accesskey="&chooseButton.accesskey;"
                     oncommand="gContentPane.showLanguages();"/>
           </row>
           <row id="translationBox" hidden="true">
-            <checkbox id="translate" preference="browser.translation.detectLanguage" flex="1"
-                      label="&translateWebPages.label;" accesskey="&translateWebPages.accesskey;"
-                      onsyncfrompreference="return gContentPane.updateButtons('translateButton',
-                                            'browser.translation.detectLanguage');"/>
+            <hbox align="center">
+              <checkbox id="translate" preference="browser.translation.detectLanguage"
+                        label="&translateWebPages.label;." accesskey="&translateWebPages.accesskey;"
+                        onsyncfrompreference="return gContentPane.updateButtons('translateButton',
+                                              'browser.translation.detectLanguage');"/>
+              <label>Übersetzungen von</label>
+              <image id="translationAttributionImage" aria-label="Microsoft Translator"
+                     onclick="gContentPane.openTranslationProviderAttribution()"
+                     src="chrome://browser/content/microsoft-translator-attribution.png"/>
+            </hbox>
             <button id="translateButton" label="&translateExceptions.label;"
                     oncommand="gContentPane.showTranslationExceptions();"
                     accesskey="&translateExceptions.accesskey;"/>
           </row>
         </rows>
       </grid>
 
     </groupbox>
--- a/browser/components/preferences/in-content/content.js
+++ b/browser/components/preferences/in-content/content.js
@@ -181,10 +181,16 @@ var gContentPane = {
   /**
    * Displays the translation exceptions dialog where specific site and language
    * translation preferences can be set.
    */
   showTranslationExceptions: function ()
   {
     openDialog("chrome://browser/content/preferences/translation.xul",
                "Browser:TranslationExceptions", null);
+  },
+
+  openTranslationProviderAttribution: function ()
+  {
+    Components.utils.import("resource:///modules/translation/Translation.jsm");
+    Translation.openProviderAttribution();
   }
 };
--- a/browser/components/preferences/in-content/content.xul
+++ b/browser/components/preferences/in-content/content.xul
@@ -129,17 +129,24 @@
     <description flex="1" control="chooseLanguage">&chooseLanguage.label;</description>
     <button id="chooseLanguage"
             label="&chooseButton.label;"
             accesskey="&chooseButton.accesskey;"
             oncommand="gContentPane.showLanguages();"/>
   </hbox>
 
   <hbox id="translationBox" hidden="true">
-    <checkbox id="translate" preference="browser.translation.detectLanguage" flex="1"
-              label="&translateWebPages.label;" accesskey="&translateWebPages.accesskey;"
-              onsyncfrompreference="return gContentPane.updateButtons('translateButton',
-                                    'browser.translation.detectLanguage');"/>
+    <hbox align="center" flex="1">
+      <checkbox id="translate" preference="browser.translation.detectLanguage"
+                label="&translateWebPages.label;." accesskey="&translateWebPages.accesskey;"
+                onsyncfrompreference="return gContentPane.updateButtons('translateButton',
+                                              'browser.translation.detectLanguage');"/>
+      <label>Übersetzungen von</label>
+      <separator orient="vertical" class="thin"/>
+      <image id="translationAttributionImage" aria-label="Microsoft Translator"
+             onclick="gContentPane.openTranslationProviderAttribution()"
+             src="chrome://browser/content/microsoft-translator-attribution.png"/>
+    </hbox>
     <button id="translateButton" label="&translateExceptions.label;"
             oncommand="gContentPane.showTranslationExceptions();"
             accesskey="&translateExceptions.accesskey;"/>
   </hbox>
 </groupbox>
--- a/browser/components/sessionstore/src/SessionStore.jsm
+++ b/browser/components/sessionstore/src/SessionStore.jsm
@@ -2529,17 +2529,17 @@ let SessionStoreInternal = {
 
       // Save the index in case we updated it above.
       tabData.index = activeIndex + 1;
 
       // In electrolysis, we may need to change the browser's remote
       // attribute so that it runs in a content process.
       let activePageData = tabData.entries[activeIndex] || null;
       let uri = activePageData ? activePageData.url || null : null;
-      tabbrowser.updateBrowserRemoteness(browser, uri);
+      tabbrowser.updateBrowserRemotenessByURL(browser, uri);
 
       // Start a new epoch and include the epoch in the restoreHistory
       // message. If a message is received that relates to a previous epoch, we
       // discard it.
       let epoch = this._nextRestoreEpoch++;
       this._browserEpochs.set(browser.permanentKey, epoch);
 
       // keep the data around to prevent dataloss in case
--- a/browser/components/translation/Translation.jsm
+++ b/browser/components/translation/Translation.jsm
@@ -75,16 +75,22 @@ this.Translation = {
     trUI.translatedFrom = aData.translatedFrom;
     trUI.translatedTo = aData.translatedTo;
     trUI.originalShown = aData.originalShown;
 
     trUI.showURLBarIcon();
 
     if (trUI.shouldShowInfoBar(aBrowser.currentURI))
       trUI.showTranslationInfoBar();
+  },
+
+  openProviderAttribution: function() {
+    Cu.import("resource:///modules/RecentWindow.jsm");
+    RecentWindow.getMostRecentBrowserWindow().openUILinkIn(
+      "http://aka.ms/MicrosoftTranslatorAttribution", "tab");
   }
 };
 
 /* TranslationUI objects keep the information related to translation for
  * a specific browser.  This object is passed to the translation
  * infobar so that it can initialize itself.  The properties exposed to
  * the infobar are:
  * - detectedLanguage, code of the language detected on the web page.
@@ -301,16 +307,23 @@ let TranslationHealthReport = {
    *        the user has manually adjusted the detected language false should
    *        be passed.
    */
   recordLanguageChange: function (beforeFirstTranslation) {
     this._withProvider(provider => provider.recordLanguageChange(beforeFirstTranslation));
   },
 
   /**
+   * Record a denied translation offer.
+   */
+  recordDeniedTranslationOffer: function () {
+    this._withProvider(provider => provider.recordDeniedTranslationOffer());
+  },
+
+  /**
    * Retrieve the translation provider and pass it to the given function.
    *
    * @param callback
    *        The function that will be passed the translation provider.
    */
   _withProvider: function (callback) {
     try {
       let reporter = Cc["@mozilla.org/datareporting/service;1"]
@@ -358,16 +371,17 @@ TranslationMeasurement1.prototype = Obje
     missedTranslationOpportunityCount: DAILY_COUNTER_FIELD,
     pageTranslatedCount: DAILY_COUNTER_FIELD,
     charactersTranslatedCount: DAILY_COUNTER_FIELD,
     translationOpportunityCountsByLanguage: DAILY_LAST_TEXT_FIELD,
     missedTranslationOpportunityCountsByLanguage: DAILY_LAST_TEXT_FIELD,
     pageTranslatedCountsByLanguage: DAILY_LAST_TEXT_FIELD,
     detectedLanguageChangedBefore: DAILY_COUNTER_FIELD,
     detectedLanguageChangedAfter: DAILY_COUNTER_FIELD,
+    deniedTranslationOffer: DAILY_COUNTER_FIELD,
     detectLanguageEnabled: DAILY_LAST_NUMERIC_FIELD,
     showTranslationUI: DAILY_LAST_NUMERIC_FIELD,
   },
 
   shouldIncludeField: function (field) {
     if (!Services.prefs.getBoolPref("toolkit.telemetry.enabled")) {
       // This measurement should only be included when telemetry is
       // enabled, so we will not include any fields.
@@ -494,16 +508,25 @@ TranslationProvider.prototype = Object.f
       if (beforeFirstTranslation) {
           yield m.incrementDailyCounter("detectedLanguageChangedBefore");
         } else {
           yield m.incrementDailyCounter("detectedLanguageChangedAfter");
         }
     }.bind(this));
   },
 
+  recordDeniedTranslationOffer: function () {
+    let m = this.getMeasurement(TranslationMeasurement1.prototype.name,
+                                TranslationMeasurement1.prototype.version);
+
+    return this._enqueueTelemetryStorageTask(function* recordTask() {
+      yield m.incrementDailyCounter("deniedTranslationOffer");
+    }.bind(this));
+  },
+
   collectDailyData: function () {
     let m = this.getMeasurement(TranslationMeasurement1.prototype.name,
                                 TranslationMeasurement1.prototype.version);
 
     return this._enqueueTelemetryStorageTask(function* recordTask() {
       let detectLanguageEnabled = Services.prefs.getBoolPref("browser.translation.detectLanguage");
       yield m.setDailyLastNumeric("detectLanguageEnabled", detectLanguageEnabled ? 1 : 0);
 
--- a/browser/components/translation/jar.mn
+++ b/browser/components/translation/jar.mn
@@ -1,5 +1,6 @@
 # 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/.
 browser.jar:
        content/browser/translation-infobar.xml
+       content/browser/microsoft-translator-attribution.png
new file mode 100644
index 0000000000000000000000000000000000000000..d9d277461b4b66b92f47e420649f8a20b5f5b780
GIT binary patch
literal 3422
zc$|G!2|Sct7biQ}QcP0s%vj4ZGYrOLDKqvNWeM@g3^SO_!py{2%P4!OBudm<NKr<M
zRvFD?i84jDB)mvj3nB82w(t9WzxVy_^SjTv=iLAQ+;h)8_xC($dtDvmWz}UxL`3AB
z9MSGVnJMf#(vrfrssrPWh=`ab$<v4FgT)|&XcQwnffh(KVo}0H)|#aaD;ysbMq~m5
zi6JDa6?p2wV=$0JumXFVVxib@6fu<K7(*v|#JG9}#e@Y}5WqIpKuZ=<=zv0G;(;s*
znaV)2tia#>B8B5MGXxC$4q=8_fp@P>0DZ7~fhZcC2sAY^H4K6p!+_=%Mle&j1q@~Y
zG={=VATTJz*uoG7L&D9GFf-uK1{SVHCj=wi(e^*r5^7f9P$n}R34ugKMHxkz7}4k<
z5SWF91q5mgF*Y_7A`BVPR3@HfNM&gL@_;5Xg6O1hCW%G`uIczd+99SD82oDsl<?nf
zsf?d#5+)47!iPg(Mo`Fq0kPQs52a9kqZv$hV(|Y*Gd!cii4b=pgLa4>L=?g`*T~^W
z6rG4?(&(Nv8u?ci_lDA#G)5>b9Ed^z^|1IL5_L`A{+)ouBAuuVCY~BZbV6H!g%%?c
ziGV~vp$KER>27<dtuWbkCKh&Pu-$NTgdN%hZj46Q{^Fu(L5C<rD)SeY@E@-2KXTV<
z;Rl;YCq)to_H-Hr_<hev(%-~lVqs<vGlg2%Lw6(oK9(O`!r#R5le_yLxe#G6kpDU9
zUnXJstPOwHtx)-0`9!L)-08x)zFAwUAiNWsnRY%*4_YuY3Qs4B{7AeL1s@_j8ayF7
zqKRlJ1Zj}adpw15oyd=-BJ6rUrLc?L_MiCFER=~(=-r;Ip7DaP&@4QlA>f=v%dIAm
zTyHf-1<Y}JHkO2X3UBDjMNK53gUB~E!g4_=>h|`hP?>s1rJqUh3WJsT_6t=yApAG)
zmE!yNWBXyT^VE-zY?j}?{d)h#Xl?PAd#f)F`F~l73A_~KmDp4_bPQ0nVV3aKSZ{XV
zBjitR{ImjwHWDj?`0G-Zcx(iswKjrGlL|YxSgM%l+opJwJ%hVFV6qM)J~07)0LfQR
z2e-Z-FX6#Ui+0~<ivk;~Qm!;=F-4Q&GX;OlP6w*3N<WE|DD<9KxxoHhBkJ@{=dMEa
zuAL9sCS^xpcb}wO-x-yp_)a<Bxz{YGEbj7(<U`32Qg5@~^g4};6tNXT){ae_`nt{2
zvJWLLk&4leWqUeb6)Du3)N6<oV6eqpO6e6sl~nGL^=%DCw;r%h@Xw0W9wCjtZ)`ku
zQPp;wc){~g_l9_P?p~<(V*5-FtLg-0EL%diOW~4IE!#0&t4QFylrdKPblzP_Vlq)G
zQ!A-%d%AUj>6teloq9SG!`A|}fBX9RJ0Pnu%d&Rhq}KuV#vbiW<ALv^(0B!3h3Dn-
zG|e5+0A<ygn9U)VKj;q>2KRkR>(4ko!`Pqsv0ZntKq|S*E;0aG&FWjodp4-e4#90c
z|8@(zyZ$|}9Q6Fzg+05iA4i#|2TOGij}LvZU25#wTDQ+$YNEJl(K2(}8P5Rg8yvY0
z4bmn#$#P_G<8<kcWLzZOK|AANTMACrbKt8A**Go%u=AW=maYKoV5gEYggL)0-AS(W
zh~0Jny*AWqDFSHv#MY~ND-t8Da(vcH^Ye2JvOU-G-xfN(zM_s^zV4QL5#!|IBW6*q
zU-+$L_C;W<PQwGyNp(TP*c3(W_Lv0Y1i$2MDYCcU^$lN(V>qVgw>U|3zUJmuk~-L?
zLNqzp4vn8JiH9vX#ww4h#IB192|WBfhPOG)Br3#pC);nrx9CyVF-jm8o`)+fdb}vH
zh)|KaI$CiV6ru-8hzqAw;tW=s@soqi_bL?;T*9ZjHlsF;!?z<uXWMqP%dp&mt7qB)
zBT{WBeUHaG1+pWn`4ovEWc84rLUIk9ixIuax;&X<d$r?9)8Jv}9?0oVdtdI|bPY({
zkcOPEhu|yPs!-2wdI<}yY1c6EJ%!uRaa`Ajvw($`ctO3O@&oy2gUBvRD~E;madkDE
z+9UizN@}cK#@4g3nAiIN4IqEV{gRiA4f&kB4&z*-vuFJ?jmRU0&sx$?Z!mk6Nq!k>
z3iCIIY}P6WKIZ1xW~;C7k9W~axvs@1@H{y@+*)Brbb3MR@1Gy<zPEDVz=3`n>!IPo
zQA^?T#p*HRt2S}26;nNJDo`*o>ne1?0G|#;<yfD%0z9BK`7-wzD0ss@p6^~1MmNT<
zhj5h!n1O%Z=dw|$Z!2s^b(*`E7w70*FOP33uXU3Qt@j;Jp4stvQOC`Z5IPP4J>3w^
z)A4Eu;+^IJ1|=QNf7sl&=b_FL-e{@ewN%-Y#~(UD23BW$&=u|pCj)``$6A7sFU_jp
zc5*LIrNsqaYCN+n%Uyi^h0X7*Q7U`x?LD~P!EaI?1lZKSanK~?g_V*O<Uy00&O1%4
zhMMw6%jVb0E9>JU^l!%czv^67k>eWR%%X-WH!QD0zTK&xM_`p~l(0Nk>{~~Ncs}o$
zt%hG}@v-6+UQ_)G7*8EvBS-1xzZ^+XYLPh$@NLuak9)YsJVrM7(G><f!l!H5k*r;-
z1qM&)4q9R#yAsUy;JiYo)^jb>mk*~>79O3?M;9LR9*1|$?@AEA(L_#l94>ix`(9E<
zcWC*P^vsroYXS=m>ytC@((S5Tjutl=K-gJR$(D0bN;BJLaMIk%nkyo1wuPw6e`2=-
zL@FzmCA}i`w)M=RlUS@y<)OB+xcdOTKr-7us=fOdA}!xpgAiF+(Jw{~T$BflQ+Nh}
zA`ywcwmf&}zxp;y_L`)QreYe@k7eg4WG$&1)^1aKB{FsSV4nGtLCqF*d%m~pZ1uvH
zWbUTaZ}8)-2fZ4IssY6&528RDPEiy}m+BIV?4Y8klH%t|nCtui?`(-HgJL7JiV|z>
z3WJPd_~4%4;?_?ee3nXzCg?Ix&1>yPP&I%`{Nj+jHJzV(ZorKO(!ZJg$n6lj;Kpa=
zFfLh9Fk|KgEw0)B!B6dz=qP8_+$V;ZDL&+){TT*w=H{B5;}^}9rq{F#OL8^LTGw$@
zTR!D%Ej#cf9_A}sb)mAZ-e5X9qome78_62Y#*fk6yb~*l1`-T#gwCB&kNt6#d7=aQ
z`FjdlJ3vbh?QcHIWp@Yf_#=$FG1e@`_zv}JR~)roC*NY*p+~Lb4xHJIt@8oLYfF4E
z_WFR^S$D-0N7O1j>UpD@0Mog6K6&Y=QYNV`g4_Po1*)xZxJ+p-IV&uwIzZWP?>XGI
z4@Yq81fF3%bn#J>F_6Tm?Vm2Cy>Nh%5LwdXm=q;US_<y!pf;da%+v2->z`u!0=xx4
zyP-aEf1$Waj;?CYa!29h_WX^4fP>e*Sw;jkF2sqyLP?i~NON0=!>RyrkMq*(0r@4#
z5V%h7nL&g6Bl_@Hp0~?zrJUJdGUxkR{#^xU2FI1y`>6<5M+CQm5cvi1q0-u!EyHq7
zEzM5BEuf12nqJL9L2nxzF61`&274&kLIbMk-rChTYeHlvB2x8hb~WxKFYPl<ksH_Y
z@<q+U1mE=vmK~ijoNcynFT0yOmr0V=XYA5&)+xj-r0P|78Om{7(!HSNK1X_+O*wQi
zEAg8}C3`pv{u3M*U(n<zGr?8+TX3Y}&Os+t*lFLq^)jIR=oadY5y^X7T-ADqwDMyN
zL|(y(lZ4)tR6v>zciL~N4}EyxGwV&rBKg`M_{DRa3nM8s?v&Kg8@lq|@+*9J7kggo
z7Ool{ei(nNe9FAJYhxA4GWYq}laZPev1H8<R6D%}{)8dexhwbU*8X*yK(*(`+0*eU
zID6@U*1Kxgp7`eUddc)YT96D;kmRXHSba*tH)p2ddh$;xOK!2QRz)uNjU#x-)IR=>
zJg=_ArN1P$u09RUXebj$t{UcLa0|Beb7zm{U}nb5WZW%Z-f8*#DphhuP!M-bGICBJ
zTPm&?T0Wc{z47%{ViuoV7oK@U+SN;OAUPJ+d$2z%rWj;2j*FML8?{}nKXE-9cy|9z
zg@LXFZR_oAi|2;lpE?1!Xj!X@QR8-?YPGGOlLfU?Rb8fYAHi=%XIS$%sWVgW%QSA4
fYv^|PK3EmWTN=|@$GmxK?QhP>&J}&#7RUZKMltZ&
--- a/browser/components/translation/test/unit/test_healthreport.js
+++ b/browser/components/translation/test/unit/test_healthreport.js
@@ -191,16 +191,38 @@ add_task(function* test_record_translati
   Assert.equal(day.get("detectedLanguageChangedBefore"), 1);
   Assert.ok(day.has("detectedLanguageChangedAfter"));
   Assert.equal(day.get("detectedLanguageChangedAfter"), 2);
 
   yield provider.shutdown();
   yield storage.close();
 });
 
+add_task(function* test_denied_translation_offer() {
+  let storage = yield Metrics.Storage("translation");
+  let provider = new TranslationProvider();
+  yield provider.init(storage);
+  let now = new Date();
+
+  yield provider.recordDeniedTranslationOffer();
+  yield provider.recordDeniedTranslationOffer();
+
+  let m = provider.getMeasurement("translation", 1);
+  let values = yield m.getValues();
+  Assert.equal(values.days.size, 1);
+  Assert.ok(values.days.hasDay(now));
+  let day = values.days.getDay(now);
+
+  Assert.ok(day.has("deniedTranslationOffer"));
+  Assert.equal(day.get("deniedTranslationOffer"), 2);
+
+  yield provider.shutdown();
+  yield storage.close();
+});
+
 add_task(function* test_collect_daily() {
   let storage = yield Metrics.Storage("translation");
   let provider = new TranslationProvider();
   yield provider.init(storage);
   let now = new Date();
 
   // Set the prefs we test here to `false` initially.
   const kPrefDetectLanguage = "browser.translation.detectLanguage";
@@ -248,16 +270,18 @@ add_task(function* test_healthreporter_j
     yield provider.recordTranslationOpportunity("fr", now);
     yield provider.recordLanguageChange(true);
     yield provider.recordTranslation("fr", "en", 1000, now);
     yield provider.recordLanguageChange(false);
 
     yield provider.recordTranslationOpportunity("es", now);
     yield provider.recordTranslation("es", "en", 1000, now);
 
+    yield provider.recordDeniedTranslationOffer();
+
     yield reporter.collectMeasurements();
     let payload = yield reporter.getJSONPayload(true);
     let today = reporter._formatDate(now);
 
     Assert.ok(today in payload.data.days);
     let day = payload.data.days[today];
 
     Assert.ok("org.mozilla.translation.translation" in day);
@@ -280,16 +304,19 @@ add_task(function* test_healthreporter_j
     Assert.ok("es" in translations["pageTranslatedCountsByLanguage"]);
     Assert.equal(translations["pageTranslatedCountsByLanguage"]["es"]["total"], 1);
     Assert.equal(translations["pageTranslatedCountsByLanguage"]["es"]["en"], 1);
 
     Assert.ok("detectedLanguageChangedBefore" in translations);
     Assert.equal(translations["detectedLanguageChangedBefore"], 1);
     Assert.ok("detectedLanguageChangedAfter" in translations);
     Assert.equal(translations["detectedLanguageChangedAfter"], 1);
+    
+    Assert.ok("deniedTranslationOffer" in translations);
+    Assert.equal(translations["deniedTranslationOffer"], 1);
   } finally {
     reporter._shutdown();
   }
 });
 
 // Test the payload after recording with telemetry disabled.
 add_task(function* test_healthreporter_json2() {
   Services.prefs.setBoolPref("toolkit.telemetry.enabled", false);
@@ -304,16 +331,18 @@ add_task(function* test_healthreporter_j
     yield provider.recordTranslationOpportunity("fr", now);
     yield provider.recordLanguageChange(true);
     yield provider.recordTranslation("fr", "en", 1000, now);
     yield provider.recordLanguageChange(false);
 
     yield provider.recordTranslationOpportunity("es", now);
     yield provider.recordTranslation("es", "en", 1000, now);
 
+    yield provider.recordDeniedTranslationOffer();
+
     yield reporter.collectMeasurements();
     let payload = yield reporter.getJSONPayload(true);
     let today = reporter._formatDate(now);
 
     Assert.ok(today in payload.data.days);
     let day = payload.data.days[today];
 
     Assert.ok("org.mozilla.translation.translation" in day);
@@ -322,12 +351,13 @@ add_task(function* test_healthreporter_j
 
     Assert.ok(!("translationOpportunityCount" in translations));
     Assert.ok(!("pageTranslatedCount" in translations));
     Assert.ok(!("charactersTranslatedCount" in translations));
     Assert.ok(!("translationOpportunityCountsByLanguage" in translations));
     Assert.ok(!("pageTranslatedCountsByLanguage" in translations));
     Assert.ok(!("detectedLanguageChangedBefore" in translations));
     Assert.ok(!("detectedLanguageChangedAfter" in translations));
+    Assert.ok(!("deniedTranslationOffer" in translations));
   } finally {
     reporter._shutdown();
   }
 });
--- a/browser/components/translation/translation-infobar.xml
+++ b/browser/components/translation/translation-infobar.xml
@@ -93,27 +93,35 @@
 
           </xul:deck>
           <xul:spacer flex="1"/>
 
           <xul:button type="menu"
                       class="translate-infobar-element options-menu-button"
                       anonid="options"
                       label="&translation.options.menu;">
-            <xul:menupopup onpopupshowing="document.getBindingParent(this).optionsShowing();">
+            <xul:menupopup class="translation-menupopup cui-widget-panel cui-widget-panelview
+                                  cui-widget-panelWithFooter PanelUI-subView"
+                           onpopupshowing="document.getBindingParent(this).optionsShowing();">
               <xul:menuitem anonid="neverForLanguage"
                             oncommand="document.getBindingParent(this).neverForLanguage();"/>
               <xul:menuitem anonid="neverForSite"
                             oncommand="document.getBindingParent(this).neverForSite();"
                             label="&translation.options.neverForSite.label;"
                             accesskey="&translation.options.neverForSite.accesskey;"/>
               <xul:menuseparator/>
               <xul:menuitem oncommand="openPreferences('paneContent');"
                             label="&translation.options.preferences.label;"
                             accesskey="&translation.options.preferences.accesskey;"/>
+              <xul:menuitem class="translation-attribution subviewbutton panel-subview-footer"
+                            oncommand="document.getBindingParent(this).openProviderAttribution();">
+                <xul:label>Übersetzungen von</xul:label>
+                <xul:image src="chrome://browser/content/microsoft-translator-attribution.png"
+                           aria-label="Microsoft Translator"/>
+              </xul:menuitem>
             </xul:menupopup>
           </xul:button>
 
         </xul:hbox>
         <xul:toolbarbutton ondblclick="event.stopPropagation();"
                            class="messageCloseButton close-icon tabbable"
                            xbl:inherits="hidden=hideclose"
                            tooltiptext="&closeNotification.tooltip;"
@@ -305,11 +313,19 @@
             let perms = Services.perms;
             perms.add(uri, "translate", perms.DENY_ACTION);
 
             this.close();
           ]]>
         </body>
       </method>
 
+      <method name="openProviderAttribution">
+        <body>
+          <![CDATA[
+            Translation.openProviderAttribution();
+          ]]>
+        </body>
+      </method>
+
     </implementation>
   </binding>
 </bindings>
--- a/browser/config/mozconfigs/linux32/debug
+++ b/browser/config/mozconfigs/linux32/debug
@@ -1,14 +1,17 @@
 ac_add_options --enable-debug
 ac_add_options --enable-dmd
 ac_add_options --enable-signmar
 
 ac_add_options --disable-unified-compilation
 
+MOZ_AUTOMATION_TALOS_SENDCHANGE=0
+MOZ_AUTOMATION_L10N_CHECK=0
+
 . $topsrcdir/build/unix/mozconfig.linux32
 
 # Needed to enable breakpad in application.ini
 export MOZILLA_OFFICIAL=1
 
 #Use ccache
 . "$topsrcdir/build/mozconfig.cache"
 
--- a/browser/config/mozconfigs/linux64/debug
+++ b/browser/config/mozconfigs/linux64/debug
@@ -1,12 +1,15 @@
 ac_add_options --enable-debug
 ac_add_options --enable-dmd
 ac_add_options --enable-signmar
 
+MOZ_AUTOMATION_TALOS_SENDCHANGE=0
+MOZ_AUTOMATION_L10N_CHECK=0
+
 . $topsrcdir/build/unix/mozconfig.linux
 
 # Needed to enable breakpad in application.ini
 export MOZILLA_OFFICIAL=1
 
 # Use ccache
 . "$topsrcdir/build/mozconfig.cache"
 
--- a/browser/config/mozconfigs/linux64/debug-static-analysis-clang
+++ b/browser/config/mozconfigs/linux64/debug-static-analysis-clang
@@ -1,8 +1,15 @@
+MOZ_AUTOMATION_BUILD_SYMBOLS=0
+MOZ_AUTOMATION_PACKAGE_TESTS=0
+MOZ_AUTOMATION_UNITTEST_SENDCHANGE=0
+MOZ_AUTOMATION_TALOS_SENDCHANGE=0
+MOZ_AUTOMATION_L10N_CHECK=0
+MOZ_AUTOMATION_CHECK=0
+
 . "$topsrcdir/build/mozconfig.common"
 
 ac_add_options --enable-debug
 
 ac_add_options --disable-unified-compilation
 
 # Use Clang as specified in manifest
 export CC="$topsrcdir/clang/bin/clang"
--- a/browser/config/mozconfigs/linux64/nightly-nonunified
+++ b/browser/config/mozconfigs/linux64/nightly-nonunified
@@ -1,3 +1,8 @@
+MOZ_AUTOMATION_UPLOAD=0
+MOZ_AUTOMATION_UNITTEST_SENDCHANGE=0
+MOZ_AUTOMATION_TALOS_SENDCHANGE=0
+MOZ_AUTOMATION_CHECK=0
+
 . "$topsrcdir/browser/config/mozconfigs/linux64/nightly"
 
 ac_add_options --disable-unified-compilation
--- a/browser/confvars.sh
+++ b/browser/confvars.sh
@@ -4,19 +4,19 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 MOZ_APP_BASENAME=Firefox
 MOZ_APP_VENDOR=Mozilla
 MOZ_UPDATER=1
 MOZ_PHOENIX=1
 
 if test "$OS_ARCH" = "WINNT"; then
+  MOZ_MAINTENANCE_SERVICE=1
   if ! test "$HAVE_64BIT_OS"; then
     MOZ_VERIFY_MAR_SIGNATURE=1
-    MOZ_MAINTENANCE_SERVICE=1
     if test "$MOZ_UPDATE_CHANNEL" = "nightly" -o \
             "$MOZ_UPDATE_CHANNEL" = "aurora" -o \
             "$MOZ_UPDATE_CHANNEL" = "beta" -o \
             "$MOZ_UPDATE_CHANNEL" = "release"; then
       if ! test "$MOZ_DEBUG"; then
         MOZ_STUB_INSTALLER=1
       fi
     fi
--- a/browser/experiments/Experiments.jsm
+++ b/browser/experiments/Experiments.jsm
@@ -1561,17 +1561,17 @@ Experiments.ExperimentEntry.prototype = 
 
     return Task.spawn(function ExperimentEntry_runFilterFunction_task() {
       const nullprincipal = Cc["@mozilla.org/nullprincipal;1"].createInstance(Ci.nsIPrincipal);
       let options = {
         sandboxName: "telemetry experiments jsfilter sandbox",
         wantComponents: false,
       };
 
-      let sandbox = Cu.Sandbox(nullprincipal);
+      let sandbox = Cu.Sandbox(nullprincipal, options);
       try {
         Cu.evalInSandbox(jsfilter, sandbox);
       } catch (e) {
         this._log.error("runFilterFunction() - failed to eval jsfilter: " + e.message);
         throw ["jsfilter-evalfailed"];
       }
 
       // You can't insert arbitrarily complex objects into a sandbox, so
--- a/browser/installer/windows/nsis/maintenanceservice_installer.nsi
+++ b/browser/installer/windows/nsis/maintenanceservice_installer.nsi
@@ -70,24 +70,21 @@ OutFile "maintenanceservice_installer.ex
 ; Get installation folder from registry if available
 InstallDirRegKey HKLM "Software\Mozilla\MaintenanceService" ""
 
 SetOverwrite on
 
 !define MaintUninstallKey \
  "Software\Microsoft\Windows\CurrentVersion\Uninstall\MozillaMaintenanceService"
 
-; The HAVE_64BIT_OS define also means that we have an x64 build,
-; not just an x64 OS.
-!ifdef HAVE_64BIT_OS
-  ; See below, we actually abort the install for x64 builds currently.
-  InstallDir "$PROGRAMFILES64\${MaintFullName}\"
-!else
-  InstallDir "$PROGRAMFILES32\${MaintFullName}\"
-!endif
+; Always install into the 32-bit location even if we have a 64-bit build.
+; This is because we use only 1 service for all Firefox channels.
+; Allow either x86 and x64 builds to exist at this location, depending on
+; what is the latest build.
+InstallDir "$PROGRAMFILES32\${MaintFullName}\"
 ShowUnInstDetails nevershow
 
 ################################################################################
 # Modern User Interface - MUI
 
 !define MUI_ICON setup.ico
 !define MUI_UNICON setup.ico
 !define MUI_WELCOMEPAGE_TITLE_3LINES
@@ -116,23 +113,16 @@ BrandingText " "
 
 Function .onInit
   ; Remove the current exe directory from the search order.
   ; This only effects LoadLibrary calls and not implicitly loaded DLLs.
   System::Call 'kernel32::SetDllDirectoryW(w "")'
 
   SetSilent silent
 
-!ifdef HAVE_64BIT_OS
-  ; We plan to eventually enable 64bit native builds to use the maintenance
-  ; service, but for the initial release, to reduce testing and development,
-  ; 64-bit builds will not install the maintenanceservice.
-  Abort
-!endif
-
   ; On Windows 2000 we do not install the maintenance service.
   ; We won't run this installer from the parent installer, but just in case 
   ; someone tries to execute it on Windows 2000...
   ${Unless} ${AtLeastWinXP}
     Abort
   ${EndUnless}
 FunctionEnd
 
@@ -200,18 +190,17 @@ Section "MaintenanceService"
   WriteUninstaller "$INSTDIR\Uninstall.exe"
   WriteRegStr HKLM "${MaintUninstallKey}" "DisplayName" "${MaintFullName}"
   WriteRegStr HKLM "${MaintUninstallKey}" "UninstallString" \
                    '"$INSTDIR\uninstall.exe"'
   WriteRegStr HKLM "${MaintUninstallKey}" "DisplayIcon" \
                    "$INSTDIR\Uninstall.exe,0"
   WriteRegStr HKLM "${MaintUninstallKey}" "DisplayVersion" "${AppVersion}"
   WriteRegStr HKLM "${MaintUninstallKey}" "Publisher" "Mozilla"
-  WriteRegStr HKLM "${MaintUninstallKey}" "Comments" \
-                   "${BrandFullName} ${AppVersion} (${ARCH} ${AB_CD})"
+  WriteRegStr HKLM "${MaintUninstallKey}" "Comments" "${BrandFullName}"
   WriteRegDWORD HKLM "${MaintUninstallKey}" "NoModify" 1
   ${GetSize} "$INSTDIR" "/S=0K" $R2 $R3 $R4
   WriteRegDWORD HKLM "${MaintUninstallKey}" "EstimatedSize" $R2
 
   ; Write out that a maintenance service was attempted.
   ; We do this because on upgrades we will check this value and we only
   ; want to install once on the first upgrade to maintenance service.
   ; Also write out that we are currently installed, preferences will check
--- a/browser/locales/en-US/chrome/browser/loop/loop.properties
+++ b/browser/locales/en-US/chrome/browser/loop/loop.properties
@@ -1,16 +1,30 @@
+# 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/.
+
+# Panel Strings
+
 get_link_to_share=Get a link and invite someone to talk
+share_link_url=Share the link below with your friend to start your call!
+do_not_disturb=Do not disturb
+
 get_a_call_url=Get a call url
 new_url=New url
+caller.placeholder=Identify this call
+
 unable_retrieve_url=Sorry, we were unable to retrieve a call url.
-share_link_url=Share the link below with your friend to start your call!
-caller.placeholder=Identify this call
-cannot_start_call_session_not_ready=Can't start call, session is not ready.
-network_disconnected=The network connection terminated abruptly.
-peer_ended_conversation=Your peer ended the conversation.
-stop=Stop
-call_has_ended=Your call has ended.
-close_window=Close this window
-do_not_disturb=Do not disturb
+
+# Conversation Window Strings
+
+incoming_call_title=Incoming Call…
 incoming_call=Incoming call
 accept_button=Accept
 decline_button=Decline
+stop=Stop
+
+peer_ended_conversation=Your peer ended the conversation.
+call_has_ended=Your call has ended.
+close_window=Close this window
+
+cannot_start_call_session_not_ready=Can't start call, session is not ready.
+network_disconnected=The network connection terminated abruptly.
--- a/browser/modules/TabCrashReporter.jsm
+++ b/browser/modules/TabCrashReporter.jsm
@@ -74,17 +74,17 @@ this.TabCrashReporter = {
         if (browser.isRemoteBrowser)
           continue;
 
         let doc = browser.contentDocument;
         if (!doc.documentURI.startsWith("about:tabcrashed"))
           continue;
 
         let url = browser.currentURI.spec;
-        window.gBrowser.updateBrowserRemoteness(browser, url);
+        window.gBrowser.updateBrowserRemotenessByURL(browser, url);
         browser.loadURIWithFlags(url, Ci.nsIWebNavigation.LOAD_FLAGS_NONE, null, null, null);
       }
     }
   },
 
   onAboutTabCrashedLoad: function (aBrowser) {
     if (!this.childMap)
       return;
--- a/browser/modules/test/unit/social/head.js
+++ b/browser/modules/test/unit/social/head.js
@@ -80,16 +80,17 @@ function initApp() {
   createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9");
   // prepare a blocklist file for the blocklist service
   var blocklistFile = gProfD.clone();
   blocklistFile.append("blocklist.xml");
   if (blocklistFile.exists())
     blocklistFile.remove(false);
   var source = do_get_file("blocklist.xml");
   source.copyTo(gProfD, "blocklist.xml");
+  blocklistFile.lastModifiedTime = Date.now();
 
 
   let internalManager = Cc["@mozilla.org/addons/integration;1"].
                      getService(Ci.nsIObserver).
                      QueryInterface(Ci.nsITimerCallback);
 
   internalManager.observe(null, "addons-startup", null);
 }
--- a/browser/themes/linux/preferences/preferences.css
+++ b/browser/themes/linux/preferences/preferences.css
@@ -49,16 +49,22 @@ radio[pane=paneSync] {
 label.small {
   font-size: smaller;
 }
 
 #tabPrefsBox {
   margin: 5px;
 }
 
+/* Content Pane */
+#translationAttributionImage {
+  width: 70px;
+  cursor: pointer;
+}
+
 /* Applications Pane */
 #BrowserPreferences[animated="true"] #handlersView {
   height: 25em;
 }
 
 #BrowserPreferences[animated="false"] #handlersView {
   -moz-box-flex: 1;
 }
--- a/browser/themes/osx/preferences/preferences.css
+++ b/browser/themes/osx/preferences/preferences.css
@@ -135,16 +135,21 @@ caption {
 }
 
 #popupPolicyRow {
   margin-bottom: 4px !important;
   padding-bottom: 4px !important;
   border-bottom: 1px solid #ccc;
 }
 
+#translationAttributionImage {
+  width: 70px;
+  cursor: pointer;
+}
+
 #browserUseCurrent,
 #browserUseBookmark,
 #browserUseBlank {
   margin-top: 10px;
 }
 
 #advancedPrefs {
   margin: 0 8px;
--- a/browser/themes/shared/translation/infobar.inc.css
+++ b/browser/themes/shared/translation/infobar.inc.css
@@ -41,8 +41,26 @@ notification[value="translation"] menuli
 
 notification[value="translation"] menulist > .menulist-dropmarker {
   -moz-appearance: toolbarbutton-dropdown;
   border: none;
   background-color: transparent;
   margin: auto;
   padding: 5px 0;
 }
+
+.translation-menupopup arrowscrollbox {
+  padding-bottom: 0;
+}
+
+.translation-attribution {
+  cursor: pointer;
+  -moz-box-align: end;
+  font-size: small;
+}
+
+.translation-attribution > label {
+  margin-bottom: 0;
+}
+
+.translation-attribution > image {
+  width: 70px;
+}
--- a/browser/themes/windows/browser.css
+++ b/browser/themes/windows/browser.css
@@ -2438,16 +2438,20 @@ notification[value="translation"] {
 }
 
 .translated-notification-icon,
 #translated-notification-icon {
   list-style-image: url(chrome://browser/skin/translation-16.png);
   -moz-image-region: rect(0px, 32px, 16px, 16px);
 }
 
+.translation-menupopup {
+  -moz-appearance: none;
+}
+
 /* Bookmarks roots menu-items */
 #subscribeToPageMenuitem:not([disabled]),
 #subscribeToPageMenupopup,
 #BMB_subscribeToPageMenuitem:not([disabled]),
 #BMB_subscribeToPageMenupopup {
   list-style-image: url("chrome://browser/skin/feeds/feedIcon16.png");
 }
 
--- a/browser/themes/windows/preferences/preferences.css
+++ b/browser/themes/windows/preferences/preferences.css
@@ -48,16 +48,22 @@ radio[pane=paneSync] {
 label.small {
   font-size: smaller;
 }
 
 #tabPrefsBox {
   margin: 6px;
 }
 
+/* Content Pane */
+#translationAttributionImage {
+  width: 70px;
+  cursor: pointer;
+}
+
 /* Applications Pane */
 #BrowserPreferences[animated="true"] #handlersView {
   height: 25em;
 }
 
 #BrowserPreferences[animated="false"] #handlersView {
   -moz-box-flex: 1;
 }
--- a/build/autoconf/altoptions.m4
+++ b/build/autoconf/altoptions.m4
@@ -13,17 +13,16 @@ dnl Send comments, improvements, bugs to
 dnl MOZ_ARG_ENABLE_BOOL(           NAME, HELP, IF-YES [, IF-NO [, ELSE]])
 dnl MOZ_ARG_DISABLE_BOOL(          NAME, HELP, IF-NO [, IF-YES [, ELSE]])
 dnl MOZ_ARG_ENABLE_STRING(         NAME, HELP, IF-SET [, ELSE])
 dnl MOZ_ARG_ENABLE_BOOL_OR_STRING( NAME, HELP, IF-YES, IF-NO, IF-SET[, ELSE]]])
 dnl MOZ_ARG_WITH_BOOL(             NAME, HELP, IF-YES [, IF-NO [, ELSE])
 dnl MOZ_ARG_WITHOUT_BOOL(          NAME, HELP, IF-NO [, IF-YES [, ELSE])
 dnl MOZ_ARG_WITH_STRING(           NAME, HELP, IF-SET [, ELSE])
 dnl MOZ_ARG_HEADER(Comment)
-dnl MOZ_CHECK_PTHREADS(            NAME, IF-YES [, ELSE ])
 dnl MOZ_READ_MYCONFIG() - Read in 'myconfig.sh' file
 
 
 dnl MOZ_TWO_STRING_TEST(NAME, VAL, STR1, IF-STR1, STR2, IF-STR2 [, ELSE])
 AC_DEFUN([MOZ_TWO_STRING_TEST],
 [if test "[$2]" = "[$3]"; then
     ifelse([$4], , :, [$4])
   elif test "[$2]" = "[$5]"; then
@@ -75,48 +74,15 @@ AC_DEFUN([MOZ_ARG_WITHOUT_BOOL],
 dnl MOZ_ARG_WITH_STRING(NAME, HELP, IF-SET [, ELSE])
 AC_DEFUN([MOZ_ARG_WITH_STRING],
 [AC_ARG_WITH([$1], [$2], [$3], [$4])])
 
 dnl MOZ_ARG_HEADER(Comment)
 dnl This is used by webconfig to group options
 define(MOZ_ARG_HEADER, [# $1])
 
-dnl
-dnl Apparently, some systems cannot properly check for the pthread
-dnl library unless <pthread.h> is included so we need to test
-dnl using it
-dnl
-dnl MOZ_CHECK_PTHREADS(lib, success, failure)
-AC_DEFUN([MOZ_CHECK_PTHREADS],
-[
-AC_MSG_CHECKING([for pthread_create in -l$1])
-echo "
-    #include <pthread.h>
-    #include <stdlib.h>
-    void *foo(void *v) { int a = 1;  } 
-    int main() { 
-        pthread_t t;
-        if (!pthread_create(&t, 0, &foo, 0)) {
-            pthread_join(t, 0);
-        }
-        exit(0);
-    }" > dummy.c ;
-    echo "${CC-cc} -o dummy${ac_exeext} dummy.c $CFLAGS $CPPFLAGS -l[$1] $LDFLAGS $LIBS" 1>&5;
-    ${CC-cc} -o dummy${ac_exeext} dummy.c $CFLAGS $CPPFLAGS -l[$1] $LDFLAGS $LIBS 2>&5;
-    _res=$? ;
-    rm -f dummy.c dummy${ac_exeext} ;
-    if test "$_res" = "0"; then
-        AC_MSG_RESULT([yes])
-        [$2]
-    else
-        AC_MSG_RESULT([no])
-        [$3]
-    fi
-])
-
 dnl MOZ_READ_MYCONFIG() - Read in 'myconfig.sh' file
 AC_DEFUN([MOZ_READ_MOZCONFIG],
 [AC_REQUIRE([AC_INIT_BINSH])dnl
 # Read in '.mozconfig' script to set the initial options.
 # See the mozconfig2configure script for more details.
 _AUTOCONF_TOOLS_DIR=`dirname [$]0`/[$1]/build/autoconf
 . $_AUTOCONF_TOOLS_DIR/mozconfig2configure])
--- a/build/automation.py.in
+++ b/build/automation.py.in
@@ -469,17 +469,17 @@ class Automation(object):
         status = self.Process([pk12util, "-i", os.path.join(certPath, item), "-w",
                     pwfilePath, "-d", profileDir], 
                     env = env).wait()
         automationutils.printstatus(status, "pk12util")
 
     os.unlink(pwfilePath)
     return 0
 
-  def environment(self, env=None, xrePath=None, crashreporter=True, debugger=False, dmdPath=None):
+  def environment(self, env=None, xrePath=None, crashreporter=True, debugger=False, dmdPath=None, lsanPath=None):
     if xrePath == None:
       xrePath = self.DIST_BIN
     if env == None:
       env = dict(os.environ)
 
     ldLibraryPath = os.path.abspath(os.path.join(SCRIPT_DIR, xrePath))
     dmdLibrary = None
     preloadEnvVar = None
--- a/build/automationutils.py
+++ b/build/automationutils.py
@@ -443,17 +443,17 @@ def parseKeyValue(strings, separator='='
 
 def systemMemory():
   """
   Returns total system memory in kilobytes.
   Works only on unix-like platforms where `free` is in the path.
   """
   return int(os.popen("free").readlines()[1].split()[1])
 
-def environment(xrePath, env=None, crashreporter=True, debugger=False, dmdPath=None):
+def environment(xrePath, env=None, crashreporter=True, debugger=False, dmdPath=None, lsanPath=None):
   """populate OS environment variables for mochitest"""
 
   env = os.environ.copy() if env is None else env
 
   assert os.path.isabs(xrePath)
 
   ldLibraryPath = xrePath
 
@@ -516,21 +516,40 @@ def environment(xrePath, env=None, crash
         log.info("TEST-UNEXPECTED-FAIL | runtests.py | Failed to find ASan symbolizer at %s", llvmsym)
 
       totalMemory = systemMemory()
 
       # Only 4 GB RAM or less available? Use custom ASan options to reduce
       # the amount of resources required to do the tests. Standard options
       # will otherwise lead to OOM conditions on the current test slaves.
       message = "INFO | runtests.py | ASan running in %s configuration"
+      asanOptions = []
       if totalMemory <= 1024 * 1024 * 4:
         message = message % 'low-memory'
-        env["ASAN_OPTIONS"] = "quarantine_size=50331648:malloc_context_size=5"
+        asanOptions = ['quarantine_size=50331648', 'malloc_context_size=5']
       else:
         message = message % 'default memory'
+
+      if lsanPath:
+        log.info("LSan enabled.")
+        asanOptions.append('detect_leaks=1')
+        lsanOptions = ["exitcode=0"]
+        suppressionsFile = os.path.join(lsanPath, 'lsan_suppressions.txt')
+        if os.path.exists(suppressionsFile):
+          log.info("LSan using suppression file " + suppressionsFile)
+          lsanOptions.append("suppressions=" + suppressionsFile)
+        else:
+          log.info("WARNING | runtests.py | LSan suppressions file does not exist! " + suppressionsFile)
+        env["LSAN_OPTIONS"] = ':'.join(lsanOptions)
+        # Run shutdown GCs and CCs to avoid spurious leaks.
+        env['MOZ_CC_RUN_DURING_SHUTDOWN'] = '1'
+
+      if len(asanOptions):
+        env['ASAN_OPTIONS'] = ':'.join(asanOptions)
+
     except OSError,err:
       log.info("Failed determine available memory, disabling ASan low-memory configuration: %s", err.strerror)
     except:
       log.info("Failed determine available memory, disabling ASan low-memory configuration")
     else:
       log.info(message)
 
   return env
@@ -673,8 +692,103 @@ class ShutdownLeaks(object):
     counted = set()
 
     for url in leakedWindows:
       if not url in counted:
         counts.append((url, leakedWindows.count(url)))
         counted.add(url)
 
     return sorted(counts, key=itemgetter(1), reverse=True)
+
+
+class LSANLeaks(object):
+  """
+  Parses the log when running an LSAN build, looking for interesting stack frames
+  in allocation stacks, and prints out reports.
+  """
+
+  def __init__(self, logger):
+    self.logger = logger
+    self.inReport = False
+    self.foundFrames = set([])
+    self.recordMoreFrames = None
+    self.currStack = None
+    self.maxNumRecordedFrames = 4
+
+    # Don't various allocation-related stack frames, as they do not help much to
+    # distinguish different leaks.
+    unescapedSkipList = [
+      "malloc", "js_malloc", "malloc_", "__interceptor_malloc", "moz_malloc", "moz_xmalloc",
+      "calloc", "js_calloc", "calloc_", "__interceptor_calloc", "moz_calloc", "moz_xcalloc",
+      "realloc","js_realloc", "realloc_", "__interceptor_realloc", "moz_realloc", "moz_xrealloc",
+      "new",
+      "js::MallocProvider",
+    ]
+    self.skipListRegExp = re.compile("^" + "|".join([re.escape(f) for f in unescapedSkipList]) + "$")
+
+    self.startRegExp = re.compile("==\d+==ERROR: LeakSanitizer: detected memory leaks")
+    self.stackFrameRegExp = re.compile("    #\d+ 0x[0-9a-f]+ in ([^(</]+)")
+    self.sysLibStackFrameRegExp = re.compile("    #\d+ 0x[0-9a-f]+ \(([^+]+)\+0x[0-9a-f]+\)")
+
+
+  def log(self, line):
+    if re.match(self.startRegExp, line):
+      self.inReport = True
+      return
+
+    if not self.inReport:
+      return
+
+    if line.startswith("Direct leak"):
+      self._finishStack()
+      self.recordMoreFrames = True
+      self.currStack = []
+      return
+
+    if line.startswith("Indirect leak"):
+      self._finishStack()
+      # Only report direct leaks, in the hope that they are less flaky.
+      self.recordMoreFrames = False
+      return
+
+    if line.startswith("SUMMARY: AddressSanitizer"):
+      self._finishStack()
+      self.inReport = False
+      return
+
+    if not self.recordMoreFrames:
+      return
+
+    stackFrame = re.match(self.stackFrameRegExp, line)
+    if stackFrame:
+      # Split the frame to remove any return types.
+      frame = stackFrame.group(1).split()[-1]
+      if not re.match(self.skipListRegExp, frame):
+        self._recordFrame(frame)
+      return
+
+    sysLibStackFrame = re.match(self.sysLibStackFrameRegExp, line)
+    if sysLibStackFrame:
+      # System library stack frames will never match the skip list,
+      # so don't bother checking if they do.
+      self._recordFrame(sysLibStackFrame.group(1))
+
+    # If we don't match either of these, just ignore the frame.
+    # We'll end up with "unknown stack" if everything is ignored.
+
+  def process(self):
+    for f in self.foundFrames:
+      self.logger("TEST-UNEXPECTED-FAIL | LeakSanitizer | leak at " + f)
+
+  def _finishStack(self):
+    if self.recordMoreFrames and len(self.currStack) == 0:
+      self.currStack = ["unknown stack"]
+    if self.currStack:
+      self.foundFrames.add(", ".join(self.currStack))
+      self.currStack = None
+    self.recordMoreFrames = False
+    self.numRecordedFrames = 0
+
+  def _recordFrame(self, frame):
+    self.currStack.append(frame)
+    self.numRecordedFrames += 1
+    if self.numRecordedFrames >= self.maxNumRecordedFrames:
+      self.recordMoreFrames = False
--- a/build/gen_mach_buildprops.py
+++ b/build/gen_mach_buildprops.py
@@ -1,15 +1,20 @@
 #!/usr/bin/python
 #
 # 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/.
 
-import sys, os, sha, json, re
+import sys
+import os
+import sha
+import json
+import re
+import errno
 from argparse import ArgumentParser
 
 def getFileHashAndSize(filename):
     sha1Hash = 'UNKNOWN'
     size = 'UNKNOWN'
 
     try:
         # open in binary mode to make sure we get consistent results
@@ -46,25 +51,30 @@ def getUrlProperties(filename):
         ('jsshellUrl', lambda m: 'jsshell-' in m and m.endswith('.zip')),
         ('completeMarUrl', lambda m: m.endswith('.complete.mar')),
         # packageUrl must be last!
         ('packageUrl', lambda m: True),
     ]
     url_re = re.compile(r'''^(https?://.*?\.(?:tar\.bz2|dmg|zip|apk|rpm|mar|tar\.gz))$''')
     properties = {}
 
-    with open(filename) as f:
-        for line in f:
-            m = url_re.match(line)
-            if m:
-                m = m.group(1)
-                for prop, condition in property_conditions:
-                    if condition(m):
-                        properties.update({prop: m})
-                        break
+    try:
+        with open(filename) as f:
+            for line in f:
+                m = url_re.match(line)
+                if m:
+                    m = m.group(1)
+                    for prop, condition in property_conditions:
+                        if condition(m):
+                            properties.update({prop: m})
+                            break
+    except IOError as e:
+        if e.errno != errno.ENOENT:
+            raise
+        properties = {prop: 'UNKNOWN' for prop, condition in property_conditions}
     return properties
 
 if __name__ == '__main__':
     parser = ArgumentParser(description='Generate mach_build_properties.json for automation builds.')
     parser.add_argument("--complete-mar-file", required=True,
                         action="store", dest="complete_mar_file",
                         help="Path to the complete MAR file, relative to the objdir.")
     parser.add_argument("--upload-output", required=True,
--- a/build/mach_bootstrap.py
+++ b/build/mach_bootstrap.py
@@ -33,16 +33,17 @@ SEARCH_PATHS = [
     'python/configobj',
     'python/jsmin',
     'python/psutil',
     'python/which',
     'build/pymake',
     'config',
     'dom/bindings',
     'dom/bindings/parser',
+    'layout/tools/reftest',
     'other-licenses/ply',
     'xpcom/idl-parser',
     'testing',
     'testing/xpcshell',
     'testing/marionette/client',
     'testing/marionette/client/marionette',
     'testing/marionette/transport',
     'testing/mozbase/mozcrash',
--- a/build/mobile/remoteautomation.py
+++ b/build/mobile/remoteautomation.py
@@ -43,17 +43,17 @@ class RemoteAutomation(Automation):
 
     def setProduct(self, product):
         self._product = product
 
     def setRemoteLog(self, logfile):
         self._remoteLog = logfile
 
     # Set up what we need for the remote environment
-    def environment(self, env=None, xrePath=None, crashreporter=True, debugger=False, dmdPath=None):
+    def environment(self, env=None, xrePath=None, crashreporter=True, debugger=False, dmdPath=None, lsanPath=None):
         # Because we are running remote, we don't want to mimic the local env
         # so no copying of os.environ
         if env is None:
             env = {}
 
         if dmdPath:
             env['DMD'] = '1'
             env['MOZ_REPLACE_MALLOC_LIB'] = os.path.join(dmdPath, 'libdmd.so')
--- a/build/moz-automation.mk
+++ b/build/moz-automation.mk
@@ -12,63 +12,67 @@ endif
 endif
 
 include $(topsrcdir)/toolkit/mozapps/installer/package-name.mk
 
 # Log file from the 'make upload' step. We need this to parse out the URLs of
 # the uploaded files.
 AUTOMATION_UPLOAD_OUTPUT = $(DIST)/automation-upload.txt
 
+# Helper variables to convert from MOZ_AUTOMATION_* variables to the
+# corresponding the make target
+tier_BUILD_SYMBOLS = buildsymbols
+tier_CHECK = check
+tier_L10N_CHECK = l10n-check
+tier_PACKAGE = package
+tier_PACKAGE_TESTS = package-tests
+tier_UPDATE_PACKAGING = update-packaging
+tier_UPLOAD_SYMBOLS = uploadsymbols
+tier_UPLOAD = upload
+
 # Automation build steps. Everything in MOZ_AUTOMATION_TIERS also gets used in
 # TIERS for mach display. As such, the MOZ_AUTOMATION_TIERS are roughly sorted
 # here in the order that they will be executed (since mach doesn't know of the
 # dependencies between them).
-
-MOZ_AUTOMATION_TIERS += package-tests
-MOZ_AUTOMATION_TIERS += buildsymbols
-
-ifdef NIGHTLY_BUILD
-MOZ_AUTOMATION_TIERS += uploadsymbols
-endif
-
-ifdef MOZ_UPDATE_PACKAGING
-MOZ_AUTOMATION_TIERS += update-packaging
-automation/upload: automation/update-packaging
-automation/update-packaging: automation/package
-endif
-
-MOZ_AUTOMATION_TIERS += package
-MOZ_AUTOMATION_TIERS += check
-
-ifndef MOZ_ASAN
-MOZ_AUTOMATION_TIERS += l10n-check
-automation/l10n-check: automation/package
-endif
-
-MOZ_AUTOMATION_TIERS += upload
-
-automation/build: $(addprefix automation/,$(MOZ_AUTOMATION_TIERS))
-	$(PYTHON) $(topsrcdir)/build/gen_mach_buildprops.py --complete-mar-file $(DIST)/$(COMPLETE_MAR) --upload-output $(AUTOMATION_UPLOAD_OUTPUT)
+moz_automation_symbols = PACKAGE_TESTS BUILD_SYMBOLS UPLOAD_SYMBOLS PACKAGE UPDATE_PACKAGING CHECK L10N_CHECK UPLOAD
+MOZ_AUTOMATION_TIERS := $(foreach sym,$(moz_automation_symbols),$(if $(filter 1,$(MOZ_AUTOMATION_$(sym))),$(tier_$(sym))))
 
 # Dependencies between automation build steps
 automation/uploadsymbols: automation/buildsymbols
 
+automation/update-packaging: automation/package
+
+automation/l10n-check: automation/package
+
 automation/upload: automation/package
 automation/upload: automation/package-tests
 automation/upload: automation/buildsymbols
+automation/upload: automation/update-packaging
 
 # automation/package and automation/check should depend on build (which is
 # implicit due to the way client.mk invokes automation/build), but buildsymbols
 # changes the binaries/libs, and that's what we package/test.
 automation/package: automation/buildsymbols
 automation/check: automation/buildsymbols
 
+automation/build: $(addprefix automation/,$(MOZ_AUTOMATION_TIERS))
+	$(PYTHON) $(topsrcdir)/build/gen_mach_buildprops.py --complete-mar-file $(DIST)/$(COMPLETE_MAR) --upload-output $(AUTOMATION_UPLOAD_OUTPUT)
+
 # make check runs with the keep-going flag so we can see all the failures
 AUTOMATION_EXTRA_CMDLINE-check = -k
 
 # We need the log from make upload to grep it for urls in order to set
 # properties.
 AUTOMATION_EXTRA_CMDLINE-upload = 2>&1 | tee $(AUTOMATION_UPLOAD_OUTPUT)
 
+# The commands only run if the corresponding MOZ_AUTOMATION_* variable is
+# enabled. This means, for example, if we enable MOZ_AUTOMATION_UPLOAD, then
+# 'buildsymbols' will only run if MOZ_AUTOMATION_BUILD_SYMBOLS is also set.
+# However, the target automation/buildsymbols will still be executed in this
+# case because it is a prerequisite of automation/upload.
+define automation_commands
+$(call BUILDSTATUS,TIER_START $1)
+@$(MAKE) $1 $(AUTOMATION_EXTRA_CMDLINE-$1)
+$(call BUILDSTATUS,TIER_FINISH $1)
+endef
+
 automation/%:
-	$(call BUILDSTATUS,TIER_START $*)
-	@$(MAKE) $* $(AUTOMATION_EXTRA_CMDLINE-$*)
-	$(call BUILDSTATUS,TIER_FINISH $*)
+	$(if $(filter $*,$(MOZ_AUTOMATION_TIERS)),$(call automation_commands,$*))
new file mode 100644
--- /dev/null
+++ b/build/mozconfig.automation
@@ -0,0 +1,21 @@
+# 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/.
+
+# Common mozconfig for automation builds.
+#
+# We export MOZ_AUTOMATION_* variables here to trigger various steps in
+# automation builds.  For example, if MOZ_AUTOMATION_PACKAGE is set, then the
+# package step will run.  This file contains the default settings, which can be
+# overridden by setting them earlier in the appropriate mozconfig.
+
+mk_add_options "export MOZ_AUTOMATION_BUILD_SYMBOLS=${MOZ_AUTOMATION_BUILD_SYMBOLS-1}"
+mk_add_options "export MOZ_AUTOMATION_CHECK=${MOZ_AUTOMATION_CHECK-1}"
+mk_add_options "export MOZ_AUTOMATION_L10N_CHECK=${MOZ_AUTOMATION_L10N_CHECK-1}"
+mk_add_options "export MOZ_AUTOMATION_PACKAGE=${MOZ_AUTOMATION_PACKAGE-1}"
+mk_add_options "export MOZ_AUTOMATION_PACKAGE_TESTS=${MOZ_AUTOMATION_PACKAGE_TESTS-1}"
+mk_add_options "export MOZ_AUTOMATION_TALOS_SENDCHANGE=${MOZ_AUTOMATION_TALOS_SENDCHANGE-1}"
+mk_add_options "export MOZ_AUTOMATION_UNITTEST_SENDCHANGE=${MOZ_AUTOMATION_UNITTEST_SENDCHANGE-1}"
+mk_add_options "export MOZ_AUTOMATION_UPDATE_PACKAGING=${MOZ_AUTOMATION_UPDATE_PACKAGING-0}"
+mk_add_options "export MOZ_AUTOMATION_UPLOAD=${MOZ_AUTOMATION_UPLOAD-1}"
+mk_add_options "export MOZ_AUTOMATION_UPLOAD_SYMBOLS=${MOZ_AUTOMATION_UPLOAD_SYMBOLS-0}"
--- a/build/mozconfig.common
+++ b/build/mozconfig.common
@@ -10,8 +10,10 @@
 # another mozconfig file, you'll need to use mozconfig.common.override instead
 # of this file.
 
 mk_add_options AUTOCLOBBER=1
 
 ac_add_options --enable-crashreporter
 
 ac_add_options --enable-release
+
+. "$topsrcdir/build/mozconfig.automation"
new file mode 100644
--- /dev/null
+++ b/build/sanitizers/lsan_suppressions.txt
@@ -0,0 +1,108 @@
+### !!! Please do not add suppressions for new leaks in Gecko code, unless they are intentional !!!
+
+###
+### Some of these leak in every test run.
+###
+
+# LSan runs with a shallow stack depth and no debug symbols, so some small intentional
+# leaks in system libraries show up with this.  You do not want this enabled
+# when running locally with a deep stack, as it can catch too much.
+leak:libc.so
+
+# nsComponentManagerImpl intentionally leaks factory entries, and probably some other stuff.
+leak:nsComponentManagerImpl
+# These two variants are needed when fast unwind is disabled and stack depth is limited.
+leak:mozJSComponentLoader::LoadModule
+leak:nsNativeModuleLoader::LoadModule
+
+# Bug 980109 - Freeing this properly on shutdown is hard.
+leak:profiler_init
+
+# Bug 981220 - Pixman fails to free TLS memory.
+leak:pixman_implementation_lookup_composite
+
+# Bug 987918 - Font shutdown leaks when CLEANUP_MEMORY is not enabled.
+leak:libfontconfig.so
+leak:GI___strdup
+# The symbol is really __GI___strdup, but if you have the leading _, it doesn't suppress it.
+
+
+###
+### Many leaks only affect some test suites.  The suite annotations are not checked.
+###
+
+# Bug 800200 - JSD1 is leaking, but it is about to be removed, so ignore it. m4
+leak:jsd_CreateLock
+leak:jsdScript::GetExecutableLines
+leak:jsdService::ActivateDebugger
+
+# Bug 979928 - WebRTC is leaky. m2, m3
+leak:/media/mtransport/
+leak:/media/webrtc/signaling/
+
+# Bug 981195 - Small leak in the parser. m4
+leak:TypeCompartment::fixObjectType
+
+# Bug 982111 - WebM is leaking. m1
+leak:nestegg_read_packet
+
+# Bug 987385 - Various plugin leaks. m3
+leak:mozilla::plugins::PPluginInstanceParent::CallNPP_HandleEvent
+leak:mozilla::plugins::PPluginModuleParent::OnCallReceived
+
+# Bug 987925 - Small leak under PK11_ChangePW. m5
+leak:sec_asn1e_allocate_item
+leak:PORT_Strdup_Util
+
+# Bug 1021302 - Leak of fds allocated in nsSocketTransport::BuildSocket(). m1, m5, dt, oth
+leak:nsSocketTransport::BuildSocket
+leak:nsServerSocket::OnSocketReady
+
+# Bug 1021350 - Small leak under event_base_once. m1, m4, bc3
+leak:event_base_once
+
+# Bug 1021854 - nsFileStreamBase::DoOpen() leaking fds. bc1, oth
+leak:nsLocalFile::OpenNSPRFileDesc
+
+# Bug 1021932 - AllocateArrayBufferContents leaks. m1
+# Bug 1023583 - Leak of array buffer data involving web audio and XHR::OnStopRequest(). m1
+# Bug 1023585 - Leak of array buffer in JSStructuredCloneWriter::transferOwnership(). m1
+leak:AllocateArrayBufferContents
+
+# Bug 1022010 - Small leak under _render_glyph_outline. bc1
+leak:_render_glyph_outline
+
+# Bug 1022042 - compareVariants in the test plugin leaks identifiers. oth
+leak:compareVariants(_NPP*,
+
+# Bug 1022954 - ScriptSource leaks sourceMapURL_ sometimes. dt
+leak:ScriptSource::setSourceMapURL
+
+# Bug 1023548 - Small leak under SECITEM_AllocItem_Util. bc1, bc3
+leak:SECITEM_AllocItem_Util
+
+# This is a one-time leak, so it is probably okay to ignore. bc1, oth
+leak:GlobalPrinters::InitializeGlobalPrinters
+leak:nsPSPrinterList::GetPrinterList
+
+# Bug 1028456 - More leaks with _PR_Getfd, in nsLocalFile::CopyToNative and do_create. bc1, bc3
+leak:_PR_Getfd
+
+
+###
+### Leaks with system libraries in their stacks. These show up across a number of tests.
+### Better symbols and disabling fast stackwalking may help diagnose these.
+###
+
+leak:libcairo.so
+leak:libdricore.so
+leak:libGL.so
+leak:libglib-2.0.so
+leak:libp11-kit.so
+leak:libpulse.so
+leak:libpulsecommon-1.1.so
+leak:libresolv.so
+leak:libstdc++.so
+leak:libXrandr.so
+leak:pthread_setspecific_internal
+leak:swrast_dri.so
--- a/build/unix/mozconfig.asan
+++ b/build/unix/mozconfig.asan
@@ -1,8 +1,14 @@
+if [ "x$IS_NIGHTLY" = "xyes" ]; then
+  MOZ_AUTOMATION_UPDATE_PACKAGING=1
+fi
+MOZ_AUTOMATION_TALOS_SENDCHANGE=0
+MOZ_AUTOMATION_L10N_CHECK=0
+
 . "$topsrcdir/build/mozconfig.common"
 
 # Use Clang as specified in manifest
 export CC="$topsrcdir/clang/bin/clang -fgnu89-inline"
 export CXX="$topsrcdir/clang/bin/clang++"
 export LLVM_SYMBOLIZER="$topsrcdir/clang/bin/llvm-symbolizer"
 
 # Mandatory flags for ASan
--- a/build/unix/mozconfig.linux
+++ b/build/unix/mozconfig.linux
@@ -1,8 +1,13 @@
+if [ "x$IS_NIGHTLY" = "xyes" ]; then
+  MOZ_AUTOMATION_UPLOAD_SYMBOLS=1
+  MOZ_AUTOMATION_UPDATE_PACKAGING=1
+fi
+
 . "$topsrcdir/build/mozconfig.common"
 
 # some b2g desktop builds still happen on i686 machines, and the tooltool
 # toolchain is x86_64 only.
 # We also deal with valgrind builds here, they don't use tooltool manifests at
 # all yet.
 if [ -z "$no_tooltool" ]
 then
--- a/build/virtualenv_packages.txt
+++ b/build/virtualenv_packages.txt
@@ -12,13 +12,14 @@ which.pth:python/which
 ply.pth:other-licenses/ply/
 codegen.pth:python/codegen/
 mock.pth:python/mock-1.0.0
 mozilla.pth:build
 mozilla.pth:config
 mozilla.pth:xpcom/typelib/xpt/tools
 mozilla.pth:dom/bindings
 mozilla.pth:dom/bindings/parser
+mozilla.pth:layout/tools/reftest
 moztreedocs.pth:tools/docs
 copy:build/buildconfig.py
 packages.txt:testing/mozbase/packages.txt
 objdir:build
 gyp.pth:media/webrtc/trunk/tools/gyp/pylib
--- a/chrome/src/nsChromeRegistry.cpp
+++ b/chrome/src/nsChromeRegistry.cpp
@@ -11,30 +11,34 @@
 #include "prprf.h"
 
 #include "nsCOMPtr.h"
 #include "nsError.h"
 #include "nsEscape.h"
 #include "nsNetUtil.h"
 #include "nsString.h"
 
-#include "nsCSSStyleSheet.h"
+#include "mozilla/CSSStyleSheet.h"
+#include "mozilla/dom/URL.h"
 #include "nsIConsoleService.h"
 #include "nsIDocument.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMLocation.h"
 #include "nsIDOMWindowCollection.h"
 #include "nsIDOMWindow.h"
 #include "nsIObserverService.h"
 #include "nsIPresShell.h"
 #include "nsIScriptError.h"
 #include "nsIWindowMediator.h"
-#include "mozilla/dom/URL.h"
 
 nsChromeRegistry* nsChromeRegistry::gChromeRegistry;
+
+// DO NOT use namespace mozilla; it'll break due to a naming conflict between
+// mozilla::TextRange and a TextRange in OSX headers.
+using mozilla::CSSStyleSheet;
 using mozilla::dom::IsChromeURI;
 
 ////////////////////////////////////////////////////////////////////////////////
 
 void
 nsChromeRegistry::LogMessage(const char* aMsg, ...)
 {
   nsCOMPtr<nsIConsoleService> console 
@@ -289,17 +293,17 @@ nsChromeRegistry::ConvertChromeURL(nsIUR
 #else
     path.Insert("unix/", 0);
 #endif
   }
 
   if (!baseURI) {
     LogMessage("No chrome package registered for chrome://%s/%s/%s",
                package.get(), provider.get(), path.get());
-    return NS_ERROR_FAILURE;
+    return NS_ERROR_FILE_NOT_FOUND;
   }
 
   return NS_NewURI(aResult, path, nullptr, baseURI);
 }
 
 ////////////////////////////////////////////////////////////////////////
 
 // theme stuff
@@ -410,17 +414,17 @@ nsresult nsChromeRegistry::RefreshWindow
     nsCOMArray<nsIStyleSheet> newAgentSheets;
     for (int32_t l = 0; l < agentSheets.Count(); ++l) {
       nsIStyleSheet *sheet = agentSheets[l];
 
       nsIURI* uri = sheet->GetSheetURI();
 
       if (IsChromeURI(uri)) {
         // Reload the sheet.
-        nsRefPtr<nsCSSStyleSheet> newSheet;
+        nsRefPtr<CSSStyleSheet> newSheet;
         rv = document->LoadChromeSheetSync(uri, true,
                                            getter_AddRefs(newSheet));
         if (NS_FAILED(rv)) return rv;
         if (newSheet) {
           rv = newAgentSheets.AppendObject(newSheet) ? NS_OK : NS_ERROR_FAILURE;
           if (NS_FAILED(rv)) return rv;
         }
       }
@@ -449,22 +453,22 @@ nsresult nsChromeRegistry::RefreshWindow
     if (!oldSheets.AppendObject(styleSheet)) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
   }
 
   // Iterate over our old sheets and kick off a sync load of the new
   // sheet if and only if it's a chrome URL.
   for (i = 0; i < count; i++) {
-    nsRefPtr<nsCSSStyleSheet> sheet = do_QueryObject(oldSheets[i]);
+    nsRefPtr<CSSStyleSheet> sheet = do_QueryObject(oldSheets[i]);
     nsIURI* uri = sheet ? sheet->GetOriginalURI() : nullptr;
 
     if (uri && IsChromeURI(uri)) {
       // Reload the sheet.
-      nsRefPtr<nsCSSStyleSheet> newSheet;
+      nsRefPtr<CSSStyleSheet> newSheet;
       // XXX what about chrome sheets that have a title or are disabled?  This
       // only works by sheer dumb luck.
       document->LoadChromeSheetSync(uri, false, getter_AddRefs(newSheet));
       // Even if it's null, we put in in there.
       newSheets.AppendObject(newSheet);
     }
     else {
       // Just use the same sheet.
--- a/chrome/src/nsChromeRegistryChrome.cpp
+++ b/chrome/src/nsChromeRegistryChrome.cpp
@@ -267,17 +267,17 @@ nsChromeRegistryChrome::GetSelectedLocal
   if (NS_FAILED(rv))
     return rv;
   PackageEntry* entry =
       static_cast<PackageEntry*>(PL_DHashTableOperate(&mPackagesHash,
                                                       & realpackage,
                                                       PL_DHASH_LOOKUP));
 
   if (PL_DHASH_ENTRY_IS_FREE(entry))
-    return NS_ERROR_FAILURE;
+    return NS_ERROR_FILE_NOT_FOUND;
 
   aLocale = entry->locales.GetSelected(mSelectedLocale, nsProviderArray::LOCALE);
   if (aLocale.IsEmpty())
     return NS_ERROR_FAILURE;
 
   return NS_OK;
 }
 
@@ -555,17 +555,17 @@ nsresult
 nsChromeRegistryChrome::GetFlagsFromPackage(const nsCString& aPackage,
                                             uint32_t* aFlags)
 {
   PackageEntry* entry =
       static_cast<PackageEntry*>(PL_DHashTableOperate(&mPackagesHash,
                                                       & (nsACString&) aPackage,
                                                       PL_DHASH_LOOKUP));
   if (PL_DHASH_ENTRY_IS_FREE(entry))
-    return NS_ERROR_NOT_AVAILABLE;
+    return NS_ERROR_FILE_NOT_FOUND;
 
   *aFlags = entry->flags;
   return NS_OK;
 }
 
 PLHashNumber
 nsChromeRegistryChrome::HashKey(PLDHashTable *table, const void *key)
 {
--- a/configure.in
+++ b/configure.in
@@ -2799,23 +2799,23 @@ dnl ====================================
 dnl = pthread support
 dnl = Start by checking whether the system support pthreads
 dnl ========================================================
 case "$target_os" in
 darwin*)
     MOZ_USE_PTHREADS=1
     ;;
 *)
-    MOZ_CHECK_PTHREADS(pthreads,
+    AC_CHECK_LIB(pthreads, pthread_create,
         MOZ_USE_PTHREADS=1 _PTHREAD_LDFLAGS="-lpthreads",
-        MOZ_CHECK_PTHREADS(pthread,
+        AC_CHECK_LIB(pthread, pthread_create,
             MOZ_USE_PTHREADS=1 _PTHREAD_LDFLAGS="-lpthread",
-            MOZ_CHECK_PTHREADS(c_r,
+            AC_CHECK_LIB(c_r, pthread_create,
                 MOZ_USE_PTHREADS=1 _PTHREAD_LDFLAGS="-lc_r",
-                MOZ_CHECK_PTHREADS(c,
+                AC_CHECK_LIB(c, pthread_create,
                     MOZ_USE_PTHREADS=1
                 )
             )
         )
     )
     ;;
 esac
 
@@ -7796,59 +7796,16 @@ if test "$SOLARIS_SUNPRO_CC"; then
   PROFILE_USE_LDFLAGS="-xprofile=use:$_objdir/$enable_application"
 fi
 
 AC_SUBST(PROFILE_GEN_CFLAGS)
 AC_SUBST(PROFILE_GEN_LDFLAGS)
 AC_SUBST(PROFILE_USE_CFLAGS)
 AC_SUBST(PROFILE_USE_LDFLAGS)
 
-AC_LANG_CPLUSPLUS
-
-dnl ========================================================
-dnl Autoconf test for gcc 2.7.2.x (and maybe others?) so that we don't
-dnl provide non-const forms of the operator== for comparing nsCOMPtrs to
-dnl raw pointers in nsCOMPtr.h.  (VC++ has the same bug.)
-dnl ========================================================
-_SAVE_CXXFLAGS=$CXXFLAGS
-CXXFLAGS="$CXXFLAGS ${_WARNINGS_CXXFLAGS}"
-AC_CACHE_CHECK(for correct overload resolution with const and templates,
-    ac_nscap_nonconst_opeq_bug,
-    [AC_TRY_COMPILE([
-                      template <class T>
-                      class Pointer
-                        {
-                        public:
-                          T* myPtr;
-                        };
-
-                      template <class T, class U>
-                      int operator==(const Pointer<T>& rhs, U* lhs)
-                        {
-                          return rhs.myPtr == lhs;
-                        }
-
-                      template <class T, class U>
-                      int operator==(const Pointer<T>& rhs, const U* lhs)
-                        {
-                          return rhs.myPtr == lhs;
-                        }
-                    ],
-                    [
-                      Pointer<int> foo;
-                      const int* bar;
-                      return foo == bar;
-                    ],
-                    ac_nscap_nonconst_opeq_bug="no",
-                    ac_nscap_nonconst_opeq_bug="yes")])
-CXXFLAGS="$_SAVE_CXXFLAGS"
-
-if test "$ac_nscap_nonconst_opeq_bug" = "yes" ; then
-    AC_DEFINE(NSCAP_DONT_PROVIDE_NONCONST_OPEQ)
-fi
 fi # ! SKIP_COMPILER_CHECKS
 
 AC_DEFINE(CPP_THROW_NEW, [throw()])
 AC_LANG_C
 
 if test "$COMPILE_ENVIRONMENT"; then
 MOZ_EXPAND_LIBS
 fi # COMPILE_ENVIRONMENT
@@ -7870,17 +7827,17 @@ else
   if test -z "$_WIN32_MSVC"; then
     _USE_CPP_INCLUDE_FLAG=
     _DEFINES_CFLAGS='$(ACDEFINES) -D_MOZILLA_CONFIG_H_ -DMOZILLA_CLIENT'
     _DEFINES_CXXFLAGS='$(ACDEFINES) -D_MOZILLA_CONFIG_H_ -DMOZILLA_CLIENT'
   else
     echo '#include <stdio.h>' > dummy-hello.c
     changequote(,)
     dnl This output is localized, split at the first double space or colon and space.
-    _CL_PREFIX_REGEX="^\([^:]*:.*[ :] \)\(.*stdio.h\)$"
+    _CL_PREFIX_REGEX="^\([^:]*:.*[ :] \)\(.*\\\stdio.h\)$"
     CL_INCLUDES_PREFIX=`${CC} -showIncludes -c -Fonul dummy-hello.c 2>&1 | sed -ne 's/'"$_CL_PREFIX_REGEX"'/\1/p'`
     _CL_STDIO_PATH=`${CC} -showIncludes -c -Fonul dummy-hello.c 2>&1 | sed -ne 's/'"$_CL_PREFIX_REGEX"'/\2/p'`
     changequote([,])
     if ! test -e "$_CL_STDIO_PATH"; then
         AC_MSG_ERROR([Unable to parse cl -showIncludes prefix. This compiler's locale has an unsupported formatting.])
     fi
     if test -z "$CL_INCLUDES_PREFIX"; then
         AC_MSG_ERROR([Cannot find cl -showIncludes prefix.])
--- a/content/base/public/FragmentOrElement.h
+++ b/content/base/public/FragmentOrElement.h
@@ -119,16 +119,17 @@ public:
 
   ~nsNodeWeakReference();
 
   // nsISupports
   NS_DECL_ISUPPORTS
 
   // nsIWeakReference
   NS_DECL_NSIWEAKREFERENCE
+  virtual size_t SizeOfOnlyThis(mozilla::MallocSizeOf aMallocSizeOf) const;
 
   void NoticeNodeDestruction()
   {
     mNode = nullptr;
   }
 
 private:
   nsINode* mNode;
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -24,17 +24,16 @@
 #include "mozilla/WeakPtr.h"
 #include "Units.h"
 #include "nsExpirationTracker.h"
 #include "nsClassHashtable.h"
 
 class imgIRequest;
 class nsAString;
 class nsBindingManager;
-class nsCSSStyleSheet;
 class nsIDocShell;
 class nsDocShell;
 class nsDOMNavigationTiming;
 class nsFrameLoader;
 class nsHTMLCSSStyleSheet;
 class nsHTMLDocument;
 class nsHTMLStyleSheet;
 class nsIAtom;
@@ -78,16 +77,17 @@ class nsTextNode;
 class nsWindowSizes;
 class nsSmallVoidArray;
 class nsDOMCaretPosition;
 class nsViewportInfo;
 class nsIGlobalObject;
 struct nsCSSSelectorList;
 
 namespace mozilla {
+class CSSStyleSheet;
 class ErrorResult;
 class EventStates;
 
 namespace css {
 class Loader;
 class ImageLoader;
 } // namespace css
 
@@ -117,16 +117,17 @@ class NodeIterator;
 class ProcessingInstruction;
 class StyleSheetList;
 class SVGDocument;
 class Touch;
 class TouchList;
 class TreeWalker;
 class UndoManager;
 class XPathEvaluator;
+class XPathResult;
 template<typename> class OwningNonNull;
 template<typename> class Sequence;
 
 template<typename, typename> class CallbackObjectHolder;
 typedef CallbackObjectHolder<NodeFilter, nsIDOMNodeFilter> NodeFilterHolder;
 } // namespace dom
 } // namespace mozilla
 
@@ -774,17 +775,17 @@ public:
    * This function prepends the given style sheet to the document's style set
    * in order to make sure that it does not override user-agent style sheets
    * supplied by add-ons or by the app (Firefox OS or Firefox Mobile, for
    * example), since their sheets should override built-in sheets.
    *
    * TODO We can get rid of the whole concept of delayed loading if we fix
    * bug 77999.
    */
-  virtual void EnsureOnDemandBuiltInUASheet(nsCSSStyleSheet* aSheet) = 0;
+  virtual void EnsureOnDemandBuiltInUASheet(mozilla::CSSStyleSheet* aSheet) = 0;
 
   /**
    * Get the number of (document) stylesheets
    *
    * @return the number of stylesheets
    * @throws no exceptions
    */
   virtual int32_t GetNumberOfStyleSheets() const = 0;
@@ -1831,17 +1832,17 @@ public:
    * Called by the chrome registry to load style sheets.  Can be put
    * back there if and when when that module is merged with libgklayout.
    *
    * This always does a synchronous load.  If aIsAgentSheet is true,
    * it also uses the system principal and enables unsafe rules.
    * DO NOT USE FOR UNTRUSTED CONTENT.
    */
   virtual nsresult LoadChromeSheetSync(nsIURI* aURI, bool aIsAgentSheet,
-                                       nsCSSStyleSheet** aSheet) = 0;
+                                       mozilla::CSSStyleSheet** aSheet) = 0;
 
   /**
    * Returns true if the locale used for the document specifies a direction of
    * right to left. For chrome documents, this comes from the chrome registry.
    * This is used to determine the current state for the :-moz-locale-dir pseudoclass
    * so once can know whether a document is expected to be rendered left-to-right
    * or right-to-left.
    */
@@ -2269,20 +2270,20 @@ public:
   Element* GetBindingParent(nsINode& aNode);
   void LoadBindingDocument(const nsAString& aURI, mozilla::ErrorResult& rv);
   already_AddRefed<nsIDOMXPathExpression>
     CreateExpression(const nsAString& aExpression,
                      nsIDOMXPathNSResolver* aResolver,
                      mozilla::ErrorResult& rv);
   already_AddRefed<nsIDOMXPathNSResolver>
     CreateNSResolver(nsINode* aNodeResolver, mozilla::ErrorResult& rv);
-  already_AddRefed<nsISupports>
-    Evaluate(const nsAString& aExpression, nsINode* aContextNode,
+  already_AddRefed<mozilla::dom::XPathResult>
+    Evaluate(JSContext* aCx, const nsAString& aExpression, nsINode* aContextNode,
              nsIDOMXPathNSResolver* aResolver, uint16_t aType,
-             nsISupports* aResult, mozilla::ErrorResult& rv);
+             JS::Handle<JSObject*> aResult, mozilla::ErrorResult& rv);
   // Touch event handlers already on nsINode
   already_AddRefed<mozilla::dom::Touch>
     CreateTouch(nsIDOMWindow* aView, mozilla::dom::EventTarget* aTarget,
                 int32_t aIdentifier, int32_t aPageX, int32_t aPageY,
                 int32_t aScreenX, int32_t aScreenY, int32_t aClientX,
                 int32_t aClientY, int32_t aRadiusX, int32_t aRadiusY,
                 float aRotationAngle, float aForce);
   already_AddRefed<mozilla::dom::TouchList> CreateTouchList();
--- a/content/base/public/nsIStyleSheetLinkingElement.h
+++ b/content/base/public/nsIStyleSheetLinkingElement.h
@@ -11,30 +11,33 @@
 class nsICSSLoaderObserver;
 class nsIURI;
 
 #define NS_ISTYLESHEETLINKINGELEMENT_IID          \
 { 0xd753c84a, 0x17fd, 0x4d5f, \
  { 0xb2, 0xe9, 0x63, 0x52, 0x8c, 0x87, 0x99, 0x7a } }
 
 class nsIStyleSheet;
-class nsCSSStyleSheet;
+
+namespace mozilla {
+class CSSStyleSheet;
+} // namespace mozilla
 
 class nsIStyleSheetLinkingElement : public nsISupports {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISTYLESHEETLINKINGELEMENT_IID)
 
   /**
    * Used to make the association between a style sheet and
    * the element that linked it to the document.
    *
    * @param aStyleSheet the style sheet associated with this
    *                    element.
    */
-  NS_IMETHOD SetStyleSheet(nsCSSStyleSheet* aStyleSheet) = 0;
+  NS_IMETHOD SetStyleSheet(mozilla::CSSStyleSheet* aStyleSheet) = 0;
 
   /**
    * Used to obtain the style sheet linked in by this element.
    *
    * @param aStyleSheet out parameter that returns the style
    *                    sheet associated with this element.
    */
   NS_IMETHOD GetStyleSheet(nsIStyleSheet*& aStyleSheet) = 0;
--- a/content/base/src/ChildIterator.cpp
+++ b/content/base/src/ChildIterator.cpp
@@ -20,29 +20,29 @@ public:
     : mIsContentElement(true), mContentElement(aInsertionPoint) {}
 
   MatchedNodes(XBLChildrenElement* aInsertionPoint)
     : mIsContentElement(false), mChildrenElement(aInsertionPoint) {}
 
   uint32_t Length() const
   {
     return mIsContentElement ? mContentElement->MatchedNodes().Length()
-                             : mChildrenElement->mInsertedChildren.Length();
+                             : mChildrenElement->InsertedChildrenLength();
   }
 
   nsIContent* operator[](int32_t aIndex) const
   {
     return mIsContentElement ? mContentElement->MatchedNodes()[aIndex]
-                             : mChildrenElement->mInsertedChildren[aIndex];
+                             : mChildrenElement->InsertedChild(aIndex);
   }
 
   bool IsEmpty() const
   {
     return mIsContentElement ? mContentElement->MatchedNodes().IsEmpty()
-                             : mChildrenElement->mInsertedChildren.IsEmpty();
+                             : !mChildrenElement->HasInsertedChildren();
   }
 protected:
   bool mIsContentElement;
   union {
     HTMLContentElement* mContentElement;
     XBLChildrenElement* mChildrenElement;
   };
 };
--- a/content/base/src/EventSource.cpp
+++ b/content/base/src/EventSource.cpp
@@ -1231,25 +1231,21 @@ EventSource::DispatchAllMessageEvents()
 
   mGoingToDispatchAllMessages = false;
 
   nsresult rv = CheckInnerWindowCorrectness();
   if (NS_FAILED(rv)) {
     return;
   }
 
-  // We need a parent object so that we can enter its compartment.
-  nsCOMPtr<nsIGlobalObject> parentObject = do_QueryInterface(GetParentObject());
-  if (NS_WARN_IF(!parentObject)) {
+  AutoJSAPI jsapi;
+  if (NS_WARN_IF(!jsapi.InitUsingWin(GetOwner()))) {
     return;
   }
-
-  AutoJSAPI jsapi;
   JSContext* cx = jsapi.cx();
-  JSAutoCompartment ac(cx, parentObject->GetGlobalJSObject());
 
   while (mMessagesToDispatch.GetSize() > 0) {
     nsAutoPtr<Message>
       message(static_cast<Message*>(mMessagesToDispatch.PopFront()));
 
     // Now we can turn our string into a jsval
     JS::Rooted<JS::Value> jsData(cx);
     {
--- a/content/base/src/FragmentOrElement.cpp
+++ b/content/base/src/FragmentOrElement.cpp
@@ -495,16 +495,22 @@ nsNodeWeakReference::~nsNodeWeakReferenc
 
 NS_IMETHODIMP
 nsNodeWeakReference::QueryReferent(const nsIID& aIID, void** aInstancePtr)
 {
   return mNode ? mNode->QueryInterface(aIID, aInstancePtr) :
                  NS_ERROR_NULL_POINTER;
 }
 
+size_t
+nsNodeWeakReference::SizeOfOnlyThis(mozilla::MallocSizeOf aMallocSizeOf) const
+{
+  return aMallocSizeOf(this);
+}
+
 
 NS_IMPL_CYCLE_COLLECTION(nsNodeSupportsWeakRefTearoff, mNode)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsNodeSupportsWeakRefTearoff)
   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
 NS_INTERFACE_MAP_END_AGGREGATED(mNode)
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsNodeSupportsWeakRefTearoff)
--- a/content/base/src/ShadowRoot.cpp
+++ b/content/base/src/ShadowRoot.cpp
@@ -132,17 +132,17 @@ ShadowRoot::StyleSheetChanged()
   if (shell) {
     OwnerDoc()->BeginUpdate(UPDATE_STYLE);
     shell->RecordShadowStyleChange(this);
     OwnerDoc()->EndUpdate(UPDATE_STYLE);
   }
 }
 
 void
-ShadowRoot::InsertSheet(nsCSSStyleSheet* aSheet,
+ShadowRoot::InsertSheet(CSSStyleSheet* aSheet,
                         nsIContent* aLinkingContent)
 {
   nsCOMPtr<nsIStyleSheetLinkingElement>
     linkingElement = do_QueryInterface(aLinkingContent);
   MOZ_ASSERT(linkingElement, "The only styles in a ShadowRoot should come "
                              "from <style>.");
 
   linkingElement->SetStyleSheet(aSheet); // This sets the ownerNode on the sheet
@@ -163,17 +163,17 @@ ShadowRoot::InsertSheet(nsCSSStyleSheet*
   }
 
   if (aSheet->IsApplicable()) {
     StyleSheetChanged();
   }
 }
 
 void
-ShadowRoot::RemoveSheet(nsCSSStyleSheet* aSheet)
+ShadowRoot::RemoveSheet(CSSStyleSheet* aSheet)
 {
   mProtoBinding->RemoveStyleSheet(aSheet);
 
   if (aSheet->IsApplicable()) {
     StyleSheetChanged();
   }
 }
 
@@ -714,17 +714,17 @@ ShadowRootStyleSheetList::ShadowRootStyl
   MOZ_COUNT_CTOR(ShadowRootStyleSheetList);
 }
 
 ShadowRootStyleSheetList::~ShadowRootStyleSheetList()
 {
   MOZ_COUNT_DTOR(ShadowRootStyleSheetList);
 }
 
-nsCSSStyleSheet*
+CSSStyleSheet*
 ShadowRootStyleSheetList::IndexedGetter(uint32_t aIndex, bool& aFound)
 {
   aFound = aIndex < mShadowRoot->mProtoBinding->SheetCount();
 
   if (!aFound) {
     return nullptr;
   }
 
--- a/content/base/src/ShadowRoot.h
+++ b/content/base/src/ShadowRoot.h
@@ -43,18 +43,18 @@ public:
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
 
   ShadowRoot(nsIContent* aContent, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
              nsXBLPrototypeBinding* aProtoBinding);
   virtual ~ShadowRoot();
 
   void AddToIdTable(Element* aElement, nsIAtom* aId);
   void RemoveFromIdTable(Element* aElement, nsIAtom* aId);
-  void InsertSheet(nsCSSStyleSheet* aSheet, nsIContent* aLinkingContent);
-  void RemoveSheet(nsCSSStyleSheet* aSheet);
+  void InsertSheet(CSSStyleSheet* aSheet, nsIContent* aLinkingContent);
+  void RemoveSheet(CSSStyleSheet* aSheet);
   bool ApplyAuthorStyles();
   void SetApplyAuthorStyles(bool aApplyAuthorStyles);
   StyleSheetList* StyleSheets();
   HTMLShadowElement* GetShadowElement() { return mShadowElement; }
 
   /**
    * Sets the current shadow insertion point where the older
    * ShadowRoot will be projected.
@@ -182,17 +182,17 @@ public:
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ShadowRootStyleSheetList, StyleSheetList)
 
   virtual nsINode* GetParentObject() const MOZ_OVERRIDE
   {
     return mShadowRoot;
   }
 
   virtual uint32_t Length() MOZ_OVERRIDE;
-  virtual nsCSSStyleSheet* IndexedGetter(uint32_t aIndex, bool& aFound) MOZ_OVERRIDE;
+  virtual CSSStyleSheet* IndexedGetter(uint32_t aIndex, bool& aFound) MOZ_OVERRIDE;
 
 protected:
   nsRefPtr<ShadowRoot> mShadowRoot;
 };
 
 } // namespace dom
 } // namespace mozilla
 
--- a/content/base/src/StyleSheetList.cpp
+++ b/content/base/src/StyleSheetList.cpp
@@ -1,17 +1,17 @@
 /* -*- Mode: C++; 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/. */
 
 #include "mozilla/dom/StyleSheetList.h"
 
+#include "mozilla/CSSStyleSheet.h"
 #include "mozilla/dom/StyleSheetListBinding.h"
-#include "nsCSSStyleSheet.h"
 
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(StyleSheetList)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(StyleSheetList)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
--- a/content/base/src/StyleSheetList.h
+++ b/content/base/src/StyleSheetList.h
@@ -4,20 +4,21 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_StyleSheetList_h
 #define mozilla_dom_StyleSheetList_h
 
 #include "nsIDOMStyleSheetList.h"
 #include "nsWrapperCache.h"
 
-class nsCSSStyleSheet;
 class nsINode;
 
 namespace mozilla {
+class CSSStyleSheet;
+
 namespace dom {
 
 class StyleSheetList : public nsIDOMStyleSheetList
                      , public nsWrapperCache
 {
 public:
   StyleSheetList()
   {
@@ -29,18 +30,18 @@ public:
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(StyleSheetList)
   NS_DECL_NSIDOMSTYLESHEETLIST
 
   virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE MOZ_FINAL;
 
   virtual nsINode* GetParentObject() const = 0;
 
   virtual uint32_t Length() = 0;
-  virtual nsCSSStyleSheet* IndexedGetter(uint32_t aIndex, bool& aFound) = 0;
-  nsCSSStyleSheet* Item(uint32_t aIndex)
+  virtual CSSStyleSheet* IndexedGetter(uint32_t aIndex, bool& aFound) = 0;
+  CSSStyleSheet* Item(uint32_t aIndex)
   {
     bool dummy = false;
     return IndexedGetter(aIndex, dummy);
   }
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/content/base/src/WebSocket.cpp
+++ b/content/base/src/WebSocket.cpp
@@ -860,24 +860,21 @@ WebSocket::CreateAndDispatchMessageEvent
                                          bool isBinary)
 {
   NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
 
   nsresult rv = CheckInnerWindowCorrectness();
   if (NS_FAILED(rv))
     return NS_OK;
 
-  nsCOMPtr<nsIGlobalObject> globalObject = do_QueryInterface(GetOwner());
-  if (NS_WARN_IF(!globalObject)) {
+  AutoJSAPI jsapi;
+  if (NS_WARN_IF(!jsapi.InitUsingWin(GetOwner()))) {
     return NS_ERROR_FAILURE;
   }
-
-  AutoJSAPI jsapi;
   JSContext* cx = jsapi.cx();
-  JSAutoCompartment ac(cx, globalObject->GetGlobalJSObject());
 
   // Create appropriate JS object for message
   JS::Rooted<JS::Value> jsData(cx);
   if (isBinary) {
     if (mBinaryType == dom::BinaryType::Blob) {
       rv = nsContentUtils::CreateBlobBuffer(cx, aData, &jsData);
       NS_ENSURE_SUCCESS(rv, rv);
     } else if (mBinaryType == dom::BinaryType::Arraybuffer) {
--- a/content/base/src/nsContentSink.cpp
+++ b/content/base/src/nsContentSink.cpp
@@ -202,17 +202,17 @@ nsContentSink::Init(nsIDocument* aDoc,
     mDynamicLowerValue = sEnablePerfMode == 1;
     FavorPerformanceHint(!mDynamicLowerValue, 0);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsContentSink::StyleSheetLoaded(nsCSSStyleSheet* aSheet,
+nsContentSink::StyleSheetLoaded(CSSStyleSheet* aSheet,
                                 bool aWasAlternate,
                                 nsresult aStatus)
 {
   NS_ASSERTION(!mRunsToCompletion, "How come a fragment parser observed sheets?");
   if (!aWasAlternate) {
     NS_ASSERTION(mPendingSheetCount > 0, "How'd that happen?");
     --mPendingSheetCount;
 
--- a/content/base/src/nsContentSink.h
+++ b/content/base/src/nsContentSink.h
@@ -81,17 +81,18 @@ class nsContentSink : public nsICSSLoade
 {
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsContentSink,
                                            nsICSSLoaderObserver)
     // nsITimerCallback
   NS_DECL_NSITIMERCALLBACK
 
   // nsICSSLoaderObserver
-  NS_IMETHOD StyleSheetLoaded(nsCSSStyleSheet* aSheet, bool aWasAlternate,
+  NS_IMETHOD StyleSheetLoaded(mozilla::CSSStyleSheet* aSheet,
+                              bool aWasAlternate,
                               nsresult aStatus) MOZ_OVERRIDE;
 
   virtual nsresult ProcessMETATag(nsIContent* aContent);
 
   // nsIContentSink implementation helpers
   nsresult WillParseImpl(void);
   nsresult WillInterruptImpl(void);
   nsresult WillResumeImpl(void);
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -6406,25 +6406,22 @@ nsContentUtils::GetContentSecurityPolicy
 }
 
 // static
 bool
 nsContentUtils::IsPatternMatching(nsAString& aValue, nsAString& aPattern,
                                   nsIDocument* aDocument)
 {
   NS_ASSERTION(aDocument, "aDocument should be a valid pointer (not null)");
-  nsCOMPtr<nsIGlobalObject> globalObject =
-    do_QueryInterface(aDocument->GetWindow());
-  if (NS_WARN_IF(!globalObject)) {
-    return true;
-  }
 
   AutoJSAPI jsapi;
+  if (NS_WARN_IF(!jsapi.InitUsingWin(aDocument->GetWindow()))) {
+    return true;
+  }
   JSContext* cx = jsapi.cx();
-  JSAutoCompartment ac(cx, globalObject->GetGlobalJSObject());
 
   // The pattern has to match the entire value.
   aPattern.Insert(NS_LITERAL_STRING("^(?:"), 0);
   aPattern.AppendLiteral(")$");
 
   JS::Rooted<JSObject*> re(cx,
     JS_NewUCRegExpObjectNoStatics(cx,
                                   static_cast<jschar*>(aPattern.BeginWriting()),
--- a/content/base/src/nsDOMDataChannel.cpp
+++ b/content/base/src/nsDOMDataChannel.cpp
@@ -378,24 +378,21 @@ nsDOMDataChannel::DoOnMessageAvailable(c
 
   LOG(("DoOnMessageAvailable%s\n",aBinary ? ((mBinaryType == DC_BINARY_TYPE_BLOB) ? " (blob)" : " (binary)") : ""));
 
   nsresult rv = CheckInnerWindowCorrectness();
   if (NS_FAILED(rv)) {
     return NS_OK;
   }
 
-  nsCOMPtr<nsIGlobalObject> globalObject = do_QueryInterface(GetOwner());
-  if (NS_WARN_IF(!globalObject)) {
+  AutoJSAPI jsapi;
+  if (NS_WARN_IF(!jsapi.InitUsingWin(GetOwner()))) {
     return NS_ERROR_FAILURE;
   }
-
-  AutoJSAPI jsapi;
   JSContext* cx = jsapi.cx();
-  JSAutoCompartment ac(cx, globalObject->GetGlobalJSObject());
 
   JS::Rooted<JS::Value> jsData(cx);
 
   if (aBinary) {
     if (mBinaryType == DC_BINARY_TYPE_BLOB) {
       rv = nsContentUtils::CreateBlobBuffer(cx, aData, &jsData);
       NS_ENSURE_SUCCESS(rv, rv);
     } else if (mBinaryType == DC_BINARY_TYPE_ARRAYBUFFER) {
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -213,16 +213,17 @@
 #include "nsIEditor.h"
 #include "nsIDOMCSSStyleRule.h"
 #include "mozilla/css/Rule.h"
 #include "nsIDOMLocation.h"
 #include "nsIHttpChannelInternal.h"
 #include "nsISecurityConsoleMessage.h"
 #include "nsCharSeparatedTokenizer.h"
 #include "mozilla/dom/XPathEvaluator.h"
+#include "mozilla/dom/XPathResult.h"
 #include "nsIDocumentEncoder.h"
 #include "nsIDocumentActivity.h"
 #include "nsIStructuredCloneContainer.h"
 #include "nsIMutableArray.h"
 #include "nsContentPermissionHelper.h"
 #include "mozilla/dom/DOMStringList.h"
 #include "nsWindowMemoryReporter.h"
 
@@ -756,29 +757,29 @@ nsDOMStyleSheetList::Length()
       nsCOMPtr<nsIDOMStyleSheet> domss(do_QueryInterface(sheet));
       NS_ASSERTION(domss, "All \"normal\" sheets implement nsIDOMStyleSheet");
     }
 #endif
   }
   return mLength;
 }
 
-nsCSSStyleSheet*
+CSSStyleSheet*
 nsDOMStyleSheetList::IndexedGetter(uint32_t aIndex, bool& aFound)
 {
   if (!mDocument || aIndex >= (uint32_t)mDocument->GetNumberOfStyleSheets()) {
     aFound = false;
     return nullptr;
   }
 
   aFound = true;
   nsIStyleSheet *sheet = mDocument->GetStyleSheetAt(aIndex);
   NS_ASSERTION(sheet, "Must have a sheet");
 
-  return static_cast<nsCSSStyleSheet*>(sheet);
+  return static_cast<CSSStyleSheet*>(sheet);
 }
 
 void
 nsDOMStyleSheetList::NodeWillBeDestroyed(const nsINode *aNode)
 {
   mDocument = nullptr;
 }
 
@@ -3965,29 +3966,29 @@ nsDocument::RemoveChildAt(uint32_t aInde
     DestroyElementMaps();
   }
 
   doRemoveChildAt(aIndex, aNotify, oldKid, mChildren);
   mCachedRootElement = nullptr;
 }
 
 void
-nsDocument::EnsureOnDemandBuiltInUASheet(nsCSSStyleSheet* aSheet)
+nsDocument::EnsureOnDemandBuiltInUASheet(CSSStyleSheet* aSheet)
 {
   // Contains() takes nsISupport*, so annoyingly we have to cast here
   if (mOnDemandBuiltInUASheets.Contains(static_cast<nsIStyleSheet*>(aSheet))) {
     return;
   }
   BeginUpdate(UPDATE_STYLE);
   AddOnDemandBuiltInUASheet(aSheet);
   EndUpdate(UPDATE_STYLE);
 }
 
 void
-nsDocument::AddOnDemandBuiltInUASheet(nsCSSStyleSheet* aSheet)
+nsDocument::AddOnDemandBuiltInUASheet(CSSStyleSheet* aSheet)
 {
   // Contains() takes nsISupport*, so annoyingly we have to cast here
   MOZ_ASSERT(!mOnDemandBuiltInUASheets.Contains(static_cast<nsIStyleSheet*>(aSheet)));
 
   // Prepend here so that we store the sheets in mOnDemandBuiltInUASheets in
   // the same order that they should end up in the style set.
   mOnDemandBuiltInUASheets.InsertElementAt(0, aSheet);
 
@@ -4275,17 +4276,17 @@ nsDocument::LoadAdditionalStyleSheet(add
 
   // Checking if we have loaded this one already.
   if (FindSheet(mAdditionalSheets[aType], aSheetURI) >= 0)
     return NS_ERROR_INVALID_ARG;
 
   // Loading the sheet sync.
   nsRefPtr<mozilla::css::Loader> loader = new mozilla::css::Loader();
 
-  nsRefPtr<nsCSSStyleSheet> sheet;
+  nsRefPtr<CSSStyleSheet> sheet;
   nsresult rv = loader->LoadSheetSync(aSheetURI, aType == eAgentSheet,
     true, getter_AddRefs(sheet));
   NS_ENSURE_SUCCESS(rv, rv);
 
   mAdditionalSheets[aType].AppendObject(sheet);
   sheet->SetOwningDocument(this);
   MOZ_ASSERT(sheet->IsApplicable());
 
@@ -9326,17 +9327,17 @@ namespace {
 
 /**
  * Stub for LoadSheet(), since all we want is to get the sheet into
  * the CSSLoader's style cache
  */
 class StubCSSLoaderObserver MOZ_FINAL : public nsICSSLoaderObserver {
 public:
   NS_IMETHOD
-  StyleSheetLoaded(nsCSSStyleSheet*, bool, nsresult)
+  StyleSheetLoaded(CSSStyleSheet*, bool, nsresult)
   {
     return NS_OK;
   }
   NS_DECL_ISUPPORTS
 };
 NS_IMPL_ISUPPORTS(StubCSSLoaderObserver, nsICSSLoaderObserver)
 
 }
@@ -9352,17 +9353,17 @@ nsDocument::PreloadStyle(nsIURI* uri, co
   CSSLoader()->LoadSheet(uri, NodePrincipal(),
                          NS_LossyConvertUTF16toASCII(charset),
                          obs,
                          Element::StringToCORSMode(aCrossOriginAttr));
 }
 
 nsresult
 nsDocument::LoadChromeSheetSync(nsIURI* uri, bool isAgentSheet,
-                                nsCSSStyleSheet** sheet)
+                                CSSStyleSheet** sheet)
 {
   return CSSLoader()->LoadSheetSync(uri, isAgentSheet, isAgentSheet, sheet);
 }
 
 class nsDelayedEventDispatcher : public nsRunnable
 {
 public:
   nsDelayedEventDispatcher(nsTArray<nsCOMPtr<nsIDocument> >& aDocuments)
@@ -9701,37 +9702,37 @@ nsIDocument::CreateStaticClone(nsIDocShe
       clonedDoc = static_cast<nsDocument*>(tmp.get());
       if (IsStaticDocument()) {
         clonedDoc->mOriginalDocument = mOriginalDocument;
       } else {
         clonedDoc->mOriginalDocument = this;
       }
       int32_t sheetsCount = GetNumberOfStyleSheets();
       for (int32_t i = 0; i < sheetsCount; ++i) {
-        nsRefPtr<nsCSSStyleSheet> sheet = do_QueryObject(GetStyleSheetAt(i));
+        nsRefPtr<CSSStyleSheet> sheet = do_QueryObject(GetStyleSheetAt(i));
         if (sheet) {
           if (sheet->IsApplicable()) {
-            nsRefPtr<nsCSSStyleSheet> clonedSheet =
+            nsRefPtr<CSSStyleSheet> clonedSheet =
               sheet->Clone(nullptr, nullptr, clonedDoc, nullptr);
             NS_WARN_IF_FALSE(clonedSheet, "Cloning a stylesheet didn't work!");
             if (clonedSheet) {
               clonedDoc->AddStyleSheet(clonedSheet);
             }
           }
         }
       }
 
       sheetsCount = thisAsDoc->mOnDemandBuiltInUASheets.Count();
       // Iterate backwards to maintain order
       for (int32_t i = sheetsCount - 1; i >= 0; --i) {
-        nsRefPtr<nsCSSStyleSheet> sheet =
+        nsRefPtr<CSSStyleSheet> sheet =
           do_QueryObject(thisAsDoc->mOnDemandBuiltInUASheets[i]);
         if (sheet) {
           if (sheet->IsApplicable()) {
-            nsRefPtr<nsCSSStyleSheet> clonedSheet =
+            nsRefPtr<CSSStyleSheet> clonedSheet =
               sheet->Clone(nullptr, nullptr, clonedDoc, nullptr);
             NS_WARN_IF_FALSE(clonedSheet, "Cloning a stylesheet didn't work!");
             if (clonedSheet) {
               clonedDoc->AddOnDemandBuiltInUASheet(clonedSheet);
             }
           }
         }
       }
@@ -12099,23 +12100,24 @@ nsIDocument::CreateExpression(const nsAS
 
 already_AddRefed<nsIDOMXPathNSResolver>
 nsIDocument::CreateNSResolver(nsINode* aNodeResolver,
                               ErrorResult& rv)
 {
   return XPathEvaluator()->CreateNSResolver(aNodeResolver, rv);
 }
 
-already_AddRefed<nsISupports>
-nsIDocument::Evaluate(const nsAString& aExpression, nsINode* aContextNode,
-                      nsIDOMXPathNSResolver* aResolver, uint16_t aType,
-                      nsISupports* aResult, ErrorResult& rv)
-{
-  return XPathEvaluator()->Evaluate(aExpression, aContextNode, aResolver, aType,
-                                    aResult, rv);
+already_AddRefed<XPathResult>
+nsIDocument::Evaluate(JSContext* aCx, const nsAString& aExpression,
+                      nsINode* aContextNode, nsIDOMXPathNSResolver* aResolver,
+                      uint16_t aType, JS::Handle<JSObject*> aResult,
+                      ErrorResult& rv)
+{
+  return XPathEvaluator()->Evaluate(aCx, aExpression, aContextNode, aResolver,
+                                    aType, aResult, rv);
 }
 
 NS_IMETHODIMP
 nsDocument::CreateExpression(const nsAString& aExpression,
                              nsIDOMXPathNSResolver* aResolver,
                              nsIDOMXPathExpression** aResult)
 {
   return XPathEvaluator()->CreateExpression(aExpression, aResolver, aResult);
--- a/content/base/src/nsDocument.h
+++ b/content/base/src/nsDocument.h
@@ -452,17 +452,18 @@ public:
   NS_DECL_NSIMUTATIONOBSERVER_NODEWILLBEDESTROYED
 
   virtual nsINode* GetParentObject() const MOZ_OVERRIDE
   {
     return mDocument;
   }
 
   virtual uint32_t Length() MOZ_OVERRIDE;
-  virtual nsCSSStyleSheet* IndexedGetter(uint32_t aIndex, bool& aFound) MOZ_OVERRIDE;
+  virtual mozilla::CSSStyleSheet*
+  IndexedGetter(uint32_t aIndex, bool& aFound) MOZ_OVERRIDE;
 
 protected:
   int32_t       mLength;
   nsIDocument*  mDocument;
 };
 
 class nsOnloadBlocker MOZ_FINAL : public nsIRequest
 {
@@ -775,17 +776,17 @@ public:
   virtual mozilla::dom::AnimationTimeline* Timeline() MOZ_OVERRIDE;
 
   virtual nsresult SetSubDocumentFor(Element* aContent,
                                      nsIDocument* aSubDoc) MOZ_OVERRIDE;
   virtual nsIDocument* GetSubDocumentFor(nsIContent* aContent) const MOZ_OVERRIDE;
   virtual Element* FindContentForSubDocument(nsIDocument *aDocument) const MOZ_OVERRIDE;
   virtual Element* GetRootElementInternal() const MOZ_OVERRIDE;
 
-  virtual void EnsureOnDemandBuiltInUASheet(nsCSSStyleSheet* aSheet) MOZ_OVERRIDE;
+  virtual void EnsureOnDemandBuiltInUASheet(mozilla::CSSStyleSheet* aSheet) MOZ_OVERRIDE;
 
   /**
    * Get the (document) style sheets owned by this document.
    * These are ordered, highest priority last
    */
   virtual int32_t GetNumberOfStyleSheets() const MOZ_OVERRIDE;
   virtual nsIStyleSheet* GetStyleSheetAt(int32_t aIndex) const MOZ_OVERRIDE;
   virtual int32_t GetIndexOfStyleSheet(nsIStyleSheet* aSheet) const MOZ_OVERRIDE;
@@ -927,17 +928,17 @@ public:
 
   // for radio group
   nsRadioGroupStruct* GetRadioGroup(const nsAString& aName) const;
   nsRadioGroupStruct* GetOrCreateRadioGroup(const nsAString& aName);
 
   virtual nsViewportInfo GetViewportInfo(const mozilla::ScreenIntSize& aDisplaySize) MOZ_OVERRIDE;
 
 private:
-  void AddOnDemandBuiltInUASheet(nsCSSStyleSheet* aSheet);
+  void AddOnDemandBuiltInUASheet(mozilla::CSSStyleSheet* aSheet);
   nsRadioGroupStruct* GetRadioGroupInternal(const nsAString& aName) const;
   void SendToConsole(nsCOMArray<nsISecurityConsoleMessage>& aMessages);
 
 public:
   // nsIDOMNode
   NS_FORWARD_NSIDOMNODE_TO_NSINODE_OVERRIDABLE
 
   // nsIDOMDocument
@@ -1075,17 +1076,17 @@ public:
 
   virtual void MaybePreLoadImage(nsIURI* uri,
                                  const nsAString &aCrossOriginAttr) MOZ_OVERRIDE;
 
   virtual void PreloadStyle(nsIURI* uri, const nsAString& charset,
                             const nsAString& aCrossOriginAttr) MOZ_OVERRIDE;
 
   virtual nsresult LoadChromeSheetSync(nsIURI* uri, bool isAgentSheet,
-                                       nsCSSStyleSheet** sheet) MOZ_OVERRIDE;
+                                       mozilla::CSSStyleSheet** sheet) MOZ_OVERRIDE;
 
   virtual nsISupports* GetCurrentContentSink() MOZ_OVERRIDE;
 
   virtual mozilla::EventStates GetDocumentState() MOZ_OVERRIDE;
 
   virtual void RegisterHostObjectUri(const nsACString& aUri) MOZ_OVERRIDE;
   virtual void UnregisterHostObjectUri(const nsACString& aUri) MOZ_OVERRIDE;
 
--- a/content/base/src/nsFrameLoader.cpp
+++ b/content/base/src/nsFrameLoader.cpp
@@ -2064,24 +2064,33 @@ nsFrameLoader::TryRemoteBrowser()
     return false;
   }
 
   nsCOMPtr<nsPIDOMWindow> parentWin = doc->GetWindow();
   if (!parentWin) {
     return false;
   }
 
-  nsCOMPtr<nsIDocShellTreeItem> parentAsItem(parentWin->GetDocShell());
-  if (!parentAsItem) {
+  nsCOMPtr<nsIDocShell> parentDocShell = parentWin->GetDocShell();
+  if (!parentDocShell) {
     return false;
   }
 
+  TabParent* openingTab = static_cast<TabParent*>(parentDocShell->GetOpener());
+  ContentParent* openerContentParent = nullptr;
+
+  if (openingTab &&
+      openingTab->Manager() &&
+      openingTab->Manager()->IsContentParent()) {
+    openerContentParent = openingTab->Manager()->AsContentParent();
+  }
+
   // <iframe mozbrowser> gets to skip these checks.
   if (!OwnerIsBrowserOrAppFrame()) {
-    if (parentAsItem->ItemType() != nsIDocShellTreeItem::typeChrome) {
+    if (parentDocShell->ItemType() != nsIDocShellTreeItem::typeChrome) {
       return false;
     }
 
     if (!mOwnerContent->IsXUL()) {
       return false;
     }
 
     nsAutoString value;
@@ -2091,17 +2100,17 @@ nsFrameLoader::TryRemoteBrowser()
         !StringBeginsWith(value, NS_LITERAL_STRING("content-"),
                           nsCaseInsensitiveStringComparator())) {
       return false;
     }
   }
 
   uint32_t chromeFlags = 0;
   nsCOMPtr<nsIDocShellTreeOwner> parentOwner;
-  if (NS_FAILED(parentAsItem->GetTreeOwner(getter_AddRefs(parentOwner))) ||
+  if (NS_FAILED(parentDocShell->GetTreeOwner(getter_AddRefs(parentOwner))) ||
       !parentOwner) {
     return false;
   }
   nsCOMPtr<nsIXULWindow> window(do_GetInterface(parentOwner));
   if (window && NS_FAILED(window->GetChromeFlags(&chromeFlags))) {
     return false;
   }
 
@@ -2128,21 +2137,21 @@ nsFrameLoader::TryRemoteBrowser()
     // The |else| above is unnecessary; OwnerIsBrowserFrame() implies !ownApp.
     rv = context.SetTabContextForBrowserFrame(containingApp, scrollingBehavior);
   } else {
     rv = context.SetTabContextForNormalFrame(scrollingBehavior);
   }
   NS_ENSURE_TRUE(rv, false);
 
   nsCOMPtr<Element> ownerElement = mOwnerContent;
-  mRemoteBrowser = ContentParent::CreateBrowserOrApp(context, ownerElement);
+  mRemoteBrowser = ContentParent::CreateBrowserOrApp(context, ownerElement, openerContentParent);
   if (mRemoteBrowser) {
     mChildID = mRemoteBrowser->Manager()->ChildID();
     nsCOMPtr<nsIDocShellTreeItem> rootItem;
-    parentAsItem->GetRootTreeItem(getter_AddRefs(rootItem));
+    parentDocShell->GetRootTreeItem(getter_AddRefs(rootItem));
     nsCOMPtr<nsIDOMWindow> rootWin = rootItem->GetWindow();
     nsCOMPtr<nsIDOMChromeWindow> rootChromeWin = do_QueryInterface(rootWin);
 
     if (rootChromeWin) {
       nsCOMPtr<nsIBrowserDOMWindow> browserDOMWin;
       rootChromeWin->GetBrowserDOMWindow(getter_AddRefs(browserDOMWin));
       mRemoteBrowser->SetBrowserDOMWindow(browserDOMWin);
     }
@@ -2150,16 +2159,17 @@ nsFrameLoader::TryRemoteBrowser()
     mContentParent = mRemoteBrowser->Manager();
 
     if (mOwnerContent->AttrValueIs(kNameSpaceID_None,
                                    nsGkAtoms::mozpasspointerevents,
                                    nsGkAtoms::_true,
                                    eCaseMatters)) {
       unused << mRemoteBrowser->SendSetUpdateHitRegion(true);
     }
+    parentDocShell->SetOpenedRemote(mRemoteBrowser);
   }
   return true;
 }
 
 mozilla::dom::PBrowserParent*
 nsFrameLoader::GetRemoteBrowser()
 {
   return mRemoteBrowser;
--- a/content/base/src/nsScriptLoader.cpp
+++ b/content/base/src/nsScriptLoader.cpp
@@ -882,26 +882,23 @@ nsScriptLoader::AttemptAsyncScriptParse(
     return NS_ERROR_FAILURE;
   }
 
   nsCOMPtr<nsIScriptGlobalObject> globalObject = GetScriptGlobalObject();
   if (!globalObject) {
     return NS_ERROR_FAILURE;
   }
 
-  nsCOMPtr<nsIScriptContext> context = globalObject->GetScriptContext();
-  if (!context) {
+  AutoJSAPI jsapi;
+  if (!jsapi.InitWithLegacyErrorReporting(globalObject)) {
     return NS_ERROR_FAILURE;
   }
 
-  AutoJSAPIWithErrorsReportedToWindow jsapi(context);
   JSContext* cx = jsapi.cx();
   JS::Rooted<JSObject*> global(cx, globalObject->GetGlobalJSObject());
-  JSAutoCompartment ac(cx, global);
-
   JS::CompileOptions options(cx);
   FillCompileOptionsForRequest(aRequest, global, &options);
 
   if (!JS::CanCompileOffThread(cx, options, aRequest->mScriptTextLength)) {
     return NS_ERROR_FAILURE;
   }
 
   nsRefPtr<NotifyOffThreadScriptLoadCompletedRunnable> runnable =
--- a/content/base/src/nsStyleLinkElement.cpp
+++ b/content/base/src/nsStyleLinkElement.cpp
@@ -7,22 +7,22 @@
 /*
  * A base class which implements nsIStyleSheetLinkingElement and can
  * be subclassed by various content nodes that want to load
  * stylesheets (<style>, <link>, processing instructions, etc).
  */
 
 #include "nsStyleLinkElement.h"
 
+#include "mozilla/CSSStyleSheet.h"
 #include "mozilla/css/Loader.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/FragmentOrElement.h"
 #include "mozilla/dom/ShadowRoot.h"
 #include "mozilla/Preferences.h"
-#include "nsCSSStyleSheet.h"
 #include "nsIContent.h"
 #include "nsIDocument.h"
 #include "nsIDOMComment.h"
 #include "nsIDOMNode.h"
 #include "nsIDOMStyleSheet.h"
 #include "nsNetUtil.h"
 #include "nsUnicharUtils.h"
 #include "nsCRT.h"
@@ -55,17 +55,17 @@ nsStyleLinkElement::Unlink()
 void
 nsStyleLinkElement::Traverse(nsCycleCollectionTraversalCallback &cb)
 {
   nsStyleLinkElement* tmp = this;
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStyleSheet);
 }
 
 NS_IMETHODIMP 
-nsStyleLinkElement::SetStyleSheet(nsCSSStyleSheet* aStyleSheet)
+nsStyleLinkElement::SetStyleSheet(CSSStyleSheet* aStyleSheet)
 {
   if (mStyleSheet) {
     mStyleSheet->SetOwningNode(nullptr);
   }
 
   mStyleSheet = aStyleSheet;
   if (mStyleSheet) {
     nsCOMPtr<nsINode> node = do_QueryObject(this);
@@ -257,17 +257,17 @@ UpdateIsElementInStyleScopeFlagOnSubtree
       n = n->GetNextNode(aElement);
     }
   }
 }
 
 static Element*
 GetScopeElement(nsIStyleSheet* aSheet)
 {
-  nsRefPtr<nsCSSStyleSheet> cssStyleSheet = do_QueryObject(aSheet);
+  nsRefPtr<CSSStyleSheet> cssStyleSheet = do_QueryObject(aSheet);
   if (!cssStyleSheet) {
     return nullptr;
   }
 
   return cssStyleSheet->GetScopeElement();
 }
 
 nsresult
--- a/content/base/src/nsStyleLinkElement.h
+++ b/content/base/src/nsStyleLinkElement.h
@@ -9,21 +9,21 @@
  * be subclassed by various content nodes that want to load
  * stylesheets (<style>, <link>, processing instructions, etc).
  */
 
 #ifndef nsStyleLinkElement_h___
 #define nsStyleLinkElement_h___
 
 #include "mozilla/Attributes.h"
+#include "mozilla/CORSMode.h"
+#include "mozilla/CSSStyleSheet.h"
 #include "nsCOMPtr.h"
 #include "nsIStyleSheetLinkingElement.h"
-#include "nsCSSStyleSheet.h"
 #include "nsTArray.h"
-#include "mozilla/CORSMode.h"
 
 class nsIDocument;
 class nsIURI;
 
 namespace mozilla {
 namespace dom {
 class ShadowRoot;
 } // namespace dom
@@ -32,20 +32,20 @@ class ShadowRoot;
 class nsStyleLinkElement : public nsIStyleSheetLinkingElement
 {
 public:
   nsStyleLinkElement();
   virtual ~nsStyleLinkElement();
 
   NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) MOZ_OVERRIDE = 0;
 
-  nsCSSStyleSheet* GetSheet() const { return mStyleSheet; }
+  mozilla::CSSStyleSheet* GetSheet() const { return mStyleSheet; }
 
   // nsIStyleSheetLinkingElement  
-  NS_IMETHOD SetStyleSheet(nsCSSStyleSheet* aStyleSheet) MOZ_OVERRIDE;
+  NS_IMETHOD SetStyleSheet(mozilla::CSSStyleSheet* aStyleSheet) MOZ_OVERRIDE;
   NS_IMETHOD GetStyleSheet(nsIStyleSheet*& aStyleSheet) MOZ_OVERRIDE;
   NS_IMETHOD InitStyleLinkElement(bool aDontLoadStyle) MOZ_OVERRIDE;
   NS_IMETHOD UpdateStyleSheet(nsICSSLoaderObserver* aObserver,
                               bool* aWillNotify,
                               bool* aIsAlternate) MOZ_OVERRIDE;
   NS_IMETHOD SetEnableUpdates(bool aEnableUpdates) MOZ_OVERRIDE;
   NS_IMETHOD GetCharset(nsAString& aCharset) MOZ_OVERRIDE;
 
@@ -117,17 +117,17 @@ private:
    */
   nsresult DoUpdateStyleSheet(nsIDocument* aOldDocument,
                               mozilla::dom::ShadowRoot* aOldShadowRoot,
                               nsICSSLoaderObserver* aObserver,
                               bool* aWillNotify,
                               bool* aIsAlternate,
                               bool aForceUpdate);
 
-  nsRefPtr<nsCSSStyleSheet> mStyleSheet;
+  nsRefPtr<mozilla::CSSStyleSheet> mStyleSheet;
 protected:
   bool mDontLoadStyle;
   bool mUpdatesEnabled;
   uint32_t mLineNumber;
 };
 
 #endif /* nsStyleLinkElement_h___ */
 
--- a/content/base/src/nsTreeSanitizer.cpp
+++ b/content/base/src/nsTreeSanitizer.cpp
@@ -1,24 +1,24 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set sw=2 ts=2 et tw=80: */
 /* 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 "mozilla/ArrayUtils.h"
+#include "nsTreeSanitizer.h"
 
-#include "nsTreeSanitizer.h"
-#include "nsCSSParser.h"
-#include "nsCSSProperty.h"
+#include "mozilla/ArrayUtils.h"
+#include "mozilla/CSSStyleSheet.h"
 #include "mozilla/css/Declaration.h"
 #include "mozilla/css/StyleRule.h"
 #include "mozilla/css/Rule.h"
+#include "nsCSSParser.h"
+#include "nsCSSProperty.h"
 #include "nsUnicharInputStream.h"
-#include "nsCSSStyleSheet.h"
 #include "nsIDOMCSSRule.h"
 #include "nsAttrName.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsNetUtil.h"
 #include "nsComponentManagerUtils.h"
 #include "nsNullPrincipal.h"
 #include "nsContentUtils.h"
 #include "nsIParserUtils.h"
@@ -1093,17 +1093,17 @@ nsTreeSanitizer::SanitizeStyleSheet(cons
                                     nsIURI* aBaseURI)
 {
   nsresult rv;
   aSanitized.Truncate();
   // aSanitized will hold the permitted CSS text.
   // -moz-binding is blacklisted.
   bool didSanitize = false;
   // Create a sheet to hold the parsed CSS
-  nsRefPtr<nsCSSStyleSheet> sheet = new nsCSSStyleSheet(CORS_NONE);
+  nsRefPtr<CSSStyleSheet> sheet = new CSSStyleSheet(CORS_NONE);
   sheet->SetURIs(aDocument->GetDocumentURI(), nullptr, aBaseURI);
   sheet->SetPrincipal(aDocument->NodePrincipal());
   // Create the CSS parser, and parse the CSS text.
   nsCSSParser parser(nullptr, sheet);
   rv = parser.ParseSheet(aOriginal, aDocument->GetDocumentURI(), aBaseURI,
                          aDocument->NodePrincipal(), 0, false);
   NS_ENSURE_SUCCESS(rv, true);
   // Mark the sheet as complete.
--- a/content/canvas/src/CanvasRenderingContext2D.cpp
+++ b/content/canvas/src/CanvasRenderingContext2D.cpp
@@ -2320,17 +2320,16 @@ CanvasRenderingContext2D::SetFont(const 
   gfxFontStyle style(fontStyle->mFont.style,
                      fontStyle->mFont.weight,
                      fontStyle->mFont.stretch,
                      NSAppUnitsToFloatPixels(fontStyle->mSize, float(aupcp)),
                      language,
                      fontStyle->mFont.sizeAdjust,
                      fontStyle->mFont.systemFont,
                      printerFont,
-                     fontStyle->mFont.variant == NS_STYLE_FONT_VARIANT_SMALL_CAPS,
                      fontStyle->mFont.synthesis & NS_FONT_SYNTHESIS_WEIGHT,
                      fontStyle->mFont.synthesis & NS_FONT_SYNTHESIS_STYLE,
                      fontStyle->mFont.languageOverride);
 
   fontStyle->mFont.AddFontFeaturesToStyle(&style);
 
   nsPresContext *c = presShell->GetPresContext();
   CurrentState().fontGroup =
--- a/content/canvas/src/ImageEncoder.cpp
+++ b/content/canvas/src/ImageEncoder.cpp
@@ -258,16 +258,20 @@ ImageEncoder::ExtractDataInternal(const 
                                   const nsAString& aOptions,
                                   uint8_t* aImageBuffer,
                                   int32_t aFormat,
                                   const nsIntSize aSize,
                                   nsICanvasRenderingContextInternal* aContext,
                                   nsIInputStream** aStream,
                                   imgIEncoder* aEncoder)
 {
+  if (aSize.IsEmpty()) {
+    return NS_ERROR_INVALID_ARG;
+  }
+
   nsCOMPtr<nsIInputStream> imgStream;
 
   // get image bytes
   nsresult rv;
   if (aImageBuffer) {
     rv = ImageEncoder::GetInputStream(
       aSize.width,
       aSize.height,
--- a/content/canvas/src/WebGLElementArrayCache.cpp
+++ b/content/canvas/src/WebGLElementArrayCache.cpp
@@ -2,16 +2,17 @@
 /* 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 "WebGLElementArrayCache.h"
 
 #include "mozilla/Assertions.h"
 #include "mozilla/MemoryReporting.h"
+#include "mozilla/MathAlgorithms.h"
 
 #include <cstdlib>
 #include <cstring>
 #include <limits>
 #include <algorithm>
 
 namespace mozilla {
 
@@ -288,26 +289,16 @@ public:
       }
 
       // walk up 1 level
       firstTreeIndex = ParentNode(firstTreeIndex);
       lastTreeIndex = ParentNode(lastTreeIndex);
     }
   }
 
-  template<typename U>
-  static U NextPowerOfTwo(U x) {
-    U result = 1;
-    while (result < x)
-      result <<= 1;
-    MOZ_ASSERT(result >= x);
-    MOZ_ASSERT((result & (result - 1)) == 0);
-    return result;
-  }
-
   // Updates the tree from the parent's buffer contents. Fallible, as it
   // may have to resize the tree storage.
   bool Update(size_t firstByte, size_t lastByte);
 
   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
   {
     return aMallocSizeOf(this) + mTreeData.SizeOfExcludingThis(aMallocSizeOf);
   }
@@ -360,17 +351,17 @@ bool WebGLElementArrayCacheTree<T>::Upda
     // it would just be equal to
     //
     //    ceil(numberOfElements / sElementsPerLeaf)
     //
     // The way we implement this (division+ceil) operation in integer arithmetic
     // is as follows:
     size_t numLeavesNonPOT = (numberOfElements + sElementsPerLeaf - 1) / sElementsPerLeaf;
     // It only remains to round that up to the next power of two:
-    requiredNumLeaves = NextPowerOfTwo(numLeavesNonPOT);
+    requiredNumLeaves = RoundUpPow2(numLeavesNonPOT);
   }
 
   // Step #0: if needed, resize our tree data storage.
   if (requiredNumLeaves != NumLeaves()) {
     // see class comment for why we the tree storage size is 2 * numLeaves
     if (!mTreeData.SetLength(2 * requiredNumLeaves)) {
       mTreeData.SetLength(0);
       return false;
--- a/content/html/content/src/HTMLLinkElement.cpp
+++ b/content/html/content/src/HTMLLinkElement.cpp
@@ -76,35 +76,34 @@ NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION
 NS_INTERFACE_TABLE_TAIL_INHERITING(nsGenericHTMLElement)
 
 
 NS_IMPL_ELEMENT_CLONE(HTMLLinkElement)
 
 bool
 HTMLLinkElement::Disabled()
 {
-  nsCSSStyleSheet* ss = GetSheet();
+  CSSStyleSheet* ss = GetSheet();
   return ss && ss->Disabled();
 }
 
 NS_IMETHODIMP
 HTMLLinkElement::GetMozDisabled(bool* aDisabled)
 {
   *aDisabled = Disabled();
   return NS_OK;
 }
 
 void
 HTMLLinkElement::SetDisabled(bool aDisabled)
 {
-  nsCSSStyleSheet* ss = GetSheet();
+  CSSStyleSheet* ss = GetSheet();
   if (ss) {
     ss->SetDisabled(aDisabled);
   }
-
 }
 
 NS_IMETHODIMP
 HTMLLinkElement::SetMozDisabled(bool aDisabled)
 {
   SetDisabled(aDisabled);
   return NS_OK;
 }
--- a/content/html/content/src/HTMLStyleElement.cpp
+++ b/content/html/content/src/HTMLStyleElement.cpp
@@ -64,31 +64,31 @@ HTMLStyleElement::GetMozDisabled(bool* a
 
   *aDisabled = Disabled();
   return NS_OK;
 }
 
 bool
 HTMLStyleElement::Disabled()
 {
-  nsCSSStyleSheet* ss = GetSheet();
+  CSSStyleSheet* ss = GetSheet();
   return ss && ss->Disabled();
 }
 
 NS_IMETHODIMP
 HTMLStyleElement::SetMozDisabled(bool aDisabled)
 {
   SetDisabled(aDisabled);
   return NS_OK;
 }
 
 void
 HTMLStyleElement::SetDisabled(bool aDisabled)
 {
-  nsCSSStyleSheet* ss = GetSheet();
+  CSSStyleSheet* ss = GetSheet();
   if (ss) {
     ss->SetDisabled(aDisabled);
   }
 }
 
 NS_IMPL_STRING_ATTR(HTMLStyleElement, Media, media)
 NS_IMPL_BOOL_ATTR(HTMLStyleElement, Scoped, scoped)
 NS_IMPL_STRING_ATTR(HTMLStyleElement, Type, type)
--- a/content/html/content/test/test_bug389797.html
+++ b/content/html/content/test/test_bug389797.html
@@ -185,16 +185,21 @@ HTML_TAG("object", "Object", [],
 HTML_TAG("ol", "OList");
 HTML_TAG("optgroup", "OptGroup");
 HTML_TAG("option", "Option");
 HTML_TAG("p", "Paragraph");
 HTML_TAG("param", "Param");
 HTML_TAG("plaintext", "");
 HTML_TAG("pre", "Pre");
 HTML_TAG("q", "Quote");
+HTML_TAG("rb", "");
+HTML_TAG("rp", "");
+HTML_TAG("rt", "");
+HTML_TAG("rtc", "");
+HTML_TAG("ruby", "");
 HTML_TAG("s", "");
 HTML_TAG("samp", "");
 HTML_TAG("script", "Script", [ "nsIScriptLoaderObserver" ], []);
 HTML_TAG("section", "")
 HTML_TAG("select", "Select", ["nsIDOMHTMLSelectElement"]);
 HTML_TAG("small", "");
 HTML_TAG("span", "Span");
 HTML_TAG("strike", "");
--- a/content/html/document/src/nsHTMLDocument.cpp
+++ b/content/html/document/src/nsHTMLDocument.cpp
@@ -2751,17 +2751,17 @@ nsHTMLDocument::EditingStateChanged()
     nsCOMArray<nsIStyleSheet> agentSheets;
     rv = presShell->GetAgentStyleSheets(agentSheets);
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsCOMPtr<nsIURI> uri;
     rv = NS_NewURI(getter_AddRefs(uri), NS_LITERAL_STRING("resource://gre/res/contenteditable.css"));
     NS_ENSURE_SUCCESS(rv, rv);
 
-    nsRefPtr<nsCSSStyleSheet> sheet;
+    nsRefPtr<CSSStyleSheet> sheet;
     rv = LoadChromeSheetSync(uri, true, getter_AddRefs(sheet));
     NS_ENSURE_TRUE(sheet, rv);
 
     bool result = agentSheets.AppendObject(sheet);
     NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY);
 
     // Should we update the editable state of all the nodes in the document? We
     // need to do this when the designMode value changes, as that overrides
--- a/content/media/AudioNodeEngine.h
+++ b/content/media/AudioNodeEngine.h
@@ -355,18 +355,20 @@ public:
   {
     return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
   }
 
   void SizeOfIncludingThis(MallocSizeOf aMallocSizeOf,
                            AudioNodeSizes& aUsage) const
   {
     aUsage.mEngine = SizeOfIncludingThis(aMallocSizeOf);
-    aUsage.mDomNode = mNode->SizeOfIncludingThis(aMallocSizeOf);
-    aUsage.mNodeType = mNode->NodeType();
+    if (HasNode()) {
+      aUsage.mDomNode = mNode->SizeOfIncludingThis(aMallocSizeOf);
+      aUsage.mNodeType = mNode->NodeType();
+    }
   }
 
 private:
   dom::AudioNode* mNode;
   Mutex mNodeMutex;
   const uint16_t mInputCount;
   const uint16_t mOutputCount;
 };
--- a/content/media/MediaDecoder.cpp
+++ b/content/media/MediaDecoder.cpp
@@ -424,16 +424,17 @@ MediaDecoder::MediaDecoder() :
   mIsDormant(false),
   mIsExitingDormant(false),
   mPlayState(PLAY_STATE_PAUSED),
   mNextState(PLAY_STATE_PAUSED),
   mCalledResourceLoaded(false),
   mIgnoreProgressData(false),
   mInfiniteStream(false),
   mOwner(nullptr),
+  mPlaybackStatistics(new MediaChannelStatistics()),
   mPinnedForSeek(false),
   mShuttingDown(false),
   mPausedForPlaybackRateNull(false),
   mMinimizePreroll(false)
 {
   MOZ_COUNT_CTOR(MediaDecoder);
   MOZ_ASSERT(NS_IsMainThread());
   MediaMemoryTracker::AddMediaDecoder(this);
@@ -935,17 +936,17 @@ double MediaDecoder::ComputePlaybackRate
   GetReentrantMonitor().AssertCurrentThreadIn();
   MOZ_ASSERT(NS_IsMainThread() || OnStateMachineThread() || OnDecodeThread());
 
   int64_t length = mResource ? mResource->GetLength() : -1;
   if (mDuration >= 0 && length >= 0) {
     *aReliable = true;
     return length * static_cast<double>(USECS_PER_S) / mDuration;
   }
-  return mPlaybackStatistics.GetRateAtLastStop(aReliable);
+  return mPlaybackStatistics->GetRateAtLastStop(aReliable);
 }
 
 void MediaDecoder::UpdatePlaybackRate()
 {
   MOZ_ASSERT(NS_IsMainThread() || OnStateMachineThread());
   GetReentrantMonitor().AssertCurrentThreadIn();
   if (!mResource)
     return;
@@ -1027,17 +1028,17 @@ void MediaDecoder::NotifyBytesConsumed(i
   }
 
   ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
   MOZ_ASSERT(mDecoderStateMachine);
   if (mIgnoreProgressData) {
     return;
   }
   if (aOffset >= mDecoderPosition) {
-    mPlaybackStatistics.AddBytes(aBytes);
+    mPlaybackStatistics->AddBytes(aBytes);
   }
   mDecoderPosition = aOffset + aBytes;
 }
 
 void MediaDecoder::UpdateReadyStateForData()
 {
   MOZ_ASSERT(NS_IsMainThread());
   if (!mOwner || mShuttingDown || !mDecoderStateMachine)
--- a/content/media/MediaDecoder.h
+++ b/content/media/MediaDecoder.h
@@ -713,24 +713,24 @@ public:
   // Something has changed that could affect the computed playback rate,
   // so recompute it. The monitor must be held.
   virtual void UpdatePlaybackRate();
 
   // Used to estimate rates of data passing through the decoder's channel.
   // Records activity stopping on the channel. The monitor must be held.
   virtual void NotifyPlaybackStarted() {
     GetReentrantMonitor().AssertCurrentThreadIn();
-    mPlaybackStatistics.Start();
+    mPlaybackStatistics->Start();
   }
 
   // Used to estimate rates of data passing through the decoder's channel.
   // Records activity stopping on the channel. The monitor must be held.
   virtual void NotifyPlaybackStopped() {
     GetReentrantMonitor().AssertCurrentThreadIn();
-    mPlaybackStatistics.Stop();
+    mPlaybackStatistics->Stop();
   }
 
   // The actual playback rate computation. The monitor must be held.
   virtual double ComputePlaybackRate(bool* aReliable);
 
   // Return true when the media is same-origin with the element. The monitor
   // must be held.
   bool IsSameOriginMedia();
@@ -1189,17 +1189,17 @@ protected:
   // when data is arriving slower than PROGRESS_MS. A value of null indicates
   // that a stall event has already fired and not to fire another one until
   // more data is received. Read/Write from the main thread only.
   TimeStamp mDataTime;
 
   // Data needed to estimate playback data rate. The timeline used for
   // this estimate is "decode time" (where the "current time" is the
   // time of the last decoded video frame).
-  MediaChannelStatistics mPlaybackStatistics;
+  nsRefPtr<MediaChannelStatistics> mPlaybackStatistics;
 
   // True when our media stream has been pinned. We pin the stream
   // while seeking.
   bool mPinnedForSeek;
 
   // True if the decoder is being shutdown. At this point all events that
   // are currently queued need to return immediately to prevent javascript
   // being run that operates on the element and decoder during shutdown.
--- a/content/media/MediaDecoderReader.h
+++ b/content/media/MediaDecoderReader.h
@@ -16,34 +16,27 @@ namespace mozilla {
 
 namespace dom {
 class TimeRanges;
 }
 
 class RequestSampleCallback;
 class MediaDecoderReader;
 
-template <>
-struct HasDangerousPublicDestructor<MediaDecoderReader>
-{
-  static const bool value = true;
-};
-
 // Encapsulates the decoding and reading of media data. Reading can either
 // synchronous and done on the calling "decode" thread, or asynchronous and
 // performed on a background thread, with the result being returned by
 // callback. Never hold the decoder monitor when calling into this class.
 // Unless otherwise specified, methods and fields of this class can only
 // be accessed on the decode task queue.
 class MediaDecoderReader {
 public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaDecoderReader)
 
   MediaDecoderReader(AbstractMediaDecoder* aDecoder);
-  virtual ~MediaDecoderReader();
 
   // Initializes the reader, returns NS_OK on success, or NS_ERROR_FAILURE
   // on failure.
   virtual nsresult Init(MediaDecoderReader* aCloneDonor) = 0;
 
   // True if this reader is waiting media resource allocation
   virtual bool IsWaitingMediaResources() { return false; }
   // True when this reader need to become dormant state
@@ -176,16 +169,17 @@ public:
   }
 
   AudioData* DecodeToFirstAudioData();
   VideoData* DecodeToFirstVideoData();
 
   MediaInfo GetMediaInfo() { return mInfo; }
 
 protected:
+  virtual ~MediaDecoderReader();
 
   // Overrides of this function should decodes an unspecified amount of
   // audio data, enqueuing the audio data in mAudioQueue. Returns true
   // when there's more audio to decode, false if the audio is finished,
   // end of file has been reached, or an un-recoverable read error has
   // occured. This function blocks until the decode is complete.
   virtual bool DecodeAudioData() {
     return false;
--- a/content/media/MediaResource.h
+++ b/content/media/MediaResource.h
@@ -33,22 +33,16 @@ static const int64_t RELIABLE_DATA_THRES
 class nsIHttpChannel;
 class nsIPrincipal;
 
 namespace mozilla {
 
 class MediaDecoder;
 class MediaChannelStatistics;
 
-template<>
-struct HasDangerousPublicDestructor<MediaChannelStatistics>
-{
-  static const bool value = true;
-};
-
 /**
  * This class is useful for estimating rates of data passing through
  * some channel. The idea is that activity on the channel "starts"
  * and "stops" over time. At certain times data passes through the
  * channel (usually while the channel is active; data passing through
  * an inactive channel is ignored). The GetRate() function computes
  * an estimate of the "current rate" of the channel, which is some
  * kind of average of the data passing through over the time the
@@ -114,16 +108,17 @@ public:
     double seconds = time.ToSeconds();
     *aReliable = (seconds >= 3.0) ||
                  (mAccumulatedBytes >= RELIABLE_DATA_THRESHOLD);
     if (seconds <= 0.0)
       return 0.0;
     return static_cast<double>(mAccumulatedBytes)/seconds;
   }
 private:
+  ~MediaChannelStatistics() {}
   int64_t      mAccumulatedBytes;
   TimeDuration mAccumulatedTime;
   TimeStamp    mLastStartTime;
   bool         mIsStarted;
 };
 
 // Forward declaration for use in MediaByteRange.
 class TimestampedMediaByteRange;
--- a/content/media/MediaStreamGraph.cpp
+++ b/content/media/MediaStreamGraph.cpp
@@ -2781,17 +2781,18 @@ MediaStreamGraphImpl::CollectReports(nsI
     rv = aHandleReport->Callback(EmptyCString(), _path,                     \
                                  KIND_HEAP, UNITS_BYTES, _amount,           \
                                  NS_LITERAL_CSTRING(_desc), aData);         \
     NS_ENSURE_SUCCESS(rv, rv);                                              \
   } while (0)
 
   for (size_t i = 0; i < mAudioStreamSizes.Length(); i++) {
     const AudioNodeSizes& usage = mAudioStreamSizes[i];
-    const char* const nodeType =  usage.mNodeType.get();
+    const char* const nodeType =  usage.mNodeType.IsEmpty() ?
+                                  "<unknown>" : usage.mNodeType.get();
 
     nsPrintfCString domNodePath("explicit/webaudio/audio-node/%s/dom-nodes",
                                 nodeType);
     REPORT(domNodePath, usage.mDomNode,
            "Memory used by AudioNode DOM objects (Web Audio).");
 
     nsPrintfCString enginePath("explicit/webaudio/audio-node/%s/engine-objects",
                                nodeType);
--- a/content/media/MediaStreamGraph.h
+++ b/content/media/MediaStreamGraph.h
@@ -227,16 +227,17 @@ public:
   virtual void NotifyMainThreadStateChanged() = 0;
 };
 
 /**
  * Helper struct used to keep track of memory usage by AudioNodes.
  */
 struct AudioNodeSizes
 {
+  AudioNodeSizes() : mDomNode(0), mStream(0), mEngine(0), mNodeType() {}
   size_t mDomNode;
   size_t mStream;
   size_t mEngine;
   nsCString mNodeType;
 };
 
 class MediaStreamGraphImpl;
 class SourceMediaStream;
--- a/content/media/fmp4/ffmpeg/FFmpegDataDecoder.cpp
+++ b/content/media/fmp4/ffmpeg/FFmpegDataDecoder.cpp
@@ -82,16 +82,19 @@ FFmpegDataDecoder::Init()
   mCodecContext.opaque = this;
 
   // FFmpeg takes this as a suggestion for what format to use for audio samples.
   mCodecContext.request_sample_fmt = AV_SAMPLE_FMT_FLT;
 
   // FFmpeg will call back to this to negotiate a video pixel format.
   mCodecContext.get_format = ChoosePixelFormat;
 
+  mCodecContext.extradata = mExtraData.begin();
+  mCodecContext.extradata_size = mExtraData.length();
+
   AVDictionary* opts = nullptr;
   if (avcodec_open2(&mCodecContext, codec, &opts) < 0) {
     NS_WARNING("Couldn't initialise ffmpeg decoder");
     return NS_ERROR_FAILURE;
   }
 
   if (mCodecContext.codec_type == AVMEDIA_TYPE_AUDIO &&
       mCodecContext.sample_fmt != AV_SAMPLE_FMT_FLT &&
--- a/content/media/fmp4/ffmpeg/FFmpegDataDecoder.h
+++ b/content/media/fmp4/ffmpeg/FFmpegDataDecoder.h
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef __FFmpegDataDecoder_h__
 #define __FFmpegDataDecoder_h__
 
 #include "FFmpegDecoderModule.h"
 #include "FFmpegRuntimeLinker.h"
 #include "FFmpegCompat.h"
+#include "mozilla/Vector.h"
 
 namespace mozilla
 {
 
 class FFmpegDataDecoder : public MediaDataDecoder
 {
 public:
   FFmpegDataDecoder(MediaTaskQueue* aTaskQueue, AVCodecID aCodecID);
@@ -26,16 +27,17 @@ public:
   virtual nsresult Input(mp4_demuxer::MP4Sample* aSample) = 0;
   virtual nsresult Flush() MOZ_OVERRIDE;
   virtual nsresult Drain() = 0;
   virtual nsresult Shutdown() MOZ_OVERRIDE;
 
 protected:
   MediaTaskQueue* mTaskQueue;
   AVCodecContext mCodecContext;
+  Vector<uint8_t> mExtraData;
 
 private:
   static bool sFFmpegInitDone;
 
   AVCodecID mCodecID;
 };
 
 } // namespace mozilla
--- a/content/media/fmp4/ffmpeg/FFmpegH264Decoder.cpp
+++ b/content/media/fmp4/ffmpeg/FFmpegH264Decoder.cpp
@@ -28,16 +28,17 @@ FFmpegH264Decoder::FFmpegH264Decoder(
   MediaTaskQueue* aTaskQueue, MediaDataDecoderCallback* aCallback,
   const mp4_demuxer::VideoDecoderConfig &aConfig,
   ImageContainer* aImageContainer)
   : FFmpegDataDecoder(aTaskQueue, AV_CODEC_ID_H264)
   , mCallback(aCallback)
   , mImageContainer(aImageContainer)
 {
   MOZ_COUNT_CTOR(FFmpegH264Decoder);
+  mExtraData.append(aConfig.extra_data.begin(), aConfig.extra_data.length());
 }
 
 nsresult
 FFmpegH264Decoder::Init()
 {
   nsresult rv = FFmpegDataDecoder::Init();
   NS_ENSURE_SUCCESS(rv, rv);
 
--- a/content/media/fmp4/wmf/WMFAudioOutputSource.cpp
+++ b/content/media/fmp4/wmf/WMFAudioOutputSource.cpp
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* 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 "WMFAudioOutputSource.h"
+#include "mp4_demuxer/DecoderData.h"
 #include "VideoUtils.h"
 #include "WMFUtils.h"
 #include "nsTArray.h"
 
 #include "prlog.h"
 
 #ifdef PR_LOGGING
 PRLogModuleInfo* GetDemuxerLog();
@@ -123,16 +124,24 @@ WMFAudioOutputSource::Init()
   NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr);
 
   mDecoder = decoder;
 
   return decoder.forget();
 }
 
 HRESULT
+WMFAudioOutputSource::Input(mp4_demuxer::MP4Sample* aSample)
+{
+  const uint8_t* data = reinterpret_cast<const uint8_t*>(aSample->data);
+  uint32_t length = aSample->size;
+  return mDecoder->Input(data, length, aSample->composition_timestamp);
+}
+
+HRESULT
 WMFAudioOutputSource::Output(int64_t aStreamOffset,
                         nsAutoPtr<MediaData>& aOutData)
 {
   aOutData = nullptr;
   RefPtr<IMFSample> sample;
   HRESULT hr = mDecoder->Output(&sample);
   if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) {
     return MF_E_TRANSFORM_NEED_MORE_INPUT;
--- a/content/media/fmp4/wmf/WMFAudioOutputSource.h
+++ b/content/media/fmp4/wmf/WMFAudioOutputSource.h
@@ -17,16 +17,18 @@ namespace mozilla {
 
 class WMFAudioOutputSource : public WMFOutputSource {
 public:
   WMFAudioOutputSource(const mp4_demuxer::AudioDecoderConfig& aConfig);
   ~WMFAudioOutputSource();
 
   virtual TemporaryRef<MFTDecoder> Init() MOZ_OVERRIDE;
 
+  virtual HRESULT Input(mp4_demuxer::MP4Sample* aSample) MOZ_OVERRIDE;
+
   // Note WMF's AAC decoder sometimes output negatively timestamped samples,
   // presumably they're the preroll samples, and we strip them. We may return
   // a null aOutput in this case.
   virtual HRESULT Output(int64_t aStreamOffset,
                          nsAutoPtr<MediaData>& aOutput) MOZ_OVERRIDE;
 private:
 
   // IMFTransform wrapper that performs the decoding.
--- a/content/media/fmp4/wmf/WMFDecoderModule.cpp
+++ b/content/media/fmp4/wmf/WMFDecoderModule.cpp
@@ -65,17 +65,18 @@ WMFDecoderModule::Shutdown()
 
 MediaDataDecoder*
 WMFDecoderModule::CreateH264Decoder(const mp4_demuxer::VideoDecoderConfig& aConfig,
                                     mozilla::layers::LayersBackend aLayersBackend,
                                     mozilla::layers::ImageContainer* aImageContainer,
                                     MediaTaskQueue* aVideoTaskQueue,
                                     MediaDataDecoderCallback* aCallback)
 {
-  return new WMFMediaDataDecoder(new WMFVideoOutputSource(aLayersBackend,
+  return new WMFMediaDataDecoder(new WMFVideoOutputSource(aConfig,
+                                                          aLayersBackend,
                                                           aImageContainer,
                                                           sDXVAEnabled),
                                  aVideoTaskQueue,
                                  aCallback);
 }
 
 MediaDataDecoder*
 WMFDecoderModule::CreateAACDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig,
--- a/content/media/fmp4/wmf/WMFMediaDataDecoder.cpp
+++ b/content/media/fmp4/wmf/WMFMediaDataDecoder.cpp
@@ -62,21 +62,19 @@ WMFMediaDataDecoder::Input(mp4_demuxer::
       &WMFMediaDataDecoder::ProcessDecode,
       nsAutoPtr<mp4_demuxer::MP4Sample>(aSample)));
   return NS_OK;
 }
 
 void
 WMFMediaDataDecoder::ProcessDecode(mp4_demuxer::MP4Sample* aSample)
 {
-  const uint8_t* data = reinterpret_cast<const uint8_t*>(aSample->data);
-  uint32_t length = aSample->size;
-  HRESULT hr = mDecoder->Input(data, length, aSample->composition_timestamp);
+  HRESULT hr = mSource->Input(aSample);
   if (FAILED(hr)) {
-    NS_WARNING("WMFAudioDecoder failed to input data");
+    NS_WARNING("WMFOutputSource rejected sample");
     mCallback->Error();
     return;
   }
 
   mLastStreamOffset = aSample->byte_offset;
 
   ProcessOutput();
 }
--- a/content/media/fmp4/wmf/WMFMediaDataDecoder.h
+++ b/content/media/fmp4/wmf/WMFMediaDataDecoder.h
@@ -8,29 +8,36 @@
 #define WMFMediaDataDecoder_h_
 
 
 #include "WMF.h"
 #include "MP4Reader.h"
 #include "MFTDecoder.h"
 #include "mozilla/RefPtr.h"
 
+class mp4_demuxer::MP4Sample;
+
 namespace mozilla {
 
 // Encapsulates the initialization of the MFTDecoder appropriate for decoding
 // a given stream, and the process of converting the IMFSample produced
 // by the MFT into a MediaData object.
 class WMFOutputSource {
 public:
   virtual ~WMFOutputSource() {}
 
   // Creates an initializs the MFTDecoder.
   // Returns nullptr on failure.
   virtual TemporaryRef<MFTDecoder> Init() = 0;
 
+  // Submit a compressed sample for decoding.
+  // This should forward to the MFTDecoder after performing
+  // any required sample formatting.
+  virtual HRESULT Input(mp4_demuxer::MP4Sample* aSample) = 0;
+
   // Produces decoded output, if possible. Blocks until output can be produced,
   // or until no more is able to be produced.
   // Returns S_OK on success, or MF_E_TRANSFORM_NEED_MORE_INPUT if there's not
   // enough data to produce more output. If this returns a failure code other
   // than MF_E_TRANSFORM_NEED_MORE_INPUT, an error will be reported to the
   // MP4Reader.
   virtual HRESULT Output(int64_t aStreamOffset,
                          nsAutoPtr<MediaData>& aOutput) = 0;
--- a/content/media/fmp4/wmf/WMFVideoOutputSource.cpp
+++ b/content/media/fmp4/wmf/WMFVideoOutputSource.cpp
@@ -8,16 +8,18 @@
 #include "MediaDecoderReader.h"
 #include "WMFUtils.h"
 #include "ImageContainer.h"
 #include "VideoUtils.h"
 #include "DXVA2Manager.h"
 #include "nsThreadUtils.h"
 #include "Layers.h"
 #include "mozilla/layers/LayersTypes.h"
+#include "mp4_demuxer/AnnexB.h"
+#include "mp4_demuxer/DecoderData.h"
 #include "prlog.h"
 #include "gfx2DGlue.h"
 
 #ifdef PR_LOGGING
 PRLogModuleInfo* GetDemuxerLog();
 #define LOG(...) PR_LOG(GetDemuxerLog(), PR_LOG_DEBUG, (__VA_ARGS__))
 #else
 #define LOG(...)
@@ -25,22 +27,25 @@ PRLogModuleInfo* GetDemuxerLog();
 
 using mozilla::gfx::ToIntRect;
 using mozilla::layers::Image;
 using mozilla::layers::LayerManager;
 using mozilla::layers::LayersBackend;
 
 namespace mozilla {
 
-WMFVideoOutputSource::WMFVideoOutputSource(mozilla::layers::LayersBackend aLayersBackend,
-                                 mozilla::layers::ImageContainer* aImageContainer,
-                                 bool aDXVAEnabled)
+WMFVideoOutputSource::WMFVideoOutputSource(
+                            const mp4_demuxer::VideoDecoderConfig& aConfig,
+                            mozilla::layers::LayersBackend aLayersBackend,
+                            mozilla::layers::ImageContainer* aImageContainer,
+                            bool aDXVAEnabled)
   : mVideoStride(0)
   , mVideoWidth(0)
   , mVideoHeight(0)
+  , mConfig(aConfig)
   , mImageContainer(aImageContainer)
   , mDXVAEnabled(aDXVAEnabled)
   , mLayersBackend(aLayersBackend)
   , mUseHwAccel(false)
 {
   NS_ASSERTION(!NS_IsMainThread(), "Should not be on main thread.");
   MOZ_ASSERT(mImageContainer);
   MOZ_COUNT_CTOR(WMFVideoOutputSource);
@@ -134,16 +139,27 @@ WMFVideoOutputSource::Init()
 
   mDecoder = decoder;
   LOG("Video Decoder initialized, Using DXVA: %s", (mUseHwAccel ? "Yes" : "No"));
 
   return decoder.forget();
 }
 
 HRESULT
+WMFVideoOutputSource::Input(mp4_demuxer::MP4Sample* aSample)
+{
+  // We must prepare samples in AVC Annex B.
+  mp4_demuxer::AnnexB::ConvertSample(aSample, mConfig.annex_b);
+  // Forward sample data to the decoder.
+  const uint8_t* data = reinterpret_cast<const uint8_t*>(aSample->data);
+  uint32_t length = aSample->size;
+  return mDecoder->Input(data, length, aSample->composition_timestamp);
+}
+
+HRESULT
 WMFVideoOutputSource::ConfigureVideoFrameGeometry()
 {
   RefPtr<IMFMediaType> mediaType;
   HRESULT hr = mDecoder->GetOutputMediaType(mediaType);
   NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
 
   // Verify that the video subtype is what we expect it to be.
   // When using hardware acceleration/DXVA2 the video format should
--- a/content/media/fmp4/wmf/WMFVideoOutputSource.h
+++ b/content/media/fmp4/wmf/WMFVideoOutputSource.h
@@ -15,23 +15,26 @@
 #include "mozilla/RefPtr.h"
 
 namespace mozilla {
 
 class DXVA2Manager;
 
 class WMFVideoOutputSource : public WMFOutputSource {
 public:
-  WMFVideoOutputSource(mozilla::layers::LayersBackend aLayersBackend,
+  WMFVideoOutputSource(const mp4_demuxer::VideoDecoderConfig& aConfig,
+                       mozilla::layers::LayersBackend aLayersBackend,
                        mozilla::layers::ImageContainer* aImageContainer,
                        bool aDXVAEnabled);
   ~WMFVideoOutputSource();
 
   virtual TemporaryRef<MFTDecoder> Init() MOZ_OVERRIDE;
 
+  virtual HRESULT Input(mp4_demuxer::MP4Sample* aSample) MOZ_OVERRIDE;
+
   virtual HRESULT Output(int64_t aStreamOffset,
                          nsAutoPtr<MediaData>& aOutput) MOZ_OVERRIDE;
 
 private:
 
   bool InitializeDXVA();
 
   HRESULT ConfigureVideoFrameGeometry();
@@ -46,16 +49,18 @@ private:
 
   // Video frame geometry.
   VideoInfo mVideoInfo;
   uint32_t mVideoStride;
   uint32_t mVideoWidth;
   uint32_t mVideoHeight;
   nsIntRect mPictureRegion;
 
+  const mp4_demuxer::VideoDecoderConfig& mConfig;
+
   RefPtr<MFTDecoder> mDecoder;
   RefPtr<layers::ImageContainer> mImageContainer;
   nsAutoPtr<DXVA2Manager> mDXVA2Manager;
   RefPtr<MediaTaskQueue> mTaskQueue;
   MediaDataDecoderCallback* mCallback;
 
   const bool mDXVAEnabled;
   const layers::LayersBackend mLayersBackend;
--- a/content/media/mediasource/MediaSource.h
+++ b/content/media/mediasource/MediaSource.h
@@ -9,17 +9,16 @@
 
 #include "MediaSourceDecoder.h"
 #include "js/RootingAPI.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/DOMEventTargetHelper.h"
 #include "mozilla/dom/MediaSourceBinding.h"
 #include "mozilla/Monitor.h"
-#include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 #include "nsCycleCollectionNoteChild.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsID.h"
 #include "nsISupports.h"
 #include "nscore.h"
 
 struct JSContext;
--- a/content/media/mediasource/MediaSourceDecoder.cpp
+++ b/content/media/mediasource/MediaSourceDecoder.cpp
@@ -9,16 +9,17 @@
 #include "AbstractMediaDecoder.h"
 #include "MediaDecoderReader.h"
 #include "MediaDecoderStateMachine.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/FloatingPoint.h"
 #include "mozilla/dom/HTMLMediaElement.h"
 #include "mozilla/dom/TimeRanges.h"
 #include "mozilla/mozalloc.h"
+#include "nsAutoPtr.h"
 #include "nsISupports.h"
 #include "nsIThread.h"
 #include "prlog.h"
 #include "MediaSource.h"
 #include "SubBufferDecoder.h"
 #include "SourceBufferResource.h"
 #include "SourceBufferList.h"
 #include "VideoUtils.h"
@@ -409,31 +410,31 @@ MediaSourceReader::InitializePendingDeco
 already_AddRefed<SubBufferDecoder>
 MediaSourceReader::CreateSubDecoder(const nsACString& aType,
                                     MediaSourceDecoder* aParentDecoder,
                                     MediaTaskQueue* aTaskQueue)
 {
   // XXX: Why/when is mDecoder null here, since it should be equal to aParentDecoder?!
   nsRefPtr<SubBufferDecoder> decoder =
     new SubBufferDecoder(new SourceBufferResource(nullptr, aType), aParentDecoder);
-  nsAutoPtr<MediaDecoderReader> reader(DecoderTraits::CreateReader(aType, decoder));
+  nsRefPtr<MediaDecoderReader> reader(DecoderTraits::CreateReader(aType, decoder));
   if (!reader) {
     return nullptr;
   }
   // Set a callback on the subreader that forwards calls to this reader.
   // This reader will then forward them onto the state machine via this
   // reader's callback.
   RefPtr<MediaDataDecodedListener<MediaSourceReader>> callback =
     new MediaDataDecodedListener<MediaSourceReader>(this, aTaskQueue);
   reader->SetCallback(callback);
   reader->SetTaskQueue(aTaskQueue);
   reader->Init(nullptr);
   ReentrantMonitorAutoEnter mon(aParentDecoder->GetReentrantMonitor());
   MSE_DEBUG("Registered subdecoder %p subreader %p", decoder.get(), reader.get());
-  decoder->SetReader(reader.forget());
+  decoder->SetReader(reader);
   mPendingDecoders.AppendElement(decoder);
   if (NS_FAILED(static_cast<MediaSourceDecoder*>(mDecoder)->EnqueueDecoderInitialization())) {
     MSE_DEBUG("%p: Failed to enqueue decoder initialization task", this);
     return nullptr;
   }
   mDecoder->NotifyWaitingForResourcesStatusChanged();
   return decoder.forget();
 }
--- a/content/media/mediasource/SourceBufferList.h
+++ b/content/media/mediasource/SourceBufferList.h
@@ -7,17 +7,16 @@
 #ifndef mozilla_dom_SourceBufferList_h_
 #define mozilla_dom_SourceBufferList_h_
 
 #include "SourceBuffer.h"
 #include "js/RootingAPI.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/DOMEventTargetHelper.h"
-#include "nsAutoPtr.h"
 #include "nsCycleCollectionNoteChild.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsISupports.h"
 #include "nsTArray.h"
 
 struct JSContext;
 class JSObject;
 
--- a/content/media/mediasource/SubBufferDecoder.h
+++ b/content/media/mediasource/SubBufferDecoder.h
@@ -81,16 +81,16 @@ public:
 
   void SetMediaStartTime(int64_t aMediaStartTime)
   {
     mMediaStartTime = aMediaStartTime;
   }
 
 private:
   MediaSourceDecoder* mParentDecoder;
-  nsAutoPtr<MediaDecoderReader> mReader;
+  nsRefPtr<MediaDecoderReader> mReader;
   int64_t mMediaDuration;
   int64_t mMediaStartTime;
 };
 
 } // namespace mozilla
 
 #endif /* MOZILLA_SUBBUFFERDECODER_H_ */
--- a/content/media/plugins/MediaResourceServer.cpp
+++ b/content/media/plugins/MediaResourceServer.cpp
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* 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 "mozilla/Assertions.h"
 #include "mozilla/Base64.h"
+#include "mozilla/IntegerPrintfMacros.h"
 #include "nsThreadUtils.h"
 #include "nsIServiceManager.h"
 #include "nsISocketTransport.h"
 #include "nsIOutputStream.h"
 #include "nsIInputStream.h"
 #include "nsIRandomGenerator.h"
 #include "nsReadLine.h"
 #include "nsNetCID.h"
@@ -223,17 +224,17 @@ ServeResourceEvent::Run() {
     // the end of the resource and the client is informed of this via
     // the content-range header.
     NS_NAMED_LITERAL_CSTRING(byteRange, "Range: bytes=");
     const char* s = strstr(line.get(), byteRange.get());
     if (s) {
       start = strtoll(s+byteRange.Length(), nullptr, 10);
 
       // Clamp 'start' to be between 0 and the resource length.
-      start = std::max(0ll, std::min(resource->GetLength(), start));
+      start = std::max(int64_t(0), std::min(resource->GetLength(), start));
     }
   }
 
   // HTTP response to use if this is a non byte range request
   const char* response_normal = "HTTP/1.1 200 OK\r\n";
 
   // HTTP response to use if this is a byte range request
   const char* response_range = "HTTP/1.1 206 Partial Content\r\n";
@@ -263,28 +264,29 @@ ServeResourceEvent::Run() {
   nsAutoArrayPtr<char> b(new char[buffer_size]);
 
   // If we know the length of the resource, send a Content-Length header.
   int64_t contentlength = resource->GetLength() - start;
   if (contentlength > 0) {
     static_assert (buffer_size > 1024,
                    "buffer_size must be large enough "
                    "to hold response headers");
-    snprintf(b, buffer_size, "Content-Length: %lld\r\n", contentlength);
+    snprintf(b, buffer_size, "Content-Length: %" PRId64 "\r\n", contentlength);
     rv = WriteAll(b, strlen(b));
     if (NS_FAILED(rv)) { Shutdown(); return NS_OK; }
   }
 
   // If the request was a byte range request, respond with a Content-Range
   // header which details the extent of the data returned.
   if (start > 0) {
     static_assert (buffer_size > 1024,
                    "buffer_size must be large enough "
                    "to hold response headers");
-    snprintf(b, buffer_size, "Content-Range: bytes %lld-%lld/%lld\r\n",
+    snprintf(b, buffer_size, "Content-Range: "
+             "bytes %" PRId64 "-%" PRId64 "/%" PRId64 "\r\n",
              start, resource->GetLength() - 1, resource->GetLength());
     rv = WriteAll(b, strlen(b));
     if (NS_FAILED(rv)) { Shutdown(); return NS_OK; }
   }
 
   rv = WriteAll(response_end, strlen(response_end));
   if (NS_FAILED(rv)) { Shutdown(); return NS_OK; }
 
--- a/content/media/webaudio/AudioContext.cpp
+++ b/content/media/webaudio/AudioContext.cpp
@@ -432,16 +432,17 @@ AudioContext::Listener()
 }
 
 void
 AudioContext::DecodeAudioData(const ArrayBuffer& aBuffer,
                               DecodeSuccessCallback& aSuccessCallback,
                               const Optional<OwningNonNull<DecodeErrorCallback> >& aFailureCallback)
 {
   AutoJSAPI jsapi;
+  jsapi.Init();
   JSContext* cx = jsapi.cx();
   JSAutoCompartment ac(cx, aBuffer.Obj());
 
   aBuffer.ComputeLengthAndData();
 
   // Neuter the array buffer
   size_t length = aBuffer.Length();
   JS::RootedObject obj(cx, aBuffer.Obj());
--- a/content/media/webaudio/AudioDestinationNode.cpp
+++ b/content/media/webaudio/AudioDestinationNode.cpp
@@ -121,25 +121,21 @@ public:
   void FireOfflineCompletionEvent(AudioDestinationNode* aNode)
   {
     AudioContext* context = aNode->Context();
     context->Shutdown();
     // Shutdown drops self reference, but the context is still referenced by aNode,
     // which is strongly referenced by the runnable that called
     // AudioDestinationNode::FireOfflineCompletionEvent.
 
-    // We need the global for the context so that we can enter its compartment.
-    JSObject* global = context->GetGlobalJSObject();
-    if (NS_WARN_IF(!global)) {
+    AutoJSAPI jsapi;
+    if (NS_WARN_IF(!jsapi.InitUsingWin(aNode->GetOwner()))) {
       return;
     }
-
-    AutoJSAPI jsapi;
     JSContext* cx = jsapi.cx();
-    JSAutoCompartment ac(cx, global);
 
     // Create the input buffer
     ErrorResult rv;
     nsRefPtr<AudioBuffer> renderedBuffer =
       AudioBuffer::Create(context, mInputChannels.Length(),
                           mLength, mSampleRate, cx, rv);
     if (rv.Failed()) {
       return;
--- a/content/media/webaudio/AudioProcessingEvent.cpp
+++ b/content/media/webaudio/AudioProcessingEvent.cpp
@@ -36,26 +36,22 @@ AudioProcessingEvent::WrapObject(JSConte
 {
   return AudioProcessingEventBinding::Wrap(aCx, this);
 }
 
 already_AddRefed<AudioBuffer>
 AudioProcessingEvent::LazilyCreateBuffer(uint32_t aNumberOfChannels,
                                          ErrorResult& aRv)
 {
-  // We need the global for the context so that we can enter its compartment.
-  JSObject* global = mNode->Context()->GetGlobalJSObject();
-  if (NS_WARN_IF(!global)) {
+  AutoJSAPI jsapi;
+  if (NS_WARN_IF(!jsapi.InitUsingWin(mNode->GetOwner()))) {
     aRv.Throw(NS_ERROR_UNEXPECTED);
     return nullptr;
   }
-
-  AutoJSAPI jsapi;
   JSContext* cx = jsapi.cx();
-  JSAutoCompartment ac(cx, global);
 
   nsRefPtr<AudioBuffer> buffer =
     AudioBuffer::Create(mNode->Context(), aNumberOfChannels,
                         mNode->BufferSize(),
                         mNode->Context()->SampleRate(), cx, aRv);
   MOZ_ASSERT(buffer || aRv.ErrorCode() == NS_ERROR_OUT_OF_MEMORY);
   return buffer.forget();
 }
--- a/content/media/webaudio/MediaBufferDecoder.cpp
+++ b/content/media/webaudio/MediaBufferDecoder.cpp
@@ -11,16 +11,17 @@
 #include <speex/speex_resampler.h>
 #include "nsXPCOMCIDInternal.h"
 #include "nsComponentManagerUtils.h"
 #include "MediaDecoderReader.h"
 #include "BufferMediaResource.h"
 #include "DecoderTraits.h"
 #include "AudioContext.h"
 #include "AudioBuffer.h"
+#include "nsAutoPtr.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "nsIScriptError.h"
 #include "nsMimeTypes.h"
 #include "WebAudioUtils.h"
 
 namespace mozilla {
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(WebAudioDecodeJob)
@@ -146,17 +147,17 @@ private:
   nsCString mContentType;
   uint8_t* mBuffer;
   uint32_t mLength;
   WebAudioDecodeJob& mDecodeJob;
   PhaseEnum mPhase;
   nsCOMPtr<nsIThreadPool> mThreadPool;
   nsCOMPtr<nsIPrincipal> mPrincipal;
   nsRefPtr<BufferDecoder> mBufferDecoder;
-  nsAutoPtr<MediaDecoderReader> mDecoderReader;
+  nsRefPtr<MediaDecoderReader> mDecoderReader;
 };
 
 NS_IMETHODIMP
 MediaDecodeTask::Run()
 {
   MOZ_ASSERT(mBufferDecoder);
   MOZ_ASSERT(mDecoderReader);
   switch (mPhase) {
@@ -407,25 +408,21 @@ MediaDecodeTask::CallbackTheResult()
 }
 
 bool
 WebAudioDecodeJob::AllocateBuffer()
 {
   MOZ_ASSERT(!mOutput);
   MOZ_ASSERT(NS_IsMainThread());
 
-  // We need the global for the context so that we can enter its compartment.
-  JSObject* global = mContext->GetGlobalJSObject();
-  if (NS_WARN_IF(!global)) {
+  AutoJSAPI jsapi;
+  if (NS_WARN_IF(!jsapi.InitUsingWin(mContext->GetOwner()))) {
     return false;
   }
-
-  AutoJSAPI jsapi;
   JSContext* cx = jsapi.cx();
-  JSAutoCompartment ac(cx, global);
 
   // Now create the AudioBuffer
   ErrorResult rv;
   mOutput = AudioBuffer::Create(mContext, mChannelBuffers.Length(),
                                 mWriteIndex, mContext->SampleRate(), cx, rv);
   if (rv.Failed()) {
     return false;
   }
@@ -445,25 +442,27 @@ MediaBufferDecoder::AsyncDecodeMedia(con
   // Do not attempt to decode the media if we were not successful at sniffing
   // the content type.
   if (!*aContentType ||
       strcmp(aContentType, APPLICATION_OCTET_STREAM) == 0) {
     nsCOMPtr<nsIRunnable> event =
       new ReportResultTask(aDecodeJob,
                            &WebAudioDecodeJob::OnFailure,
                            WebAudioDecodeJob::UnknownContent);
+    JS_free(nullptr, aBuffer);
     NS_DispatchToMainThread(event);
     return;
   }
 
   if (!EnsureThreadPoolInitialized()) {
     nsCOMPtr<nsIRunnable> event =
       new ReportResultTask(aDecodeJob,
                            &WebAudioDecodeJob::OnFailure,
                            WebAudioDecodeJob::UnknownError);
+    JS_free(nullptr, aBuffer);
     NS_DispatchToMainThread(event);
     return;
   }
 
   MOZ_ASSERT(mThreadPool);
 
   nsRefPtr<MediaDecodeTask> task =
     new MediaDecodeTask(aContentType, aBuffer, aLength, aDecodeJob, mThreadPool);
--- a/content/media/webaudio/MediaBufferDecoder.h
+++ b/content/media/webaudio/MediaBufferDecoder.h
@@ -4,17 +4,16 @@
  * 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 MediaBufferDecoder_h_
 #define MediaBufferDecoder_h_
 
 #include "nsWrapperCache.h"
 #include "nsCOMPtr.h"
-#include "nsAutoPtr.h"
 #include "nsIThreadPool.h"
 #include "nsString.h"
 #include "nsTArray.h"
 #include "mozilla/dom/TypedArray.h"
 #include "mozilla/MemoryReporting.h"
 
 namespace mozilla {
 
--- a/content/media/webaudio/ScriptProcessorNode.cpp
+++ b/content/media/webaudio/ScriptProcessorNode.cpp
@@ -397,25 +397,21 @@ private:
           // this function.
           MutexAutoLock lock(mStream->Engine()->NodeMutex());
           node = static_cast<ScriptProcessorNode*>(mStream->Engine()->Node());
         }
         if (!node || !node->Context()) {
           return NS_OK;
         }
 
-        // Get the global for the context so that we can enter its compartment.
-        JSObject* global = node->Context()->GetGlobalJSObject();
-        if (NS_WARN_IF(!global)) {
+        AutoJSAPI jsapi;
+        if (NS_WARN_IF(!jsapi.InitUsingWin(node->GetOwner()))) {
           return NS_OK;
         }
-
-        AutoJSAPI jsapi;
         JSContext* cx = jsapi.cx();
-        JSAutoCompartment ac(cx, global);
 
         // Create the input buffer
         nsRefPtr<AudioBuffer> inputBuffer;
         if (!mNullInput) {
           ErrorResult rv;
           inputBuffer =
             AudioBuffer::Create(node->Context(), mInputChannels.Length(),
                                 node->BufferSize(),
--- a/content/media/webrtc/LoadManager.cpp
+++ b/content/media/webrtc/LoadManager.cpp
@@ -35,25 +35,25 @@ namespace mozilla {
 
 NS_IMPL_ISUPPORTS(LoadManagerSingleton, nsIObserver)
 
 
 LoadManagerSingleton::LoadManagerSingleton(int aLoadMeasurementInterval,
                                            int aAveragingMeasurements,
                                            float aHighLoadThreshold,
                                            float aLowLoadThreshold)
-  : mLoadSum(0.0f),
+  : mLock("LoadManager"),
+    mCurrentState(webrtc::kLoadNormal),
+    mOveruseActive(false),
+    mLoadSum(0.0f),
     mLoadSumMeasurements(0),
-    mOveruseActive(false),
     mLoadMeasurementInterval(aLoadMeasurementInterval),
     mAveragingMeasurements(aAveragingMeasurements),
     mHighLoadThreshold(aHighLoadThreshold),
-    mLowLoadThreshold(aLowLoadThreshold),
-    mCurrentState(webrtc::kLoadNormal),
-    mLock("LoadManager")
+    mLowLoadThreshold(aLowLoadThreshold)
 {
 #if defined(PR_LOGGING)
   if (!gLoadManagerLog)
     gLoadManagerLog = PR_NewLogModule("LoadManager");
 #endif
   LOG(("LoadManager - Initializing (%dms x %d, %f, %f)",
        mLoadMeasurementInterval, mAveragingMeasurements,
        mHighLoadThreshold, mLowLoadThreshold));
--- a/content/media/webrtc/LoadManager.h
+++ b/content/media/webrtc/LoadManager.h
@@ -49,18 +49,18 @@ private:
                          float aHighLoadThreshold,
                          float aLowLoadThreshold);
     ~LoadManagerSingleton();
 
     void LoadHasChanged();
 
     nsRefPtr<LoadMonitor> mLoadMonitor;
 
-    // This protexts access to the mObservers list, the current state, pretty much all
-    // the other members (below)
+    // This protects access to the mObservers list, the current state, and
+    // pretty much all the other members (below).
     Mutex mLock;
     nsTArray<webrtc::CPULoadStateObserver*> mObservers;
     webrtc::CPULoadState mCurrentState;
     // Set when overuse was signaled to us, and hasn't been un-signaled yet.
     bool  mOveruseActive;
     float mLoadSum;
     int   mLoadSumMeasurements;
     // Load measurement settings
--- a/content/media/webrtc/LoadManagerFactory.cpp
+++ b/content/media/webrtc/LoadManagerFactory.cpp
@@ -24,19 +24,19 @@ LoadManagerSingleton::Get() {
   if (!sSingleton) {
     MOZ_ASSERT(NS_IsMainThread());
 
     int loadMeasurementInterval =
       mozilla::Preferences::GetInt("media.navigator.load_adapt.measure_interval", 1000);
     int averagingSeconds =
       mozilla::Preferences::GetInt("media.navigator.load_adapt.avg_seconds", 3);
     float highLoadThreshold =
-      mozilla::Preferences::GetFloat("media.navigator.load_adapt.high_load", 0.90);
+      mozilla::Preferences::GetFloat("media.navigator.load_adapt.high_load", 0.90f);
     float lowLoadThreshold =
-      mozilla::Preferences::GetFloat("media.navigator.load_adapt.low_load", 0.40);
+      mozilla::Preferences::GetFloat("media.navigator.load_adapt.low_load", 0.40f);
 
     sSingleton = new LoadManagerSingleton(loadMeasurementInterval,
                                           averagingSeconds,
                                           highLoadThreshold,
                                           lowLoadThreshold);
 
     nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
     if (obs) {
--- a/content/media/webrtc/MediaEngineWebRTC.h
+++ b/content/media/webrtc/MediaEngineWebRTC.h
@@ -262,23 +262,23 @@ private:
 };
 
 class MediaEngineWebRTCAudioSource : public MediaEngineAudioSource,
                                      public webrtc::VoEMediaProcess
 {
 public:
   MediaEngineWebRTCAudioSource(webrtc::VoiceEngine* aVoiceEnginePtr, int aIndex,
     const char* name, const char* uuid)
-    : mVoiceEngine(aVoiceEnginePtr)
+    : mSamples(0)
+    , mVoiceEngine(aVoiceEnginePtr)
     , mMonitor("WebRTCMic.Monitor")
     , mCapIndex(aIndex)
     , mChannel(-1)
     , mInitDone(false)
     , mStarted(false)
-    , mSamples(0)
     , mEchoOn(false), mAgcOn(false), mNoiseOn(false)
     , mEchoCancel(webrtc::kEcDefault)
     , mAGC(webrtc::kAgcDefault)
     , mNoiseSuppress(webrtc::kNsDefault)
     , mPlayoutDelay(0)
     , mNullTransport(nullptr) {
     MOZ_ASSERT(aVoiceEnginePtr);
     mState = kReleased;
@@ -314,16 +314,23 @@ public:
 
   // VoEMediaProcess.
   void Process(int channel, webrtc::ProcessingTypes type,
                int16_t audio10ms[], int length,
                int samplingFreq, bool isStereo);
 
   NS_DECL_THREADSAFE_ISUPPORTS
 
+protected:
+  // mSamples is an int to avoid conversions when comparing/etc to
+  // samplingFreq & length. Making mSamples protected instead of private is a
+  // silly way to avoid -Wunused-private-field warnings when PR_LOGGING is not
+  // #defined. mSamples is not actually expected to be used by a derived class.
+  int mSamples;
+
 private:
   static const unsigned int KMaxDeviceNameLength = 128;
   static const unsigned int KMaxUniqueIdLength = 256;
 
   void Init();
   void Shutdown();
 
   webrtc::VoiceEngine* mVoiceEngine;
@@ -339,17 +346,16 @@ private:
   Monitor mMonitor;
   nsTArray<SourceMediaStream *> mSources; // When this goes empty, we shut down HW
 
   int mCapIndex;
   int mChannel;
   TrackID mTrackID;
   bool mInitDone;
   bool mStarted;
-  int mSamples; // int to avoid conversions when comparing/etc to samplingFreq & length
 
   nsString mDeviceName;
   nsString mDeviceUUID;
 
   bool mEchoOn, mAgcOn, mNoiseOn;
   webrtc::EcModes  mEchoCancel;
   webrtc::AgcModes mAGC;
   webrtc::NsModes  mNoiseSuppress;
--- a/content/media/webrtc/PeerIdentity.cpp
+++ b/content/media/webrtc/PeerIdentity.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * vim: sw=2 ts=2 sts=2 expandtab
  * 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 "PeerIdentity.h"
 
+#include "mozilla/DebugOnly.h"
 #include "nsCOMPtr.h"
 #include "nsIIDNService.h"
 #include "nsNetCID.h"
 #include "nsServiceManagerUtils.h"
 
 namespace mozilla {
 
 bool
@@ -71,14 +72,14 @@ PeerIdentity::GetHost(const nsAString& a
   }
 }
 
 /* static */ void
 PeerIdentity::GetNormalizedHost(const nsCOMPtr<nsIIDNService>& aIdnService,
                                 const nsAString& aHost,
                                 nsACString& aNormalizedHost)
 {
-  nsCString chost = NS_ConvertUTF16toUTF8(aHost);
-  nsresult rv = aIdnService->ConvertUTF8toACE(chost, aNormalizedHost);
-  NS_WARN_IF(NS_FAILED(rv));
+  const nsCString chost = NS_ConvertUTF16toUTF8(aHost);
+  DebugOnly<nsresult> rv = aIdnService->ConvertUTF8toACE(chost, aNormalizedHost);
+  NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Failed to convert UTF-8 host to ASCII");
 }
 
 } /* namespace mozilla */
--- a/content/media/webrtc/moz.build
+++ b/content/media/webrtc/moz.build
@@ -52,8 +52,16 @@ EXPORTS.mozilla += [
     'PeerIdentity.h',
 ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'gklayout'
 if CONFIG['OS_ARCH'] == 'WINNT':
     DEFINES['NOMINMAX'] = True
+
+
+if CONFIG['_MSC_VER']:
+  CXXFLAGS += [
+    '-wd4275', # non dll-interface class used as base for dll-interface class
+  ]
+
+FAIL_ON_WARNINGS = True
--- a/content/svg/document/src/SVGDocument.cpp
+++ b/content/svg/document/src/SVGDocument.cpp
@@ -138,29 +138,29 @@ SVGDocument::EnsureNonSVGUserAgentStyleS
           catMan->GetCategoryEntry("agent-style-sheets", name.get(),
                                    getter_Copies(spec));
 
           mozilla::css::Loader* cssLoader = CSSLoader();
           if (cssLoader->GetEnabled()) {
             nsCOMPtr<nsIURI> uri;
             NS_NewURI(getter_AddRefs(uri), spec);
             if (uri) {
-              nsRefPtr<nsCSSStyleSheet> cssSheet;
+              nsRefPtr<CSSStyleSheet> cssSheet;
               cssLoader->LoadSheetSync(uri, true, true, getter_AddRefs(cssSheet));
               if (cssSheet) {
                 EnsureOnDemandBuiltInUASheet(cssSheet);
               }
             }
           }
         }
       }
     }
   }
 
-  nsCSSStyleSheet* sheet = nsLayoutStylesheetCache::NumberControlSheet();
+  CSSStyleSheet* sheet = nsLayoutStylesheetCache::NumberControlSheet();
   if (sheet) {
     // number-control.css can be behind a pref
     EnsureOnDemandBuiltInUASheet(sheet);
   }
   EnsureOnDemandBuiltInUASheet(nsLayoutStylesheetCache::FormsSheet());
   EnsureOnDemandBuiltInUASheet(nsLayoutStylesheetCache::CounterStylesSheet());
   EnsureOnDemandBuiltInUASheet(nsLayoutStylesheetCache::HTMLSheet());
   EnsureOnDemandBuiltInUASheet(nsLayoutStylesheetCache::UASheet());
--- a/content/test/unit/test_range.js
+++ b/content/test/unit/test_range.js
@@ -132,17 +132,16 @@ function evalXPathInDocumentFragment(aCo
                  targetType,
                  filter);
   var targetNode = walker.nextNode();
   do_check_neq(targetNode, null);
 
   // Apply our remaining xpath to the found node.
   var expr = aContextNode.ownerDocument.createExpression(realPath, null);
   var result = expr.evaluate(targetNode, UNORDERED_TYPE, null);
-  do_check_true(result instanceof C_i.nsIDOMXPathResult);
   return result.singleNodeValue;
 }
 
 /**
  * Get a DOM range corresponding to the test's source node.
  *
  * @param aSourceNode <source/> element with range information.
  * @param aFragment   DocumentFragment generated with getFragment().
--- a/content/xml/document/src/nsXMLContentSink.cpp
+++ b/content/xml/document/src/nsXMLContentSink.cpp
@@ -15,17 +15,17 @@
 #include "nsNetUtil.h"
 #include "nsIDocShell.h"
 #include "nsIStyleSheetLinkingElement.h"
 #include "nsIDOMComment.h"
 #include "nsIDOMCDATASection.h"
 #include "DocumentType.h"
 #include "nsHTMLParts.h"
 #include "nsCRT.h"
-#include "nsCSSStyleSheet.h"
+#include "mozilla/CSSStyleSheet.h"
 #include "mozilla/css/Loader.h"
 #include "nsGkAtoms.h"
 #include "nsContentUtils.h"
 #include "nsIScriptContext.h"
 #include "nsNameSpaceManager.h"
 #include "nsIServiceManager.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIContentViewer.h"
@@ -58,16 +58,17 @@
 #include "nsHtml5SVGLoadDispatcher.h"
 #include "nsTextNode.h"
 #include "mozilla/dom/CDATASection.h"
 #include "mozilla/dom/Comment.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/HTMLTemplateElement.h"
 #include "mozilla/dom/ProcessingInstruction.h"
 
+using namespace mozilla;
 using namespace mozilla::dom;
 
 // XXX Open Issues:
 // 1) what's not allowed - We need to figure out which HTML tags
 //    (prefixed with a HTML namespace qualifier) are explicitly not
 //    allowed (if any).
 // 2) factoring code with nsHTMLContentSink - There's some amount of
 //    common code between this and the HTML content sink. This will
@@ -409,17 +410,17 @@ nsXMLContentSink::OnTransformDone(nsresu
   ScrollToRef();
 
   originalDocument->EndLoad();
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXMLContentSink::StyleSheetLoaded(nsCSSStyleSheet* aSheet,
+nsXMLContentSink::StyleSheetLoaded(CSSStyleSheet* aSheet,
                                    bool aWasAlternate,
                                    nsresult aStatus)
 {
   if (!mPrettyPrinting) {
     return nsContentSink::StyleSheetLoaded(aSheet, aWasAlternate, aStatus);
   }
 
   if (!mDocument->CSSLoader()->HasPendingLoads()) {
--- a/content/xml/document/src/nsXMLContentSink.h
+++ b/content/xml/document/src/nsXMLContentSink.h
@@ -78,17 +78,18 @@ public:
   virtual bool IsScriptExecuting() MOZ_OVERRIDE;
   virtual void ContinueInterruptedParsingAsync() MOZ_OVERRIDE;
 
   // nsITransformObserver
   NS_IMETHOD OnDocumentCreated(nsIDocument *aResultDocument) MOZ_OVERRIDE;
   NS_IMETHOD OnTransformDone(nsresult aResult, nsIDocument *aResultDocument) MOZ_OVERRIDE;
 
   // nsICSSLoaderObserver
-  NS_IMETHOD StyleSheetLoaded(nsCSSStyleSheet* aSheet, bool aWasAlternate,
+  NS_IMETHOD StyleSheetLoaded(mozilla::CSSStyleSheet* aSheet,
+                              bool aWasAlternate,
                               nsresult aStatus) MOZ_OVERRIDE;
   static bool ParsePIData(const nsString &aData, nsString &aHref,
                           nsString &aTitle, nsString &aMedia,
                           bool &aIsAlternate);
 
 protected:
 
   nsIParser* GetParser();
--- a/content/xul/document/src/XULDocument.cpp
+++ b/content/xul/document/src/XULDocument.cpp
@@ -66,27 +66,28 @@
 #include "nsIScriptGlobalObject.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsNodeInfoManager.h"
 #include "nsContentCreatorFunctions.h"
 #include "nsContentUtils.h"
 #include "nsIParser.h"
 #include "nsCharsetSource.h"
 #include "nsIParserService.h"
-#include "nsCSSStyleSheet.h"
+#include "mozilla/CSSStyleSheet.h"
 #include "mozilla/css/Loader.h"
 #include "nsIScriptError.h"
 #include "nsIStyleSheetLinkingElement.h"
 #include "nsIObserverService.h"
 #include "nsNodeUtils.h"
 #include "nsIDocShellTreeOwner.h"
 #include "nsIXULWindow.h"
 #include "nsXULPopupManager.h"
 #include "nsCCUncollectableMarker.h"
 #include "nsURILoader.h"
+#include "mozilla/AddonPathService.h"
 #include "mozilla/BasicEvents.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/NodeInfoInlines.h"
 #include "mozilla/dom/ProcessingInstruction.h"
 #include "mozilla/dom/XULDocumentBinding.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/Preferences.h"
 #include "nsTextNode.h"
@@ -3283,17 +3284,17 @@ XULDocument::DoneWalking()
             }
         }
     }
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
-XULDocument::StyleSheetLoaded(nsCSSStyleSheet* aSheet,
+XULDocument::StyleSheetLoaded(CSSStyleSheet* aSheet,
                               bool aWasAlternate,
                               nsresult aStatus)
 {
     if (!aWasAlternate) {
         // Don't care about when alternate sheets finish loading
 
         NS_ASSERTION(mPendingSheets > 0,
             "Unexpected StyleSheetLoaded notification");
@@ -3686,19 +3687,24 @@ XULDocument::ExecuteScript(nsIScriptCont
         return NS_ERROR_NULL_POINTER;
 
     NS_ENSURE_TRUE(mScriptGlobalObject, NS_ERROR_NOT_INITIALIZED);
 
     // Execute the precompiled script with the given version
     nsAutoMicroTask mt;
     JSContext *cx = aContext->GetNativeContext();
     AutoCxPusher pusher(cx);
-    JS::Rooted<JSObject*> global(cx, mScriptGlobalObject->GetGlobalJSObject());
+    JS::Rooted<JSObject*> baseGlobal(cx, mScriptGlobalObject->GetGlobalJSObject());
+    NS_ENSURE_TRUE(baseGlobal, NS_ERROR_FAILURE);
+    NS_ENSURE_TRUE(nsContentUtils::GetSecurityManager()->ScriptAllowed(baseGlobal), NS_OK);
+
+    JSAddonId *addonId = MapURIToAddonID(mCurrentPrototype->GetURI());
+    JS::Rooted<JSObject*> global(cx, xpc::GetAddonScope(cx, baseGlobal, addonId));
     NS_ENSURE_TRUE(global, NS_ERROR_FAILURE);
-    NS_ENSURE_TRUE(nsContentUtils::GetSecurityManager()->ScriptAllowed(global), NS_OK);
+
     JS::ExposeObjectToActiveJS(global);
     xpc_UnmarkGrayScript(aScriptObject);
     JSAutoCompartment ac(cx, global);
 
     // The script is in the compilation scope. Clone it into the target scope
     // and execute it.
     if (!JS::CloneAndExecuteScript(cx, global, aScriptObject))
         nsJSUtils::ReportPendingException(cx);
@@ -3934,17 +3940,17 @@ XULDocument::AddPrototypeSheets()
 {
     nsresult rv;
 
     const nsCOMArray<nsIURI>& sheets = mCurrentPrototype->GetStyleSheetReferences();
 
     for (int32_t i = 0; i < sheets.Count(); i++) {
         nsCOMPtr<nsIURI> uri = sheets[i];
 
-        nsRefPtr<nsCSSStyleSheet> incompleteSheet;
+        nsRefPtr<CSSStyleSheet> incompleteSheet;
         rv = CSSLoader()->LoadSheet(uri,
                                     mCurrentPrototype->DocumentPrincipal(),
                                     EmptyCString(), this,
                                     getter_AddRefs(incompleteSheet));
 
         // XXXldb We need to prevent bogus sheets from being held in the
         // prototype's list, but until then, don't propagate the failure
         // from LoadSheet (and thus exit the loop).
--- a/content/xul/document/src/XULDocument.h
+++ b/content/xul/document/src/XULDocument.h
@@ -158,17 +158,17 @@ public:
 
     // nsDocument interface overrides
     virtual Element* GetElementById(const nsAString & elementId) MOZ_OVERRIDE;
 
     // nsIDOMXULDocument interface
     NS_DECL_NSIDOMXULDOCUMENT
 
     // nsICSSLoaderObserver
-    NS_IMETHOD StyleSheetLoaded(nsCSSStyleSheet* aSheet,
+    NS_IMETHOD StyleSheetLoaded(CSSStyleSheet* aSheet,
                                 bool aWasAlternate,
                                 nsresult aStatus) MOZ_OVERRIDE;
 
     virtual void EndUpdate(nsUpdateType aUpdateType) MOZ_OVERRIDE;
 
     virtual bool IsDocumentRightToLeft() MOZ_OVERRIDE;
 
     virtual void ResetDocumentDirection() MOZ_OVERRIDE;
@@ -331,17 +331,17 @@ protected:
      */
     bool                           mRestrictPersistence;
     nsTHashtable<nsStringHashKey>  mPersistenceIds;
 
     /**
      * An array of style sheets, that will be added (preserving order) to the
      * document after all of them are loaded (in DoneWalking).
      */
-    nsTArray<nsRefPtr<nsCSSStyleSheet> > mOverlaySheets;
+    nsTArray<nsRefPtr<CSSStyleSheet>> mOverlaySheets;
 
     nsCOMPtr<nsIDOMXULCommandDispatcher>     mCommandDispatcher; // [OWNER] of the focus tracker
 
     // Maintains the template builders that have been attached to
     // content elements
     typedef nsInterfaceHashtable<nsISupportsHashKey, nsIXULTemplateBuilder>
         BuilderTable;
     BuilderTable* mTemplateBuilderTable;
--- a/content/xul/document/src/nsXULPrototypeCache.cpp
+++ b/content/xul/document/src/nsXULPrototypeCache.cpp
@@ -2,33 +2,33 @@
 /* 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 "nsXULPrototypeCache.h"
 
 #include "plstr.h"
 #include "nsXULPrototypeDocument.h"
-#include "nsCSSStyleSheet.h"
 #include "nsIServiceManager.h"
 #include "nsIURI.h"
 
 #include "nsIChromeRegistry.h"
 #include "nsIFile.h"
 #include "nsIObjectInputStream.h"
 #include "nsIObjectOutputStream.h"
 #include "nsIObserverService.h"
 #include "nsIStringStream.h"
 #include "nsIStorageStream.h"
 
 #include "nsNetUtil.h"
 #include "nsAppDirectoryServiceDefs.h"
 
 #include "js/TracingAPI.h"
 
+#include "mozilla/CSSStyleSheet.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/scache/StartupCache.h"
 #include "mozilla/scache/StartupCacheUtils.h"
 #include "mozilla/Telemetry.h"
 
 using namespace mozilla;
 using namespace mozilla::scache;
 
@@ -167,17 +167,17 @@ nsXULPrototypeCache::PutPrototype(nsXULP
     nsCOMPtr<nsIURI> uri = aDocument->GetURI();
     // Put() releases any old value and addrefs the new one
     mPrototypeTable.Put(uri, aDocument);
 
     return NS_OK;
 }
 
 nsresult
-nsXULPrototypeCache::PutStyleSheet(nsCSSStyleSheet* aStyleSheet)
+nsXULPrototypeCache::PutStyleSheet(CSSStyleSheet* aStyleSheet)
 {
     nsIURI* uri = aStyleSheet->GetSheetURI();
 
     mStyleSheetTable.Put(uri, aStyleSheet);
 
     return NS_OK;
 }
 
@@ -234,17 +234,17 @@ FlushSkinXBL(nsIURI* aKey, nsRefPtr<nsXB
   if (!strncmp(str.get(), "/skin", 5)) {
     ret = PL_DHASH_REMOVE;
   }
 
   return ret;
 }
 
 static PLDHashOperator
-FlushSkinSheets(nsIURI* aKey, nsRefPtr<nsCSSStyleSheet>& aSheet, void* aClosure)
+FlushSkinSheets(nsIURI* aKey, nsRefPtr<CSSStyleSheet>& aSheet, void* aClosure)
 {
   nsAutoCString str;
   aSheet->GetSheetURI()->GetPath(str);
 
   PLDHashOperator ret = PL_DHASH_NEXT;
 
   if (!strncmp(str.get(), "/skin", 5)) {
     // This is a skin binding. Add the key to the list.
--- a/content/xul/document/src/nsXULPrototypeCache.h
+++ b/content/xul/document/src/nsXULPrototypeCache.h
@@ -14,17 +14,19 @@
 #include "nsRefPtrHashtable.h"
 #include "nsURIHashKey.h"
 #include "nsXULPrototypeDocument.h"
 #include "nsIInputStream.h"
 #include "nsIStorageStream.h"
 
 #include "mozilla/scache/StartupCache.h"
 
-class nsCSSStyleSheet;
+namespace mozilla {
+class CSSStyleSheet;
+} // namespace mozilla
 
 /**
  * The XUL prototype cache can be used to store and retrieve shared data for
  * XUL documents, style sheets, XBL, and scripts.
  *
  * The cache has two levels:
  *  1. In-memory hashtables
  *  2. The on-disk cache file.
@@ -67,25 +69,25 @@ public:
         return mXBLDocTable.GetWeak(aURL);
     }
     nsresult PutXBLDocumentInfo(nsXBLDocumentInfo* aDocumentInfo);
 
     /**
      * Get a style sheet by URI. If the style sheet is not in the cache,
      * returns nullptr.
      */
-    nsCSSStyleSheet* GetStyleSheet(nsIURI* aURI) {
+    mozilla::CSSStyleSheet* GetStyleSheet(nsIURI* aURI) {
         return mStyleSheetTable.GetWeak(aURI);
     }
 
     /**
      * Store a style sheet in the cache. The key, style sheet's URI is obtained
      * from the style sheet itself.
      */
-    nsresult PutStyleSheet(nsCSSStyleSheet* aStyleSheet);
+    nsresult PutStyleSheet(mozilla::CSSStyleSheet* aStyleSheet);
 
     /**
      * Write the XUL prototype document to a cache file. The proto must be
      * fully loaded.
      */
     nsresult WritePrototype(nsXULPrototypeDocument* aPrototypeDocument);
 
     /**
@@ -116,17 +118,17 @@ protected:
     nsXULPrototypeCache();
     virtual ~nsXULPrototypeCache();
 
     static nsXULPrototypeCache* sInstance;
 
     void FlushSkinFiles();
 
     nsRefPtrHashtable<nsURIHashKey,nsXULPrototypeDocument>   mPrototypeTable; // owns the prototypes
-    nsRefPtrHashtable<nsURIHashKey,nsCSSStyleSheet>          mStyleSheetTable;
+    nsRefPtrHashtable<nsURIHashKey,mozilla::CSSStyleSheet>   mStyleSheetTable;
     nsJSThingHashtable<nsURIHashKey, JSScript*>              mScriptTable;
     nsRefPtrHashtable<nsURIHashKey,nsXBLDocumentInfo>        mXBLDocTable;
 
     nsTHashtable<nsURIHashKey>                               mCacheURITable;
 
     nsInterfaceHashtable<nsURIHashKey, nsIStorageStream>     mOutputStreamTable;
     nsInterfaceHashtable<nsURIHashKey, nsIObjectInputStream> mInputStreamTable;
 
--- a/content/xul/templates/src/nsXMLBinding.cpp
+++ b/content/xul/templates/src/nsXMLBinding.cpp
@@ -1,16 +1,21 @@
 /* -*- Mode: C++; 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/. */
 
 #include "nsXULTemplateQueryProcessorXML.h"
 #include "nsXULTemplateResultXML.h"
 #include "nsXMLBinding.h"
+#include "mozilla/ErrorResult.h"
+#include "mozilla/dom/XPathResult.h"
+
+using namespace mozilla;
+using namespace mozilla::dom;
 
 NS_IMPL_CYCLE_COLLECTING_NATIVE_ADDREF(nsXMLBindingSet)
 NS_IMPL_CYCLE_COLLECTING_NATIVE_RELEASE(nsXMLBindingSet)
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsXMLBindingSet)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXMLBindingSet)
   nsXMLBinding* binding = tmp->mFirst;
@@ -78,66 +83,70 @@ nsXMLBindingSet::LookupTargetIndex(nsIAt
     idx++;
     binding = binding->mNext;
   }
 
   *aBinding = nullptr;
   return -1;
 }
 
-void
+XPathResult*
 nsXMLBindingValues::GetAssignmentFor(nsXULTemplateResultXML* aResult,
                                      nsXMLBinding* aBinding,
                                      int32_t aIndex,
-                                     uint16_t aType,
-                                     nsIDOMXPathResult** aValue)
+                                     uint16_t aType)
 {
-  *aValue = mValues.SafeObjectAt(aIndex);
-
-  if (!*aValue) {
-    nsCOMPtr<nsIDOMNode> contextNode;
-    aResult->GetNode(getter_AddRefs(contextNode));
-    if (contextNode) {
-      nsCOMPtr<nsISupports> resultsupports;
-      aBinding->mExpr->Evaluate(contextNode, aType,
-                                nullptr, getter_AddRefs(resultsupports));
-
-      nsCOMPtr<nsIDOMXPathResult> result = do_QueryInterface(resultsupports);
-      if (result && mValues.ReplaceObjectAt(result, aIndex))
-        *aValue = result;
-    }
+  XPathResult* value = mValues.SafeElementAt(aIndex);
+  if (value) {
+    return value;
   }
 
-  NS_IF_ADDREF(*aValue);
+  nsCOMPtr<nsIDOMNode> contextNode;
+  aResult->GetNode(getter_AddRefs(contextNode));
+  if (!contextNode) {
+    return nullptr;
+  }
+
+  mValues.EnsureLengthAtLeast(aIndex + 1);
+
+  nsCOMPtr<nsISupports> resultsupports;
+  aBinding->mExpr->Evaluate(contextNode, aType,
+                            nullptr, getter_AddRefs(resultsupports));
+
+  mValues.ReplaceElementAt(aIndex, XPathResult::FromSupports(resultsupports));
+
+  return mValues[aIndex];
 }
 
 void
 nsXMLBindingValues::GetNodeAssignmentFor(nsXULTemplateResultXML* aResult,
                                          nsXMLBinding* aBinding,
                                          int32_t aIndex,
                                          nsIDOMNode** aNode)
 {
-  nsCOMPtr<nsIDOMXPathResult> result;
-  GetAssignmentFor(aResult, aBinding, aIndex,
-                   nsIDOMXPathResult::FIRST_ORDERED_NODE_TYPE,
-                   getter_AddRefs(result));
+  XPathResult* result = GetAssignmentFor(aResult, aBinding, aIndex,
+                                         XPathResult::FIRST_ORDERED_NODE_TYPE);
 
-  if (result)
-    result->GetSingleNodeValue(aNode);
-  else
+  nsINode* node;
+  ErrorResult rv;
+  if (result && (node = result->GetSingleNodeValue(rv))) {
+    CallQueryInterface(node, aNode);
+  } else {
     *aNode = nullptr;
+  }
 }
 
 void
 nsXMLBindingValues::GetStringAssignmentFor(nsXULTemplateResultXML* aResult,
                                            nsXMLBinding* aBinding,
                                            int32_t aIndex,
                                            nsAString& aValue)
 {
-  nsCOMPtr<nsIDOMXPathResult> result;
-  GetAssignmentFor(aResult, aBinding, aIndex,
-                   nsIDOMXPathResult::STRING_TYPE, getter_AddRefs(result));
+  XPathResult* result = GetAssignmentFor(aResult, aBinding, aIndex,
+                                         XPathResult::STRING_TYPE);
 
-  if (result)
-    result->GetStringValue(aValue);
-  else
+  if (result) {
+    ErrorResult rv;
+    result->GetStringValue(aValue, rv);
+  } else {
     aValue.Truncate();
+  }
 }
--- a/content/xul/templates/src/nsXMLBinding.h
+++ b/content/xul/templates/src/nsXMLBinding.h
@@ -8,16 +8,21 @@
 
 #include "nsAutoPtr.h"
 #include "nsIAtom.h"
 #include "nsCycleCollectionParticipant.h"
 #include "mozilla/Attributes.h"
 
 class nsXULTemplateResultXML;
 class nsXMLBindingValues;
+namespace mozilla {
+namespace dom {
+class XPathResult;
+}
+}
 
 /**
  * Classes related to storing bindings for XML handling.
  */
 
 /**
  * a <binding> description
  */
@@ -87,17 +92,17 @@ protected:
   // the binding set
   nsRefPtr<nsXMLBindingSet> mBindings;
 
   /**
    * A set of values for variable bindings. To look up a binding value,
    * scan through the binding set in mBindings for the right target atom.
    * Its index will correspond to the index in this array.
    */
-  nsCOMArray<nsIDOMXPathResult> mValues;
+  nsTArray<nsRefPtr<mozilla::dom::XPathResult> > mValues;
 
 public:
 
   nsXMLBindingValues() { MOZ_COUNT_CTOR(nsXMLBindingValues); }
   ~nsXMLBindingValues() { MOZ_COUNT_DTOR(nsXMLBindingValues); }
 
   nsXMLBindingSet* GetBindingSet() { return mBindings; }
 
@@ -112,24 +117,22 @@ public:
 
   /**
    * Retrieve the assignment for a particular variable
    *
    * aResult the result generated from the template
    * aBinding the binding looked up using LookupTargetIndex
    * aIndex the index of the assignment to retrieve
    * aType the type of result expected
-   * aValue the value of the assignment
    */
-  void
+  mozilla::dom::XPathResult*
   GetAssignmentFor(nsXULTemplateResultXML* aResult,
                    nsXMLBinding* aBinding,
                    int32_t idx,
-                   uint16_t type,
-                   nsIDOMXPathResult** aValue);
+                   uint16_t type);
 
   void
   GetNodeAssignmentFor(nsXULTemplateResultXML* aResult,
                        nsXMLBinding* aBinding,
                        int32_t idx,
                        nsIDOMNode** aValue);
 
   void
--- a/content/xul/templates/src/nsXULTemplateQueryProcessorXML.cpp
+++ b/content/xul/templates/src/nsXULTemplateQueryProcessorXML.cpp
@@ -21,47 +21,48 @@
 #include "nsPIDOMWindow.h"
 #include "nsXULContentUtils.h"
 #include "nsXMLHttpRequest.h"
 
 #include "nsXULTemplateQueryProcessorXML.h"
 #include "nsXULTemplateResultXML.h"
 #include "nsXULSortService.h"
 
+using namespace mozilla;
 using namespace mozilla::dom;
 
 NS_IMPL_ISUPPORTS(nsXMLQuery, nsXMLQuery)
 
 //----------------------------------------------------------------------
 //
 // nsXULTemplateResultSetXML
 //
 
 NS_IMPL_ISUPPORTS(nsXULTemplateResultSetXML, nsISimpleEnumerator)
 
 NS_IMETHODIMP
 nsXULTemplateResultSetXML::HasMoreElements(bool *aResult)
 {
     // if GetSnapshotLength failed, then the return type was not a set of
     // nodes, so just return false in this case.
-    uint32_t length;
-    if (NS_SUCCEEDED(mResults->GetSnapshotLength(&length)))
-        *aResult = (mPosition < length);
-    else
-        *aResult = false;
-
+    ErrorResult rv;
+    uint32_t length = mResults->GetSnapshotLength(rv);
+    *aResult = !rv.Failed() && mPosition < length;
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULTemplateResultSetXML::GetNext(nsISupports **aResult)
 {
-    nsCOMPtr<nsIDOMNode> node;
-    nsresult rv = mResults->SnapshotItem(mPosition, getter_AddRefs(node));
-    NS_ENSURE_SUCCESS(rv, rv);
+    ErrorResult rv;
+    nsCOMPtr<nsIDOMNode> node =
+        do_QueryInterface(mResults->SnapshotItem(mPosition, rv));
+    if (rv.Failed()) {
+        return rv.ErrorCode();
+    }
 
     nsXULTemplateResultXML* result =
         new nsXULTemplateResultXML(mQuery, node, mBindingSet);
     NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY);
 
     ++mPosition;
     *aResult = result;
     NS_ADDREF(result);
@@ -326,23 +327,21 @@ nsXULTemplateQueryProcessorXML::Generate
         context = mRoot;
 
     nsIDOMXPathExpression* expr = xmlquery->GetResultsExpression();
     if (!expr)
         return NS_ERROR_FAILURE;
 
     nsCOMPtr<nsISupports> exprsupportsresults;
     nsresult rv = expr->Evaluate(context,
-                                 nsIDOMXPathResult::ORDERED_NODE_SNAPSHOT_TYPE,
+                                 XPathResult::ORDERED_NODE_SNAPSHOT_TYPE,
                                  nullptr, getter_AddRefs(exprsupportsresults));
     NS_ENSURE_SUCCESS(rv, rv);
 
-    nsCOMPtr<nsIDOMXPathResult> exprresults =
-        do_QueryInterface(exprsupportsresults);
-
+    XPathResult* exprresults = XPathResult::FromSupports(exprsupportsresults);
     nsXULTemplateResultSetXML* results =
         new nsXULTemplateResultSetXML(xmlquery, exprresults,
                                       xmlquery->GetBindingSet());
     NS_ENSURE_TRUE(results, NS_ERROR_OUT_OF_MEMORY);
 
     *aResults = results;
     NS_ADDREF(*aResults);
 
--- a/content/xul/templates/src/nsXULTemplateQueryProcessorXML.h
+++ b/content/xul/templates/src/nsXULTemplateQueryProcessorXML.h
@@ -12,21 +12,21 @@
 #include "nsISimpleEnumerator.h"
 #include "nsString.h"
 #include "nsCOMArray.h"
 #include "nsRefPtrHashtable.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMEventListener.h"
 #include "nsIDOMXPathExpression.h"
 #include "nsIDOMXPathEvaluator.h"
-#include "nsIDOMXPathResult.h"
 #include "nsXMLBinding.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsIXMLHttpRequest.h"
 #include "mozilla/Attributes.h"
+#include "mozilla/dom/XPathResult.h"
 
 class nsXULTemplateQueryProcessorXML;
 
 #define NS_IXMLQUERY_IID \
   {0x0358d692, 0xccce, 0x4a97, \
     { 0xb2, 0x51, 0xba, 0x8f, 0x17, 0x0f, 0x3b, 0x6f }}
  
 class nsXMLQuery MOZ_FINAL : public nsISupports
@@ -86,31 +86,31 @@ private:
 
     // reference back to the query
     nsCOMPtr<nsXMLQuery> mQuery;
 
     // the binding set created from <assign> nodes
     nsRefPtr<nsXMLBindingSet> mBindingSet;
 
     // set of results contained in this enumerator
-    nsCOMPtr<nsIDOMXPathResult> mResults;
+    nsRefPtr<mozilla::dom::XPathResult> mResults;
 
     // current position within the list of results
     uint32_t mPosition;
 
 public:
 
     // nsISupports interface
     NS_DECL_ISUPPORTS
 
     // nsISimpleEnumerator interface
     NS_DECL_NSISIMPLEENUMERATOR
 
     nsXULTemplateResultSetXML(nsXMLQuery* aQuery,
-                              nsIDOMXPathResult* aResults,
+                              mozilla::dom::XPathResult* aResults,
                               nsXMLBindingSet* aBindingSet)
         : mQuery(aQuery),
           mBindingSet(aBindingSet),
           mResults(aResults),
           mPosition(0)
     {}
 };
 
--- a/dom/apps/src/Webapps.jsm
+++ b/dom/apps/src/Webapps.jsm
@@ -947,17 +947,17 @@ this.DOMApplicationRegistry = {
           // If we can't load the manifest, we probably have a corrupted
           // registry. We delete the app since we can't do anything with it.
           delete this.webapps[aResult.id];
           return;
         }
 
         let localeManifest = new ManifestHelper(manifest, app.origin);
 
-        app.name = localeManifest.name;
+        app.name = manifest.name;
         app.csp = manifest.csp || "";
         app.role = localeManifest.role;
         if (app.appStatus >= Ci.nsIPrincipal.APP_STATUS_PRIVILEGED) {
           app.redirects = this.sanitizeRedirects(manifest.redirects);
         }
         this._registerSystemMessages(manifest, app);
         this._registerInterAppConnections(manifest, app);
         appsToRegister.push({ manifest: manifest, app: app });
@@ -1966,17 +1966,17 @@ this.DOMApplicationRegistry = {
           origin: aApp.origin,
           manifestURL: aData.manifestURL
         }, true);
       }
 
       this.updateDataStore(this.webapps[aId].localId, aApp.origin,
                            aApp.manifestURL, aApp.manifest);
 
-      aApp.name = manifest.name;
+      aApp.name = aNewManifest.name;
       aApp.csp = manifest.csp || "";
       aApp.role = manifest.role || "";
       aApp.updateTime = Date.now();
     } else {
       manifest = new ManifestHelper(aOldManifest, aApp.origin);
     }
 
     // Update the registry.
@@ -2331,45 +2331,45 @@ this.DOMApplicationRegistry = {
 
     app.id = aId;
     app.installTime = Date.now();
     app.lastUpdateCheck = Date.now();
 
     return app;
   },
 
-  _cloneApp: function(aData, aNewApp, aManifest, aId, aLocalId) {
+  _cloneApp: function(aData, aNewApp, aLocaleManifest, aManifest, aId, aLocalId) {
     let appObject = AppsUtils.cloneAppObject(aNewApp);
     appObject.appStatus =
       aNewApp.appStatus || Ci.nsIPrincipal.APP_STATUS_INSTALLED;
 
-    if (aManifest.appcache_path) {
+    if (aLocaleManifest.appcache_path) {
       appObject.installState = "pending";
       appObject.downloadAvailable = true;
       appObject.downloading = true;
       appObject.downloadSize = 0;
       appObject.readyToApplyDownload = false;
-    } else if (aManifest.package_path) {
+    } else if (aLocaleManifest.package_path) {
       appObject.installState = "pending";
       appObject.downloadAvailable = true;
       appObject.downloading = true;
-      appObject.downloadSize = aManifest.size;
+      appObject.downloadSize = aLocaleManifest.size;
       appObject.readyToApplyDownload = false;
     } else {
       appObject.installState = "installed";
       appObject.downloadAvailable = false;
       appObject.downloading = false;
       appObject.readyToApplyDownload = false;
     }
 
     appObject.localId = aLocalId;
     appObject.basePath = OS.Path.dirname(this.appsFile);
     appObject.name = aManifest.name;
-    appObject.csp = aManifest.csp || "";
-    appObject.role = aManifest.role || "";
+    appObject.csp = aLocaleManifest.csp || "";
+    appObject.role = aLocaleManifest.role;
     appObject.installerAppId = aData.appId;
     appObject.installerIsBrowser = aData.isBrowser;
 
     return appObject;
   },
 
   _writeManifestFile: function(aId, aIsPackage, aJsonManifest) {
     debug("_writeManifestFile");
@@ -2477,17 +2477,17 @@ this.DOMApplicationRegistry = {
     let app = this._setupApp(aData, id);
 
     let jsonManifest = aData.isPackage ? app.updateManifest : app.manifest;
     yield this._writeManifestFile(id, aData.isPackage, jsonManifest);
 
     debug("app.origin: " + app.origin);
     let manifest = new ManifestHelper(jsonManifest, app.origin);
 
-    let appObject = this._cloneApp(aData, app, manifest, id, localId);
+    let appObject = this._cloneApp(aData, app, manifest, jsonManifest, id, localId);
 
     this.webapps[id] = appObject;
 
     // For package apps, the permissions are not in the mini-manifest, so
     // don't update the permissions yet.
     if (!aData.isPackage) {
       if (supportUseCurrentProfile()) {
         PermissionsInstaller.installPermissions(
--- a/dom/archivereader/ArchiveRequest.cpp
+++ b/dom/archivereader/ArchiveRequest.cpp
@@ -126,29 +126,22 @@ ArchiveRequest::ReaderReady(nsTArray<nsC
 {
   if (NS_FAILED(aStatus)) {
     FireError(aStatus);
     return NS_OK;
   }
 
   nsresult rv;
 
-  nsCOMPtr<nsIGlobalObject> globalObject = do_QueryInterface(GetOwner());
-  if (NS_WARN_IF(!globalObject)) {
+  AutoJSAPI jsapi;
+  if (NS_WARN_IF(!jsapi.InitUsingWin(GetOwner()))) {
     return NS_ERROR_UNEXPECTED;
   }
-
-  AutoJSAPI jsapi;
   JSContext* cx = jsapi.cx();
 
-  JS::Rooted<JSObject*> global(cx, globalObject->GetGlobalJSObject());
-  NS_ASSERTION(global, "Failed to get global object!");
-
-  JSAutoCompartment ac(cx, global);
-
   JS::Rooted<JS::Value> result(cx);
   switch (mOperation) {
     case GetFilenames:
       rv = GetFilenamesResult(cx, result.address(), aFileList);
       break;
 
     case GetFile:
       rv = GetFileResult(cx, &result, aFileList);
--- a/dom/base/Console.cpp
+++ b/dom/base/Console.cpp
@@ -319,27 +319,28 @@ private:
   RunConsole() MOZ_OVERRIDE
   {
     // Walk up to our containing page
     WorkerPrivate* wp = mWorkerPrivate;
     while (wp->GetParent()) {
       wp = wp->GetParent();
     }
 
-    AutoJSAPI jsapi;
-    JSContext* cx = jsapi.cx();
-    ClearException ce(cx);
-
     nsPIDOMWindow* window = wp->GetWindow();
     NS_ENSURE_TRUE_VOID(window);
 
     nsRefPtr<nsGlobalWindow> win = static_cast<nsGlobalWindow*>(window);
     NS_ENSURE_TRUE_VOID(win);
 
-    JSAutoCompartment ac(cx, win->GetWrapperPreserveColor());
+    AutoJSAPI jsapi;
+    if (NS_WARN_IF(!jsapi.Init(win))) {
+      return;
+    }
+    JSContext* cx = jsapi.cx();
+    ClearException ce(cx);
 
     ErrorResult error;
     nsRefPtr<Console> console = win->GetConsole(error);
     if (error.Failed()) {
       NS_WARNING("Failed to get console from the window.");
       return;
     }
 
@@ -431,27 +432,28 @@ private:
   RunConsole() MOZ_OVERRIDE
   {
     // Walk up to our containing page
     WorkerPrivate* wp = mWorkerPrivate;
     while (wp->GetParent()) {
       wp = wp->GetParent();
     }
 
-    AutoJSAPI jsapi;
-    JSContext* cx = jsapi.cx();
-    ClearException ce(cx);
-
     nsPIDOMWindow* window = wp->GetWindow();
     NS_ENSURE_TRUE_VOID(window);
 
     nsRefPtr<nsGlobalWindow> win = static_cast<nsGlobalWindow*>(window);
     NS_ENSURE_TRUE_VOID(win);
 
-    JSAutoCompartment ac(cx, win->GetWrapperPreserveColor());
+    AutoJSAPI jsapi;
+    if (NS_WARN_IF(!jsapi.Init(win))) {
+      return;
+    }
+    JSContext* cx = jsapi.cx();
+    ClearException ce(cx);
 
     ErrorResult error;
     nsRefPtr<Console> console = win->GetConsole(error);
     if (error.Failed()) {
       NS_WARNING("Failed to get console from the window.");
       return;
     }
 
--- a/dom/base/MessagePort.cpp
+++ b/dom/base/MessagePort.cpp
@@ -267,24 +267,21 @@ PopulateMessagePortList(MessagePortBase*
   return PL_DHASH_NEXT;
 }
 
 NS_IMETHODIMP
 PostMessageRunnable::Run()
 {
   MOZ_ASSERT(mPort);
 
-  nsCOMPtr<nsIGlobalObject> globalObject = do_QueryInterface(mPort->GetOwner());
-  if (NS_WARN_IF(!globalObject)) {
+  AutoJSAPI jsapi;
+  if (NS_WARN_IF(!jsapi.Init(mPort->GetParentObject()))) {
     return NS_ERROR_UNEXPECTED;
   }
-
-  AutoJSAPI jsapi;
   JSContext* cx = jsapi.cx();
-  JSAutoCompartment ac(cx, globalObject->GetGlobalJSObject());
 
   // Deserialize the structured clone data
   JS::Rooted<JS::Value> messageData(cx);
   StructuredCloneInfo scInfo;
   scInfo.mEvent = this;
   scInfo.mPort = mPort;
 
   if (!mBuffer.read(cx, &messageData, &kPostMessageCallbacks, &scInfo)) {
--- a/dom/base/ScriptSettings.cpp
+++ b/dom/base/ScriptSettings.cpp
@@ -9,16 +9,18 @@
 #include "mozilla/Assertions.h"
 
 #include "jsapi.h"
 #include "xpcpublic.h"
 #include "nsIGlobalObject.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIScriptContext.h"
 #include "nsContentUtils.h"
+#include "nsGlobalWindow.h"
+#include "nsPIDOMWindow.h"
 #include "nsTArray.h"
 #include "nsJSUtils.h"
 
 namespace mozilla {
 namespace dom {
 
 static mozilla::ThreadLocal<ScriptSettingsStackEntry*> sScriptSettingsTLS;
 
@@ -216,57 +218,110 @@ FindJSContext(nsIGlobalObject* aGlobalOb
   }
   if (!cx) {
     cx = nsContentUtils::GetSafeJSContext();
   }
   return cx;
 }
 
 AutoJSAPI::AutoJSAPI()
-  : mCx(nsContentUtils::GetDefaultJSContextForThread())
+  : mCx(nullptr)
 {
-  if (NS_IsMainThread()) {
-    mCxPusher.construct(mCx);
-  }
-
-  // Leave the cx in a null compartment.
-  mNullAc.construct(mCx);
 }
 
-AutoJSAPI::AutoJSAPI(JSContext *aCx, bool aIsMainThread, bool aSkipNullAc)
-  : mCx(aCx)
+void
+AutoJSAPI::InitInternal(JSObject* aGlobal, JSContext* aCx, bool aIsMainThread)
 {
-  MOZ_ASSERT_IF(aIsMainThread, NS_IsMainThread());
+  mCx = aCx;
   if (aIsMainThread) {
     mCxPusher.construct(mCx);
   }
 
-  // In general we want to leave the cx in a null compartment, but we let
-  // subclasses skip this if they plan to immediately enter a compartment.
-  if (!aSkipNullAc) {
-    mNullAc.construct(mCx);
-  }
+  mAutoNullableCompartment.construct(mCx, aGlobal);
+}
+
+AutoJSAPI::AutoJSAPI(nsIGlobalObject* aGlobalObject,
+                     bool aIsMainThread,
+                     JSContext* aCx)
+{
+  MOZ_ASSERT(aGlobalObject);
+  MOZ_ASSERT(aGlobalObject->GetGlobalJSObject(), "Must have a JS global");
+  MOZ_ASSERT(aCx);
+  MOZ_ASSERT_IF(aIsMainThread, NS_IsMainThread());
+
+  InitInternal(aGlobalObject->GetGlobalJSObject(), aCx, aIsMainThread);
+}
+
+void
+AutoJSAPI::Init()
+{
+  MOZ_ASSERT(!mCx, "An AutoJSAPI should only be initialised once");
+
+  InitInternal(/* aGlobal */ nullptr,
+               nsContentUtils::GetDefaultJSContextForThread(),
+               NS_IsMainThread());
 }
 
-AutoJSAPIWithErrorsReportedToWindow::AutoJSAPIWithErrorsReportedToWindow(nsIScriptContext* aScx)
-  : AutoJSAPI(aScx->GetNativeContext(), /* aIsMainThread = */ true)
+bool
+AutoJSAPI::Init(nsIGlobalObject* aGlobalObject, JSContext* aCx)
 {
+  MOZ_ASSERT(!mCx, "An AutoJSAPI should only be initialised once");
+  MOZ_ASSERT(aCx);
+
+  if (NS_WARN_IF(!aGlobalObject)) {
+    return false;
+  }
+
+  JSObject* global = aGlobalObject->GetGlobalJSObject();
+  if (NS_WARN_IF(!global)) {
+    return false;
+  }
+
+  InitInternal(global, aCx, NS_IsMainThread());
+  return true;
+}
+
+bool
+AutoJSAPI::Init(nsIGlobalObject* aGlobalObject)
+{
+  return Init(aGlobalObject, nsContentUtils::GetDefaultJSContextForThread());
 }
 
-AutoJSAPIWithErrorsReportedToWindow::AutoJSAPIWithErrorsReportedToWindow(nsIGlobalObject* aGlobalObject)
-  : AutoJSAPI(FindJSContext(aGlobalObject), /* aIsMainThread = */ true)
+bool
+AutoJSAPI::InitWithLegacyErrorReporting(nsIGlobalObject* aGlobalObject)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  return Init(aGlobalObject, FindJSContext(aGlobalObject));
+}
+
+bool
+AutoJSAPI::InitUsingWin(nsPIDOMWindow* aWindow, JSContext* aCx)
 {
+  return Init(static_cast<nsGlobalWindow*>(aWindow), aCx);
+}
+
+bool
+AutoJSAPI::InitUsingWin(nsPIDOMWindow* aWindow)
+{
+  return Init(static_cast<nsGlobalWindow*>(aWindow));
+}
+
+bool
+AutoJSAPI::InitWithLegacyErrorReportingUsingWin(nsPIDOMWindow* aWindow)
+{
+  return InitWithLegacyErrorReporting(static_cast<nsGlobalWindow*>(aWindow));
 }
 
 AutoEntryScript::AutoEntryScript(nsIGlobalObject* aGlobalObject,
                                  bool aIsMainThread,
                                  JSContext* aCx)
-  : AutoJSAPI(aCx ? aCx : FindJSContext(aGlobalObject), aIsMainThread, /* aSkipNullAc = */ true)
+  : AutoJSAPI(aGlobalObject, aIsMainThread,
+              aCx ? aCx : FindJSContext(aGlobalObject))
   , ScriptSettingsStackEntry(aGlobalObject, /* aCandidate = */ true)
-  , mAc(cx(), aGlobalObject->GetGlobalJSObject())
   , mWebIDLCallerPrincipal(nullptr)
 {
   MOZ_ASSERT(aGlobalObject);
   MOZ_ASSERT_IF(!aCx, aIsMainThread); // cx is mandatory off-main-thread.
   MOZ_ASSERT_IF(aCx && aIsMainThread, aCx == FindJSContext(aGlobalObject));
 }
 
 AutoIncumbentScript::AutoIncumbentScript(nsIGlobalObject* aGlobalObject)
--- a/dom/base/ScriptSettings.h
+++ b/dom/base/ScriptSettings.h
@@ -11,17 +11,17 @@
 
 #include "nsCxPusher.h"
 #include "MainThreadUtils.h"
 #include "nsIGlobalObject.h"
 #include "nsIPrincipal.h"
 
 #include "mozilla/Maybe.h"
 
-class nsIGlobalObject;
+class nsPIDOMWindow;
 
 namespace mozilla {
 namespace dom {
 
 /*
  * System-wide setup/teardown routines. Init and Destroy should be invoked
  * once each, at startup and shutdown (respectively).
  */
@@ -87,22 +87,24 @@ private:
   ScriptSettingsStackEntry *mOlder;
 };
 
 /*
  * For any interaction with JSAPI, an AutoJSAPI (or one of its subclasses)
  * must be on the stack.
  *
  * This base class should be instantiated as-is when the caller wants to use
- * JSAPI but doesn't expect to run script. Its current duties are as-follows:
+ * JSAPI but doesn't expect to run script. The caller must then call one of its
+ * Init functions before being able to access the JSContext through cx().
+ * Its current duties are as-follows (see individual Init comments for details):
  *
  * * Grabbing an appropriate JSContext, and, on the main thread, pushing it onto
  *   the JSContext stack.
- * * Entering a null compartment, so that the consumer is forced to select a
- *   compartment to enter before manipulating objects.
+ * * Entering an initial (possibly null) compartment, to ensure that the
+ *   previously entered compartment for that JSContext is not used by mistake.
  *
  * Additionally, the following duties are planned, but not yet implemented:
  *
  * * De-poisoning the JSRuntime to allow manipulation of JSAPI. We can't
  *   actually implement this poisoning until all the JSContext pushing in the
  *   system goes through AutoJSAPI (see bug 951991). For now, this de-poisoning
  *   effectively corresponds to having a non-null cx on the stack.
  * * Reporting any exceptions left on the JSRuntime, unless the caller steals
@@ -116,47 +118,74 @@ private:
  * should be used, which does additional manipulation of the script settings
  * stack. In bug 991758, we'll add hard invariants to SpiderMonkey, such that
  * any attempt to run script without an AutoEntryScript on the stack will
  * fail. This prevents system code from accidentally triggering script
  * execution at inopportune moments via surreptitious getters and proxies.
  */
 class AutoJSAPI {
 public:
-  // Public constructor for use when the base class is constructed as-is. It
-  // uses the SafeJSContext (or worker equivalent), and enters a null
-  // compartment.
+  // Trivial constructor. One of the Init functions must be called before
+  // accessing the JSContext through cx().
   AutoJSAPI();
-  JSContext* cx() const { return mCx; }
+
+  // This uses the SafeJSContext (or worker equivalent), and enters a null
+  // compartment, so that the consumer is forced to select a compartment to
+  // enter before manipulating objects.
+  void Init();
+
+  // This uses the SafeJSContext (or worker equivalent), and enters the
+  // compartment of aGlobalObject.
+  // If aGlobalObject or its associated JS global are null then it returns
+  // false and use of cx() will cause an assertion.
+  bool Init(nsIGlobalObject* aGlobalObject);
+
+  // Unsurprisingly, this uses aCx and enters the compartment of aGlobalObject.
+  // If aGlobalObject or its associated JS global are null then it returns
+  // false and use of cx() will cause an assertion.
+  // If aCx is null it will cause an assertion.
+  bool Init(nsIGlobalObject* aGlobalObject, JSContext* aCx);
+
+  // This may only be used on the main thread.
+  // This attempts to use the JSContext associated with aGlobalObject, otherwise
+  // it uses the SafeJSContext. It then enters the compartment of aGlobalObject.
+  // This means that existing error reporting mechanisms that use the JSContext
+  // to find the JSErrorReporter should still work as before.
+  // We should be able to remove this around bug 981198.
+  // If aGlobalObject or its associated JS global are null then it returns
+  // false and use of cx() will cause an assertion.
+  bool InitWithLegacyErrorReporting(nsIGlobalObject* aGlobalObject);
+
+  // Convenience functions to take an nsPIDOMWindow*, when it is more easily
+  // available than an nsIGlobalObject.
+  bool InitUsingWin(nsPIDOMWindow* aWindow);
+  bool InitUsingWin(nsPIDOMWindow* aWindow, JSContext* aCx);
+  bool InitWithLegacyErrorReportingUsingWin(nsPIDOMWindow* aWindow);
+
+  JSContext* cx() const {
+    MOZ_ASSERT(mCx, "Must call Init before using an AutoJSAPI");
+    return mCx;
+  }
 
   bool CxPusherIsStackTop() { return mCxPusher.ref().IsStackTop(); }
 
 protected:
   // Protected constructor, allowing subclasses to specify a particular cx to
-  // be used.
-  AutoJSAPI(JSContext *aCx, bool aIsMainThread, bool aSkipNullAC = false);
+  // be used. This constructor initialises the AutoJSAPI, so Init must NOT be
+  // called on subclasses that use this.
+  // If aGlobalObject, its associated JS global or aCx are null this will cause
+  // an assertion, as will setting aIsMainThread incorrectly.
+  AutoJSAPI(nsIGlobalObject* aGlobalObject, bool aIsMainThread, JSContext* aCx);
 
 private:
   mozilla::Maybe<AutoCxPusher> mCxPusher;
-  mozilla::Maybe<JSAutoNullCompartment> mNullAc;
+  mozilla::Maybe<JSAutoNullableCompartment> mAutoNullableCompartment;
   JSContext *mCx;
-};
 
-// Note - the ideal way to implement this is with an accessor on AutoJSAPI
-// that lets us select the error reporting target. But at present,
-// implementing it that way would require us to destroy and reconstruct
-// mCxPusher, which is pretty wasteful. So we do this for now, since it should
-// be pretty easy to switch things over later.
-//
-// This should only be used on the main thread.
-class AutoJSAPIWithErrorsReportedToWindow : public AutoJSAPI {
-  public:
-    AutoJSAPIWithErrorsReportedToWindow(nsIScriptContext* aScx);
-    // Equivalent to AutoJSAPI if aGlobal is not a Window.
-    AutoJSAPIWithErrorsReportedToWindow(nsIGlobalObject* aGlobalObject);
+  void InitInternal(JSObject* aGlobal, JSContext* aCx, bool aIsMainThread);
 };
 
 /*
  * A class that represents a new script entry point.
  */
 class AutoEntryScript : public AutoJSAPI,
                         protected ScriptSettingsStackEntry {
 public:
@@ -165,17 +194,16 @@ public:
                   // Note: aCx is mandatory off-main-thread.
                   JSContext* aCx = nullptr);
 
   void SetWebIDLCallerPrincipal(nsIPrincipal *aPrincipal) {
     mWebIDLCallerPrincipal = aPrincipal;
   }
 
 private:
-  JSAutoCompartment mAc;
   // It's safe to make this a weak pointer, since it's the subject principal
   // when we go on the stack, so can't go away until after we're gone.  In
   // particular, this is only used from the CallSetup constructor, and only in
   // the aIsJSImplementedWebIDL case.  And in that case, the subject principal
   // is the principal of the callee function that is part of the CallArgs just a
   // bit up the stack, and which will outlive us.  So we know the principal
   // can't go away until then either.
   nsIPrincipal* mWebIDLCallerPrincipal;
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -109,17 +109,16 @@
 #include "nsITreeContentView.h"
 #include "nsITreeView.h"
 #include "nsIXULTemplateBuilder.h"
 #include "nsITreeColumns.h"
 #endif
 #include "nsIDOMXPathExpression.h"
 #include "nsIDOMNSXPathExpression.h"
 #include "nsIDOMXPathNSResolver.h"
-#include "nsIDOMXPathResult.h"
 
 // Storage includes
 #include "nsIDOMStorage.h"
 #include "nsPIDOMStorage.h"
 
 // Drag and drop
 #include "nsIDOMFile.h"
 #include "nsDOMBlobBuilder.h" // nsDOMMultipartFile
@@ -345,18 +344,16 @@ static nsDOMClassInfoData sClassInfoData
 
   NS_DEFINE_CLASSINFO_DATA(XSLTProcessor, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(XPathExpression, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(XPathNSResolver, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(XPathResult, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   // WhatWG Storage
 
   // mrbkap says we don't need WANT_ADDPROPERTY on Storage objects
   // since a call to addProperty() is always followed by a call to
   // setProperty(), except in the case when a getter or setter is set
   // for a property. But we don't care about getters or setters here.
   NS_DEFINE_CLASSINFO_DATA(Storage, nsStorage2SH,
@@ -953,20 +950,16 @@ nsDOMClassInfo::Init()
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMXPathExpression)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSXPathExpression)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(XPathNSResolver, nsIDOMXPathNSResolver)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMXPathNSResolver)
   DOM_CLASSINFO_MAP_END
 
-  DOM_CLASSINFO_MAP_BEGIN(XPathResult, nsIDOMXPathResult)
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMXPathResult)
-  DOM_CLASSINFO_MAP_END
-
   DOM_CLASSINFO_MAP_BEGIN(Storage, nsIDOMStorage)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMStorage)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(Blob, nsIDOMBlob)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMBlob)
   DOM_CLASSINFO_MAP_END
 
--- a/dom/base/nsDOMClassInfoClasses.h
+++ b/dom/base/nsDOMClassInfoClasses.h
@@ -43,17 +43,16 @@ DOMCI_CLASS(CSSMozDocumentRule)
 DOMCI_CLASS(CSSSupportsRule)
 
 // XSLTProcessor
 DOMCI_CLASS(XSLTProcessor)
 
 // DOM Level 3 XPath objects
 DOMCI_CLASS(XPathExpression)
 DOMCI_CLASS(XPathNSResolver)
-DOMCI_CLASS(XPathResult)
 
 // WhatWG WebApps Objects
 DOMCI_CLASS(Storage)
 
 DOMCI_CLASS(Blob)
 DOMCI_CLASS(File)
 
 // DOM modal content window class, almost identical to Window
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -2354,16 +2354,17 @@ nsGlobalWindow::SetNewDocument(nsIDocume
   // clear smartcard events, our document has gone away.
   if (mCrypto && XRE_GetProcessType() != GeckoProcessType_Content) {
     nsresult rv = mCrypto->SetEnableSmartCardEvents(false);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 #endif
 
   AutoJSAPI jsapi;
+  jsapi.Init();
   JSContext *cx = jsapi.cx();
 
   if (!mDoc) {
     // First document load.
 
     // Get our private root. If it is equal to us, then we need to
     // attach our global key bindings that handles browser scrolling
     // and other browser commands.
@@ -8000,16 +8001,17 @@ NS_IMETHODIMP
 PostMessageEvent::Run()
 {
   NS_ABORT_IF_FALSE(mTargetWindow->IsOuterWindow(),
                     "should have been passed an outer window!");
   NS_ABORT_IF_FALSE(!mSource || mSource->IsOuterWindow(),
                     "should have been passed an outer window!");
 
   AutoJSAPI jsapi;
+  jsapi.Init();
   JSContext* cx = jsapi.cx();
 
   // If we bailed before this point we're going to leak mMessage, but
   // that's probably better than crashing.
 
   nsRefPtr<nsGlobalWindow> targetWindow;
   if (mTargetWindow->IsClosedOrClosing() ||
       !(targetWindow = mTargetWindow->GetCurrentInnerWindowInternal()) ||
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -1590,16 +1590,17 @@ static const JSFunctionSpec JProfFunctio
 
 #endif /* defined(MOZ_JPROF) */
 
 nsresult
 nsJSContext::InitClasses(JS::Handle<JSObject*> aGlobalObj)
 {
   JSOptionChangedCallback(js_options_dot_str, this);
   AutoJSAPI jsapi;
+  jsapi.Init();
   JSContext* cx = jsapi.cx();
   JSAutoCompartment ac(cx, aGlobalObj);
 
   // Attempt to initialize profiling functions
   ::JS_DefineProfilingFunctions(cx, aGlobalObj);
 
 #ifdef NS_TRACE_MALLOC
   if (nsContentUtils::IsCallerChrome()) {
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -258,17 +258,17 @@ DOMInterfaces = {
     'resultNotAddRefed': ['getRGBColorValue', 'getRectValue']
 },
 
 'CSSStyleDeclaration': {
     'nativeType': 'nsICSSDeclaration'
 },
 
 'CSSStyleSheet': {
-    'nativeType': 'nsCSSStyleSheet',
+    'nativeType': 'mozilla::CSSStyleSheet',
     'binaryNames': { 'ownerRule': 'DOMOwnerRule' },
 },
 
 'CSSValue': {
     'concrete': False
 },
 
 'CSSValueList': {
@@ -1061,17 +1061,17 @@ DOMInterfaces = {
     'workers': True,
 },
 
 'SourceBufferList': {
     'resultNotAddRefed': [ '__indexedGetter' ],
 },
 
 'StyleSheet': {
-    'nativeType': 'nsCSSStyleSheet',
+    'nativeType': 'mozilla::CSSStyleSheet',
 },
 
 'SVGAnimatedLengthList': {
     'nativeType': 'mozilla::DOMSVGAnimatedLengthList',
     'headerFile': 'DOMSVGAnimatedLengthList.h',
 },
 
 'SVGAnimatedNumberList': {
@@ -1654,16 +1654,20 @@ DOMInterfaces = {
 'XMLStylesheetProcessingInstruction': {
     'resultNotAddRefed': [ 'sheet' ]
 },
 
 'XPathEvaluator': {
     'wrapperCache': False
 },
 
+'XPathResult': {
+    'resultNotAddRefed': ['singleNodeValue', 'iterateNext', 'snapshotItem']
+},
+
 'XULDocument': {
     'headerFile': 'XULDocument.h'
 },
 
 'XULElement': {
     'nativeType': 'nsXULElement',
     'resultNotAddRefed': [ 'controllers', 'style' ]
 },
@@ -1991,12 +1995,11 @@ addExternalIface('OutputStream', nativeT
                  notflattened=True)
 addExternalIface('Principal', nativeType='nsIPrincipal',
                  headerFile='nsIPrincipal.h', notflattened=True)
 addExternalIface('StackFrame', nativeType='nsIStackFrame',
                  headerFile='nsIException.h', notflattened=True)
 addExternalIface('URI', nativeType='nsIURI', headerFile='nsIURI.h',
                  notflattened=True)
 addExternalIface('UserDataHandler')
-addExternalIface('XPathResult', nativeType='nsISupports')
 addExternalIface('XPathExpression')
 addExternalIface('XPathNSResolver')
 addExternalIface('XULCommandDispatcher')
--- a/dom/browser-element/BrowserElementParent.jsm
+++ b/dom/browser-element/BrowserElementParent.jsm
@@ -60,20 +60,16 @@ function visibilityChangeHandler(e) {
 }
 
 this.BrowserElementParentBuilder = {
   create: function create(frameLoader, hasRemoteFrame, isPendingFrame) {
     return new BrowserElementParent(frameLoader, hasRemoteFrame);
   }
 }
 
-
-// The active input method iframe.
-let activeInputFrame = null;
-
 function BrowserElementParent(frameLoader, hasRemoteFrame, isPendingFrame) {
   debug("Creating new BrowserElementParent object for " + frameLoader);
   this._domRequestCounter = 0;
   this._pendingDOMRequests = {};
   this._pendingSetInputMethodActive = [];
   this._hasRemoteFrame = hasRemoteFrame;
   this._nextPaintListeners = [];
 
@@ -108,22 +104,17 @@ function BrowserElementParent(frameLoade
       if (self._isAlive()) {
         fn.apply(self, arguments);
       }
     };
   };
 
   let defineDOMRequestMethod = function(domName, msgName) {
     XPCNativeWrapper.unwrap(self._frameElement)[domName] = function() {
-      if (!self._mm) {
-        return self._queueDOMRequest;
-      }
-      if (self._isAlive()) {
-        return self._sendDOMRequest(msgName);
-      }
+      return self._sendDOMRequest(msgName);
     };
   }
 
   // Define methods on the frame element.
   defineNoReturnMethod('setVisible', this._setVisible);
   defineDOMRequestMethod('getVisible', 'get-visible');
   defineNoReturnMethod('sendMouseEvent', this._sendMouseEvent);
 
@@ -337,23 +328,16 @@ BrowserElementParent.prototype = {
       return false;
     }
     return true;
   },
 
   _recvHello: function() {
     debug("recvHello");
 
-    this._ready = true;
-
-    // Handle pending SetInputMethodActive request.
-    while (this._pendingSetInputMethodActive.length > 0) {
-      this._setInputMethodActive(this._pendingSetInputMethodActive.shift());
-    }
-
     // Inform our child if our owner element's document is invisible.  Note
     // that we must do so here, rather than in the BrowserElementParent
     // constructor, because the BrowserElementChild may not be initialized when
     // we run our constructor.
     if (this._window.document.hidden) {
       this._ownerVisibilityChange();
     }
 
@@ -477,60 +461,46 @@ BrowserElementParent.prototype = {
     }
 
     return new this._window.Event('mozbrowser' + evtName,
                                   { bubbles: true,
                                     cancelable: cancelable });
   },
 
   /**
-   * If remote frame haven't been set up, we enqueue a function that get a
-   * DOMRequest until the remote frame is ready and return another DOMRequest
-   * to caller. When we get the real DOMRequest, we will help forward the
-   * success/error callback to the DOMRequest that caller got.
-   */
-  _queueDOMRequest: function(msgName, args) {
-    if (!this._pendingAPICalls) {
-      return;
-    }
-
-    let req = Services.DOMRequest.createRequest(this._window);
-    let self = this;
-    let getRealDOMRequest = function() {
-      let realReq = self._sendDOMRequest(msgName, args);
-      realReq.onsuccess = function(v) {
-        Services.DOMRequest.fireSuccess(req, v);
-      };
-      realReq.onerror = function(v) {
-        Services.DOMRequest.fireError(req, v);
-      };
-    };
-    this._pendingAPICalls.push(getRealDOMRequest);
-    return req;
-  },
-
-  /**
    * Kick off a DOMRequest in the child process.
    *
    * We'll fire an event called |msgName| on the child process, passing along
    * an object with two fields:
    *
    *  - id:  the ID of this request.
    *  - arg: arguments to pass to the child along with this request.
    *
    * We expect the child to pass the ID back to us upon completion of the
    * request.  See _gotDOMRequestResult.
    */
   _sendDOMRequest: function(msgName, args) {
     let id = 'req_' + this._domRequestCounter++;
     let req = Services.DOMRequest.createRequest(this._window);
-    if (this._sendAsyncMsg(msgName, {id: id, args: args})) {
-      this._pendingDOMRequests[id] = req;
+    let self = this;
+    let send = function() {
+      if (!self._isAlive()) {
+        return;
+      }
+      if (self._sendAsyncMsg(msgName, {id: id, args: args})) {
+        self._pendingDOMRequests[id] = req;
+      } else {
+        Services.DOMRequest.fireErrorAsync(req, "fail");
+      }
+    };
+    if (this._mm) {
+      send();
     } else {
-      Services.DOMRequest.fireErrorAsync(req, "fail");
+      // Child haven't been loaded.
+      this._pendingAPICalls.push(send);
     }
     return req;
   },
 
   /**
    * Called when the child process finishes handling a DOMRequest.  data.json
    * must have the fields [id, successRv], if the DOMRequest was successful, or
    * [id, errorMsg], if the request was not successful.
@@ -726,23 +696,16 @@ BrowserElementParent.prototype = {
     let height = parseInt(_height);
     let mimeType = (typeof _mimeType === 'string') ?
       _mimeType.trim().toLowerCase() : 'image/jpeg';
     if (isNaN(width) || isNaN(height) || width < 0 || height < 0) {
       throw Components.Exception("Invalid argument",
                                  Cr.NS_ERROR_INVALID_ARG);
     }
 
-    if (!this._mm) {
-      // Child haven't been loaded.
-      return this._queueDOMRequest('get-screenshot',
-                                   {width: width, height: height,
-                                    mimeType: mimeType});
-    }
-
     return this._sendDOMRequest('get-screenshot',
                                 {width: width, height: height,
                                  mimeType: mimeType});
   },
 
   _recvNextPaint: function(data) {
     let listeners = this._nextPaintListeners;
     this._nextPaintListeners = [];
@@ -795,60 +758,18 @@ BrowserElementParent.prototype = {
   },
 
   _setInputMethodActive: function(isActive) {
     if (typeof isActive !== 'boolean') {
       throw Components.Exception("Invalid argument",
                                  Cr.NS_ERROR_INVALID_ARG);
     }
 
-    // Wait until browserElementChild is initialized.
-    if (!this._ready) {
-      this._pendingSetInputMethodActive.push(isActive);
-      return;
-    }
-
-    let req = Services.DOMRequest.createRequest(this._window);
-
-    // Deactivate the old input method if needed.
-    if (activeInputFrame && isActive) {
-      if (Cu.isDeadWrapper(activeInputFrame)) {
-        // If the activeInputFrame is already a dead object,
-        // we should simply set it to null directly.
-        activeInputFrame = null;
-        this._sendSetInputMethodActiveDOMRequest(req, isActive);
-        return req;
-      }
-
-      let reqOld = XPCNativeWrapper.unwrap(activeInputFrame)
-                                   .setInputMethodActive(false);
-
-      // We wan't to continue regardless whether this req succeeded
-      reqOld.onsuccess = reqOld.onerror = function() {
-        activeInputFrame = null;
-        this._sendSetInputMethodActiveDOMRequest(req, isActive);
-      }.bind(this);
-    } else {
-      this._sendSetInputMethodActiveDOMRequest(req, isActive);
-    }
-    return req;
-  },
-
-  _sendSetInputMethodActiveDOMRequest: function(req, isActive) {
-    let id = 'req_' + this._domRequestCounter++;
-    let data = {
-      id : id,
-      args: { isActive: isActive }
-    };
-    if (this._sendAsyncMsg('set-input-method-active', data)) {
-      activeInputFrame = this._frameElement;
-      this._pendingDOMRequests[id] = req;
-    } else {
-      Services.DOMRequest.fireErrorAsync(req, 'fail');
-    }
+    return this._sendDOMRequest('set-input-method-active',
+                                {isActive: isActive});
   },
 
   _fireKeyEvent: function(data) {
     let evt = this._window.document.createEvent("KeyboardEvent");
     evt.initKeyEvent(data.json.type, true, true, this._window,
                      false, false, false, false, // modifiers
                      data.json.keyCode,
                      data.json.charCode);
--- a/dom/browser-element/mochitest/browserElement_SetInputMethodActive.js
+++ b/dom/browser-element/mochitest/browserElement_SetInputMethodActive.js
@@ -167,16 +167,23 @@ function next(msg) {
       // Do nothing and wait for the input to show up in input frame.
       break;
 
     case 2:
       is(from, 'input', 'Message sequence unexpected (2).');
       is(value, '#0hello',
          'Failed to get correct input from the first iframe.');
 
+      let req0 = gFrames[0].setInputMethodActive(false);
+      req0.onsuccess = function() {
+        ok(true, 'setInputMethodActive succeeded (0).');
+      };
+      req0.onerror = function() {
+        ok(false, 'setInputMethodActive failed (0): ' + this.error.name);
+      };
       let req1 = gFrames[1].setInputMethodActive(true);
       req1.onsuccess = function() {
        ok(true, 'setInputMethodActive succeeded (1).');
       };
       req1.onerror = function() {
        ok(false, 'setInputMethodActive failed (1): ' + this.error.name);
       };
       break;
--- a/dom/camera/CameraPreferences.cpp
+++ b/dom/camera/CameraPreferences.cpp
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; 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/. */
 
 #include "CameraPreferences.h"
 #include "CameraCommon.h"
+#include "mozilla/ArrayUtils.h"
 #include "mozilla/Monitor.h"
 #include "mozilla/StaticPtr.h"
 #include "mozilla/Preferences.h"
 
 using namespace mozilla;
 
 /* statics */
 static StaticAutoPtr<Monitor> sPrefMonitor;
--- a/dom/crypto/WebCryptoTask.cpp
+++ b/dom/crypto/WebCryptoTask.cpp
@@ -261,16 +261,20 @@ public:
       AesCbcParams params;
       nsresult rv = Coerce(aCx, params, aAlgorithm);
       if (NS_FAILED(rv) || !params.mIv.WasPassed()) {
         mEarlyRv = NS_ERROR_DOM_INVALID_ACCESS_ERR;
         return;
       }
 
       ATTEMPT_BUFFER_INIT(mIv, params.mIv.Value())
+      if (mIv.Length() != 16) {
+        mEarlyRv = NS_ERROR_DOM_DATA_ERR;
+        return;
+      }
     } else if (algName.EqualsLiteral(WEBCRYPTO_ALG_AES_CTR)) {
       mMechanism = CKM_AES_CTR;
       telemetryAlg = TA_AES_CTR;
       AesCtrParams params;
       nsresult rv = Coerce(aCx, params, aAlgorithm);
       if (NS_FAILED(rv) || !params.mCounter.WasPassed() ||
           !params.mLength.WasPassed()) {
         mEarlyRv = NS_ERROR_DOM_SYNTAX_ERR;
@@ -1160,21 +1164,27 @@ public:
         hashName.Assign(hashAlg.mName.Value());
       }
 
       if (params.mLength.WasPassed()) {
         mLength = params.mLength.Value();
       } else {
         KeyAlgorithm hashAlg(global, hashName);
         switch (hashAlg.Mechanism()) {
-          case CKM_SHA_1: mLength = 128; break;
-          case CKM_SHA256: mLength = 256; break;
-          case CKM_SHA384: mLength = 384; break;
-          case CKM_SHA512: mLength = 512; break;
-          default: mLength = 0; break;
+          case CKM_SHA_1:
+          case CKM_SHA256:
+            mLength = 512;
+            break;
+          case CKM_SHA384:
+          case CKM_SHA512:
+            mLength = 1024;
+            break;
+          default:
+            mLength = 0;
+            break;
         }
       }
 
       if (mLength == 0) {
         mEarlyRv = NS_ERROR_DOM_DATA_ERR;
         return;
       }
 
--- a/dom/crypto/test/tests.js
+++ b/dom/crypto/test/tests.js
@@ -327,17 +327,32 @@ TestArray.addTest(
 // -----------------------------------------------------------------------------
 TestArray.addTest(
   "Generate a 256-bit HMAC-SHA-256 key without specifying a key length",
   function() {
     var that = this;
     var alg = { name: "HMAC", hash: {name: "SHA-256"} };
     crypto.subtle.generateKey(alg, true, ["sign", "verify"]).then(
       complete(that, function(x) {
-        return hasKeyFields(x) && x.algorithm.length == 256;
+        return hasKeyFields(x) && x.algorithm.length == 512;
+      }),
+      error(that)
+    );
+  }
+);
+
+// -----------------------------------------------------------------------------
+TestArray.addTest(
+  "Generate a 256-bit HMAC-SHA-512 key without specifying a key length",
+  function() {
+    var that = this;
+    var alg = { name: "HMAC", hash: {name: "SHA-512"} };
+    crypto.subtle.generateKey(alg, true, ["sign", "verify"]).then(
+      complete(that, function(x) {
+        return hasKeyFields(x) && x.algorithm.length == 1024;
       }),
       error(that)
     );
   }
 );
 
 // -----------------------------------------------------------------------------
 TestArray.addTest(
@@ -455,16 +470,46 @@ TestArray.addTest(
         memcmp_complete(that, tv.aes_cbc_enc.result),
         error(that)
       );
   }
 );
 
 // -----------------------------------------------------------------------------
 TestArray.addTest(
+  "AES-CBC encrypt with wrong IV size",
+  function () {
+    var that = this;
+
+    function encrypt(x, iv) {
+      console.log(x);
+      return crypto.subtle.encrypt(
+        { name: "AES-CBC", iv: iv },
+        x, tv.aes_cbc_enc.data);
+    }
+
+    function doEncrypt(x) {
+      return encrypt(x, new Uint8Array(15))
+        .then(
+          null,
+          function () { return encrypt(new Uint8Array(17)); }
+        );
+    }
+
+    crypto.subtle.importKey("raw", tv.aes_cbc_enc.key, "AES-CBC", false, ['encrypt'])
+      .then(doEncrypt)
+      .then(
+        error(that),
+        complete(that)
+      );
+  }
+);
+
+// -----------------------------------------------------------------------------
+TestArray.addTest(
   "AES-CBC decrypt",
   function () {
     var that = this;
 
     function doDecrypt(x) {
       return crypto.subtle.decrypt(
         { name: "AES-CBC", iv: tv.aes_cbc_dec.iv },
         x, tv.aes_cbc_dec.data);
@@ -476,16 +521,45 @@ TestArray.addTest(
         memcmp_complete(that, tv.aes_cbc_dec.result),
         error(that)
       );
   }
 );
 
 // -----------------------------------------------------------------------------
 TestArray.addTest(
+  "AES-CBC decrypt with wrong IV size",
+  function () {
+    var that = this;
+
+    function decrypt(x, iv) {
+      return crypto.subtle.decrypt(
+        { name: "AES-CBC", iv: iv },
+        x, tv.aes_cbc_dec.data);
+    }
+
+    function doDecrypt(x) {
+      return decrypt(x, new Uint8Array(15))
+        .then(
+          null,
+          function () { return decrypt(x, new Uint8Array(17)); }
+        );
+    }
+
+    crypto.subtle.importKey("raw", tv.aes_cbc_dec.key, "AES-CBC", false, ['decrypt'])
+      .then(doDecrypt)
+      .then(
+        error(that),
+        complete(that)
+      );
+  }
+);
+
+// -----------------------------------------------------------------------------
+TestArray.addTest(
   "AES-CTR encryption",
   function () {
     var that = this;
 
     function doEncrypt(x) {
       return crypto.subtle.encrypt(
         { name: "AES-CTR", counter: tv.aes_ctr_enc.iv, length: 32 },
         x, tv.aes_ctr_enc.data);
@@ -497,16 +571,45 @@ TestArray.addTest(
         memcmp_complete(that, tv.aes_ctr_enc.result),
         error(that)
       );
   }
 );
 
 // -----------------------------------------------------------------------------
 TestArray.addTest(
+  "AES-CTR encryption with wrong IV size",
+  function () {
+    var that = this;
+
+    function encrypt(x, iv) {
+      return crypto.subtle.encrypt(
+        { name: "AES-CTR", counter: iv, length: 32 },
+        x, tv.aes_ctr_enc.data);
+    }
+
+    function doEncrypt(x) {
+      return encrypt(x, new Uint8Array(15))
+        .then(
+          null,
+          function () { return encrypt(x, new Uint8Array(17)); }
+        );
+    }
+
+    crypto.subtle.importKey("raw", tv.aes_ctr_enc.key, "AES-CTR", false, ['encrypt'])
+      .then(doEncrypt)
+      .then(
+        error(that),
+        complete(that)
+      );
+  }
+);
+
+// -----------------------------------------------------------------------------
+TestArray.addTest(
   "AES-CTR decryption",
   function () {
     var that = this;
 
     function doDecrypt(x) {
       return crypto.subtle.decrypt(
         { name: "AES-CTR", counter: tv.aes_ctr_dec.iv, length: 32 },
         x, tv.aes_ctr_dec.data);
@@ -518,16 +621,45 @@ TestArray.addTest(
         memcmp_complete(that, tv.aes_ctr_dec.result),
         error(that)
       );
   }
 );
 
 // -----------------------------------------------------------------------------
 TestArray.addTest(
+  "AES-CTR decryption with wrong IV size",
+  function () {
+    var that = this;
+
+    function doDecrypt(x, iv) {
+      return crypto.subtle.decrypt(
+        { name: "AES-CTR", counter: iv, length: 32 },
+        x, tv.aes_ctr_dec.data);
+    }
+
+    function decrypt(x) {
+      return decrypt(x, new Uint8Array(15))
+        .then(
+          null,
+          function () { return decrypt(x, new Uint8Array(17)); }
+        );
+    }
+
+    crypto.subtle.importKey("raw", tv.aes_ctr_dec.key, "AES-CTR", false, ['decrypt'])
+      .then(doDecrypt)
+      .then(
+        error(that),
+        complete(that)
+      );
+  }
+);
+
+// -----------------------------------------------------------------------------
+TestArray.addTest(
   "AES-GCM encryption",
   function () {
     var that = this;
 
     function doEncrypt(x) {
       return crypto.subtle.encrypt(
         {
           name: "AES-GCM",
--- a/dom/devicestorage/nsDeviceStorage.cpp
+++ b/dom/devicestorage/nsDeviceStorage.cpp
@@ -1719,25 +1719,21 @@ nsIFileToJsval(nsPIDOMWindow* aWindow, D
   return InterfaceToJsval(aWindow, blob, &NS_GET_IID(nsIDOMBlob));
 }
 
 JS::Value StringToJsval(nsPIDOMWindow* aWindow, nsAString& aString)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aWindow);
 
-  JSObject* global =
-    static_cast<nsGlobalWindow*>(aWindow)->GetWrapperPreserveColor();
-  if (NS_WARN_IF(!global)) {
+  AutoJSAPI jsapi;
+  if (NS_WARN_IF(!jsapi.InitUsingWin(aWindow))) {
     return JSVAL_NULL;
   }
-
-  AutoJSAPI jsapi;
   JSContext* cx = jsapi.cx();
-  JSAutoCompartment ac(cx, global);
 
   JS::Rooted<JS::Value> result(cx);
   if (!xpc::StringToJsval(cx, aString, &result)) {
     return JSVAL_NULL;
   }
 
   return result;
 }
--- a/dom/events/EventListenerManager.cpp
+++ b/dom/events/EventListenerManager.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; 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/. */
 
 // Microsoft's API Name hackery sucks
 #undef CreateEvent
 
+#include "mozilla/AddonPathService.h"
 #include "mozilla/BasicEvents.h"
 #include "mozilla/CycleCollectedJSRuntime.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/EventListenerManager.h"
 #ifdef MOZ_B2G
 #include "mozilla/Hal.h"
 #endif // #ifdef MOZ_B2G
 #include "mozilla/HalSensor.h"
@@ -769,22 +770,22 @@ EventListenerManager::CompileEventHandle
              "What is there to compile?");
 
   nsresult result = NS_OK;
   nsCOMPtr<nsIDocument> doc;
   nsCOMPtr<nsIScriptGlobalObject> global =
     GetScriptGlobalAndDocument(getter_AddRefs(doc));
   NS_ENSURE_STATE(global);
 
-  nsIScriptContext* context = global->GetScriptContext();
-  NS_ENSURE_STATE(context);
-
   // Activate JSAPI, and make sure that exceptions are reported on the right
   // Window.
-  AutoJSAPIWithErrorsReportedToWindow jsapi(context);
+  AutoJSAPI jsapi;
+  if (NS_WARN_IF(!jsapi.InitWithLegacyErrorReporting(global))) {
+    return NS_ERROR_UNEXPECTED;
+  }
   JSContext* cx = jsapi.cx();
 
   nsCOMPtr<nsIAtom> typeAtom = aListener->mTypeAtom;
   nsIAtom* attrName = typeAtom;
 
   // Flag us as not a string so we don't keep trying to compile strings which
   // can't be compiled.
   aListener->mHandlerIsString = false;
@@ -837,32 +838,45 @@ EventListenerManager::CompileEventHandle
 
   nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(mTarget);
   uint32_t argCount;
   const char **argNames;
   nsContentUtils::GetEventArgNames(aElement->GetNameSpaceID(),
                                    typeAtom, win,
                                    &argCount, &argNames);
 
+  JSAddonId *addonId = MapURIToAddonID(uri);
+
   // Wrap the event target, so that we can use it as the scope for the event
   // handler. Note that mTarget is different from aElement in the <body> case,
   // where mTarget is a Window.
   //
   // The wrapScope doesn't really matter here, because the target will create
   // its reflector in the proper scope, and then we'll enter that compartment.
-  JS::Rooted<JSObject*> wrapScope(cx, context->GetWindowProxy());
+  JS::Rooted<JSObject*> wrapScope(cx, global->GetGlobalJSObject());
   JS::Rooted<JS::Value> v(cx);
   {
     JSAutoCompartment ac(cx, wrapScope);
     nsresult rv = nsContentUtils::WrapNative(cx, mTarget, &v,
                                              /* aAllowWrapping = */ false);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
   }
+  if (addonId) {
+    JS::Rooted<JSObject*> vObj(cx, &v.toObject());
+    JS::Rooted<JSObject*> addonScope(cx, xpc::GetAddonScope(cx, vObj, addonId));
+    if (!addonScope) {
+      return NS_ERROR_FAILURE;
+    }
+    JSAutoCompartment ac(cx, addonScope);
+    if (!JS_WrapValue(cx, &v)) {
+      return NS_ERROR_FAILURE;
+    }
+  }
   JS::Rooted<JSObject*> target(cx, &v.toObject());
   JSAutoCompartment ac(cx, target);
 
   nsDependentAtomString str(attrName);
   // Most of our names are short enough that we don't even have to malloc
   // the JS string stuff, so don't worry about playing games with
   // refcounting XPCOM stringbuffers.
   JS::Rooted<JSString*> jsStr(cx, JS_NewUCStringCopyN(cx,
--- a/dom/icc/src/Icc.cpp
+++ b/dom/icc/src/Icc.cpp
@@ -43,23 +43,21 @@ nsresult
 Icc::NotifyEvent(const nsAString& aName)
 {
   return DispatchTrustedEvent(aName);
 }
 
 nsresult
 Icc::NotifyStkEvent(const nsAString& aName, const nsAString& aMessage)
 {
-  nsresult rv;
-  nsIScriptContext* sc = GetContextForEventHandlers(&rv);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  AutoJSAPIWithErrorsReportedToWindow jsapi(sc);
+  AutoJSAPI jsapi;
+  if (NS_WARN_IF(!jsapi.InitWithLegacyErrorReportingUsingWin(GetOwner()))) {
+    return NS_ERROR_UNEXPECTED;
+  }
   JSContext* cx = jsapi.cx();
-  JSAutoCompartment ac(cx, sc->GetWindowProxyPreserveColor());
   JS::Rooted<JS::Value> value(cx);
 
   if (!aMessage.IsEmpty()) {
     nsCOMPtr<nsIJSON> json(new nsJSON());
     nsresult rv = json->DecodeToJSVal(aMessage, cx, &value);
     NS_ENSURE_SUCCESS(rv, rv);
   } else {
     value = JS::NullValue();
--- a/dom/imptests/failures/editing/conformancetest/test_runtest.html.json
+++ b/dom/imptests/failures/editing/conformancetest/test_runtest.html.json
@@ -3867,19 +3867,16 @@
   "[[\"stylewithcss\",\"false\"],[\"defaultparagraphseparator\",\"p\"],[\"inserthorizontalrule\",\"\"]] \"<p>foo<b>b[a]r</b>baz</p>\" queryCommandValue(\"defaultparagraphseparator\") before":true,
   "[[\"stylewithcss\",\"false\"],[\"defaultparagraphseparator\",\"p\"],[\"inserthorizontalrule\",\"\"]] \"<p>foo<b>b[a]r</b>baz</p>\" queryCommandValue(\"defaultparagraphseparator\") after":true,
   "[[\"inserthorizontalrule\",\"\"]] \"<address>foo[bar]baz</address>\" compare innerHTML":true,
   "[[\"inserthorizontalrule\",\"\"]] \"<bdi>foo[bar]baz</bdi>\" compare innerHTML":true,
   "[[\"inserthorizontalrule\",\"\"]] \"<blink>foo[bar]baz</blink>\" compare innerHTML":true,
   "[[\"inserthorizontalrule\",\"\"]] \"<table><caption>foo[bar]baz</caption><tr><td>quz</table>\": execCommand(\"inserthorizontalrule\", false, \"\") return value":true,
   "[[\"inserthorizontalrule\",\"\"]] \"<table><caption>foo[bar]baz</caption><tr><td>quz</table>\" compare innerHTML":true,
   "[[\"inserthorizontalrule\",\"\"]] \"<dl><dt>foo[bar]baz</dt></dl>\" compare innerHTML":true,
-  "[[\"inserthorizontalrule\",\"\"]] \"<ruby>foo[bar]baz<rt>quz</rt></ruby>\" compare innerHTML":true,
-  "[[\"inserthorizontalrule\",\"\"]] \"<ruby>foo<rt>bar[baz]quz</rt></ruby>\" compare innerHTML":true,
-  "[[\"inserthorizontalrule\",\"\"]] \"<ruby>foo<rp>bar[baz]quz</rp><rt>qoz</rt><rp>qiz</rp></ruby>\" compare innerHTML":true,
   "[[\"inserthorizontalrule\",\"\"]] \"fo[o<span contenteditable=false>bar</span>b]az\" compare innerHTML":true,
   "[[\"stylewithcss\",\"true\"],[\"inserthtml\",\"ab<b>c</b>d\"]] \"[foo<span style=color:#aBcDeF>bar]</span>baz\" compare innerHTML":true,
   "[[\"stylewithcss\",\"false\"],[\"inserthtml\",\"ab<b>c</b>d\"]] \"[foo<span style=color:#aBcDeF>bar]</span>baz\" compare innerHTML":true,
   "[[\"stylewithcss\",\"true\"],[\"inserthtml\",\"ab<b>c</b>d\"]] \"{foo<span style=color:#aBcDeF>bar}</span>baz\" compare innerHTML":true,
   "[[\"stylewithcss\",\"false\"],[\"inserthtml\",\"ab<b>c</b>d\"]] \"{foo<span style=color:#aBcDeF>bar}</span>baz\" compare innerHTML":true,
   "[[\"stylewithcss\",\"true\"],[\"inserthtml\",\"ab<b>c</b>d\"]] \"foo<span style=color:#aBcDeF>[bar</span><span style=color:#fEdCbA>baz]</span>quz\" compare innerHTML":true,
   "[[\"stylewithcss\",\"false\"],[\"inserthtml\",\"ab<b>c</b>d\"]] \"foo<span style=color:#aBcDeF>[bar</span><span style=color:#fEdCbA>baz]</span>quz\" compare innerHTML":true,
   "[[\"inserthtml\",\"\"]] \"foo[bar]baz\": execCommand(\"inserthtml\", false, \"\") return value":true,
--- a/dom/interfaces/xpath/nsIDOMNSXPathExpression.idl
+++ b/dom/interfaces/xpath/nsIDOMNSXPathExpression.idl
@@ -1,16 +1,15 @@
 /* -*- 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/. */
 
 #include "domstubs.idl"
 
-interface nsIDOMXPathResult;
 interface XPathException;
 
 /**
  * Interface for Mozilla specific XPathExpression functions.
  */
 [scriptable, uuid(ce600ca8-e98a-4419-ad61-2f6d0cb0ecc8)]
 interface nsIDOMNSXPathExpression : nsISupports
 {
--- a/dom/interfaces/xpath/nsIDOMXPathEvaluator.idl
+++ b/dom/interfaces/xpath/nsIDOMXPathEvaluator.idl
@@ -5,17 +5,16 @@
 
 /**
  * Corresponds to http://www.w3.org/TR/2002/WD-DOM-Level-3-XPath-20020208
  */
 
 #include "domstubs.idl"
 
 interface nsIDOMXPathNSResolver;
-interface nsIDOMXPathResult;
 interface nsIDOMXPathExpression;
 interface XPathException;
 
 [uuid(75506f8a-b504-11d5-a7f2-ca108ab8b6fc)]
 interface nsIDOMXPathEvaluator : nsISupports
 {
   nsIDOMXPathExpression    createExpression(in DOMString expression, 
                                             in nsIDOMXPathNSResolver resolver)
--- a/dom/interfaces/xpath/nsIDOMXPathExpression.idl
+++ b/dom/interfaces/xpath/nsIDOMXPathExpression.idl
@@ -4,17 +4,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /**
  * Corresponds to http://www.w3.org/TR/2002/WD-DOM-Level-3-XPath-20020208
  */
 
 #include "domstubs.idl"
 
-interface nsIDOMXPathResult;
 interface XPathException;
 
 [scriptable, uuid(75506f82-b504-11d5-a7f2-ca108ab8b6fc)]
 interface nsIDOMXPathExpression : nsISupports
 {
   nsISupports              evaluate(in nsIDOMNode contextNode, 
                                     in unsigned short type, 
                                     in nsISupports result)
--- a/dom/interfaces/xpath/nsIDOMXPathResult.idl
+++ b/dom/interfaces/xpath/nsIDOMXPathResult.idl
@@ -2,50 +2,25 @@
 /* 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/. */
 
 /**
  * Corresponds to http://www.w3.org/TR/2002/WD-DOM-Level-3-XPath-20020208
  */
 
-#include "domstubs.idl"
+#include "nsISupports.idl"
 
-interface XPathException;
-
-[scriptable, uuid(75506f84-b504-11d5-a7f2-ca108ab8b6fc)]
+[uuid(75506f84-b504-11d5-a7f2-ca108ab8b6fc)]
 interface nsIDOMXPathResult : nsISupports
 {
   // XPathResultType
   const unsigned short      ANY_TYPE                       = 0;
   const unsigned short      NUMBER_TYPE                    = 1;
   const unsigned short      STRING_TYPE                    = 2;
   const unsigned short      BOOLEAN_TYPE                   = 3;
   const unsigned short      UNORDERED_NODE_ITERATOR_TYPE   = 4;
   const unsigned short      ORDERED_NODE_ITERATOR_TYPE     = 5;
   const unsigned short      UNORDERED_NODE_SNAPSHOT_TYPE   = 6;
   const unsigned short      ORDERED_NODE_SNAPSHOT_TYPE     = 7;
   const unsigned short      ANY_UNORDERED_NODE_TYPE        = 8;
   const unsigned short      FIRST_ORDERED_NODE_TYPE        = 9;
-
-  readonly attribute unsigned short   resultType;
-  readonly attribute double           numberValue;
-                                      // raises(XPathException) on retrieval
-
-  readonly attribute DOMString        stringValue;
-                                      // raises(XPathException) on retrieval
-
-  readonly attribute boolean          booleanValue;
-                                      // raises(XPathException) on retrieval
-
-  readonly attribute nsIDOMNode       singleNodeValue;
-                                      // raises(XPathException) on retrieval
-
-  readonly attribute boolean          invalidIteratorState;
-  readonly attribute unsigned long    snapshotLength;
-                                      // raises(XPathException) on retrieval
-
-  nsIDOMNode               iterateNext()
-                                      raises(XPathException, 
-                                             DOMException);
-  nsIDOMNode               snapshotItem(in unsigned long index)
-                                      raises(XPathException);
 };
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -826,17 +826,18 @@ ContentParent::AnswerBridgeToChildProces
         // You can't bridge to a process you didn't open!
         KillHard();
         return false;
     }
 }
 
 /*static*/ TabParent*
 ContentParent::CreateBrowserOrApp(const TabContext& aContext,
-                                  Element* aFrameElement)
+                                  Element* aFrameElement,
+                                  ContentParent* aOpenerContentParent)
 {
     if (!sCanLaunchSubprocesses) {
         return nullptr;
     }
 
     ProcessPriority initialPriority = GetInitialProcessPriority(aFrameElement);
 
     if (aContext.IsBrowserElement() || !aContext.HasOwnApp()) {
@@ -858,19 +859,22 @@ ContentParent::CreateBrowserOrApp(const 
             if (!child->CallBridgeToChildProcess(id)) {
                 return nullptr;
             }
             ContentBridgeParent* parent = child->GetLastBridge();
             parent->SetChildID(id);
             parent->SetIsForApp(isForApp);
             parent->SetIsForBrowser(isForBrowser);
             constructorSender = parent;
-        } else if (nsRefPtr<ContentParent> cp =
-                   GetNewOrUsed(aContext.IsBrowserElement(), initialPriority)) {
-            constructorSender = cp;
+        } else {
+          if (aOpenerContentParent) {
+            constructorSender = aOpenerContentParent;
+          } else {
+            constructorSender = GetNewOrUsed(aContext.IsBrowserElement(), initialPriority);
+          }
         }
         if (constructorSender) {
             uint32_t chromeFlags = 0;
 
             // Propagate the private-browsing status of the element's parent
             // docshell to the remote docshell, via the chrome flags.
             nsCOMPtr<Element> frameElement = do_QueryInterface(aFrameElement);
             MOZ_ASSERT(frameElement);
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -110,17 +110,18 @@ public:
 
     /**
      * Get or create a content process for the given TabContext.  aFrameElement
      * should be the frame/iframe element with which this process will
      * associated.
      */
     static TabParent*
     CreateBrowserOrApp(const TabContext& aContext,
-                       Element* aFrameElement);
+                       Element* aFrameElement,
+                       ContentParent* aOpenerContentParent);
 
     static void GetAll(nsTArray<ContentParent*>& aArray);
     static void GetAllEvenIfDead(nsTArray<ContentParent*>& aArray);
 
     static bool IgnoreIPCPrincipal();
 
     virtual bool RecvCreateChildProcess(const IPCTabContext& aContext,
                                         const hal::ProcessPriority& aPriority,
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -89,17 +89,25 @@ parent:
     /**
      * When child sends this message, parent should move focus to
      * the next or previous focusable element.
      */
     MoveFocus(bool forward);
 
     Event(RemoteDOMEvent aEvent);
 
-    intr CreateWindow() returns (PBrowser window);
+    intr CreateWindow(uint32_t aChromeFlags,
+                      bool aCalledFromJS,
+                      bool aPositionSpecified,
+                      bool aSizeSpecified,
+                      nsString aURI,
+                      nsString aName,
+                      nsString aFeatures,
+                      nsString aBaseURI)
+      returns (bool windowIsNew, PBrowser window);
 
     sync SyncMessage(nsString aMessage, ClonedMessageData aData,
                      CpowEntry[] aCpows, Principal aPrincipal)
       returns (nsString[] retval);
 
     rpc RpcMessage(nsString aMessage, ClonedMessageData aData,
                    CpowEntry[] aCpows, Principal aPrincipal)
       returns (nsString[] retval);
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -37,19 +37,21 @@
 #include "nsEmbedCID.h"
 #include <algorithm>
 #ifdef MOZ_CRASHREPORTER
 #include "nsExceptionHandler.h"
 #endif
 #include "nsFilePickerProxy.h"
 #include "mozilla/dom/Element.h"
 #include "nsIBaseWindow.h"
+#include "nsIBrowserDOMWindow.h"
 #include "nsICachedFileDescriptorListener.h"
 #include "nsIDocumentInlines.h"
 #include "nsIDocShellTreeOwner.h"
+#include "nsIDOMChromeWindow.h"
 #include "nsIDOMEvent.h"
 #include "nsIDOMWindow.h"
 #include "nsIDOMWindowUtils.h"
 #include "nsIDocShell.h"
 #include "nsIURI.h"
 #include "nsIURIFixup.h"
 #include "nsCDefaultURIFixup.h"
 #include "nsIWebBrowser.h"
@@ -59,16 +61,17 @@
 #include "nsIXULRuntime.h"
 #include "nsInterfaceHashtable.h"
 #include "nsPIDOMWindow.h"
 #include "nsPIWindowRoot.h"
 #include "nsLayoutUtils.h"
 #include "nsPrintfCString.h"
 #include "nsThreadUtils.h"
 #include "nsWeakReference.h"
+#include "nsWindowWatcher.h"
 #include "PermissionMessageUtils.h"
 #include "PCOMContentPermissionRequestChild.h"
 #include "PuppetWidget.h"
 #include "StructuredCloneUtils.h"
 #include "nsViewportInfo.h"
 #include "JavaScriptChild.h"
 #include "nsILoadContext.h"
 #include "ipc/nsGUIEventIPC.h"
@@ -1225,23 +1228,78 @@ TabChild::ProvideWindow(nsIDOMWindow* aP
 
       // Note that BrowserFrameProvideWindow may return NS_ERROR_ABORT if the
       // open window call was canceled.  It's important that we pass this error
       // code back to our caller.
       return BrowserFrameProvideWindow(aParent, aURI, aName, aFeatures,
                                        aWindowIsNew, aReturn);
     }
 
-    // Otherwise, create a new top-level window.
+    int32_t openLocation =
+      nsWindowWatcher::GetWindowOpenLocation(aParent, aChromeFlags, aCalledFromJS,
+                                             aPositionSpecified, aSizeSpecified);
+
+    // If it turns out we're opening in the current browser, just hand over the
+    // current browser's docshell.
+    if (openLocation == nsIBrowserDOMWindow::OPEN_CURRENTWINDOW) {
+      nsCOMPtr<nsIWebBrowser> browser = do_GetInterface(WebNavigation());
+      *aWindowIsNew = false;
+      return browser->GetContentDOMWindow(aReturn);
+    }
+
+    // Otherwise, we're opening a new tab or a new window. We have to contact
+    // TabParent in order to do either.
+
     PBrowserChild* newChild;
-    if (!CallCreateWindow(&newChild)) {
+
+    nsAutoCString uriString;
+    if (aURI) {
+      aURI->GetSpec(uriString);
+    }
+
+    nsCOMPtr<nsIDOMDocument> domDoc;
+    aParent->GetDocument(getter_AddRefs(domDoc));
+    if (!domDoc) {
+      NS_ERROR("Could retrieve document from nsIBaseWindow");
+      return NS_ERROR_FAILURE;
+    }
+
+    nsCOMPtr<nsIDocument> doc;
+    doc = do_QueryInterface(domDoc);
+    if (!doc) {
+      NS_ERROR("Document from nsIBaseWindow didn't QI to nsIDocument");
+      return NS_ERROR_FAILURE;
+    }
+
+    nsCOMPtr<nsIURI> baseURI = doc->GetDocBaseURI();
+    if (!baseURI) {
+      NS_ERROR("nsIDocument didn't return a base URI");
+      return NS_ERROR_FAILURE;
+    }
+
+    nsAutoCString baseURIString;
+    baseURI->GetSpec(baseURIString);
+
+    nsAutoString nameString;
+    nameString.Assign(aName);
+    nsAutoCString features;
+
+    // We can assume that if content is requesting to open a window from a remote
+    // tab, then we want to enforce that the new window is also a remote tab.
+    features.Assign(aFeatures);
+    features.Append(",remote");
+
+    if (!CallCreateWindow(aChromeFlags, aCalledFromJS, aPositionSpecified,
+                          aSizeSpecified, NS_ConvertUTF8toUTF16(uriString),
+                          nameString, NS_ConvertUTF8toUTF16(features),
+                          NS_ConvertUTF8toUTF16(baseURIString),
+                          aWindowIsNew, &newChild)) {
         return NS_ERROR_NOT_AVAILABLE;
     }
 
-    *aWindowIsNew = true;
     nsCOMPtr<nsIDOMWindow> win =
         do_GetInterface(static_cast<TabChild*>(newChild)->WebNavigation());
     win.forget(aReturn);
     return NS_OK;
 }
 
 nsresult
 TabChild::BrowserFrameProvideWindow(nsIDOMWindow* aOpener,
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -39,25 +39,28 @@
 #include "nsIDOMElement.h"
 #include "nsIDOMEvent.h"
 #include "nsIDOMWindow.h"
 #include "nsIDOMWindowUtils.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIPromptFactory.h"
 #include "nsIURI.h"
 #include "nsIWebBrowserChrome.h"
+#include "nsIWindowCreator2.h"
 #include "nsIXULBrowserWindow.h"
 #include "nsIXULWindow.h"
 #include "nsViewManager.h"
 #include "nsIWidget.h"
 #include "nsIWindowWatcher.h"
 #include "nsPIDOMWindow.h"
+#include "nsPIWindowWatcher.h"
 #include "nsPrintfCString.h"
 #include "nsServiceManagerUtils.h"
 #include "nsThreadUtils.h"
+#include "nsWindowWatcher.h"
 #include "private/pprio.h"
 #include "PermissionMessageUtils.h"
 #include "StructuredCloneUtils.h"
 #include "ColorPickerParent.h"
 #include "JavaScriptParent.h"
 #include "FilePickerParent.h"
 #include "TabChild.h"
 #include "LoadContext.h"
@@ -383,45 +386,105 @@ TabParent::RecvEvent(const RemoteDOMEven
   event->SetOwner(target);
 
   bool dummy;
   target->DispatchEvent(event, &dummy);
   return true;
 }
 
 bool
-TabParent::AnswerCreateWindow(PBrowserParent** retval)
+TabParent::AnswerCreateWindow(const uint32_t& aChromeFlags,
+                              const bool& aCalledFromJS,
+                              const bool& aPositionSpecified,
+                              const bool& aSizeSpecified,
+                              const nsString& aURI,
+                              const nsString& aName,
+                              const nsString& aFeatures,
+                              const nsString& aBaseURI,
+                              bool* aWindowIsNew,
+                              PBrowserParent** aRetVal)
 {
-    if (!mBrowserDOMWindow) {
-        return false;
-    }
+  if (IsBrowserOrApp()) {
+    return false;
+  }
+
+  nsresult rv;
+  nsCOMPtr<nsPIWindowWatcher> pwwatch =
+    do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
+  NS_ENSURE_SUCCESS(rv, false);
 
-    // Only non-app, non-browser processes may call CreateWindow.
-    if (IsBrowserOrApp()) {
-        return false;
-    }
+  nsCOMPtr<nsIContent> frame(do_QueryInterface(mFrameElement));
+  NS_ENSURE_TRUE(frame, false);
+
+  nsCOMPtr<nsIDOMWindow> parent = do_QueryInterface(frame->OwnerDoc()->GetWindow());
+  NS_ENSURE_TRUE(parent, false);
+
+  int32_t openLocation =
+    nsWindowWatcher::GetWindowOpenLocation(parent, aChromeFlags, aCalledFromJS,
+                                           aPositionSpecified, aSizeSpecified);
 
-    // Get a new rendering area from the browserDOMWin.  We don't want
-    // to be starting any loads here, so get it with a null URI.
+  MOZ_ASSERT(openLocation == nsIBrowserDOMWindow::OPEN_NEWTAB ||
+             openLocation == nsIBrowserDOMWindow::OPEN_NEWWINDOW);
+
+  *aWindowIsNew = true;
+
+  // Opening new tabs is the easy case...
+  if (openLocation == nsIBrowserDOMWindow::OPEN_NEWTAB) {
+    NS_ENSURE_TRUE(mBrowserDOMWindow, false);
+
     nsCOMPtr<nsIFrameLoaderOwner> frameLoaderOwner;
     mBrowserDOMWindow->OpenURIInFrame(nullptr, nullptr,
                                       nsIBrowserDOMWindow::OPEN_NEWTAB,
                                       nsIBrowserDOMWindow::OPEN_NEW,
                                       getter_AddRefs(frameLoaderOwner));
-    if (!frameLoaderOwner) {
-        return false;
-    }
+    NS_ENSURE_TRUE(frameLoaderOwner, false);
 
     nsRefPtr<nsFrameLoader> frameLoader = frameLoaderOwner->GetFrameLoader();
-    if (!frameLoader) {
-        return false;
-    }
+    NS_ENSURE_TRUE(frameLoader, false);
+
+    *aRetVal = frameLoader->GetRemoteBrowser();
+    return true;
+  }
+
+  // WindowWatcher is going to expect a valid URI to open a window
+  // to. If it can't find one, it's going to attempt to figure one
+  // out on its own, which is problematic because it can't access
+  // the document for the remote browser we're opening. Luckily,
+  // TabChild has sent us a baseURI with which we can ensure that
+  // the URI we pass to WindowWatcher is valid.
+  nsCOMPtr<nsIURI> baseURI;
+  rv = NS_NewURI(getter_AddRefs(baseURI), aBaseURI);
+  NS_ENSURE_SUCCESS(rv, false);
+
+  nsCOMPtr<nsIURI> finalURI;
+  rv = NS_NewURI(getter_AddRefs(finalURI), NS_ConvertUTF16toUTF8(aURI).get(), baseURI);
+  NS_ENSURE_SUCCESS(rv, false);
 
-    *retval = frameLoader->GetRemoteBrowser();
-    return true;
+  nsAutoCString finalURIString;
+  finalURI->GetSpec(finalURIString);
+
+  nsCOMPtr<nsIDOMWindow> window;
+
+  rv = pwwatch->OpenWindow2(parent, finalURIString.get(),
+                            NS_ConvertUTF16toUTF8(aName).get(),
+                            NS_ConvertUTF16toUTF8(aFeatures).get(), aCalledFromJS,
+                            false, false, this, nullptr, getter_AddRefs(window));
+  NS_ENSURE_SUCCESS(rv, false);
+
+  nsCOMPtr<nsPIDOMWindow> pwindow = do_QueryInterface(window);
+  NS_ENSURE_TRUE(pwindow, false);
+
+  nsRefPtr<nsIDocShell> newDocShell = pwindow->GetDocShell();
+  NS_ENSURE_TRUE(newDocShell, false);
+
+  nsCOMPtr<nsITabParent> newRemoteTab = newDocShell->GetOpenedRemote();
+  NS_ENSURE_TRUE(newRemoteTab, false);
+
+  *aRetVal = static_cast<TabParent*>(newRemoteTab.get());
+  return true;
 }
 
 void
 TabParent::LoadURL(nsIURI* aURI)
 {
     MOZ_ASSERT(aURI);
 
     if (mIsDestroyed) {
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -122,17 +122,26 @@ public:
                                              TextureFactoryIdentifier* aFactoryIdentifier,
                                              uint64_t* aLayersId,
                                              bool* aSuccess) MOZ_OVERRIDE;
     virtual bool RecvBrowserFrameOpenWindow(PBrowserParent* aOpener,
                                             const nsString& aURL,
                                             const nsString& aName,
                                             const nsString& aFeatures,
                                             bool* aOutWindowOpened) MOZ_OVERRIDE;
-    virtual bool AnswerCreateWindow(PBrowserParent** retval) MOZ_OVERRIDE;
+    virtual bool AnswerCreateWindow(const uint32_t& aChromeFlags,
+                                    const bool& aCalledFromJS,
+                                    const bool& aPositionSpecified,
+                                    const bool& aSizeSpecified,
+                                    const nsString& aURI,
+                                    const nsString& aName,
+                                    const nsString& aFeatures,
+                                    const nsString& aBaseURI,
+                                    bool* aWindowIsNew,
+                                    PBrowserParent** aRetVal) MOZ_OVERRIDE;
     virtual bool RecvSyncMessage(const nsString& aMessage,
                                  const ClonedMessageData& aData,
                                  const InfallibleTArray<CpowEntry>& aCpows,
                                  const IPC::Principal& aPrincipal,
                                  InfallibleTArray<nsString>* aJSONRetVal) MOZ_OVERRIDE;
     virtual bool AnswerRpcMessage(const nsString& aMessage,
                                   const ClonedMessageData& aData,
                                   const InfallibleTArray<CpowEntry>& aCpows,
--- a/dom/tests/browser/browser.ini
+++ b/dom/tests/browser/browser.ini
@@ -16,16 +16,21 @@ support-files =
 [browser_autofocus_background.js]
 [browser_autofocus_preference.js]
 [browser_bug396843.js]
 [browser_focus_steal_from_chrome.js]
 [browser_focus_steal_from_chrome_during_mousedown.js]
 [browser_frame_elements.js]
 [browser_geolocation_privatebrowsing_perwindowpb.js]
 [browser_localStorage_privatestorageevent.js]
+[browser_test_new_window_from_content.js]
+skip-if = (toolkit == 'android' || buildapp == 'b2g')
+support-files =
+  test_new_window_from_content_child.html
+  test_new_window_from_content_child.js
 [browser_webapps_permissions.js]
 # TODO: Re-enable permissions tests on Mac, bug 795334
 skip-if = buildapp != "b2g"
 support-files =
   test-webapp.webapp
   test-webapp-reinstall.webapp
   test-webapp-original.webapp
   test-webapps-permissions.html
new file mode 100644
--- /dev/null
+++ b/dom/tests/browser/browser_test_new_window_from_content.js
@@ -0,0 +1,340 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+/*
+  We have three ways for content to open new windows:
+     1) window.open (with the default features)
+     2) window.open (with non-default features)
+     3) target="_blank" in <a> tags
+
+     We also have two prefs that modify our window opening behaviours:
+
+     1) browser.link.open_newwindow
+
+        This has a numeric value that allows us to set our window-opening behaviours from
+        content in three ways:
+        1) Open links that would normally open a new window in the current tab
+        2) Open links that would normally open a new window in a new window
+        3) Open links that would normally open a new window in a new tab (default)
+
+     2) browser.link.open_newwindow.restriction
+
+        This has a numeric value that allows us to fine tune the browser.link.open_newwindow
+        pref so that it can discriminate between different techniques for opening windows.
+
+        0) All things that open windows should behave according to browser.link.open_newwindow.
+        1) No things that open windows should behave according to browser.link.open_newwindow
+           (essentially rendering browser.link.open_newwindow inert).
+        2) Most things that open windows should behave according to browser.link.open_newwindow,
+           _except_ for window.open calls with the "feature" parameter. This will open in a new
+           window regardless of what browser.link.open_newwindow is set at. (default)
+
+     This file attempts to test each window opening technique against all possible settings for
+     each preference.
+*/
+
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/Promise.jsm");
+Cu.import("resource://gre/modules/Task.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+const kXULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+const kContentDoc = "http://www.example.com/browser/dom/tests/browser/test_new_window_from_content_child.html";
+const kContentScript = "chrome://mochitests/content/browser/dom/tests/browser/test_new_window_from_content_child.js";
+const kNewWindowPrefKey = "browser.link.open_newwindow";
+const kNewWindowRestrictionPrefKey = "browser.link.open_newwindow.restriction";
+const kSameTab = "same tab";
+const kNewWin = "new window";
+const kNewTab = "new tab";
+
+// The following "matrices" represent the result of content attempting to
+// open a window with window.open with the default feature set. The key of
+// the kWinOpenDefault object represents the value of browser.link.open_newwindow.
+// The value for each key is an array that represents the result (either opening
+// the link in the same tab, a new window, or a new tab), where the index of each
+// result maps to the browser.link.open_newwindow.restriction pref. I've tried
+// to illustrate this more clearly in the kWinOpenDefault object.
+const kWinOpenDefault = {
+//                    open_newwindow.restriction
+//                    0         1        2
+// open_newwindow
+                  1: [kSameTab, kNewWin, kSameTab],
+                  2: [kNewWin, kNewWin, kNewWin],
+                  3: [kNewTab, kNewWin, kNewTab],
+};
+
+const kWinOpenNonDefault = {
+  1: [kSameTab, kNewWin, kNewWin],
+  2: [kNewWin, kNewWin, kNewWin],
+  3: [kNewTab, kNewWin, kNewWin],
+};
+
+const kTargetBlank = {
+  1: [kSameTab, kSameTab, kSameTab],
+  2: [kNewWin, kNewWin, kNewWin],
+  3: [kNewTab, kNewTab, kNewTab],
+};
+
+// We'll be changing these preferences a lot, so we'll stash their original
+// values and make sure we restore them at the end of the test.
+let originalNewWindowPref = Services.prefs.getIntPref(kNewWindowPrefKey);
+let originalNewWindowRestrictionPref =
+  Services.prefs.getIntPref(kNewWindowRestrictionPrefKey);
+
+registerCleanupFunction(function() {
+  Services.prefs.setIntPref(kNewWindowPrefKey, originalNewWindowPref);
+  Services.prefs.setIntPref(kNewWindowRestrictionPrefKey,
+                            originalNewWindowRestrictionPref);
+  // If there are any content tabs leftover, make sure they're not going to
+  // block exiting with onbeforeunload.
+  for (let tab of gBrowser.tabs) {
+    let browser = gBrowser.getBrowserForTab(tab);
+    if (browser.contentDocument.location == kContentDoc) {
+      closeTab(tab);
+    }
+  }
+});
+
+/**
+ * WindowOpenListener is a very simple nsIWindowMediatorListener that
+ * listens for a new window opening to aExpectedURI. It has two Promises
+ * attached to it - openPromise and closePromise. As you'd expect,
+ * openPromise resolves when the window is opened, and closePromise
+ * resolves if and when a window with the same URI closes. There is
+ * no attempt to make sure that it's the same window opening and
+ * closing - we just use the URI.
+ *
+ * @param aExpectedURI the URI to watch for in a new window.
+ * @return nsIWindowMediatorListener
+ */
+function WindowOpenListener(aExpectedURI) {
+  this._openDeferred = Promise.defer();
+  this._closeDeferred = Promise.defer();
+  this._expectedURI = aExpectedURI;
+}
+
+WindowOpenListener.prototype = {
+  get openPromise() {
+    return this._openDeferred.promise;
+  },
+
+  get closePromise() {
+    return this._closeDeferred.promise;
+  },
+
+  onOpenWindow: function(aXULWindow) {
+    let domWindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor)
+                              .getInterface(Ci.nsIDOMWindow);
+    let location = domWindow.document.location;
+    if (location == this._expectedURI) {
+      let deferred = this._openDeferred;
+      domWindow.addEventListener("load", function onWindowLoad() {
+        domWindow.removeEventListener("load", onWindowLoad);
+        deferred.resolve(domWindow);
+      })
+    }
+  },
+
+  onCloseWindow: function(aXULWindow) {
+    this._closeDeferred.resolve();
+  },
+  onWindowTitleChange: function(aXULWindow, aNewTitle) {},
+
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIWindowMediatorListener])
+};
+
+/**
+ * Adds the testing tab, and injects our frame script which
+ * allows us to send click events to links and other things.
+ *
+ * @return a Promise that resolves once the tab is loaded and ready.
+ */
+function loadAndSelectTestTab() {
+  let tab = gBrowser.addTab(kContentDoc);
+  gBrowser.selectedTab = tab;
+
+  let browser = gBrowser.getBrowserForTab(tab);
+
+  // Bug 687194 - Mochitest registers its chrome URLs after browser
+  // initialization, so the content processes don't pick them up. That
+  // means we can't load our frame script from its chrome URI, because
+  // the content process won't be able to find it.
+  //
+  // Instead, we resolve the chrome URI for the script to a file URI, which
+  // we can then pass to the content process, which it is able to find.
+  let registry = Cc['@mozilla.org/chrome/chrome-registry;1'].getService(Ci.nsIChromeRegistry);
+  let fileURI = registry.convertChromeURL(Services.io.newURI(kContentScript, null, null)).spec;
+  browser.messageManager.loadFrameScript(fileURI, false);
+
+  let deferred = Promise.defer();
+  browser.addEventListener("DOMContentLoaded", function onBrowserLoad(aEvent) {
+    browser.removeEventListener("DOMContentLoaded", onBrowserLoad);
+    deferred.resolve(tab);
+  });
+
+  return deferred.promise;
+}
+
+/**
+ * Clears the onbeforeunload event handler from the testing tab,
+ * and then closes the tab.
+ *
+ * @param aTab the testing tab to close.
+ * @param a Promise that resolves once the tab has been closed.
+ */
+function closeTab(aTab) {
+  let deferred = Promise.defer();
+  let browserMM = gBrowser.getBrowserForTab(aTab).messageManager;
+  browserMM.sendAsyncMessage("TEST:allow-unload");
+  browserMM.addMessageListener("TEST:allow-unload:done", function(aMessage) {
+    gBrowser.removeTab(aTab);
+    deferred.resolve();
+  })
+  return deferred.promise;
+}
+
+/**
+ * Sends a click event on some item into a tab.
+ *
+ * @param aTab the tab to send the click event to
+ * @param aItemId the item within the tab content to click.
+ */
+function clickInTab(aTab, aItemId) {
+  let browserMM = gBrowser.getBrowserForTab(aTab).messageManager;
+  browserMM.sendAsyncMessage("TEST:click-item", {
+    details: aItemId,
+  });
+}
+
+/**
+ * For some expectation when a link is clicked, creates and
+ * returns a Promise that resolves when that expectation is
+ * fulfilled. For example, aExpectation might be kSameTab, which
+ * will cause this function to return a Promise that resolves when
+ * the current tab attempts to browse to about:blank.
+ *
+ * This function also takes care of cleaning up once the result has
+ * occurred - for example, if a new window was opened, this function
+ * closes it before resolving.
+ *
+ * @param aTab the tab with the test document
+ * @param aExpectation one of kSameTab, kNewWin, or kNewTab.
+ * @return a Promise that resolves when the expectation is fulfilled,
+ *         and cleaned up after.
+ */
+function prepareForResult(aTab, aExpectation) {
+  let deferred = Promise.defer();
+  let browser = gBrowser.getBrowserForTab(aTab);
+
+  switch(aExpectation) {
+    case kSameTab:
+      // We expect about:blank to be loaded in the current tab. In order
+      // to prevent us needing to reload the document and content script
+      // after browsing away, we'll detect the attempt by using onbeforeunload,
+      // and then cancel the unload. It's a hack, but it's also a pretty
+      // cheap way of detecting when we're browsing away in the test tab.
+      // The onbeforeunload event handler is set in the content script automatically.
+      browser.addEventListener("DOMWillOpenModalDialog", function onModalDialog() {
+        browser.removeEventListener("DOMWillOpenModalDialog", onModalDialog, true);
+        executeSoon(() => {
+          let stack = browser.parentNode;
+          let dialogs = stack.getElementsByTagNameNS(kXULNS, "tabmodalprompt");
+          dialogs[0].ui.button1.click()
+          deferred.resolve();
+        })
+      }, true);
+      break;
+    case kNewWin:
+      let listener = new WindowOpenListener("about:blank");
+      Services.wm.addListener(listener);
+
+      info("Waiting for a new about:blank window");
+      listener.openPromise.then(function(aWindow) {
+        info("Got the new about:blank window - closing it.");
+        executeSoon(() => {
+          aWindow.close();
+        });
+        listener.closePromise.then(() => {
+          info("New about:blank window closed!");
+          Services.wm.removeListener(listener);
+          deferred.resolve();
+        });
+      });
+      break;
+    case kNewTab:
+      gBrowser.tabContainer.addEventListener("TabOpen", function onTabOpen(aEvent) {
+        let newTab = aEvent.target;
+        let newBrowser = gBrowser.getBrowserForTab(newTab);
+        if (newBrowser.contentDocument.location.href == "about:blank") {
+          gBrowser.tabContainer.removeEventListener("TabOpen", onTabOpen);
+          executeSoon(() => {
+            gBrowser.removeTab(newTab);
+            deferred.resolve();
+          })
+        }
+      })
+      break;
+    default:
+      ok(false, "prepareForResult can't handle an expectation of " + aExpectation)
+      return;
+  }
+
+  return deferred.promise;
+}
+
+/**
+ * Ensure that clicks on a link with ID aLinkID cause us to
+ * perform as specified in the supplied aMatrix (kWinOpenDefault,
+ * for example).
+ *
+ * @param aLinkId the id of the link within the testing page to test.
+ * @param aMatrix a testing matrix for the
+ *        browser.link.open_newwindow and browser.link.open_newwindow.restriction
+ *        prefs to test against. See kWinOpenDefault for an example.
+ */
+function testLinkWithMatrix(aLinkId, aMatrix) {
+  return Task.spawn(function* () {
+    let tab = yield loadAndSelectTestTab();
+    // This nested for-loop is unravelling the matrix const
+    // we set up, and gives us three things through each tick
+    // of the inner loop:
+    // 1) newWindowPref: a browser.link.open_newwindow pref to try
+    // 2) newWindowRestPref: a browser.link.open_newwindow.restriction pref to try
+    // 3) expectation: what we expect the click outcome on this link to be,
+    //                 which will either be kSameTab, kNewWin or kNewTab.
+
+    for (let newWindowPref in aMatrix) {
+      let expectations = aMatrix[newWindowPref];
+      for (let i = 0; i < expectations.length; ++i) {
+        let newWindowRestPref = i;
+        let expectation = expectations[i];
+
+        Services.prefs.setIntPref("browser.link.open_newwindow", newWindowPref);
+        Services.prefs.setIntPref("browser.link.open_newwindow.restriction", newWindowRestPref);
+        info("Clicking on " + aLinkId);
+        info("Testing with browser.link.open_newwindow = " + newWindowPref + " and " +
+             "browser.link.open_newwindow.restriction = " + newWindowRestPref);
+        info("Expecting: " + expectation);
+        let resultPromise = prepareForResult(tab, expectation);
+        clickInTab(tab, aLinkId);
+        yield resultPromise;
+        ok(true, "Got expectation: " + expectation);
+      }
+    }
+    yield closeTab(tab);
+  });
+}
+
+add_task(function* test_window_open_with_defaults() {
+  yield testLinkWithMatrix("winOpenDefault", kWinOpenDefault);
+});
+
+add_task(function* test_window_open_with_non_defaults() {
+  yield testLinkWithMatrix("winOpenNonDefault", kWinOpenNonDefault);
+});
+
+add_task(function* test_target__blank() {
+  yield testLinkWithMatrix("targetBlank", kTargetBlank);
+});
new file mode 100644
--- /dev/null
+++ b/dom/tests/browser/test_new_window_from_content_child.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<head>
+  <meta charset="utf-8">
+  <title>Test popup window opening behaviour</title>
+</head>
+<body>
+  <p><a id="winOpenDefault" href="#" onclick="return openWindow();">Open a new window via window.open with default features.</a></p>
+  <p><a id="winOpenNonDefault" href="#" onclick="return openWindow('resizable=no, toolbar=no, scrollbars=no, menubar=no, status=no, directories=no, height=100, width=500');">Open a new window via window.open with non-default features.</a></p>
+  <p><a id="targetBlank" href="about:blank" target="_blank">Open a new window via target="_blank".</a></p>
+</body>
+</html>
+
+<script>
+function openWindow(aFeatures="") {
+  window.open("about:blank", "_blank", aFeatures);
+  return false;
+}
+
+window.onbeforeunload = function(aEvent) {
+  return "We should not browse away from this document.";
+}
+
+</script>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/dom/tests/browser/test_new_window_from_content_child.js
@@ -0,0 +1,19 @@
+// A hacky mechanism for catching and detecting that we're attempting
+// to browse away is by setting the onbeforeunload event handler. We
+// detect this dialog opening in the parent test script, and dismiss
+// it.
+
+function handleClickItem(aMessage) {
+  let itemId = aMessage.data.details;
+  content.console.log("Getting item with ID: " + itemId);
+  let item = content.document.getElementById(itemId);
+  item.click();
+}
+
+function handleAllowUnload(aMessage) {
+  content.onbeforeunload = null;
+  sendSyncMessage("TEST:allow-unload:done");
+}
+
+addMessageListener("TEST:click-item", handleClickItem);
+addMessageListener("TEST:allow-unload", handleAllowUnload);
\ No newline at end of file
--- a/dom/webidl/XPathEvaluator.webidl
+++ b/dom/webidl/XPathEvaluator.webidl
@@ -1,23 +1,22 @@
 /* -*- 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/.
  */
 
 interface XPathExpression;
 interface XPathNSResolver;
-interface XPathResult;
 
 [Constructor]
 interface XPathEvaluator {
   // Based on nsIDOMXPathEvaluator
   [NewObject, Throws]
   XPathExpression createExpression(DOMString expression,
                                    XPathNSResolver? resolver);
   [NewObject, Throws]
   XPathNSResolver createNSResolver(Node? nodeResolver);
   [Throws]
   XPathResult evaluate(DOMString expression, Node? contextNode,
                        XPathNSResolver? resolver, unsigned short type,
-                       XPathResult? result);
+                       object? result);
 };
new file mode 100644
--- /dev/null
+++ b/dom/webidl/XPathResult.webidl
@@ -0,0 +1,38 @@
+/* -*- 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/.
+ *
+ * Corresponds to http://www.w3.org/TR/2002/WD-DOM-Level-3-XPath-20020208
+ */
+
+interface XPathResult {
+  // XPathResultType
+  const unsigned short ANY_TYPE = 0;
+  const unsigned short NUMBER_TYPE = 1;
+  const unsigned short STRING_TYPE = 2;
+  const unsigned short BOOLEAN_TYPE = 3;
+  const unsigned short UNORDERED_NODE_ITERATOR_TYPE = 4;
+  const unsigned short ORDERED_NODE_ITERATOR_TYPE = 5;
+  const unsigned short UNORDERED_NODE_SNAPSHOT_TYPE = 6;
+  const unsigned short ORDERED_NODE_SNAPSHOT_TYPE = 7;
+  const unsigned short ANY_UNORDERED_NODE_TYPE = 8;
+  const unsigned short FIRST_ORDERED_NODE_TYPE = 9;
+
+  readonly attribute unsigned short resultType;
+  [Throws]
+  readonly attribute double numberValue;
+  [Throws]
+  readonly attribute DOMString stringValue;
+  [Throws]
+  readonly attribute boolean booleanValue;
+  [Throws]
+  readonly attribute Node? singleNodeValue;
+  readonly attribute boolean invalidIteratorState;
+  [Throws]
+  readonly attribute unsigned long snapshotLength;
+  [Throws]
+  Node? iterateNext();
+  [Throws]
+  Node? snapshotItem(unsigned long index);
+};
--- a/dom/webidl/moz.build
+++ b/dom/webidl/moz.build
@@ -474,16 +474,17 @@ WEBIDL_FILES = [
     'WorkerNavigator.webidl',
     'XMLDocument.webidl',
     'XMLHttpRequest.webidl',
     'XMLHttpRequestEventTarget.webidl',
     'XMLHttpRequestUpload.webidl',
     'XMLSerializer.webidl',
     'XMLStylesheetProcessingInstruction.webidl',
     'XPathEvaluator.webidl',
+    'XPathResult.webidl',
     'XULCommandEvent.webidl',
     'XULDocument.webidl',
     'XULElement.webidl',
 ]
 
 if CONFIG['MOZ_AUDIO_CHANNEL_MANAGER']:
     WEBIDL_FILES += [
         'AudioChannelManager.webidl',
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -3130,20 +3130,21 @@ WorkerPrivateParent<Derived>::BroadcastE
   for (size_t index = 0; index < sharedWorkers.Length(); index++) {
     nsRefPtr<SharedWorker>& sharedWorker = sharedWorkers[index];
 
     // May be null.
     nsPIDOMWindow* window = sharedWorker->GetOwner();
 
     size_t actionsIndex = windowActions.LastIndexOf(WindowAction(window));
 
-    nsIGlobalObject* global = sharedWorker->GetParentObject();
-    AutoJSAPIWithErrorsReportedToWindow jsapi(global);
+    AutoJSAPI jsapi;
+    if (NS_WARN_IF(!jsapi.InitWithLegacyErrorReportingUsingWin(sharedWorker->GetOwner()))) {
+      continue;
+    }
     JSContext* cx = jsapi.cx();
-    JSAutoCompartment ac(cx, global->GetGlobalJSObject());
 
     RootedDictionary<ErrorEventInit> errorInit(aCx);
     errorInit.mBubbles = false;
     errorInit.mCancelable = true;
     errorInit.mMessage = aMessage;
     errorInit.mFilename = aFilename;
     errorInit.mLineno = aLineNumber;
     errorInit.mColno = aColumnNumber;
--- a/dom/xbl/XBLChildrenElement.cpp
+++ b/dom/xbl/XBLChildrenElement.cpp
@@ -98,18 +98,18 @@ nsAnonymousContentList::GetLength(uint32
   }
 
   uint32_t count = 0;
   for (nsIContent* child = mParent->GetFirstChild();
        child;
        child = child->GetNextSibling()) {
     if (child->NodeInfo()->Equals(nsGkAtoms::children, kNameSpaceID_XBL)) {
       XBLChildrenElement* point = static_cast<XBLChildrenElement*>(child);
-      if (!point->mInsertedChildren.IsEmpty()) {
-        count += point->mInsertedChildren.Length();
+      if (point->HasInsertedChildren()) {
+        count += point->InsertedChildrenLength();
       }
       else {
         count += point->GetChildCount();
       }
     }
     else {
       ++count;
     }
@@ -139,21 +139,21 @@ nsAnonymousContentList::Item(uint32_t aI
   }
 
   uint32_t remIndex = aIndex;
   for (nsIContent* child = mParent->GetFirstChild();
        child;
        child = child->GetNextSibling()) {
     if (child->NodeInfo()->Equals(nsGkAtoms::children, kNameSpaceID_XBL)) {
       XBLChildrenElement* point = static_cast<XBLChildrenElement*>(child);
-      if (!point->mInsertedChildren.IsEmpty()) {
-        if (remIndex < point->mInsertedChildren.Length()) {
-          return point->mInsertedChildren[remIndex];
+      if (point->HasInsertedChildren()) {
+        if (remIndex < point->InsertedChildrenLength()) {
+          return point->InsertedChild(remIndex);
         }
-        remIndex -= point->mInsertedChildren.Length();
+        remIndex -= point->InsertedChildrenLength();
       }
       else {
         if (remIndex < point->GetChildCount()) {
           return point->GetChildAt(remIndex);
         }
         remIndex -= point->GetChildCount();
       }
     }
@@ -174,33 +174,33 @@ nsAnonymousContentList::IndexOf(nsIConte
   NS_ASSERTION(!aContent->NodeInfo()->Equals(nsGkAtoms::children,
                                              kNameSpaceID_XBL),
                "Looking for insertion point");
 
   if (!mParent) {
     return -1;
   }
 
-  size_t index = 0;
+  int32_t index = 0;
   for (nsIContent* child = mParent->GetFirstChild();
        child;
        child = child->GetNextSibling()) {
     if (child->NodeInfo()->Equals(nsGkAtoms::children, kNameSpaceID_XBL)) {
       XBLChildrenElement* point = static_cast<XBLChildrenElement*>(child);
-      if (!point->mInsertedChildren.IsEmpty()) {
-        size_t insIndex = point->mInsertedChildren.IndexOf(aContent);
-        if (insIndex != point->mInsertedChildren.NoIndex) {
+      if (point->HasInsertedChildren()) {
+        int32_t insIndex = point->IndexOfInsertedChild(aContent);
+        if (insIndex != -1) {
           return index + insIndex;
         }
-        index += point->mInsertedChildren.Length();
+        index += point->InsertedChildrenLength();
       }
       else {
         int32_t insIndex = point->IndexOf(aContent);
         if (insIndex != -1) {
-          return index + (size_t)insIndex;
+          return index + insIndex;
         }
         index += point->GetChildCount();
       }
     }
     else {
       if (child == aContent) {
         return index;
       }
--- a/dom/xbl/XBLChildrenElement.h
+++ b/dom/xbl/XBLChildrenElement.h
@@ -17,18 +17,16 @@ class nsAnonymousContentList;
 namespace mozilla {
 namespace dom {
 
 class ExplicitChildIterator;
 
 class XBLChildrenElement : public nsXMLElement
 {
 public:
-  friend class mozilla::dom::ExplicitChildIterator;
-  friend class nsAnonymousContentList;
   XBLChildrenElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
     : nsXMLElement(aNodeInfo)
   {
   }
   XBLChildrenElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
     : nsXMLElement(aNodeInfo)
   {
   }
@@ -110,39 +108,40 @@ public:
     return mInsertedChildren.Length();
   }
 
   bool HasInsertedChildren()
   {
     return !mInsertedChildren.IsEmpty();
   }
 
-  enum {
-    NoIndex = uint32_t(-1)
-  };
-  uint32_t IndexOfInsertedChild(nsIContent* aChild)
+  int32_t IndexOfInsertedChild(nsIContent* aChild)
   {
     return mInsertedChildren.IndexOf(aChild);
   }
 
   bool Includes(nsIContent* aChild)
   {
     NS_ASSERTION(!mIncludes.IsEmpty(),
                  "Shouldn't check for includes on default insertion point");
     return mIncludes.Contains(aChild->Tag());
   }
 
   bool IsDefaultInsertion()
   {
     return mIncludes.IsEmpty();
   }
 
-  nsTArray<nsIContent*> mInsertedChildren;
+  nsIContent* InsertedChild(uint32_t aIndex)
+  {
+    return mInsertedChildren[aIndex];
+  }
 
 private:
+  nsTArray<nsIContent*> mInsertedChildren; // WEAK
   nsTArray<nsCOMPtr<nsIAtom> > mIncludes;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 class nsAnonymousContentList : public nsINodeList
 {
--- a/dom/xbl/nsBindingManager.cpp
+++ b/dom/xbl/nsBindingManager.cpp
@@ -808,51 +808,51 @@ nsBindingManager::MediumFeaturesChanged(
   set->EnumerateEntries(EnumMediumFeaturesChanged, &data);
   return NS_OK;
 }
 
 static PLDHashOperator
 EnumAppendAllSheets(nsRefPtrHashKey<nsIContent> *aKey, void* aClosure)
 {
   nsIContent *boundContent = aKey->GetKey();
-  nsTArray<nsCSSStyleSheet*>* array =
-    static_cast<nsTArray<nsCSSStyleSheet*>*>(aClosure);
+  nsTArray<CSSStyleSheet*>* array =
+    static_cast<nsTArray<CSSStyleSheet*>*>(aClosure);
   for (nsXBLBinding *binding = boundContent->GetXBLBinding(); binding;
        binding = binding->GetBaseBinding()) {
     binding->PrototypeBinding()->AppendStyleSheetsTo(*array);
   }
   return PL_DHASH_NEXT;
 }
 
 void
-nsBindingManager::AppendAllSheets(nsTArray<nsCSSStyleSheet*>& aArray)
+nsBindingManager::AppendAllSheets(nsTArray<CSSStyleSheet*>& aArray)
 {
   if (mBoundContentSet) {
     mBoundContentSet->EnumerateEntries(EnumAppendAllSheets, &aArray);
   }
 }
 
 static void
 InsertAppendedContent(XBLChildrenElement* aPoint,
                       nsIContent* aFirstNewContent)
 {
-  size_t insertionIndex;
+  int32_t insertionIndex;
   if (nsIContent* prevSibling = aFirstNewContent->GetPreviousSibling()) {
     // If we have a previous sibling, then it must already be in aPoint. Find
     // it and insert after it.
     insertionIndex = aPoint->IndexOfInsertedChild(prevSibling);
-    MOZ_ASSERT(insertionIndex != aPoint->NoIndex);
+    MOZ_ASSERT(insertionIndex != -1);
 
     // Our insertion index is one after our previous sibling's index.
     ++insertionIndex;
   } else {
     // Otherwise, we append.
     // TODO This is wrong for nested insertion points. In that case, we need to
     // keep track of the right index to insert into.
-    insertionIndex = aPoint->mInsertedChildren.Length();
+    insertionIndex = aPoint->InsertedChildrenLength();
   }
 
   // Do the inserting.
   for (nsIContent* currentChild = aFirstNewContent;
        currentChild;
        currentChild = currentChild->GetNextSibling()) {
     aPoint->InsertInsertedChildAt(currentChild, insertionIndex++);
   }
@@ -1072,25 +1072,25 @@ nsBindingManager::HandleChildInsertion(n
     if (!point) {
       break;
     }
 
     // Insert the child into the proper insertion point.
     // TODO If there were multiple insertion points, this approximation can be
     // wrong. We need to re-run the distribution algorithm. In the meantime,
     // this should work well enough.
-    size_t index = aAppend ? point->mInsertedChildren.Length() : 0;
+    uint32_t index = aAppend ? point->InsertedChildrenLength() : 0;
     for (nsIContent* currentSibling = aChild->GetPreviousSibling();
          currentSibling;
          currentSibling = currentSibling->GetPreviousSibling()) {
       // If we find one of our previous siblings in the insertion point, the
       // index following it is the correct insertion point. Otherwise, we guess
       // based on whether we're appending or inserting.
-      size_t pointIndex = point->IndexOfInsertedChild(currentSibling);
-      if (pointIndex != point->NoIndex) {
+      int32_t pointIndex = point->IndexOfInsertedChild(currentSibling);
+      if (pointIndex != -1) {
         index = pointIndex + 1;
         break;
       }
     }
 
     point->InsertInsertedChildAt(aChild, index);
 
     nsIContent* newParent = point->GetParent();
--- a/dom/xbl/nsBindingManager.h
+++ b/dom/xbl/nsBindingManager.h
@@ -25,17 +25,20 @@ class nsIDocument;
 class nsIURI;
 class nsXBLDocumentInfo;
 class nsIStreamListener;
 class nsStyleSet;
 class nsXBLBinding;
 template<class E> class nsRefPtr;
 typedef nsTArray<nsRefPtr<nsXBLBinding> > nsBindingList;
 class nsIPrincipal;
-class nsCSSStyleSheet;
+
+namespace mozilla {
+class CSSStyleSheet;
+} // namespace mozilla
 
 class nsBindingManager MOZ_FINAL : public nsStubMutationObserver
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
@@ -111,17 +114,17 @@ public:
   /**
    * Do any processing that needs to happen as a result of a change in
    * the characteristics of the medium, and return whether this rule
    * processor's rules have changed (e.g., because of media queries).
    */
   nsresult MediumFeaturesChanged(nsPresContext* aPresContext,
                                  bool* aRulesChanged);
 
-  void AppendAllSheets(nsTArray<nsCSSStyleSheet*>& aArray);
+  void AppendAllSheets(nsTArray<mozilla::CSSStyleSheet*>& aArray);
 
   void Traverse(nsIContent *aContent,
                             nsCycleCollectionTraversalCallback &cb);
 
   NS_DECL_CYCLE_COLLECTION_CLASS(nsBindingManager)
 
   // Notify the binding manager when an outermost update begins and
   // ends.  The end method can execute script.
--- a/dom/xbl/nsXBLBinding.cpp
+++ b/dom/xbl/nsXBLBinding.cpp
@@ -697,17 +697,17 @@ static void
 UpdateInsertionParent(XBLChildrenElement* aPoint,
                       nsIContent* aOldBoundElement)
 {
   if (aPoint->IsDefaultInsertion()) {
     return;
   }
 
   for (size_t i = 0; i < aPoint->InsertedChildrenLength(); ++i) {
-    nsIContent* child = aPoint->mInsertedChildren[i];
+    nsIContent* child = aPoint->InsertedChild(i);
 
     MOZ_ASSERT(child->GetParentNode());
 
     // Here, we're iterating children that we inserted. There are two cases:
     // either |child| is an explicit child of |aOldBoundElement| and is no
     // longer inserted anywhere or it's a child of a <children> element
     // parented to |aOldBoundElement|. In the former case, the child is no
     // longer inserted anywhere, so we set its insertion parent to null. In the
--- a/dom/xbl/nsXBLPrototypeBinding.cpp
+++ b/dom/xbl/nsXBLPrototypeBinding.cpp
@@ -1681,40 +1681,40 @@ void
 nsXBLPrototypeBinding::EnsureResources()
 {
   if (!mResources) {
     mResources = new nsXBLPrototypeResources(this);
   }
 }
 
 void
-nsXBLPrototypeBinding::AppendStyleSheet(nsCSSStyleSheet* aSheet)
+nsXBLPrototypeBinding::AppendStyleSheet(CSSStyleSheet* aSheet)
 {
   EnsureResources();
   mResources->AppendStyleSheet(aSheet);
 }
 
 void
-nsXBLPrototypeBinding::RemoveStyleSheet(nsCSSStyleSheet* aSheet)
+nsXBLPrototypeBinding::RemoveStyleSheet(CSSStyleSheet* aSheet)
 {
   if (!mResources) {
     MOZ_ASSERT(false, "Trying to remove a sheet that does not exist.");
     return;
   }
 
   mResources->RemoveStyleSheet(aSheet);
 } 
 void
-nsXBLPrototypeBinding::InsertStyleSheetAt(size_t aIndex, nsCSSStyleSheet* aSheet)
+nsXBLPrototypeBinding::InsertStyleSheetAt(size_t aIndex, CSSStyleSheet* aSheet)
 {
   EnsureResources();
   mResources->InsertStyleSheetAt(aIndex, aSheet);
 }
 
-nsCSSStyleSheet*
+CSSStyleSheet*
 nsXBLPrototypeBinding::StyleSheetAt(size_t aIndex) const
 {
   MOZ_ASSERT(mResources);
   return mResources->StyleSheetAt(aIndex);
 }
 
 size_t
 nsXBLPrototypeBinding::SheetCount() const
@@ -1725,14 +1725,14 @@ nsXBLPrototypeBinding::SheetCount() cons
 bool
 nsXBLPrototypeBinding::HasStyleSheets() const
 {
   return mResources && mResources->HasStyleSheets();
 }
 
 void
 nsXBLPrototypeBinding::AppendStyleSheetsTo(
-                                      nsTArray<nsCSSStyleSheet*>& aResult) const
+                                      nsTArray<CSSStyleSheet*>& aResult) const
 {
   if (mResources) {
     mResources->AppendStyleSheetsTo(aResult);
   }
 }
--- a/dom/xbl/nsXBLPrototypeBinding.h
+++ b/dom/xbl/nsXBLPrototypeBinding.h
@@ -20,16 +20,20 @@
 
 class nsIAtom;
 class nsIContent;
 class nsIDocument;
 class nsXBLAttributeEntry;
 class nsXBLBinding;
 class nsXBLProtoImplField;
 
+namespace mozilla {
+class CSSStyleSheet;
+} // namespace mozilla
+
 // *********************************************************************/
 // The XBLPrototypeBinding class
 
 // Instances of this class are owned by the nsXBLDocumentInfo object returned
 // by XBLDocumentInfo().  Consumers who want to refcount things should refcount
 // that.
 class nsXBLPrototypeBinding MOZ_FINAL
 {
@@ -108,23 +112,23 @@ public:
   void SetBasePrototype(nsXBLPrototypeBinding* aBinding);
   nsXBLPrototypeBinding* GetBasePrototype() { return mBaseBinding; }
 
   nsXBLDocumentInfo* XBLDocumentInfo() const { return mXBLDocInfoWeak; }
   bool IsChrome() { return mXBLDocInfoWeak->IsChrome(); }
 
   void SetInitialAttributes(nsIContent* aBoundElement, nsIContent* aAnonymousContent);
 
-  void AppendStyleSheet(nsCSSStyleSheet* aSheet);
-  void RemoveStyleSheet(nsCSSStyleSheet* aSheet);
-  void InsertStyleSheetAt(size_t aIndex, nsCSSStyleSheet* aSheet);
-  nsCSSStyleSheet* StyleSheetAt(size_t aIndex) const;
+  void AppendStyleSheet(mozilla::CSSStyleSheet* aSheet);
+  void RemoveStyleSheet(mozilla::CSSStyleSheet* aSheet);
+  void InsertStyleSheetAt(size_t aIndex, mozilla::CSSStyleSheet* aSheet);
+  mozilla::CSSStyleSheet* StyleSheetAt(size_t aIndex) const;
   size_t SheetCount() const;
   bool HasStyleSheets() const;
-  void AppendStyleSheetsTo(nsTArray<nsCSSStyleSheet*>& aResult) const;
+  void AppendStyleSheetsTo(nsTArray<mozilla::CSSStyleSheet*>& aResult) const;
 
   nsIStyleRuleProcessor* GetRuleProcessor();
 
   nsresult FlushSkinSheets();
 
   nsIAtom* GetBaseTag(int32_t* aNamespaceID);
   void SetBaseTag(int32_t aNamespaceID, nsIAtom* aTag);
 
--- a/dom/xbl/nsXBLPrototypeResources.cpp
+++ b/dom/xbl/nsXBLPrototypeResources.cpp
@@ -75,28 +75,28 @@ nsXBLPrototypeResources::FlushSkinSheets
     return NS_OK;
   }
 
   // We have scoped stylesheets.  Reload any chrome stylesheets we
   // encounter.  (If they aren't skin sheets, it doesn't matter, since
   // they'll still be in the chrome cache.
   mRuleProcessor = nullptr;
 
-  nsTArray<nsRefPtr<nsCSSStyleSheet>> oldSheets;
+  nsTArray<nsRefPtr<CSSStyleSheet>> oldSheets;
 
   oldSheets.SwapElements(mStyleSheetList);
 
   mozilla::css::Loader* cssLoader = doc->CSSLoader();
 
   for (size_t i = 0, count = oldSheets.Length(); i < count; ++i) {
-    nsCSSStyleSheet* oldSheet = oldSheets[i];
+    CSSStyleSheet* oldSheet = oldSheets[i];
 
     nsIURI* uri = oldSheet->GetSheetURI();
 
-    nsRefPtr<nsCSSStyleSheet> newSheet;
+    nsRefPtr<CSSStyleSheet> newSheet;
     if (IsChromeURI(uri)) {
       if (NS_FAILED(cssLoader->LoadSheetSync(uri, getter_AddRefs(newSheet))))
         continue;
     }
     else {
       newSheet = oldSheet;
     }
 
@@ -133,35 +133,35 @@ void
 nsXBLPrototypeResources::GatherRuleProcessor()
 {
   mRuleProcessor = new nsCSSRuleProcessor(mStyleSheetList,
                                           nsStyleSet::eDocSheet,
                                           nullptr);
 }
 
 void
-nsXBLPrototypeResources::AppendStyleSheet(nsCSSStyleSheet* aSheet)
+nsXBLPrototypeResources::AppendStyleSheet(CSSStyleSheet* aSheet)
 {
   mStyleSheetList.AppendElement(aSheet);
 }
 
 void
-nsXBLPrototypeResources::RemoveStyleSheet(nsCSSStyleSheet* aSheet)
+nsXBLPrototypeResources::RemoveStyleSheet(CSSStyleSheet* aSheet)
 {
   DebugOnly<bool> found = mStyleSheetList.RemoveElement(aSheet);
   MOZ_ASSERT(found, "Trying to remove a sheet that does not exist.");
 }
 
 void
-nsXBLPrototypeResources::InsertStyleSheetAt(size_t aIndex, nsCSSStyleSheet* aSheet)
+nsXBLPrototypeResources::InsertStyleSheetAt(size_t aIndex, CSSStyleSheet* aSheet)
 {
   mStyleSheetList.InsertElementAt(aIndex, aSheet);
 }
 
-nsCSSStyleSheet*
+CSSStyleSheet*
 nsXBLPrototypeResources::StyleSheetAt(size_t aIndex) const
 {
   return mStyleSheetList[aIndex];
 }
 
 size_t
 nsXBLPrototypeResources::SheetCount() const
 {
@@ -171,12 +171,12 @@ nsXBLPrototypeResources::SheetCount() co
 bool
 nsXBLPrototypeResources::HasStyleSheets() const
 {
   return !mStyleSheetList.IsEmpty();
 }
 
 void
 nsXBLPrototypeResources::AppendStyleSheetsTo(
-                                      nsTArray<nsCSSStyleSheet*>& aResult) const
+                                      nsTArray<CSSStyleSheet*>& aResult) const
 {
   aResult.AppendElements(mStyleSheetList);
 }
--- a/dom/xbl/nsXBLPrototypeResources.h
+++ b/dom/xbl/nsXBLPrototypeResources.h
@@ -5,22 +5,25 @@
 
 #ifndef nsXBLPrototypeResources_h__
 #define nsXBLPrototypeResources_h__
 
 #include "nsAutoPtr.h"
 #include "nsICSSLoaderObserver.h"
 
 class nsCSSRuleProcessor;
-class nsCSSStyleSheet;
 class nsIAtom;
 class nsIContent;
 class nsXBLPrototypeBinding;
 class nsXBLResourceLoader;
 
+namespace mozilla {
+class CSSStyleSheet;
+} // namespace mozilla
+
 // *********************************************************************/
 // The XBLPrototypeResources class
 
 class nsXBLPrototypeResources
 {
 public:
   nsXBLPrototypeResources(nsXBLPrototypeBinding* aBinding);
   ~nsXBLPrototypeResources();
@@ -31,37 +34,37 @@ public:
   nsresult FlushSkinSheets();
 
   nsresult Write(nsIObjectOutputStream* aStream);
 
   void Traverse(nsCycleCollectionTraversalCallback &cb) const;
 
   void ClearLoader();
 
-  void AppendStyleSheet(nsCSSStyleSheet* aSheet);
-  void RemoveStyleSheet(nsCSSStyleSheet* aSheet);
-  void InsertStyleSheetAt(size_t aIndex, nsCSSStyleSheet* aSheet);
-  nsCSSStyleSheet* StyleSheetAt(size_t aIndex) const;
+  void AppendStyleSheet(mozilla::CSSStyleSheet* aSheet);
+  void RemoveStyleSheet(mozilla::CSSStyleSheet* aSheet);
+  void InsertStyleSheetAt(size_t aIndex, mozilla::CSSStyleSheet* aSheet);
+  mozilla::CSSStyleSheet* StyleSheetAt(size_t aIndex) const;
   size_t SheetCount() const;
   bool HasStyleSheets() const;
-  void AppendStyleSheetsTo(nsTArray<nsCSSStyleSheet*>& aResult) const;
+  void AppendStyleSheetsTo(nsTArray<mozilla::CSSStyleSheet*>& aResult) const;
 
   /**
    * Recreates mRuleProcessor to represent the current list of style sheets
    * stored in mStyleSheetList.  (Named GatherRuleProcessor to parallel
    * nsStyleSet::GatherRuleProcessors.)
    */
   void GatherRuleProcessor();
 
   nsCSSRuleProcessor* GetRuleProcessor() const { return mRuleProcessor; }
 
 private:
   // A loader object. Exists only long enough to load resources, and then it dies.
   nsRefPtr<nsXBLResourceLoader> mLoader;
 
   // A list of loaded stylesheets for this binding.
-  nsTArray<nsRefPtr<nsCSSStyleSheet>> mStyleSheetList;
+  nsTArray<nsRefPtr<mozilla::CSSStyleSheet>> mStyleSheetList;
 
   // The list of stylesheets converted to a rule processor.
   nsRefPtr<nsCSSRuleProcessor> mRuleProcessor;
 };
 
 #endif
--- a/dom/xbl/nsXBLResourceLoader.cpp
+++ b/dom/xbl/nsXBLResourceLoader.cpp
@@ -1,39 +1,41 @@
 /* -*- Mode: C++; 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/. */
 
 #include "nsTArray.h"
 #include "nsString.h"
-#include "nsCSSStyleSheet.h"
 #include "nsIStyleRuleProcessor.h"
 #include "nsIDocument.h"
 #include "nsIContent.h"
 #include "nsIPresShell.h"
 #include "nsXBLService.h"
 #include "nsIServiceManager.h"
 #include "nsXBLResourceLoader.h"
 #include "nsXBLPrototypeResources.h"
 #include "nsIDocumentObserver.h"
 #include "imgILoader.h"
 #include "imgRequestProxy.h"
+#include "mozilla/CSSStyleSheet.h"
 #include "mozilla/css/Loader.h"
 #include "nsIURI.h"
 #include "nsNetUtil.h"
 #include "nsGkAtoms.h"
 #include "nsFrameManager.h"
 #include "nsStyleContext.h"
 #include "nsXBLPrototypeBinding.h"
 #include "nsCSSRuleProcessor.h"
 #include "nsContentUtils.h"
 #include "nsStyleSet.h"
 #include "nsIScriptSecurityManager.h"
 
+using namespace mozilla;
+
 NS_IMPL_CYCLE_COLLECTION(nsXBLResourceLoader, mBoundElements)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXBLResourceLoader)
   NS_INTERFACE_MAP_ENTRY(nsICSSLoaderObserver)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsXBLResourceLoader)
@@ -130,17 +132,17 @@ nsXBLResourceLoader::LoadResources(bool*
       bool chrome;
       nsresult rv;
       if (NS_SUCCEEDED(url->SchemeIs("chrome", &chrome)) && chrome)
       {
         rv = nsContentUtils::GetSecurityManager()->
           CheckLoadURIWithPrincipal(docPrincipal, url,
                                     nsIScriptSecurityManager::ALLOW_CHROME);
         if (NS_SUCCEEDED(rv)) {
-          nsRefPtr<nsCSSStyleSheet> sheet;
+          nsRefPtr<CSSStyleSheet> sheet;
           rv = cssLoader->LoadSheetSync(url, getter_AddRefs(sheet));
           NS_ASSERTION(NS_SUCCEEDED(rv), "Load failed!!!");
           if (NS_SUCCEEDED(rv))
           {
             rv = StyleSheetLoaded(sheet, false, NS_OK);
             NS_ASSERTION(NS_SUCCEEDED(rv), "Processing the style sheet failed!!!");
           }
         }
@@ -159,17 +161,17 @@ nsXBLResourceLoader::LoadResources(bool*
   
   // Destroy our resource list.
   delete mResourceList;
   mResourceList = nullptr;
 }
 
 // nsICSSLoaderObserver
 NS_IMETHODIMP
-nsXBLResourceLoader::StyleSheetLoaded(nsCSSStyleSheet* aSheet,
+nsXBLResourceLoader::StyleSheetLoaded(CSSStyleSheet* aSheet,
                                       bool aWasAlternate,
                                       nsresult aStatus)
 {
   if (!mResources) {
     // Our resources got destroyed -- just bail out
     return NS_OK;
   }
    
--- a/dom/xbl/nsXBLResourceLoader.h
+++ b/dom/xbl/nsXBLResourceLoader.h
@@ -24,17 +24,18 @@ class nsIObjectOutputStream;
 
 class nsXBLResourceLoader : public nsICSSLoaderObserver
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS(nsXBLResourceLoader)
 
   // nsICSSLoaderObserver
-  NS_IMETHOD StyleSheetLoaded(nsCSSStyleSheet* aSheet, bool aWasAlternate,
+  NS_IMETHOD StyleSheetLoaded(mozilla::CSSStyleSheet* aSheet,
+                              bool aWasAlternate,
                               nsresult aStatus) MOZ_OVERRIDE;
 
   void LoadResources(bool* aResult);
   void AddResource(nsIAtom* aResourceType, const nsAString& aSrc);
   void AddResourceListener(nsIContent* aElement);
 
   nsXBLResourceLoader(nsXBLPrototypeBinding* aBinding,
                       nsXBLPrototypeResources* aResources);
--- a/dom/xslt/tests/mochitest/test_bug319374.xhtml
+++ b/dom/xslt/tests/mochitest/test_bug319374.xhtml
@@ -34,18 +34,17 @@ https://bugzilla.mozilla.org/show_bug.cg
     function getAnonymousNodes(e) {
       return SpecialPowers.wrap(document).getAnonymousNodes(e);
     }
     try {
       var xp = new XPathEvaluator();
       var result = xp.evaluate("*",
                                document.getElementById('content'),
                                null,
-                               SpecialPowers.Ci.nsIDOMXPathResult.
-                                 UNORDERED_NODE_ITERATOR_TYPE,
+                               XPathResult.UNORDERED_NODE_ITERATOR_TYPE,
                                null);
       var res = null;
       while (res = result.iterateNext()) {
         ++counter; 
         var anon = getAnonymousNodes(res);
         anon[0].removeChild(anon[0].firstChild); // Removing a child node
         anon[0].removeAttribute("attr1"); // Removing an attribute
         anon[1].firstChild.data = "anon text changed" // Modifying text data
@@ -64,36 +63,34 @@ https://bugzilla.mozilla.org/show_bug.cg
     var anonAttr2 =
       getAnonymousNodes(document.getElementById('content').
         lastChild)[0].getAttributeNode('attr');
     var resultAttr = null;
     try {
       var xp2 = SpecialPowers.wrap(xp).evaluate(".",
                             anonAttr1,
                             null,
-                            SpecialPowers.Ci.nsIDOMXPathResult.
-                              UNORDERED_NODE_ITERATOR_TYPE,
+                            XPathResult.UNORDERED_NODE_ITERATOR_TYPE,
                             null);
       // Attribute changing in a different anonymous tree.
       anonAttr2.value = "foo";
       resultAttr = xp2.iterateNext();
       ok(SpecialPowers.compare(resultAttr, anonAttr1), "XPathEvaluator returned wrong attribute!")
     } catch (e) {
       ok(false, e);
     }
 
     // Test 3: If the anonymous tree in which context node is in is modified,
     //         XPath result should throw when iterateNext() is called.
     resultAttr = null;
     try {
       var xp3 = xp.evaluate(".",
                             anonAttr1,
                             null,
-                            SpecialPowers.Ci.nsIDOMXPathResult.
-                              UNORDERED_NODE_ITERATOR_TYPE,
+                            XPathResult.UNORDERED_NODE_ITERATOR_TYPE,
                             null);
       // Attribute changing in the same anonymous tree.
       anonAttr1.ownerElement.setAttribute("foo", "bar");
       resultAttr = xp3.iterateNext();
       ok(resultAttr == anonAttr1,
          "XPathEvaluator should have thrown an exception!")
     } catch (e) {
       ok(true, e);
--- a/dom/xslt/xpath/XPathEvaluator.cpp
+++ b/dom/xslt/xpath/XPathEvaluator.cpp
@@ -4,28 +4,29 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/XPathEvaluator.h"
 #include "mozilla/Move.h"
 #include "nsCOMPtr.h"
 #include "nsIAtom.h"
 #include "nsXPathExpression.h"
 #include "nsXPathNSResolver.h"
-#include "nsXPathResult.h"
+#include "XPathResult.h"
 #include "nsContentCID.h"
 #include "txExpr.h"
 #include "txExprParser.h"
 #include "nsError.h"
 #include "txURIUtils.h"
 #include "nsIDocument.h"
 #include "nsIDOMDocument.h"
 #include "nsDOMString.h"
 #include "nsNameSpaceManager.h"
 #include "nsContentUtils.h"
 #include "mozilla/dom/XPathEvaluatorBinding.h"
+#include "mozilla/dom/BindingUtils.h"
 
 extern nsresult
 TX_ResolveFunctionCallXPCOM(const nsCString &aContractID, int32_t aNamespaceID,
                             nsIAtom *aName, nsISupports *aState,
                             FunctionCall **aFunction);
 
 namespace mozilla {
 namespace dom {
@@ -169,26 +170,28 @@ XPathEvaluator::CreateNSResolver(nsINode
                                  ErrorResult& rv)
 {
   nsCOMPtr<nsIDOMNode> nodeResolver = do_QueryInterface(aNodeResolver);
   nsCOMPtr<nsIDOMXPathNSResolver> res;
   rv = CreateNSResolver(nodeResolver, getter_AddRefs(res));
   return res.forget();
 }
 
-already_AddRefed<nsISupports>
-XPathEvaluator::Evaluate(const nsAString& aExpression, nsINode* aContextNode,
+already_AddRefed<XPathResult>
+XPathEvaluator::Evaluate(JSContext* aCx, const nsAString& aExpression,
+                         nsINode* aContextNode,
                          nsIDOMXPathNSResolver* aResolver, uint16_t aType,
-                         nsISupports* aResult, ErrorResult& rv)
+                         JS::Handle<JSObject*> aResult, ErrorResult& rv)
 {
   nsCOMPtr<nsIDOMNode> contextNode = do_QueryInterface(aContextNode);
   nsCOMPtr<nsISupports> res;
   rv = Evaluate(aExpression, contextNode, aResolver, aType,
-                aResult, getter_AddRefs(res));
-  return res.forget();
+                aResult ? UnwrapDOMObjectToISupports(aResult) : nullptr,
+                getter_AddRefs(res));
+  return res.forget().downcast<nsIXPathResult>().downcast<XPathResult>();
 }
 
 
 /*
  * Implementation of txIParseContext private to XPathEvaluator, based on a
  * nsIDOMXPathNSResolver
  */
 
--- a/dom/xslt/xpath/XPathEvaluator.h
+++ b/dom/xslt/xpath/XPathEvaluator.h
@@ -16,16 +16,17 @@
 
 class nsINode;
 class txResultRecycler;
 
 namespace mozilla {
 namespace dom {
 
 class GlobalObject;
+class XPathResult;
 
 /**
  * A class for evaluating an XPath expression string
  */
 class XPathEvaluator MOZ_FINAL : public nsIDOMXPathEvaluator
 {
 public:
     XPathEvaluator(nsIDocument* aDocument = nullptr);
@@ -45,20 +46,21 @@ public:
     static already_AddRefed<XPathEvaluator>
         Constructor(const GlobalObject& aGlobal, ErrorResult& rv);
     already_AddRefed<nsIDOMXPathExpression>
         CreateExpression(const nsAString& aExpression,
                          nsIDOMXPathNSResolver* aResolver,
                          ErrorResult& rv);
     already_AddRefed<nsIDOMXPathNSResolver>
         CreateNSResolver(nsINode* aNodeResolver, ErrorResult& rv);
-    already_AddRefed<nsISupports>
-        Evaluate(const nsAString& aExpression, nsINode* aContextNode,
-                 nsIDOMXPathNSResolver* aResolver, uint16_t aType,
-                 nsISupports* aResult, ErrorResult& rv);
+    already_AddRefed<XPathResult>
+        Evaluate(JSContext* aCx, const nsAString& aExpression,
+                 nsINode* aContextNode, nsIDOMXPathNSResolver* aResolver,
+                 uint16_t aType, JS::Handle<JSObject*> aResult,
+                 ErrorResult& rv);
 private:
     nsWeakPtr mDocument;
     nsRefPtr<txResultRecycler> mRecycler;
 };
 
 inline nsISupports*
 ToSupports(XPathEvaluator* e)
 {
rename from dom/xslt/xpath/nsXPathResult.cpp
rename to dom/xslt/xpath/XPathResult.cpp
--- a/dom/xslt/xpath/nsXPathResult.cpp
+++ b/dom/xslt/xpath/XPathResult.cpp
@@ -1,267 +1,184 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* 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 "nsXPathResult.h"
+#include "XPathResult.h"
 #include "txExprResult.h"
 #include "txNodeSet.h"
 #include "nsError.h"
 #include "mozilla/dom/Attr.h"
 #include "mozilla/dom/Element.h"
 #include "nsDOMClassInfoID.h"
 #include "nsIDOMNode.h"
 #include "nsIDOMDocument.h"
 #include "nsDOMString.h"
 #include "txXPathTreeWalker.h"
 #include "nsCycleCollectionParticipant.h"
+#include "mozilla/dom/XPathResultBinding.h"
 
-using namespace mozilla::dom;
+namespace mozilla {
+namespace dom {
 
-nsXPathResult::nsXPathResult() : mDocument(nullptr),
-                                 mCurrentPos(0),
-                                 mResultType(ANY_TYPE),
-                                 mInvalidIteratorState(true),
-                                 mBooleanResult(false),
-                                 mNumberResult(0)
+XPathResult::XPathResult(nsINode* aParent)
+    : mParent(aParent),
+      mDocument(nullptr),
+      mCurrentPos(0),
+      mResultType(ANY_TYPE),
+      mInvalidIteratorState(true),
+      mBooleanResult(false),
+      mNumberResult(0)
 {
+    SetIsDOMBinding();
 }
 
-nsXPathResult::nsXPathResult(const nsXPathResult &aResult)
-    : mResult(aResult.mResult),
+XPathResult::XPathResult(const XPathResult &aResult)
+    : mParent(aResult.mParent),
+      mResult(aResult.mResult),
       mResultNodes(aResult.mResultNodes),
       mDocument(aResult.mDocument),
+      mContextNode(aResult.mContextNode),
       mCurrentPos(0),
       mResultType(aResult.mResultType),
-      mContextNode(aResult.mContextNode),
       mInvalidIteratorState(aResult.mInvalidIteratorState)
 {
+    SetIsDOMBinding();
     if (mDocument) {
         mDocument->AddMutationObserver(this);
     }
 }
 
-nsXPathResult::~nsXPathResult()
+XPathResult::~XPathResult()
 {
     RemoveObserver();
 }
 
-NS_IMPL_CYCLE_COLLECTION_CLASS(nsXPathResult)
+NS_IMPL_CYCLE_COLLECTION_CLASS(XPathResult)
 
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXPathResult)
+NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(XPathResult)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(XPathResult)
+    NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
+    NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
     {
         tmp->RemoveObserver();
     }
     NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocument)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXPathResult)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(XPathResult)
+    NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
+    NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocument)
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mResultNodes)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
-NS_IMPL_CYCLE_COLLECTING_ADDREF(nsXPathResult)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(nsXPathResult)
+NS_IMPL_CYCLE_COLLECTING_ADDREF(XPathResult)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(XPathResult)
 
-DOMCI_DATA(XPathResult, nsXPathResult)
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXPathResult)
-    NS_INTERFACE_MAP_ENTRY(nsIDOMXPathResult)
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(XPathResult)
+    NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
     NS_INTERFACE_MAP_ENTRY(nsIMutationObserver)
     NS_INTERFACE_MAP_ENTRY(nsIXPathResult)
-    NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMXPathResult)
-    NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(XPathResult)
+    NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPathResult)
 NS_INTERFACE_MAP_END
 
+JSObject*
+XPathResult::WrapObject(JSContext* aCx)
+{
+    return XPathResultBinding::Wrap(aCx, this);
+}
+
 void
-nsXPathResult::RemoveObserver()
+XPathResult::RemoveObserver()
 {
     if (mDocument) {
         mDocument->RemoveMutationObserver(this);
     }
 }
 
-NS_IMETHODIMP
-nsXPathResult::GetResultType(uint16_t *aResultType)
-{
-    *aResultType = mResultType;
-
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsXPathResult::GetNumberValue(double *aNumberValue)
-{
-    if (mResultType != NUMBER_TYPE) {
-        return NS_ERROR_DOM_TYPE_ERR;
-    }
-
-    *aNumberValue = mNumberResult;
-
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsXPathResult::GetStringValue(nsAString &aStringValue)
-{
-    if (mResultType != STRING_TYPE) {
-        return NS_ERROR_DOM_TYPE_ERR;
-    }
-
-    aStringValue = mStringResult;
-
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsXPathResult::GetBooleanValue(bool *aBooleanValue)
-{
-    if (mResultType != BOOLEAN_TYPE) {
-        return NS_ERROR_DOM_TYPE_ERR;
-    }
-
-    *aBooleanValue = mBooleanResult;
-
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsXPathResult::GetSingleNodeValue(nsIDOMNode **aSingleNodeValue)
-{
-    if (!isNode()) {
-        return NS_ERROR_DOM_TYPE_ERR;
-    }
-
-    if (mResultNodes.Count() > 0) {
-        NS_ADDREF(*aSingleNodeValue = mResultNodes[0]);
-    }
-    else {
-        *aSingleNodeValue = nullptr;
-    }
-
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsXPathResult::GetInvalidIteratorState(bool *aInvalidIteratorState)
-{
-    *aInvalidIteratorState = isIterator() && mInvalidIteratorState;
-
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsXPathResult::GetSnapshotLength(uint32_t *aSnapshotLength)
-{
-    if (!isSnapshot()) {
-        return NS_ERROR_DOM_TYPE_ERR;
-    }
-
-    *aSnapshotLength = (uint32_t)mResultNodes.Count();
-
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsXPathResult::IterateNext(nsIDOMNode **aResult)
+nsINode*
+XPathResult::IterateNext(ErrorResult& aRv)
 {
     if (!isIterator()) {
-        return NS_ERROR_DOM_TYPE_ERR;
+        aRv.Throw(NS_ERROR_DOM_TYPE_ERR);
+        return nullptr;
     }
 
     if (mDocument) {
         mDocument->FlushPendingNotifications(Flush_Content);
     }
 
     if (mInvalidIteratorState) {
-        return NS_ERROR_DOM_INVALID_STATE_ERR;
-    }
-
-    if (mCurrentPos < (uint32_t)mResultNodes.Count()) {
-        NS_ADDREF(*aResult = mResultNodes[mCurrentPos++]);
-    }
-    else {
-        *aResult = nullptr;
+        aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
+        return nullptr;
     }
 
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsXPathResult::SnapshotItem(uint32_t aIndex, nsIDOMNode **aResult)
-{
-    if (!isSnapshot()) {
-        return NS_ERROR_DOM_TYPE_ERR;
-    }
-
-    NS_IF_ADDREF(*aResult = mResultNodes.SafeObjectAt(aIndex));
-
-    return NS_OK;
+    return mResultNodes.SafeObjectAt(mCurrentPos++);
 }
 
 void
-nsXPathResult::NodeWillBeDestroyed(const nsINode* aNode)
+XPathResult::NodeWillBeDestroyed(const nsINode* aNode)
 {
     nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this);
     // Set to null to avoid unregistring unnecessarily
     mDocument = nullptr;
     Invalidate(aNode->IsNodeOfType(nsINode::eCONTENT) ?
                static_cast<const nsIContent*>(aNode) : nullptr);
 }
 
 void
-nsXPathResult::CharacterDataChanged(nsIDocument* aDocument,
-                                    nsIContent *aContent,
-                                    CharacterDataChangeInfo* aInfo)
+XPathResult::CharacterDataChanged(nsIDocument* aDocument,
+                                  nsIContent *aContent,
+                                  CharacterDataChangeInfo* aInfo)
 {
     Invalidate(aContent);
 }
 
 void
-nsXPathResult::AttributeChanged(nsIDocument* aDocument,
-                                Element* aElement,
-                                int32_t aNameSpaceID,
-                                nsIAtom* aAttribute,
-                                int32_t aModType)
+XPathResult::AttributeChanged(nsIDocument* aDocument,
+                              Element* aElement,
+                              int32_t aNameSpaceID,
+                              nsIAtom* aAttribute,
+                              int32_t aModType)
 {
     Invalidate(aElement);
 }
 
 void
-nsXPathResult::ContentAppended(nsIDocument* aDocument,
-                               nsIContent* aContainer,
-                               nsIContent* aFirstNewContent,
-                               int32_t aNewIndexInContainer)
+XPathResult::ContentAppended(nsIDocument* aDocument,
+                             nsIContent* aContainer,
+                             nsIContent* aFirstNewContent,
+                             int32_t aNewIndexInContainer)
 {
     Invalidate(aContainer);
 }
 
 void
-nsXPathResult::ContentInserted(nsIDocument* aDocument,
-                               nsIContent* aContainer,
-                               nsIContent* aChild,
-                               int32_t aIndexInContainer)
+XPathResult::ContentInserted(nsIDocument* aDocument,
+                             nsIContent* aContainer,
+                             nsIContent* aChild,
+                             int32_t aIndexInContainer)
 {
     Invalidate(aContainer);
 }
 
 void
-nsXPathResult::ContentRemoved(nsIDocument* aDocument,
-                              nsIContent* aContainer,
-                              nsIContent* aChild,
-                              int32_t aIndexInContainer,
-                              nsIContent* aPreviousSibling)
+XPathResult::ContentRemoved(nsIDocument* aDocument,
+                            nsIContent* aContainer,
+                            nsIContent* aChild,
+                            int32_t aIndexInContainer,
+                            nsIContent* aPreviousSibling)
 {
     Invalidate(aContainer);
 }
 
 nsresult
-nsXPathResult::SetExprResult(txAExprResult* aExprResult, uint16_t aResultType,
-                             nsINode* aContextNode)
+XPathResult::SetExprResult(txAExprResult* aExprResult, uint16_t aResultType,
+                           nsINode* aContextNode)
 {
     MOZ_ASSERT(aExprResult);
 
     if ((isSnapshot(aResultType) || isIterator(aResultType) ||
          isNode(aResultType)) &&
         aExprResult->getResultType() != txAExprResult::NODESET) {
         // The DOM spec doesn't really say what should happen when reusing an
         // XPathResult and an error is thrown. Let's not touch the XPathResult
@@ -300,59 +217,48 @@ nsXPathResult::SetExprResult(txAExprResu
         default:
         {
             MOZ_ASSERT(isNode() || isIterator() || isSnapshot());
         }
     }
 
     if (aExprResult->getResultType() == txAExprResult::NODESET) {
         txNodeSet *nodeSet = static_cast<txNodeSet*>(aExprResult);
-        nsCOMPtr<nsIDOMNode> node;
         int32_t i, count = nodeSet->size();
         for (i = 0; i < count; ++i) {
-            txXPathNativeNode::getNode(nodeSet->get(i), getter_AddRefs(node));
-            if (node) {
-                mResultNodes.AppendObject(node);
-            }
+            nsINode* node = txXPathNativeNode::getNode(nodeSet->get(i));
+            mResultNodes.AppendObject(node);
         }
 
         if (count > 0) {
             mResult = nullptr;
         }
     }
 
     if (!isIterator()) {
         return NS_OK;
     }
 
     mInvalidIteratorState = false;
 
     if (mResultNodes.Count() > 0) {
         // If we support the document() function in DOM-XPath we need to
         // observe all documents that we have resultnodes in.
-        nsCOMPtr<nsIDOMDocument> document;
-        mResultNodes[0]->GetOwnerDocument(getter_AddRefs(document));
-        if (document) {
-            mDocument = do_QueryInterface(document);
-        }
-        else {
-            mDocument = do_QueryInterface(mResultNodes[0]);
-        }
-
+        mDocument = mResultNodes[0]->OwnerDoc();
         NS_ASSERTION(mDocument, "We need a document!");
         if (mDocument) {
             mDocument->AddMutationObserver(this);
         }
     }
 
     return NS_OK;
 }
 
 void
-nsXPathResult::Invalidate(const nsIContent* aChangeRoot)
+XPathResult::Invalidate(const nsIContent* aChangeRoot)
 {
     nsCOMPtr<nsINode> contextNode = do_QueryReferent(mContextNode);
     if (contextNode && aChangeRoot && aChangeRoot->GetBindingParent()) {
         // If context node is in anonymous content, changes to
         // non-anonymous content need to invalidate the XPathResult. If
         // the changes are happening in a different anonymous trees, no
         // invalidation should happen.
         nsIContent* ctxBindingParent = nullptr;
@@ -376,17 +282,17 @@ nsXPathResult::Invalidate(const nsIConte
     // Make sure nulling out mDocument is the last thing we do.
     if (mDocument) {
         mDocument->RemoveMutationObserver(this);
         mDocument = nullptr;
     }
 }
 
 nsresult
-nsXPathResult::GetExprResult(txAExprResult** aExprResult)
+XPathResult::GetExprResult(txAExprResult** aExprResult)
 {
     if (isIterator() && mInvalidIteratorState) {
         return NS_ERROR_DOM_INVALID_STATE_ERR;
     }
 
     if (mResult) {
         NS_ADDREF(*aExprResult = mResult);
 
@@ -413,25 +319,23 @@ nsXPathResult::GetExprResult(txAExprResu
     }
 
     NS_ADDREF(*aExprResult = nodeSet);
 
     return NS_OK;
 }
 
 nsresult
-nsXPathResult::Clone(nsIXPathResult **aResult)
+XPathResult::Clone(nsIXPathResult **aResult)
 {
     *aResult = nullptr;
 
     if (isIterator() && mInvalidIteratorState) {
         return NS_ERROR_DOM_INVALID_STATE_ERR;
     }
 
-    nsCOMPtr<nsIXPathResult> result = new nsXPathResult(*this);
-    if (!result) {
-        return NS_ERROR_OUT_OF_MEMORY;
-    }
-
-    result.swap(*aResult);
+    NS_ADDREF(*aResult = new XPathResult(*this));
 
     return NS_OK;
 }
+
+} // namespace dom
+} // namespace mozilla
rename from dom/xslt/xpath/nsXPathResult.h
rename to dom/xslt/xpath/XPathResult.h
--- a/dom/xslt/xpath/nsXPathResult.h
+++ b/dom/xslt/xpath/XPathResult.h
@@ -1,26 +1,30 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* 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 nsXPathResult_h__
-#define nsXPathResult_h__
+#ifndef mozilla_dom_XPathResult_h
+#define mozilla_dom_XPathResult_h
 
-#include "txExprResult.h"
-#include "nsIDOMXPathResult.h"
 #include "nsStubMutationObserver.h"
+#include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 #include "nsCOMArray.h"
 #include "nsWeakPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "mozilla/Attributes.h"
+#include "mozilla/ErrorResult.h"
+#include "nsString.h"
+#include "nsWrapperCache.h"
+#include "nsINode.h"
 
 class nsIDocument;
+class txAExprResult;
 
 // {662f2c9a-c7cd-4cab-9349-e733df5a838c}
 #define NS_IXPATHRESULT_IID \
 { 0x662f2c9a, 0xc7cd, 0x4cab, {0x93, 0x49, 0xe7, 0x33, 0xdf, 0x5a, 0x83, 0x8c }}
 
 class nsIXPathResult : public nsISupports
 {
 public:
@@ -29,44 +33,131 @@ public:
                                    uint16_t aResultType,
                                    nsINode* aContextNode) = 0;
     virtual nsresult GetExprResult(txAExprResult **aExprResult) = 0;
     virtual nsresult Clone(nsIXPathResult **aResult) = 0;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIXPathResult, NS_IXPATHRESULT_IID)
 
+namespace mozilla {
+namespace dom {
+
 /**
  * A class for evaluating an XPath expression string
  */
-class nsXPathResult MOZ_FINAL : public nsIDOMXPathResult,
-                                public nsStubMutationObserver,
-                                public nsIXPathResult
+class XPathResult MOZ_FINAL : public nsIXPathResult,
+                              public nsStubMutationObserver,
+                              public nsWrapperCache
 {
 public:
-    nsXPathResult();
-    nsXPathResult(const nsXPathResult &aResult);
-    ~nsXPathResult();
+    XPathResult(nsINode* aParent);
+    XPathResult(const XPathResult &aResult);
+    ~XPathResult();
+
+    enum {
+        ANY_TYPE = 0U,
+        NUMBER_TYPE = 1U,
+        STRING_TYPE = 2U,
+        BOOLEAN_TYPE = 3U,
+        UNORDERED_NODE_ITERATOR_TYPE = 4U,
+        ORDERED_NODE_ITERATOR_TYPE = 5U,
+        UNORDERED_NODE_SNAPSHOT_TYPE = 6U,
+        ORDERED_NODE_SNAPSHOT_TYPE = 7U,
+        ANY_UNORDERED_NODE_TYPE = 8U,
+        FIRST_ORDERED_NODE_TYPE = 9U
+    };
 
     // nsISupports interface
     NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-    NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsXPathResult, nsIDOMXPathResult)
+    NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(XPathResult,
+                                                           nsIXPathResult)
+
+    static XPathResult* FromSupports(nsISupports* aSupports)
+    {
+        return static_cast<XPathResult*>(static_cast<nsIXPathResult*>(aSupports));
+    }
+
+    virtual JSObject* WrapObject(JSContext* aCx);
+    nsINode* GetParentObject() const
+    {
+        return mParent;
+    }
+    uint16_t ResultType() const
+    {
+        return mResultType;
+    }
+    double GetNumberValue(ErrorResult& aRv) const
+    {
+        if (mResultType != NUMBER_TYPE) {
+            aRv.Throw(NS_ERROR_DOM_TYPE_ERR);
+            return 0;
+        }
+
+        return mNumberResult;
+    }
+    void GetStringValue(nsAString &aStringValue, ErrorResult& aRv) const
+    {
+        if (mResultType != STRING_TYPE) {
+            aRv.Throw(NS_ERROR_DOM_TYPE_ERR);
+            return;
+        }
 
-    // nsIDOMXPathResult interface
-    NS_DECL_NSIDOMXPATHRESULT
+        aStringValue = mStringResult;
+    }
+    bool GetBooleanValue(ErrorResult& aRv) const
+    {
+        if (mResultType != BOOLEAN_TYPE) {
+            aRv.Throw(NS_ERROR_DOM_TYPE_ERR);
+            return false;
+        }
+
+        return mBooleanResult;
+    }
+    nsINode* GetSingleNodeValue(ErrorResult& aRv) const
+    {
+        if (!isNode()) {
+            aRv.Throw(NS_ERROR_DOM_TYPE_ERR);
+            return nullptr;
+       }
+
+        return mResultNodes.SafeObjectAt(0);
+    }
+    bool InvalidIteratorState() const
+    {
+        return isIterator() && mInvalidIteratorState;
+    }
+    uint32_t GetSnapshotLength(ErrorResult& aRv) const
+    {
+        if (!isSnapshot()) {
+            aRv.Throw(NS_ERROR_DOM_TYPE_ERR);
+            return 0;
+        }
+
+        return (uint32_t)mResultNodes.Count();
+    }
+    nsINode* IterateNext(ErrorResult& aRv);
+    nsINode* SnapshotItem(uint32_t aIndex, ErrorResult& aRv) const
+    {
+        if (!isSnapshot()) {
+            aRv.Throw(NS_ERROR_DOM_TYPE_ERR);
+            return nullptr;
+        }
+
+        return mResultNodes.SafeObjectAt(aIndex);
+    }
 
     // nsIMutationObserver interface
     NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED
     NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
     NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
     NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
     NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
     NS_DECL_NSIMUTATIONOBSERVER_NODEWILLBEDESTROYED
 
-    // nsIXPathResult interface
     nsresult SetExprResult(txAExprResult *aExprResult, uint16_t aResultType,
                            nsINode* aContextNode) MOZ_OVERRIDE;
     nsresult GetExprResult(txAExprResult **aExprResult) MOZ_OVERRIDE;
     nsresult Clone(nsIXPathResult **aResult) MOZ_OVERRIDE;
     void RemoveObserver();
 private:
     static bool isSnapshot(uint16_t aResultType)
     {
@@ -93,21 +184,25 @@ private:
     }
     bool isNode() const
     {
         return isNode(mResultType);
     }
 
     void Invalidate(const nsIContent* aChangeRoot);
 
+    nsCOMPtr<nsINode> mParent;
     nsRefPtr<txAExprResult> mResult;
-    nsCOMArray<nsIDOMNode> mResultNodes;
+    nsCOMArray<nsINode> mResultNodes;
     nsCOMPtr<nsIDocument> mDocument;
+    nsWeakPtr mContextNode;
     uint32_t mCurrentPos;
     uint16_t mResultType;
-    nsWeakPtr mContextNode;
     bool mInvalidIteratorState;
     bool mBooleanResult;
     double mNumberResult;
     nsString mStringResult;
 };
 
-#endif
+} // namespace dom
+} // namespace mozilla
+
+#endif /* mozilla_dom_XPathResult_h */
--- a/dom/xslt/xpath/moz.build
+++ b/dom/xslt/xpath/moz.build
@@ -1,22 +1,22 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 EXPORTS.mozilla.dom += [
     'XPathEvaluator.h',
+    'XPathResult.h',
 ]
 
 UNIFIED_SOURCES += [
     'nsXPathExpression.cpp',
     'nsXPathNSResolver.cpp',
-    'nsXPathResult.cpp',
     'txBooleanExpr.cpp',
     'txBooleanResult.cpp',
     'txCoreFunctionCall.cpp',
     'txErrorExpr.cpp',
     'txExpr.cpp',
     'txExprLexer.cpp',
     'txExprParser.cpp',
     'txFilterExpr.cpp',
@@ -42,16 +42,17 @@ UNIFIED_SOURCES += [
     'txStringResult.cpp',
     'txUnaryExpr.cpp',
     'txUnionExpr.cpp',
     'txUnionNodeTest.cpp',
     'txVariableRefExpr.cpp',
     'txXPathOptimizer.cpp',
     'txXPCOMExtensionFunction.cpp',
     'XPathEvaluator.cpp',
+    'XPathResult.cpp',
 ]
 
 FAIL_ON_WARNINGS = True
 
 LOCAL_INCLUDES += [
     '../base',
     '../xml',
     '../xslt',
--- a/dom/xslt/xpath/nsXPathExpression.cpp
+++ b/dom/xslt/xpath/nsXPathExpression.cpp
@@ -6,20 +6,21 @@
 #include "mozilla/Move.h"
 #include "nsXPathExpression.h"
 #include "txExpr.h"
 #include "txExprResult.h"
 #include "nsError.h"
 #include "nsIDOMCharacterData.h"
 #include "nsDOMClassInfoID.h"
 #include "nsIDOMDocument.h"
-#include "nsXPathResult.h"
+#include "XPathResult.h"
 #include "txURIUtils.h"
 #include "txXPathTreeWalker.h"
 
+using namespace mozilla::dom;
 using mozilla::Move;
 
 NS_IMPL_CYCLE_COLLECTION(nsXPathExpression, mDocument)
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsXPathExpression)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsXPathExpression)
 
 DOMCI_DATA(XPathExpression, nsXPathExpression)
@@ -110,43 +111,42 @@ nsXPathExpression::EvaluateWithContext(n
 
     EvalContextImpl eContext(*contextNode, aContextPosition, aContextSize,
                              mRecycler);
     nsRefPtr<txAExprResult> exprResult;
     nsresult rv = mExpression->evaluate(&eContext, getter_AddRefs(exprResult));
     NS_ENSURE_SUCCESS(rv, rv);
 
     uint16_t resultType = aType;
-    if (aType == nsIDOMXPathResult::ANY_TYPE) {
+    if (aType == XPathResult::ANY_TYPE) {
         short exprResultType = exprResult->getResultType();
         switch (exprResultType) {
             case txAExprResult::NUMBER:
-                resultType = nsIDOMXPathResult::NUMBER_TYPE;
+                resultType = XPathResult::NUMBER_TYPE;
                 break;
             case txAExprResult::STRING:
-                resultType = nsIDOMXPathResult::STRING_TYPE;
+                resultType = XPathResult::STRING_TYPE;
                 break;
             case txAExprResult::BOOLEAN:
-                resultType = nsIDOMXPathResult::BOOLEAN_TYPE;
+                resultType = XPathResult::BOOLEAN_TYPE;
                 break;
             case txAExprResult::NODESET:
-                resultType = nsIDOMXPathResult::UNORDERED_NODE_ITERATOR_TYPE;
+                resultType = XPathResult::UNORDERED_NODE_ITERATOR_TYPE;
                 break;
             case txAExprResult::RESULT_TREE_FRAGMENT:
                 NS_ERROR("Can't return a tree fragment!");
                 return NS_ERROR_FAILURE;
         }
     }
 
     // We need a result object and it must be our implementation.
     nsCOMPtr<nsIXPathResult> xpathResult = do_QueryInterface(aInResult);
     if (!xpathResult) {
         // Either no aInResult or not one of ours.
-        xpathResult = new nsXPathResult();
-        NS_ENSURE_TRUE(xpathResult, NS_ERROR_OUT_OF_MEMORY);
+        xpathResult = new XPathResult(context);
     }
     rv = xpathResult->SetExprResult(exprResult, resultType, context);
     NS_ENSURE_SUCCESS(rv, rv);
 
     return CallQueryInterface(xpathResult, aResult);
 }
 
 /*
--- a/dom/xslt/xpath/txMozillaXPathTreeWalker.cpp
+++ b/dom/xslt/xpath/txMozillaXPathTreeWalker.cpp
@@ -20,17 +20,17 @@
 #include "nsUnicharUtils.h"
 #include "nsAttrName.h"
 #include "nsTArray.h"
 #include "mozilla/dom/Attr.h"
 #include "mozilla/dom/Element.h"
 #include <stdint.h>
 #include <algorithm>
 
-using mozilla::dom::Attr;
+using namespace mozilla::dom;
 
 const uint32_t kUnknownIndex = uint32_t(-1);
 
 txXPathTreeWalker::txXPathTreeWalker(const txXPathTreeWalker& aOther)
     : mPosition(aOther.mPosition),
       mCurrentIndex(aOther.mCurrentIndex)
 {
 }
@@ -678,21 +678,19 @@ txXPathNativeNode::createXPathNode(nsICo
 {
     nsINode* root = aKeepRootAlive ? txXPathNode::RootOf(aContent) : nullptr;
 
     return new txXPathNode(aContent, txXPathNode::eContent, root);
 }
 
 /* static */
 txXPathNode*
-txXPathNativeNode::createXPathNode(nsIDOMNode* aNode, bool aKeepRootAlive)
+txXPathNativeNode::createXPathNode(nsINode* aNode, bool aKeepRootAlive)
 {
-    uint16_t nodeType;
-    aNode->GetNodeType(&nodeType);
-
+    uint16_t nodeType = aNode->NodeType();
     if (nodeType == nsIDOMNode::ATTRIBUTE_NODE) {
         nsCOMPtr<nsIAttribute> attr = do_QueryInterface(aNode);
         NS_ASSERTION(attr, "doesn't implement nsIAttribute");
 
         mozilla::dom::NodeInfo *nodeInfo = attr->NodeInfo();
         mozilla::dom::Element* parent =
           static_cast<Attr*>(attr.get())->GetElement();
         if (!parent) {
@@ -709,61 +707,57 @@ txXPathNativeNode::createXPathNode(nsIDO
             }
         }
 
         NS_ERROR("Couldn't find the attribute in its parent!");
 
         return nullptr;
     }
 
-    nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
     uint32_t index;
-    nsINode* root = aKeepRootAlive ? node.get() : nullptr;
+    nsINode* root = aKeepRootAlive ? aNode : nullptr;
 
     if (nodeType == nsIDOMNode::DOCUMENT_NODE) {
         index = txXPathNode::eDocument;
     }
     else {
         index = txXPathNode::eContent;
         if (root) {
             root = txXPathNode::RootOf(root);
         }
     }
 
-    return new txXPathNode(node, index, root);
+    return new txXPathNode(aNode, index, root);
 }
 
 /* static */
 txXPathNode*
 txXPathNativeNode::createXPathNode(nsIDOMDocument* aDocument)
 {
     nsCOMPtr<nsIDocument> document = do_QueryInterface(aDocument);
     return new txXPathNode(document);
 }
 
 /* static */
-nsresult
-txXPathNativeNode::getNode(const txXPathNode& aNode, nsIDOMNode** aResult)
+nsINode*
+txXPathNativeNode::getNode(const txXPathNode& aNode)
 {
     if (!aNode.isAttribute()) {
-        return CallQueryInterface(aNode.mNode, aResult);
+        return aNode.mNode;
     }
 
     const nsAttrName* name = aNode.Content()->GetAttrNameAt(aNode.mIndex);
 
     nsAutoString namespaceURI;
     nsContentUtils::NameSpaceManager()->GetNameSpaceURI(name->NamespaceID(), namespaceURI);
 
-    nsCOMPtr<nsIDOMElement> element = do_QueryInterface(aNode.mNode);
-    nsCOMPtr<nsIDOMAttr> attr;
-    element->GetAttributeNodeNS(namespaceURI,
-                                nsDependentAtomString(name->LocalName()),
-                                getter_AddRefs(attr));
-
-    return CallQueryInterface(attr, aResult);
+    nsCOMPtr<Element> element = do_QueryInterface(aNode.mNode);
+    nsDOMAttributeMap* map = element->Attributes();
+    return map->GetNamedItemNS(namespaceURI,
+                               nsDependentAtomString(name->LocalName()));
 }
 
 /* static */
 nsIContent*
 txXPathNativeNode::getContent(const txXPathNode& aNode)
 {
     NS_ASSERTION(aNode.isContent(),
                  "Only call getContent on nsIContent wrappers!");
--- a/dom/xslt/xpath/txXPathTreeWalker.h
+++ b/dom/xslt/xpath/txXPathTreeWalker.h
@@ -112,22 +112,32 @@ public:
       nsIContent* content = aNode.Content();
       return content->IsHTML() && content->IsInHTMLDocument();
     }
 };
 
 class txXPathNativeNode
 {
 public:
+    static txXPathNode* createXPathNode(nsINode* aNode,
+                                        bool aKeepRootAlive = false);
     static txXPathNode* createXPathNode(nsIDOMNode* aNode,
-                                        bool aKeepRootAlive = false);
+                                        bool aKeepRootAlive = false)
+    {
+        nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
+        return createXPathNode(node, aKeepRootAlive);
+    }
     static txXPathNode* createXPathNode(nsIContent* aContent,
                                         bool aKeepRootAlive = false);
     static txXPathNode* createXPathNode(nsIDOMDocument* aDocument);
-    static nsresult getNode(const txXPathNode& aNode, nsIDOMNode** aResult);
+    static nsINode* getNode(const txXPathNode& aNode);
+    static nsresult getNode(const txXPathNode& aNode, nsIDOMNode** aResult)
+    {
+        return CallQueryInterface(getNode(aNode), aResult);
+    }
     static nsIContent* getContent(const txXPathNode& aNode);
     static nsIDocument* getDocument(const txXPathNode& aNode);
     static void addRef(const txXPathNode& aNode)
     {
         NS_ADDREF(aNode.mNode);
     }
     static void release(const txXPathNode& aNode)
     {
--- a/dom/xslt/xslt/txMozillaXMLOutput.cpp
+++ b/dom/xslt/xslt/txMozillaXMLOutput.cpp
@@ -18,37 +18,38 @@
 #include "nsContentCID.h"
 #include "nsNetUtil.h"
 #include "nsUnicharUtils.h"
 #include "nsGkAtoms.h"
 #include "txLog.h"
 #include "nsIConsoleService.h"
 #include "nsIDOMDocumentFragment.h"
 #include "nsNameSpaceManager.h"
-#include "nsCSSStyleSheet.h"
 #include "txStringUtils.h"
 #include "txURIUtils.h"
 #include "nsIHTMLDocument.h"
 #include "nsIStyleSheetLinkingElement.h"
 #include "nsIDocumentTransformer.h"
+#include "mozilla/CSSStyleSheet.h"
 #include "mozilla/css/Loader.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/EncodingUtils.h"
 #include "nsContentUtils.h"
 #include "txXMLUtils.h"
 #include "nsContentSink.h"
 #include "nsINode.h"
 #include "nsContentCreatorFunctions.h"
 #include "nsError.h"
 #include "nsIFrame.h"
 #include <algorithm>
 #include "nsTextNode.h"
 #include "mozilla/dom/Comment.h"
 #include "mozilla/dom/ProcessingInstruction.h"
 
+using namespace mozilla;
 using namespace mozilla::dom;
 
 #define TX_ENSURE_CURRENTNODE                           \
     NS_ASSERTION(mCurrentNode, "mCurrentNode is nullptr"); \
     if (!mCurrentNode)                                  \
         return NS_ERROR_UNEXPECTED
 
 txMozillaXMLOutput::txMozillaXMLOutput(txOutputFormat* aFormat,
@@ -976,17 +977,17 @@ txTransformNotifier::ScriptEvaluated(nsr
     if (mScriptElements.RemoveObject(aElement)) {
         SignalTransformEnd();
     }
 
     return NS_OK;
 }
 
 NS_IMETHODIMP 
-txTransformNotifier::StyleSheetLoaded(nsCSSStyleSheet* aSheet,
+txTransformNotifier::StyleSheetLoaded(CSSStyleSheet* aSheet,
                                       bool aWasAlternate,
                                       nsresult aStatus)
 {
     if (mPendingStylesheetCount == 0) {
         // We weren't waiting on this stylesheet anyway.  This can happen if
         // SignalTransformEnd got called with an error aResult.  See
         // http://bugzilla.mozilla.org/show_bug.cgi?id=215465.
         return NS_OK;
--- a/dom/xslt/xslt/txMozillaXMLOutput.h
+++ b/dom/xslt/xslt/txMozillaXMLOutput.h
@@ -33,17 +33,17 @@ class txTransformNotifier MOZ_FINAL : pu
 {
 public:
     txTransformNotifier();
 
     NS_DECL_ISUPPORTS
     NS_DECL_NSISCRIPTLOADEROBSERVER
     
     // nsICSSLoaderObserver
-    NS_IMETHOD StyleSheetLoaded(nsCSSStyleSheet* aSheet,
+    NS_IMETHOD StyleSheetLoaded(mozilla::CSSStyleSheet* aSheet,
                                 bool aWasAlternate,
                                 nsresult aStatus) MOZ_OVERRIDE;
 
     void Init(nsITransformObserver* aObserver);
     nsresult AddScriptElement(nsIScriptElement* aElement);
     void AddPendingStylesheet();
     void OnTransformEnd(nsresult aResult = NS_OK);
     void OnTransformStart();
--- a/dom/xslt/xslt/txMozillaXSLTProcessor.cpp
+++ b/dom/xslt/xslt/txMozillaXSLTProcessor.cpp
@@ -15,17 +15,17 @@
 #include "nsIDOMDocument.h"
 #include "nsIDOMDocumentFragment.h"
 #include "nsIDOMNodeList.h"
 #include "nsIIOService.h"
 #include "nsILoadGroup.h"
 #include "nsIStringBundle.h"
 #include "nsIURI.h"
 #include "nsNetUtil.h"
-#include "nsXPathResult.h"
+#include "XPathResult.h"
 #include "txExecutionState.h"
 #include "txMozillaTextOutput.h"
 #include "txMozillaXMLOutput.h"
 #include "txURIUtils.h"
 #include "txXMLUtils.h"
 #include "txUnknownHandler.h"
 #include "txXSLTProcessor.h"
 #include "nsIPrincipal.h"
@@ -804,17 +804,17 @@ txMozillaXSLTProcessor::SetParameter(con
                         NS_ENSURE_SUCCESS(rv, rv);
 
                         if (!nsContentUtils::CanCallerAccess(node)) {
                             return NS_ERROR_DOM_SECURITY_ERR;
                         }
                     }
                 }
 
-                // Clone the nsXPathResult so that mutations don't affect this
+                // Clone the XPathResult so that mutations don't affect this
                 // variable.
                 nsCOMPtr<nsIXPathResult> clone;
                 rv = xpathResult->Clone(getter_AddRefs(clone));
                 NS_ENSURE_SUCCESS(rv, rv);
 
                 nsCOMPtr<nsIWritableVariant> variant =
                     do_CreateInstance("@mozilla.org/variant;1", &rv);
                 NS_ENSURE_SUCCESS(rv, rv);
--- a/editor/idl/nsIEditorStyleSheets.idl
+++ b/editor/idl/nsIEditorStyleSheets.idl
@@ -1,20 +1,22 @@
 /* -*- Mode: C++; 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/. */
 
 #include "nsISupports.idl"
 
 %{C++
-class nsCSSStyleSheet;
+namespace mozilla {
+class CSSStyleSheet;
+} // namespace mozilla
 %}
 
-[ptr] native nsCSSStyleSheet(nsCSSStyleSheet);
+[ptr] native CSSStyleSheet(mozilla::CSSStyleSheet);
 
 [scriptable, uuid(4805e682-49b9-11d3-9ce4-ed60bd6cb5bc)]
 
 interface nsIEditorStyleSheets : nsISupports
 {
   /** Load and apply the style sheet, specified by aURL, to the
     * editor's document, replacing the last style sheet added (if any).
     * This is always asynchronous, and may cause network I/O.
@@ -70,22 +72,22 @@ interface nsIEditorStyleSheets : nsISupp
   /** Enable or disable the given style sheet from the editor's document
     * This is always synchronous
     *
     * @param aURL  The style sheet to be enabled or disabled
     * @param aEnable true to enable, or false to disable the style sheet
     */
   void enableStyleSheet(in AString aURL, in boolean aEnable);
 
-  /** Get the nsCSSStyleSheet associated with the given URL.
+  /** Get the CSSStyleSheet associated with the given URL.
     *
     * @param aURL         The style sheet's URL
     * @return             the style sheet
     */
-  [noscript] nsCSSStyleSheet getStyleSheetForURL(in AString aURL);
+  [noscript] CSSStyleSheet getStyleSheetForURL(in AString aURL);
 
-  /** Get the URL associated with the given nsCSSStyleSheet.
+  /** Get the URL associated with the given CSSStyleSheet.
     *
     * @param aStyleSheet  The style sheet
     * @return             the style sheet's URL
     */
-  [noscript] AString getURLForStyleSheet(in nsCSSStyleSheet aStyleSheet);
+  [noscript] AString getURLForStyleSheet(in CSSStyleSheet aStyleSheet);
 };
--- a/editor/libeditor/base/nsEditPropertyAtomList.h
+++ b/editor/libeditor/base/nsEditPropertyAtomList.h
@@ -126,16 +126,21 @@ EDITOR_ATOM(nav, "nav")
 EDITOR_ATOM(noscript, "noscript")
 EDITOR_ATOM(object, "object")
 EDITOR_ATOM(ol, "ol")
 EDITOR_ATOM(output, "output")
 EDITOR_ATOM(p, "p")
 EDITOR_ATOM(pre, "pre")
 EDITOR_ATOM(progress, "progress")
 EDITOR_ATOM(q, "q")
+EDITOR_ATOM(rb, "rb")
+EDITOR_ATOM(rp, "rp")
+EDITOR_ATOM(rt, "rt")
+EDITOR_ATOM(rtc, "rtc")
+EDITOR_ATOM(ruby, "ruby")
 EDITOR_ATOM(samp, "samp")
 EDITOR_ATOM(script, "script")
 EDITOR_ATOM(section, "section")
 EDITOR_ATOM(select, "select")
 EDITOR_ATOM(size, "size")
 EDITOR_ATOM(small, "small")
 EDITOR_ATOM(span, "span")
 EDITOR_ATOM(s, "s")
--- a/editor/libeditor/base/nsEditor.cpp
+++ b/editor/libeditor/base/nsEditor.cpp
@@ -4421,33 +4421,33 @@ nsEditor::CreateTxnForIMEText(const nsAS
     txn.forget(aTxn);
   }
 
   return rv;
 }
 
 
 NS_IMETHODIMP 
-nsEditor::CreateTxnForAddStyleSheet(nsCSSStyleSheet* aSheet, AddStyleSheetTxn* *aTxn)
+nsEditor::CreateTxnForAddStyleSheet(CSSStyleSheet* aSheet, AddStyleSheetTxn* *aTxn)
 {
   nsRefPtr<AddStyleSheetTxn> txn = new AddStyleSheetTxn();
 
   nsresult rv = txn->Init(this, aSheet);
   if (NS_SUCCEEDED(rv))
   {
     txn.forget(aTxn);
   }
 
   return rv;
 }
 
 
 
 NS_IMETHODIMP 
-nsEditor::CreateTxnForRemoveStyleSheet(nsCSSStyleSheet* aSheet, RemoveStyleSheetTxn* *aTxn)
+nsEditor::CreateTxnForRemoveStyleSheet(CSSStyleSheet* aSheet, RemoveStyleSheetTxn* *aTxn)
 {
   nsRefPtr<RemoveStyleSheetTxn> txn = new RemoveStyleSheetTxn();
 
   nsresult rv = txn->Init(this, aSheet);
   if (NS_SUCCEEDED(rv))
   {
     txn.forget(aTxn);
   }
--- a/editor/libeditor/base/nsEditor.h
+++ b/editor/libeditor/base/nsEditor.h
@@ -34,17 +34,16 @@ class DeleteNodeTxn;
 class DeleteTextTxn;
 class EditAggregateTxn;
 class IMETextTxn;
 class InsertElementTxn;
 class InsertTextTxn;
 class JoinElementTxn;
 class RemoveStyleSheetTxn;
 class SplitElementTxn;
-class nsCSSStyleSheet;
 class nsIAtom;
 class nsIContent;
 class nsIDOMCharacterData;
 class nsIDOMDataTransfer;
 class nsIDOMDocument;
 class nsIDOMElement;
 class nsIDOMEvent;
 class nsIDOMEventListener;
@@ -63,16 +62,17 @@ class nsISelection;
 class nsISupports;
 class nsITransaction;
 class nsIWidget;
 class nsRange;
 class nsString;
 class nsTransactionManager;
 
 namespace mozilla {
+class CSSStyleSheet;
 class ErrorResult;
 class TextComposition;
 
 namespace dom {
 class DataTransfer;
 class Element;
 class EventTarget;
 class Selection;
@@ -316,21 +316,23 @@ protected:
                                     int32_t aOffset,
                                     InsertTextTxn ** aTxn);
 
   NS_IMETHOD CreateTxnForIMEText(const nsAString & aStringToInsert,
                                  IMETextTxn ** aTxn);
 
   /** create a transaction for adding a style sheet
     */
-  NS_IMETHOD CreateTxnForAddStyleSheet(nsCSSStyleSheet* aSheet, AddStyleSheetTxn* *aTxn);
+  NS_IMETHOD CreateTxnForAddStyleSheet(mozilla::CSSStyleSheet* aSheet,
+                                       AddStyleSheetTxn* *aTxn);
 
   /** create a transaction for removing a style sheet
     */
-  NS_IMETHOD CreateTxnForRemoveStyleSheet(nsCSSStyleSheet* aSheet, RemoveStyleSheetTxn* *aTxn);
+  NS_IMETHOD CreateTxnForRemoveStyleSheet(mozilla::CSSStyleSheet* aSheet,
+                                          RemoveStyleSheetTxn* *aTxn);
   
   NS_IMETHOD DeleteText(nsIDOMCharacterData *aElement,
                         uint32_t             aOffset,
                         uint32_t             aLength);
 
   inline nsresult DeleteText(mozilla::dom::Text* aText, uint32_t aOffset,
                              uint32_t aLength)
   {
--- a/editor/libeditor/base/nsStyleSheetTxns.cpp
+++ b/editor/libeditor/base/nsStyleSheetTxns.cpp
@@ -3,25 +3,27 @@
  * 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 <stddef.h>                     // for nullptr
 
 #include "nsAString.h"
 #include "nsCOMPtr.h"                   // for nsCOMPtr, do_QueryInterface, etc
-#include "nsCSSStyleSheet.h"            // for nsCSSStyleSheet
+#include "mozilla/CSSStyleSheet.h"      // for mozilla::CSSStyleSheet
 #include "nsDebug.h"                    // for NS_ENSURE_TRUE
 #include "nsError.h"                    // for NS_OK, etc
 #include "nsIDOMDocument.h"             // for nsIDOMDocument
 #include "nsIDocument.h"                // for nsIDocument
 #include "nsIDocumentObserver.h"        // for UPDATE_STYLE
 #include "nsIEditor.h"                  // for nsIEditor
 #include "nsStyleSheetTxns.h"
 
+using namespace mozilla;
+
 class nsIStyleSheet;
 
 static void
 AddStyleSheet(nsIEditor* aEditor, nsIStyleSheet* aSheet)
 {
   nsCOMPtr<nsIDOMDocument> domDoc;
   aEditor->GetDocument(getter_AddRefs(domDoc));
   nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
@@ -53,17 +55,17 @@ AddStyleSheetTxn::AddStyleSheetTxn()
 
 NS_IMPL_CYCLE_COLLECTION_INHERITED(AddStyleSheetTxn, EditTxn,
                                    mSheet)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AddStyleSheetTxn)
 NS_INTERFACE_MAP_END_INHERITING(EditTxn)
 
 NS_IMETHODIMP
-AddStyleSheetTxn::Init(nsIEditor *aEditor, nsCSSStyleSheet *aSheet)
+AddStyleSheetTxn::Init(nsIEditor *aEditor, CSSStyleSheet *aSheet)
 {
   NS_ENSURE_TRUE(aEditor && aSheet, NS_ERROR_INVALID_ARG);
 
   mEditor = aEditor;
   mSheet = aSheet;
 
   return NS_OK;
 }
@@ -103,17 +105,17 @@ RemoveStyleSheetTxn::RemoveStyleSheetTxn
 
 NS_IMPL_CYCLE_COLLECTION_INHERITED(RemoveStyleSheetTxn, EditTxn,
                                    mSheet)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(RemoveStyleSheetTxn)
 NS_INTERFACE_MAP_END_INHERITING(EditTxn)
 
 NS_IMETHODIMP
-RemoveStyleSheetTxn::Init(nsIEditor *aEditor, nsCSSStyleSheet *aSheet)
+RemoveStyleSheetTxn::Init(nsIEditor *aEditor, CSSStyleSheet *aSheet)
 {
   NS_ENSURE_TRUE(aEditor && aSheet, NS_ERROR_INVALID_ARG);
 
   mEditor = aEditor;
   mSheet = aSheet;
 
   return NS_OK;
 }
--- a/editor/libeditor/base/nsStyleSheetTxns.h
+++ b/editor/libeditor/base/nsStyleSheetTxns.h
@@ -3,67 +3,67 @@
  * 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 nsStylesheetTxns_h__
 #define nsStylesheetTxns_h__
 
 #include "EditTxn.h"                    // for EditTxn, NS_DECL_EDITTXN
 #include "nsAutoPtr.h"                  // for nsRefPtr
-#include "nsCSSStyleSheet.h"            // for nsCSSStyleSheet
+#include "mozilla/CSSStyleSheet.h"      // for mozilla::CSSStyleSheet
 #include "nsCycleCollectionParticipant.h"
 #include "nsID.h"                       // for REFNSIID
-#include "nsISupportsImpl.h"            // for nsCSSStyleSheet::Release
+#include "nsISupportsImpl.h"            // for CSSStyleSheet::Release
 #include "nscore.h"                     // for NS_IMETHOD
 
 class nsIEditor;
 
 class AddStyleSheetTxn : public EditTxn
 {
 public:
   /** Initialize the transaction.
     * @param aEditor the object providing core editing operations
     * @param aSheet   the stylesheet to add
     */
-  NS_IMETHOD Init(nsIEditor         *aEditor,
-                  nsCSSStyleSheet   *aSheet);
+  NS_IMETHOD Init(nsIEditor* aEditor,
+                  mozilla::CSSStyleSheet* aSheet);
 
   AddStyleSheetTxn();
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(AddStyleSheetTxn, EditTxn)
   NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
 
   NS_DECL_EDITTXN
 
 protected:
 
-  nsIEditor*  mEditor;                  // the editor that created this transaction
-  nsRefPtr<nsCSSStyleSheet>  mSheet;    // the style sheet to add
+  nsIEditor* mEditor;                      // the editor that created this transaction
+  nsRefPtr<mozilla::CSSStyleSheet> mSheet; // the style sheet to add
 
 };
 
 
 class RemoveStyleSheetTxn : public EditTxn
 {
 public:
   /** Initialize the transaction.
     * @param aEditor the object providing core editing operations
     * @param aSheet   the stylesheet to remove
     */
-  NS_IMETHOD Init(nsIEditor         *aEditor,
-                  nsCSSStyleSheet   *aSheet);
+  NS_IMETHOD Init(nsIEditor* aEditor,
+                  mozilla::CSSStyleSheet* aSheet);
 
   RemoveStyleSheetTxn();
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(RemoveStyleSheetTxn, EditTxn)
   NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
 
   NS_DECL_EDITTXN
 
 protected:
 
-  nsIEditor*  mEditor;                  // the editor that created this transaction
-  nsRefPtr<nsCSSStyleSheet>  mSheet;    // the style sheet to remove
+  nsIEditor* mEditor;                      // the editor that created this transaction
+  nsRefPtr<mozilla::CSSStyleSheet> mSheet; // the style sheet to remove
 
 };
 
 
 #endif /* nsStylesheetTxns_h__ */
--- a/editor/libeditor/html/nsHTMLEditUtils.cpp
+++ b/editor/libeditor/html/nsHTMLEditUtils.cpp
@@ -529,18 +529,18 @@ nsHTMLEditUtils::SupportsAlignAttr(nsIDO
 #define GROUP_TOPLEVEL         (1 << 1)  
 
 // base, link, meta, script, style, title
 #define GROUP_HEAD_CONTENT     (1 << 2)
 
 // b, big, i, s, small, strike, tt, u
 #define GROUP_FONTSTYLE        (1 << 3)
 
-// abbr, acronym, cite, code, datalist, del, dfn, em, ins, kbd, mark, samp,
-// strong, var
+// abbr, acronym, cite, code, datalist, del, dfn, em, ins, kbd, mark, rb, rp
+// rt, rtc, ruby, samp, strong, var
 #define GROUP_PHRASE           (1 << 4)
 
 // a, applet, basefont, bdo, br, font, iframe, img, map, meter, object, output,
 // progress, q, script, span, sub, sup
 #define GROUP_SPECIAL          (1 << 5)
 
 // button, form, input, label, select, textarea
 #define GROUP_FORMCONTROL      (1 << 6)
@@ -734,16 +734,21 @@ static const nsElementInfo kElements[eHT
        GROUP_SELECT_CONTENT | GROUP_OPTIONS, GROUP_LEAF),
   ELEM(output, true, true, GROUP_SPECIAL, GROUP_INLINE_ELEMENT),
   ELEM(p, true, false, GROUP_BLOCK | GROUP_P, GROUP_INLINE_ELEMENT),
   ELEM(param, false, false, GROUP_OBJECT_CONTENT, GROUP_NONE),
   ELEM(plaintext, false, false, GROUP_NONE, GROUP_NONE),
   ELEM(pre, true, true, GROUP_BLOCK, GROUP_INLINE_ELEMENT),
   ELEM(progress, true, false, GROUP_SPECIAL, GROUP_FLOW_ELEMENT),
   ELEM(q, true, true, GROUP_SPECIAL, GROUP_INLINE_ELEMENT),
+  ELEM(rb, true, true, GROUP_PHRASE, GROUP_INLINE_ELEMENT),
+  ELEM(rp, true, true, GROUP_PHRASE, GROUP_INLINE_ELEMENT),
+  ELEM(rt, true, true, GROUP_PHRASE, GROUP_INLINE_ELEMENT),
+  ELEM(rtc, true, true, GROUP_PHRASE, GROUP_INLINE_ELEMENT),
+  ELEM(ruby, true, true, GROUP_PHRASE, GROUP_INLINE_ELEMENT),
   ELEM(s, true, true, GROUP_FONTSTYLE, GROUP_INLINE_ELEMENT),
   ELEM(samp, true, true, GROUP_PHRASE, GROUP_INLINE_ELEMENT),
   ELEM(script, true, false, GROUP_HEAD_CONTENT | GROUP_SPECIAL,
        GROUP_LEAF),
   ELEM(section, true, true, GROUP_BLOCK, GROUP_FLOW_ELEMENT),
   ELEM(select, true, false, GROUP_FORMCONTROL, GROUP_SELECT_CONTENT),
   ELEM(shadow, true, false, GROUP_NONE, GROUP_INLINE_ELEMENT),
   ELEM(small, true, true, GROUP_FONTSTYLE, GROUP_INLINE_ELEMENT),
--- a/editor/libeditor/html/nsHTMLEditor.cpp
+++ b/editor/libeditor/html/nsHTMLEditor.cpp
@@ -31,18 +31,18 @@
 #include "nsIDOMKeyEvent.h"
 #include "nsIDOMMouseEvent.h"
 #include "nsIDOMHTMLAnchorElement.h"
 #include "nsISelectionController.h"
 #include "nsIDOMHTMLDocument.h"
 #include "nsILinkHandler.h"
 #include "nsIInlineSpellChecker.h"
 
+#include "mozilla/CSSStyleSheet.h"
 #include "mozilla/css/Loader.h"
-#include "nsCSSStyleSheet.h"
 #include "nsIDOMStyleSheet.h"
 
 #include "nsIContent.h"