Merge mozilla-central to autoland
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Thu, 23 Mar 2017 13:59:20 +0100
changeset 399688 3092b9f2090ddf52909ddeafacf72c059112d8ad
parent 399687 01e61eff9b62792fe018936eefc9e142d29613f0 (current diff)
parent 399626 2e95b7e18fcf2b24844e484776c050e0d0c51e70 (diff)
child 399689 8f23d68f4d10c4891f1f92bc12933aa4ab0158ca
push id1490
push usermtabara@mozilla.com
push dateMon, 31 Jul 2017 14:08:16 +0000
treeherdermozilla-release@70e32e6bf15e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone55.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 mozilla-central to autoland
caps/nsExpandedPrincipal.cpp
caps/nsExpandedPrincipal.h
caps/nsNullPrincipal.cpp
caps/nsNullPrincipal.h
caps/nsNullPrincipalURI.cpp
caps/nsNullPrincipalURI.h
caps/nsPrincipal.cpp
caps/nsPrincipal.h
caps/nsSystemPrincipal.cpp
caps/nsSystemPrincipal.h
gfx/thebes/gfxFontconfigFonts.cpp
gfx/thebes/gfxFontconfigUtils.cpp
js/src/wasm/WasmDebugFrame.cpp
js/src/wasm/WasmDebugFrame.h
layout/base/nsPresContext.cpp
toolkit/components/telemetry/Histograms.json
--- a/accessible/base/TextAttrs.cpp
+++ b/accessible/base/TextAttrs.cpp
@@ -13,20 +13,16 @@
 #include "gfxFont.h"
 #include "nsFontMetrics.h"
 #include "nsLayoutUtils.h"
 #include "nsContainerFrame.h"
 #include "HyperTextAccessible.h"
 #include "mozilla/AppUnits.h"
 #include "mozilla/gfx/2D.h"
 
-#if defined(MOZ_WIDGET_GTK)
-#include "gfxPlatformGtk.h" // xxx - for UseFcFontList
-#endif
-
 using namespace mozilla;
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
 // TextAttrsMgr
 ////////////////////////////////////////////////////////////////////////////////
 
 void
@@ -647,38 +643,24 @@ TextAttrsMgr::FontWeightTextAttr::
   // When there doesn't exist a bold font in the family and so the rendering of
   // a non-bold font face is changed so that the user sees what looks like a
   // bold font, i.e. synthetic bolding is used. IsSyntheticBold method is only
   // needed on Mac, but it is "safe" to use on all platforms.  (For non-Mac
   // platforms it always return false.)
   if (font->IsSyntheticBold())
     return 700;
 
-  bool useFontEntryWeight = true;
-
-  // Under Linux, when gfxPangoFontGroup code is used,
-  // font->GetStyle()->weight will give the absolute weight requested of the
-  // font face. The gfxPangoFontGroup code uses the gfxFontEntry constructor
-  // which doesn't initialize the weight field.
-#if defined(MOZ_WIDGET_GTK)
-  useFontEntryWeight = gfxPlatformGtk::UseFcFontList();
-#endif
-
-  if (useFontEntryWeight) {
-    // On Windows, font->GetStyle()->weight will give the same weight as
-    // fontEntry->Weight(), the weight of the first font in the font group,
-    // which may not be the weight of the font face used to render the
-    // characters. On Mac, font->GetStyle()->weight will just give the same
-    // number as getComputedStyle(). fontEntry->Weight() will give the weight
-    // of the font face used.
-    gfxFontEntry *fontEntry = font->GetFontEntry();
-    return fontEntry->Weight();
-  } else {
-    return font->GetStyle()->weight;
-  }
+  // On Windows, font->GetStyle()->weight will give the same weight as
+  // fontEntry->Weight(), the weight of the first font in the font group,
+  // which may not be the weight of the font face used to render the
+  // characters. On Mac, font->GetStyle()->weight will just give the same
+  // number as getComputedStyle(). fontEntry->Weight() will give the weight
+  // of the font face used.
+  gfxFontEntry *fontEntry = font->GetFontEntry();
+  return fontEntry->Weight();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // AutoGeneratedTextAttr
 ////////////////////////////////////////////////////////////////////////////////
 TextAttrsMgr::AutoGeneratedTextAttr::
   AutoGeneratedTextAttr(HyperTextAccessible* aHyperTextAcc,
                         Accessible* aAccessible) :
--- a/accessible/base/nsAccessibilityService.cpp
+++ b/accessible/base/nsAccessibilityService.cpp
@@ -590,16 +590,17 @@ nsAccessibilityService::ContentRemoved(n
     if (!child) {
       Accessible* container = document->GetContainerAccessible(aChildNode);
       a11y::TreeWalker walker(container ? container : document, aChildNode,
                               a11y::TreeWalker::eWalkCache);
       child = walker.Next();
     }
 
     if (child) {
+      MOZ_DIAGNOSTIC_ASSERT(child->Parent(), "Unattached accessible from tree");
       document->ContentRemoved(child->Parent(), aChildNode);
 #ifdef A11Y_LOG
       if (logging::IsEnabled(logging::eTree))
         logging::AccessibleNNode("real container", child->Parent());
 #endif
     }
   }
 
--- a/browser/base/content/pageinfo/permissions.js
+++ b/browser/base/content/pageinfo/permissions.js
@@ -213,27 +213,28 @@ function onIndexedDBClear() {
 }
 
 function onIndexedDBUsageCallback(request) {
   let uri = request.principal.URI;
   if (!uri.equals(gPermURI)) {
     throw new Error("Callback received for bad URI: " + uri);
   }
 
-  if (request.usage) {
+  let usage = request.result.usage;
+  if (usage) {
     if (!("DownloadUtils" in window)) {
       Components.utils.import("resource://gre/modules/DownloadUtils.jsm");
     }
 
     var status = document.getElementById("indexedDBStatus");
     var button = document.getElementById("indexedDBClear");
 
     status.value =
       gBundle.getFormattedString("indexedDBUsage",
-                                 DownloadUtils.convertByteUnits(request.usage));
+                                 DownloadUtils.convertByteUnits(usage));
     status.removeAttribute("hidden");
     button.removeAttribute("hidden");
   }
 }
 
 function fillInPluginPermissionTemplate(aPluginName, aPermissionString) {
   let permPluginTemplate = document.getElementById("permPluginTemplate").cloneNode(true);
   permPluginTemplate.setAttribute("permString", aPermissionString);
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -63,19 +63,16 @@
       <field name="mURIFixup" readonly="true">
         Components.classes["@mozilla.org/docshell/urifixup;1"]
                   .getService(Components.interfaces.nsIURIFixup);
       </field>
       <field name="_unifiedComplete" readonly="true">
          Components.classes["@mozilla.org/autocomplete/search;1?name=unifiedcomplete"]
                    .getService(Components.interfaces.mozIPlacesAutoComplete);
       </field>
-      <field name="AppConstants" readonly="true">
-        (Components.utils.import("resource://gre/modules/AppConstants.jsm", {})).AppConstants;
-      </field>
       <field name="mTabBox" readonly="true">
         document.getAnonymousElementByAttribute(this, "anonid", "tabbox");
       </field>
       <field name="mPanelContainer" readonly="true">
         document.getAnonymousElementByAttribute(this, "anonid", "panelcontainer");
       </field>
       <field name="mStringBundle">
         document.getAnonymousElementByAttribute(this, "anonid", "tbstringbundle");
@@ -103,17 +100,17 @@
       </field>
       <field name="mIsBusy">
         false
       </field>
       <field name="_outerWindowIDBrowserMap">
         new Map();
       </field>
       <field name="arrowKeysShouldWrap" readonly="true">
-        this.AppConstants.platform == "macosx";
+        AppConstants == "macosx";
       </field>
 
       <field name="_autoScrollPopup">
         null
       </field>
 
       <field name="_previewMode">
         false
@@ -2650,26 +2647,28 @@
         <body>
           <![CDATA[
             if (aTab.closing ||
                 this._windowIsClosing)
               return false;
 
             var browser = this.getBrowserForTab(aTab);
 
-            if (!aTab._pendingPermitUnload && !aAdoptedByTab && !aSkipPermitUnload) {
+            if (!aTab._pendingPermitUnload &&
+                !aSkipPermitUnload &&
+                aTab.linkedPanel &&
+                !aAdoptedByTab) {
               // We need to block while calling permitUnload() because it
               // processes the event queue and may lead to another removeTab()
               // call before permitUnload() returns.
 
               TelemetryStopwatch.start("FX_TAB_CLOSE_PERMIT_UNLOAD_TIME_MS", aTab);
 
               aTab._pendingPermitUnload = true;
-              let {permitUnload, timedOut} = aTab.linkedPanel ?
-                  browser.permitUnload() : {permitUnload: true, timedOut: false};
+              let {permitUnload, timedOut} = browser.permitUnload();
               delete aTab._pendingPermitUnload;
 
               TelemetryStopwatch.finish("FX_TAB_CLOSE_PERMIT_UNLOAD_TIME_MS", aTab);
 
               // If we were closed during onbeforeunload, we return false now
               // so we don't (try to) close the same tab again. Of course, we
               // also stop if the unload was cancelled by the user:
               if (aTab.closing || (!timedOut && !permitUnload)) {
@@ -3420,17 +3419,17 @@
         </body>
       </method>
 
       <!-- Opens a given tab to a non-remote window. -->
       <method name="openNonRemoteWindow">
         <parameter name="aTab"/>
         <body>
           <![CDATA[
-            if (!this.AppConstants.E10S_TESTING_ONLY) {
+            if (!AppConstants.E10S_TESTING_ONLY) {
               throw "This method is intended only for e10s testing!";
             }
             let url = aTab.linkedBrowser.currentURI.spec;
             return window.openDialog("chrome://browser/content/", "_blank", "chrome,all,dialog=no,non-remote", url);
           ]]>
         </body>
       </method>
 
@@ -4032,17 +4031,17 @@
               this.lastVisibleTab = this.visibleTab;
             },
 
             assert(cond) {
               if (!cond) {
                 dump("Assertion failure\n" + Error().stack);
 
                 // Don't break a user's browser if an assertion fails.
-                if (this.tabbrowser.AppConstants.DEBUG) {
+                if (AppConstants.DEBUG) {
                   throw new Error("Assertion failure");
                 }
               }
             },
 
             // We've decided to try to load requestedTab.
             loadRequestedTab() {
               this.assert(!this.loadTimer);
@@ -4808,17 +4807,17 @@
                 return;
               case aEvent.DOM_VK_PAGE_DOWN:
                 this.moveTabForward();
                 aEvent.preventDefault();
                 return;
             }
           }
 
-          if (this.AppConstants.platform != "macosx") {
+          if (AppConstants.platform != "macosx") {
             if (aEvent.ctrlKey && !aEvent.shiftKey && !aEvent.metaKey &&
                 aEvent.keyCode == KeyEvent.DOM_VK_F4 &&
                 !this.mCurrentTab.pinned) {
               this.removeCurrentTab({animate: true});
               aEvent.preventDefault();
             }
           }
         ]]></body>
@@ -4830,17 +4829,17 @@
           if (!aEvent.isTrusted) {
             // Don't let untrusted events mess with tabs.
             return;
           }
 
           if (aEvent.altKey)
             return;
 
-          if (this.AppConstants.platform == "macosx") {
+          if (AppConstants.platform == "macosx") {
             if (!aEvent.metaKey)
               return;
 
             var offset = 1;
             switch (aEvent.charCode) {
               case "}".charCodeAt(0):
                 offset = -1;
               case "{".charCodeAt(0):
@@ -4893,17 +4892,17 @@
                   "tabs.unmuteAudio.background.tooltip" :
                   "tabs.muteAudio.background.tooltip";
               }
 
               label = this.mStringBundle.getString(stringID);
             }
           } else {
             label = tab.getAttribute("label");
-            if (this.AppConstants.E10S_TESTING_ONLY &&
+            if (AppConstants.E10S_TESTING_ONLY &&
                 tab.linkedBrowser &&
                 tab.linkedBrowser.isRemoteBrowser) {
               label += " - e10s";
               if (Services.prefs.getIntPref("dom.ipc.processCount") > 1) {
                 label += " (" + tab.linkedBrowser.frameLoader.tabParent.osPid + ")";
               }
             }
             if (tab.userContextId) {
@@ -5176,17 +5175,17 @@
           Services.obs.addObserver(this, "contextual-identity-updated", false);
 
           this.mCurrentTab = this.tabContainer.firstChild;
           const nsIEventListenerService =
             Components.interfaces.nsIEventListenerService;
           let els = Components.classes["@mozilla.org/eventlistenerservice;1"]
                               .getService(nsIEventListenerService);
           els.addSystemEventListener(document, "keydown", this, false);
-          if (this.AppConstants.platform == "macosx") {
+          if (AppConstants.platform == "macosx") {
             els.addSystemEventListener(document, "keypress", this, false);
           }
           window.addEventListener("sizemodechange", this);
 
           var uniqueId = this._generateUniquePanelID();
           this.mPanelContainer.childNodes[0].id = uniqueId;
           this.mCurrentTab.linkedPanel = uniqueId;
           this.mCurrentTab.permanentKey = this.mCurrentBrowser.permanentKey;
@@ -5293,17 +5292,17 @@
             this._tabFilters.delete(tab);
             this._tabListeners.delete(tab);
           }
           const nsIEventListenerService =
             Components.interfaces.nsIEventListenerService;
           let els = Components.classes["@mozilla.org/eventlistenerservice;1"]
                               .getService(nsIEventListenerService);
           els.removeSystemEventListener(document, "keydown", this, false);
-          if (this.AppConstants.platform == "macosx") {
+          if (AppConstants.platform == "macosx") {
             els.removeSystemEventListener(document, "keypress", this, false);
           }
           window.removeEventListener("sizemodechange", this);
 
           if (gMultiProcessBrowser) {
             let messageManager = window.getGroupMessageManager("browsers");
             messageManager.removeMessageListener("DOMTitleChanged", this);
             window.messageManager.removeMessageListener("contextmenu", this);
@@ -6653,17 +6652,17 @@
         event.stopPropagation();
       ]]></handler>
 
       <handler event="keydown" group="system"><![CDATA[
         if (event.altKey || event.shiftKey)
           return;
 
         let wrongModifiers;
-        if (this.tabbrowser.AppConstants.platform == "macosx") {
+        if (AppConstants.platform == "macosx") {
           wrongModifiers = !event.metaKey;
         } else {
           wrongModifiers = !event.ctrlKey || event.metaKey;
         }
 
         if (wrongModifiers)
           return;
 
@@ -6736,17 +6735,17 @@
         let toDrag = canvas;
         let dragImageOffset = -16;
         if (gMultiProcessBrowser) {
           var context = canvas.getContext("2d");
           context.fillStyle = "white";
           context.fillRect(0, 0, canvas.width, canvas.height);
 
           let captureListener;
-          let platform = this.tabbrowser.AppConstants.platform;
+          let platform = AppConstants.platform;
           // On Windows and Mac we can update the drag image during a drag
           // using updateDragImage. On Linux, we can use a panel.
           if (platform == "win" || platform == "macosx") {
             captureListener = function() {
               dt.updateDragImage(canvas, dragImageOffset, dragImageOffset);
             }
           } else {
             // Create a panel to use it in setDragImage
@@ -7021,17 +7020,17 @@
           // resize _before_ move to ensure the window fits the new screen.  if
           // the window is too large for its screen, the window manager may do
           // automatic repositioning.
           window.resizeTo(winWidth, winHeight);
           window.moveTo(left, top);
           window.focus();
         } else {
           let props = { screenX: left, screenY: top };
-          if (this.tabbrowser.AppConstants.platform != "win") {
+          if (AppConstants.platform != "win") {
             props.outerWidth = winWidth;
             props.outerHeight = winHeight;
           }
           this.tabbrowser.replaceTabWithWindow(draggedTab, props);
         }
         event.stopPropagation();
       ]]></handler>
 
--- a/browser/components/preferences/SiteDataManager.jsm
+++ b/browser/components/preferences/SiteDataManager.jsm
@@ -78,17 +78,17 @@ this.SiteDataManager = {
 
   _updateQuota() {
     this._quotaUsageRequests = [];
     let promises = [];
     for (let site of this._sites.values()) {
       promises.push(new Promise(resolve => {
         let callback = {
           onUsageResult(request) {
-            site.quotaUsage = request.usage;
+            site.quotaUsage = request.result.usage;
             resolve();
           }
         };
         // XXX: The work of integrating localStorage into Quota Manager is in progress.
         //      After the bug 742822 and 1286798 landed, localStorage usage will be included.
         //      So currently only get indexedDB usage.
         this._quotaUsageRequests.push(
           this._qms.getUsageForPrincipal(site.perm.principal, callback));
--- a/browser/components/preferences/in-content-old/tests/browser_advanced_siteData.js
+++ b/browser/components/preferences/in-content-old/tests/browser_advanced_siteData.js
@@ -127,17 +127,17 @@ function getPersistentStoragePermStatus(
   let principal = Services.scriptSecurityManager.createCodebasePrincipal(uri, {});
   return Services.perms.testExactPermissionFromPrincipal(principal, "persistent-storage");
 }
 
 function getQuotaUsage(origin) {
   return new Promise(resolve => {
     let uri = NetUtil.newURI(origin);
     let principal = Services.scriptSecurityManager.createCodebasePrincipal(uri, {});
-    Services.qms.getUsageForPrincipal(principal, request => resolve(request.usage));
+    Services.qms.getUsageForPrincipal(principal, request => resolve(request.result.usage));
   });
 }
 
 // XXX: The intermittent bug 1331851
 // The implementation of nsICacheStorageConsumptionObserver must be passed as weak referenced,
 // so we must hold this observer here well. If we didn't, there would be a chance that
 // in Linux debug test run the observer was released before the operation at gecko was completed
 // (may be because of a relatively quicker GC cycle or a relatively slower operation).
--- a/browser/components/preferences/in-content/tests/browser_advanced_siteData.js
+++ b/browser/components/preferences/in-content/tests/browser_advanced_siteData.js
@@ -127,17 +127,17 @@ function getPersistentStoragePermStatus(
   let principal = Services.scriptSecurityManager.createCodebasePrincipal(uri, {});
   return Services.perms.testExactPermissionFromPrincipal(principal, "persistent-storage");
 }
 
 function getQuotaUsage(origin) {
   return new Promise(resolve => {
     let uri = NetUtil.newURI(origin);
     let principal = Services.scriptSecurityManager.createCodebasePrincipal(uri, {});
-    Services.qms.getUsageForPrincipal(principal, request => resolve(request.usage));
+    Services.qms.getUsageForPrincipal(principal, request => resolve(request.result.usage));
   });
 }
 
 // XXX: The intermittent bug 1331851
 // The implementation of nsICacheStorageConsumptionObserver must be passed as weak referenced,
 // so we must hold this observer here well. If we didn't, there would be a chance that
 // in Linux debug test run the observer was released before the operation at gecko was completed
 // (may be because of a relatively quicker GC cycle or a relatively slower operation).
--- a/build/macosx/local-mozconfig.common
+++ b/build/macosx/local-mozconfig.common
@@ -27,16 +27,21 @@ elif [ -d "$topsrcdir/../clang" ]; then
     ldflags="-B$topsrcdir/../cctools/bin"
 fi
 
 # Ensure the updated linker doesn't generate things our older build tools
 # don't understand.
 ldflags="$ldflags -Wl,-no_data_in_code_info"
 export LDFLAGS="$ldflags"
 
+# Until bug 1342503 is fixed, we can't build some of the webrender dependencies
+# on buildbot OS X builders, because rustc will use some random system toolchain
+# instead of the one we package with tooltool.
+ac_add_options --disable-webrender
+
 # If not set use the system default clang
 if [ -z "$CC" ]; then
     export CC=clang
 fi
 
 # If not set use the system default clang++
 if [ -z "$CXX" ]; then
     export CXX=clang++
--- a/build/valgrind/i386-redhat-linux-gnu.sup
+++ b/build/valgrind/i386-redhat-linux-gnu.sup
@@ -14,26 +14,16 @@
 {
    Bug 793598
    Memcheck:Leak
    ...
    obj:/lib/libdbus-1.so.3.4.0
    ...
 }
 {
-   Bug 793600
-   Memcheck:Leak
-   fun:realloc
-   obj:/usr/lib/libfontconfig.so.1.4.4
-   ...
-   fun:FcDefaultSubstitute
-   fun:_ZN17gfxPangoFontGroup11MakeFontSetEP14_PangoLanguagedP9nsAutoRefI10_FcPatternE
-   ...
-}
-{
    Bug 794366
    Memcheck:Leak
    ...
    obj:/usr/lib/libgtk-x11-2.0.so.0.1800.9
    ...
 }
 {
    Bug 794368
--- a/build/valgrind/x86_64-redhat-linux-gnu.sup
+++ b/build/valgrind/x86_64-redhat-linux-gnu.sup
@@ -13,26 +13,16 @@
 }
 {
    Bug 793598
    Memcheck:Leak
    ...
    obj:/lib64/libdbus-1.so.3.4.0
    ...
 }
-{
-   Bug 793600
-   Memcheck:Leak
-   fun:realloc
-   obj:/usr/lib64/libfontconfig.so.1.4.4
-   ...
-   fun:FcDefaultSubstitute
-   fun:_ZN17gfxPangoFontGroup11MakeFontSetEP14_PangoLanguagedP9nsAutoRefI10_FcPatternE
-   ...
-}
 # Fontconfig is going fancy with its cache structure and that confuses valgrind.
 # https://bugs.freedesktop.org/show_bug.cgi?id=8215
 # https://bugs.freedesktop.org/show_bug.cgi?id=8428
 {
    Bug 1187649
    Memcheck:Leak
    match-leak-kinds: definite
    fun:realloc
--- a/caps/BasePrincipal.cpp
+++ b/caps/BasePrincipal.cpp
@@ -7,302 +7,32 @@
 #include "mozilla/BasePrincipal.h"
 
 #include "nsDocShell.h"
 #ifdef MOZ_CRASHREPORTER
 #include "nsExceptionHandler.h"
 #endif
 #include "nsIAddonPolicyService.h"
 #include "nsIContentSecurityPolicy.h"
-#include "nsIEffectiveTLDService.h"
 #include "nsIObjectInputStream.h"
 #include "nsIObjectOutputStream.h"
 
-#include "nsPrincipal.h"
+#include "ContentPrincipal.h"
 #include "nsNetUtil.h"
 #include "nsIURIWithPrincipal.h"
-#include "nsNullPrincipal.h"
+#include "NullPrincipal.h"
 #include "nsScriptSecurityManager.h"
 #include "nsServiceManagerUtils.h"
 
 #include "mozilla/dom/ChromeUtils.h"
 #include "mozilla/dom/CSPDictionariesBinding.h"
-#include "mozilla/dom/quota/QuotaManager.h"
 #include "mozilla/dom/ToJSValue.h"
-#include "mozilla/dom/URLSearchParams.h"
 
 namespace mozilla {
 
-using dom::URLParams;
-
-bool OriginAttributes::sFirstPartyIsolation = false;
-bool OriginAttributes::sRestrictedOpenerAccess = false;
-
-void
-OriginAttributes::InitPrefs()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  static bool sInited = false;
-  if (!sInited) {
-    sInited = true;
-    Preferences::AddBoolVarCache(&sFirstPartyIsolation,
-                                 "privacy.firstparty.isolate");
-    Preferences::AddBoolVarCache(&sRestrictedOpenerAccess,
-                                 "privacy.firstparty.isolate.restrict_opener_access");
-  }
-}
-
-void
-OriginAttributes::SetFirstPartyDomain(const bool aIsTopLevelDocument,
-                                      nsIURI* aURI)
-{
-  bool isFirstPartyEnabled = IsFirstPartyEnabled();
-
-  // If the pref is off or this is not a top level load, bail out.
-  if (!isFirstPartyEnabled || !aIsTopLevelDocument) {
-    return;
-  }
-
-  nsCOMPtr<nsIEffectiveTLDService> tldService =
-    do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID);
-  MOZ_ASSERT(tldService);
-  if (!tldService) {
-    return;
-  }
-
-  nsAutoCString baseDomain;
-  nsresult rv = tldService->GetBaseDomain(aURI, 0, baseDomain);
-  if (NS_FAILED(rv)) {
-    nsAutoCString scheme;
-    rv = aURI->GetScheme(scheme);
-    NS_ENSURE_SUCCESS_VOID(rv);
-    if (scheme.EqualsLiteral("about")) {
-      baseDomain.AssignLiteral(ABOUT_URI_FIRST_PARTY_DOMAIN);
-    }
-  }
-
-  mFirstPartyDomain = NS_ConvertUTF8toUTF16(baseDomain);
-}
-
-void
-OriginAttributes::SetFirstPartyDomain(const bool aIsTopLevelDocument,
-                                      const nsACString& aDomain)
-{
-  bool isFirstPartyEnabled = IsFirstPartyEnabled();
-
-  // If the pref is off or this is not a top level load, bail out.
-  if (!isFirstPartyEnabled || !aIsTopLevelDocument) {
-    return;
-  }
-
-  mFirstPartyDomain = NS_ConvertUTF8toUTF16(aDomain);
-}
-
-void
-OriginAttributes::CreateSuffix(nsACString& aStr) const
-{
-  URLParams params;
-  nsAutoString value;
-
-  //
-  // Important: While serializing any string-valued attributes, perform a
-  // release-mode assertion to make sure that they don't contain characters that
-  // will break the quota manager when it uses the serialization for file
-  // naming.
-  //
-
-  if (mAppId != nsIScriptSecurityManager::NO_APP_ID) {
-    value.AppendInt(mAppId);
-    params.Set(NS_LITERAL_STRING("appId"), value);
-  }
-
-  if (mInIsolatedMozBrowser) {
-    params.Set(NS_LITERAL_STRING("inBrowser"), NS_LITERAL_STRING("1"));
-  }
-
-  if (mUserContextId != nsIScriptSecurityManager::DEFAULT_USER_CONTEXT_ID) {
-    value.Truncate();
-    value.AppendInt(mUserContextId);
-    params.Set(NS_LITERAL_STRING("userContextId"), value);
-  }
-
-
-  if (mPrivateBrowsingId) {
-    value.Truncate();
-    value.AppendInt(mPrivateBrowsingId);
-    params.Set(NS_LITERAL_STRING("privateBrowsingId"), value);
-  }
-
-  if (!mFirstPartyDomain.IsEmpty()) {
-    MOZ_RELEASE_ASSERT(mFirstPartyDomain.FindCharInSet(dom::quota::QuotaManager::kReplaceChars) == kNotFound);
-    params.Set(NS_LITERAL_STRING("firstPartyDomain"), mFirstPartyDomain);
-  }
-
-  aStr.Truncate();
-
-  params.Serialize(value);
-  if (!value.IsEmpty()) {
-    aStr.AppendLiteral("^");
-    aStr.Append(NS_ConvertUTF16toUTF8(value));
-  }
-
-// In debug builds, check the whole string for illegal characters too (just in case).
-#ifdef DEBUG
-  nsAutoCString str;
-  str.Assign(aStr);
-  MOZ_ASSERT(str.FindCharInSet(dom::quota::QuotaManager::kReplaceChars) == kNotFound);
-#endif
-}
-
-void
-OriginAttributes::CreateAnonymizedSuffix(nsACString& aStr) const
-{
-  OriginAttributes attrs = *this;
-
-  if (!attrs.mFirstPartyDomain.IsEmpty()) {
-    attrs.mFirstPartyDomain.AssignLiteral("_anonymizedFirstPartyDomain_");
-  }
-
-  attrs.CreateSuffix(aStr);
-}
-
-namespace {
-
-class MOZ_STACK_CLASS PopulateFromSuffixIterator final
-  : public URLParams::ForEachIterator
-{
-public:
-  explicit PopulateFromSuffixIterator(OriginAttributes* aOriginAttributes)
-    : mOriginAttributes(aOriginAttributes)
-  {
-    MOZ_ASSERT(aOriginAttributes);
-    // If mPrivateBrowsingId is passed in as >0 and is not present in the suffix,
-    // then it will remain >0 when it should be 0 according to the suffix. Set to 0 before
-    // iterating to fix this.
-    mOriginAttributes->mPrivateBrowsingId = 0;
-  }
-
-  bool URLParamsIterator(const nsString& aName,
-                         const nsString& aValue) override
-  {
-    if (aName.EqualsLiteral("appId")) {
-      nsresult rv;
-      int64_t val  = aValue.ToInteger64(&rv);
-      NS_ENSURE_SUCCESS(rv, false);
-      NS_ENSURE_TRUE(val <= UINT32_MAX, false);
-      mOriginAttributes->mAppId = static_cast<uint32_t>(val);
-
-      return true;
-    }
-
-    if (aName.EqualsLiteral("inBrowser")) {
-      if (!aValue.EqualsLiteral("1")) {
-        return false;
-      }
-
-      mOriginAttributes->mInIsolatedMozBrowser = true;
-      return true;
-    }
-
-    if (aName.EqualsLiteral("addonId")) {
-      // No longer supported. Silently ignore so that legacy origin strings
-      // don't cause failures.
-      return true;
-    }
-
-    if (aName.EqualsLiteral("userContextId")) {
-      nsresult rv;
-      int64_t val  = aValue.ToInteger64(&rv);
-      NS_ENSURE_SUCCESS(rv, false);
-      NS_ENSURE_TRUE(val <= UINT32_MAX, false);
-      mOriginAttributes->mUserContextId  = static_cast<uint32_t>(val);
-
-      return true;
-    }
-
-    if (aName.EqualsLiteral("privateBrowsingId")) {
-      nsresult rv;
-      int64_t val = aValue.ToInteger64(&rv);
-      NS_ENSURE_SUCCESS(rv, false);
-      NS_ENSURE_TRUE(val >= 0 && val <= UINT32_MAX, false);
-      mOriginAttributes->mPrivateBrowsingId = static_cast<uint32_t>(val);
-
-      return true;
-    }
-
-    if (aName.EqualsLiteral("firstPartyDomain")) {
-      MOZ_RELEASE_ASSERT(mOriginAttributes->mFirstPartyDomain.IsEmpty());
-      mOriginAttributes->mFirstPartyDomain.Assign(aValue);
-      return true;
-    }
-
-    // No other attributes are supported.
-    return false;
-  }
-
-private:
-  OriginAttributes* mOriginAttributes;
-};
-
-} // namespace
-
-bool
-OriginAttributes::PopulateFromSuffix(const nsACString& aStr)
-{
-  if (aStr.IsEmpty()) {
-    return true;
-  }
-
-  if (aStr[0] != '^') {
-    return false;
-  }
-
-  URLParams params;
-  params.ParseInput(Substring(aStr, 1, aStr.Length() - 1));
-
-  PopulateFromSuffixIterator iterator(this);
-  return params.ForEach(iterator);
-}
-
-bool
-OriginAttributes::PopulateFromOrigin(const nsACString& aOrigin,
-                                     nsACString& aOriginNoSuffix)
-{
-  // RFindChar is only available on nsCString.
-  nsCString origin(aOrigin);
-  int32_t pos = origin.RFindChar('^');
-
-  if (pos == kNotFound) {
-    aOriginNoSuffix = origin;
-    return true;
-  }
-
-  aOriginNoSuffix = Substring(origin, 0, pos);
-  return PopulateFromSuffix(Substring(origin, pos));
-}
-
-void
-OriginAttributes::SyncAttributesWithPrivateBrowsing(bool aInPrivateBrowsing)
-{
-  mPrivateBrowsingId = aInPrivateBrowsing ? 1 : 0;
-}
-
-/* static */
-bool
-OriginAttributes::IsPrivateBrowsing(const nsACString& aOrigin)
-{
-  nsAutoCString dummy;
-  OriginAttributes attrs;
-  if (NS_WARN_IF(!attrs.PopulateFromOrigin(aOrigin, dummy))) {
-    return false;
-  }
-
-  return !!attrs.mPrivateBrowsingId;
-}
-
 BasePrincipal::BasePrincipal(PrincipalKind aKind)
   : mKind(aKind)
   , mDomainSet(false)
 {}
 
 BasePrincipal::~BasePrincipal()
 {}
 
@@ -640,46 +370,46 @@ already_AddRefed<BasePrincipal>
 BasePrincipal::CreateCodebasePrincipal(nsIURI* aURI, const OriginAttributes& aAttrs)
 {
   // If the URI is supposed to inherit the security context of whoever loads it,
   // we shouldn't make a codebase principal for it.
   bool inheritsPrincipal;
   nsresult rv = NS_URIChainHasFlags(aURI, nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
                                     &inheritsPrincipal);
   if (NS_FAILED(rv) || inheritsPrincipal) {
-    return nsNullPrincipal::Create(aAttrs);
+    return NullPrincipal::Create(aAttrs);
   }
 
   // Check whether the URI knows what its principal is supposed to be.
   nsCOMPtr<nsIURIWithPrincipal> uriPrinc = do_QueryInterface(aURI);
   if (uriPrinc) {
     nsCOMPtr<nsIPrincipal> principal;
     uriPrinc->GetPrincipal(getter_AddRefs(principal));
     if (!principal) {
-      return nsNullPrincipal::Create(aAttrs);
+      return NullPrincipal::Create(aAttrs);
     }
     RefPtr<BasePrincipal> concrete = Cast(principal);
     return concrete.forget();
   }
 
   // Mint a codebase principal.
-  RefPtr<nsPrincipal> codebase = new nsPrincipal();
+  RefPtr<ContentPrincipal> codebase = new ContentPrincipal();
   rv = codebase->Init(aURI, aAttrs);
   NS_ENSURE_SUCCESS(rv, nullptr);
   return codebase.forget();
 }
 
 already_AddRefed<BasePrincipal>
 BasePrincipal::CreateCodebasePrincipal(const nsACString& aOrigin)
 {
   MOZ_ASSERT(!StringBeginsWith(aOrigin, NS_LITERAL_CSTRING("[")),
              "CreateCodebasePrincipal does not support System and Expanded principals");
 
   MOZ_ASSERT(!StringBeginsWith(aOrigin, NS_LITERAL_CSTRING(NS_NULLPRINCIPAL_SCHEME ":")),
-             "CreateCodebasePrincipal does not support nsNullPrincipal");
+             "CreateCodebasePrincipal does not support NullPrincipal");
 
   nsAutoCString originNoSuffix;
   mozilla::OriginAttributes attrs;
   if (!attrs.PopulateFromOrigin(aOrigin, originNoSuffix)) {
     return nullptr;
   }
 
   nsCOMPtr<nsIURI> uri;
--- a/caps/BasePrincipal.h
+++ b/caps/BasePrincipal.h
@@ -5,197 +5,27 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_BasePrincipal_h
 #define mozilla_BasePrincipal_h
 
 #include "nsJSPrincipals.h"
 
 #include "mozilla/Attributes.h"
-#include "mozilla/dom/ChromeUtils.h"
-#include "mozilla/dom/ChromeUtilsBinding.h"
-#include "nsIScriptSecurityManager.h"
+#include "mozilla/OriginAttributes.h"
 
 class nsIContentSecurityPolicy;
 class nsIObjectOutputStream;
 class nsIObjectInputStream;
 class nsIURI;
 
-class nsExpandedPrincipal;
+class ExpandedPrincipal;
 
 namespace mozilla {
 
-// Base OriginAttributes class. This has several subclass flavors, and is not
-// directly constructable itself.
-class OriginAttributes : public dom::OriginAttributesDictionary
-{
-public:
-  OriginAttributes() {}
-
-  OriginAttributes(uint32_t aAppId, bool aInIsolatedMozBrowser)
-  {
-    mAppId = aAppId;
-    mInIsolatedMozBrowser = aInIsolatedMozBrowser;
-  }
-
-  explicit OriginAttributes(const OriginAttributesDictionary& aOther)
-    : OriginAttributesDictionary(aOther)
-  {}
-
-  void SetFirstPartyDomain(const bool aIsTopLevelDocument, nsIURI* aURI);
-  void SetFirstPartyDomain(const bool aIsTopLevelDocument, const nsACString& aDomain);
-
-  enum {
-    STRIP_FIRST_PARTY_DOMAIN = 0x01,
-    STRIP_USER_CONTEXT_ID = 0x02,
-  };
-
-  inline void StripAttributes(uint32_t aFlags)
-  {
-    if (aFlags & STRIP_FIRST_PARTY_DOMAIN) {
-      mFirstPartyDomain.Truncate();
-    }
-
-    if (aFlags & STRIP_USER_CONTEXT_ID) {
-      mUserContextId = nsIScriptSecurityManager::DEFAULT_USER_CONTEXT_ID;
-    }
-  }
-
-  bool operator==(const OriginAttributes& aOther) const
-  {
-    return mAppId == aOther.mAppId &&
-           mInIsolatedMozBrowser == aOther.mInIsolatedMozBrowser &&
-           mUserContextId == aOther.mUserContextId &&
-           mPrivateBrowsingId == aOther.mPrivateBrowsingId &&
-           mFirstPartyDomain == aOther.mFirstPartyDomain;
-  }
-
-  bool operator!=(const OriginAttributes& aOther) const
-  {
-    return !(*this == aOther);
-  }
-
-  // Serializes/Deserializes non-default values into the suffix format, i.e.
-  // |!key1=value1&key2=value2|. If there are no non-default attributes, this
-  // returns an empty string.
-  void CreateSuffix(nsACString& aStr) const;
-
-  // Don't use this method for anything else than debugging!
-  void CreateAnonymizedSuffix(nsACString& aStr) const;
-
-  MOZ_MUST_USE bool PopulateFromSuffix(const nsACString& aStr);
-
-  // Populates the attributes from a string like
-  // |uri!key1=value1&key2=value2| and returns the uri without the suffix.
-  MOZ_MUST_USE bool PopulateFromOrigin(const nsACString& aOrigin,
-                                       nsACString& aOriginNoSuffix);
-
-  // Helper function to match mIsPrivateBrowsing to existing private browsing
-  // flags. Once all other flags are removed, this can be removed too.
-  void SyncAttributesWithPrivateBrowsing(bool aInPrivateBrowsing);
-
-  // check if "privacy.firstparty.isolate" is enabled.
-  static inline bool IsFirstPartyEnabled()
-  {
-    return sFirstPartyIsolation;
-  }
-
-  // check if the access of window.opener across different FPDs is restricted.
-  // We only restrict the access of window.opener when first party isolation
-  // is enabled and "privacy.firstparty.isolate.restrict_opener_access" is on.
-  static inline bool IsRestrictOpenerAccessForFPI()
-  {
-    // We always want to restrict window.opener if first party isolation is
-    // disabled.
-    return !sFirstPartyIsolation || sRestrictedOpenerAccess;
-  }
-
-  // returns true if the originAttributes suffix has mPrivateBrowsingId value
-  // different than 0.
-  static bool IsPrivateBrowsing(const nsACString& aOrigin);
-
-  static void InitPrefs();
-
-private:
-  static bool sFirstPartyIsolation;
-  static bool sRestrictedOpenerAccess;
-};
-
-class OriginAttributesPattern : public dom::OriginAttributesPatternDictionary
-{
-public:
-  // To convert a JSON string to an OriginAttributesPattern, do the following:
-  //
-  // OriginAttributesPattern pattern;
-  // if (!pattern.Init(aJSONString)) {
-  //   ... // handle failure.
-  // }
-  OriginAttributesPattern() {}
-
-  explicit OriginAttributesPattern(const OriginAttributesPatternDictionary& aOther)
-    : OriginAttributesPatternDictionary(aOther) {}
-
-  // Performs a match of |aAttrs| against this pattern.
-  bool Matches(const OriginAttributes& aAttrs) const
-  {
-    if (mAppId.WasPassed() && mAppId.Value() != aAttrs.mAppId) {
-      return false;
-    }
-
-    if (mInIsolatedMozBrowser.WasPassed() && mInIsolatedMozBrowser.Value() != aAttrs.mInIsolatedMozBrowser) {
-      return false;
-    }
-
-    if (mUserContextId.WasPassed() && mUserContextId.Value() != aAttrs.mUserContextId) {
-      return false;
-    }
-
-    if (mPrivateBrowsingId.WasPassed() && mPrivateBrowsingId.Value() != aAttrs.mPrivateBrowsingId) {
-      return false;
-    }
-
-    if (mFirstPartyDomain.WasPassed() && mFirstPartyDomain.Value() != aAttrs.mFirstPartyDomain) {
-      return false;
-    }
-
-    return true;
-  }
-
-  bool Overlaps(const OriginAttributesPattern& aOther) const
-  {
-    if (mAppId.WasPassed() && aOther.mAppId.WasPassed() &&
-        mAppId.Value() != aOther.mAppId.Value()) {
-      return false;
-    }
-
-    if (mInIsolatedMozBrowser.WasPassed() &&
-        aOther.mInIsolatedMozBrowser.WasPassed() &&
-        mInIsolatedMozBrowser.Value() != aOther.mInIsolatedMozBrowser.Value()) {
-      return false;
-    }
-
-    if (mUserContextId.WasPassed() && aOther.mUserContextId.WasPassed() &&
-        mUserContextId.Value() != aOther.mUserContextId.Value()) {
-      return false;
-    }
-
-    if (mPrivateBrowsingId.WasPassed() && aOther.mPrivateBrowsingId.WasPassed() &&
-        mPrivateBrowsingId.Value() != aOther.mPrivateBrowsingId.Value()) {
-      return false;
-    }
-
-    if (mFirstPartyDomain.WasPassed() && aOther.mFirstPartyDomain.WasPassed() &&
-        mFirstPartyDomain.Value() != aOther.mFirstPartyDomain.Value()) {
-      return false;
-    }
-
-    return true;
-  }
-};
-
 /*
  * Base class from which all nsIPrincipal implementations inherit. Use this for
  * default implementations and other commonalities between principal
  * implementations.
  *
  * We should merge nsJSPrincipals into this class at some point.
  */
 class BasePrincipal : public nsJSPrincipals
@@ -278,17 +108,17 @@ protected:
   // Note that this does not check OriginAttributes. Callers that depend on
   // those must call Subsumes instead.
   virtual bool SubsumesInternal(nsIPrincipal* aOther, DocumentDomainConsideration aConsider) = 0;
 
   // Internal, side-effect-free check to determine whether the concrete
   // principal would allow the load ignoring any common behavior implemented in
   // BasePrincipal::CheckMayLoad.
   virtual bool MayLoadInternal(nsIURI* aURI) = 0;
-  friend class ::nsExpandedPrincipal;
+  friend class ::ExpandedPrincipal;
 
   // This function should be called as the last step of the initialization of the
   // principal objects.  It's typically called as the last step from the Init()
   // method of the child classes.
   void FinishInit();
 
   nsCOMPtr<nsIContentSecurityPolicy> mCSP;
   nsCOMPtr<nsIContentSecurityPolicy> mPreloadCSP;
rename from caps/nsPrincipal.cpp
rename to caps/ContentPrincipal.cpp
--- a/caps/nsPrincipal.cpp
+++ b/caps/ContentPrincipal.cpp
@@ -1,29 +1,31 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=2 sw=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 "nsPrincipal.h"
+#include "ContentPrincipal.h"
 
 #include "mozIThirdPartyUtil.h"
 #include "nscore.h"
 #include "nsScriptSecurityManager.h"
 #include "nsString.h"
 #include "nsReadableUtils.h"
 #include "pratom.h"
 #include "nsIURI.h"
 #include "nsIURL.h"
 #include "nsIStandardURL.h"
 #include "nsIURIWithPrincipal.h"
 #include "nsJSPrincipals.h"
 #include "nsIEffectiveTLDService.h"
 #include "nsIClassInfoImpl.h"
+#include "nsIObjectInputStream.h"
+#include "nsIObjectOutputStream.h"
 #include "nsIProtocolHandler.h"
 #include "nsError.h"
 #include "nsIContentSecurityPolicy.h"
 #include "nsNetCID.h"
 #include "jswrapper.h"
 
 #include "mozilla/dom/nsCSPContext.h"
 #include "mozilla/dom/ScriptSettings.h"
@@ -53,52 +55,53 @@ GetAddonPolicyService(nsresult* aRv)
   *aRv = NS_OK;
   if (!addonPolicyService) {
     addonPolicyService = do_GetService("@mozilla.org/addons/policy-service;1", aRv);
     ClearOnShutdown(&addonPolicyService);
   }
   return addonPolicyService;
 }
 
-NS_IMPL_CLASSINFO(nsPrincipal, nullptr, nsIClassInfo::MAIN_THREAD_ONLY,
+NS_IMPL_CLASSINFO(ContentPrincipal, nullptr, nsIClassInfo::MAIN_THREAD_ONLY,
                   NS_PRINCIPAL_CID)
-NS_IMPL_QUERY_INTERFACE_CI(nsPrincipal,
+NS_IMPL_QUERY_INTERFACE_CI(ContentPrincipal,
                            nsIPrincipal,
                            nsISerializable)
-NS_IMPL_CI_INTERFACE_GETTER(nsPrincipal,
+NS_IMPL_CI_INTERFACE_GETTER(ContentPrincipal,
                             nsIPrincipal,
                             nsISerializable)
 
 // Called at startup:
 /* static */ void
-nsPrincipal::InitializeStatics()
+ContentPrincipal::InitializeStatics()
 {
   Preferences::AddBoolVarCache(&gCodeBasePrincipalSupport,
                                "signed.applets.codebase_principal_support",
                                false);
 }
 
-nsPrincipal::nsPrincipal()
+ContentPrincipal::ContentPrincipal()
   : BasePrincipal(eCodebasePrincipal)
   , mCodebaseImmutable(false)
   , mDomainImmutable(false)
   , mInitialized(false)
 {
 }
 
-nsPrincipal::~nsPrincipal()
+ContentPrincipal::~ContentPrincipal()
 {
   // let's clear the principal within the csp to avoid a tangling pointer
   if (mCSP) {
     static_cast<nsCSPContext*>(mCSP.get())->clearLoadingPrincipal();
   }
 }
 
 nsresult
-nsPrincipal::Init(nsIURI *aCodebase, const OriginAttributes& aOriginAttributes)
+ContentPrincipal::Init(nsIURI *aCodebase,
+                       const OriginAttributes& aOriginAttributes)
 {
   NS_ENSURE_STATE(!mInitialized);
   NS_ENSURE_ARG(aCodebase);
 
   mInitialized = true;
 
   // Assert that the URI we get here isn't any of the schemes that we know we
   // should not get here.  These schemes always either inherit their principal
@@ -118,23 +121,23 @@ nsPrincipal::Init(nsIURI *aCodebase, con
   mOriginAttributes = aOriginAttributes;
 
   FinishInit();
 
   return NS_OK;
 }
 
 nsresult
-nsPrincipal::GetScriptLocation(nsACString &aStr)
+ContentPrincipal::GetScriptLocation(nsACString &aStr)
 {
   return mCodebase->GetSpec(aStr);
 }
 
 nsresult
-nsPrincipal::GetOriginInternal(nsACString& aOrigin)
+ContentPrincipal::GetOriginInternal(nsACString& aOrigin)
 {
   if (!mCodebase) {
     return NS_ERROR_FAILURE;
   }
 
   nsCOMPtr<nsIURI> origin = NS_GetInnermostURI(mCodebase);
   if (!origin) {
     return NS_ERROR_FAILURE;
@@ -244,22 +247,22 @@ nsPrincipal::GetOriginInternal(nsACStrin
   if (pos != kNotFound) {
     aOrigin.Truncate(pos);
   }
 
   return NS_OK;
 }
 
 bool
-nsPrincipal::SubsumesInternal(nsIPrincipal* aOther,
-                              BasePrincipal::DocumentDomainConsideration aConsideration)
+ContentPrincipal::SubsumesInternal(nsIPrincipal* aOther,
+                                   BasePrincipal::DocumentDomainConsideration aConsideration)
 {
   MOZ_ASSERT(aOther);
 
-  // For nsPrincipal, Subsumes is equivalent to Equals.
+  // For ContentPrincipal, Subsumes is equivalent to Equals.
   if (aOther == this) {
     return true;
   }
 
   // If either the subject or the object has changed its principal by
   // explicitly setting document.domain then the other must also have
   // done so in order to be considered the same origin. This prevents
   // DNS spoofing based on document.domain (154930)
@@ -281,33 +284,33 @@ nsPrincipal::SubsumesInternal(nsIPrincip
   rv = aOther->GetURI(getter_AddRefs(otherURI));
   NS_ENSURE_SUCCESS(rv, false);
 
   // Compare codebases.
   return nsScriptSecurityManager::SecurityCompareURIs(mCodebase, otherURI);
 }
 
 NS_IMETHODIMP
-nsPrincipal::GetURI(nsIURI** aURI)
+ContentPrincipal::GetURI(nsIURI** aURI)
 {
   if (mCodebaseImmutable) {
     NS_ADDREF(*aURI = mCodebase);
     return NS_OK;
   }
 
   if (!mCodebase) {
     *aURI = nullptr;
     return NS_OK;
   }
 
   return NS_EnsureSafeToReturn(mCodebase, aURI);
 }
 
 bool
-nsPrincipal::MayLoadInternal(nsIURI* aURI)
+ContentPrincipal::MayLoadInternal(nsIURI* aURI)
 {
   // See if aURI is something like a Blob URI that is actually associated with
   // a principal.
   nsCOMPtr<nsIURIWithPrincipal> uriWithPrin = do_QueryInterface(aURI);
   nsCOMPtr<nsIPrincipal> uriPrin;
   if (uriWithPrin) {
     uriWithPrin->GetPrincipal(getter_AddRefs(uriPrin));
   }
@@ -333,42 +336,42 @@ nsPrincipal::MayLoadInternal(nsIURI* aUR
       NS_RelaxStrictFileOriginPolicy(aURI, mCodebase)) {
     return true;
   }
 
   return false;
 }
 
 NS_IMETHODIMP
-nsPrincipal::GetHashValue(uint32_t* aValue)
+ContentPrincipal::GetHashValue(uint32_t* aValue)
 {
   NS_PRECONDITION(mCodebase, "Need a codebase");
 
   *aValue = nsScriptSecurityManager::HashPrincipalByOrigin(this);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsPrincipal::GetDomain(nsIURI** aDomain)
+ContentPrincipal::GetDomain(nsIURI** aDomain)
 {
   if (!mDomain) {
     *aDomain = nullptr;
     return NS_OK;
   }
 
   if (mDomainImmutable) {
     NS_ADDREF(*aDomain = mDomain);
     return NS_OK;
   }
 
   return NS_EnsureSafeToReturn(mDomain, aDomain);
 }
 
 NS_IMETHODIMP
-nsPrincipal::SetDomain(nsIURI* aDomain)
+ContentPrincipal::SetDomain(nsIURI* aDomain)
 {
   mDomain = NS_TryToMakeImmutable(aDomain);
   mDomainImmutable = URIIsImmutable(mDomain);
   mDomainSet = true;
 
   // Recompute all wrappers between compartments using this principal and other
   // non-chrome compartments.
   AutoSafeJSContext cx;
@@ -379,17 +382,17 @@ nsPrincipal::SetDomain(nsIURI* aDomain)
   success = js::RecomputeWrappers(cx, js::CompartmentsWithPrincipals(principals),
                                   js::ContentCompartmentsOnly());
   NS_ENSURE_TRUE(success, NS_ERROR_FAILURE);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsPrincipal::GetBaseDomain(nsACString& aBaseDomain)
+ContentPrincipal::GetBaseDomain(nsACString& aBaseDomain)
 {
   // For a file URI, we return the file path.
   if (NS_URIIsLocalFile(mCodebase)) {
     nsCOMPtr<nsIURL> url = do_QueryInterface(mCodebase);
 
     if (url) {
       return url->GetFilePath(aBaseDomain);
     }
@@ -414,17 +417,17 @@ nsPrincipal::GetBaseDomain(nsACString& a
   if (thirdPartyUtil) {
     return thirdPartyUtil->GetBaseDomain(mCodebase, aBaseDomain);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsPrincipal::GetAddonId(nsAString& aAddonId)
+ContentPrincipal::GetAddonId(nsAString& aAddonId)
 {
   if (mAddonIdCache.isSome()) {
     aAddonId.Assign(mAddonIdCache.ref());
     return NS_OK;
   }
 
   NS_ENSURE_TRUE(mCodebase, NS_ERROR_FAILURE);
 
@@ -443,17 +446,17 @@ nsPrincipal::GetAddonId(nsAString& aAddo
     mAddonIdCache.emplace();
   }
 
   aAddonId.Assign(mAddonIdCache.ref());
   return NS_OK;
 };
 
 NS_IMETHODIMP
-nsPrincipal::Read(nsIObjectInputStream* aStream)
+ContentPrincipal::Read(nsIObjectInputStream* aStream)
 {
   nsCOMPtr<nsISupports> supports;
   nsCOMPtr<nsIURI> codebase;
   nsresult rv = NS_ReadOptionalObject(aStream, true, getter_AddRefs(supports));
   if (NS_FAILED(rv)) {
     return rv;
   }
 
@@ -489,17 +492,17 @@ nsPrincipal::Read(nsIObjectInputStream* 
   }
 
   SetDomain(domain);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsPrincipal::Write(nsIObjectOutputStream* aStream)
+ContentPrincipal::Write(nsIObjectOutputStream* aStream)
 {
   NS_ENSURE_STATE(mCodebase);
   nsresult rv = NS_WriteOptionalCompoundObject(aStream, mCodebase, NS_GET_IID(nsIURI),
                                                true);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
rename from caps/nsPrincipal.h
rename to caps/ContentPrincipal.h
--- a/caps/nsPrincipal.h
+++ b/caps/ContentPrincipal.h
@@ -1,40 +1,40 @@
 /* -*- 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/. */
 
-#ifndef nsPrincipal_h__
-#define nsPrincipal_h__
+#ifndef ContentPrincipal_h
+#define ContentPrincipal_h
 
 #include "nsCOMPtr.h"
 #include "nsJSPrincipals.h"
 #include "nsTArray.h"
 #include "nsIContentSecurityPolicy.h"
 #include "nsIProtocolHandler.h"
 #include "nsNetUtil.h"
 #include "nsScriptSecurityManager.h"
 #include "mozilla/BasePrincipal.h"
 
-class nsPrincipal final : public mozilla::BasePrincipal
+class ContentPrincipal final : public mozilla::BasePrincipal
 {
 public:
   NS_DECL_NSISERIALIZABLE
   NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) override;
   NS_IMETHOD GetHashValue(uint32_t* aHashValue) override;
   NS_IMETHOD GetURI(nsIURI** aURI) override;
   NS_IMETHOD GetDomain(nsIURI** aDomain) override;
   NS_IMETHOD SetDomain(nsIURI* aDomain) override;
   NS_IMETHOD GetBaseDomain(nsACString& aBaseDomain) override;
   NS_IMETHOD GetAddonId(nsAString& aAddonId) override;
   bool IsCodebasePrincipal() const override { return true; }
   nsresult GetOriginInternal(nsACString& aOrigin) override;
 
-  nsPrincipal();
+  ContentPrincipal();
 
   // Init() must be called before the principal is in a usable state.
   nsresult Init(nsIURI* aCodebase,
                 const mozilla::OriginAttributes& aOriginAttributes);
 
   virtual nsresult GetScriptLocation(nsACString& aStr) override;
 
   /**
@@ -45,23 +45,24 @@ public:
   nsCOMPtr<nsIURI> mDomain;
   nsCOMPtr<nsIURI> mCodebase;
   // If mCodebaseImmutable is true, mCodebase is non-null and immutable
   bool mCodebaseImmutable;
   bool mDomainImmutable;
   bool mInitialized;
 
 protected:
-  virtual ~nsPrincipal();
+  virtual ~ContentPrincipal();
 
-  bool SubsumesInternal(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration) override;
+  bool SubsumesInternal(nsIPrincipal* aOther,
+                        DocumentDomainConsideration aConsideration) override;
   bool MayLoadInternal(nsIURI* aURI) override;
 
 private:
   mozilla::Maybe<nsString> mAddonIdCache;
 };
 
 #define NS_PRINCIPAL_CONTRACTID "@mozilla.org/principal;1"
 #define NS_PRINCIPAL_CID \
 { 0x653e0e4d, 0x3ee4, 0x45fa, \
   { 0xb2, 0x72, 0x97, 0xc2, 0x0b, 0xc0, 0x1e, 0xb8 } }
 
-#endif // nsPrincipal_h__
+#endif // ContentPrincipal_h
rename from caps/nsExpandedPrincipal.cpp
rename to caps/ExpandedPrincipal.cpp
--- a/caps/nsExpandedPrincipal.cpp
+++ b/caps/ExpandedPrincipal.cpp
@@ -1,27 +1,27 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=2 sw=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 "nsExpandedPrincipal.h"
+#include "ExpandedPrincipal.h"
 #include "nsIClassInfoImpl.h"
 
 using namespace mozilla;
 
-NS_IMPL_CLASSINFO(nsExpandedPrincipal, nullptr, nsIClassInfo::MAIN_THREAD_ONLY,
+NS_IMPL_CLASSINFO(ExpandedPrincipal, nullptr, nsIClassInfo::MAIN_THREAD_ONLY,
                   NS_EXPANDEDPRINCIPAL_CID)
-NS_IMPL_QUERY_INTERFACE_CI(nsExpandedPrincipal,
+NS_IMPL_QUERY_INTERFACE_CI(ExpandedPrincipal,
                            nsIPrincipal,
                            nsIExpandedPrincipal)
-NS_IMPL_CI_INTERFACE_GETTER(nsExpandedPrincipal,
-                             nsIPrincipal,
-                             nsIExpandedPrincipal)
+NS_IMPL_CI_INTERFACE_GETTER(ExpandedPrincipal,
+                            nsIPrincipal,
+                            nsIExpandedPrincipal)
 
 struct OriginComparator
 {
   bool LessThan(nsIPrincipal* a, nsIPrincipal* b) const
   {
     nsAutoCString originA;
     nsresult rv = a->GetOrigin(originA);
     NS_ENSURE_SUCCESS(rv, false);
@@ -38,56 +38,56 @@ struct OriginComparator
     NS_ENSURE_SUCCESS(rv, false);
     nsAutoCString originB;
     rv = b->GetOrigin(originB);
     NS_ENSURE_SUCCESS(rv, false);
     return a == b;
   }
 };
 
-nsExpandedPrincipal::nsExpandedPrincipal(nsTArray<nsCOMPtr<nsIPrincipal>> &aWhiteList,
-                                         const OriginAttributes& aAttrs)
+ExpandedPrincipal::ExpandedPrincipal(nsTArray<nsCOMPtr<nsIPrincipal>> &aWhiteList,
+                                     const OriginAttributes& aAttrs)
   : BasePrincipal(eExpandedPrincipal)
 {
-  // We force the principals to be sorted by origin so that nsExpandedPrincipal
+  // We force the principals to be sorted by origin so that ExpandedPrincipal
   // origins can have a canonical form.
   OriginComparator c;
   for (size_t i = 0; i < aWhiteList.Length(); ++i) {
     mPrincipals.InsertElementSorted(aWhiteList[i], c);
   }
   mOriginAttributes = aAttrs;
 }
 
-nsExpandedPrincipal::~nsExpandedPrincipal()
+ExpandedPrincipal::~ExpandedPrincipal()
 { }
 
-already_AddRefed<nsExpandedPrincipal>
-nsExpandedPrincipal::Create(nsTArray<nsCOMPtr<nsIPrincipal>>& aWhiteList,
-                            const OriginAttributes& aAttrs)
+already_AddRefed<ExpandedPrincipal>
+ExpandedPrincipal::Create(nsTArray<nsCOMPtr<nsIPrincipal>>& aWhiteList,
+                          const OriginAttributes& aAttrs)
 {
-  RefPtr<nsExpandedPrincipal> ep = new nsExpandedPrincipal(aWhiteList, aAttrs);
+  RefPtr<ExpandedPrincipal> ep = new ExpandedPrincipal(aWhiteList, aAttrs);
   ep->FinishInit();
   return ep.forget();
 }
 
 NS_IMETHODIMP
-nsExpandedPrincipal::GetDomain(nsIURI** aDomain)
+ExpandedPrincipal::GetDomain(nsIURI** aDomain)
 {
   *aDomain = nullptr;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsExpandedPrincipal::SetDomain(nsIURI* aDomain)
+ExpandedPrincipal::SetDomain(nsIURI* aDomain)
 {
   return NS_OK;
 }
 
 nsresult
-nsExpandedPrincipal::GetOriginInternal(nsACString& aOrigin)
+ExpandedPrincipal::GetOriginInternal(nsACString& aOrigin)
 {
   aOrigin.AssignLiteral("[Expanded Principal [");
   for (size_t i = 0; i < mPrincipals.Length(); ++i) {
     if (i != 0) {
       aOrigin.AppendLiteral(", ");
     }
 
     nsAutoCString subOrigin;
@@ -96,18 +96,18 @@ nsExpandedPrincipal::GetOriginInternal(n
     aOrigin.Append(subOrigin);
   }
 
   aOrigin.Append("]]");
   return NS_OK;
 }
 
 bool
-nsExpandedPrincipal::SubsumesInternal(nsIPrincipal* aOther,
-                                      BasePrincipal::DocumentDomainConsideration aConsideration)
+ExpandedPrincipal::SubsumesInternal(nsIPrincipal* aOther,
+                                    BasePrincipal::DocumentDomainConsideration aConsideration)
 {
   // If aOther is an ExpandedPrincipal too, we break it down into its component
   // nsIPrincipals, and check subsumes on each one.
   nsCOMPtr<nsIExpandedPrincipal> expanded = do_QueryInterface(aOther);
   if (expanded) {
     nsTArray< nsCOMPtr<nsIPrincipal> >* otherList;
     expanded->GetWhiteList(&otherList);
     for (uint32_t i = 0; i < otherList->Length(); ++i){
@@ -128,73 +128,73 @@ nsExpandedPrincipal::SubsumesInternal(ns
       return true;
     }
   }
 
   return false;
 }
 
 bool
-nsExpandedPrincipal::MayLoadInternal(nsIURI* uri)
+ExpandedPrincipal::MayLoadInternal(nsIURI* uri)
 {
   for (uint32_t i = 0; i < mPrincipals.Length(); ++i){
     if (BasePrincipal::Cast(mPrincipals[i])->MayLoadInternal(uri)) {
       return true;
     }
   }
 
   return false;
 }
 
 NS_IMETHODIMP
-nsExpandedPrincipal::GetHashValue(uint32_t* result)
+ExpandedPrincipal::GetHashValue(uint32_t* result)
 {
   MOZ_CRASH("extended principal should never be used as key in a hash map");
 }
 
 NS_IMETHODIMP
-nsExpandedPrincipal::GetURI(nsIURI** aURI)
+ExpandedPrincipal::GetURI(nsIURI** aURI)
 {
   *aURI = nullptr;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsExpandedPrincipal::GetWhiteList(nsTArray<nsCOMPtr<nsIPrincipal> >** aWhiteList)
+ExpandedPrincipal::GetWhiteList(nsTArray<nsCOMPtr<nsIPrincipal> >** aWhiteList)
 {
   *aWhiteList = &mPrincipals;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsExpandedPrincipal::GetBaseDomain(nsACString& aBaseDomain)
+ExpandedPrincipal::GetBaseDomain(nsACString& aBaseDomain)
 {
   return NS_ERROR_NOT_AVAILABLE;
 }
 
 NS_IMETHODIMP
-nsExpandedPrincipal::GetAddonId(nsAString& aAddonId)
+ExpandedPrincipal::GetAddonId(nsAString& aAddonId)
 {
   aAddonId.Truncate();
   return NS_OK;
 };
 
 bool
-nsExpandedPrincipal::AddonHasPermission(const nsAString& aPerm)
+ExpandedPrincipal::AddonHasPermission(const nsAString& aPerm)
 {
   for (size_t i = 0; i < mPrincipals.Length(); ++i) {
     if (BasePrincipal::Cast(mPrincipals[i])->AddonHasPermission(aPerm)) {
       return true;
     }
   }
   return false;
 }
 
 nsresult
-nsExpandedPrincipal::GetScriptLocation(nsACString& aStr)
+ExpandedPrincipal::GetScriptLocation(nsACString& aStr)
 {
   aStr.Assign("[Expanded Principal [");
   for (size_t i = 0; i < mPrincipals.Length(); ++i) {
     if (i != 0) {
       aStr.AppendLiteral(", ");
     }
 
     nsAutoCString spec;
@@ -208,18 +208,18 @@ nsExpandedPrincipal::GetScriptLocation(n
   return NS_OK;
 }
 
 //////////////////////////////////////////
 // Methods implementing nsISerializable //
 //////////////////////////////////////////
 
 NS_IMETHODIMP
-nsExpandedPrincipal::Read(nsIObjectInputStream* aStream)
+ExpandedPrincipal::Read(nsIObjectInputStream* aStream)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-nsExpandedPrincipal::Write(nsIObjectOutputStream* aStream)
+ExpandedPrincipal::Write(nsIObjectOutputStream* aStream)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
rename from caps/nsExpandedPrincipal.h
rename to caps/ExpandedPrincipal.h
--- a/caps/nsExpandedPrincipal.h
+++ b/caps/ExpandedPrincipal.h
@@ -1,56 +1,59 @@
 /* -*- 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/. */
 
-#ifndef nsExpandedPrincipal_h
-#define nsExpandedPrincipal_h
+#ifndef ExpandedPrincipal_h
+#define ExpandedPrincipal_h
 
 #include "nsCOMPtr.h"
 #include "nsJSPrincipals.h"
 #include "nsTArray.h"
 #include "nsNetUtil.h"
 #include "mozilla/BasePrincipal.h"
 
-class nsExpandedPrincipal : public nsIExpandedPrincipal
-                          , public mozilla::BasePrincipal
+class ExpandedPrincipal : public nsIExpandedPrincipal
+                        , public mozilla::BasePrincipal
 {
-  nsExpandedPrincipal(nsTArray<nsCOMPtr<nsIPrincipal>> &aWhiteList,
-                      const mozilla::OriginAttributes& aAttrs);
+  ExpandedPrincipal(nsTArray<nsCOMPtr<nsIPrincipal>> &aWhiteList,
+                    const mozilla::OriginAttributes& aAttrs);
 
 public:
-  static already_AddRefed<nsExpandedPrincipal>
+  static already_AddRefed<ExpandedPrincipal>
   Create(nsTArray<nsCOMPtr<nsIPrincipal>>& aWhiteList,
          const mozilla::OriginAttributes& aAttrs);
 
   NS_DECL_NSIEXPANDEDPRINCIPAL
   NS_DECL_NSISERIALIZABLE
+
   NS_IMETHOD_(MozExternalRefCountType) AddRef() override { return nsJSPrincipals::AddRef(); };
   NS_IMETHOD_(MozExternalRefCountType) Release() override { return nsJSPrincipals::Release(); };
   NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) override;
   NS_IMETHOD GetHashValue(uint32_t* aHashValue) override;
   NS_IMETHOD GetURI(nsIURI** aURI) override;
   NS_IMETHOD GetDomain(nsIURI** aDomain) override;
   NS_IMETHOD SetDomain(nsIURI* aDomain) override;
   NS_IMETHOD GetBaseDomain(nsACString& aBaseDomain) override;
   NS_IMETHOD GetAddonId(nsAString& aAddonId) override;
   virtual bool AddonHasPermission(const nsAString& aPerm) override;
   virtual nsresult GetScriptLocation(nsACString &aStr) override;
   nsresult GetOriginInternal(nsACString& aOrigin) override;
 
 protected:
-  virtual ~nsExpandedPrincipal();
+  virtual ~ExpandedPrincipal();
 
-  bool SubsumesInternal(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration) override;
+  bool SubsumesInternal(nsIPrincipal* aOther,
+                        DocumentDomainConsideration aConsideration) override;
+
   bool MayLoadInternal(nsIURI* aURI) override;
 
 private:
   nsTArray< nsCOMPtr<nsIPrincipal> > mPrincipals;
 };
 
 #define NS_EXPANDEDPRINCIPAL_CONTRACTID "@mozilla.org/expandedprincipal;1"
 #define NS_EXPANDEDPRINCIPAL_CID \
 { 0xe8ee88b0, 0x5571, 0x4086, \
   { 0xa4, 0x5b, 0x39, 0xa7, 0x16, 0x90, 0x6b, 0xdb } }
 
-#endif // nsExpandedPrincipal_h
+#endif // ExpandedPrincipal_h
rename from caps/nsNullPrincipal.cpp
rename to caps/NullPrincipal.cpp
--- a/caps/nsNullPrincipal.cpp
+++ b/caps/NullPrincipal.cpp
@@ -8,191 +8,192 @@
  * This is the principal that has no rights and can't be accessed by
  * anything other than itself and chrome; null principals are not
  * same-origin with anything but themselves.
  */
 
 #include "mozilla/ArrayUtils.h"
 
 #include "nsDocShell.h"
-#include "nsNullPrincipal.h"
-#include "nsNullPrincipalURI.h"
+#include "NullPrincipal.h"
+#include "NullPrincipalURI.h"
 #include "nsMemory.h"
 #include "nsIURIWithPrincipal.h"
 #include "nsIClassInfoImpl.h"
 #include "nsNetCID.h"
 #include "nsError.h"
 #include "nsIScriptSecurityManager.h"
-#include "nsPrincipal.h"
+#include "ContentPrincipal.h"
 #include "nsScriptSecurityManager.h"
 #include "pratom.h"
 
 using namespace mozilla;
 
-NS_IMPL_CLASSINFO(nsNullPrincipal, nullptr, nsIClassInfo::MAIN_THREAD_ONLY,
+NS_IMPL_CLASSINFO(NullPrincipal, nullptr, nsIClassInfo::MAIN_THREAD_ONLY,
                   NS_NULLPRINCIPAL_CID)
-NS_IMPL_QUERY_INTERFACE_CI(nsNullPrincipal,
+NS_IMPL_QUERY_INTERFACE_CI(NullPrincipal,
                            nsIPrincipal,
                            nsISerializable)
-NS_IMPL_CI_INTERFACE_GETTER(nsNullPrincipal,
+NS_IMPL_CI_INTERFACE_GETTER(NullPrincipal,
                             nsIPrincipal,
                             nsISerializable)
 
-/* static */ already_AddRefed<nsNullPrincipal>
-nsNullPrincipal::CreateWithInheritedAttributes(nsIPrincipal* aInheritFrom)
+/* static */ already_AddRefed<NullPrincipal>
+NullPrincipal::CreateWithInheritedAttributes(nsIPrincipal* aInheritFrom)
 {
-  RefPtr<nsNullPrincipal> nullPrin = new nsNullPrincipal();
+  RefPtr<NullPrincipal> nullPrin = new NullPrincipal();
   nsresult rv = nullPrin->Init(Cast(aInheritFrom)->OriginAttributesRef());
   MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
   return nullPrin.forget();
 }
 
-/* static */ already_AddRefed<nsNullPrincipal>
-nsNullPrincipal::CreateWithInheritedAttributes(nsIDocShell* aDocShell, bool aIsFirstParty)
+/* static */ already_AddRefed<NullPrincipal>
+NullPrincipal::CreateWithInheritedAttributes(nsIDocShell* aDocShell, bool aIsFirstParty)
 {
   OriginAttributes attrs = nsDocShell::Cast(aDocShell)->GetOriginAttributes();
   attrs.SetFirstPartyDomain(aIsFirstParty, NS_LITERAL_CSTRING(NULL_PRINCIPAL_FIRST_PARTY_DOMAIN));
 
-  RefPtr<nsNullPrincipal> nullPrin = new nsNullPrincipal();
+  RefPtr<NullPrincipal> nullPrin = new NullPrincipal();
   nsresult rv = nullPrin->Init(attrs);
   MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
   return nullPrin.forget();
 }
 
-/* static */ already_AddRefed<nsNullPrincipal>
-nsNullPrincipal::Create(const OriginAttributes& aOriginAttributes, nsIURI* aURI)
+/* static */ already_AddRefed<NullPrincipal>
+NullPrincipal::Create(const OriginAttributes& aOriginAttributes, nsIURI* aURI)
 {
-  RefPtr<nsNullPrincipal> nullPrin = new nsNullPrincipal();
+  RefPtr<NullPrincipal> nullPrin = new NullPrincipal();
   nsresult rv = nullPrin->Init(aOriginAttributes, aURI);
   MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
 
   return nullPrin.forget();
 }
 
 nsresult
-nsNullPrincipal::Init(const OriginAttributes& aOriginAttributes, nsIURI* aURI)
+NullPrincipal::Init(const OriginAttributes& aOriginAttributes, nsIURI* aURI)
 {
   mOriginAttributes = aOriginAttributes;
 
   if (aURI) {
     nsAutoCString scheme;
     nsresult rv = aURI->GetScheme(scheme);
     NS_ENSURE_SUCCESS(rv, rv);
 
     NS_ENSURE_TRUE(scheme.EqualsLiteral(NS_NULLPRINCIPAL_SCHEME),
                    NS_ERROR_NOT_AVAILABLE);
 
     mURI = aURI;
   } else {
-    mURI = nsNullPrincipalURI::Create();
+    mURI = NullPrincipalURI::Create();
     NS_ENSURE_TRUE(mURI, NS_ERROR_NOT_AVAILABLE);
   }
 
   FinishInit();
 
   return NS_OK;
 }
 
 nsresult
-nsNullPrincipal::GetScriptLocation(nsACString &aStr)
+NullPrincipal::GetScriptLocation(nsACString &aStr)
 {
   return mURI->GetSpec(aStr);
 }
 
 /**
  * nsIPrincipal implementation
  */
 
 NS_IMETHODIMP
-nsNullPrincipal::GetHashValue(uint32_t *aResult)
+NullPrincipal::GetHashValue(uint32_t *aResult)
 {
   *aResult = (NS_PTR_TO_INT32(this) >> 2);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsNullPrincipal::SetCsp(nsIContentSecurityPolicy* aCsp) {
+NullPrincipal::SetCsp(nsIContentSecurityPolicy* aCsp)
+{
   // Never destroy an existing CSP on the principal.
   // This method should only be called in rare cases.
 
   MOZ_ASSERT(!mCSP, "do not destroy an existing CSP");
   if (mCSP) {
     return NS_ERROR_ALREADY_INITIALIZED;
   }
 
   mCSP = aCsp;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsNullPrincipal::GetURI(nsIURI** aURI)
+NullPrincipal::GetURI(nsIURI** aURI)
 {
   return NS_EnsureSafeToReturn(mURI, aURI);
 }
 
 NS_IMETHODIMP
-nsNullPrincipal::GetDomain(nsIURI** aDomain)
+NullPrincipal::GetDomain(nsIURI** aDomain)
 {
   return NS_EnsureSafeToReturn(mURI, aDomain);
 }
 
 NS_IMETHODIMP
-nsNullPrincipal::SetDomain(nsIURI* aDomain)
+NullPrincipal::SetDomain(nsIURI* aDomain)
 {
   // I think the right thing to do here is to just throw...  Silently failing
   // seems counterproductive.
   return NS_ERROR_NOT_AVAILABLE;
 }
 
 nsresult
-nsNullPrincipal::GetOriginInternal(nsACString& aOrigin)
+NullPrincipal::GetOriginInternal(nsACString& aOrigin)
 {
   return mURI->GetSpec(aOrigin);
 }
 
 bool
-nsNullPrincipal::MayLoadInternal(nsIURI* aURI)
+NullPrincipal::MayLoadInternal(nsIURI* aURI)
 {
   // Also allow the load if we are the principal of the URI being checked.
   nsCOMPtr<nsIURIWithPrincipal> uriPrinc = do_QueryInterface(aURI);
   if (uriPrinc) {
     nsCOMPtr<nsIPrincipal> principal;
     uriPrinc->GetPrincipal(getter_AddRefs(principal));
 
     if (principal == this) {
       return true;
     }
   }
 
   return false;
 }
 
 NS_IMETHODIMP
-nsNullPrincipal::GetBaseDomain(nsACString& aBaseDomain)
+NullPrincipal::GetBaseDomain(nsACString& aBaseDomain)
 {
   // For a null principal, we use our unique uuid as the base domain.
   return mURI->GetPath(aBaseDomain);
 }
 
 NS_IMETHODIMP
-nsNullPrincipal::GetAddonId(nsAString& aAddonId)
+NullPrincipal::GetAddonId(nsAString& aAddonId)
 {
   aAddonId.Truncate();
   return NS_OK;
 };
 
 /**
  * nsISerializable implementation
  */
 NS_IMETHODIMP
-nsNullPrincipal::Read(nsIObjectInputStream* aStream)
+NullPrincipal::Read(nsIObjectInputStream* aStream)
 {
-  // Note - nsNullPrincipal use NS_GENERIC_FACTORY_CONSTRUCTOR_INIT, which means
+  // Note - NullPrincipal use NS_GENERIC_FACTORY_CONSTRUCTOR_INIT, which means
   // that the Init() method has already been invoked by the time we deserialize.
-  // This is in contrast to nsPrincipal, which uses NS_GENERIC_FACTORY_CONSTRUCTOR,
+  // This is in contrast to ContentPrincipal, which uses NS_GENERIC_FACTORY_CONSTRUCTOR,
   // in which case ::Read needs to invoke Init().
 
   nsAutoCString spec;
   nsresult rv = aStream->ReadCString(spec);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIURI> uri;
   rv = NS_NewURI(getter_AddRefs(uri), spec);
@@ -205,17 +206,17 @@ nsNullPrincipal::Read(nsIObjectInputStre
   OriginAttributes attrs;
   bool ok = attrs.PopulateFromSuffix(suffix);
   NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
 
   return Init(attrs, uri);
 }
 
 NS_IMETHODIMP
-nsNullPrincipal::Write(nsIObjectOutputStream* aStream)
+NullPrincipal::Write(nsIObjectOutputStream* aStream)
 {
   NS_ENSURE_STATE(mURI);
 
   nsAutoCString spec;
   nsresult rv = mURI->GetSpec(spec);
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = aStream->WriteStringZ(spec.get());
rename from caps/nsNullPrincipal.h
rename to caps/NullPrincipal.h
--- a/caps/nsNullPrincipal.h
+++ b/caps/NullPrincipal.h
@@ -4,18 +4,18 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /**
  * This is the principal that has no rights and can't be accessed by
  * anything other than itself and chrome; null principals are not
  * same-origin with anything but themselves.
  */
 
-#ifndef nsNullPrincipal_h__
-#define nsNullPrincipal_h__
+#ifndef NullPrincipal_h
+#define NullPrincipal_h
 
 #include "nsIPrincipal.h"
 #include "nsJSPrincipals.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsCOMPtr.h"
 #include "nsIContentSecurityPolicy.h"
 
 #include "mozilla/BasePrincipal.h"
@@ -25,62 +25,63 @@ class nsIURI;
 
 #define NS_NULLPRINCIPAL_CID \
 { 0xbd066e5f, 0x146f, 0x4472, \
   { 0x83, 0x31, 0x7b, 0xfd, 0x05, 0xb1, 0xed, 0x90 } }
 #define NS_NULLPRINCIPAL_CONTRACTID "@mozilla.org/nullprincipal;1"
 
 #define NS_NULLPRINCIPAL_SCHEME "moz-nullprincipal"
 
-class nsNullPrincipal final : public mozilla::BasePrincipal
+class NullPrincipal final : public mozilla::BasePrincipal
 {
 public:
   // This should only be used by deserialization, and the factory constructor.
   // Other consumers should use the Create and CreateWithInheritedAttributes
   // methods.
-  nsNullPrincipal()
+  NullPrincipal()
     : BasePrincipal(eNullPrincipal)
   {
   }
 
   NS_DECL_NSISERIALIZABLE
 
   NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) override;
   NS_IMETHOD GetHashValue(uint32_t* aHashValue) override;
   NS_IMETHOD SetCsp(nsIContentSecurityPolicy* aCsp) override;
   NS_IMETHOD GetURI(nsIURI** aURI) override;
   NS_IMETHOD GetDomain(nsIURI** aDomain) override;
   NS_IMETHOD SetDomain(nsIURI* aDomain) override;
   NS_IMETHOD GetBaseDomain(nsACString& aBaseDomain) override;
   NS_IMETHOD GetAddonId(nsAString& aAddonId) override;
   nsresult GetOriginInternal(nsACString& aOrigin) override;
 
-  static already_AddRefed<nsNullPrincipal> CreateWithInheritedAttributes(nsIPrincipal* aInheritFrom);
+  static already_AddRefed<NullPrincipal> CreateWithInheritedAttributes(nsIPrincipal* aInheritFrom);
 
   // Create NullPrincipal with origin attributes from docshell.
   // If aIsFirstParty is true, and the pref 'privacy.firstparty.isolate' is also
   // enabled, the mFirstPartyDomain value of the origin attributes will be set
   // to NULL_PRINCIPAL_FIRST_PARTY_DOMAIN.
-  static already_AddRefed<nsNullPrincipal> CreateWithInheritedAttributes(nsIDocShell* aDocShell, bool aIsFirstParty = false);
+  static already_AddRefed<NullPrincipal>
+  CreateWithInheritedAttributes(nsIDocShell* aDocShell, bool aIsFirstParty = false);
 
-  static already_AddRefed<nsNullPrincipal>
+  static already_AddRefed<NullPrincipal>
   Create(const mozilla::OriginAttributes& aOriginAttributes = mozilla::OriginAttributes(),
          nsIURI* aURI = nullptr);
 
   nsresult Init(const mozilla::OriginAttributes& aOriginAttributes = mozilla::OriginAttributes(),
                 nsIURI* aURI = nullptr);
 
   virtual nsresult GetScriptLocation(nsACString &aStr) override;
 
  protected:
-  virtual ~nsNullPrincipal() {}
+  virtual ~NullPrincipal() = default;
 
   bool SubsumesInternal(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration) override
   {
     return aOther == this;
   }
 
   bool MayLoadInternal(nsIURI* aURI) override;
 
   nsCOMPtr<nsIURI> mURI;
 };
 
-#endif // nsNullPrincipal_h__
+#endif // NullPrincipal_h__
rename from caps/nsNullPrincipalURI.cpp
rename to caps/NullPrincipalURI.cpp
--- a/caps/nsNullPrincipalURI.cpp
+++ b/caps/NullPrincipalURI.cpp
@@ -1,41 +1,41 @@
 /* -*- 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 "nsNullPrincipalURI.h"
+#include "NullPrincipalURI.h"
 
 #include "mozilla/DebugOnly.h"
 #include "mozilla/MemoryReporting.h"
 
 #include "mozilla/ipc/URIParams.h"
 
 #include "nsEscape.h"
 #include "nsCRT.h"
 #include "nsIUUIDGenerator.h"
 
 ////////////////////////////////////////////////////////////////////////////////
-//// nsNullPrincipalURI
+//// NullPrincipalURI
 
-nsNullPrincipalURI::nsNullPrincipalURI()
+NullPrincipalURI::NullPrincipalURI()
   : mPath(mPathBytes, ArrayLength(mPathBytes), ArrayLength(mPathBytes) - 1)
 {
 }
 
-nsNullPrincipalURI::nsNullPrincipalURI(const nsNullPrincipalURI& aOther)
+NullPrincipalURI::NullPrincipalURI(const NullPrincipalURI& aOther)
   : mPath(mPathBytes, ArrayLength(mPathBytes), ArrayLength(mPathBytes) - 1)
 {
   mPath.Assign(aOther.mPath);
 }
 
 nsresult
-nsNullPrincipalURI::Init()
+NullPrincipalURI::Init()
 {
   // FIXME: bug 327161 -- make sure the uuid generator is reseeding-resistant.
   nsCOMPtr<nsIUUIDGenerator> uuidgen = services::GetUUIDGenerator();
   NS_ENSURE_TRUE(uuidgen, NS_ERROR_NOT_AVAILABLE);
 
   nsID id;
   nsresult rv = uuidgen->GenerateUUIDInPlace(&id);
   NS_ENSURE_SUCCESS(rv, rv);
@@ -46,343 +46,343 @@ nsNullPrincipalURI::Init()
 
   MOZ_ASSERT(mPath.Length() == NSID_LENGTH - 1);
   MOZ_ASSERT(strlen(mPath.get()) == NSID_LENGTH - 1);
 
   return NS_OK;
 }
 
 /* static */
-already_AddRefed<nsNullPrincipalURI>
-nsNullPrincipalURI::Create()
+already_AddRefed<NullPrincipalURI>
+NullPrincipalURI::Create()
 {
-  RefPtr<nsNullPrincipalURI> uri = new nsNullPrincipalURI();
+  RefPtr<NullPrincipalURI> uri = new NullPrincipalURI();
   nsresult rv = uri->Init();
   NS_ENSURE_SUCCESS(rv, nullptr);
   return uri.forget();
 }
 
 static NS_DEFINE_CID(kNullPrincipalURIImplementationCID,
                      NS_NULLPRINCIPALURI_IMPLEMENTATION_CID);
 
-NS_IMPL_ADDREF(nsNullPrincipalURI)
-NS_IMPL_RELEASE(nsNullPrincipalURI)
+NS_IMPL_ADDREF(NullPrincipalURI)
+NS_IMPL_RELEASE(NullPrincipalURI)
 
-NS_INTERFACE_MAP_BEGIN(nsNullPrincipalURI)
+NS_INTERFACE_MAP_BEGIN(NullPrincipalURI)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIURI)
   if (aIID.Equals(kNullPrincipalURIImplementationCID))
-    foundInterface = static_cast<nsIURI *>(this);
+    foundInterface = static_cast<nsIURI*>(this);
   else
   NS_INTERFACE_MAP_ENTRY(nsIURI)
   NS_INTERFACE_MAP_ENTRY(nsISizeOf)
   NS_INTERFACE_MAP_ENTRY(nsIIPCSerializableURI)
 NS_INTERFACE_MAP_END
 
 ////////////////////////////////////////////////////////////////////////////////
 //// nsIURI
 
 NS_IMETHODIMP
-nsNullPrincipalURI::GetAsciiHost(nsACString &_host)
+NullPrincipalURI::GetAsciiHost(nsACString& _host)
 {
   _host.Truncate();
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsNullPrincipalURI::GetAsciiHostPort(nsACString &_hostport)
+NullPrincipalURI::GetAsciiHostPort(nsACString& _hostport)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-nsNullPrincipalURI::GetAsciiSpec(nsACString &_spec)
+NullPrincipalURI::GetAsciiSpec(nsACString& _spec)
 {
   nsAutoCString buffer;
-  // Ignore the return value -- nsNullPrincipalURI::GetSpec() is infallible.
+  // Ignore the return value -- NullPrincipalURI::GetSpec() is infallible.
   Unused << GetSpec(buffer);
   // This uses the infallible version of |NS_EscapeURL| as |GetSpec| is
   // already infallible.
   NS_EscapeURL(buffer, esc_OnlyNonASCII | esc_AlwaysCopy, _spec);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsNullPrincipalURI::GetHost(nsACString &_host)
+NullPrincipalURI::GetHost(nsACString& _host)
 {
   _host.Truncate();
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsNullPrincipalURI::SetHost(const nsACString &aHost)
+NullPrincipalURI::SetHost(const nsACString& aHost)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-nsNullPrincipalURI::GetHostPort(nsACString &_host)
+NullPrincipalURI::GetHostPort(nsACString& _host)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-nsNullPrincipalURI::SetHostPort(const nsACString &aHost)
+NullPrincipalURI::SetHostPort(const nsACString& aHost)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-nsNullPrincipalURI::SetHostAndPort(const nsACString &aHost)
+NullPrincipalURI::SetHostAndPort(const nsACString& aHost)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-nsNullPrincipalURI::GetOriginCharset(nsACString &_charset)
+NullPrincipalURI::GetOriginCharset(nsACString& _charset)
 {
   _charset.Truncate();
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsNullPrincipalURI::GetPassword(nsACString &_password)
+NullPrincipalURI::GetPassword(nsACString& _password)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-nsNullPrincipalURI::SetPassword(const nsACString &aPassword)
+NullPrincipalURI::SetPassword(const nsACString& aPassword)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-nsNullPrincipalURI::GetPath(nsACString &_path)
+NullPrincipalURI::GetPath(nsACString& _path)
 {
   _path = mPath;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsNullPrincipalURI::SetPath(const nsACString &aPath)
+NullPrincipalURI::SetPath(const nsACString& aPath)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-nsNullPrincipalURI::GetFilePath(nsACString &aFilePath)
+NullPrincipalURI::GetFilePath(nsACString& aFilePath)
 {
   aFilePath.Truncate();
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-nsNullPrincipalURI::SetFilePath(const nsACString &aFilePath)
+NullPrincipalURI::SetFilePath(const nsACString& aFilePath)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-nsNullPrincipalURI::GetQuery(nsACString &aQuery)
+NullPrincipalURI::GetQuery(nsACString& aQuery)
 {
   aQuery.Truncate();
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-nsNullPrincipalURI::SetQuery(const nsACString &aQuery)
+NullPrincipalURI::SetQuery(const nsACString& aQuery)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-nsNullPrincipalURI::GetRef(nsACString &_ref)
+NullPrincipalURI::GetRef(nsACString& _ref)
 {
   _ref.Truncate();
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-nsNullPrincipalURI::SetRef(const nsACString &aRef)
+NullPrincipalURI::SetRef(const nsACString& aRef)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-nsNullPrincipalURI::GetPrePath(nsACString &_prePath)
+NullPrincipalURI::GetPrePath(nsACString& _prePath)
 {
   _prePath = NS_LITERAL_CSTRING(NS_NULLPRINCIPAL_SCHEME ":");
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsNullPrincipalURI::GetPort(int32_t *_port)
+NullPrincipalURI::GetPort(int32_t* _port)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-nsNullPrincipalURI::SetPort(int32_t aPort)
+NullPrincipalURI::SetPort(int32_t aPort)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-nsNullPrincipalURI::GetScheme(nsACString &_scheme)
+NullPrincipalURI::GetScheme(nsACString& _scheme)
 {
   _scheme = NS_LITERAL_CSTRING(NS_NULLPRINCIPAL_SCHEME);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsNullPrincipalURI::SetScheme(const nsACString &aScheme)
+NullPrincipalURI::SetScheme(const nsACString& aScheme)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-nsNullPrincipalURI::GetSpec(nsACString &_spec)
+NullPrincipalURI::GetSpec(nsACString& _spec)
 {
   _spec = NS_LITERAL_CSTRING(NS_NULLPRINCIPAL_SCHEME ":") + mPath;
   return NS_OK;
 }
 
 // result may contain unescaped UTF-8 characters
 NS_IMETHODIMP
-nsNullPrincipalURI::GetSpecIgnoringRef(nsACString &result)
+NullPrincipalURI::GetSpecIgnoringRef(nsACString& _result)
 {
-  return GetSpec(result);
+  return GetSpec(_result);
 }
 
 NS_IMETHODIMP
-nsNullPrincipalURI::GetHasRef(bool *result)
+NullPrincipalURI::GetHasRef(bool* _result)
 {
-  *result = false;
+  *_result = false;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsNullPrincipalURI::SetSpec(const nsACString &aSpec)
+NullPrincipalURI::SetSpec(const nsACString& aSpec)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-nsNullPrincipalURI::GetUsername(nsACString &_username)
+NullPrincipalURI::GetUsername(nsACString& _username)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-nsNullPrincipalURI::SetUsername(const nsACString &aUsername)
+NullPrincipalURI::SetUsername(const nsACString& aUsername)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-nsNullPrincipalURI::GetUserPass(nsACString &_userPass)
+NullPrincipalURI::GetUserPass(nsACString& _userPass)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-nsNullPrincipalURI::SetUserPass(const nsACString &aUserPass)
+NullPrincipalURI::SetUserPass(const nsACString& aUserPass)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-nsNullPrincipalURI::Clone(nsIURI **_newURI)
+NullPrincipalURI::Clone(nsIURI** _newURI)
 {
-  nsCOMPtr<nsIURI> uri = new nsNullPrincipalURI(*this);
+  nsCOMPtr<nsIURI> uri = new NullPrincipalURI(*this);
   uri.forget(_newURI);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsNullPrincipalURI::CloneIgnoringRef(nsIURI **_newURI)
+NullPrincipalURI::CloneIgnoringRef(nsIURI** _newURI)
 {
-  // GetRef/SetRef not supported by nsNullPrincipalURI, so
+  // GetRef/SetRef not supported by NullPrincipalURI, so
   // CloneIgnoringRef() is the same as Clone().
   return Clone(_newURI);
 }
 
 NS_IMETHODIMP
-nsNullPrincipalURI::CloneWithNewRef(const nsACString& newRef, nsIURI **_newURI)
+NullPrincipalURI::CloneWithNewRef(const nsACString& newRef, nsIURI** _newURI)
 {
-  // GetRef/SetRef not supported by nsNullPrincipalURI, so
+  // GetRef/SetRef not supported by NullPrincipalURI, so
   // CloneWithNewRef() is the same as Clone().
   return Clone(_newURI);
 }
 
 NS_IMETHODIMP
-nsNullPrincipalURI::Equals(nsIURI *aOther, bool *_equals)
+NullPrincipalURI::Equals(nsIURI* aOther, bool* _equals)
 {
   *_equals = false;
-  RefPtr<nsNullPrincipalURI> otherURI;
+  RefPtr<NullPrincipalURI> otherURI;
   nsresult rv = aOther->QueryInterface(kNullPrincipalURIImplementationCID,
                                        getter_AddRefs(otherURI));
   if (NS_SUCCEEDED(rv)) {
     *_equals = mPath == otherURI->mPath;
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsNullPrincipalURI::EqualsExceptRef(nsIURI *aOther, bool *_equals)
+NullPrincipalURI::EqualsExceptRef(nsIURI* aOther, bool* _equals)
 {
-  // GetRef/SetRef not supported by nsNullPrincipalURI, so
+  // GetRef/SetRef not supported by NullPrincipalURI, so
   // EqualsExceptRef() is the same as Equals().
   return Equals(aOther, _equals);
 }
 
 NS_IMETHODIMP
-nsNullPrincipalURI::Resolve(const nsACString &aRelativePath,
-                            nsACString &_resolvedURI)
+NullPrincipalURI::Resolve(const nsACString& aRelativePath,
+                            nsACString& _resolvedURI)
 {
   _resolvedURI = aRelativePath;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsNullPrincipalURI::SchemeIs(const char *aScheme, bool *_schemeIs)
+NullPrincipalURI::SchemeIs(const char* aScheme, bool* _schemeIs)
 {
   *_schemeIs = (0 == nsCRT::strcasecmp(NS_NULLPRINCIPAL_SCHEME, aScheme));
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 //// nsIIPCSerializableURI
 
 void
-nsNullPrincipalURI::Serialize(mozilla::ipc::URIParams &aParams)
+NullPrincipalURI::Serialize(mozilla::ipc::URIParams& aParams)
 {
   aParams = mozilla::ipc::NullPrincipalURIParams();
 }
 
 bool
-nsNullPrincipalURI::Deserialize(const mozilla::ipc::URIParams &aParams)
+NullPrincipalURI::Deserialize(const mozilla::ipc::URIParams& aParams)
 {
   if (aParams.type() != mozilla::ipc::URIParams::TNullPrincipalURIParams) {
     MOZ_ASSERT_UNREACHABLE("unexpected URIParams type");
     return false;
   }
 
   nsresult rv = Init();
   NS_ENSURE_SUCCESS(rv, false);
 
   return true;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 //// nsISizeOf
 
 size_t
-nsNullPrincipalURI::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
+NullPrincipalURI::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
 {
   return mPath.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
 }
 
 size_t
-nsNullPrincipalURI::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
+NullPrincipalURI::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
+{
   return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
 }
-
rename from caps/nsNullPrincipalURI.h
rename to caps/NullPrincipalURI.h
--- a/caps/nsNullPrincipalURI.h
+++ b/caps/NullPrincipalURI.h
@@ -3,57 +3,57 @@
  * 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/. */
 
 /**
  * This wraps nsSimpleURI so that all calls to it are done on the main thread.
  */
 
-#ifndef __nsNullPrincipalURI_h__
-#define __nsNullPrincipalURI_h__
+#ifndef __NullPrincipalURI_h__
+#define __NullPrincipalURI_h__
 
 #include "nsIURI.h"
 #include "nsISizeOf.h"
 #include "nsString.h"
 #include "mozilla/Attributes.h"
 #include "nsIIPCSerializableURI.h"
 #include "mozilla/MemoryReporting.h"
-#include "nsNullPrincipal.h"
+#include "NullPrincipal.h"
 #include "nsID.h"
 
 // {51fcd543-3b52-41f7-b91b-6b54102236e6}
 #define NS_NULLPRINCIPALURI_IMPLEMENTATION_CID \
   {0x51fcd543, 0x3b52, 0x41f7, \
     {0xb9, 0x1b, 0x6b, 0x54, 0x10, 0x22, 0x36, 0xe6} }
 
-class nsNullPrincipalURI final : public nsIURI
-                               , public nsISizeOf
-                               , public nsIIPCSerializableURI
+class NullPrincipalURI final : public nsIURI
+                             , public nsISizeOf
+                             , public nsIIPCSerializableURI
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIURI
   NS_DECL_NSIIPCSERIALIZABLEURI
 
   // nsISizeOf
   virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
   virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
 
   // NB: This constructor exists only for deserialization.  Everyone
   // else should call Create.
-  nsNullPrincipalURI();
+  NullPrincipalURI();
 
   // Returns null on failure.
-  static already_AddRefed<nsNullPrincipalURI> Create();
+  static already_AddRefed<NullPrincipalURI> Create();
 
 private:
-  nsNullPrincipalURI(const nsNullPrincipalURI& aOther);
+  NullPrincipalURI(const NullPrincipalURI& aOther);
 
-  ~nsNullPrincipalURI() {}
+  ~NullPrincipalURI() {}
 
   nsresult Init();
 
   char mPathBytes[NSID_LENGTH];
   nsFixedCString mPath;
 };
 
-#endif // __nsNullPrincipalURI_h__
+#endif // __NullPrincipalURI_h__
copy from caps/BasePrincipal.cpp
copy to caps/OriginAttributes.cpp
--- a/caps/BasePrincipal.cpp
+++ b/caps/OriginAttributes.cpp
@@ -1,38 +1,20 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=2 sw=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/BasePrincipal.h"
-
-#include "nsDocShell.h"
-#ifdef MOZ_CRASHREPORTER
-#include "nsExceptionHandler.h"
-#endif
-#include "nsIAddonPolicyService.h"
-#include "nsIContentSecurityPolicy.h"
+#include "mozilla/OriginAttributes.h"
+#include "mozilla/Preferences.h"
+#include "mozilla/dom/URLSearchParams.h"
+#include "mozilla/dom/quota/QuotaManager.h"
 #include "nsIEffectiveTLDService.h"
-#include "nsIObjectInputStream.h"
-#include "nsIObjectOutputStream.h"
-
-#include "nsPrincipal.h"
-#include "nsNetUtil.h"
-#include "nsIURIWithPrincipal.h"
-#include "nsNullPrincipal.h"
-#include "nsScriptSecurityManager.h"
-#include "nsServiceManagerUtils.h"
-
-#include "mozilla/dom/ChromeUtils.h"
-#include "mozilla/dom/CSPDictionariesBinding.h"
-#include "mozilla/dom/quota/QuotaManager.h"
-#include "mozilla/dom/ToJSValue.h"
-#include "mozilla/dom/URLSearchParams.h"
+#include "nsIURI.h"
 
 namespace mozilla {
 
 using dom::URLParams;
 
 bool OriginAttributes::sFirstPartyIsolation = false;
 bool OriginAttributes::sRestrictedOpenerAccess = false;
 
@@ -293,457 +275,9 @@ OriginAttributes::IsPrivateBrowsing(cons
   OriginAttributes attrs;
   if (NS_WARN_IF(!attrs.PopulateFromOrigin(aOrigin, dummy))) {
     return false;
   }
 
   return !!attrs.mPrivateBrowsingId;
 }
 
-BasePrincipal::BasePrincipal(PrincipalKind aKind)
-  : mKind(aKind)
-  , mDomainSet(false)
-{}
-
-BasePrincipal::~BasePrincipal()
-{}
-
-NS_IMETHODIMP
-BasePrincipal::GetOrigin(nsACString& aOrigin)
-{
-  nsresult rv = GetOriginNoSuffix(aOrigin);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsAutoCString suffix;
-  rv = GetOriginSuffix(suffix);
-  NS_ENSURE_SUCCESS(rv, rv);
-  aOrigin.Append(suffix);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-BasePrincipal::GetOriginNoSuffix(nsACString& aOrigin)
-{
-  if (mOriginNoSuffix) {
-    return mOriginNoSuffix->ToUTF8String(aOrigin);
-  }
-  return GetOriginInternal(aOrigin);
-}
-
-bool
-BasePrincipal::Subsumes(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration)
-{
-  MOZ_ASSERT(aOther);
-  MOZ_ASSERT_IF(Kind() == eCodebasePrincipal, mOriginSuffix);
-
-  // Expanded principals handle origin attributes for each of their
-  // sub-principals individually, null principals do only simple checks for
-  // pointer equality, and system principals are immune to origin attributes
-  // checks, so only do this check for codebase principals.
-  if (Kind() == eCodebasePrincipal &&
-      mOriginSuffix != Cast(aOther)->mOriginSuffix) {
-    return false;
-  }
-
-  return SubsumesInternal(aOther, aConsideration);
-}
-
-NS_IMETHODIMP
-BasePrincipal::Equals(nsIPrincipal *aOther, bool *aResult)
-{
-  NS_ENSURE_TRUE(aOther, NS_ERROR_INVALID_ARG);
-
-  *aResult = FastEquals(aOther);
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-BasePrincipal::EqualsConsideringDomain(nsIPrincipal *aOther, bool *aResult)
-{
-  NS_ENSURE_TRUE(aOther, NS_ERROR_INVALID_ARG);
-
-  *aResult = FastEqualsConsideringDomain(aOther);
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-BasePrincipal::Subsumes(nsIPrincipal *aOther, bool *aResult)
-{
-  NS_ENSURE_TRUE(aOther, NS_ERROR_INVALID_ARG);
-
-  *aResult = FastSubsumes(aOther);
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-BasePrincipal::SubsumesConsideringDomain(nsIPrincipal *aOther, bool *aResult)
-{
-  NS_ENSURE_TRUE(aOther, NS_ERROR_INVALID_ARG);
-
-  *aResult = FastSubsumesConsideringDomain(aOther);
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-BasePrincipal::SubsumesConsideringDomainIgnoringFPD(nsIPrincipal *aOther,
-                                                    bool *aResult)
-{
-  NS_ENSURE_TRUE(aOther, NS_ERROR_INVALID_ARG);
-
-  *aResult = FastSubsumesConsideringDomainIgnoringFPD(aOther);
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-BasePrincipal::CheckMayLoad(nsIURI* aURI, bool aReport, bool aAllowIfInheritsPrincipal)
-{
-  // Check the internal method first, which allows us to quickly approve loads
-  // for the System Principal.
-  if (MayLoadInternal(aURI)) {
-    return NS_OK;
-  }
-
-  nsresult rv;
-  if (aAllowIfInheritsPrincipal) {
-    // If the caller specified to allow loads of URIs that inherit
-    // our principal, allow the load if this URI inherits its principal.
-    bool doesInheritSecurityContext;
-    rv = NS_URIChainHasFlags(aURI, nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
-                             &doesInheritSecurityContext);
-    if (NS_SUCCEEDED(rv) && doesInheritSecurityContext) {
-      return NS_OK;
-    }
-  }
-
-  bool fetchableByAnyone;
-  rv = NS_URIChainHasFlags(aURI, nsIProtocolHandler::URI_FETCHABLE_BY_ANYONE, &fetchableByAnyone);
-  if (NS_SUCCEEDED(rv) && fetchableByAnyone) {
-    return NS_OK;
-  }
-
-  if (aReport) {
-    nsCOMPtr<nsIURI> prinURI;
-    rv = GetURI(getter_AddRefs(prinURI));
-    if (NS_SUCCEEDED(rv) && prinURI) {
-      nsScriptSecurityManager::ReportError(nullptr, NS_LITERAL_STRING("CheckSameOriginError"), prinURI, aURI);
-    }
-  }
-
-  return NS_ERROR_DOM_BAD_URI;
-}
-
-NS_IMETHODIMP
-BasePrincipal::GetCsp(nsIContentSecurityPolicy** aCsp)
-{
-  NS_IF_ADDREF(*aCsp = mCSP);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-BasePrincipal::SetCsp(nsIContentSecurityPolicy* aCsp)
-{
-  // Never destroy an existing CSP on the principal.
-  // This method should only be called in rare cases.
-
-  MOZ_ASSERT(!mCSP, "do not destroy an existing CSP");
-  if (mCSP) {
-    return NS_ERROR_ALREADY_INITIALIZED;
-  }
-
-  mCSP = aCsp;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-BasePrincipal::EnsureCSP(nsIDOMDocument* aDocument,
-                         nsIContentSecurityPolicy** aCSP)
-{
-  if (mCSP) {
-    // if there is a CSP already associated with this principal
-    // then just return that - do not overwrite it!!!
-    NS_IF_ADDREF(*aCSP = mCSP);
-    return NS_OK;
-  }
-
-  nsresult rv = NS_OK;
-  mCSP = do_CreateInstance("@mozilla.org/cspcontext;1", &rv);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // Store the request context for violation reports
-  rv = aDocument ? mCSP->SetRequestContext(aDocument, nullptr)
-                 : mCSP->SetRequestContext(nullptr, this);
-  NS_ENSURE_SUCCESS(rv, rv);
-  NS_IF_ADDREF(*aCSP = mCSP);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-BasePrincipal::GetPreloadCsp(nsIContentSecurityPolicy** aPreloadCSP)
-{
-  NS_IF_ADDREF(*aPreloadCSP = mPreloadCSP);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-BasePrincipal::EnsurePreloadCSP(nsIDOMDocument* aDocument,
-                                nsIContentSecurityPolicy** aPreloadCSP)
-{
-  if (mPreloadCSP) {
-    // if there is a speculative CSP already associated with this principal
-    // then just return that - do not overwrite it!!!
-    NS_IF_ADDREF(*aPreloadCSP = mPreloadCSP);
-    return NS_OK;
-  }
-
-  nsresult rv = NS_OK;
-  mPreloadCSP = do_CreateInstance("@mozilla.org/cspcontext;1", &rv);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // Store the request context for violation reports
-  rv = aDocument ? mPreloadCSP->SetRequestContext(aDocument, nullptr)
-                 : mPreloadCSP->SetRequestContext(nullptr, this);
-  NS_ENSURE_SUCCESS(rv, rv);
-  NS_IF_ADDREF(*aPreloadCSP = mPreloadCSP);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-BasePrincipal::GetCspJSON(nsAString& outCSPinJSON)
-{
-  outCSPinJSON.Truncate();
-  dom::CSPPolicies jsonPolicies;
-
-  if (!mCSP) {
-    jsonPolicies.ToJSON(outCSPinJSON);
-    return NS_OK;
-  }
-  return mCSP->ToJSON(outCSPinJSON);
-}
-
-NS_IMETHODIMP
-BasePrincipal::GetIsNullPrincipal(bool* aResult)
-{
-  *aResult = Kind() == eNullPrincipal;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-BasePrincipal::GetIsCodebasePrincipal(bool* aResult)
-{
-  *aResult = Kind() == eCodebasePrincipal;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-BasePrincipal::GetIsExpandedPrincipal(bool* aResult)
-{
-  *aResult = Kind() == eExpandedPrincipal;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-BasePrincipal::GetIsSystemPrincipal(bool* aResult)
-{
-  *aResult = Kind() == eSystemPrincipal;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-BasePrincipal::GetOriginAttributes(JSContext* aCx, JS::MutableHandle<JS::Value> aVal)
-{
-  if (NS_WARN_IF(!ToJSValue(aCx, mOriginAttributes, aVal))) {
-    return NS_ERROR_FAILURE;
-  }
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-BasePrincipal::GetOriginSuffix(nsACString& aOriginAttributes)
-{
-  MOZ_ASSERT(mOriginSuffix);
-  return mOriginSuffix->ToUTF8String(aOriginAttributes);
-}
-
-NS_IMETHODIMP
-BasePrincipal::GetAppStatus(uint16_t* aAppStatus)
-{
-  // TODO: Remove GetAppStatus.
-  *aAppStatus = nsIPrincipal::APP_STATUS_NOT_INSTALLED;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-BasePrincipal::GetAppId(uint32_t* aAppId)
-{
-  if (AppId() == nsIScriptSecurityManager::UNKNOWN_APP_ID) {
-    MOZ_ASSERT(false);
-    *aAppId = nsIScriptSecurityManager::NO_APP_ID;
-    return NS_OK;
-  }
-
-  *aAppId = AppId();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-BasePrincipal::GetUserContextId(uint32_t* aUserContextId)
-{
-  *aUserContextId = UserContextId();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-BasePrincipal::GetPrivateBrowsingId(uint32_t* aPrivateBrowsingId)
-{
-  *aPrivateBrowsingId = PrivateBrowsingId();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-BasePrincipal::GetIsInIsolatedMozBrowserElement(bool* aIsInIsolatedMozBrowserElement)
-{
-  *aIsInIsolatedMozBrowserElement = IsInIsolatedMozBrowserElement();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-BasePrincipal::GetUnknownAppId(bool* aUnknownAppId)
-{
-  *aUnknownAppId = AppId() == nsIScriptSecurityManager::UNKNOWN_APP_ID;
-  return NS_OK;
-}
-
-bool
-BasePrincipal::AddonHasPermission(const nsAString& aPerm)
-{
-  nsAutoString addonId;
-  NS_ENSURE_SUCCESS(GetAddonId(addonId), false);
-
-  if (addonId.IsEmpty()) {
-    return false;
-  }
-
-  nsCOMPtr<nsIAddonPolicyService> aps =
-    do_GetService("@mozilla.org/addons/policy-service;1");
-  NS_ENSURE_TRUE(aps, false);
-
-  bool retval = false;
-  nsresult rv = aps->AddonHasPermission(addonId, aPerm, &retval);
-  NS_ENSURE_SUCCESS(rv, false);
-  return retval;
-}
-
-already_AddRefed<BasePrincipal>
-BasePrincipal::CreateCodebasePrincipal(nsIURI* aURI, const OriginAttributes& aAttrs)
-{
-  // If the URI is supposed to inherit the security context of whoever loads it,
-  // we shouldn't make a codebase principal for it.
-  bool inheritsPrincipal;
-  nsresult rv = NS_URIChainHasFlags(aURI, nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
-                                    &inheritsPrincipal);
-  if (NS_FAILED(rv) || inheritsPrincipal) {
-    return nsNullPrincipal::Create(aAttrs);
-  }
-
-  // Check whether the URI knows what its principal is supposed to be.
-  nsCOMPtr<nsIURIWithPrincipal> uriPrinc = do_QueryInterface(aURI);
-  if (uriPrinc) {
-    nsCOMPtr<nsIPrincipal> principal;
-    uriPrinc->GetPrincipal(getter_AddRefs(principal));
-    if (!principal) {
-      return nsNullPrincipal::Create(aAttrs);
-    }
-    RefPtr<BasePrincipal> concrete = Cast(principal);
-    return concrete.forget();
-  }
-
-  // Mint a codebase principal.
-  RefPtr<nsPrincipal> codebase = new nsPrincipal();
-  rv = codebase->Init(aURI, aAttrs);
-  NS_ENSURE_SUCCESS(rv, nullptr);
-  return codebase.forget();
-}
-
-already_AddRefed<BasePrincipal>
-BasePrincipal::CreateCodebasePrincipal(const nsACString& aOrigin)
-{
-  MOZ_ASSERT(!StringBeginsWith(aOrigin, NS_LITERAL_CSTRING("[")),
-             "CreateCodebasePrincipal does not support System and Expanded principals");
-
-  MOZ_ASSERT(!StringBeginsWith(aOrigin, NS_LITERAL_CSTRING(NS_NULLPRINCIPAL_SCHEME ":")),
-             "CreateCodebasePrincipal does not support nsNullPrincipal");
-
-  nsAutoCString originNoSuffix;
-  mozilla::OriginAttributes attrs;
-  if (!attrs.PopulateFromOrigin(aOrigin, originNoSuffix)) {
-    return nullptr;
-  }
-
-  nsCOMPtr<nsIURI> uri;
-  nsresult rv = NS_NewURI(getter_AddRefs(uri), originNoSuffix);
-  NS_ENSURE_SUCCESS(rv, nullptr);
-
-  return BasePrincipal::CreateCodebasePrincipal(uri, attrs);
-}
-
-already_AddRefed<BasePrincipal>
-BasePrincipal::CloneStrippingUserContextIdAndFirstPartyDomain()
-{
-  OriginAttributes attrs = OriginAttributesRef();
-  attrs.StripAttributes(OriginAttributes::STRIP_USER_CONTEXT_ID |
-                        OriginAttributes::STRIP_FIRST_PARTY_DOMAIN);
-
-  nsAutoCString originNoSuffix;
-  nsresult rv = GetOriginNoSuffix(originNoSuffix);
-  NS_ENSURE_SUCCESS(rv, nullptr);
-
-  nsCOMPtr<nsIURI> uri;
-  rv = NS_NewURI(getter_AddRefs(uri), originNoSuffix);
-  NS_ENSURE_SUCCESS(rv, nullptr);
-
-  return BasePrincipal::CreateCodebasePrincipal(uri, attrs);
-}
-
-bool
-BasePrincipal::AddonAllowsLoad(nsIURI* aURI, bool aExplicit /* = false */)
-{
-  nsAutoString addonId;
-  NS_ENSURE_SUCCESS(GetAddonId(addonId), false);
-
-  if (addonId.IsEmpty()) {
-    return false;
-  }
-
-  nsCOMPtr<nsIAddonPolicyService> aps = do_GetService("@mozilla.org/addons/policy-service;1");
-  NS_ENSURE_TRUE(aps, false);
-
-  bool allowed = false;
-  nsresult rv = aps->AddonMayLoadURI(addonId, aURI, aExplicit, &allowed);
-  return NS_SUCCEEDED(rv) && allowed;
-}
-
-void
-BasePrincipal::FinishInit()
-{
-  // First compute the origin suffix since it's infallible.
-  nsAutoCString originSuffix;
-  mOriginAttributes.CreateSuffix(originSuffix);
-  mOriginSuffix = NS_Atomize(originSuffix);
-
-  // Then compute the origin without the suffix.
-  nsAutoCString originNoSuffix;
-  nsresult rv = GetOriginInternal(originNoSuffix);
-  if (NS_FAILED(rv)) {
-    // If GetOriginInternal fails, we will get a null atom for mOriginNoSuffix,
-    // which we deal with anywhere mOriginNoSuffix is used.
-    // Once this is made infallible we can remove those null checks.
-    mOriginNoSuffix = nullptr;
-    return;
-  }
-  mOriginNoSuffix = NS_Atomize(originNoSuffix);
-}
-
 } // namespace mozilla
copy from caps/BasePrincipal.h
copy to caps/OriginAttributes.h
--- a/caps/BasePrincipal.h
+++ b/caps/OriginAttributes.h
@@ -1,35 +1,23 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 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/. */
 
-#ifndef mozilla_BasePrincipal_h
-#define mozilla_BasePrincipal_h
+#ifndef mozilla_OriginAttributes_h
+#define mozilla_OriginAttributes_h
 
-#include "nsJSPrincipals.h"
-
-#include "mozilla/Attributes.h"
 #include "mozilla/dom/ChromeUtils.h"
 #include "mozilla/dom/ChromeUtilsBinding.h"
 #include "nsIScriptSecurityManager.h"
 
-class nsIContentSecurityPolicy;
-class nsIObjectOutputStream;
-class nsIObjectInputStream;
-class nsIURI;
-
-class nsExpandedPrincipal;
-
 namespace mozilla {
 
-// Base OriginAttributes class. This has several subclass flavors, and is not
-// directly constructable itself.
 class OriginAttributes : public dom::OriginAttributesDictionary
 {
 public:
   OriginAttributes() {}
 
   OriginAttributes(uint32_t aAppId, bool aInIsolatedMozBrowser)
   {
     mAppId = aAppId;
@@ -186,214 +174,11 @@ public:
         mFirstPartyDomain.Value() != aOther.mFirstPartyDomain.Value()) {
       return false;
     }
 
     return true;
   }
 };
 
-/*
- * Base class from which all nsIPrincipal implementations inherit. Use this for
- * default implementations and other commonalities between principal
- * implementations.
- *
- * We should merge nsJSPrincipals into this class at some point.
- */
-class BasePrincipal : public nsJSPrincipals
-{
-public:
-  enum PrincipalKind {
-    eNullPrincipal,
-    eCodebasePrincipal,
-    eExpandedPrincipal,
-    eSystemPrincipal
-  };
-
-  explicit BasePrincipal(PrincipalKind aKind);
-
-  enum DocumentDomainConsideration { DontConsiderDocumentDomain, ConsiderDocumentDomain};
-  bool Subsumes(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration);
-
-  NS_IMETHOD GetOrigin(nsACString& aOrigin) final;
-  NS_IMETHOD GetOriginNoSuffix(nsACString& aOrigin) final;
-  NS_IMETHOD Equals(nsIPrincipal* other, bool* _retval) final;
-  NS_IMETHOD EqualsConsideringDomain(nsIPrincipal* other, bool* _retval) final;
-  NS_IMETHOD Subsumes(nsIPrincipal* other, bool* _retval) final;
-  NS_IMETHOD SubsumesConsideringDomain(nsIPrincipal* other, bool* _retval) final;
-  NS_IMETHOD SubsumesConsideringDomainIgnoringFPD(nsIPrincipal* other, bool* _retval) final;
-  NS_IMETHOD CheckMayLoad(nsIURI* uri, bool report, bool allowIfInheritsPrincipal) final;
-  NS_IMETHOD GetCsp(nsIContentSecurityPolicy** aCsp) override;
-  NS_IMETHOD SetCsp(nsIContentSecurityPolicy* aCsp) override;
-  NS_IMETHOD EnsureCSP(nsIDOMDocument* aDocument, nsIContentSecurityPolicy** aCSP) override;
-  NS_IMETHOD GetPreloadCsp(nsIContentSecurityPolicy** aPreloadCSP) override;
-  NS_IMETHOD EnsurePreloadCSP(nsIDOMDocument* aDocument, nsIContentSecurityPolicy** aCSP) override;
-  NS_IMETHOD GetCspJSON(nsAString& outCSPinJSON) override;
-  NS_IMETHOD GetIsNullPrincipal(bool* aResult) override;
-  NS_IMETHOD GetIsCodebasePrincipal(bool* aResult) override;
-  NS_IMETHOD GetIsExpandedPrincipal(bool* aResult) override;
-  NS_IMETHOD GetIsSystemPrincipal(bool* aResult) override;
-  NS_IMETHOD GetOriginAttributes(JSContext* aCx, JS::MutableHandle<JS::Value> aVal) final;
-  NS_IMETHOD GetOriginSuffix(nsACString& aOriginSuffix) final;
-  NS_IMETHOD GetAppStatus(uint16_t* aAppStatus) final;
-  NS_IMETHOD GetAppId(uint32_t* aAppStatus) final;
-  NS_IMETHOD GetIsInIsolatedMozBrowserElement(bool* aIsInIsolatedMozBrowserElement) final;
-  NS_IMETHOD GetUnknownAppId(bool* aUnknownAppId) final;
-  NS_IMETHOD GetUserContextId(uint32_t* aUserContextId) final;
-  NS_IMETHOD GetPrivateBrowsingId(uint32_t* aPrivateBrowsingId) final;
-
-  virtual bool AddonHasPermission(const nsAString& aPerm);
-
-  virtual bool IsCodebasePrincipal() const { return false; };
-
-  static BasePrincipal* Cast(nsIPrincipal* aPrin) { return static_cast<BasePrincipal*>(aPrin); }
-  static already_AddRefed<BasePrincipal>
-  CreateCodebasePrincipal(nsIURI* aURI, const OriginAttributes& aAttrs);
-  static already_AddRefed<BasePrincipal> CreateCodebasePrincipal(const nsACString& aOrigin);
-
-  const OriginAttributes& OriginAttributesRef() final { return mOriginAttributes; }
-  uint32_t AppId() const { return mOriginAttributes.mAppId; }
-  uint32_t UserContextId() const { return mOriginAttributes.mUserContextId; }
-  uint32_t PrivateBrowsingId() const { return mOriginAttributes.mPrivateBrowsingId; }
-  bool IsInIsolatedMozBrowserElement() const { return mOriginAttributes.mInIsolatedMozBrowser; }
-
-  PrincipalKind Kind() const { return mKind; }
-
-  already_AddRefed<BasePrincipal> CloneStrippingUserContextIdAndFirstPartyDomain();
-
-  // Helper to check whether this principal is associated with an addon that
-  // allows unprivileged code to load aURI.  aExplicit == true will prevent
-  // use of all_urls permission, requiring the domain in its permissions.
-  bool AddonAllowsLoad(nsIURI* aURI, bool aExplicit = false);
-
-  // Call these to avoid the cost of virtual dispatch.
-  inline bool FastEquals(nsIPrincipal* aOther);
-  inline bool FastEqualsConsideringDomain(nsIPrincipal* aOther);
-  inline bool FastSubsumes(nsIPrincipal* aOther);
-  inline bool FastSubsumesConsideringDomain(nsIPrincipal* aOther);
-  inline bool FastSubsumesConsideringDomainIgnoringFPD(nsIPrincipal* aOther);
-
-protected:
-  virtual ~BasePrincipal();
-
-  virtual nsresult GetOriginInternal(nsACString& aOrigin) = 0;
-  // Note that this does not check OriginAttributes. Callers that depend on
-  // those must call Subsumes instead.
-  virtual bool SubsumesInternal(nsIPrincipal* aOther, DocumentDomainConsideration aConsider) = 0;
-
-  // Internal, side-effect-free check to determine whether the concrete
-  // principal would allow the load ignoring any common behavior implemented in
-  // BasePrincipal::CheckMayLoad.
-  virtual bool MayLoadInternal(nsIURI* aURI) = 0;
-  friend class ::nsExpandedPrincipal;
-
-  // This function should be called as the last step of the initialization of the
-  // principal objects.  It's typically called as the last step from the Init()
-  // method of the child classes.
-  void FinishInit();
-
-  nsCOMPtr<nsIContentSecurityPolicy> mCSP;
-  nsCOMPtr<nsIContentSecurityPolicy> mPreloadCSP;
-  nsCOMPtr<nsIAtom> mOriginNoSuffix;
-  nsCOMPtr<nsIAtom> mOriginSuffix;
-  OriginAttributes mOriginAttributes;
-  PrincipalKind mKind;
-  bool mDomainSet;
-};
-
-inline bool
-BasePrincipal::FastEquals(nsIPrincipal* aOther)
-{
-  auto other = Cast(aOther);
-  if (Kind() != other->Kind()) {
-    // Principals of different kinds can't be equal.
-    return false;
-  }
-
-  // Two principals are considered to be equal if their origins are the same.
-  // If the two principals are codebase principals, their origin attributes
-  // (aka the origin suffix) must also match.
-  // If the two principals are null principals, they're only equal if they're
-  // the same object.
-  if (Kind() == eNullPrincipal || Kind() == eSystemPrincipal) {
-    return this == other;
-  }
-
-  if (mOriginNoSuffix) {
-    if (Kind() == eCodebasePrincipal) {
-      return mOriginNoSuffix == other->mOriginNoSuffix &&
-             mOriginSuffix == other->mOriginSuffix;
-    }
-
-    MOZ_ASSERT(Kind() == eExpandedPrincipal);
-    return mOriginNoSuffix == other->mOriginNoSuffix;
-  }
-
-  // If mOriginNoSuffix is null on one of our principals, we must fall back
-  // to the slow path.
-  return Subsumes(aOther, DontConsiderDocumentDomain) &&
-         other->Subsumes(this, DontConsiderDocumentDomain);
-}
-
-inline bool
-BasePrincipal::FastEqualsConsideringDomain(nsIPrincipal* aOther)
-{
-  // If neither of the principals have document.domain set, we use the fast path
-  // in Equals().  Otherwise, we fall back to the slow path below.
-  auto other = Cast(aOther);
-  if (!mDomainSet && !other->mDomainSet) {
-    return FastEquals(aOther);
-  }
-
-  return Subsumes(aOther, ConsiderDocumentDomain) &&
-         other->Subsumes(this, ConsiderDocumentDomain);
-}
-
-inline bool
-BasePrincipal::FastSubsumes(nsIPrincipal* aOther)
-{
-  // If two principals are equal, then they both subsume each other.
-  // We deal with two special cases first:
-  // Null principals only subsume each other if they are equal, and are only
-  // equal if they're the same object.
-  // Also, if mOriginNoSuffix is null, FastEquals falls back to the slow path
-  // using Subsumes, so we don't want to use it in that case to avoid an
-  // infinite recursion.
-  auto other = Cast(aOther);
-  if (Kind() == eNullPrincipal && other->Kind() == eNullPrincipal) {
-    return this == other;
-  }
-  if (mOriginNoSuffix && FastEquals(aOther)) {
-    return true;
-  }
-
-  // Otherwise, fall back to the slow path.
-  return Subsumes(aOther, DontConsiderDocumentDomain);
-}
-
-inline bool
-BasePrincipal::FastSubsumesConsideringDomain(nsIPrincipal* aOther)
-{
-  // If neither of the principals have document.domain set, we hand off to
-  // FastSubsumes() which has fast paths for some special cases. Otherwise, we fall
-  // back to the slow path below.
-  if (!mDomainSet && !Cast(aOther)->mDomainSet) {
-    return FastSubsumes(aOther);
-  }
-
-  return Subsumes(aOther, ConsiderDocumentDomain);
-}
-
-inline bool
-BasePrincipal::FastSubsumesConsideringDomainIgnoringFPD(nsIPrincipal* aOther)
-{
-  if (Kind() == eCodebasePrincipal &&
-      !dom::ChromeUtils::IsOriginAttributesEqualIgnoringFPD(
-            mOriginAttributes, Cast(aOther)->mOriginAttributes)) {
-    return false;
-  }
-
- return SubsumesInternal(aOther, ConsiderDocumentDomain);
-}
-
 } // namespace mozilla
 
-#endif /* mozilla_BasePrincipal_h */
+#endif /* mozilla_OriginAttributes_h */
rename from caps/nsSystemPrincipal.cpp
rename to caps/SystemPrincipal.cpp
--- a/caps/nsSystemPrincipal.cpp
+++ b/caps/SystemPrincipal.cpp
@@ -1,156 +1,156 @@
 /* -*- 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/. */
 
 /* The privileged system principal. */
 
 #include "nscore.h"
-#include "nsSystemPrincipal.h"
+#include "SystemPrincipal.h"
 #include "nsIComponentManager.h"
 #include "nsIServiceManager.h"
 #include "nsIURL.h"
 #include "nsCOMPtr.h"
 #include "nsXPIDLString.h"
 #include "nsReadableUtils.h"
 #include "nsCRT.h"
 #include "nsString.h"
 #include "nsIClassInfoImpl.h"
 #include "nsIScriptSecurityManager.h"
 #include "pratom.h"
 
-NS_IMPL_CLASSINFO(nsSystemPrincipal, nullptr,
+NS_IMPL_CLASSINFO(SystemPrincipal, nullptr,
                   nsIClassInfo::SINGLETON | nsIClassInfo::MAIN_THREAD_ONLY,
                   NS_SYSTEMPRINCIPAL_CID)
-NS_IMPL_QUERY_INTERFACE_CI(nsSystemPrincipal,
+NS_IMPL_QUERY_INTERFACE_CI(SystemPrincipal,
                            nsIPrincipal,
                            nsISerializable)
-NS_IMPL_CI_INTERFACE_GETTER(nsSystemPrincipal,
+NS_IMPL_CI_INTERFACE_GETTER(SystemPrincipal,
                             nsIPrincipal,
                             nsISerializable)
 
 #define SYSTEM_PRINCIPAL_SPEC "[System Principal]"
 
-already_AddRefed<nsSystemPrincipal>
-nsSystemPrincipal::Create()
+already_AddRefed<SystemPrincipal>
+SystemPrincipal::Create()
 {
-  RefPtr<nsSystemPrincipal> sp = new nsSystemPrincipal();
+  RefPtr<SystemPrincipal> sp = new SystemPrincipal();
   sp->FinishInit();
   return sp.forget();
 }
 
 nsresult
-nsSystemPrincipal::GetScriptLocation(nsACString &aStr)
+SystemPrincipal::GetScriptLocation(nsACString &aStr)
 {
     aStr.AssignLiteral(SYSTEM_PRINCIPAL_SPEC);
     return NS_OK;
 }
 
 ///////////////////////////////////////
 // Methods implementing nsIPrincipal //
 ///////////////////////////////////////
 
 NS_IMETHODIMP
-nsSystemPrincipal::GetHashValue(uint32_t *result)
+SystemPrincipal::GetHashValue(uint32_t *result)
 {
     *result = NS_PTR_TO_INT32(this);
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsSystemPrincipal::GetURI(nsIURI** aURI)
+SystemPrincipal::GetURI(nsIURI** aURI)
 {
     *aURI = nullptr;
     return NS_OK;
 }
 
 nsresult
-nsSystemPrincipal::GetOriginInternal(nsACString& aOrigin)
+SystemPrincipal::GetOriginInternal(nsACString& aOrigin)
 {
     aOrigin.AssignLiteral(SYSTEM_PRINCIPAL_SPEC);
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsSystemPrincipal::GetCsp(nsIContentSecurityPolicy** aCsp)
+SystemPrincipal::GetCsp(nsIContentSecurityPolicy** aCsp)
 {
   *aCsp = nullptr;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsSystemPrincipal::SetCsp(nsIContentSecurityPolicy* aCsp)
+SystemPrincipal::SetCsp(nsIContentSecurityPolicy* aCsp)
 {
   // Never destroy an existing CSP on the principal.
   // This method should only be called in rare cases.
 
   return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
-nsSystemPrincipal::EnsureCSP(nsIDOMDocument* aDocument,
-                             nsIContentSecurityPolicy** aCSP)
+SystemPrincipal::EnsureCSP(nsIDOMDocument* aDocument,
+                           nsIContentSecurityPolicy** aCSP)
 {
   // CSP on a system principal makes no sense
   return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
-nsSystemPrincipal::GetPreloadCsp(nsIContentSecurityPolicy** aPreloadCSP)
+SystemPrincipal::GetPreloadCsp(nsIContentSecurityPolicy** aPreloadCSP)
 {
   *aPreloadCSP = nullptr;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsSystemPrincipal::EnsurePreloadCSP(nsIDOMDocument* aDocument,
-                                    nsIContentSecurityPolicy** aPreloadCSP)
+SystemPrincipal::EnsurePreloadCSP(nsIDOMDocument* aDocument,
+                                  nsIContentSecurityPolicy** aPreloadCSP)
 {
   // CSP on a system principal makes no sense
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsSystemPrincipal::GetDomain(nsIURI** aDomain)
+SystemPrincipal::GetDomain(nsIURI** aDomain)
 {
     *aDomain = nullptr;
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsSystemPrincipal::SetDomain(nsIURI* aDomain)
+SystemPrincipal::SetDomain(nsIURI* aDomain)
 {
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsSystemPrincipal::GetBaseDomain(nsACString& aBaseDomain)
+SystemPrincipal::GetBaseDomain(nsACString& aBaseDomain)
 {
   // No base domain for chrome.
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsSystemPrincipal::GetAddonId(nsAString& aAddonId)
+SystemPrincipal::GetAddonId(nsAString& aAddonId)
 {
   aAddonId.Truncate();
   return NS_OK;
 };
 
 //////////////////////////////////////////
 // Methods implementing nsISerializable //
 //////////////////////////////////////////
 
 NS_IMETHODIMP
-nsSystemPrincipal::Read(nsIObjectInputStream* aStream)
+SystemPrincipal::Read(nsIObjectInputStream* aStream)
 {
     // no-op: CID is sufficient to identify the mSystemPrincipal singleton
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsSystemPrincipal::Write(nsIObjectOutputStream* aStream)
+SystemPrincipal::Write(nsIObjectOutputStream* aStream)
 {
     // no-op: CID is sufficient to identify the mSystemPrincipal singleton
     return NS_OK;
 }
rename from caps/nsSystemPrincipal.h
rename to caps/SystemPrincipal.h
--- a/caps/nsSystemPrincipal.h
+++ b/caps/SystemPrincipal.h
@@ -1,39 +1,39 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 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/. */
 
 /* The privileged system principal. */
 
-#ifndef nsSystemPrincipal_h__
-#define nsSystemPrincipal_h__
+#ifndef SystemPrincipal_h
+#define SystemPrincipal_h
 
 #include "nsIPrincipal.h"
 #include "nsJSPrincipals.h"
 
 #include "mozilla/BasePrincipal.h"
 
 #define NS_SYSTEMPRINCIPAL_CID \
 { 0x4a6212db, 0xaccb, 0x11d3, \
 { 0xb7, 0x65, 0x0, 0x60, 0xb0, 0xb6, 0xce, 0xcb }}
 #define NS_SYSTEMPRINCIPAL_CONTRACTID "@mozilla.org/systemprincipal;1"
 
 
-class nsSystemPrincipal final : public mozilla::BasePrincipal
+class SystemPrincipal final : public mozilla::BasePrincipal
 {
-  nsSystemPrincipal()
+  SystemPrincipal()
     : BasePrincipal(eSystemPrincipal)
   {
   }
 
 public:
-  static already_AddRefed<nsSystemPrincipal> Create();
+  static already_AddRefed<SystemPrincipal> Create();
 
   NS_DECL_NSISERIALIZABLE
   NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) override;
   NS_IMETHOD GetHashValue(uint32_t* aHashValue) override;
   NS_IMETHOD GetURI(nsIURI** aURI) override;
   NS_IMETHOD GetDomain(nsIURI** aDomain) override;
   NS_IMETHOD SetDomain(nsIURI* aDomain) override;
   NS_IMETHOD GetCsp(nsIContentSecurityPolicy** aCsp) override;
@@ -43,22 +43,23 @@ public:
   NS_IMETHOD EnsurePreloadCSP(nsIDOMDocument* aDocument, nsIContentSecurityPolicy** aCSP) override;
   NS_IMETHOD GetBaseDomain(nsACString& aBaseDomain) override;
   NS_IMETHOD GetAddonId(nsAString& aAddonId) override;
   nsresult GetOriginInternal(nsACString& aOrigin) override;
 
   virtual nsresult GetScriptLocation(nsACString &aStr) override;
 
 protected:
-  virtual ~nsSystemPrincipal(void) {}
+  virtual ~SystemPrincipal(void) {}
 
-  bool SubsumesInternal(nsIPrincipal *aOther, DocumentDomainConsideration aConsideration) override
+  bool SubsumesInternal(nsIPrincipal *aOther,
+                        DocumentDomainConsideration aConsideration) override
   {
     return true;
   }
 
   bool MayLoadInternal(nsIURI* aURI) override
   {
     return true;
   }
 };
 
-#endif // nsSystemPrincipal_h__
+#endif // SystemPrincipal_h
--- a/caps/moz.build
+++ b/caps/moz.build
@@ -20,39 +20,41 @@ XPIDL_SOURCES += [
     'nsIPrincipal.idl',
     'nsIScriptSecurityManager.idl',
 ]
 
 XPIDL_MODULE = 'caps'
 
 EXPORTS += [
     'nsJSPrincipals.h',
-    'nsNullPrincipal.h',
-    'nsNullPrincipalURI.h',
+    'NullPrincipal.h',
+    'NullPrincipalURI.h',
 ]
 
 EXPORTS.mozilla = [
-    'BasePrincipal.h'
+    'BasePrincipal.h',
+    'OriginAttributes.h',
 ]
 
 SOURCES += [
     # Compile this separately since nsExceptionHandler.h conflicts
-    # with something from nsNullPrincipal.cpp.
+    # with something from NullPrincipal.cpp.
     'BasePrincipal.cpp',
 ]
 
 UNIFIED_SOURCES += [
+    'ContentPrincipal.cpp',
     'DomainPolicy.cpp',
-    'nsExpandedPrincipal.cpp',
+    'ExpandedPrincipal.cpp',
     'nsJSPrincipals.cpp',
-    'nsNullPrincipal.cpp',
-    'nsNullPrincipalURI.cpp',
-    'nsPrincipal.cpp',
     'nsScriptSecurityManager.cpp',
-    'nsSystemPrincipal.cpp',
+    'NullPrincipal.cpp',
+    'NullPrincipalURI.cpp',
+    'OriginAttributes.cpp',
+    'SystemPrincipal.cpp',
 ]
 
 LOCAL_INCLUDES += [
     '/docshell/base',
     '/dom/base',
     '/js/xpconnect/src',
 ]
 
--- a/caps/nsIPrincipal.idl
+++ b/caps/nsIPrincipal.idl
@@ -352,22 +352,22 @@ interface nsIPrincipal : nsISerializable
 
     /**
      * Returns true iff this is the system principal.
      */
     [infallible] readonly attribute boolean isSystemPrincipal;
 };
 
 /**
- * If nsSystemPrincipal is too risky to use, but we want a principal to access
- * more than one origin, nsExpandedPrincipals letting us define an array of
- * principals it subsumes. So script with an nsExpandedPrincipals will gain
+ * If SystemPrincipal is too risky to use, but we want a principal to access
+ * more than one origin, ExpandedPrincipals letting us define an array of
+ * principals it subsumes. So script with an ExpandedPrincipals will gain
  * same origin access when at least one of its principals it contains gained
- * sameorigin acccess. An nsExpandedPrincipal will be subsumed by the system
- * principal, and by another nsExpandedPrincipal that has all its principals.
+ * sameorigin acccess. An ExpandedPrincipal will be subsumed by the system
+ * principal, and by another ExpandedPrincipal that has all its principals.
  * It is added for jetpack content-scripts to let them interact with the
  * content and a well defined set of other domains, without the risk of
  * leaking out a system principal to the content. See: Bug 734891
  */
 [uuid(f3e177Df-6a5e-489f-80a7-2dd1481471d8)]
 interface nsIExpandedPrincipal : nsISupports
 {
   /**
--- a/caps/nsScriptSecurityManager.cpp
+++ b/caps/nsScriptSecurityManager.cpp
@@ -15,19 +15,18 @@
 #include "nsIServiceManager.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "nsIScriptContext.h"
 #include "nsIURL.h"
 #include "nsINestedURI.h"
 #include "nspr.h"
 #include "nsJSPrincipals.h"
 #include "mozilla/BasePrincipal.h"
-#include "nsSystemPrincipal.h"
-#include "nsPrincipal.h"
-#include "nsNullPrincipal.h"
+#include "SystemPrincipal.h"
+#include "NullPrincipal.h"
 #include "DomainPolicy.h"
 #include "nsXPIDLString.h"
 #include "nsCRT.h"
 #include "nsCRTGlue.h"
 #include "nsDocShell.h"
 #include "nsError.h"
 #include "nsDOMCID.h"
 #include "nsTextFormatter.h"
@@ -1136,17 +1135,17 @@ nsScriptSecurityManager::CreateCodebaseP
 NS_IMETHODIMP
 nsScriptSecurityManager::CreateNullPrincipal(JS::Handle<JS::Value> aOriginAttributes,
                                              JSContext* aCx, nsIPrincipal** aPrincipal)
 {
   OriginAttributes attrs;
   if (!aOriginAttributes.isObject() || !attrs.Init(aCx, aOriginAttributes)) {
       return NS_ERROR_INVALID_ARG;
   }
-  nsCOMPtr<nsIPrincipal> prin = nsNullPrincipal::Create(attrs);
+  nsCOMPtr<nsIPrincipal> prin = NullPrincipal::Create(attrs);
   prin.forget(aPrincipal);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsScriptSecurityManager::GetAppCodebasePrincipal(nsIURI* aURI,
                                                  uint32_t aAppId,
                                                  bool aInIsolatedMozBrowser,
@@ -1330,17 +1329,17 @@ nsresult nsScriptSecurityManager::Init()
         mozilla::services::GetStringBundleService();
     if (!bundleService)
         return NS_ERROR_FAILURE;
 
     rv = bundleService->CreateBundle("chrome://global/locale/security/caps.properties", &sStrBundle);
     NS_ENSURE_SUCCESS(rv, rv);
 
     // Create our system principal singleton
-    RefPtr<nsSystemPrincipal> system = nsSystemPrincipal::Create();
+    RefPtr<SystemPrincipal> system = SystemPrincipal::Create();
 
     mSystemPrincipal = system;
 
     //-- Register security check callback in the JS engine
     //   Currently this is used to control access to function.caller
     sContext = danger::GetJSContext();
 
     static const JSSecurityCallbacks securityCallbacks = {
@@ -1402,23 +1401,23 @@ nsScriptSecurityManager::InitStatics()
 
     ClearOnShutdown(&gScriptSecMan);
     gScriptSecMan = ssManager;
 }
 
 // Currently this nsGenericFactory constructor is used only from FastLoad
 // (XPCOM object deserialization) code, when "creating" the system principal
 // singleton.
-nsSystemPrincipal *
+SystemPrincipal *
 nsScriptSecurityManager::SystemPrincipalSingletonConstructor()
 {
     nsIPrincipal *sysprin = nullptr;
     if (gScriptSecMan)
         NS_ADDREF(sysprin = gScriptSecMan->mSystemPrincipal);
-    return static_cast<nsSystemPrincipal*>(sysprin);
+    return static_cast<SystemPrincipal*>(sysprin);
 }
 
 struct IsWhitespace {
     static bool Test(char aChar) { return NS_IsAsciiWhitespace(aChar); };
 };
 struct IsWhitespaceOrComma {
     static bool Test(char aChar) { return aChar == ',' || NS_IsAsciiWhitespace(aChar); };
 };
--- a/caps/nsScriptSecurityManager.h
+++ b/caps/nsScriptSecurityManager.h
@@ -19,17 +19,17 @@
 #include "plstr.h"
 #include "js/TypeDecls.h"
 
 #include <stdint.h>
 
 class nsCString;
 class nsIIOService;
 class nsIStringBundle;
-class nsSystemPrincipal;
+class SystemPrincipal;
 
 namespace mozilla {
 class OriginAttributes;
 } // namespace mozilla
 
 /////////////////////////////
 // nsScriptSecurityManager //
 /////////////////////////////
@@ -50,17 +50,17 @@ public:
     NS_DECL_NSIOBSERVER
 
     static nsScriptSecurityManager*
     GetScriptSecurityManager();
 
     // Invoked exactly once, by XPConnect.
     static void InitStatics();
 
-    static nsSystemPrincipal*
+    static SystemPrincipal*
     SystemPrincipalSingletonConstructor();
 
     /**
      * Utility method for comparing two URIs.  For security purposes, two URIs
      * are equivalent if their schemes, hosts, and ports (if any) match.  This
      * method returns true if aSubjectURI and aObjectURI have the same origin,
      * false otherwise.
      */
--- a/devtools/client/inspector/boxmodel/components/BoxModelEditable.js
+++ b/devtools/client/inspector/boxmodel/components/BoxModelEditable.js
@@ -11,17 +11,17 @@ const { editableItem } = require("devtoo
 const LONG_TEXT_ROTATE_LIMIT = 3;
 
 module.exports = createClass({
 
   displayName: "BoxModelEditable",
 
   propTypes: {
     box: PropTypes.string.isRequired,
-    direction: PropTypes.string.isRequired,
+    direction: PropTypes.string,
     property: PropTypes.string.isRequired,
     textContent: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
     onShowBoxModelEditor: PropTypes.func.isRequired,
   },
 
   mixins: [ addons.PureRenderMixin ],
 
   componentDidMount() {
@@ -37,23 +37,25 @@ module.exports = createClass({
   render() {
     let {
       box,
       direction,
       property,
       textContent,
     } = this.props;
 
-    let rotate = (direction == "left" || direction == "right") &&
+    let rotate = direction &&
+                 (direction == "left" || direction == "right") &&
                  textContent.toString().length > LONG_TEXT_ROTATE_LIMIT;
 
     return dom.p(
       {
-        className: `boxmodel-${box} boxmodel-${direction}
-          ${rotate ? "boxmodel-rotate" : ""}`,
+        className: `boxmodel-${box}
+                    ${direction ? " boxmodel-" + direction : "boxmodel-" + property}
+                    ${rotate ? " boxmodel-rotate" : ""}`,
       },
       dom.span(
         {
           className: "boxmodel-editable",
           "data-box": box,
           title: property,
           ref: "span",
         },
--- a/devtools/client/inspector/boxmodel/components/BoxModelMain.js
+++ b/devtools/client/inspector/boxmodel/components/BoxModelMain.js
@@ -129,16 +129,51 @@ module.exports = createClass({
     let marginTop = this.getMarginValue("margin-top", "top");
     let marginRight = this.getMarginValue("margin-right", "right");
     let marginBottom = this.getMarginValue("margin-bottom", "bottom");
     let marginLeft = this.getMarginValue("margin-left", "left");
 
     height = this.getHeightValue(height);
     width = this.getWidthValue(width);
 
+    let contentBox = layout["box-sizing"] == "content-box" ?
+      dom.p(
+        {
+          className: "boxmodel-size",
+        },
+        BoxModelEditable({
+          box: "content",
+          property: "width",
+          textContent: width,
+          onShowBoxModelEditor
+        }),
+        dom.span(
+          {},
+          "\u00D7"
+        ),
+        BoxModelEditable({
+          box: "content",
+          property: "height",
+          textContent: height,
+          onShowBoxModelEditor
+        })
+      )
+      :
+      dom.p(
+        {
+          className: "boxmodel-size",
+        },
+        dom.span(
+          {
+            title: BOXMODEL_L10N.getStr("boxmodel.content"),
+          },
+          SHARED_L10N.getFormatStr("dimensions", width, height)
+        )
+      );
+
     return dom.div(
       {
         className: "boxmodel-main",
         onMouseOver: this.onHighlightMouseOver,
         onMouseOut: this.props.onHideBoxModelHighlighter,
       },
       displayPosition ?
         dom.span(
@@ -193,17 +228,17 @@ module.exports = createClass({
             ),
             dom.div(
               {
                 className: "boxmodel-paddings",
                 "data-box": "padding",
                 title: BOXMODEL_L10N.getStr("boxmodel.padding"),
               },
               dom.div({
-                className: "boxmodel-content",
+                className: "boxmodel-contents",
                 "data-box": "content",
                 title: BOXMODEL_L10N.getStr("boxmodel.content"),
               })
             )
           )
         )
       ),
       displayPosition ?
@@ -325,24 +360,13 @@ module.exports = createClass({
       }),
       BoxModelEditable({
         box: "padding",
         direction: "left",
         property: "padding-left",
         textContent: paddingLeft,
         onShowBoxModelEditor,
       }),
-      dom.p(
-        {
-          className: "boxmodel-size",
-        },
-        dom.span(
-          {
-            "data-box": "content",
-            title: BOXMODEL_L10N.getStr("boxmodel.content"),
-          },
-          SHARED_L10N.getFormatStr("dimensions", width, height)
-        )
-      )
+      contentBox
     );
   },
 
 });
--- a/devtools/client/inspector/boxmodel/components/ComputedProperty.js
+++ b/devtools/client/inspector/boxmodel/components/ComputedProperty.js
@@ -23,16 +23,17 @@ module.exports = createClass({
   },
 
   render() {
     const { name, value } = this.props;
 
     return dom.div(
       {
         className: "property-view",
+        "data-property-name": name,
         tabIndex: "0",
         ref: container => {
           this.container = container;
         },
       },
       dom.div(
         {
           className: "property-name-container",
--- a/devtools/client/inspector/boxmodel/test/browser.ini
+++ b/devtools/client/inspector/boxmodel/test/browser.ini
@@ -17,16 +17,17 @@ support-files =
 # [browser_boxmodel_editablemodel_allproperties.js]
 # Disabled for too many intermittent failures (bug 1009322)
 [browser_boxmodel_editablemodel_bluronclick.js]
 [browser_boxmodel_editablemodel_border.js]
 [browser_boxmodel_editablemodel_stylerules.js]
 [browser_boxmodel_guides.js]
 [browser_boxmodel_navigation.js]
 skip-if = true # Bug 1336198
+[browser_boxmodel_properties.js]
 [browser_boxmodel_rotate-labels-on-sides.js]
 [browser_boxmodel_sync.js]
 [browser_boxmodel_tooltips.js]
 skip-if = true # Bug 1336198
 [browser_boxmodel_update-after-navigation.js]
 [browser_boxmodel_update-after-reload.js]
 # [browser_boxmodel_update-in-iframes.js]
 # Bug 1020038 boxmodel-view updates for iframe elements changes
--- a/devtools/client/inspector/boxmodel/test/browser_boxmodel.js
+++ b/devtools/client/inspector/boxmodel/test/browser_boxmodel.js
@@ -9,18 +9,22 @@
 
 // Expected values:
 var res1 = [
   {
     selector: ".boxmodel-element-size",
     value: "160" + "\u00D7" + "160.117"
   },
   {
-    selector: ".boxmodel-size > span",
-    value: "100" + "\u00D7" + "100.117"
+    selector: ".boxmodel-size > .boxmodel-width",
+    value: "100"
+  },
+  {
+    selector: ".boxmodel-size > .boxmodel-height",
+    value: "100.117"
   },
   {
     selector: ".boxmodel-margin.boxmodel-top > span",
     value: 30
   },
   {
     selector: ".boxmodel-margin.boxmodel-left > span",
     value: "auto"
@@ -68,18 +72,22 @@ var res1 = [
 ];
 
 var res2 = [
   {
     selector: ".boxmodel-element-size",
     value: "190" + "\u00D7" + "210"
   },
   {
-    selector: ".boxmodel-size > span",
-    value: "100" + "\u00D7" + "150"
+    selector: ".boxmodel-size > .boxmodel-width",
+    value: "100"
+  },
+  {
+    selector: ".boxmodel-size > .boxmodel-height",
+    value: "150"
   },
   {
     selector: ".boxmodel-margin.boxmodel-top > span",
     value: 30
   },
   {
     selector: ".boxmodel-margin.boxmodel-left > span",
     value: "auto"
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/boxmodel/test/browser_boxmodel_properties.js
@@ -0,0 +1,120 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Test that the box model properties list displays the right values
+// and that it updates when the node's style is changed.
+
+const TEST_URI = `
+  <style type='text/css'>
+    div {
+      box-sizing: border-box;
+      display: block;
+      float: left;
+      line-height: 20px;
+      position: relative;
+      z-index: 2;
+      height: 100px;
+      width: 100px;
+      border: 10px solid black;
+      padding: 20px;
+      margin: 30px auto;
+    }
+  </style>
+  <div>Test Node</div>
+`;
+
+const res1 = [
+  {
+    property: "box-sizing",
+    value: "border-box"
+  },
+  {
+    property: "display",
+    value: "block"
+  },
+  {
+    property: "float",
+    value: "left"
+  },
+  {
+    property: "line-height",
+    value: "20px"
+  },
+  {
+    property: "position",
+    value: "relative"
+  },
+  {
+    property: "z-index",
+    value: 2
+  },
+];
+
+const res2 = [
+  {
+    property: "box-sizing",
+    value: "content-box"
+  },
+  {
+    property: "display",
+    value: "block"
+  },
+  {
+    property: "float",
+    value: "right"
+  },
+  {
+    property: "line-height",
+    value: "10px"
+  },
+  {
+    property: "position",
+    value: "static"
+  },
+  {
+    property: "z-index",
+    value: 5
+  },
+];
+
+add_task(function* () {
+  yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
+  let { inspector, boxmodel, testActor } = yield openLayoutView();
+  yield selectNode("div", inspector);
+
+  yield testInitialValues(inspector, boxmodel);
+  yield testChangingValues(inspector, boxmodel, testActor);
+});
+
+function* testInitialValues(inspector, boxmodel) {
+  info("Test that the initial values of the box model are correct");
+  let doc = boxmodel.document;
+
+  for (let { property, value } of res1) {
+    let elt = doc.querySelector(getPropertySelector(property));
+    is(elt.textContent, value, property + " has the right value.");
+  }
+}
+
+function* testChangingValues(inspector, boxmodel, testActor) {
+  info("Test that changing the document updates the box model");
+  let doc = boxmodel.document;
+
+  let onUpdated = waitForUpdate(inspector);
+  yield testActor.setAttribute("div", "style",
+                               "box-sizing:content-box;float:right;" +
+                               "line-height:10px;position:static;z-index:5;");
+  yield onUpdated;
+
+  for (let { property, value } of res2) {
+    let elt = doc.querySelector(getPropertySelector(property));
+    is(elt.textContent, value, property + " has the right value after style update.");
+  }
+}
+
+function getPropertySelector(propertyName) {
+  return `.boxmodel-properties-wrapper .property-view` +
+  `[data-property-name=${propertyName}] .property-value`;
+}
--- a/devtools/client/inspector/boxmodel/test/doc_boxmodel_iframe2.html
+++ b/devtools/client/inspector/boxmodel/test/doc_boxmodel_iframe2.html
@@ -1,3 +1,3 @@
 <!DOCTYPE html>
-<p style="width:100px;height:100px;background:red;">iframe 1</p>
-<iframe src="data:text/html,<div style='width:400px;height:200px;background:yellow;'>iframe 2</div>"></iframe>
+<p style="width:100px;height:100px;background:red;box-sizing:border-box">iframe 1</p>
+<iframe src="data:text/html,<div style='width:400px;height:200px;background:yellow;box-sizing:border-box'>iframe 2</div>"></iframe>
--- a/devtools/client/inspector/boxmodel/test/head.js
+++ b/devtools/client/inspector/boxmodel/test/head.js
@@ -6,18 +6,20 @@
 /* import-globals-from ../../test/head.js */
 "use strict";
 
 // Import the inspector's head.js first (which itself imports shared-head.js).
 Services.scriptloader.loadSubScript(
   "chrome://mochitests/content/browser/devtools/client/inspector/test/head.js",
   this);
 
+Services.prefs.setBoolPref("devtools.layoutview.enabled", true);
 Services.prefs.setIntPref("devtools.toolbox.footer.height", 350);
 registerCleanupFunction(() => {
+  Services.prefs.clearUserPref("devtools.layoutview.enabled");
   Services.prefs.clearUserPref("devtools.toolbox.footer.height");
 });
 
 /**
  * Highlight a node and set the inspector's current selection to the node or
  * the first match of the given css selector.
  *
  * @param  {String|NodeFront} selectorOrNodeFront
@@ -62,16 +64,46 @@ function openBoxModelView() {
       inspector: data.inspector,
       view: data.inspector.computedview,
       testActor: data.testActor
     };
   });
 }
 
 /**
+ * Open the toolbox, with the inspector tool visible, and the layout view
+ * sidebar tab selected to display the box model view with properties.
+ *
+ * @return {Promise} a promise that resolves when the inspector is ready and the box model
+ *         view is visible and ready.
+ */
+function openLayoutView() {
+  return openInspectorSidebarTab("layoutview").then(data => {
+    // The actual highligher show/hide methods are mocked in box model tests.
+    // The highlighter is tested in devtools/inspector/test.
+    function mockHighlighter({highlighter}) {
+      highlighter.showBoxModel = function () {
+        return promise.resolve();
+      };
+      highlighter.hideBoxModel = function () {
+        return promise.resolve();
+      };
+    }
+    mockHighlighter(data.toolbox);
+
+    return {
+      toolbox: data.toolbox,
+      inspector: data.inspector,
+      boxmodel: data.inspector.boxmodel,
+      testActor: data.testActor
+    };
+  });
+}
+
+/**
  * Wait for the boxmodel-view-updated event.
  *
  * @param  {InspectorPanel} inspector
  *         The instance of InspectorPanel currently loaded in the toolbox.
  * @param  {Boolean} waitForSelectionUpdate
  *         Should the boxmodel-view-updated event come from a new selection.
  * @return {Promise} a promise
  */
--- a/devtools/client/inspector/inspector.js
+++ b/devtools/client/inspector/inspector.js
@@ -921,20 +921,28 @@ Inspector.prototype = {
     this.target.off("thread-paused", this.updateDebuggerPausedWarning);
     this.target.off("thread-resumed", this.updateDebuggerPausedWarning);
     this._toolbox.off("select", this.updateDebuggerPausedWarning);
 
     if (this.ruleview) {
       this.ruleview.destroy();
     }
 
+    if (this.boxmodel) {
+      this.boxmodel.destroy();
+    }
+
     if (this.computedview) {
       this.computedview.destroy();
     }
 
+    if (this.gridInspector) {
+      this.gridInspector.destroy();
+    }
+
     if (this.layoutview) {
       this.layoutview.destroy();
     }
 
     if (this.fontInspector) {
       this.fontInspector.destroy();
     }
 
--- a/devtools/client/jsonview/main.js
+++ b/devtools/client/jsonview/main.js
@@ -45,17 +45,17 @@ var JsonView = {
 
   // Message handlers for events from child processes
 
   /**
    * Save JSON to a file needs to be implemented here
    * in the parent process.
    */
   onSave: function (message) {
-    JsonViewUtils.getTargetFile(file => {
+    JsonViewUtils.getTargetFile().then(file => {
       if (file) {
         JsonViewUtils.saveToFile(file, message.data);
       }
     });
   }
 };
 
 // Exports from this module
--- a/devtools/client/themes/boxmodel.css
+++ b/devtools/client/themes/boxmodel.css
@@ -47,17 +47,17 @@
 
 .boxmodel-margin,
 .boxmodel-size {
   color: var(--theme-highlight-blue);
 }
 
 /* Regions are 3 nested elements with wide borders and outlines */
 
-.boxmodel-content {
+.boxmodel-contents {
   height: 18px;
 }
 
 .boxmodel-margins,
 .boxmodel-borders,
 .boxmodel-paddings {
   border-color: hsla(210,100%,85%,0.2);
   border-width: 18px;
@@ -79,17 +79,17 @@
 .boxmodel-borders {
   border-color: #444444;
 }
 
 .boxmodel-paddings {
   border-color: #6a5acd;
 }
 
-.boxmodel-content {
+.boxmodel-contents {
   background-color: #87ceeb;
 }
 
 .theme-firebug .boxmodel-main,
 .theme-firebug .boxmodel-header {
   font-family: var(--proportional-font-family);
 }
 
@@ -99,25 +99,27 @@
 }
 
 .theme-firebug .boxmodel-header {
   font-size: var(--theme-toolbar-font-size);
 }
 
 /* Editable region sizes are contained in absolutely positioned <p> */
 
-.boxmodel-main > p {
+.boxmodel-main > p,
+.boxmodel-size {
   position: absolute;
   pointer-events: none;
   margin: 0;
   text-align: center;
 }
 
 .boxmodel-main > p > span,
-.boxmodel-main > p > input {
+.boxmodel-main > p > input,
+.boxmodel-content {
   vertical-align: middle;
   pointer-events: auto;
 }
 
 /* Coordinates for the region sizes */
 
 .boxmodel-top,
 .boxmodel-bottom {
@@ -167,18 +169,18 @@
 }
 
 .boxmodel-position.boxmodel-top,
 .boxmodel-position.boxmodel-bottom,
 .boxmodel-position.boxmodel-left,
 .boxmodel-position.boxmodel-right,
 .boxmodel-margin.boxmodel-right,
 .boxmodel-margin.boxmodel-left,
+.boxmodel-border.boxmodel-right,
 .boxmodel-border.boxmodel-left,
-.boxmodel-border.boxmodel-right,
 .boxmodel-padding.boxmodel-right,
 .boxmodel-padding.boxmodel-left {
   width: 21px;
 }
 
 .boxmodel-padding.boxmodel-left {
   left: 60px;
 }
@@ -213,16 +215,22 @@
 
 .boxmodel-rotate.boxmodel-left.boxmodel-position:not(.boxmodel-editing) {
   border-top: none;
   border-right: 1px solid var(--theme-highlight-purple);
   width: auto;
   height: 30px;
 }
 
+.boxmodel-size > p {
+  display: inline-block;
+  margin: auto;
+  line-height: 0;
+}
+
 .boxmodel-rotate.boxmodel-right.boxmodel-position:not(.boxmodel-editing) {
   border-top: none;
   border-left: 1px solid var(--theme-highlight-purple);
   width: auto;
   height: 30px;
 }
 
 /* Box Model Positioning: contains top, right, bottom, left */
@@ -285,18 +293,16 @@
   border: 1px dashed transparent;
   -moz-user-select: none;
 }
 
 .boxmodel-editable:hover {
   border-bottom-color: hsl(0, 0%, 50%);
 }
 
-/* Make sure the content size doesn't appear as editable like the other sizes */
-
 .boxmodel-size > span {
   cursor: default;
 }
 
 /* Box Model Info: contains the position and size of the element */
 
 .boxmodel-element-size {
   flex: 1;
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -115,17 +115,17 @@
 #include "nsIFormPOSTActionChannel.h"
 #include "nsIUploadChannel.h"
 #include "nsIUploadChannel2.h"
 #include "nsIWebProgress.h"
 #include "nsILayoutHistoryState.h"
 #include "nsITimer.h"
 #include "nsISHistoryInternal.h"
 #include "nsIPrincipal.h"
-#include "nsNullPrincipal.h"
+#include "NullPrincipal.h"
 #include "nsISHEntry.h"
 #include "nsIWindowWatcher.h"
 #include "nsIPromptFactory.h"
 #include "nsITransportSecurityInfo.h"
 #include "nsINode.h"
 #include "nsINSSErrorsService.h"
 #include "nsIApplicationCacheChannel.h"
 #include "nsIApplicationCacheContainer.h"
@@ -1496,30 +1496,30 @@ nsDocShell::LoadURI(nsIURI* aURI,
       if (principalIsExplicit) {
         return NS_ERROR_DOM_SECURITY_ERR;
       }
       // Don't inherit from the current page.  Just do the safe thing
       // and pretend that we were loaded by a nullprincipal.
       //
       // We didn't inherit OriginAttributes here as ExpandedPrincipal doesn't
       // have origin attributes.
-      principalToInherit = nsNullPrincipal::CreateWithInheritedAttributes(this);
+      principalToInherit = NullPrincipal::CreateWithInheritedAttributes(this);
       inheritPrincipal = false;
     }
   }
   if (!principalToInherit && !inheritPrincipal && !principalIsExplicit) {
     // See if there's system or chrome JS code running
     inheritPrincipal = nsContentUtils::LegacyIsCallerChromeOrNativeCode();
   }
 
   if (aLoadFlags & LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL) {
     inheritPrincipal = false;
     // If aFirstParty is true and the pref 'privacy.firstparty.isolate' is
     // enabled, we will set firstPartyDomain on the origin attributes.
-    principalToInherit = nsNullPrincipal::CreateWithInheritedAttributes(this, aFirstParty);
+    principalToInherit = NullPrincipal::CreateWithInheritedAttributes(this, aFirstParty);
   }
 
   // If the triggeringPrincipal is not passed explicitly, we first try to create
   // a principal from the referrer, since the referrer URI reflects the web origin
   // that triggered the load. If there is no referrer URI, we fall back to using
   // the SystemPrincipal. It's safe to assume that no provided triggeringPrincipal
   // and no referrer simulate a load that was triggered by the system.
   // It's important to note that this block of code needs to appear *after* the block
@@ -8122,19 +8122,19 @@ nsDocShell::CreateAboutBlankContentViewe
 
   nsCOMPtr<nsIDocumentLoaderFactory> docFactory =
     nsContentUtils::FindInternalContentViewer(NS_LITERAL_CSTRING("text/html"));
 
   if (docFactory) {
     nsCOMPtr<nsIPrincipal> principal;
     if (mSandboxFlags & SANDBOXED_ORIGIN) {
       if (aPrincipal) {
-        principal = nsNullPrincipal::CreateWithInheritedAttributes(aPrincipal);
+        principal = NullPrincipal::CreateWithInheritedAttributes(aPrincipal);
       } else {
-        principal = nsNullPrincipal::CreateWithInheritedAttributes(this);
+        principal = NullPrincipal::CreateWithInheritedAttributes(this);
       }
     } else {
       principal = aPrincipal;
     }
     // generate (about:blank) document to load
     docFactory->CreateBlankDocument(mLoadGroup, principal,
                                     getter_AddRefs(blankDoc));
     if (blankDoc) {
@@ -12404,23 +12404,23 @@ nsDocShell::AddToSessionHistory(nsIURI* 
       if (!triggeringPrincipal) {
         triggeringPrincipal = loadInfo->TriggeringPrincipal();
       }
 
       // For now keep storing just the principal in the SHEntry.
       if (!principalToInherit) {
         if (loadInfo->GetLoadingSandboxed()) {
           if (loadInfo->LoadingPrincipal()) {
-            principalToInherit = nsNullPrincipal::CreateWithInheritedAttributes(
+            principalToInherit = NullPrincipal::CreateWithInheritedAttributes(
             loadInfo->LoadingPrincipal());
           } else {
             // get the OriginAttributes
             OriginAttributes attrs;
             loadInfo->GetOriginAttributes(&attrs);
-            principalToInherit = nsNullPrincipal::Create(attrs);
+            principalToInherit = NullPrincipal::Create(attrs);
           }
         } else {
           principalToInherit = loadInfo->PrincipalToInherit();
         }
       }
     }
   }
 
@@ -12601,17 +12601,17 @@ nsDocShell::LoadHistoryEntry(nsISHEntry*
       // user prevented it). Interrupt the history load.
       return NS_OK;
     }
 
     if (!triggeringPrincipal) {
       // Ensure that we have a triggeringPrincipal.  Otherwise javascript:
       // URIs will pick it up from the about:blank page we just loaded,
       // and we don't really want even that in this case.
-      triggeringPrincipal = nsNullPrincipal::CreateWithInheritedAttributes(this);
+      triggeringPrincipal = NullPrincipal::CreateWithInheritedAttributes(this);
     }
   }
 
   /* If there is a valid postdata *and* the user pressed
    * reload or shift-reload, take user's permission before we
    * repost the data to the server.
    */
   if ((aLoadType & LOAD_CMD_RELOAD) && postData) {
@@ -14373,17 +14373,17 @@ nsDocShell::GetPrintPreview(nsIWebBrowse
 #if NS_PRINT_PREVIEW
   nsCOMPtr<nsIDocumentViewerPrint> print = do_QueryInterface(mContentViewer);
   if (!print || !print->IsInitializedForPrintPreview()) {
     // XXX: Creating a brand new content viewer to host preview every
     // time we enter here seems overwork. We could skip ahead to where
     // we QI the mContentViewer if the current URI is either about:blank
     // or about:printpreview.
     Stop(nsIWebNavigation::STOP_ALL);
-    nsCOMPtr<nsIPrincipal> principal = nsNullPrincipal::CreateWithInheritedAttributes(this);
+    nsCOMPtr<nsIPrincipal> principal = NullPrincipal::CreateWithInheritedAttributes(this);
     nsCOMPtr<nsIURI> uri;
     NS_NewURI(getter_AddRefs(uri), NS_LITERAL_CSTRING("about:printpreview"));
     nsresult rv = CreateAboutBlankContentViewer(principal, uri);
     NS_ENSURE_SUCCESS(rv, rv);
     // Here we manually set current URI since we have just created a
     // brand new content viewer (about:blank) to host preview.
     SetCurrentURI(uri, nullptr, true, 0);
     print = do_QueryInterface(mContentViewer);
--- a/dom/asmjscache/AsmJSCache.cpp
+++ b/dom/asmjscache/AsmJSCache.cpp
@@ -1618,28 +1618,34 @@ public:
   {
     return ASMJS;
   }
 
   nsresult
   InitOrigin(PersistenceType aPersistenceType,
              const nsACString& aGroup,
              const nsACString& aOrigin,
+             const AtomicBool& aCanceled,
              UsageInfo* aUsageInfo) override
   {
     if (!aUsageInfo) {
       return NS_OK;
     }
-    return GetUsageForOrigin(aPersistenceType, aGroup, aOrigin, aUsageInfo);
+    return GetUsageForOrigin(aPersistenceType,
+                             aGroup,
+                             aOrigin,
+                             aCanceled,
+                             aUsageInfo);
   }
 
   nsresult
   GetUsageForOrigin(PersistenceType aPersistenceType,
                     const nsACString& aGroup,
                     const nsACString& aOrigin,
+                    const AtomicBool& aCanceled,
                     UsageInfo* aUsageInfo) override
   {
     QuotaManager* qm = QuotaManager::Get();
     MOZ_ASSERT(qm, "We were being called by the QuotaManager");
 
     nsCOMPtr<nsIFile> directory;
     nsresult rv = qm->GetDirectoryForOrigin(aPersistenceType, aOrigin,
                                             getter_AddRefs(directory));
@@ -1653,17 +1659,17 @@ public:
     MOZ_ASSERT(NS_SUCCEEDED(directory->Exists(&exists)) && exists);
 
     nsCOMPtr<nsISimpleEnumerator> entries;
     rv = directory->GetDirectoryEntries(getter_AddRefs(entries));
     NS_ENSURE_SUCCESS(rv, rv);
 
     bool hasMore;
     while (NS_SUCCEEDED((rv = entries->HasMoreElements(&hasMore))) &&
-           hasMore && !aUsageInfo->Canceled()) {
+           hasMore && !aCanceled) {
       nsCOMPtr<nsISupports> entry;
       rv = entries->GetNext(getter_AddRefs(entry));
       NS_ENSURE_SUCCESS(rv, rv);
 
       nsCOMPtr<nsIFile> file = do_QueryInterface(entry);
       NS_ENSURE_TRUE(file, NS_NOINTERFACE);
 
       int64_t fileSize;
--- a/dom/base/DOMParser.cpp
+++ b/dom/base/DOMParser.cpp
@@ -13,17 +13,17 @@
 #include "nsIScriptError.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsCRT.h"
 #include "nsStreamUtils.h"
 #include "nsContentUtils.h"
 #include "nsDOMJSUtils.h"
 #include "nsError.h"
 #include "nsPIDOMWindow.h"
-#include "nsNullPrincipal.h"
+#include "NullPrincipal.h"
 #include "mozilla/LoadInfo.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/ScriptSettings.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 DOMParser::DOMParser()
@@ -340,17 +340,17 @@ DOMParser::Init(nsIPrincipal* principal,
     OriginAttributes attrs;
     mPrincipal = BasePrincipal::CreateCodebasePrincipal(mDocumentURI, attrs);
     NS_ENSURE_TRUE(mPrincipal, NS_ERROR_FAILURE);
   } else {
     if (nsContentUtils::IsSystemPrincipal(mPrincipal)) {
       // Don't give DOMParsers the system principal.  Use a null
       // principal instead.
       mOriginalPrincipalWasSystem = true;
-      mPrincipal = nsNullPrincipal::Create();
+      mPrincipal = NullPrincipal::Create();
 
       if (!mDocumentURI) {
         rv = mPrincipal->GetURI(getter_AddRefs(mDocumentURI));
         NS_ENSURE_SUCCESS(rv, rv);
       }
     }
   }
 
@@ -451,17 +451,17 @@ DOMParser::SetUpDocument(DocumentFlavor 
   // off of nsIScriptGlobalObject, but that's a yak to shave another day.
   nsCOMPtr<nsIScriptGlobalObject> scriptHandlingObject =
     do_QueryReferent(mScriptHandlingObject);
   nsresult rv;
   if (!mPrincipal) {
     NS_ENSURE_TRUE(!mAttemptedInit, NS_ERROR_NOT_INITIALIZED);
     AttemptedInitMarker marker(&mAttemptedInit);
 
-    nsCOMPtr<nsIPrincipal> prin = nsNullPrincipal::Create();
+    nsCOMPtr<nsIPrincipal> prin = NullPrincipal::Create();
     rv = Init(prin, nullptr, nullptr, scriptHandlingObject);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   NS_ASSERTION(mPrincipal, "Must have principal by now");
   NS_ASSERTION(mDocumentURI, "Must have document URI by now");
 
   return NS_NewDOMDocument(aResult, EmptyString(), EmptyString(), nullptr,
--- a/dom/base/Location.cpp
+++ b/dom/base/Location.cpp
@@ -26,17 +26,17 @@
 #include "nsDOMClassInfoID.h"
 #include "nsReadableUtils.h"
 #include "nsITextToSubURI.h"
 #include "nsJSUtils.h"
 #include "nsContentUtils.h"
 #include "nsGlobalWindow.h"
 #include "mozilla/Likely.h"
 #include "nsCycleCollectionParticipant.h"
-#include "nsNullPrincipal.h"
+#include "NullPrincipal.h"
 #include "ScriptSettings.h"
 #include "mozilla/Unused.h"
 #include "mozilla/dom/LocationBinding.h"
 
 namespace mozilla {
 namespace dom {
 
 static nsresult
@@ -159,17 +159,17 @@ Location::CheckURL(nsIURI* aURI, nsIDocS
       bool urisEqual = false;
       if (docOriginalURI && docCurrentURI && principalURI) {
         principalURI->Equals(docOriginalURI, &urisEqual);
       }
       if (urisEqual) {
         sourceURI = docCurrentURI;
       }
       else {
-        // Use principalURI as long as it is not an nsNullPrincipalURI.  We
+        // Use principalURI as long as it is not an NullPrincipalURI.  We
         // could add a method such as GetReferrerURI to principals to make this
         // cleaner, but given that we need to start using Source Browsing
         // Context for referrer (see Bug 960639) this may be wasted effort at
         // this stage.
         if (principalURI) {
           bool isNullPrincipalScheme;
           rv = principalURI->SchemeIs(NS_NULLPRINCIPAL_SCHEME,
                                      &isNullPrincipalScheme);
--- a/dom/base/ScriptSettings.cpp
+++ b/dom/base/ScriptSettings.cpp
@@ -159,17 +159,17 @@ ScriptSettingsStackEntry::~ScriptSetting
 {
   // We must have an actual JS global for the entire time this is on the stack.
   MOZ_ASSERT_IF(mGlobalObject, mGlobalObject->GetGlobalJSObject());
 }
 
 // If the entry or incumbent global ends up being something that the subject
 // principal doesn't subsume, we don't want to use it. This never happens on
 // the web, but can happen with asymmetric privilege relationships (i.e.
-// nsExpandedPrincipal and System Principal).
+// ExpandedPrincipal and System Principal).
 //
 // The most correct thing to use instead would be the topmost global on the
 // callstack whose principal is subsumed by the subject principal. But that's
 // hard to compute, so we just substitute the global of the current
 // compartment. In practice, this is fine.
 //
 // Note that in particular things like:
 //
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -177,17 +177,17 @@
 #include "nsIWindowMediator.h"
 #include "nsIWordBreaker.h"
 #include "nsIXPConnect.h"
 #include "nsJSUtils.h"
 #include "nsLWBrkCIID.h"
 #include "nsNetCID.h"
 #include "nsNetUtil.h"
 #include "nsNodeInfoManager.h"
-#include "nsNullPrincipal.h"
+#include "NullPrincipal.h"
 #include "nsParserCIID.h"
 #include "nsParserConstants.h"
 #include "nsPIDOMWindow.h"
 #include "nsPresContext.h"
 #include "nsPrintfCString.h"
 #include "nsReferencedElement.h"
 #include "nsSandboxFlags.h"
 #include "nsScriptSecurityManager.h"
@@ -509,17 +509,17 @@ nsContentUtils::Init()
   sSecurityManager = nsScriptSecurityManager::GetScriptSecurityManager();
   if(!sSecurityManager)
     return NS_ERROR_FAILURE;
   NS_ADDREF(sSecurityManager);
 
   sSecurityManager->GetSystemPrincipal(&sSystemPrincipal);
   MOZ_ASSERT(sSystemPrincipal);
 
-  RefPtr<nsNullPrincipal> nullPrincipal = nsNullPrincipal::Create();
+  RefPtr<NullPrincipal> nullPrincipal = NullPrincipal::Create();
   if (!nullPrincipal) {
     return NS_ERROR_FAILURE;
   }
 
   nullPrincipal.forget(&sNullSubjectPrincipal);
 
   nsresult rv = CallGetService(NS_IOSERVICE_CONTRACTID, &sIOService);
   if (NS_FAILED(rv)) {
@@ -4785,17 +4785,17 @@ nsContentUtils::ParseFragmentXML(const n
 nsresult
 nsContentUtils::ConvertToPlainText(const nsAString& aSourceBuffer,
                                    nsAString& aResultBuffer,
                                    uint32_t aFlags,
                                    uint32_t aWrapCol)
 {
   nsCOMPtr<nsIURI> uri;
   NS_NewURI(getter_AddRefs(uri), "about:blank");
-  nsCOMPtr<nsIPrincipal> principal = nsNullPrincipal::Create();
+  nsCOMPtr<nsIPrincipal> principal = NullPrincipal::Create();
   nsCOMPtr<nsIDOMDocument> domDocument;
   nsresult rv = NS_NewDOMDocument(getter_AddRefs(domDocument),
                                   EmptyString(),
                                   EmptyString(),
                                   nullptr,
                                   uri,
                                   uri,
                                   principal,
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -1573,22 +1573,22 @@ public:
   static void NotifyInstalledMenuKeyboardListener(bool aInstalling);
 
   /**
    * Returns true if aPrincipal is the system principal.
    */
   static bool IsSystemPrincipal(nsIPrincipal* aPrincipal);
 
   /**
-   * Returns true if aPrincipal is an nsExpandedPrincipal.
+   * Returns true if aPrincipal is an ExpandedPrincipal.
    */
   static bool IsExpandedPrincipal(nsIPrincipal* aPrincipal);
 
   /**
-   * Returns true if aPrincipal is the system or an nsExpandedPrincipal.
+   * Returns true if aPrincipal is the system or an ExpandedPrincipal.
    */
   static bool IsSystemOrExpandedPrincipal(nsIPrincipal* aPrincipal)
   {
     return IsSystemPrincipal(aPrincipal) || IsExpandedPrincipal(aPrincipal);
   }
 
   /**
    * Gets the system principal from the security manager.
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -101,17 +101,17 @@
 #include "nsNetUtil.h"     // for NS_NewURI
 #include "nsIInputStreamChannel.h"
 #include "nsIAuthPrompt.h"
 #include "nsIAuthPrompt2.h"
 
 #include "nsIScriptSecurityManager.h"
 #include "nsIPermissionManager.h"
 #include "nsIPrincipal.h"
-#include "nsNullPrincipal.h"
+#include "NullPrincipal.h"
 
 #include "nsIDOMWindow.h"
 #include "nsPIDOMWindow.h"
 #include "nsIDOMElement.h"
 #include "nsFocusManager.h"
 
 // for radio group stuff
 #include "nsIDOMHTMLInputElement.h"
@@ -2712,17 +2712,17 @@ nsDocument::InitCSP(nsIChannel* aChannel
   rv = csp->GetCSPSandboxFlags(&cspSandboxFlags);
   NS_ENSURE_SUCCESS(rv, rv);
 
   mSandboxFlags |= cspSandboxFlags;
 
   if (cspSandboxFlags & SANDBOXED_ORIGIN) {
     // If the new CSP sandbox flags do not have the allow-same-origin flag
     // reset the document principal to a null principal
-    principal = nsNullPrincipal::Create();
+    principal = NullPrincipal::Create();
     SetPrincipal(principal);
   }
 
   // ----- Enforce frame-ancestor policy on any applied policies
   nsCOMPtr<nsIDocShell> docShell(mDocumentContainer);
   if (docShell) {
     bool safeAncestry = false;
 
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -45,17 +45,17 @@
 #include "nsError.h"
 #include "nsISHistory.h"
 #include "nsISHistoryInternal.h"
 #include "nsIDOMHTMLDocument.h"
 #include "nsIXULWindow.h"
 #include "nsIEditor.h"
 #include "nsIMozBrowserFrame.h"
 #include "nsISHistory.h"
-#include "nsNullPrincipal.h"
+#include "NullPrincipal.h"
 #include "nsIScriptError.h"
 #include "nsGlobalWindow.h"
 #include "nsPIWindowRoot.h"
 #include "nsLayoutUtils.h"
 #include "nsView.h"
 #include "GroupedSHistory.h"
 #include "PartialSHistory.h"
 
@@ -93,17 +93,17 @@
 #include "mozilla/dom/CustomEvent.h"
 
 #include "mozilla/dom/ipc/StructuredCloneData.h"
 #include "mozilla/WebBrowserPersistLocalDocument.h"
 #include "mozilla/dom/GroupedHistoryEvent.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/PromiseNativeHandler.h"
 
-#include "nsPrincipal.h"
+#include "ContentPrincipal.h"
 
 #ifdef XP_WIN
 #include "mozilla/plugins/PPluginWidgetParent.h"
 #include "../plugins/ipc/PluginWidgetParent.h"
 #endif
 
 #ifdef MOZ_XUL
 #include "nsXULPopupManager.h"
@@ -826,17 +826,17 @@ nsFrameLoader::ReallyStartLoadingInterna
     nsCOMPtr<nsIURI> baseURI = mOwnerContent->GetBaseURI();
     loadInfo->SetBaseURI(baseURI);
   }
   else {
     rv = mOwnerContent->NodePrincipal()->GetURI(getter_AddRefs(referrer));
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
-  // Use referrer as long as it is not an nsNullPrincipalURI.
+  // Use referrer as long as it is not an NullPrincipalURI.
   // We could add a method such as GetReferrerURI to principals to make this
   // cleaner, but given that we need to start using Source Browsing Context for
   // referrer (see Bug 960639) this may be wasted effort at this stage.
   if (referrer) {
     bool isNullPrincipalScheme;
     rv = referrer->SchemeIs(NS_NULLPRINCIPAL_SCHEME, &isNullPrincipalScheme);
     if (NS_SUCCEEDED(rv) && !isNullPrincipalScheme) {
       loadInfo->SetReferrer(referrer);
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -13072,19 +13072,24 @@ nsGlobalWindow::RunTimeoutHandler(Timeou
       handler->GetLocation(&filename, &lineNo, &dummyColumn);
 
       // New script entry point required, due to the "Create a script" sub-step of
       // http://www.whatwg.org/specs/web-apps/current-work/#timer-initialisation-steps
       nsAutoMicroTask mt;
       AutoEntryScript aes(this, reason, true);
       JS::CompileOptions options(aes.cx());
       options.setFileAndLine(filename, lineNo).setVersion(JSVERSION_DEFAULT);
+      options.setNoScriptRval(true);
       JS::Rooted<JSObject*> global(aes.cx(), FastGetGlobalJSObject());
-      nsresult rv =
-        nsJSUtils::EvaluateString(aes.cx(), script, global, options);
+      nsresult rv = NS_OK;
+      {
+        nsJSUtils::ExecutionContext exec(aes.cx(), global);
+        rv = exec.CompileAndExec(options, script);
+      }
+
       if (rv == NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW_UNCATCHABLE) {
         abortIntervalHandler = true;
       }
     } else {
       // Hold strong ref to ourselves while we call the callback.
       nsCOMPtr<nsISupports> me(static_cast<nsIDOMWindow*>(this));
       ErrorResult rv;
       JS::Rooted<JS::Value> ignoredVal(RootingCx());
--- a/dom/base/nsJSUtils.cpp
+++ b/dom/base/nsJSUtils.cpp
@@ -118,166 +118,172 @@ nsJSUtils::CompileFunction(AutoJSAPI& js
   {
     return NS_ERROR_FAILURE;
   }
 
   *aFunctionObject = JS_GetFunctionObject(fun);
   return NS_OK;
 }
 
-nsresult
-nsJSUtils::EvaluateString(JSContext* aCx,
-                          const nsAString& aScript,
-                          JS::Handle<JSObject*> aEvaluationGlobal,
-                          JS::CompileOptions& aCompileOptions,
-                          const EvaluateOptions& aEvaluateOptions,
-                          JS::MutableHandle<JS::Value> aRetValue)
+static nsresult
+EvaluationExceptionToNSResult(JSContext* aCx)
+{
+  if (JS_IsExceptionPending(aCx)) {
+    return NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW;
+  }
+  return NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW_UNCATCHABLE;
+}
+
+nsJSUtils::ExecutionContext::ExecutionContext(JSContext* aCx,
+                                              JS::Handle<JSObject*> aGlobal)
+  : mSamplerRAII("nsJSUtils::ExecutionContext", /* PROFILER_LABEL */
+                 js::ProfileEntry::Category::JS, __LINE__)
+  , mCx(aCx)
+  , mCompartment(aCx, aGlobal)
+  , mRetValue(aCx)
+  , mScopeChain(aCx)
+  , mRv(NS_OK)
+  , mSkip(false)
+  , mCoerceToString(false)
+#ifdef DEBUG
+  , mWantsReturnValue(false)
+  , mExpectScopeChain(false)
+#endif
 {
-  const nsPromiseFlatString& flatScript = PromiseFlatString(aScript);
-  JS::SourceBufferHolder srcBuf(flatScript.get(), aScript.Length(),
-                                JS::SourceBufferHolder::NoOwnership);
-  return EvaluateString(aCx, srcBuf, aEvaluationGlobal, aCompileOptions,
-                        aEvaluateOptions, aRetValue, nullptr);
+  MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
+  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(nsContentUtils::IsInMicroTask());
+  MOZ_ASSERT(mRetValue.isUndefined());
+
+  MOZ_ASSERT(js::GetGlobalForObjectCrossCompartment(aGlobal) == aGlobal);
+  if (MOZ_UNLIKELY(!xpc::Scriptability::Get(aGlobal).Allowed())) {
+    mSkip = true;
+    mRv = NS_OK;
+  }
+}
+
+void
+nsJSUtils::ExecutionContext::SetScopeChain(
+  const JS::AutoObjectVector& aScopeChain)
+{
+  if (mSkip) {
+    return;
+  }
+
+#ifdef DEBUG
+  mExpectScopeChain = true;
+#endif
+  // Now make sure to wrap the scope chain into the right compartment.
+  if (!mScopeChain.reserve(aScopeChain.length())) {
+    mSkip = true;
+    mRv = NS_ERROR_OUT_OF_MEMORY;
+    return;
+  }
+
+  for (size_t i = 0; i < aScopeChain.length(); ++i) {
+    JS::ExposeObjectToActiveJS(aScopeChain[i]);
+    mScopeChain.infallibleAppend(aScopeChain[i]);
+    if (!JS_WrapObject(mCx, mScopeChain[i])) {
+      mSkip = true;
+      mRv = NS_ERROR_OUT_OF_MEMORY;
+      return;
+    }
+  }
 }
 
 nsresult
-nsJSUtils::EvaluateString(JSContext* aCx,
-                          JS::SourceBufferHolder& aSrcBuf,
-                          JS::Handle<JSObject*> aEvaluationGlobal,
-                          JS::CompileOptions& aCompileOptions,
-                          const EvaluateOptions& aEvaluateOptions,
-                          JS::MutableHandle<JS::Value> aRetValue,
-                          void **aOffThreadToken)
+nsJSUtils::ExecutionContext::SyncAndExec(void **aOffThreadToken,
+                                         JS::MutableHandle<JSScript*> aScript)
 {
-  PROFILER_LABEL("nsJSUtils", "EvaluateString",
-    js::ProfileEntry::Category::JS);
+  if (mSkip) {
+    return mRv;
+  }
+
+  MOZ_ASSERT(!mWantsReturnValue);
+  MOZ_ASSERT(!mExpectScopeChain);
+  aScript.set(JS::FinishOffThreadScript(mCx, *aOffThreadToken));
+  *aOffThreadToken = nullptr; // Mark the token as having been finished.
+  if (!aScript || !JS_ExecuteScript(mCx, mScopeChain, aScript)) {
+    mSkip = true;
+    mRv = EvaluationExceptionToNSResult(mCx);
+    return mRv;
+  }
+
+  return NS_OK;
+}
+
+nsresult
+nsJSUtils::ExecutionContext::CompileAndExec(JS::CompileOptions& aCompileOptions,
+                                            JS::SourceBufferHolder& aSrcBuf)
+{
+  if (mSkip) {
+    return mRv;
+  }
 
   MOZ_ASSERT_IF(aCompileOptions.versionSet,
                 aCompileOptions.version != JSVERSION_UNKNOWN);
-  MOZ_ASSERT_IF(aEvaluateOptions.coerceToString, !aCompileOptions.noScriptRval);
-  MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
   MOZ_ASSERT(aSrcBuf.get());
-  MOZ_ASSERT(js::GetGlobalForObjectCrossCompartment(aEvaluationGlobal) ==
-             aEvaluationGlobal);
-  MOZ_ASSERT_IF(aOffThreadToken, aCompileOptions.noScriptRval);
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(nsContentUtils::IsInMicroTask());
-
-  // Unfortunately, the JS engine actually compiles scripts with a return value
-  // in a different, less efficient way.  Furthermore, it can't JIT them in many
-  // cases.  So we need to be explicitly told whether the caller cares about the
-  // return value.  Callers can do this by calling the other overload of
-  // EvaluateString() which calls this function with
-  // aCompileOptions.noScriptRval set to true.
-  aRetValue.setUndefined();
-
-  nsresult rv = NS_OK;
-
-  NS_ENSURE_TRUE(xpc::Scriptability::Get(aEvaluationGlobal).Allowed(), NS_OK);
-
-  bool ok = true;
-  // Scope the JSAutoCompartment so that we can later wrap the return value
-  // into the caller's cx.
-  {
-    JSAutoCompartment ac(aCx, aEvaluationGlobal);
-
-    // Now make sure to wrap the scope chain into the right compartment.
-    JS::AutoObjectVector scopeChain(aCx);
-    if (!scopeChain.reserve(aEvaluateOptions.scopeChain.length())) {
-      return NS_ERROR_OUT_OF_MEMORY;
-    }
-
-    for (size_t i = 0; i < aEvaluateOptions.scopeChain.length(); ++i) {
-      JS::ExposeObjectToActiveJS(aEvaluateOptions.scopeChain[i]);
-      scopeChain.infallibleAppend(aEvaluateOptions.scopeChain[i]);
-      if (!JS_WrapObject(aCx, scopeChain[i])) {
-        ok = false;
-        break;
-      }
-    }
-
-    if (ok && aOffThreadToken) {
-      JS::Rooted<JSScript*>
-        script(aCx, JS::FinishOffThreadScript(aCx, *aOffThreadToken));
-      *aOffThreadToken = nullptr; // Mark the token as having been finished.
-      if (script) {
-        ok = JS_ExecuteScript(aCx, scopeChain, script);
-      } else {
-        ok = false;
-      }
-    } else if (ok) {
-      ok = JS::Evaluate(aCx, scopeChain, aCompileOptions, aSrcBuf, aRetValue);
-    }
-
-    if (ok && aEvaluateOptions.coerceToString && !aRetValue.isUndefined()) {
-      JS::Rooted<JS::Value> value(aCx, aRetValue);
-      JSString* str = JS::ToString(aCx, value);
-      ok = !!str;
-      aRetValue.set(ok ? JS::StringValue(str) : JS::UndefinedValue());
-    }
+  MOZ_ASSERT(mRetValue.isUndefined());
+#ifdef DEBUG
+  mWantsReturnValue = !aCompileOptions.noScriptRval;
+#endif
+  MOZ_ASSERT(!mCoerceToString || mWantsReturnValue);
+  if (!JS::Evaluate(mCx, mScopeChain, aCompileOptions, aSrcBuf, &mRetValue)) {
+    mSkip = true;
+    mRv = EvaluationExceptionToNSResult(mCx);
+    return mRv;
   }
 
-  if (!ok) {
-    if (JS_IsExceptionPending(aCx)) {
-      rv = NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW;
-    } else {
-      rv = NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW_UNCATCHABLE;
-    }
+  return NS_OK;
+}
 
-    if (!aCompileOptions.noScriptRval) {
-      aRetValue.setUndefined();
-    }
+nsresult
+nsJSUtils::ExecutionContext::CompileAndExec(JS::CompileOptions& aCompileOptions,
+                                            const nsAString& aScript)
+{
+  if (mSkip) {
+    return mRv;
   }
 
-  // Wrap the return value into whatever compartment aCx was in.
-  if (ok && !aCompileOptions.noScriptRval) {
-    if (!JS_WrapValue(aCx, aRetValue)) {
-      return NS_ERROR_OUT_OF_MEMORY;
-    }
-  }
-  return rv;
+  const nsPromiseFlatString& flatScript = PromiseFlatString(aScript);
+  JS::SourceBufferHolder srcBuf(flatScript.get(), aScript.Length(),
+                                JS::SourceBufferHolder::NoOwnership);
+  return CompileAndExec(aCompileOptions, srcBuf);
 }
 
 nsresult
-nsJSUtils::EvaluateString(JSContext* aCx,
-                          JS::SourceBufferHolder& aSrcBuf,
-                          JS::Handle<JSObject*> aEvaluationGlobal,
-                          JS::CompileOptions& aCompileOptions,
-                          const EvaluateOptions& aEvaluateOptions,
-                          JS::MutableHandle<JS::Value> aRetValue)
-{
-  return EvaluateString(aCx, aSrcBuf, aEvaluationGlobal, aCompileOptions,
-                        aEvaluateOptions, aRetValue, nullptr);
-}
-
-nsresult
-nsJSUtils::EvaluateString(JSContext* aCx,
-                          const nsAString& aScript,
-                          JS::Handle<JSObject*> aEvaluationGlobal,
-                          JS::CompileOptions& aCompileOptions)
+nsJSUtils::ExecutionContext::ExtractReturnValue(JS::MutableHandle<JS::Value> aRetValue)
 {
-  EvaluateOptions options(aCx);
-  aCompileOptions.setNoScriptRval(true);
-  JS::RootedValue unused(aCx);
-  return EvaluateString(aCx, aScript, aEvaluationGlobal, aCompileOptions,
-                        options, &unused);
-}
+  MOZ_ASSERT(aRetValue.isUndefined());
+  if (mSkip) {
+    // Repeat earlier result, as NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW are not
+    // failures cases.
+#ifdef DEBUG
+    mWantsReturnValue = false;
+#endif
+    return mRv;
+  }
 
-nsresult
-nsJSUtils::EvaluateString(JSContext* aCx,
-                          JS::SourceBufferHolder& aSrcBuf,
-                          JS::Handle<JSObject*> aEvaluationGlobal,
-                          JS::CompileOptions& aCompileOptions,
-                          void **aOffThreadToken)
-{
-  EvaluateOptions options(aCx);
-  aCompileOptions.setNoScriptRval(true);
-  JS::RootedValue unused(aCx);
-  return EvaluateString(aCx, aSrcBuf, aEvaluationGlobal, aCompileOptions,
-                        options, &unused, aOffThreadToken);
+  MOZ_ASSERT(mWantsReturnValue);
+#ifdef DEBUG
+  mWantsReturnValue = false;
+#endif
+  if (mCoerceToString && !mRetValue.isUndefined()) {
+    JSString* str = JS::ToString(mCx, mRetValue);
+    if (!str) {
+      // ToString can be a function call, so an exception can be raised while
+      // executing the function.
+      mSkip = true;
+      return EvaluationExceptionToNSResult(mCx);
+    }
+    mRetValue.set(JS::StringValue(str));
+  }
+
+  aRetValue.set(mRetValue);
+  return NS_OK;
 }
 
 nsresult
 nsJSUtils::CompileModule(JSContext* aCx,
                        JS::SourceBufferHolder& aSrcBuf,
                        JS::Handle<JSObject*> aEvaluationGlobal,
                        JS::CompileOptions &aCompileOptions,
                        JS::MutableHandle<JSObject*> aModule)
--- a/dom/base/nsJSUtils.h
+++ b/dom/base/nsJSUtils.h
@@ -11,16 +11,17 @@
  * This is not a generated file. It contains common utility functions 
  * invoked from the JavaScript code generated from IDL interfaces.
  * The goal of the utility functions is to cut down on the size of
  * the generated code itself.
  */
 
 #include "mozilla/Assertions.h"
 
+#include "GeckoProfiler.h"
 #include "jsapi.h"
 #include "jsfriendapi.h"
 #include "js/Conversions.h"
 #include "nsString.h"
 
 class nsIScriptContext;
 class nsIScriptGlobalObject;
 
@@ -59,61 +60,104 @@ public:
                                   JS::AutoObjectVector& aScopeChain,
                                   JS::CompileOptions& aOptions,
                                   const nsACString& aName,
                                   uint32_t aArgCount,
                                   const char** aArgArray,
                                   const nsAString& aBody,
                                   JSObject** aFunctionObject);
 
-  struct MOZ_STACK_CLASS EvaluateOptions {
-    bool coerceToString;
-    JS::AutoObjectVector scopeChain;
+
+  // ExecutionContext is used to switch compartment.
+  class MOZ_STACK_CLASS ExecutionContext {
+    // Register stack annotations for the Gecko profiler.
+    mozilla::SamplerStackFrameRAII mSamplerRAII;
+
+    JSContext* mCx;
+
+    // Handles switching to our global's compartment.
+    JSAutoCompartment mCompartment;
+
+    // Set to a valid handle if a return value is expected.
+    JS::Rooted<JS::Value> mRetValue;
+
+    // Scope chain in which the execution takes place.
+    JS::AutoObjectVector mScopeChain;
+
+    // returned value forwarded when we have to interupt the execution eagerly
+    // with mSkip.
+    nsresult mRv;
+
+    // Used to skip upcoming phases in case of a failure.  In such case the
+    // result is carried by mRv.
+    bool mSkip;
 
-    explicit EvaluateOptions(JSContext* cx)
-      : coerceToString(false)
-      , scopeChain(cx)
-    {}
+    // Should the result be serialized before being returned.
+    bool mCoerceToString;
+
+#ifdef DEBUG
+    // Should we set the return value.
+    bool mWantsReturnValue;
+
+    bool mExpectScopeChain;
+#endif
+
+   public:
 
-    EvaluateOptions& setCoerceToString(bool aCoerce) {
-      coerceToString = aCoerce;
+    // Enter compartment in which the code would be executed.  The JSContext
+    // must come from an AutoEntryScript that has had
+    // TakeOwnershipOfErrorReporting() called on it.
+    ExecutionContext(JSContext* aCx, JS::Handle<JSObject*> aGlobal);
+
+    ExecutionContext(const ExecutionContext&) = delete;
+    ExecutionContext(ExecutionContext&&) = delete;
+
+    ~ExecutionContext() {
+      // This flag is resetted, when the returned value is extracted.
+      MOZ_ASSERT(!mWantsReturnValue);
+    }
+
+    // The returned value would be converted to a string if the
+    // |aCoerceToString| is flag set.
+    ExecutionContext& SetCoerceToString(bool aCoerceToString) {
+      mCoerceToString = aCoerceToString;
       return *this;
     }
-  };
+
+    // Set the scope chain in which the code should be executed.
+    void SetScopeChain(const JS::AutoObjectVector& aScopeChain);
 
-  // aEvaluationGlobal is the global to evaluate in.  The return value
-  // will then be wrapped back into the compartment aCx is in when
-  // this function is called.  For all the EvaluateString overloads,
-  // the JSContext must come from an AutoJSAPI that has had
-  // TakeOwnershipOfErrorReporting() called on it.
-  static nsresult EvaluateString(JSContext* aCx,
-                                 const nsAString& aScript,
-                                 JS::Handle<JSObject*> aEvaluationGlobal,
-                                 JS::CompileOptions &aCompileOptions,
-                                 const EvaluateOptions& aEvaluateOptions,
-                                 JS::MutableHandle<JS::Value> aRetValue);
+    // Copy the returned value in the mutable handle argument, in case of a
+    // evaluation failure either during the execution or the conversion of the
+    // result to a string, the nsresult would be set to the corresponding result
+    // code, and the mutable handle argument would remain unchanged.
+    //
+    // The value returned in the mutable handle argument is part of the
+    // compartment given as argument to the ExecutionContext constructor. If the
+    // caller is in a different compartment, then the out-param value should be
+    // wrapped by calling |JS_WrapValue|.
+    MOZ_MUST_USE nsresult
+    ExtractReturnValue(JS::MutableHandle<JS::Value> aRetValue);
 
-  static nsresult EvaluateString(JSContext* aCx,
-                                 JS::SourceBufferHolder& aSrcBuf,
-                                 JS::Handle<JSObject*> aEvaluationGlobal,
-                                 JS::CompileOptions &aCompileOptions,
-                                 const EvaluateOptions& aEvaluateOptions,
-                                 JS::MutableHandle<JS::Value> aRetValue);
-
+    // After getting a notification that an off-thread compilation terminated,
+    // this function will synchronize the result by moving it to the main thread
+    // before starting the execution of the script.
+    //
+    // The compiled script would be returned in the |aScript| out-param.
+    MOZ_MUST_USE nsresult SyncAndExec(void **aOffThreadToken,
+                                      JS::MutableHandle<JSScript*> aScript);
 
-  static nsresult EvaluateString(JSContext* aCx,
-                                 const nsAString& aScript,
-                                 JS::Handle<JSObject*> aEvaluationGlobal,
-                                 JS::CompileOptions &aCompileOptions);
+    // Compile a script contained in a SourceBuffer, and execute it.
+    nsresult CompileAndExec(JS::CompileOptions& aCompileOptions,
+                            JS::SourceBufferHolder& aSrcBuf);
 
-  static nsresult EvaluateString(JSContext* aCx,
-                                 JS::SourceBufferHolder& aSrcBuf,
-                                 JS::Handle<JSObject*> aEvaluationGlobal,
-                                 JS::CompileOptions &aCompileOptions,
-                                 void **aOffThreadToken);
+    // Compile a script contained in a string, and execute it.
+    nsresult CompileAndExec(JS::CompileOptions& aCompileOptions,
+                            const nsAString& aScript);
+  };
 
   static nsresult CompileModule(JSContext* aCx,
                                 JS::SourceBufferHolder& aSrcBuf,
                                 JS::Handle<JSObject*> aEvaluationGlobal,
                                 JS::CompileOptions &aCompileOptions,
                                 JS::MutableHandle<JSObject*> aModule);
 
   static nsresult ModuleDeclarationInstantiation(JSContext* aCx,
@@ -124,26 +168,16 @@ public:
 
   // Returns false if an exception got thrown on aCx.  Passing a null
   // aElement is allowed; that wil produce an empty aScopeChain.
   static bool GetScopeChainForElement(JSContext* aCx,
                                       mozilla::dom::Element* aElement,
                                       JS::AutoObjectVector& aScopeChain);
 
   static void ResetTimeZone();
-
-private:
-  // Implementation for our EvaluateString bits
-  static nsresult EvaluateString(JSContext* aCx,
-                                 JS::SourceBufferHolder& aSrcBuf,
-                                 JS::Handle<JSObject*> aEvaluationGlobal,
-                                 JS::CompileOptions& aCompileOptions,
-                                 const EvaluateOptions& aEvaluateOptions,
-                                 JS::MutableHandle<JS::Value> aRetValue,
-                                 void **aOffThreadToken);
 };
 
 template<typename T>
 inline bool
 AssignJSString(JSContext *cx, T &dest, JSString *s)
 {
   size_t len = js::GetStringLength(s);
   static_assert(js::MaxStringLength < (1 << 28),
--- a/dom/base/nsNodeInfoManager.cpp
+++ b/dom/base/nsNodeInfoManager.cpp
@@ -25,17 +25,17 @@
 #include "nsGkAtoms.h"
 #include "nsComponentManagerUtils.h"
 #include "nsLayoutStatics.h"
 #include "nsBindingManager.h"
 #include "nsHashKeys.h"
 #include "nsCCUncollectableMarker.h"
 #include "nsNameSpaceManager.h"
 #include "nsDocument.h"
-#include "nsNullPrincipal.h"
+#include "NullPrincipal.h"
 
 using namespace mozilla;
 using mozilla::dom::NodeInfo;
 
 #include "mozilla/Logging.h"
 
 static LazyLogModule gNodeInfoManagerLeakPRLog("NodeInfoManagerLeak");
 
@@ -177,17 +177,17 @@ NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_E
 nsresult
 nsNodeInfoManager::Init(nsIDocument *aDocument)
 {
   NS_ENSURE_TRUE(mNodeInfoHash, NS_ERROR_OUT_OF_MEMORY);
 
   NS_PRECONDITION(!mPrincipal,
                   "Being inited when we already have a principal?");
 
-  mPrincipal = nsNullPrincipal::Create();
+  mPrincipal = NullPrincipal::Create();
 
   if (aDocument) {
     mBindingManager = new nsBindingManager(aDocument);
   }
 
   mDefaultPrincipal = mPrincipal;
 
   mDocument = aDocument;
--- a/dom/base/nsScriptLoader.cpp
+++ b/dom/base/nsScriptLoader.cpp
@@ -2147,18 +2147,16 @@ nsScriptLoader::FillCompileOptionsForReq
 
   bool isScriptElement = !aRequest->IsModuleRequest() ||
                          aRequest->AsModuleRequest()->IsTopLevel();
   aOptions->setIntroductionType(isScriptElement ? "scriptElement"
                                                 : "importedModule");
   aOptions->setFileAndLine(aRequest->mURL.get(), aRequest->mLineNo);
   aOptions->setVersion(JSVersion(aRequest->mJSVersion));
   aOptions->setIsRunOnce(true);
-  // We only need the setNoScriptRval bit when compiling off-thread here, since
-  // otherwise nsJSUtils::EvaluateString will set it up for us.
   aOptions->setNoScriptRval(true);
   if (aRequest->mHasSourceMapURL) {
     aOptions->setSourceMapURL(aRequest->mSourceMapURL.get());
   }
   if (aRequest->mOriginPrincipal) {
     nsIPrincipal* scriptPrin = nsContentUtils::ObjectPrincipal(aScopeChain);
     bool subsumes = scriptPrin->Subsumes(aRequest->mOriginPrincipal);
     aOptions->setMutedErrors(!subsumes);
@@ -2253,20 +2251,27 @@ nsScriptLoader::EvaluateScript(nsScriptL
         MOZ_ASSERT(module);
         rv = nsJSUtils::ModuleEvaluation(aes.cx(), module);
       }
     } else {
       JS::CompileOptions options(aes.cx());
       rv = FillCompileOptionsForRequest(aes, aRequest, global, &options);
 
       if (NS_SUCCEEDED(rv)) {
-        nsAutoString inlineData;
-        SourceBufferHolder srcBuf = GetScriptSource(aRequest, inlineData);
-        rv = nsJSUtils::EvaluateString(aes.cx(), srcBuf, global, options,
-                                       aRequest->OffThreadTokenPtr());
+        {
+          nsJSUtils::ExecutionContext exec(aes.cx(), global);
+          if (aRequest->mOffThreadToken) {
+            JS::Rooted<JSScript*> script(aes.cx());
+            rv = exec.SyncAndExec(&aRequest->mOffThreadToken, &script);
+          } else {
+            nsAutoString inlineData;
+            SourceBufferHolder srcBuf = GetScriptSource(aRequest, inlineData);
+            rv = exec.CompileAndExec(options, srcBuf);
+          }
+        }
       }
     }
   }
 
   context->SetProcessingScriptTag(oldProcessingScriptTag);
   return rv;
 }
 
--- a/dom/base/nsTreeSanitizer.cpp
+++ b/dom/base/nsTreeSanitizer.cpp
@@ -14,17 +14,17 @@
 #include "nsCSSParser.h"
 #include "nsCSSPropertyID.h"
 #include "nsUnicharInputStream.h"
 #include "nsIDOMCSSRule.h"
 #include "nsAttrName.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsNetUtil.h"
 #include "nsComponentManagerUtils.h"
-#include "nsNullPrincipal.h"
+#include "NullPrincipal.h"
 #include "nsContentUtils.h"
 #include "nsIParserUtils.h"
 #include "nsIDocument.h"
 #include "nsQueryObject.h"
 
 using namespace mozilla;
 
 //
@@ -1517,17 +1517,17 @@ nsTreeSanitizer::InitializeStatics()
     sElementsMathML->PutEntry(*kElementsMathML[i]);
   }
 
   sAttributesMathML = new nsTHashtable<nsISupportsHashKey>(ArrayLength(kAttributesMathML));
   for (uint32_t i = 0; kAttributesMathML[i]; i++) {
     sAttributesMathML->PutEntry(*kAttributesMathML[i]);
   }
 
-  nsCOMPtr<nsIPrincipal> principal = nsNullPrincipal::Create();
+  nsCOMPtr<nsIPrincipal> principal = NullPrincipal::Create();
   principal.forget(&sNullPrincipal);
 }
 
 void
 nsTreeSanitizer::ReleaseStatics()
 {
   delete sElementsHTML;
   sElementsHTML = nullptr;
--- a/dom/bindings/SimpleGlobalObject.cpp
+++ b/dom/bindings/SimpleGlobalObject.cpp
@@ -5,17 +5,17 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/SimpleGlobalObject.h"
 
 #include "jsapi.h"
 #include "js/Class.h"
 
 #include "nsJSPrincipals.h"
-#include "nsNullPrincipal.h"
+#include "NullPrincipal.h"
 #include "nsThreadUtils.h"
 #include "nsContentUtils.h"
 
 #include "xpcprivate.h"
 
 #include "mozilla/dom/ScriptSettings.h"
 
 namespace mozilla {
@@ -108,17 +108,17 @@ SimpleGlobalObject::Create(GlobalType gl
            .setInvisibleToDebugger(true)
            // Put our SimpleGlobalObjects in the system zone, so we won't create
            // lots of zones for what are probably very short-lived
            // compartments.  This should help them be GCed quicker and take up
            // less memory before they're GCed.
            .setSystemZone();
 
     if (NS_IsMainThread()) {
-      nsCOMPtr<nsIPrincipal> principal = nsNullPrincipal::Create();
+      nsCOMPtr<nsIPrincipal> principal = NullPrincipal::Create();
       options.creationOptions().setTrace(xpc::TraceXPCGlobal);
       global = xpc::CreateGlobalObject(cx, js::Jsvalify(&SimpleGlobalClass),
                                        nsJSPrincipals::get(principal),
                                        options);
     } else {
       global = JS_NewGlobalObject(cx, js::Jsvalify(&SimpleGlobalClass),
                                   nullptr,
                                   JS::DontFireOnNewGlobalHook, options);
--- a/dom/cache/QuotaClient.cpp
+++ b/dom/cache/QuotaClient.cpp
@@ -11,46 +11,48 @@
 #include "mozilla/dom/quota/UsageInfo.h"
 #include "mozilla/ipc/BackgroundParent.h"
 #include "nsIFile.h"
 #include "nsISimpleEnumerator.h"
 #include "nsThreadUtils.h"
 
 namespace {
 
+using mozilla::Atomic;
 using mozilla::dom::ContentParentId;
 using mozilla::dom::cache::Manager;
 using mozilla::dom::quota::Client;
 using mozilla::dom::quota::PersistenceType;
 using mozilla::dom::quota::QuotaManager;
 using mozilla::dom::quota::UsageInfo;
 using mozilla::ipc::AssertIsOnBackgroundThread;
 
 static nsresult
-GetBodyUsage(nsIFile* aDir, UsageInfo* aUsageInfo)
+GetBodyUsage(nsIFile* aDir, const Atomic<bool>& aCanceled,
+             UsageInfo* aUsageInfo)
 {
   nsCOMPtr<nsISimpleEnumerator> entries;
   nsresult rv = aDir->GetDirectoryEntries(getter_AddRefs(entries));
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
   bool hasMore;
   while (NS_SUCCEEDED(rv = entries->HasMoreElements(&hasMore)) && hasMore &&
-         !aUsageInfo->Canceled()) {
+         !aCanceled) {
     nsCOMPtr<nsISupports> entry;
     rv = entries->GetNext(getter_AddRefs(entry));
     if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
     nsCOMPtr<nsIFile> file = do_QueryInterface(entry);
 
     bool isDir;
     rv = file->IsDirectory(&isDir);
     if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
     if (isDir) {
-      rv = GetBodyUsage(file, aUsageInfo);
+      rv = GetBodyUsage(file, aCanceled, aUsageInfo);
       if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
       continue;
     }
 
     int64_t fileSize;
     rv = file->GetFileSize(&fileSize);
     if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
     MOZ_DIAGNOSTIC_ASSERT(fileSize >= 0);
@@ -67,30 +69,32 @@ public:
   virtual Type
   GetType() override
   {
     return DOMCACHE;
   }
 
   virtual nsresult
   InitOrigin(PersistenceType aPersistenceType, const nsACString& aGroup,
-             const nsACString& aOrigin, UsageInfo* aUsageInfo) override
+             const nsACString& aOrigin, const AtomicBool& aCanceled,
+             UsageInfo* aUsageInfo) override
   {
     // The QuotaManager passes a nullptr UsageInfo if there is no quota being
     // enforced against the origin.
     if (!aUsageInfo) {
       return NS_OK;
     }
 
-    return GetUsageForOrigin(aPersistenceType, aGroup, aOrigin, aUsageInfo);
+    return GetUsageForOrigin(aPersistenceType, aGroup, aOrigin, aCanceled,
+                             aUsageInfo);
   }
 
   virtual nsresult
   GetUsageForOrigin(PersistenceType aPersistenceType, const nsACString& aGroup,
-                    const nsACString& aOrigin,
+                    const nsACString& aOrigin, const AtomicBool& aCanceled,
                     UsageInfo* aUsageInfo) override
   {
     MOZ_DIAGNOSTIC_ASSERT(aUsageInfo);
 
     QuotaManager* qm = QuotaManager::Get();
     MOZ_DIAGNOSTIC_ASSERT(qm);
 
     nsCOMPtr<nsIFile> dir;
@@ -102,34 +106,34 @@ public:
     if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
     nsCOMPtr<nsISimpleEnumerator> entries;
     rv = dir->GetDirectoryEntries(getter_AddRefs(entries));
     if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
     bool hasMore;
     while (NS_SUCCEEDED(rv = entries->HasMoreElements(&hasMore)) && hasMore &&
-           !aUsageInfo->Canceled()) {
+           !aCanceled) {
       nsCOMPtr<nsISupports> entry;
       rv = entries->GetNext(getter_AddRefs(entry));
       if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
       nsCOMPtr<nsIFile> file = do_QueryInterface(entry);
 
       nsAutoString leafName;
       rv = file->GetLeafName(leafName);
       if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
       bool isDir;
       rv = file->IsDirectory(&isDir);
       if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
       if (isDir) {
         if (leafName.EqualsLiteral("morgue")) {
-          rv = GetBodyUsage(file, aUsageInfo);
+          rv = GetBodyUsage(file, aCanceled, aUsageInfo);
           if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
         } else {
           NS_WARNING("Unknown Cache directory found!");
         }
 
         continue;
       }
 
--- a/dom/cache/test/mochitest/test_cache_orphaned_body.html
+++ b/dom/cache/test/mochitest/test_cache_orphaned_body.html
@@ -32,17 +32,18 @@ function clearStorage() {
   });
 }
 
 function storageUsage() {
   return new Promise(function(resolve, reject) {
     var qms = SpecialPowers.Services.qms;
     var principal = SpecialPowers.wrap(document).nodePrincipal;
     var cb = SpecialPowers.wrapCallback(function(request) {
-      resolve(request.usage, request.fileUsage);
+      var result = request.result;
+      resolve(result.usage, result.fileUsage);
     });
     qms.getUsageForPrincipal(principal, cb);
   });
 }
 
 function groupUsage() {
   return new Promise(function(resolve, reject) {
    navigator.storage.estimate().then(storageEstimation => {
--- a/dom/cache/test/mochitest/test_cache_orphaned_cache.html
+++ b/dom/cache/test/mochitest/test_cache_orphaned_cache.html
@@ -32,17 +32,18 @@ function clearStorage() {
   });
 }
 
 function storageUsage() {
   return new Promise(function(resolve, reject) {
     var qms = SpecialPowers.Services.qms;
     var principal = SpecialPowers.wrap(document).nodePrincipal;
     var cb = SpecialPowers.wrapCallback(function(request) {
-      resolve(request.usage, request.fileUsage);
+      var result = request.result;
+      resolve(result.usage, result.fileUsage);
     });
     qms.getUsageForPrincipal(principal, cb);
   });
 }
 
 function resetStorage() {
   return new Promise(function(resolve, reject) {
     var qms = SpecialPowers.Services.qms;
--- a/dom/cache/test/mochitest/test_cache_shrink.html
+++ b/dom/cache/test/mochitest/test_cache_shrink.html
@@ -32,17 +32,18 @@ function clearStorage() {
   });
 }
 
 function storageUsage() {
   return new Promise(function(resolve, reject) {
     var qms = SpecialPowers.Services.qms;
     var principal = SpecialPowers.wrap(document).nodePrincipal;
     var cb = SpecialPowers.wrapCallback(function(request) {
-      resolve(request.usage, request.fileUsage);
+      var result = request.result;
+      resolve(result.usage, result.fileUsage);
     });
     qms.getUsageForPrincipal(principal, cb);
   });
 }
 
 function resetStorage() {
   return new Promise(function(resolve, reject) {
     var qms = SpecialPowers.Services.qms;
--- a/dom/html/nsTextEditorState.cpp
+++ b/dom/html/nsTextEditorState.cpp
@@ -374,38 +374,41 @@ NS_IMETHODIMP
 nsTextInputSelectionImpl::ScrollSelectionIntoView(
                             RawSelectionType aRawSelectionType,
                             int16_t aRegion,
                             int16_t aFlags)
 {
   if (!mFrameSelection) 
     return NS_ERROR_FAILURE; 
 
-  return mFrameSelection->ScrollSelectionIntoView(
-                            ToSelectionType(aRawSelectionType),
-                            aRegion, aFlags);
+  RefPtr<nsFrameSelection> frameSelection = mFrameSelection;
+  return frameSelection->ScrollSelectionIntoView(
+                           ToSelectionType(aRawSelectionType),
+                           aRegion, aFlags);
 }
 
 NS_IMETHODIMP
 nsTextInputSelectionImpl::RepaintSelection(RawSelectionType aRawSelectionType)
 {
   if (!mFrameSelection)
     return NS_ERROR_FAILURE;
 
-  return mFrameSelection->RepaintSelection(ToSelectionType(aRawSelectionType));
+  RefPtr<nsFrameSelection> frameSelection = mFrameSelection;
+  return frameSelection->RepaintSelection(ToSelectionType(aRawSelectionType));
 }
 
 nsresult
 nsTextInputSelectionImpl::RepaintSelection(nsPresContext* aPresContext,
                                            SelectionType aSelectionType)
 {
   if (!mFrameSelection)
     return NS_ERROR_FAILURE;
 
-  return mFrameSelection->RepaintSelection(aSelectionType);
+  RefPtr<nsFrameSelection> frameSelection = mFrameSelection;
+  return frameSelection->RepaintSelection(aSelectionType);
 }
 
 NS_IMETHODIMP
 nsTextInputSelectionImpl::SetCaretEnabled(bool enabled)
 {
   if (!mPresShellWeak) return NS_ERROR_NOT_INITIALIZED;
 
   nsCOMPtr<nsIPresShell> shell = do_QueryReferent(mPresShellWeak);
@@ -482,92 +485,108 @@ nsTextInputSelectionImpl::SetCaretVisibi
   }
   return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsTextInputSelectionImpl::PhysicalMove(int16_t aDirection, int16_t aAmount,
                                        bool aExtend)
 {
-  if (mFrameSelection)
-    return mFrameSelection->PhysicalMove(aDirection, aAmount, aExtend);
+  if (mFrameSelection) {
+    RefPtr<nsFrameSelection> frameSelection = mFrameSelection;
+    return frameSelection->PhysicalMove(aDirection, aAmount, aExtend);
+  }
   return NS_ERROR_NULL_POINTER;
 }
 
 NS_IMETHODIMP
 nsTextInputSelectionImpl::CharacterMove(bool aForward, bool aExtend)
 {
-  if (mFrameSelection)
-    return mFrameSelection->CharacterMove(aForward, aExtend);
+  if (mFrameSelection) {
+    RefPtr<nsFrameSelection> frameSelection = mFrameSelection;
+    return frameSelection->CharacterMove(aForward, aExtend);
+  }
   return NS_ERROR_NULL_POINTER;
 }
 
 NS_IMETHODIMP
 nsTextInputSelectionImpl::CharacterExtendForDelete()
 {
-  if (mFrameSelection)
-    return mFrameSelection->CharacterExtendForDelete();
+  if (mFrameSelection) {
+    RefPtr<nsFrameSelection> frameSelection = mFrameSelection;
+    return frameSelection->CharacterExtendForDelete();
+  }
   return NS_ERROR_NULL_POINTER;
 }
 
 NS_IMETHODIMP
 nsTextInputSelectionImpl::CharacterExtendForBackspace()
 {
-  if (mFrameSelection)
-    return mFrameSelection->CharacterExtendForBackspace();
+  if (mFrameSelection) {
+    RefPtr<nsFrameSelection> frameSelection = mFrameSelection;
+    return frameSelection->CharacterExtendForBackspace();
+  }
   return NS_ERROR_NULL_POINTER;
 }
 
 NS_IMETHODIMP
 nsTextInputSelectionImpl::WordMove(bool aForward, bool aExtend)
 {
-  if (mFrameSelection)
-    return mFrameSelection->WordMove(aForward, aExtend);
+  if (mFrameSelection) {
+    RefPtr<nsFrameSelection> frameSelection = mFrameSelection;
+    return frameSelection->WordMove(aForward, aExtend);
+  }
   return NS_ERROR_NULL_POINTER;
 }
 
 NS_IMETHODIMP
 nsTextInputSelectionImpl::WordExtendForDelete(bool aForward)
 {
-  if (mFrameSelection)
-    return mFrameSelection->WordExtendForDelete(aForward);
+  if (mFrameSelection) {
+    RefPtr<nsFrameSelection> frameSelection = mFrameSelection;
+    return frameSelection->WordExtendForDelete(aForward);
+  }
   return NS_ERROR_NULL_POINTER;
 }
 
 NS_IMETHODIMP
 nsTextInputSelectionImpl::LineMove(bool aForward, bool aExtend)
 {
   if (mFrameSelection)
   {
-    nsresult result = mFrameSelection->LineMove(aForward, aExtend);
+    RefPtr<nsFrameSelection> frameSelection = mFrameSelection;
+    nsresult result = frameSelection->LineMove(aForward, aExtend);
     if (NS_FAILED(result))
       result = CompleteMove(aForward,aExtend);
     return result;
   }
   return NS_ERROR_NULL_POINTER;
 }
 
 
 NS_IMETHODIMP
 nsTextInputSelectionImpl::IntraLineMove(bool aForward, bool aExtend)
 {
-  if (mFrameSelection)
-    return mFrameSelection->IntraLineMove(aForward, aExtend);
+  if (mFrameSelection) {
+    RefPtr<nsFrameSelection> frameSelection = mFrameSelection;
+    return frameSelection->IntraLineMove(aForward, aExtend);
+  }
   return NS_ERROR_NULL_POINTER;
 }
 
 
 NS_IMETHODIMP
 nsTextInputSelectionImpl::PageMove(bool aForward, bool aExtend)
 {
   // expected behavior for PageMove is to scroll AND move the caret
   // and to remain relative position of the caret in view. see Bug 4302.
   if (mScrollFrame)
   {
-    mFrameSelection->CommonPageMove(aForward, aExtend, mScrollFrame);
+    RefPtr<nsFrameSelection> frameSelection = mFrameSelection;
+    frameSelection->CommonPageMove(aForward, aExtend, mScrollFrame);
   }
   // After ScrollSelectionIntoView(), the pending notifications might be
   // flushed and PresShell/PresContext/Frames may be dead. See bug 418470.
   return ScrollSelectionIntoView(nsISelectionController::SELECTION_NORMAL,
                                  nsISelectionController::SELECTION_FOCUS_REGION,
                                  nsISelectionController::SCROLL_SYNCHRONOUS |
                                  nsISelectionController::SCROLL_FOR_CARET_MOVE);
 }
@@ -585,18 +604,21 @@ nsTextInputSelectionImpl::CompleteScroll
                          nsIScrollableFrame::WHOLE,
                          nsIScrollableFrame::INSTANT);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsTextInputSelectionImpl::CompleteMove(bool aForward, bool aExtend)
 {
+  NS_ENSURE_STATE(mFrameSelection);
+  RefPtr<nsFrameSelection> frameSelection = mFrameSelection;
+
   // grab the parent / root DIV for this text widget
-  nsIContent* parentDIV = mFrameSelection->GetLimiter();
+  nsIContent* parentDIV = frameSelection->GetLimiter();
   if (!parentDIV)
     return NS_ERROR_UNEXPECTED;
 
   // make the caret be either at the very beginning (0) or the very end
   int32_t offset = 0;
   CaretAssociationHint hint = CARET_ASSOCIATE_BEFORE;
   if (aForward)
   {
@@ -612,17 +634,17 @@ nsTextInputSelectionImpl::CompleteMove(b
       if (child->IsHTMLElement(nsGkAtoms::br))
       {
         --offset;
         hint = CARET_ASSOCIATE_AFTER; // for Bug 106855
       }
     }
   }
 
-  mFrameSelection->HandleClick(parentDIV, offset, offset, aExtend,
+  frameSelection->HandleClick(parentDIV, offset, offset, aExtend,
                                false, hint);
 
   // if we got this far, attempt to scroll no matter what the above result is
   return CompleteScroll(aForward);
 }
 
 NS_IMETHODIMP
 nsTextInputSelectionImpl::ScrollPage(bool aForward)
@@ -667,18 +689,20 @@ nsTextInputSelectionImpl::ScrollCharacte
                          nsIScrollableFrame::LINES,
                          nsIScrollableFrame::SMOOTH);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsTextInputSelectionImpl::SelectAll()
 {
-  if (mFrameSelection)
-    return mFrameSelection->SelectAll();
+  if (mFrameSelection) {
+    RefPtr<nsFrameSelection> frameSelection = mFrameSelection;
+    return frameSelection->SelectAll();
+  }
   return NS_ERROR_NULL_POINTER;
 }
 
 NS_IMETHODIMP
 nsTextInputSelectionImpl::CheckVisibility(nsIDOMNode *node, int16_t startOffset, int16_t EndOffset, bool *_retval)
 {
   if (!mPresShellWeak) return NS_ERROR_NOT_INITIALIZED;
   nsresult result;
--- a/dom/indexedDB/ActorsParent.cpp
+++ b/dom/indexedDB/ActorsParent.cpp
@@ -9342,22 +9342,24 @@ public:
 
   nsresult
   UpgradeStorageFrom1_0To2_0(nsIFile* aDirectory) override;
 
   nsresult
   InitOrigin(PersistenceType aPersistenceType,
              const nsACString& aGroup,
              const nsACString& aOrigin,
+             const AtomicBool& aCanceled,
              UsageInfo* aUsageInfo) override;
 
   nsresult
   GetUsageForOrigin(PersistenceType aPersistenceType,
                     const nsACString& aGroup,
                     const nsACString& aOrigin,
+                    const AtomicBool& aCanceled,
                     UsageInfo* aUsageInfo) override;
 
   void
   OnOriginClearCompleted(PersistenceType aPersistenceType,
                          const nsACString& aOrigin)
                          override;
 
   void
@@ -9389,23 +9391,24 @@ private:
 
   nsresult
   GetDirectory(PersistenceType aPersistenceType,
                const nsACString& aOrigin,
                nsIFile** aDirectory);
 
   nsresult
   GetDatabaseFilenames(nsIFile* aDirectory,
-                       UsageInfo* aUsageInfo,
+                       const AtomicBool& aCanceled,
                        bool aForUpgrade,
                        nsTArray<nsString>& aSubdirsToProcess,
                        nsTHashtable<nsStringHashKey>& aDatabaseFilename);
 
   nsresult
   GetUsageForDirectoryInternal(nsIFile* aDirectory,
+                               const AtomicBool& aCanceled,
                                UsageInfo* aUsageInfo,
                                bool aDatabaseFiles);
 
   // Runs on the PBackground thread. Checks to see if there's a queued
   // Maintenance to run.
   void
   ProcessMaintenanceQueue();
 };
@@ -17823,20 +17826,21 @@ QuotaClient::GetType()
 }
 
 nsresult
 QuotaClient::UpgradeStorageFrom1_0To2_0(nsIFile* aDirectory)
 {
   AssertIsOnIOThread();
   MOZ_ASSERT(aDirectory);
 
+  AtomicBool dummy(false);
   AutoTArray<nsString, 20> subdirsToProcess;
   nsTHashtable<nsStringHashKey> databaseFilenames(20);
   nsresult rv = GetDatabaseFilenames(aDirectory,
-                                     nullptr,
+                                     /* aCanceled */ dummy,
                                      /* aForUpgrade */ true,
                                      subdirsToProcess,
                                      databaseFilenames);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   const NS_ConvertASCIItoUTF16 filesSuffix(
@@ -17919,16 +17923,17 @@ QuotaClient::UpgradeStorageFrom1_0To2_0(
 
   return NS_OK;
 }
 
 nsresult
 QuotaClient::InitOrigin(PersistenceType aPersistenceType,
                         const nsACString& aGroup,
                         const nsACString& aOrigin,
+                        const AtomicBool& aCanceled,
                         UsageInfo* aUsageInfo)
 {
   AssertIsOnIOThread();
 
   nsCOMPtr<nsIFile> directory;
   nsresult rv =
     GetDirectory(aPersistenceType, aOrigin, getter_AddRefs(directory));
   if (NS_WARN_IF(NS_FAILED(rv))) {
@@ -17937,17 +17942,17 @@ QuotaClient::InitOrigin(PersistenceType 
 
   // We need to see if there are any files in the directory already. If they
   // are database files then we need to cleanup stored files (if it's needed)
   // and also get the usage.
 
   AutoTArray<nsString, 20> subdirsToProcess;
   nsTHashtable<nsStringHashKey> databaseFilenames(20);
   rv = GetDatabaseFilenames(directory,
-                            aUsageInfo,
+                            aCanceled,
                             /* aForUpgrade */ false,
                             subdirsToProcess,
                             databaseFilenames);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   const NS_ConvertASCIItoUTF16 filesSuffix(
@@ -17969,17 +17974,19 @@ QuotaClient::InitOrigin(PersistenceType 
     }
   }
 
   const NS_ConvertASCIItoUTF16 sqliteSuffix(kSQLiteSuffix,
                                             LiteralStringLength(kSQLiteSuffix));
   const NS_ConvertASCIItoUTF16 walSuffix(kSQLiteWALSuffix,
                                          LiteralStringLength(kSQLiteWALSuffix));
 
-  for (auto iter = databaseFilenames.ConstIter(); !iter.Done(); iter.Next()) {
+  for (auto iter = databaseFilenames.ConstIter();
+       !iter.Done() && !aCanceled;
+       iter.Next()) {
     auto& databaseFilename = iter.Get()->GetKey();
 
     nsCOMPtr<nsIFile> fmDirectory;
     rv = directory->Clone(getter_AddRefs(fmDirectory));
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
 
@@ -18017,17 +18024,17 @@ QuotaClient::InitOrigin(PersistenceType 
                                     aPersistenceType,
                                     aGroup,
                                     aOrigin,
                                     TelemetryIdForFile(databaseFile));
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
 
-    if (aUsageInfo && !aUsageInfo->Canceled()) {
+    if (aUsageInfo) {
       int64_t fileSize;
       rv = databaseFile->GetFileSize(&fileSize);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
 
       MOZ_ASSERT(fileSize >= 0);
 
@@ -18054,29 +18061,30 @@ QuotaClient::InitOrigin(PersistenceType 
 
   return NS_OK;
 }
 
 nsresult
 QuotaClient::GetUsageForOrigin(PersistenceType aPersistenceType,
                                const nsACString& aGroup,
                                const nsACString& aOrigin,
+                               const AtomicBool& aCanceled,
                                UsageInfo* aUsageInfo)
 {
   AssertIsOnIOThread();
   MOZ_ASSERT(aUsageInfo);
 
   nsCOMPtr<nsIFile> directory;
   nsresult rv =
     GetDirectory(aPersistenceType, aOrigin, getter_AddRefs(directory));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
-  rv = GetUsageForDirectoryInternal(directory, aUsageInfo, true);
+  rv = GetUsageForDirectoryInternal(directory, aCanceled, aUsageInfo, true);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   return NS_OK;
 }
 
 void
@@ -18255,22 +18263,23 @@ QuotaClient::GetDirectory(PersistenceTyp
 
   directory.forget(aDirectory);
   return NS_OK;
 }
 
 nsresult
 QuotaClient::GetDatabaseFilenames(
                               nsIFile* aDirectory,
-                              UsageInfo* aUsageInfo,
+                              const AtomicBool& aCanceled,
                               bool aForUpgrade,
                               nsTArray<nsString>& aSubdirsToProcess,
                               nsTHashtable<nsStringHashKey>& aDatabaseFilenames)
 {
   AssertIsOnIOThread();
+  MOZ_ASSERT(aDirectory);
 
   nsCOMPtr<nsISimpleEnumerator> entries;
   nsresult rv = aDirectory->GetDirectoryEntries(getter_AddRefs(entries));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   const NS_ConvertASCIItoUTF16 sqliteSuffix(kSQLiteSuffix,
@@ -18281,17 +18290,17 @@ QuotaClient::GetDatabaseFilenames(
   const NS_ConvertASCIItoUTF16 shmSuffix(kSQLiteSHMSuffix,
                                          LiteralStringLength(kSQLiteSHMSuffix));
   const NS_ConvertASCIItoUTF16 walSuffix(kSQLiteWALSuffix,
                                          LiteralStringLength(kSQLiteWALSuffix));
 
   bool hasMore;
   while (NS_SUCCEEDED((rv = entries->HasMoreElements(&hasMore))) &&
          hasMore &&
-         (!aUsageInfo || !aUsageInfo->Canceled())) {
+         !aCanceled) {
     nsCOMPtr<nsISupports> entry;
     rv = entries->GetNext(getter_AddRefs(entry));
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
 
     nsCOMPtr<nsIFile> file = do_QueryInterface(entry);
     MOZ_ASSERT(file);
@@ -18357,16 +18366,17 @@ QuotaClient::GetDatabaseFilenames(
     return rv;
   }
 
   return NS_OK;
 }
 
 nsresult
 QuotaClient::GetUsageForDirectoryInternal(nsIFile* aDirectory,
+                                          const AtomicBool& aCanceled,
                                           UsageInfo* aUsageInfo,
                                           bool aDatabaseFiles)
 {
   AssertIsOnIOThread();
   MOZ_ASSERT(aDirectory);
   MOZ_ASSERT(aUsageInfo);
 
   nsCOMPtr<nsISimpleEnumerator> entries;
@@ -18383,17 +18393,17 @@ QuotaClient::GetUsageForDirectoryInterna
     kSQLiteJournalSuffix,
     LiteralStringLength(kSQLiteJournalSuffix));
   const NS_ConvertASCIItoUTF16 shmSuffix(kSQLiteSHMSuffix,
                                          LiteralStringLength(kSQLiteSHMSuffix));
 
   bool hasMore;
   while (NS_SUCCEEDED((rv = entries->HasMoreElements(&hasMore))) &&
          hasMore &&
-         !aUsageInfo->Canceled()) {
+         !aCanceled) {
     nsCOMPtr<nsISupports> entry;
     rv = entries->GetNext(getter_AddRefs(entry));
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
 
     nsCOMPtr<nsIFile> file = do_QueryInterface(entry);
     MOZ_ASSERT(file);
@@ -18418,17 +18428,17 @@ QuotaClient::GetUsageForDirectoryInterna
     }
 
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
 
     if (isDirectory) {
       if (aDatabaseFiles) {
-        rv = GetUsageForDirectoryInternal(file, aUsageInfo, false);
+        rv = GetUsageForDirectoryInternal(file, aCanceled, aUsageInfo, false);
         if (NS_WARN_IF(NS_FAILED(rv))) {
           return rv;
         }
       } else {
         nsString leafName;
         rv = file->GetLeafName(leafName);
         if (NS_WARN_IF(NS_FAILED(rv))) {
           return rv;
@@ -21231,18 +21241,17 @@ FactoryOp::CheckPermission(ContentParent
       mChromeWriteAccessAllowed = canWrite;
     } else {
       mChromeWriteAccessAllowed = true;
     }
 
     if (State::Initial == mState) {
       QuotaManager::GetInfoForChrome(&mSuffix, &mGroup, &mOrigin);
 
-      MOZ_ASSERT(
-        QuotaManager::IsOriginWhitelistedForPersistentStorage(mOrigin));
+      MOZ_ASSERT(QuotaManager::IsOriginInternal(mOrigin));
 
       mEnforcingQuota = false;
     }
 
     *aPermission = PermissionRequestBase::kPermissionAllowed;
     return NS_OK;
   }
 
@@ -21264,17 +21273,17 @@ FactoryOp::CheckPermission(ContentParent
                                           &origin);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   PermissionRequestBase::PermissionValue permission;
 
   if (persistenceType == PERSISTENCE_TYPE_PERSISTENT) {
-    if (QuotaManager::IsOriginWhitelistedForPersistentStorage(origin)) {
+    if (QuotaManager::IsOriginInternal(origin)) {
       permission = PermissionRequestBase::kPermissionAllowed;
     } else {
 #ifdef IDB_MOBILE
       return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
 #else
       rv = PermissionRequestBase::GetCurrentPermission(principal, &permission);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
--- a/dom/indexedDB/test/file.js
+++ b/dom/indexedDB/test/file.js
@@ -215,20 +215,20 @@ function verifyWasmModule(module1, modul
   ok(code2 instanceof getGlobalForObject(code1).Uint8Array, "Instance of Uint8Array");
   ok(code1.length == code2.length, "Correct length");
   verifyBuffers(code1, code2);
   continueToNextStep();
 }
 
 function grabFileUsageAndContinueHandler(request)
 {
-  testGenerator.next(request.fileUsage);
+  testGenerator.next(request.result.fileUsage);
 }
 
-function getUsage(usageHandler)
+function getCurrentUsage(usageHandler)
 {
   let qms = SpecialPowers.Services.qms;
   let principal = SpecialPowers.wrap(document).nodePrincipal;
   let cb = SpecialPowers.wrapCallback(usageHandler);
   qms.getUsageForPrincipal(principal, cb);
 }
 
 function getFileId(file)
--- a/dom/indexedDB/test/test_file_os_delete.html
+++ b/dom/indexedDB/test/test_file_os_delete.html
@@ -13,17 +13,17 @@
   function* testSteps()
   {
     const READ_WRITE = "readwrite";
 
     const name = window.location.pathname;
 
     const objectStoreName = "Blobs";
 
-    getUsage(grabFileUsageAndContinueHandler);
+    getCurrentUsage(grabFileUsageAndContinueHandler);
     let startUsage = yield undefined;
 
     const fileData1 = {
       key: 1,
       obj: { id: 1, file: getRandomFile("random.bin", 100000) }
     };
     const fileData2 = {
       key: 2,
@@ -56,46 +56,46 @@
       request.addEventListener("error", new ExpectError("ConstraintError", true));
       request.onsuccess = unexpectedSuccessHandler;
       yield undefined;
 
       event = yield undefined;
 
       is(event.type, "success", "Got correct event type");
 
-      getUsage(grabFileUsageAndContinueHandler);
+      getCurrentUsage(grabFileUsageAndContinueHandler);
       let usage = yield undefined;
 
       is(usage, startUsage + fileData1.obj.file.size + fileData2.obj.file.size,
          "Correct file usage");
 
       let trans = db.transaction([objectStoreName], READ_WRITE);
       trans.objectStore(objectStoreName).delete(fileData1.key);
       trans.oncomplete = grabEventAndContinueHandler;
       event = yield undefined;
 
       is(event.type, "complete", "Got correct event type");
 
-      getUsage(grabFileUsageAndContinueHandler);
+      getCurrentUsage(grabFileUsageAndContinueHandler);
       usage = yield undefined;
 
       is(usage, startUsage + fileData1.obj.file.size + fileData2.obj.file.size,
          "OS files exists");
 
       fileData1.obj.file = null;
       fileData2.obj.file = null;
     }
 
     scheduleGC();
     yield undefined;
 
     // Flush pending file deletions before checking usage.
     flushPendingFileDeletions();
 
-    getUsage(grabFileUsageAndContinueHandler);
+    getCurrentUsage(grabFileUsageAndContinueHandler);
     let endUsage = yield undefined;
 
     is(endUsage, startUsage, "OS files deleted");
 
     finishTest();
   }
   </script>
   <script type="text/javascript" src="file.js"></script>
--- a/dom/indexedDB/test/unit/test_idle_maintenance.js
+++ b/dom/indexedDB/test/unit/test_idle_maintenance.js
@@ -117,18 +117,19 @@ function* testSteps()
   }
   yield undefined;
 
   info("Getting usage before maintenance");
 
   let usageBeforeMaintenance;
 
   quotaManagerService.getUsageForPrincipal(principal, (request) => {
-    ok(request.usage > 0, "Usage is non-zero");
-    usageBeforeMaintenance = request.usage;
+    let usage = request.result.usage;
+    ok(usage > 0, "Usage is non-zero");
+    usageBeforeMaintenance = usage;
     continueToNextStep();
   });
   yield undefined;
 
   info("Sending fake 'idle-daily' notification to QuotaManager");
 
   let observer = quotaManagerService.QueryInterface(Ci.nsIObserver);
   observer.observe(null, "idle-daily", "");
@@ -150,18 +151,19 @@ function* testSteps()
   setTimeout(continueToNextStep, 10000);
   yield undefined;
 
   info("Getting usage after maintenance");
 
   let usageAfterMaintenance;
 
   quotaManagerService.getUsageForPrincipal(principal, (request) => {
-    ok(request.usage > 0, "Usage is non-zero");
-    usageAfterMaintenance = request.usage;
+    let usage = request.result.usage;
+    ok(usage > 0, "Usage is non-zero");
+    usageAfterMaintenance = usage;
     continueToNextStep();
   });
   yield undefined;
 
   info("Usage before: " + usageBeforeMaintenance + ". " +
        "Usage after: " + usageAfterMaintenance);
 
   ok(usageAfterMaintenance <= usageBeforeMaintenance,
--- a/dom/indexedDB/test/unit/test_view_put_get_values.js
+++ b/dom/indexedDB/test/unit/test_view_put_get_values.js
@@ -75,17 +75,17 @@ function* testSteps()
     request = db.transaction([objectStoreName])
                 .objectStore(objectStoreName).get(viewData.key);
     request.onsuccess = continueToNextStepSync;
     yield undefined;
 
     verifyView(request.result, viewData.view);
     yield undefined;
 
-    getUsage(grabFileUsageAndContinueHandler);
+    getCurrentUsage(grabFileUsageAndContinueHandler);
     let fileUsage = yield undefined;
 
     if (external) {
       ok(fileUsage > 0, "File usage is not zero");
     } else {
       ok(fileUsage == 0, "File usage is zero");
     }
 
--- a/dom/indexedDB/test/unit/xpcshell-head-parent-process.js
+++ b/dom/indexedDB/test/unit/xpcshell-head-parent-process.js
@@ -511,20 +511,20 @@ function verifyWasmModule(module1, modul
   ok(code1 instanceof Uint8Array, "Instance of Uint8Array");
   ok(code1.length == code2.length, "Correct length");
   verifyBuffers(code1, code2);
   continueToNextStep();
 }
 
 function grabFileUsageAndContinueHandler(request)
 {
-  testGenerator.next(request.fileUsage);
+  testGenerator.next(request.result.fileUsage);
 }
 
-function getUsage(usageHandler)
+function getCurrentUsage(usageHandler)
 {
   let qms = Cc["@mozilla.org/dom/quota-manager-service;1"]
               .getService(Ci.nsIQuotaManagerService);
   let principal = Cc["@mozilla.org/systemprincipal;1"]
                     .createInstance(Ci.nsIPrincipal);
   qms.getUsageForPrincipal(principal, usageHandler);
 }
 
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -53,27 +53,27 @@
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeOwner.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMEvent.h"
 #include "nsIDOMWindow.h"
 #include "nsIDOMWindowUtils.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsILoadInfo.h"
-#include "nsPrincipal.h"
 #include "nsIPromptFactory.h"
 #include "nsIURI.h"
 #include "nsIWindowWatcher.h"
 #include "nsIWebBrowserChrome.h"
 #include "nsIXULBrowserWindow.h"
 #include "nsIXULWindow.h"
 #include "nsIRemoteBrowser.h"
 #include "nsViewManager.h"
 #include "nsVariant.h"
 #include "nsIWidget.h"
+#include "nsNetUtil.h"
 #ifndef XP_WIN
 #include "nsJARProtocolHandler.h"
 #endif
 #include "nsPIDOMWindow.h"
 #include "nsPrintfCString.h"
 #include "nsServiceManagerUtils.h"
 #include "nsThreadUtils.h"
 #include "PermissionMessageUtils.h"
--- a/dom/json/nsJSON.cpp
+++ b/dom/json/nsJSON.cpp
@@ -17,17 +17,17 @@
 #include "nsIUnicodeDecoder.h"
 #include "nsNetUtil.h"
 #include "nsIURI.h"
 #include "nsComponentManagerUtils.h"
 #include "nsContentUtils.h"
 #include "nsIScriptError.h"
 #include "nsCRTGlue.h"
 #include "nsIScriptSecurityManager.h"
-#include "nsNullPrincipal.h"
+#include "NullPrincipal.h"
 #include "mozilla/Maybe.h"
 #include <algorithm>
 
 using mozilla::dom::EncodingUtils;
 
 #define JSON_STREAM_BUFSIZE 4096
 
 NS_INTERFACE_MAP_BEGIN(nsJSON)
@@ -402,17 +402,17 @@ nsJSON::DecodeInternal(JSContext* cx,
   nsCOMPtr<nsIChannel> jsonChannel;
   if (!mURI) {
     NS_NewURI(getter_AddRefs(mURI), NS_LITERAL_CSTRING("about:blank"), 0, 0 );
     if (!mURI)
       return NS_ERROR_OUT_OF_MEMORY;
   }
 
   nsresult rv;
-  nsCOMPtr<nsIPrincipal> nullPrincipal = nsNullPrincipal::Create();
+  nsCOMPtr<nsIPrincipal> nullPrincipal = NullPrincipal::Create();
 
   // The ::Decode function is deprecated [Bug 675797] and the following
   // channel is never openend, so it does not matter what securityFlags
   // we pass to NS_NewInputStreamChannel here.
   rv = NS_NewInputStreamChannel(getter_AddRefs(jsonChannel),
                                 mURI,
                                 aStream,
                                 nullPrincipal,
--- a/dom/jsurl/nsJSProtocolHandler.cpp
+++ b/dom/jsurl/nsJSProtocolHandler.cpp
@@ -264,20 +264,24 @@ nsresult nsJSThunk::EvaluateScript(nsICh
         return NS_ERROR_DOM_SECURITY_ERR;
     }
 
     JS::Rooted<JS::Value> v (cx, JS::UndefinedValue());
     // Finally, we have everything needed to evaluate the expression.
     JS::CompileOptions options(cx);
     options.setFileAndLine(mURL.get(), 1)
            .setVersion(JSVERSION_DEFAULT);
-    nsJSUtils::EvaluateOptions evalOptions(cx);
-    evalOptions.setCoerceToString(true);
-    rv = nsJSUtils::EvaluateString(cx, NS_ConvertUTF8toUTF16(script),
-                                   globalJSObject, options, evalOptions, &v);
+    {
+        nsJSUtils::ExecutionContext exec(cx, globalJSObject);
+        exec.SetCoerceToString(true);
+        exec.CompileAndExec(options, NS_ConvertUTF8toUTF16(script));
+        rv = exec.ExtractReturnValue(&v);
+    }
+
+    js::AssertSameCompartment(cx, v);
 
     if (NS_FAILED(rv) || !(v.isString() || v.isUndefined())) {
         return NS_ERROR_MALFORMED_URI;
     } else if (v.isUndefined()) {
         return NS_ERROR_DOM_RETVAL_UNDEFINED;
     } else {
         MOZ_ASSERT(rv != NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW,
                    "How did we get a non-undefined return value?");
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -23,17 +23,16 @@
 #include "nsIPopupWindowManager.h"
 #include "nsIDocShell.h"
 #include "nsIDocument.h"
 #include "nsISupportsPrimitives.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIIDNService.h"
 #include "nsNetCID.h"
 #include "nsNetUtil.h"
-#include "nsPrincipal.h"
 #include "nsICryptoHash.h"
 #include "nsICryptoHMAC.h"
 #include "nsIKeyModule.h"
 #include "nsAppDirectoryServiceDefs.h"
 #include "nsIInputStream.h"
 #include "nsILineInputStream.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/Types.h"
@@ -49,17 +48,17 @@
 #include "mozilla/Base64.h"
 #include "mozilla/ipc/BackgroundChild.h"
 #include "mozilla/media/MediaChild.h"
 #include "mozilla/media/MediaTaskUtils.h"
 #include "MediaTrackConstraints.h"
 #include "VideoUtils.h"
 #include "Latency.h"
 #include "nsProxyRelease.h"
-#include "nsNullPrincipal.h"
+#include "NullPrincipal.h"
 #include "nsVariant.h"
 
 // For snprintf
 #include "mozilla/Sprintf.h"
 
 #include "nsJSUtils.h"
 #include "nsGlobalWindow.h"
 #include "nsIUUIDGenerator.h"
@@ -1150,17 +1149,17 @@ public:
         RefPtr<GetUserMediaCallbackMediaStreamListener> mListener;
         const MediaSourceEnum mSource;
         const TrackID mTrackID;
         const RefPtr<const PeerIdentity> mPeerIdentity;
       };
 
       nsCOMPtr<nsIPrincipal> principal;
       if (mPeerIdentity) {
-        principal = nsNullPrincipal::CreateWithInheritedAttributes(window->GetExtantDoc()->NodePrincipal());
+        principal = NullPrincipal::CreateWithInheritedAttributes(window->GetExtantDoc()->NodePrincipal());
       } else {
         principal = window->GetExtantDoc()->NodePrincipal();
       }
 
       // Normal case, connect the source stream to the track union stream to
       // avoid us blocking. Pass a simple TrackSourceGetter for potential
       // fake tracks. Apart from them gUM never adds tracks dynamically.
       domStream =
--- a/dom/media/MediaStreamTrack.h
+++ b/dom/media/MediaStreamTrack.h
@@ -92,17 +92,17 @@ public:
    * PrincipalChanged().
    */
   virtual CORSMode GetCORSMode() const { return CORS_NONE; }
 
   /**
    * This is used in WebRTC. A peerIdentity constrained MediaStreamTrack cannot
    * be sent across the network to anything other than a peer with the provided
    * identity. If this is set, then GetPrincipal() should return an instance of
-   * nsNullPrincipal.
+   * NullPrincipal.
    *
    * A track's PeerIdentity is immutable and will not change during the track's
    * lifetime.
    */
   virtual const PeerIdentity* GetPeerIdentity() const { return nullptr; }
 
   /**
    * MediaStreamTrack::GetLabel (see spec) calls through to here.
--- a/dom/media/mediasink/AudioSink.cpp
+++ b/dom/media/mediasink/AudioSink.cpp
@@ -253,37 +253,16 @@ AudioSink::PopFrames(uint32_t aFrames)
     uint32_t Rate() const { return mBuffer ? mBuffer->mRate : 0; }
     AudioDataValue* GetWritable() const { return mData; }
   private:
     const RefPtr<AudioData> mBuffer;
     const uint32_t mFrames;
     AudioDataValue* const mData;
   };
 
-  class SilentChunk : public AudioStream::Chunk {
-  public:
-    SilentChunk(uint32_t aFrames, uint32_t aChannels, uint32_t aRate)
-      : mFrames(aFrames)
-      , mChannels(aChannels)
-      , mRate(aRate)
-      , mData(MakeUnique<AudioDataValue[]>(aChannels * aFrames)) {
-      memset(mData.get(), 0, aChannels * aFrames * sizeof(AudioDataValue));
-    }
-    const AudioDataValue* Data() const { return mData.get(); }
-    uint32_t Frames() const { return mFrames; }
-    uint32_t Channels() const { return mChannels; }
-    uint32_t Rate() const { return mRate; }
-    AudioDataValue* GetWritable() const { return mData.get(); }
-  private:
-    const uint32_t mFrames;
-    const uint32_t mChannels;
-    const uint32_t mRate;
-    UniquePtr<AudioDataValue[]> mData;
-  };
-
   bool needPopping = false;
   if (!mCurrentData) {
     // No data in the queue. Return an empty chunk.
     if (!mProcessedQueue.GetSize()) {
       return MakeUnique<Chunk>();
     }
 
     // We need to update our values prior popping the processed queue in
--- a/dom/media/platforms/wmf/WMFVideoMFTManager.cpp
+++ b/dom/media/platforms/wmf/WMFVideoMFTManager.cpp
@@ -379,20 +379,19 @@ FindD3D9BlacklistedDLL()
   return FindDXVABlacklistedDLL(sD3D9BlacklistingCache,
                                 gfx::gfxVars::PDMWMFDisableD3D9Dlls(),
                                 "media.wmf.disable-d3d9-for-dlls");
 }
 
 class CreateDXVAManagerEvent : public Runnable
 {
 public:
-  CreateDXVAManagerEvent(LayersBackend aBackend,
-                         layers::KnowsCompositor* aKnowsCompositor,
+  CreateDXVAManagerEvent(layers::KnowsCompositor* aKnowsCompositor,
                          nsCString& aFailureReason)
-    : mBackend(aBackend)
+    : mBackend(LayersBackend::LAYERS_D3D11)
     , mKnowsCompositor(aKnowsCompositor)
     , mFailureReason(aFailureReason)
   {
   }
 
   NS_IMETHOD Run() override {
     NS_ASSERTION(NS_IsMainThread(), "Must be on main thread.");
     nsACString* failureReason = &mFailureReason;
@@ -430,39 +429,36 @@ public:
   }
   nsAutoPtr<DXVA2Manager> mDXVA2Manager;
   layers::LayersBackend mBackend;
   layers::KnowsCompositor* mKnowsCompositor;
   nsACString& mFailureReason;
 };
 
 bool
-WMFVideoMFTManager::InitializeDXVA(bool aForceD3D9)
+WMFVideoMFTManager::InitializeDXVA()
 {
   // If we use DXVA but aren't running with a D3D layer manager then the
   // readback of decoded video frames from GPU to CPU memory grinds painting
   // to a halt, and makes playback performance *worse*.
   if (!mDXVAEnabled) {
     mDXVAFailureReason.AssignLiteral(
       "Hardware video decoding disabled or blacklisted");
     return false;
   }
   MOZ_ASSERT(!mDXVA2Manager);
   LayersBackend backend = GetCompositorBackendType(mKnowsCompositor);
-  if (backend != LayersBackend::LAYERS_D3D9
-      && backend != LayersBackend::LAYERS_D3D11) {
+  if (backend != LayersBackend::LAYERS_D3D11) {
     mDXVAFailureReason.AssignLiteral("Unsupported layers backend");
     return false;
   }
 
   // The DXVA manager must be created on the main thread.
   RefPtr<CreateDXVAManagerEvent> event =
-    new CreateDXVAManagerEvent(aForceD3D9 ? LayersBackend::LAYERS_D3D9
-                                          : backend,
-                               mKnowsCompositor,
+    new CreateDXVAManagerEvent(mKnowsCompositor,
                                mDXVAFailureReason);
 
   if (NS_IsMainThread()) {
     event->Run();
   } else {
     // This logic needs to run on the main thread
     mozilla::SyncRunnable::DispatchToThread(
       SystemGroup::EventTargetFor(mozilla::TaskCategory::Other), event);
@@ -494,36 +490,36 @@ WMFVideoMFTManager::ValidateVideoInfo()
 
 bool
 WMFVideoMFTManager::Init()
 {
   if (!ValidateVideoInfo()) {
     return false;
   }
 
-  bool success = InitInternal(/* aForceD3D9 = */ false);
+  bool success = InitInternal();
 
   if (success && mDXVA2Manager) {
     // If we had some failures but eventually made it work,
     // make sure we preserve the messages.
     if (mDXVA2Manager->IsD3D11()) {
       mDXVAFailureReason.Append(NS_LITERAL_CSTRING("Using D3D11 API"));
     } else {
       mDXVAFailureReason.Append(NS_LITERAL_CSTRING("Using D3D9 API"));
     }
   }
 
   return success;
 }
 
 bool
-WMFVideoMFTManager::InitInternal(bool aForceD3D9)
+WMFVideoMFTManager::InitInternal()
 {
   mUseHwAccel = false; // default value; changed if D3D setup succeeds.
-  bool useDxva = InitializeDXVA(aForceD3D9);
+  bool useDxva = InitializeDXVA();
 
   RefPtr<MFTDecoder> decoder(new MFTDecoder());
 
   HRESULT hr = decoder->Create(GetMFTGUID());
   NS_ENSURE_TRUE(SUCCEEDED(hr), false);
 
   RefPtr<IMFAttributes> attr(decoder->GetAttributes());
   UINT32 aware = 0;
@@ -831,18 +827,17 @@ WMFVideoMFTManager::CreateBasicVideoFram
 
   media::TimeUnit pts = GetSampleTime(aSample);
   NS_ENSURE_TRUE(pts.IsValid(), E_FAIL);
   media::TimeUnit duration = GetSampleDuration(aSample);
   NS_ENSURE_TRUE(duration.IsValid(), E_FAIL);
   nsIntRect pictureRegion = mVideoInfo.ScaledImageRect(videoWidth, videoHeight);
 
   LayersBackend backend = GetCompositorBackendType(mKnowsCompositor);
-  if (backend != LayersBackend::LAYERS_D3D9 &&
-      backend != LayersBackend::LAYERS_D3D11) {
+  if (backend != LayersBackend::LAYERS_D3D11) {
     RefPtr<VideoData> v =
       VideoData::CreateAndCopyData(mVideoInfo,
                                    mImageContainer,
                                    aStreamOffset,
                                    pts.ToMicroseconds(),
                                    duration.ToMicroseconds(),
                                    b,
                                    false,
--- a/dom/media/platforms/wmf/WMFVideoMFTManager.h
+++ b/dom/media/platforms/wmf/WMFVideoMFTManager.h
@@ -64,19 +64,19 @@ public:
     return mStreamType == H264
            ? MediaDataDecoder::ConversionRequired::kNeedAnnexB
            : MediaDataDecoder::ConversionRequired::kNeedNone;
   }
 
 private:
   bool ValidateVideoInfo();
 
-  bool InitializeDXVA(bool aForceD3D9);
+  bool InitializeDXVA();
 
-  bool InitInternal(bool aForceD3D9);
+  bool InitInternal();
 
   HRESULT CreateBasicVideoFrame(IMFSample* aSample,
                                 int64_t aStreamOffset,
                                 VideoData** aOutVideoData);
 
   HRESULT CreateD3DVideoFrame(IMFSample* aSample,
                               int64_t aStreamOffset,
                               VideoData** aOutVideoData);
--- a/dom/plugins/base/nsNPAPIPlugin.cpp
+++ b/dom/plugins/base/nsNPAPIPlugin.cpp
@@ -1363,24 +1363,33 @@ bool
   NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
                  ("NPN_Evaluate(npp %p, npobj %p, script <<<%s>>>) called\n",
                   npp, npobj, script->UTF8Characters));
 
   JS::CompileOptions options(cx);
   options.setFileAndLine(spec, 0)
          .setVersion(JSVERSION_DEFAULT);
   JS::Rooted<JS::Value> rval(cx);
-  nsJSUtils::EvaluateOptions evalOptions(cx);
+  JS::AutoObjectVector scopeChain(cx);
   if (obj != js::GetGlobalForObjectCrossCompartment(obj) &&
-      !evalOptions.scopeChain.append(obj)) {
+      !scopeChain.append(obj)) {
     return false;
   }
   obj = js::GetGlobalForObjectCrossCompartment(obj);
-  nsresult rv = nsJSUtils::EvaluateString(cx, utf16script, obj, options,
-                                          evalOptions, &rval);
+  nsresult rv = NS_OK;
+  {
+    nsJSUtils::ExecutionContext exec(cx, obj);
+    exec.SetScopeChain(scopeChain);
+    exec.CompileAndExec(options, utf16script);
+    rv = exec.ExtractReturnValue(&rval);
+  }
+
+  if (!JS_WrapValue(cx, &rval)) {
+    return false;
+  }
 
   return NS_SUCCEEDED(rv) &&
          (!result || JSValToNPVariant(npp, cx, rval, result));
 }
 
 bool
 _getproperty(NPP npp, NPObject* npobj, NPIdentifier property,
              NPVariant *result)
--- a/dom/plugins/base/nsPluginHost.cpp
+++ b/dom/plugins/base/nsPluginHost.cpp
@@ -89,17 +89,17 @@
 #include "nsPluginNativeWindow.h"
 #include "nsIContentPolicy.h"
 #include "nsContentPolicyUtils.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/Telemetry.h"
 #include "nsIImageLoadingContent.h"
 #include "mozilla/Preferences.h"
 #include "nsVersionComparator.h"
-#include "nsNullPrincipal.h"
+#include "NullPrincipal.h"
 
 #if defined(XP_WIN)
 #include "nsIWindowMediator.h"
 #include "nsIBaseWindow.h"
 #include "windows.h"
 #include "winbase.h"
 #endif
 
--- a/dom/plugins/base/nsPluginStreamListenerPeer.cpp
+++ b/dom/plugins/base/nsPluginStreamListenerPeer.cpp
@@ -28,17 +28,17 @@
 #include "nsIDocument.h"
 #include "nsIWebNavigation.h"
 #include "nsContentUtils.h"
 #include "nsNetUtil.h"
 #include "nsPluginNativeWindow.h"
 #include "GeckoProfiler.h"
 #include "nsPluginInstanceOwner.h"
 #include "nsDataHashtable.h"
-#include "nsNullPrincipal.h"
+#include "NullPrincipal.h"
 
 #define BYTERANGE_REQUEST_CONTEXT 0x01020304
 
 // nsPluginByteRangeStreamListener
 
 class nsPluginByteRangeStreamListener
   : public nsIStreamListener
   , public nsIInterfaceRequestor
--- a/dom/quota/ActorsChild.cpp
+++ b/dom/quota/ActorsChild.cpp
@@ -4,16 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "ActorsChild.h"
 
 #include "nsVariant.h"
 #include "QuotaManagerService.h"
 #include "QuotaRequests.h"
+#include "QuotaResults.h"
 
 namespace mozilla {
 namespace dom {
 namespace quota {
 
 /*******************************************************************************
  * QuotaChild
  ******************************************************************************/
@@ -136,24 +137,66 @@ QuotaUsageRequestChild::HandleResponse(n
   AssertIsOnOwningThread();
   MOZ_ASSERT(NS_FAILED(aResponse));
   MOZ_ASSERT(mRequest);
 
   mRequest->SetError(aResponse);
 }
 
 void
-QuotaUsageRequestChild::HandleResponse(const UsageResponse& aResponse)
+QuotaUsageRequestChild::HandleResponse(const nsTArray<OriginUsage>& aResponse)
 {
   AssertIsOnOwningThread();
   MOZ_ASSERT(mRequest);
 
-  mRequest->SetResult(aResponse.usage(),
-                      aResponse.fileUsage(),
-                      aResponse.limit());
+  RefPtr<nsVariant> variant = new nsVariant();
+
+  if (aResponse.IsEmpty()) {
+    variant->SetAsEmptyArray();
+  } else {
+    nsTArray<RefPtr<UsageResult>> usageResults;
+
+    const uint32_t count = aResponse.Length();
+
+    usageResults.SetCapacity(count);
+
+    for (uint32_t index = 0; index < count; index++) {
+      auto& originUsage = aResponse[index];
+
+      RefPtr<UsageResult> usageResult = new UsageResult(originUsage.origin(),
+                                                        originUsage.persisted(),
+                                                        originUsage.usage());
+
+      usageResults.AppendElement(usageResult.forget());
+    }
+
+    variant->SetAsArray(nsIDataType::VTYPE_INTERFACE_IS,
+                        &NS_GET_IID(nsIQuotaUsageResult),
+                        usageResults.Length(),
+                        static_cast<void*>(usageResults.Elements()));
+  }
+
+  mRequest->SetResult(variant);
+}
+
+void
+QuotaUsageRequestChild::HandleResponse(const OriginUsageResponse& aResponse)
+{
+  AssertIsOnOwningThread();
+  MOZ_ASSERT(mRequest);
+
+  RefPtr<OriginUsageResult> result =
+    new OriginUsageResult(aResponse.usage(),
+                          aResponse.fileUsage(),
+                          aResponse.limit());
+
+  RefPtr<nsVariant> variant = new nsVariant();
+  variant->SetAsInterface(NS_GET_IID(nsIQuotaOriginUsageResult), result);
+
+  mRequest->SetResult(variant);
 }
 
 void
 QuotaUsageRequestChild::ActorDestroy(ActorDestroyReason aWhy)
 {
   AssertIsOnOwningThread();
 
   if (mRequest) {
@@ -170,18 +213,22 @@ QuotaUsageRequestChild::Recv__delete__(c
   AssertIsOnOwningThread();
   MOZ_ASSERT(mRequest);
 
   switch (aResponse.type()) {
     case UsageRequestResponse::Tnsresult:
       HandleResponse(aResponse.get_nsresult());
       break;
 
-    case UsageRequestResponse::TUsageResponse:
-      HandleResponse(aResponse.get_UsageResponse());
+    case UsageRequestResponse::TAllUsageResponse:
+      HandleResponse(aResponse.get_AllUsageResponse().originUsages());
+      break;
+
+    case UsageRequestResponse::TOriginUsageResponse:
+      HandleResponse(aResponse.get_OriginUsageResponse());
       break;
 
     default:
       MOZ_CRASH("Unknown response type!");
   }
 
   return IPC_OK();
 }
--- a/dom/quota/ActorsChild.h
+++ b/dom/quota/ActorsChild.h
@@ -93,17 +93,20 @@ private:
 
   // Only destroyed by QuotaChild.
   ~QuotaUsageRequestChild();
 
   void
   HandleResponse(nsresult aResponse);
 
   void
-  HandleResponse(const UsageResponse& aResponse);
+  HandleResponse(const nsTArray<OriginUsage>& aResponse);
+
+  void
+  HandleResponse(const OriginUsageResponse& aResponse);
 
   // IPDL methods are only called by IPDL.
   virtual void
   ActorDestroy(ActorDestroyReason aWhy) override;
 
   virtual mozilla::ipc::IPCResult
   Recv__delete__(const UsageRequestResponse& aResponse) override;
 };
--- a/dom/quota/ActorsParent.cpp
+++ b/dom/quota/ActorsParent.cpp
@@ -910,16 +910,17 @@ class NormalOriginOperationBase
   : public OriginOperationBase
   , public OpenDirectoryListener
 {
   RefPtr<DirectoryLock> mDirectoryLock;
 
 protected:
   Nullable<PersistenceType> mPersistenceType;
   OriginScope mOriginScope;
+  mozilla::Atomic<bool> mCanceled;
   const bool mExclusive;
 
 public:
   void
   RunImmediately()
   {
     MOZ_ASSERT(GetState() == State_Initial);
 
@@ -1037,59 +1038,113 @@ private:
 
   virtual mozilla::ipc::IPCResult
   RecvStartIdleMaintenance() override;
 
   virtual mozilla::ipc::IPCResult
   RecvStopIdleMaintenance() override;
 };
 
-class GetUsageOp final
+class QuotaUsageRequestBase
   : public NormalOriginOperationBase
   , public PQuotaUsageRequestParent
 {
+public:
+  // May be overridden by subclasses if they need to perform work on the
+  // background thread before being run.
+  virtual bool
+  Init(Quota* aQuota);
+
+protected:
+  QuotaUsageRequestBase()
+    : NormalOriginOperationBase(Nullable<PersistenceType>(),
+                                OriginScope::FromNull(),
+                                /* aExclusive */ false)
+  { }
+
+  nsresult
+  GetUsageForOrigin(QuotaManager* aQuotaManager,
+                    PersistenceType aPersistenceType,
+                    const nsACString& aGroup,
+                    const nsACString& aOrigin,
+                    UsageInfo* aUsageInfo);
+
+  // Subclasses use this override to set the IPDL response value.
+  virtual void
+  GetResponse(UsageRequestResponse& aResponse) = 0;
+
+private:
+  void
+  SendResults() override;
+
+  // IPDL methods.
+  void
+  ActorDestroy(ActorDestroyReason aWhy) override;
+
+  mozilla::ipc::IPCResult
+  RecvCancel() override;
+};
+
+class GetUsageOp final
+  : public QuotaUsageRequestBase
+{
+  nsTArray<OriginUsage> mOriginUsages;
+  nsDataHashtable<nsCStringHashKey, uint32_t> mOriginUsagesIndex;
+
+  bool mGetAll;
+
+public:
+  explicit GetUsageOp(const UsageRequestParams& aParams);
+
+private:
+  ~GetUsageOp()
+  { }
+
+  nsresult
+  TraverseRepository(QuotaManager* aQuotaManager,
+                     PersistenceType aPersistenceType);
+
+  nsresult
+  DoDirectoryWork(QuotaManager* aQuotaManager) override;
+
+  void
+  GetResponse(UsageRequestResponse& aResponse) override;
+};
+
+class GetOriginUsageOp final
+  : public QuotaUsageRequestBase
+{
   // If mGetGroupUsage is false, we use mUsageInfo to record the origin usage
   // and the file usage. Otherwise, we use it to record the group usage and the
   // limit.
   UsageInfo mUsageInfo;
 
-  const UsageParams mParams;
+  const OriginUsageParams mParams;
   nsCString mSuffix;
   nsCString mGroup;
   bool mGetGroupUsage;
 
 public:
-  explicit GetUsageOp(const UsageRequestParams& aParams);
+  explicit GetOriginUsageOp(const UsageRequestParams& aParams);
 
   MOZ_IS_CLASS_INIT bool
-  Init(Quota* aQuota);
+  Init(Quota* aQuota) override;
 
 private:
-  ~GetUsageOp()
+  ~GetOriginUsageOp()
   { }
 
   MOZ_IS_CLASS_INIT virtual nsresult
   DoInitOnMainThread() override;
 
-  nsresult
-  AddToUsage(QuotaManager* aQuotaManager,
-             PersistenceType aPersistenceType);
-
   virtual nsresult
   DoDirectoryWork(QuotaManager* aQuotaManager) override;
 
-  virtual void
-  SendResults() override;
-
-  // IPDL methods.
-  virtual void
-  ActorDestroy(ActorDestroyReason aWhy) override;
-
-  virtual mozilla::ipc::IPCResult
-  RecvCancel() override;
+  void
+  GetResponse(UsageRequestResponse& aResponse) override;
 };
 
 class QuotaRequestBase
   : public NormalOriginOperationBase
   , public PQuotaRequestParent
 {
 public:
   // May be overridden by subclasses if they need to perform work on the
@@ -4191,17 +4246,21 @@ QuotaManager::InitializeOrigin(Persisten
 
     Client::Type clientType;
     rv = Client::TypeFromText(leafName, clientType);
     if (NS_FAILED(rv)) {
       UNKNOWN_FILE_WARNING(leafName);
       return NS_ERROR_UNEXPECTED;
     }
 
-    rv = mClients[clientType]->InitOrigin(aPersistenceType, aGroup, aOrigin,
+    Atomic<bool> dummy(false);
+    rv = mClients[clientType]->InitOrigin(aPersistenceType,
+                                          aGroup,
+                                          aOrigin,
+                                          /* aCanceled */ dummy,
                                           usageInfo);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   if (trackQuota) {
     InitQuotaForOrigin(aPersistenceType, aGroup, aOrigin,
                        usageInfo->TotalUsage(), aAccessTime, aPersisted);
   }
@@ -5291,20 +5350,19 @@ QuotaManager::GetInfoForChrome(nsACStrin
   }
   if (aOrigin) {
     ChromeOrigin(*aOrigin);
   }
 }
 
 // static
 bool
-QuotaManager::IsOriginWhitelistedForPersistentStorage(const nsACString& aOrigin)
-{
-  // The first prompt and quota tracking is not required for these origins in
-  // persistent storage.
+QuotaManager::IsOriginInternal(const nsACString& aOrigin)
+{
+  // The first prompt is not required for these origins.
   if (aOrigin.EqualsLiteral(kChromeOrigin) ||
       StringBeginsWith(aOrigin, nsDependentCString(kAboutHomeOriginPrefix)) ||
       StringBeginsWith(aOrigin, nsDependentCString(kIndexedDBOriginPrefix)) ||
       StringBeginsWith(aOrigin, nsDependentCString(kResourceOriginPrefix))) {
     return true;
   }
 
   return false;
@@ -6225,49 +6283,67 @@ Quota::ActorDestroy(ActorDestroyReason a
   MOZ_ASSERT(!mActorDestroyed);
   mActorDestroyed = true;
 #endif
 }
 
 PQuotaUsageRequestParent*
 Quota::AllocPQuotaUsageRequestParent(const UsageRequestParams& aParams)
 {
-  RefPtr<GetUsageOp> actor = new GetUsageOp(aParams);
+  AssertIsOnBackgroundThread();
+  MOZ_ASSERT(aParams.type() != UsageRequestParams::T__None);
+
+  RefPtr<QuotaUsageRequestBase> actor;
+
+  switch (aParams.type()) {
+    case UsageRequestParams::TAllUsageParams:
+      actor = new GetUsageOp(aParams);
+      break;
+
+    case UsageRequestParams::TOriginUsageParams:
+      actor = new GetOriginUsageOp(aParams);
+      break;
+
+    default:
+      MOZ_CRASH("Should never get here!");
+  }
+
+  MOZ_ASSERT(actor);
 
   // Transfer ownership to IPDL.
   return actor.forget().take();
 }
 
 mozilla::ipc::IPCResult
 Quota::RecvPQuotaUsageRequestConstructor(PQuotaUsageRequestParent* aActor,
                                          const UsageRequestParams& aParams)
 {
   AssertIsOnBackgroundThread();
   MOZ_ASSERT(aActor);
   MOZ_ASSERT(aParams.type() != UsageRequestParams::T__None);
 
-  auto* op = static_cast<GetUsageOp*>(aActor);
+  auto* op = static_cast<QuotaUsageRequestBase*>(aActor);
 
   if (NS_WARN_IF(!op->Init(this))) {
     return IPC_FAIL_NO_REASON(this);
   }
 
   op->RunImmediately();
   return IPC_OK();
 }
 
 bool
 Quota::DeallocPQuotaUsageRequestParent(PQuotaUsageRequestParent* aActor)
 {
   AssertIsOnBackgroundThread();
   MOZ_ASSERT(aActor);
 
   // Transfer ownership back from IPDL.
-  RefPtr<GetUsageOp> actor =
-    dont_AddRef(static_cast<GetUsageOp*>(aActor));
+  RefPtr<QuotaUsageRequestBase> actor =
+    dont_AddRef(static_cast<QuotaUsageRequestBase*>(aActor));
   return true;
 }
 
 PQuotaRequestParent*
 Quota::AllocPQuotaRequestParent(const RequestParams& aParams)
 {
   AssertIsOnBackgroundThread();
   MOZ_ASSERT(aParams.type() != RequestParams::T__None);
@@ -6331,16 +6407,17 @@ mozilla::ipc::IPCResult
 Quota::RecvPQuotaRequestConstructor(PQuotaRequestParent* aActor,
                                     const RequestParams& aParams)
 {
   AssertIsOnBackgroundThread();
   MOZ_ASSERT(aActor);
   MOZ_ASSERT(aParams.type() != RequestParams::T__None);
 
   auto* op = static_cast<QuotaRequestBase*>(aActor);
+
   if (NS_WARN_IF(!op->Init(this))) {
     return IPC_FAIL_NO_REASON(this);
   }
 
   op->RunImmediately();
   return IPC_OK();
 }
 
@@ -6409,103 +6486,67 @@ Quota::RecvStopIdleMaintenance()
     return IPC_OK();
   }
 
   quotaManager->StopIdleMaintenance();
 
   return IPC_OK();
 }
 
-GetUsageOp::GetUsageOp(const UsageRequestParams& aParams)
-  : NormalOriginOperationBase(Nullable<PersistenceType>(),
-                              OriginScope::FromNull(),
-                              /* aExclusive */ false)
-  , mParams(aParams.get_UsageParams())
-  , mGetGroupUsage(aParams.get_UsageParams().getGroupUsage())
-{
-  AssertIsOnOwningThread();
-  MOZ_ASSERT(aParams.type() == UsageRequestParams::TUsageParams);
-}
-
 bool
-GetUsageOp::Init(Quota* aQuota)
+QuotaUsageRequestBase::Init(Quota* aQuota)
 {
   AssertIsOnOwningThread();
   MOZ_ASSERT(aQuota);
 
-  mNeedsMainThreadInit = true;
   mNeedsQuotaManagerInit = true;
 
   return true;
 }
 
 nsresult
-GetUsageOp::DoInitOnMainThread()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(GetState() == State_Initializing);
-  MOZ_ASSERT(mNeedsMainThreadInit);
-
-  const PrincipalInfo& principalInfo = mParams.principalInfo();
-
-  nsresult rv;
-  nsCOMPtr<nsIPrincipal> principal =
-    PrincipalInfoToPrincipal(principalInfo, &rv);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  // Figure out which origin we're dealing with.
-  nsCString origin;
-  rv = QuotaManager::GetInfoFromPrincipal(principal, &mSuffix, &mGroup,
-                                          &origin);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  mOriginScope.SetFromOrigin(origin);
-
-  return NS_OK;
-}
-
-nsresult
-GetUsageOp::AddToUsage(QuotaManager* aQuotaManager,
-                       PersistenceType aPersistenceType)
+QuotaUsageRequestBase::GetUsageForOrigin(QuotaManager* aQuotaManager,
+                                         PersistenceType aPersistenceType,
+                                         const nsACString& aGroup,
+                                         const nsACString& aOrigin,
+                                         UsageInfo* aUsageInfo)
 {
   AssertIsOnIOThread();
+  MOZ_ASSERT(aQuotaManager);
+  MOZ_ASSERT(aUsageInfo);
+  MOZ_ASSERT(aUsageInfo->TotalUsage() == 0);
 
   nsCOMPtr<nsIFile> directory;
   nsresult rv = aQuotaManager->GetDirectoryForOrigin(aPersistenceType,
-                                                     mOriginScope.GetOrigin(),
+                                                     aOrigin,
                                                      getter_AddRefs(directory));
   NS_ENSURE_SUCCESS(rv, rv);
 
   bool exists;
   rv = directory->Exists(&exists);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // If the directory exists then enumerate all the files inside, adding up
   // the sizes to get the final usage statistic.
-  if (exists && !mUsageInfo.Canceled()) {
+  if (exists && !mCanceled) {
     bool initialized;
 
     if (aPersistenceType == PERSISTENCE_TYPE_PERSISTENT) {
-      initialized =
-        aQuotaManager->IsOriginInitialized(mOriginScope.GetOrigin());
+      initialized = aQuotaManager->IsOriginInitialized(aOrigin);
     } else {
       initialized = aQuotaManager->IsTemporaryStorageInitialized();
     }
 
     nsCOMPtr<nsISimpleEnumerator> entries;
     rv = directory->GetDirectoryEntries(getter_AddRefs(entries));
     NS_ENSURE_SUCCESS(rv, rv);
 
     bool hasMore;
     while (NS_SUCCEEDED((rv = entries->HasMoreElements(&hasMore))) &&
-           hasMore && !mUsageInfo.Canceled()) {
+           hasMore && !mCanceled) {
       nsCOMPtr<nsISupports> entry;
       rv = entries->GetNext(getter_AddRefs(entry));
       NS_ENSURE_SUCCESS(rv, rv);
 
       nsCOMPtr<nsIFile> file = do_QueryInterface(entry);
       NS_ENSURE_TRUE(file, NS_NOINTERFACE);
 
       bool isDirectory;
@@ -6557,44 +6598,319 @@ GetUsageOp::AddToUsage(QuotaManager* aQu
         continue;
       }
 
       Client* client = aQuotaManager->GetClient(clientType);
       MOZ_ASSERT(client);
 
       if (initialized) {
         rv = client->GetUsageForOrigin(aPersistenceType,
-                                       mGroup,
-                                       mOriginScope.GetOrigin(),
-                                       &mUsageInfo);
+                                       aGroup,
+                                       aOrigin,
+                                       mCanceled,
+                                       aUsageInfo);
       }
       else {
         rv = client->InitOrigin(aPersistenceType,
-                                mGroup,
-                                mOriginScope.GetOrigin(),
-                                &mUsageInfo);
+                                aGroup,
+                                aOrigin,
+                                mCanceled,
+                                aUsageInfo);
       }
       NS_ENSURE_SUCCESS(rv, rv);
     }
   }
 
   return NS_OK;
 }
 
+void
+QuotaUsageRequestBase::SendResults()
+{
+  AssertIsOnOwningThread();
+
+  if (IsActorDestroyed()) {
+    if (NS_SUCCEEDED(mResultCode)) {
+      mResultCode = NS_ERROR_FAILURE;
+    }
+  } else {
+    if (mCanceled) {
+      mResultCode = NS_ERROR_FAILURE;
+    }
+
+    UsageRequestResponse response;
+
+    if (NS_SUCCEEDED(mResultCode)) {
+      GetResponse(response);
+    } else {
+      response = mResultCode;
+    }
+
+    Unused << PQuotaUsageRequestParent::Send__delete__(this, response);
+  }
+}
+
+void
+QuotaUsageRequestBase::ActorDestroy(ActorDestroyReason aWhy)
+{
+  AssertIsOnOwningThread();
+
+  NoteActorDestroyed();
+}
+
+mozilla::ipc::IPCResult
+QuotaUsageRequestBase::RecvCancel()
+{
+  AssertIsOnOwningThread();
+
+  if (mCanceled.exchange(true)) {
+    NS_WARNING("Canceled more than once?!");
+    return IPC_FAIL_NO_REASON(this);
+  }
+
+  return IPC_OK();
+}
+
+GetUsageOp::GetUsageOp(const UsageRequestParams& aParams)
+  : mGetAll(aParams.get_AllUsageParams().getAll())
+{
+  AssertIsOnOwningThread();
+  MOZ_ASSERT(aParams.type() == UsageRequestParams::TAllUsageParams);
+}
+
+nsresult
+GetUsageOp::TraverseRepository(QuotaManager* aQuotaManager,
+                               PersistenceType aPersistenceType)
+{
+  AssertIsOnIOThread();
+  MOZ_ASSERT(aQuotaManager);
+
+  nsresult rv;
+
+  nsCOMPtr<nsIFile> directory =
+    do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  rv = directory->InitWithPath(aQuotaManager->GetStoragePath(aPersistenceType));
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  bool exists;
+  rv = directory->Exists(&exists);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  if (!exists) {
+    return NS_OK;
+  }
+
+  nsCOMPtr<nsISimpleEnumerator> entries;
+  rv = directory->GetDirectoryEntries(getter_AddRefs(entries));
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  bool persistent = aPersistenceType == PERSISTENCE_TYPE_PERSISTENT;
+
+  bool hasMore;
+  while (NS_SUCCEEDED((rv = entries->HasMoreElements(&hasMore))) &&
+         hasMore && !mCanceled) {
+    nsCOMPtr<nsISupports> entry;
+    rv = entries->GetNext(getter_AddRefs(entry));
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
+
+    nsCOMPtr<nsIFile> originDir = do_QueryInterface(entry);
+    MOZ_ASSERT(originDir);
+
+    bool isDirectory;
+    rv = originDir->IsDirectory(&isDirectory);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
+
+    if (!isDirectory) {
+      nsString leafName;
+      rv = originDir->GetLeafName(leafName);
+      if (NS_WARN_IF(NS_FAILED(rv))) {
+        return rv;
+      }
+
+      if (!IsOSMetadata(leafName)) {
+        UNKNOWN_FILE_WARNING(leafName);
+      }
+      continue;
+    }
+
+    int64_t timestamp;
+    bool persisted;
+    nsCString suffix;
+    nsCString group;
+    nsCString origin;
+    rv = aQuotaManager->GetDirectoryMetadata2WithRestore(originDir,
+                                                         persistent,
+                                                         &timestamp,
+                                                         &persisted,
+                                                         suffix,
+                                                         group,
+                                                         origin);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
+
+    if (!mGetAll && aQuotaManager->IsOriginInternal(origin)) {
+      continue;
+    }
+
+    OriginUsage* originUsage;
+
+    // We can't store pointers to OriginUsage objects in the hashtable
+    // since AppendElement() reallocates its internal array buffer as number
+    // of elements grows.
+    uint32_t index;
+    if (mOriginUsagesIndex.Get(origin, &index)) {
+      originUsage = &mOriginUsages[index];
+    } else {
+      index = mOriginUsages.Length();
+
+      originUsage = mOriginUsages.AppendElement();
+
+      originUsage->origin() = origin;
+      originUsage->persisted() = false;
+      originUsage->usage() = 0;
+
+      mOriginUsagesIndex.Put(origin, index);
+    }
+
+    if (aPersistenceType == PERSISTENCE_TYPE_DEFAULT) {
+      originUsage->persisted() = persisted;
+    }
+
+    UsageInfo usageInfo;
+    rv = GetUsageForOrigin(aQuotaManager,
+                           aPersistenceType,
+                           group,
+                           origin,
+                           &usageInfo);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
+
+    originUsage->usage() = originUsage->usage() + usageInfo.TotalUsage();
+  }
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  return NS_OK;
+}
+
 nsresult
 GetUsageOp::DoDirectoryWork(QuotaManager* aQuotaManager)
 {
   AssertIsOnIOThread();
-  MOZ_ASSERT(mUsageInfo.TotalUsage() == 0);
 
   PROFILER_LABEL("Quota", "GetUsageOp::DoDirectoryWork",
                  js::ProfileEntry::Category::OTHER);
 
   nsresult rv;
 
+  for (const PersistenceType type : kAllPersistenceTypes) {
+    rv = TraverseRepository(aQuotaManager, type);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
+  }
+
+  return NS_OK;
+}
+
+void
+GetUsageOp::GetResponse(UsageRequestResponse& aResponse)
+{
+  AssertIsOnOwningThread();
+
+  aResponse = AllUsageResponse();
+
+  if (!mOriginUsages.IsEmpty()) {
+    nsTArray<OriginUsage>& originUsages =
+      aResponse.get_AllUsageResponse().originUsages();
+
+    mOriginUsages.SwapElements(originUsages);
+  }
+}
+
+GetOriginUsageOp::GetOriginUsageOp(const UsageRequestParams& aParams)
+  : mParams(aParams.get_OriginUsageParams())
+  , mGetGroupUsage(aParams.get_OriginUsageParams().getGroupUsage())
+{
+  AssertIsOnOwningThread();
+  MOZ_ASSERT(aParams.type() == UsageRequestParams::TOriginUsageParams);
+}
+
+bool
+GetOriginUsageOp::Init(Quota* aQuota)
+{
+  AssertIsOnOwningThread();
+  MOZ_ASSERT(aQuota);
+
+  if (NS_WARN_IF(!QuotaUsageRequestBase::Init(aQuota))) {
+    return false;
+  }
+
+  mNeedsMainThreadInit = true;
+
+  return true;
+}
+
+nsresult
+GetOriginUsageOp::DoInitOnMainThread()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(GetState() == State_Initializing);
+  MOZ_ASSERT(mNeedsMainThreadInit);
+
+  const PrincipalInfo& principalInfo = mParams.principalInfo();
+
+  nsresult rv;
+  nsCOMPtr<nsIPrincipal> principal =
+    PrincipalInfoToPrincipal(principalInfo, &rv);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  // Figure out which origin we're dealing with.
+  nsCString origin;
+  rv = QuotaManager::GetInfoFromPrincipal(principal, &mSuffix, &mGroup,
+                                          &origin);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  mOriginScope.SetFromOrigin(origin);
+
+  return NS_OK;
+}
+
+nsresult
+GetOriginUsageOp::DoDirectoryWork(QuotaManager* aQuotaManager)
+{
+  AssertIsOnIOThread();
+  MOZ_ASSERT(mUsageInfo.TotalUsage() == 0);
+
+  PROFILER_LABEL("Quota", "GetOriginUsageOp::DoDirectoryWork",
+                 js::ProfileEntry::Category::OTHER);
+
+  nsresult rv;
+
   if (mGetGroupUsage) {
     nsCOMPtr<nsIFile> directory;
 
     // Ensure origin is initialized first. It will initialize all origins for
     // temporary storage including origins belonging to our group.
     rv = aQuotaManager->EnsureOriginIsInitialized(PERSISTENCE_TYPE_TEMPORARY,
                                                   mSuffix, mGroup,
                                                   mOriginScope.GetOrigin(),
@@ -6606,82 +6922,50 @@ GetUsageOp::DoDirectoryWork(QuotaManager
     // Get cached usage and limit (the method doesn't have to stat any files).
     aQuotaManager->GetGroupUsageAndLimit(mGroup, &mUsageInfo);
 
     return NS_OK;
   }
 
   // Add all the persistent/temporary/default storage files we care about.
   for (const PersistenceType type : kAllPersistenceTypes) {
-    rv = AddToUsage(aQuotaManager, type);
+    UsageInfo usageInfo;
+    rv = GetUsageForOrigin(aQuotaManager,
+                           type,
+                           mGroup,
+                           mOriginScope.GetOrigin(),
+                           &usageInfo);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
+
+    mUsageInfo.Append(usageInfo);
   }
 
   return NS_OK;
 }
 
 void
-GetUsageOp::SendResults()
+GetOriginUsageOp::GetResponse(UsageRequestResponse& aResponse)
 {
   AssertIsOnOwningThread();
 
-  if (IsActorDestroyed()) {
-    if (NS_SUCCEEDED(mResultCode)) {
-      mResultCode = NS_ERROR_FAILURE;
-    }
+  OriginUsageResponse usageResponse;
+
+  // We'll get the group usage when mGetGroupUsage is true and get the
+  // origin usage when mGetGroupUsage is false.
+  usageResponse.usage() = mUsageInfo.TotalUsage();
+
+  if (mGetGroupUsage) {
+    usageResponse.limit() = mUsageInfo.Limit();
   } else {
-    if (mUsageInfo.Canceled()) {
-      mResultCode = NS_ERROR_FAILURE;
-    }
-
-    UsageRequestResponse response;
-
-    if (NS_SUCCEEDED(mResultCode)) {
-      UsageResponse usageResponse;
-
-      // We'll get the group usage when mGetGroupUsage is true and get the
-      // origin usage when mGetGroupUsage is false.
-      usageResponse.usage() = mUsageInfo.TotalUsage();
-
-      if (mGetGroupUsage) {
-        usageResponse.limit() = mUsageInfo.Limit();
-      } else {
-        usageResponse.fileUsage() = mUsageInfo.FileUsage();
-      }
-
-      response = usageResponse;
-    } else {
-      response = mResultCode;
-    }
-
-    Unused << PQuotaUsageRequestParent::Send__delete__(this, response);
-  }
-}
-
-void
-GetUsageOp::ActorDestroy(ActorDestroyReason aWhy)
-{
-  AssertIsOnOwningThread();
-
-  NoteActorDestroyed();
-}
-
-mozilla::ipc::IPCResult
-GetUsageOp::RecvCancel()
-{
-  AssertIsOnOwningThread();
-
-  nsresult rv = mUsageInfo.Cancel();
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return IPC_FAIL_NO_REASON(this);
-  }
-
-  return IPC_OK();
+    usageResponse.fileUsage() = mUsageInfo.FileUsage();
+  }
+
+  aResponse = usageResponse;
 }
 
 bool
 QuotaRequestBase::Init(Quota* aQuota)
 {
   AssertIsOnOwningThread();
   MOZ_ASSERT(aQuota);
 
@@ -8180,19 +8464,17 @@ CreateOrUpgradeDirectoryMetadataHelper::
       if (NS_FAILED(rv)) {
         originProps.mTimestamp = GetLastModifiedTime(originDir, mPersistent);
         originProps.mNeedsRestore = true;
       } else if (!isApp.IsNull()) {
         originProps.mIgnore = true;
       }
     }
     else {
-      bool persistent =
-        QuotaManager::IsOriginWhitelistedForPersistentStorage(
-                                                             originProps.mSpec);
+      bool persistent = QuotaManager::IsOriginInternal(originProps.mSpec);
       originProps.mTimestamp = GetLastModifiedTime(originDir, persistent);
     }
 
     mOriginProps.AppendElement(Move(originProps));
   }
 
   if (mOriginProps.IsEmpty()) {
     return NS_OK;
@@ -8326,19 +8608,18 @@ CreateOrUpgradeDirectoryMetadataHelper::
                                  aOriginProps.mTimestamp,
                                  aOriginProps.mSuffix,
                                  aOriginProps.mGroup,
                                  aOriginProps.mOrigin);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
 
-    // Move whitelisted origins to new persistent storage.
-    if (QuotaManager::IsOriginWhitelistedForPersistentStorage(
-                                                          aOriginProps.mSpec)) {
+    // Move internal origins to new persistent storage.
+    if (QuotaManager::IsOriginInternal(aOriginProps.mSpec)) {
       if (!mPermanentStorageDir) {
         mPermanentStorageDir =
           do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv);
         if (NS_WARN_IF(NS_FAILED(rv))) {
           return rv;
         }
 
         QuotaManager* quotaManager = QuotaManager::Get();
--- a/dom/quota/Client.h
+++ b/dom/quota/Client.h
@@ -26,16 +26,18 @@ class QuotaManager;
 class UsageInfo;
 
 // An abstract interface for quota manager clients.
 // Each storage API must provide an implementation of this interface in order
 // to participate in centralized quota and storage handling.
 class Client
 {
 public:
+  typedef mozilla::Atomic<bool> AtomicBool;
+
   NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
 
   enum Type {
     IDB = 0,
     //LS,
     //APPCACHE,
     ASMJS,
     DOMCACHE,
@@ -95,22 +97,24 @@ public:
   {
     return NS_OK;
   }
 
   virtual nsresult
   InitOrigin(PersistenceType aPersistenceType,
              const nsACString& aGroup,
              const nsACString& aOrigin,
+             const AtomicBool& aCanceled,
              UsageInfo* aUsageInfo) = 0;
 
   virtual nsresult
   GetUsageForOrigin(PersistenceType aPersistenceType,
                     const nsACString& aGroup,
                     const nsACString& aOrigin,
+                    const AtomicBool& aCanceled,
                     UsageInfo* aUsageInfo) = 0;
 
   virtual void
   OnOriginClearCompleted(PersistenceType aPersistenceType,
                          const nsACString& aOrigin) = 0;
 
   virtual void
   ReleaseIOThreadObjects() = 0;
--- a/dom/quota/PQuota.ipdl
+++ b/dom/quota/PQuota.ipdl
@@ -22,25 +22,31 @@ struct InitParams
 };
 
 struct InitOriginParams
 {
   PrincipalInfo principalInfo;
   PersistenceType persistenceType;
 };
 
-struct UsageParams
+struct AllUsageParams
+{
+  bool getAll;
+};
+
+struct OriginUsageParams
 {
   PrincipalInfo principalInfo;
   bool getGroupUsage;
 };
 
 union UsageRequestParams
 {
-  UsageParams;
+  AllUsageParams;
+  OriginUsageParams;
 };
 
 struct ClearOriginParams
 {
   PrincipalInfo principalInfo;
   PersistenceType persistenceType;
   bool persistenceTypeIsExplicit;
   bool clearAll;
--- a/dom/quota/PQuotaUsageRequest.ipdl
+++ b/dom/quota/PQuotaUsageRequest.ipdl
@@ -3,27 +3,40 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 include protocol PQuota;
 
 namespace mozilla {
 namespace dom {
 namespace quota {
 
-struct UsageResponse
+struct OriginUsage
+{
+  nsCString origin;
+  bool persisted;
+  uint64_t usage;
+};
+
+struct AllUsageResponse
+{
+  OriginUsage[] originUsages;
+};
+
+struct OriginUsageResponse
 {
   uint64_t usage;
   uint64_t fileUsage;
   uint64_t limit;
 };
 
 union UsageRequestResponse
 {
   nsresult;
-  UsageResponse;
+  AllUsageResponse;
+  OriginUsageResponse;
 };
 
 protocol PQuotaUsageRequest
 {
   manager PQuota;
 
 parent:
   async Cancel();
--- a/dom/quota/QuotaManager.h
+++ b/dom/quota/QuotaManager.h
@@ -393,17 +393,17 @@ public:
                     nsACString* aOrigin);
 
   static void
   GetInfoForChrome(nsACString* aSuffix,
                    nsACString* aGroup,
                    nsACString* aOrigin);
 
   static bool
-  IsOriginWhitelistedForPersistentStorage(const nsACString& aOrigin);
+  IsOriginInternal(const nsACString& aOrigin);
 
   static void
   ChromeOrigin(nsACString& aOrigin);
 
   static bool
   AreOriginsEqualOnDisk(nsACString& aOrigin1,
                         nsACString& aOrigin2);
 
--- a/dom/quota/QuotaManagerService.cpp
+++ b/dom/quota/QuotaManagerService.cpp
@@ -580,28 +580,53 @@ QuotaManagerService::InitStoragesForPrin
     return rv;
   }
 
   request.forget(_retval);
   return NS_OK;
 }
 
 NS_IMETHODIMP
+QuotaManagerService::GetUsage(nsIQuotaUsageCallback* aCallback,
+                              bool aGetAll,
+                              nsIQuotaUsageRequest** _retval)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(aCallback);
+
+  RefPtr<UsageRequest> request = new UsageRequest(aCallback);
+
+  AllUsageParams params;
+
+  params.getAll() = aGetAll;
+
+  nsAutoPtr<PendingRequestInfo> info(new UsageRequestInfo(request, params));
+
+  nsresult rv = InitiateRequest(info);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  request.forget(_retval);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 QuotaManagerService::GetUsageForPrincipal(nsIPrincipal* aPrincipal,
                                           nsIQuotaUsageCallback* aCallback,
                                           bool aGetGroupUsage,
                                           nsIQuotaUsageRequest** _retval)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aPrincipal);
   MOZ_ASSERT(aCallback);
 
   RefPtr<UsageRequest> request = new UsageRequest(aPrincipal, aCallback);
 
-  UsageParams params;
+  OriginUsageParams params;
 
   nsresult rv = CheckedPrincipalToPrincipalInfo(aPrincipal,
                                                 params.principalInfo());
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   params.getGroupUsage() = aGetGroupUsage;
--- a/dom/quota/QuotaRequests.cpp
+++ b/dom/quota/QuotaRequests.cpp
@@ -86,23 +86,29 @@ RequestBase::GetResultCode(nsresult* aRe
   if (!mHaveResultOrErrorCode) {
     return NS_ERROR_FAILURE;
   }
 
   *aResultCode = mResultCode;
   return NS_OK;
 }
 
+UsageRequest::UsageRequest(nsIQuotaUsageCallback* aCallback)
+  : mCallback(aCallback)
+  , mBackgroundActor(nullptr)
+  , mCanceled(false)
+{
+  AssertIsOnOwningThread();
+  MOZ_ASSERT(aCallback);
+}
+
 UsageRequest::UsageRequest(nsIPrincipal* aPrincipal,
                            nsIQuotaUsageCallback* aCallback)
   : RequestBase(aPrincipal)
   , mCallback(aCallback)
-  , mUsage(0)
-  , mFileUsage(0)
-  , mLimit(0)
   , mBackgroundActor(nullptr)
   , mCanceled(false)
 {
   AssertIsOnOwningThread();
   MOZ_ASSERT(aPrincipal);
   MOZ_ASSERT(aCallback);
 }
 
@@ -121,76 +127,51 @@ UsageRequest::SetBackgroundActor(QuotaUs
   mBackgroundActor = aBackgroundActor;
 
   if (mCanceled) {
     mBackgroundActor->SendCancel();
   }
 }
 
 void
-UsageRequest::SetResult(uint64_t aUsage, uint64_t aFileUsage, uint64_t aLimit)
+UsageRequest::SetResult(nsIVariant* aResult)
 {
   AssertIsOnOwningThread();
+  MOZ_ASSERT(aResult);
   MOZ_ASSERT(!mHaveResultOrErrorCode);
 
-  mUsage = aUsage;
-  mFileUsage = aFileUsage;
-  mLimit = aLimit;
+  mResult = aResult;
+
   mHaveResultOrErrorCode = true;
 
   FireCallback();
 }
 
 NS_IMPL_CYCLE_COLLECTION_INHERITED(UsageRequest, RequestBase, mCallback)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(UsageRequest)
   NS_INTERFACE_MAP_ENTRY(nsIQuotaUsageRequest)
 NS_INTERFACE_MAP_END_INHERITING(RequestBase)
 
 NS_IMPL_ADDREF_INHERITED(UsageRequest, RequestBase)
 NS_IMPL_RELEASE_INHERITED(UsageRequest, RequestBase)
 
 NS_IMETHODIMP
-UsageRequest::GetUsage(uint64_t* aUsage)
+UsageRequest::GetResult(nsIVariant** aResult)
 {
   AssertIsOnOwningThread();
+  MOZ_ASSERT(aResult);
 
   if (!mHaveResultOrErrorCode) {
     return NS_ERROR_FAILURE;
   }
 
-  *aUsage = mUsage;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-UsageRequest::GetFileUsage(uint64_t* aFileUsage)
-{
-  AssertIsOnOwningThread();
-  MOZ_ASSERT(aFileUsage);
-
-  if (!mHaveResultOrErrorCode) {
-    return NS_ERROR_FAILURE;
-  }
+  MOZ_ASSERT(mResult);
 
-  *aFileUsage = mFileUsage;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-UsageRequest::GetLimit(uint64_t* aLimit)
-{
-  AssertIsOnOwningThread();
-  MOZ_ASSERT(aLimit);
-
-  if (!mHaveResultOrErrorCode) {
-    return NS_ERROR_FAILURE;
-  }
-
-  *aLimit = mLimit;
+  NS_ADDREF(*aResult = mResult);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 UsageRequest::GetCallback(nsIQuotaUsageCallback** aCallback)
 {
   AssertIsOnOwningThread();
   MOZ_ASSERT(aCallback);
--- a/dom/quota/QuotaRequests.h
+++ b/dom/quota/QuotaRequests.h
@@ -67,43 +67,41 @@ protected:
 };
 
 class UsageRequest final
   : public RequestBase
   , public nsIQuotaUsageRequest
 {
   nsCOMPtr<nsIQuotaUsageCallback> mCallback;
 
-  uint64_t mUsage;
-  uint64_t mFileUsage;
-
-  // Group Limit.
-  uint64_t mLimit;
+  nsCOMPtr<nsIVariant> mResult;
 
   QuotaUsageRequestChild* mBackgroundActor;
 
   bool mCanceled;
 
 public:
+  explicit UsageRequest(nsIQuotaUsageCallback* aCallback);
+
   UsageRequest(nsIPrincipal* aPrincipal,
                nsIQuotaUsageCallback* aCallback);
 
   void
   SetBackgroundActor(QuotaUsageRequestChild* aBackgroundActor);
 
   void
   ClearBackgroundActor()
   {
     AssertIsOnOwningThread();
 
     mBackgroundActor = nullptr;
   }
 
   void
-  SetResult(uint64_t aUsage, uint64_t aFileUsage, uint64_t aLimit);
+  SetResult(nsIVariant* aResult);
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_FORWARD_NSIQUOTAREQUESTBASE(RequestBase::)
   NS_DECL_NSIQUOTAUSAGEREQUEST
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(UsageRequest, RequestBase)
 
 private:
   ~UsageRequest();
new file mode 100644
--- /dev/null
+++ b/dom/quota/QuotaResults.cpp
@@ -0,0 +1,91 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 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 "QuotaResults.h"
+
+namespace mozilla {
+namespace dom {
+namespace quota {
+
+UsageResult::UsageResult(const nsACString& aOrigin,
+                         bool aPersisted,
+                         uint64_t aUsage)
+  : mOrigin(aOrigin)
+  , mUsage(aUsage)
+  , mPersisted(aPersisted)
+{
+}
+
+NS_IMPL_ISUPPORTS(UsageResult,
+                  nsIQuotaUsageResult)
+
+NS_IMETHODIMP
+UsageResult::GetOrigin(nsACString& aOrigin)
+{
+  aOrigin = mOrigin;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+UsageResult::GetPersisted(bool* aPersisted)
+{
+  MOZ_ASSERT(aPersisted);
+
+  *aPersisted = mPersisted;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+UsageResult::GetUsage(uint64_t* aUsage)
+{
+  MOZ_ASSERT(aUsage);
+
+  *aUsage = mUsage;
+  return NS_OK;
+}
+
+OriginUsageResult::OriginUsageResult(uint64_t aUsage,
+                                     uint64_t aFileUsage,
+                                     uint64_t aLimit)
+  : mUsage(aUsage)
+  , mFileUsage(aFileUsage)
+  , mLimit(aLimit)
+{
+}
+
+NS_IMPL_ISUPPORTS(OriginUsageResult,
+                  nsIQuotaOriginUsageResult)
+
+NS_IMETHODIMP
+OriginUsageResult::GetUsage(uint64_t* aUsage)
+{
+  MOZ_ASSERT(aUsage);
+
+  *aUsage = mUsage;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+OriginUsageResult::GetFileUsage(uint64_t* aFileUsage)
+{
+  MOZ_ASSERT(aFileUsage);
+
+  *aFileUsage = mFileUsage;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+OriginUsageResult::GetLimit(uint64_t* aLimit)
+{
+  MOZ_ASSERT(aLimit);
+
+  *aLimit = mLimit;
+  return NS_OK;
+}
+
+} // namespace quota
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/quota/QuotaResults.h
@@ -0,0 +1,60 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 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/. */
+
+#ifndef mozilla_dom_quota_QuotaResults_h
+#define mozilla_dom_quota_QuotaResults_h
+
+#include "nsIQuotaResults.h"
+
+namespace mozilla {
+namespace dom {
+namespace quota {
+
+class UsageResult
+  : public nsIQuotaUsageResult
+{
+  nsCString mOrigin;
+  uint64_t mUsage;
+  bool mPersisted;
+
+public:
+  UsageResult(const nsACString& aOrigin,
+              bool aPersisted,
+              uint64_t aUsage);
+
+private:
+  virtual ~UsageResult()
+  { }
+
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIQUOTAUSAGERESULT
+};
+
+class OriginUsageResult
+  : public nsIQuotaOriginUsageResult
+{
+  uint64_t mUsage;
+  uint64_t mFileUsage;
+  uint64_t mLimit;
+
+public:
+  OriginUsageResult(uint64_t aUsage,
+                    uint64_t aFileUsage,
+                    uint64_t aLimit);
+
+private:
+  virtual ~OriginUsageResult()
+  { }
+
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIQUOTAORIGINUSAGERESULT
+};
+
+} // namespace quota
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_quota_QuotaResults_h
--- a/dom/quota/StorageManager.cpp
+++ b/dom/quota/StorageManager.cpp
@@ -128,30 +128,41 @@ GetUsageForPrincipal(nsIPrincipal* aPrin
 };
 
 nsresult
 GetStorageEstimate(nsIQuotaUsageRequest* aRequest,
                    StorageEstimate& aStorageEstimate)
 {
   MOZ_ASSERT(aRequest);
 
-  uint64_t usage;
-  nsresult rv = aRequest->GetUsage(&usage);
+  nsCOMPtr<nsIVariant> result;
+  nsresult rv = aRequest->GetResult(getter_AddRefs(result));
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  nsID* iid;
+  nsCOMPtr<nsISupports> supports;
+  rv = result->GetAsInterface(&iid, getter_AddRefs(supports));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
-  uint64_t limit;
-  rv = aRequest->GetLimit(&limit);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
+  free(iid);
+
+  nsCOMPtr<nsIQuotaOriginUsageResult> originUsageResult =
+    do_QueryInterface(supports);
+  MOZ_ASSERT(originUsageResult);
 
-  aStorageEstimate.mUsage.Construct() = usage;
-  aStorageEstimate.mQuota.Construct() = limit;
+  MOZ_ALWAYS_SUCCEEDS(
+    originUsageResult->GetUsage(&aStorageEstimate.mUsage.Construct()));
+
+  MOZ_ALWAYS_SUCCEEDS(
+    originUsageResult->GetLimit(&aStorageEstimate.mQuota.Construct()));
+
   return NS_OK;
 }
 
 } // namespace
 
 /*******************************************************************************
  * Local class implementations
  ******************************************************************************/
--- a/dom/quota/UsageInfo.h
+++ b/dom/quota/UsageInfo.h
@@ -13,36 +13,29 @@
 #include "mozilla/CheckedInt.h"
 
 BEGIN_QUOTA_NAMESPACE
 
 class UsageInfo
 {
 public:
   UsageInfo()
-  : mCanceled(false), mDatabaseUsage(0), mFileUsage(0), mLimit(0)
+    : mDatabaseUsage(0)
+    , mFileUsage(0)
+    , mLimit(0)
   { }
 
   virtual ~UsageInfo()
   { }
 
-  bool
-  Canceled()
+  void
+  Append(const UsageInfo& aUsageInfo)
   {
-    return mCanceled;
-  }
-
-  nsresult
-  Cancel()
-  {
-    if (mCanceled.exchange(true)) {
-      NS_WARNING("Canceled more than once?!");
-      return NS_ERROR_UNEXPECTED;
-    }
-    return NS_OK;
+    IncrementUsage(&mDatabaseUsage, aUsageInfo.mDatabaseUsage);
+    IncrementUsage(&mFileUsage, aUsageInfo.mFileUsage);
   }
 
   void
   AppendToDatabaseUsage(uint64_t aUsage)
   {
     IncrementUsage(&mDatabaseUsage, aUsage);
   }
 
@@ -99,19 +92,16 @@ public:
     value += aDelta;
     if (value.isValid()) {
       *aUsage = value.value();
     } else {
       *aUsage = UINT64_MAX;
     }
   }
 
-protected:
-  mozilla::Atomic<bool> mCanceled;
-
 private:
   uint64_t mDatabaseUsage;
   uint64_t mFileUsage;
   uint64_t mLimit;
 };
 
 END_QUOTA_NAMESPACE
 
--- a/dom/quota/moz.build
+++ b/dom/quota/moz.build
@@ -10,16 +10,17 @@ with Files("**"):
 XPCSHELL_TESTS_MANIFESTS += [
     'test/unit/xpcshell.ini'
 ]
 
 XPIDL_SOURCES += [
     'nsIQuotaCallbacks.idl',
     'nsIQuotaManagerService.idl',
     'nsIQuotaRequests.idl',
+    'nsIQuotaResults.idl',
 ]
 
 XPIDL_MODULE = 'dom_quota'
 
 EXPORTS.mozilla.dom += [
   'StorageManager.h',
 ]
 
@@ -38,16 +39,17 @@ EXPORTS.mozilla.dom.quota += [
 ]
 
 UNIFIED_SOURCES += [
     'ActorsChild.cpp',
     'ActorsParent.cpp',
     'FileStreams.cpp',
     'QuotaManagerService.cpp',
     'QuotaRequests.cpp',
+    'QuotaResults.cpp',
     'StorageManager.cpp',
 ]
 
 IPDL_SOURCES += [
     'PQuota.ipdl',
     'PQuotaRequest.ipdl',
     'PQuotaUsageRequest.ipdl',
 ]
--- a/dom/quota/nsIQuotaManagerService.idl
+++ b/dom/quota/nsIQuotaManagerService.idl
@@ -37,16 +37,31 @@ interface nsIQuotaManagerService : nsISu
    *        A string that tells what persistence type of storages will be
    *        initialized.
    */
   [must_use] nsIQuotaRequest
   initStoragesForPrincipal(in nsIPrincipal aPrincipal,
                            in ACString aPersistenceType);
 
   /**
+   * Schedules an asynchronous callback that will inspect all origins and
+   * return the total amount of disk space being used by storages for each
+   * origin separately.
+   *
+   * @param aCallback
+   *        The callback that will be called when the usage is available.
+   * @param aGetAll
+   *        An optional boolean to indicate inspection of all origins,
+   *        including internal ones.
+   */
+  [must_use] nsIQuotaUsageRequest
+  getUsage(in nsIQuotaUsageCallback aCallback,
+           [optional] in boolean aGetAll);
+
+  /**
    * Schedules an asynchronous callback that will return the total amount of
    * disk space being used by storages for the given origin.
    *
    * @param aPrincipal
    *        A principal for the origin whose usage is being queried.
    * @param aCallback
    *        The callback that will be called when the usage is available.
    * @param aGetGroupUsage
--- a/dom/quota/nsIQuotaRequests.idl
+++ b/dom/quota/nsIQuotaRequests.idl
@@ -17,27 +17,29 @@ interface nsIQuotaRequestBase : nsISuppo
   readonly attribute nsIPrincipal principal;
 
   [must_use] readonly attribute nsresult resultCode;
 };
 
 [scriptable, uuid(166e28e6-cf6d-4927-a6d7-b51bca9d3469)]
 interface nsIQuotaUsageRequest : nsIQuotaRequestBase
 {
-  [must_use] readonly attribute unsigned long long usage;
-
-  [must_use] readonly attribute unsigned long long fileUsage;
-
-  [must_use] readonly attribute unsigned long long limit;
+  // The result can contain one of these types:
+  //   array of nsIQuotaUsageResult
+  //   nsIQuotaOriginUsageResult
+  [must_use] readonly attribute nsIVariant result;
 
   attribute nsIQuotaUsageCallback callback;
 
   [must_use] void
   cancel();
 };
 
 [scriptable, uuid(22890e3e-ff25-4372-9684-d901060e2f6c)]
 interface nsIQuotaRequest : nsIQuotaRequestBase
 {
+  // The result can contain one of these types:
+  //   void
+  //   bool
   [must_use] readonly attribute nsIVariant result;
 
   attribute nsIQuotaCallback callback;
 };
new file mode 100644
--- /dev/null
+++ b/dom/quota/nsIQuotaResults.idl
@@ -0,0 +1,27 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 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 "nsISupports.idl"
+
+[scriptable, function, uuid(d8c9328b-9aa8-4f5d-90e6-482de4a6d5b8)]
+interface nsIQuotaUsageResult : nsISupports
+{
+  readonly attribute ACString origin;
+
+  readonly attribute boolean persisted;
+
+  readonly attribute unsigned long long usage;
+};
+
+[scriptable, function, uuid(96df03d2-116a-493f-bb0b-118c212a6b32)]
+interface nsIQuotaOriginUsageResult : nsISupports
+{
+  readonly attribute unsigned long long usage;
+
+  readonly attribute unsigned long long fileUsage;
+
+  readonly attribute unsigned long long limit;
+};
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..5144112bde351703f42ab87f817421af09cdae53
GIT binary patch
literal 24717
zc%1EAcRZEv`>&)WDvC-}vX7Bnh$MRp(XjVAvSoc5l$1SEC|MDqW6Ma$CVNv>c1C80
z-;wnk&N&|a`s4eD)9b0{QC;urzV7Q>@B97SLs|@L_kkUYpE_wt(H(%#z8$A_n3+RO
z)pWEN<>mJ8zzQvVqd0=NEUa;M?A-lp=Z+n_k0Sn^G+GPz01GBsrbcSUTE^y^+B*6N
z`<k(dXr`Wfg%;wkJa_HbaS&lk!&FPnTuVh$ok8F1j}?+9#fpp9IxD`Oe9-3e2c1Ud
zk3E!<lvW%_;y(m=GL(Ew*Y>0{pQrB22XyK9t>pA$?Ls&r^?0pnLbC27_F<*zyQYs$
zbyzo1_3zzT-0{^LcAxYi-=2prZ3qfKvAO%HzdQG!&|K}Qn64A)*U<~6rSy?);sOJ%
zHQZ|IW^E4VYn$Y1LnY2U@5T`nSGe#=D+-Do*%HH}AkQI0m3If8u5!uX%{9k+7oB4G
z+mm)mpQhQxMZBk6_ElydG^N?Hi|W8922IDz@8xdSauga3?59KeB7Jm)YJBdhO*e+N
z=rn80LFxtg6FMX2+10`t9;B#quxq@(-p%&<a_%D~q1yXzzL3lgyz`T9rz@a+;QgjH
zweezUiR=sdqdFfu<5D3R?Zcsv2;1BaH3gU(*=!Zd9ygd+Z6DK1ikpnPTYULrJJJk)
zGX_=!8siHHdE-8NKNDHmS9{`P<vhp8TpslKPCTcVWZmB+GyNBM<+69Kb(MmFiRcK<
z%P6MBK1XyF-deXanB6hdGuQglSq~l-D=uE^ItvGHqKHmJUbuv@Sb|RGytb;ks-~ui
zw6rSX^H9Czzx{D^Sc=)Ck$V{L=nH*9$~P8$6Qq1Q49GW4Ep0Um!{uyKyI-uhc%jW)
zj&+uRnQN|PWP-RewOO*Ihp?lE$(FAHvaJ&+zXck)rck5hFV+kqDl;1+vlih+lfUP}
zqX`jDB#4U)lSu|6Eps(ZHFGsgwl!3LrH9OZ9U;cT!n$cHDC1yEi;uGo@oR<!?;;{C
z;-UbBNN>pu4)mm|SUGiZg@l0mP7IMF!33(OslI9SP@Co1%q%Mt2h;fr?9A*e=4M*@
zW(<g$qobpyWo9nVpsi=9WwwMni@==Stk)KtkKFRujd;xY|KS3@M`&<|TH1}96i)3m
z;UZ@um#B9=o2(EZc~k()g);W8yoI-5?!9=K>Jy>lFDbinMEc!$N!V+vxODF(q%@GK
z64^dz8$7|T=U+{#3XRv$$XS@KwyY(bfK%@->9ulmL|puI0yK_FH4=j5O+gXbUbeZo
zYI-8mPY?4QCi|Vl@YLvM{RcC{AflOi_XkrhWVyz4dKN8@^PC18l^son+<&Rm85d;v
zDaXzy&3-PfDB%@w=$6>Aa5}S@xGL6mRM)Y3@JDZNj9CPSV$xjV`+%5!PK(!-Peom#
zkB-?ydw5WL6-9jvAEP$F_S58Y?h-u^67YckjgMR5*R#GZ;_jAQgE4i($>L))Y5bFV
zS!cZI=w;g&BYjBm?vANC;b)d>h~^KzS9ZMoHgG8DmbbB1awwdj_rp*%RgAWR4dsob
z@{@*v9`Ew~;axoC<bj&g<hMf3nkC@F#6s$EWvL0$!tm2%={U`3$JOxUzSrno=nKoZ
z-sC3LXg2VrZYV7?^)xdFG@<upa}9Q}r%Vr&M~YN0w)bXz4x3=HQg2exKupTPIwqAk
z!ZsdB`U9o`wEcrK*^Q@SAIGQJAM?f^O>Gc+-lX?H$*9i2{<)oYw(#DR%U&b%_hV!Y
z7~FkwKR-3SlJ%NOk2&4ZIrj5I+04$jK5qwI;B$B1m1m74PmHAhuBsb-jaQMlhxe;)
zeWJ4&&tX`PrmP2S;&~~{L-|jaPf4}&)D7r;ANHDzDM=a3)swuK@{z0V_8`$|VOe#k
zl$}!20AZ?f$JNqnUoV?^9URB;`C9aNkVtIqy|-kWbK`LQPvfkBnY};7%k;%E>e-~@
z<(isY6FvMh%V^$Io?`U1yIhhL7V|jl*tdaxu}dC$4IY-ByGVvqvlOs@#mmXW+J<=y
z*?*v=7`v(NSS_jAuY7_-@Y0-N&mP-HTm$f9Gzm!*S*(LWY+04l!efKsj%oxFO=PgC
z1_R?a9kMFEw`&)yl|&7puKssym2SarKYADJbVo(QP1d=lJsbBK-(|lZX5a7UbtjZw
zS81?G3|{IZ{sJQpsSZ*uae1c}_aIxg{c2cVYsPm9v+Ko4)}L4)Y8GaU903#GSTbVh
zV~Yl>ti^8IM+dmWds}(^_?`7Fi6hEyX!nwZeNEfD$MrR_e5^sT5QkutT-b@mV{pRS
z;UPK^mmrda>?3dE=B#bhC8(}fmn%VQIb({h@Kg#BkCdO%lK2IEBCBq8?W4~icdWfl
z^oh`^$5h$h8p8}!N3M*w`%d^RJgHFpQrR3E6~NB=xhq8~w%JHQBIpngi=u(vGuK|j
za$Ox=en%eq1}pD|LnGr3SW5-$KZxG5?7S%lf@z}Vl6H$;q;K+3LalC|rnAx|9qs(e
z^2T9;(8<(lV`jDP@ph|u9=Ncz)`Cp7NoTg?%KvJk;9giZNyjrVvM~Dl(9%<U!_U>*
z>CJB!7IyAH`n=C_1k_)@b@lfg$~vfPZf*jBKn$T8YKFQ{vt{P~jVN@#F%{WG<IN@I
zDd(1niVmD{WRgUKvcy*j^M?^6sUzuNsxB$$aA&{AIS(0GS=I13_rqB09C;C~QcZ?<
z;y_%CTXbZFJ2&;^WJhU{lw@g9AtS?1)7{LXq6cCoejQQA5O6ARuB<XDhM+G2_^$&H
z1`hy^Tj2<FIHqo2^dN{}An(O8xBeRs04$5fgQ1oRNn)W>dw<?O7=wGZETmALER1ho
zt=~cNG8zd;Z3k1TMP1)r`q%PW^w$4LJd;3_>Mrd^r|u3BBp#~dZ$INtY8zLhAs<zr
z#ivtm09$w(6ei>P3%>8OelG_sd!~#|o5FRhSHPRaw8k*#WMGTGvB<S+Ra6g!y^a#Z
z+4NQ2x0cBGGHIh^2d|vFC?|eHDs0dVCqbaE=QPLZwrTtM-n3>HMqhuJW4Qyzc=d#P
zg348boCP5rBfc~<N2a#h-|5GvpC`GMa=uHh(BGpYUlB$BOxr@#JT^X4f(`$Ozz3V#
ziE^a9gE?OPc^-Bm=U6k6_!Fxb8e2nXW%`Eix{{EvH{(k3P+ApHwlcgW7jl)GC@}~Z
z$_yq`49$yic`nP8Vq8axAKk+_$Kk`(=xc4&o@qGVv7f6;-qS@UHi0ukys#R-(82n&
z6}~aEI(~5F<Fp2si{a-D2x)v=ZdAG4pdoC%=$n83Cg+`jnpft<&5+K#$e=U}g7NZ}
zVBW{iUuHLSmJJnS7kl&d#PLcU(TnRPuFqi+Y`Wc>_HDqBov!YCoC1#H=@dfjByl$T
ziQg(vH_NLvEm^|UMfn10-dzQJL5)U}23fD{EMda7DVIeD=kG^fvt@8k$_<T4mf{JW
zJHedlI2#LpSQV6+>J?*H*t%Ccv>?lfqZHcoy=wAK9G=v(^b0aj(vucbcGTMCWnr&-
zevqEf*_UxY<br3GnPDAsUNc4KP5-#YwB|rds0}nGrJ<tznon1O^Y1tPHT340l`aqC
z-h}iV?dv6?4Sji}k<O3(5>@L*`ZmLaAIA3ru=oCyC^Igxu4j{rH!o;&O^lD7eOY}q
z)JBHZ!qpE;r11z17g;5n$6e~`w`YUMoH#i@smC6em5h4RJSBX#enwY8#F(+9m4fOX
zWU5$8qa~$6&^SIN71kCc<5f~JhEvk0<WH2&Eo*1nr_ylsb8_L2OOsDtQh%(e*Sc=e
z{z}0M0vXGH1EUL`5B{vwo@*V)BuI0v|8$G90^=E>@kY^v)2!Bvm3_g%XUl^RKJC2e
zRoJI|yCme@w;29-S(SXBu1wo8>~V!+nDsXn78#3i296VxJuK-lxSc*1!$<wo?`r?_
z?ywn&>wX*}*=%9_VGlG&h&6rcGW3Y}JN-l(GZPITQGplom%c)!hsyhXyl&n0&A<tn
zz3U$NsLtG)Ehw<8K+QGi!()z#PX!rVf=bn`%^$pO-SA>ON+o5hLVCQeL#NbVWx=qR
zCEhV4zg<-OoOOO=j8;Hdfp0(^uB&TvZ+t6Htm(CbJj@Nc$A69M7?$c<>6X}8%A0gh
z-XU%K0^hS-*y^hSt&2u})4DJ&{~#5QN4l;KA2xbihcJ$mMLFTAM)G_f=eOU3pP%9O
z@}HrSa1~>DHJ>~?HRUM67<A~DSjzlB-ZDLQ80C)hF5TvI!FU(kdmWbvy~ug(_R*%d
z3k!#k`PKvu$6Bk-q3fzM5eiuhl%M!c#fpm;+F~2JPJW(2ZxESR(OBM0e1@(QpXWf}
zt<dMDkf^2S`j`=;hg_ve3~@tklpC{AaMTE@w}7(q?@<AChz50AbZ(2zZPB?cI{)`X
zXV|*hdlp3%L@hZ95M_=4Q-KXzCpl@sm_{Z>G#FbFoMGz(C;gV(SmDc~2rrIe@?>+l
zxjxhsU>sRxQ8W&qH!ld*JUBkZfWH=Jpw#>q_yA@_gTE~_w}s}m(A*Z9|I0!%0>ez_
z+N>#1Y7!v|9TBEt8-Zb_bAw4_PDNvTGqD+gVWty3;tG9k3W{28u8$lECeT%?#1K8y
zW_dO<3yvZ|^%}aF&aL7Cs1XhBw&>gzo!g>wTXg>KiO%))_Z-SPh+1|YM-;l_n-y7f
zGo2WWBa<W=lr0I*2n;iwU>sTD&P{#UTzak#I2AZoRv8sT&`|>jg9iY|t)RLc-Aw1-
zdjMcrG#+dV&}{*_EkL&g=>M_+B{N3Px9eWbX<4fonHXv@Xh4mY3U9VcvEt%|w(u?*
zS6C1bra(L~tm9h@#*z6J4ay?N$*}c`@gn%vN?$<Tm`^fV+0=o-1LCvHxO4~BxsoS>
z#Y>KO;#$YJU|d;Y+)ceX*&!J#TuNUkQY%(ofo<xv%(<QdJJAQ73Y;^moQomwr~!n*
z1AyaPP+gCuP^1)yf^+}g0|4iu@nEP$LW)@E_#)>jA3R%hc7=0K?Gt6xyAid={n<^O
zp!fB=ZV1$=AJV**Ej_|{pk>g5pZ99`B-TWwSVh`I4Wo3_m+1CT*g#SvhX$2ijVjzR
z*E(subdaT@R9)eUPZq-u%5y@omi#P5_TM7Tvz)Wzdwgc!k@*`(8R$mqW0s_?6nx5)
zELV_D&EnP*I-L52toff!Dz4cKEpGOZOt*OgxZ1FP<EwMo<COm$5}F$JGVh%qvxDXv
z4t)6%V;@$p6mBM4Ev|4Us7XfmM)+0vv9we2!oo*IbmZG)9Rd?}xqcww{~+L0IZ@6a
z^TbvY>R)^{!j{;`QqIWY1?5a&%eiJ&e}55YLh2EJ`6uqPmu%v%xF~lr<zLa}kGn)J
zS8jgjy@*wn!FVQC?}ymWIx+eR)|5BG3;GAi&R%zAocn4YC~~3br%37*{vLG-ZT~BA
zC&*REOl2rc)1*y$<i39%e47_lty;C;D$a-GRbp?QD}9rh?aUcX<2H3E_7pK9YBA@4
zY&f?~SW@uFEv)+EB051tf^o1mR>fvJ*bVEs3rU3~6wz-xdlxLt63KFVCMCq5FfzKf
zrbdy}1=MP167DUEOu<QX#37#^t|*~R>KRik;uVGL?SkC(Ap1P0Q^_ez-Prod|9iJY
z0)h<c8eAo>Eo6OWG$NTA_<8HyIKeLk`FC8sSWGyQlr|Unr;5n=6^|Xv8=V-^$n+x{
zW}vA^xBDU))Dvb_lA+O>?=a&@p3lLNfBjg7@x1|T$vp03xU5u#XR<G!2zpv*8In50
z+1F+CJeD12q~~RT<Bp1&m}DQ@+gR9Q5iyy<;};v71IZ7RjmZ{qC3cAwKM__ulJ!2T
z1}nfBSC5FM@+)4Cf$w!ISFPG~p|OBr9T}S7o5yS+mb?6ieO(J|DtL%9KDBk0r?XMz
zU%#Gz-8mD+z+ird+-9=MG2TVc$aB<o5SK&7Br2}>eZM_7B)`5cZ(M6h+sahrrp7Vx
z(eU?=v^xv(p5ce}nW`OT{Y@v`m-T{dGI-)yr;=A?pR#g^=aROSB9pZ<5aZSv7EL2$
zwAN;bF&^%w4CS#a@K1_jdw%;QGzvoXVy4Ei4X$xf^Q~Z{aes_nvK0TxAluj3`_g5;
za%vk`YaDgOe&Kif>xlHw@a)s0Dk?;_V)tg#-F1ZO%+1+`0)J^Im7S#P!m>{t9hQ);
z(;P{r&cCjZXI4~R-Q@r11(Th-^%!xWMCzVN2G)h!BGB2m>A)o1%-WBv)#=*Le@{kP
zaz1+!HU8<#9s`M3hr0!oPc5C<CtxM_?KxcFKY98%RtVOMa9Zr+=%bwM<sWo>o^mm_
zf)EC|KQBEG`BF+p+{Dyut<B9=<}Jm+(TEd!M^=ZpR)PQd+*k$dbZGYexFOztBIEh?
zsAXxJGxu<nJNtCtaNgh*xf(&dc6)l$+xZ1vWY*28onl<8&*b0<z{<*s!3cU+&(Khf
z0cxtVRDSaig)a|N`CSC)J^%}*K|C=duJhmlkl7av(lXz@SX8@K#t!n@l9F$f9b`B?
zAbv~itD>y@{t+Ee^M=Tni5k4r<6LxUF*q!L;nE5V2aA;}+9ED=UY*0D?I<scD=sY(
zsVQL;-D{e^Ov5E5CBHnhcA)PG2zakn=@>(Apav1&8VEQ_29*<3X0*j2%ar`@ya3QL
z8ZU-g+9jJ8UpT+qK`Gs&d{9f@$^7sYu`t%e{xU@ly?cR|lWY1;3FSo7Fn3*Uy|~{s
zh&feElyMR-WBHA<xV@7|Mj+)7ljY!rPYb*BGNLJF9j-p^9_RX!jktD;Js#r_XjSie
z-56~^n8w(0l#=ox<NhPN&laed<)+!pzc6<n8Yf$r4WHtX6EDp3w)`^FaNh(zGH~cU
zoNa1uFm_s_uX}>GnpXnOK4UO=sBQPpZ$DZB{EgdHp7$}_pojnTNWwFJAm1#+R;G?n
z!njV_@}hF#@o6H*{wQJJ6gkpvgc2THRKjOjGZF-Rs@NOb-Y|RiSw`gJO}-p*7RWkd
zRm9m!SBOx;K2s%-@JE@!+=?Mr<3<rm*#E1+p?$t)L9GT=LxW@DR`r>NW+ODsDbd^n
zu{SjKa7h7_u-&Q>t~8)TDB)YOF1P+D;hFQqw11RvRWoELFETLAqSFkagyRHC%Txxx
z_E>(~)m?OEoZ}Uhdt&`~tU<?#bKUR92Y*`B5mOo{#a&-g!fE2ievK`@aUOd7HqD;c
zA0G!tok~s5b`Pw1u>KbB%-~(mN#lFu?Qm?R@X1@GG)|9{wEXQPtg1Cl7A9`a?GNYV
zVv&9Gf!4BqLhu>9!T1Mn;!OBZr!q;f-X2~x)+x5nmrg$kuwbDnyqL}}cp~?`Dz#hW
z$f<!O)=^85xw>v!%kS)wEjQbU2k0lq-6?1i(rL5aa$4ZrW;7=oey98PqR8xwQ}GY&
zt97p778N2K&}#i;Me~%L()(D`5!xx?nFA+j6={t|1a36=z!%>*b2IvW<SV%sHuyM<
z<j9Yc!k2vXYCI%8uaE>SzHzpACnqyx8|E=!$3suS?w>dO#yiK!w)^9qf|Lq|R@D&`
z9eY*^3O~O*q6iqQoYCBYd}gw0A>PH=$g||nE9akoUOB@xWku;2U3GBEKUmM&;zioy
zbY>Rp3xE37(S-O#=6|QkbRhW-l^w9l;avJJF4!`kcY}(MMcUq>fAroNhWAO-p2!=2
zYS=}m^d?Qkcc%(*f!eZ+7R`o772R4!x)wb?1uFghp4yl82T#o_x*d;hW2XyZi>VX2
z8ftrJf{>5n-Hm2_JmaUbQNpkfRI~Katx5qN_z;M?6_1?C$Y@vP3%s}pZ&+IcG=bA~
z`toVRj~VBD*lIH=L|yU)M#W9X5~sR@wei|CvVPC%cn9Bu<CHmGuOj{g;nASK24!a`
zt*I1uZReRAvdq-)v->IbAjw%fFz~~X(AE$M_{5uz9EtDTAKhnhm+Ra6Fr|5X=tun3
zSI%|~Jify*`H?#6ge<ZBXJNDvmW9kxWmJ9^6OH}-qoa2s+PG_R`Ab-DKFY1R?if7(
zdj#?=d|U{gTQ(KMvuxy}nDzYLrQ73<lkE$gGpCoHR6l-Oz5TuU?ZV1??3K?g`vrhF
zV_jFQX)x`JK*`Qsi2B!ssS>lUV`t{AKp^uo8mzzI=S8P%sr8RjFY`0oUpckH(3|>o
z5+p&d?+*H{xV1{r7`g;CjO12fz>zel)Buw7zw`q@(`fwIrs-{(-lpkon*JZA>7Bbs
zvCy5ia(wyj@QxwA#Xr~1Ucp{EFJ(j7MQ;rs$=VfwHQ+fcnCzlEg=NX^;;VxH?ztg;
zM?RAUd+AIT3>G&Y7IJ*m>;LXu+_mcIYQe`|IywYH>o=YQvex<>z7K0Q0jGjsFP#d4
z!Rp2{L4a0&1FQm12*F-DAq0cnjpu^^?FwU|>Z{c?bl6MhU0?|C#<N0z0e*?eJYaAJ
z4hMPN91sV0HyE5h<1I{3=*|TJM(jQ&sHHK~)**P1AR0G=05N{TUOKsBlZYa(q60=$
z2K(=Q0DP6u`hae)J}?eS2T=KdVm%A?(k5~Yjor9!AK2Jra6rfj3jz^&*$NPm7iVjT
zE2)bX6x~*QU_6V#fvzU;CSV)4<paSW2SI~@OJ|fD^w;9Oaf?1M-m(A08$e>C^#<Lh
zSYT|5j%?%zV9iCj;c~618#l-Tn|cx-t#RZ827!XSEf$FK1O&=T(xL@Iw;2`~D>!<f
z)kNJQ05=kVECEIUaLEZGmdKlAfw3(7YYzYkxk(H*Zcqcpp#1no4^Y=xlv~x-8oF__
z8nB@>CqTd;Cn*R#<Xve%y!b8Qt)wf;?OEs}Nr4o}izh)qt|smlp#+hjo`Zz~m%?a$
zLANgr80q80|9@Wq$-GHiHtqxg#)bI|s<AS#zM|Y+u-4R#yF!3Xb;4vGIe9_gpdZst
zfx=lyTC`B;c7OmQW_T6@)M~PB5dwKk`*|}6a7hXxqUgu8Tx5Um10XrK7zgArEk6}1
zA5hm?lnZr{8;gES`x+b&a>9Z@L_embq23zeO6sBoMYrf07|%p-psPu|MKI(s?J*kA
zVBpdjM7+_DY5o6+H-N<6BsLqDKLTR|V?fIQ$crJdm)4_UX!gdXkicdiW&{O<oY)``
zkykt-y~Wrf;!0wp1x2^A5g1SE^PoUi6MKtb$cgO&9t>P!gNQfsibr6)ahU#vH-N<6
zBsLpY7y)BL!;aRQjWe3qORG9CG=1Z0BP3Y`9t=6bH$mOFpa_Uc!m)MKl_U?|xU>jU
zY$3=+13d6*qN8moy7faqz~dLT1PCtKLG(ECS|VWVga4UFfP~*9MjNN?ficRzgyCHY
z%9KYrOS=|;jZ^r*08sO60S-CoLEs|K(gSfb{|a{{?a@M`n~4WTSdMoK(5s2RMMy~`
s$c(K*f=hi6J%Btz59|T{%m2<NK=PyX3H#5^6K=#W9E4Og6j*%vKdFhjQ2+n{
--- a/dom/quota/test/unit/head.js
+++ b/dom/quota/test/unit/head.js
@@ -256,22 +256,34 @@ function getPersistedFromMetadata(readBu
 {
   const persistedPosition = 8; // Persisted state is stored in the 9th byte
   let view =
     readBuffer instanceof Uint8Array ? readBuffer : new Uint8Array(readBuffer);
 
   return !!view[persistedPosition];
 }
 
+function grabResultAndContinueHandler(request)
+{
+  testGenerator.next(request.result);
+}
+
 function grabUsageAndContinueHandler(request)
 {
-  testGenerator.next(request.usage);
+  testGenerator.next(request.result.usage);
 }
 
-function getUsage(usageHandler)
+function getUsage(usageHandler, getAll)
+{
+  let request = SpecialPowers._getQuotaManager().getUsage(usageHandler, getAll);
+
+  return request;
+}
+
+function getCurrentUsage(usageHandler)
 {
   let principal = Cc["@mozilla.org/systemprincipal;1"]
                     .createInstance(Ci.nsIPrincipal);
   let request =
     SpecialPowers._getQuotaManager().getUsageForPrincipal(principal,
                                                           usageHandler);
 
   return request;
--- a/dom/quota/test/unit/test_basics.js
+++ b/dom/quota/test/unit/test_basics.js
@@ -33,32 +33,32 @@ function* testSteps()
 
   info("Clearing");
 
   clear(continueToNextStepSync);
   yield undefined;
 
   info("Getting usage");
 
-  getUsage(grabUsageAndContinueHandler);
+  getCurrentUsage(grabUsageAndContinueHandler);
   let usage = yield undefined;
 
   ok(usage == 0, "Usage is zero");
 
   info("Installing package");
 
   // The profile contains just one empty IndexedDB database. The file
   // create_db.js in the package was run locally, specifically it was
   // temporarily added to xpcshell.ini and then executed:
   // mach xpcshell-test --interactive dom/quota/test/unit/create_db.js
   installPackage("basics_profile");
 
   info("Getting usage");
 
-  getUsage(grabUsageAndContinueHandler);
+  getCurrentUsage(grabUsageAndContinueHandler);
   usage = yield undefined;
 
   ok(usage > 0, "Usage is not zero");
 
   info("Clearing");
 
   clear(continueToNextStepSync);
   yield undefined;
new file mode 100644
--- /dev/null
+++ b/dom/quota/test/unit/test_getUsage.js
@@ -0,0 +1,127 @@
+/**
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+var testGenerator = testSteps();
+
+function* testSteps()
+{
+  const origins = [
+    {
+      origin: "http://example.com",
+      persisted: false,
+      usage: 49152
+    },
+
+    {
+      origin: "http://localhost",
+      persisted: false,
+      usage: 147456
+    },
+
+    {
+      origin: "http://www.mozilla.org",
+      persisted: true,
+      usage: 98304
+    }
+  ];
+
+  const allOrigins = [
+    {
+      origin: "chrome",
+      persisted: false,
+      usage: 147456
+    },
+
+    {
+      origin: "http://example.com",
+      persisted: false,
+      usage: 49152
+    },
+
+    {
+      origin: "http://localhost",
+      persisted: false,
+      usage: 147456
+    },
+
+    {
+      origin: "http://www.mozilla.org",
+      persisted: true,
+      usage: 98304
+    }
+  ];
+
+  function verifyResult(result, origins) {
+    ok(result instanceof Array, "Got an array object");
+    ok(result.length == origins.length, "Correct number of elements");
+
+    info("Sorting elements");
+
+    result.sort(function(a, b) {
+      let originA = a.origin
+      let originB = b.origin
+
+      if (originA < originB) {
+        return -1;
+      }
+      if (originA > originB) {
+        return 1;
+      }
+      return 0;
+    });
+
+    info("Verifying elements");
+
+    for (let i = 0; i < result.length; i++) {
+      let a = result[i];
+      let b = origins[i];
+      ok(a.origin == b.origin, "Origin equals");
+      ok(a.persisted == b.persisted, "Persisted equals");
+      ok(a.usage == b.usage, "Usage equals");
+    }
+  }
+
+  info("Clearing");
+
+  clear(continueToNextStepSync);
+  yield undefined;
+
+  info("Getting usage");
+
+  getUsage(grabResultAndContinueHandler, /* getAll */ true);
+  let result = yield undefined;
+
+  info("Verifying result");
+
+  verifyResult(result, []);
+
+  info("Installing package");
+
+  // The profile contains IndexedDB databases placed across the repositories.
+  // The file create_db.js in the package was run locally, specifically it was
+  // temporarily added to xpcshell.ini and then executed:
+  // mach xpcshell-test --interactive dom/quota/test/unit/create_db.js
+  installPackage("getUsage_profile");
+
+  info("Getting usage");
+
+  getUsage(grabResultAndContinueHandler, /* getAll */ false);
+  result = yield undefined;
+
+  info("Verifying result");
+
+  verifyResult(result, origins);
+
+  info("Getting usage");
+
+  getUsage(grabResultAndContinueHandler, /* getAll */ true);
+  result = yield undefined;
+
+  info("Verifying result");
+
+  verifyResult(result, allOrigins);
+
+  finishTest();
+}
--- a/dom/quota/test/unit/test_unknownFiles.js
+++ b/dom/quota/test/unit/test_unknownFiles.js
@@ -126,42 +126,42 @@ function* testSteps()
 
     request = initChromeOrigin("persistent", continueToNextStepSync);
     yield undefined;
 
     ok(request.resultCode == NS_ERROR_UNEXPECTED, "Initialization failed");
 
     info("Getting usage");
 
-    request = getUsage(continueToNextStepSync);
+    request = getCurrentUsage(continueToNextStepSync);
     yield undefined;
 
     ok(request.resultCode == NS_ERROR_UNEXPECTED, "Get usage failed");
 
     file.remove(/* recursive */ false);
 
     info("Getting usage");
 
-    request = getUsage(continueToNextStepSync);
+    request = getCurrentUsage(continueToNextStepSync);
     yield undefined;
 
     ok(request.resultCode == NS_OK, "Get usage succeeded");
 
     info("Initializing origin");
 
     request = initChromeOrigin("persistent", continueToNextStepSync);
     yield undefined;
 
     ok(request.resultCode == NS_OK, "Initialization succeeded");
 
     file = createFile(unknownFile);
 
     info("Getting usage");
 
-    request = getUsage(continueToNextStepSync);
+    request = getCurrentUsage(continueToNextStepSync);
     yield undefined;
 
     ok(request.resultCode == NS_OK, "Get usage succeeded");
 
     info("Clearing origin");
 
     request = clearChromeOrigin(continueToNextStepSync);
     yield undefined;
--- a/dom/quota/test/unit/xpcshell.ini
+++ b/dom/quota/test/unit/xpcshell.ini
@@ -2,27 +2,29 @@
 # 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/.
 
 [DEFAULT]
 head = head.js
 support-files =
   basics_profile.zip
   defaultStorageUpgrade_profile.zip
+  getUsage_profile.zip
   idbSubdirUpgrade1_profile.zip
   idbSubdirUpgrade2_profile.zip
   morgueCleanup_profile.zip
   obsoleteOriginAttributes_profile.zip
   originAttributesUpgrade_profile.zip
   removeAppsUpgrade_profile.zip
   storagePersistentUpgrade_profile.zip
   tempMetadataCleanup_profile.zip
 
 [test_basics.js]
 [test_defaultStorageUpgrade.js]
+[test_getUsage.js]
 [test_idbSubdirUpgrade.js]
 [test_morgueCleanup.js]
 [test_obsoleteOriginAttributesUpgrade.js]
 [test_originAttributesUpgrade.js]
 [test_persist.js]
 [test_removeAppsUpgrade.js]
 [test_storagePersistentUpgrade.js]
 [test_tempMetadataCleanup.js]
--- a/dom/security/nsCSPService.cpp
+++ b/dom/security/nsCSPService.cpp
@@ -15,17 +15,16 @@
 #include "nsIContentSecurityPolicy.h"
 #include "nsError.h"
 #include "nsIAsyncVerifyRedirectCallback.h"
 #include "nsAsyncRedirectVerifyHelper.h"
 #include "mozilla/Preferences.h"
 #include "nsIScriptError.h"
 #include "nsContentUtils.h"
 #include "nsContentPolicyUtils.h"
-#include "nsPrincipal.h"
 
 using namespace mozilla;
 
 /* Keeps track of whether or not CSP is enabled */
 bool CSPService::sCSPEnabled = true;
 
 static LazyLogModule gCspPRLog("CSP");
 
--- a/dom/security/test/csp/file_upgrade_insecure.html
+++ b/dom/security/test/csp/file_upgrade_insecure.html
@@ -52,16 +52,17 @@
     var mySocket = new WebSocket("ws://example.com/tests/dom/security/test/csp/file_upgrade_insecure");
     mySocket.onopen = function(e) {
       if (mySocket.url.includes("wss://")) {
         window.parent.postMessage({result: "websocket-ok"}, "*");
       }
       else {
         window.parent.postMessage({result: "websocket-error"}, "*");
       }
+      mySocket.close();
     };
     mySocket.onerror = function(e) {
       // debug information for Bug 1316305
       dump("  xxx mySocket.onerror: (mySocket): " + mySocket + "\n");
       dump("  xxx mySocket.onerror: (mySocket.url): " + mySocket.url + "\n");
       dump("  xxx mySocket.onerror: (e): " + e + "\n");
       dump("  xxx mySocket.onerror: (e.message): " + e.message + "\n");
       window.parent.postMessage({result: "websocket-unexpected-error"}, "*");
--- a/dom/security/test/csp/file_upgrade_insecure_meta.html
+++ b/dom/security/test/csp/file_upgrade_insecure_meta.html
@@ -53,16 +53,17 @@
     var mySocket = new WebSocket("ws://example.com/tests/dom/security/test/csp/file_upgrade_insecure");
     mySocket.onopen = function(e) {
       if (mySocket.url.includes("wss://")) {
         window.parent.postMessage({result: "websocket-ok"}, "*");
       }
       else {
         window.parent.postMessage({result: "websocket-error"}, "*");
       }
+      mySocket.close();
     };
     mySocket.onerror = function(e) {
       window.parent.postMessage({result: "websocket-unexpected-error"}, "*");
     };
   </script>
 
   <!-- form action: (upgrade POST from http:// to https://) -->
   <iframe name='formFrame' id='formFrame'></iframe>
--- a/dom/worklet/Worklet.cpp
+++ b/dom/worklet/Worklet.cpp
@@ -200,19 +200,16 @@ public:
 
     (void) new XPCWrappedNativeScope(cx, globalObj);
 
     JS::CompileOptions compileOptions(cx);
     compileOptions.setIntroductionType("Worklet");
     compileOptions.setFileAndLine(NS_ConvertUTF16toUTF8(mURL).get(), 0);
     compileOptions.setVersion(JSVERSION_DEFAULT);
     compileOptions.setIsRunOnce(true);
-
-    // We only need the setNoScriptRval bit when compiling off-thread here,
-    // since otherwise nsJSUtils::EvaluateString will set it up for us.
     compileOptions.setNoScriptRval(true);
 
     JSAutoCompartment comp(cx, globalObj);
 
     JS::Rooted<JS::Value> unused(cx);
     if (!JS::Evaluate(cx, compileOptions, buffer, &unused)) {
       ErrorResult error;
       error.MightThrowJSException();
--- a/dom/xbl/nsXBLProtoImplField.cpp
+++ b/dom/xbl/nsXBLProtoImplField.cpp
@@ -422,24 +422,29 @@ nsXBLProtoImplField::InstallField(JS::Ha
   JS::Rooted<JSObject*> scopeObject(cx, xpc::GetScopeForXBLExecution(cx, aBoundNode, addonId));
   NS_ENSURE_TRUE(scopeObject, NS_ERROR_OUT_OF_MEMORY);
   JSAutoCompartment ac(cx, scopeObject);
 
   JS::Rooted<JS::Value> result(cx);
   JS::CompileOptions options(cx);
   options.setFileAndLine(uriSpec.get(), mLineNumber)
          .setVersion(JSVERSION_LATEST);
-  nsJSUtils::EvaluateOptions evalOptions(cx);
-  if (!nsJSUtils::GetScopeChainForElement(cx, boundElement,
-                                          evalOptions.scopeChain)) {
+  JS::AutoObjectVector scopeChain(cx);
+  if (!nsJSUtils::GetScopeChainForElement(cx, boundElement, scopeChain)) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
-  rv = nsJSUtils::EvaluateString(cx, nsDependentString(mFieldText,
-                                                       mFieldTextLength),
-                                 scopeObject, options, evalOptions, &result);
+  rv = NS_OK;
+  {
+    nsJSUtils::ExecutionContext exec(cx, scopeObject);
+    exec.SetScopeChain(scopeChain);
+    exec.CompileAndExec(options, nsDependentString(mFieldText,
+                                                   mFieldTextLength));
+    rv = exec.ExtractReturnValue(&result);
+  }
+
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   if (rv == NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW) {
     // Report the exception now, before we try using the JSContext for
     // the JS_DefineUCProperty call.
     aes.ReportException();
--- a/dom/xslt/xslt/txExecutionState.cpp
+++ b/dom/xslt/xslt/txExecutionState.cpp
@@ -82,17 +82,20 @@ txExecutionState::~txExecutionState()
         txIEvalContext* context = (txIEvalContext*)contextIter.next();
         if (context != mInitialEvalContext) {
             delete context;
         }
     }
 
     txStackIterator handlerIter(&mResultHandlerStack);
     while (handlerIter.hasNext()) {
-        delete (txAXMLEventHandler*)handlerIter.next();
+        txAXMLEventHandler* handler = (txAXMLEventHandler*)handlerIter.next();
+        if (handler != mObsoleteHandler) {
+          delete handler;
+        }
     }
 
     txStackIterator paramIter(&mParamStack);
     while (paramIter.hasNext()) {
         delete (txVariableMap*)paramIter.next();
     }
 
     delete mInitialEvalContext;
@@ -155,16 +158,27 @@ txExecutionState::end(nsresult aResult)
     }
     else if (!mOutputHandler) {
         return NS_OK;
     }
     return mOutputHandler->endDocument(aResult);
 }
 
 void
+txExecutionState::popAndDeleteEvalContext()
+{
+  if (!mEvalContextStack.isEmpty()) {
+    auto ctx = popEvalContext();
+    if (ctx != mInitialEvalContext) {
+      delete ctx;
+    }
+  }
+}
+
+void
 txExecutionState::popAndDeleteEvalContextUntil(txIEvalContext* aContext)
 {
   auto ctx = popEvalContext();
   while (ctx && ctx != aContext) {
     MOZ_RELEASE_ASSERT(ctx != mInitialEvalContext);
     delete ctx;
     ctx = popEvalContext();
   }
--- a/dom/xslt/xslt/txExecutionState.h
+++ b/dom/xslt/xslt/txExecutionState.h
@@ -90,16 +90,18 @@ public:
         nsCOMPtr<nsIAtom> mModeLocalName;
         txVariableMap* mParams;
     };
 
     // Stack functions
     nsresult pushEvalContext(txIEvalContext* aContext);
     txIEvalContext* popEvalContext();
 
+    void popAndDeleteEvalContext();
+
     /**
      * Helper that deletes all entries before |aContext| and then
      * pops it off the stack. The caller must delete |aContext| if
      * desired.
      */
     void popAndDeleteEvalContextUntil(txIEvalContext* aContext);
 
     nsresult pushBool(bool aBool);
--- a/dom/xslt/xslt/txInstructions.cpp
+++ b/dom/xslt/xslt/txInstructions.cpp
@@ -32,26 +32,17 @@ txApplyDefaultElementTemplate::execute(t
                                       mode, &aEs, nullptr, &frame);
 
     aEs.pushTemplateRule(frame, mode, aEs.mTemplateParams);
 
     return aEs.runTemplate(templ);
 }
 
 nsresult
-txApplyImportsEnd::execute(txExecutionState& aEs)
-{
-    aEs.popTemplateRule();
-    aEs.popParamMap();
-    
-    return NS_OK;
-}
-
-nsresult
-txApplyImportsStart::execute(txExecutionState& aEs)
+txApplyImports::execute(txExecutionState& aEs)
 {
     txExecutionState::TemplateRule* rule = aEs.getCurrentTemplateRule();
     // The frame is set to null when there is no current template rule, or
     // when the current template rule is a default template. However this
     // instruction isn't used in default templates.
     if (!rule->mFrame) {
         // XXX ErrorReport: apply-imports instantiated without a current rule
         return NS_ERROR_XSLT_EXECUTION_FAILURE;
@@ -63,17 +54,22 @@ txApplyImportsStart::execute(txExecution
     txStylesheet::ImportFrame* frame = 0;
     txExpandedName mode(rule->mModeNsId, rule->mModeLocalName);
     txInstruction* templ =
         aEs.mStylesheet->findTemplate(aEs.getEvalContext()->getContextNode(),
                                       mode, &aEs, rule->mFrame, &frame);
 
     aEs.pushTemplateRule(frame, mode, rule->mParams);
 
-    return aEs.runTemplate(templ);
+    rv = aEs.runTemplate(templ);
+
+    aEs.popTemplateRule();
+    aEs.popParamMap();
+
+    return rv;
 }
 
 txApplyTemplates::txApplyTemplates(const txExpandedName& aMode)
     : mMode(aMode)
 {
 }
 
 nsresult
@@ -469,17 +465,17 @@ txLoopNodeSet::txLoopNodeSet(txInstructi
 
 nsresult
 txLoopNodeSet::execute(txExecutionState& aEs)
 {
     aEs.popTemplateRule();
     txNodeSetContext* context =
         static_cast<txNodeSetContext*>(aEs.getEvalContext());
     if (!context->hasNext()) {
-        delete aEs.popEvalContext();
+        aEs.popAndDeleteEvalContext();
 
         return NS_OK;
     }
 
     context->next();
     aEs.gotoInstruction(mTarget);
     
     return NS_OK;
--- a/dom/xslt/xslt/txInstructions.h
+++ b/dom/xslt/xslt/txInstructions.h
@@ -42,23 +42,17 @@ public:
 
 
 class txApplyDefaultElementTemplate : public txInstruction
 {
 public:
     TX_DECL_TXINSTRUCTION
 };
 
-class txApplyImportsEnd : public txInstruction
-{
-public:
-    TX_DECL_TXINSTRUCTION
-};
-
-class txApplyImportsStart : public txInstruction
+class txApplyImports : public txInstruction
 {
 public:
     TX_DECL_TXINSTRUCTION
 };
 
 class txApplyTemplates : public txInstruction
 {
 public:
--- a/dom/xslt/xslt/txStylesheetCompileHandlers.cpp
+++ b/dom/xslt/xslt/txStylesheetCompileHandlers.cpp
@@ -1307,34 +1307,29 @@ txFnText(const nsAString& aStr, txStyles
     NS_ENSURE_SUCCESS(rv, rv);
 
     return NS_OK;
 }
 
 /*
   xsl:apply-imports
 
-  txApplyImportsStart
-  txApplyImportsEnd
+  txApplyImports
 */
 static nsresult
 txFnStartApplyImports(int32_t aNamespaceID,
                       nsIAtom* aLocalName,
                       nsIAtom* aPrefix,
                       txStylesheetAttr* aAttributes,
                       int32_t aAttrCount,
                       txStylesheetCompilerState& aState)
 {
     nsresult rv = NS_OK;
 
-    nsAutoPtr<txInstruction> instr(new txApplyImportsStart);
-    rv = aState.addInstruction(Move(instr));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    instr = new txApplyImportsEnd;
+    nsAutoPtr<txInstruction> instr(new txApplyImports);
     rv = aState.addInstruction(Move(instr));
     NS_ENSURE_SUCCESS(rv, rv);
 
     return aState.pushHandlerTable(gTxIgnoreHandler);
 }
 
 static nsresult
 txFnEndApplyImports(txStylesheetCompilerState& aState)
--- a/extensions/gio/nsGIOProtocolHandler.cpp
+++ b/extensions/gio/nsGIOProtocolHandler.cpp
@@ -19,17 +19,17 @@
 #include "nsNetCID.h"
 #include "nsNetUtil.h"
 #include "nsServiceManagerUtils.h"
 #include "nsIURI.h"
 #include "nsIAuthPrompt.h"
 #include "nsIChannel.h"
 #include "nsIInputStream.h"
 #include "nsIProtocolHandler.h"
-#include "nsNullPrincipal.h"
+#include "NullPrincipal.h"
 #include "mozilla/Monitor.h"
 #include "plstr.h"
 #include "prtime.h"
 #include <gio/gio.h>
 #include <algorithm>
 
 #define MOZ_GIO_SCHEME              "moz-gio"
 #define MOZ_GIO_SUPPORTED_PROTOCOLS "network.gio.supported-protocols"
--- a/gfx/2d/RecordedEvent.cpp
+++ b/gfx/2d/RecordedEvent.cpp
@@ -1294,41 +1294,50 @@ RecordedSourceSurfaceCreation::~Recorded
   if (mDataOwned) {
     delete [] mData;
   }
 }
 
 bool
 RecordedSourceSurfaceCreation::PlayEvent(Translator *aTranslator) const
 {
+  if (!mData) {
+    return false;
+  }
+
   RefPtr<SourceSurface> src = aTranslator->GetReferenceDrawTarget()->
     CreateSourceSurfaceFromData(mData, mSize, mSize.width * BytesPerPixel(mFormat), mFormat);
   aTranslator->AddSourceSurface(mRefPtr, src);
   return true;
 }
 
 void
 RecordedSourceSurfaceCreation::RecordToStream(ostream &aStream) const
 {
   WriteElement(aStream, mRefPtr);
   WriteElement(aStream, mSize);
   WriteElement(aStream, mFormat);
+  MOZ_ASSERT(mData);
   for (int y = 0; y < mSize.height; y++) {
     aStream.write((const char*)mData + y * mStride, BytesPerPixel(mFormat) * mSize.width);
   }
 }
 
 RecordedSourceSurfaceCreation::RecordedSourceSurfaceCreation(istream &aStream)
   : RecordedEvent(SOURCESURFACECREATION), mDataOwned(true)
 {
   ReadElement(aStream, mRefPtr);
   ReadElement(aStream, mSize);
   ReadElement(aStream, mFormat);
-  mData = (uint8_t*)new char[mSize.width * mSize.height * BytesPerPixel(mFormat)];
-  aStream.read((char*)mData, mSize.width * mSize.height * BytesPerPixel(mFormat));
+  mData = (uint8_t*)new (fallible) char[mSize.width * mSize.height * BytesPerPixel(mFormat)];
+  if (!mData) {
+    gfxWarning() << "RecordedSourceSurfaceCreation failed to allocate data";
+  } else {
+    aStream.read((char*)mData, mSize.width * mSize.height * BytesPerPixel(mFormat));
+  }
 }
 
 void
 RecordedSourceSurfaceCreation::OutputSimpleEventInfo(stringstream &aStringStream) const
 {
   aStringStream << "[" << mRefPtr << "] SourceSurface created (Size: " << mSize.width << "x" << mSize.height << ")";
 }
 
--- a/gfx/gl/GLLibraryEGL.cpp
+++ b/gfx/gl/GLLibraryEGL.cpp
@@ -149,17 +149,17 @@ GetAndInitWARPDisplay(GLLibraryEGL& egl,
 
 static bool
 IsAccelAngleSupported(const nsCOMPtr<nsIGfxInfo>& gfxInfo,
                       nsACString* const out_failureId)
 {
     if (CompositorThreadHolder::IsInCompositorThread()) {
         // We can only enter here with WebRender, so assert that this is a
         // WebRender-enabled build.
-#ifndef MOZ_ENABLE_WEBRENDER
+#ifndef MOZ_BUILD_WEBRENDER
         MOZ_ASSERT(false);
 #endif
         return true;
     }
     int32_t angleSupport;
     nsCString failureId;
     gfxUtils::ThreadSafeGetFeatureStatus(gfxInfo,
                                          nsIGfxInfo::FEATURE_WEBGL_ANGLE,
--- a/gfx/layers/LayersTypes.h
+++ b/gfx/layers/LayersTypes.h
@@ -41,17 +41,16 @@ class TextureHost;
 
 #undef NONE
 #undef OPAQUE
 
 enum class LayersBackend : int8_t {
   LAYERS_NONE = 0,
   LAYERS_BASIC,
   LAYERS_OPENGL,
-  LAYERS_D3D9,
   LAYERS_D3D11,
   LAYERS_CLIENT,
   LAYERS_WR,
   LAYERS_LAST
 };
 
 enum class BufferMode : int8_t {
   BUFFER_NONE,
--- a/gfx/layers/client/CanvasClient.cpp
+++ b/gfx/layers/client/CanvasClient.cpp
@@ -331,19 +331,17 @@ TexClientFromReadback(SharedSurface* src
       ScopedPackState scopedPackState(gl);
 
       MOZ_ASSERT(mapped.stride/4 == mapped.size.width);
       gl->raw_fReadPixels(0, 0, width, height, readFormat, readType, mapped.data);
     }
 
     // RB_SWAPPED doesn't work with D3D11. (bug 1051010)
     // RB_SWAPPED doesn't work with Basic. (bug ???????)
-    // RB_SWAPPED doesn't work with D3D9. (bug ???????)
     bool layersNeedsManualSwap = layersBackend == LayersBackend::LAYERS_BASIC ||
-                                 layersBackend == LayersBackend::LAYERS_D3D9 ||
                                  layersBackend == LayersBackend::LAYERS_D3D11;
     if (texClient->HasFlags(TextureFlags::RB_SWAPPED) &&
         layersNeedsManualSwap)
     {
       size_t pixels = width * height;
       uint8_t* itr = mapped.data;
       for (size_t i = 0; i < pixels; i++) {
         SwapRB_R8G8B8A8(itr);
--- a/gfx/layers/client/ClientLayerManager.cpp
+++ b/gfx/layers/client/ClientLayerManager.cpp
@@ -821,17 +821,16 @@ ClientLayerManager::HandleMemoryPressure
 
 void
 ClientLayerManager::GetBackendName(nsAString& aName)
 {
   switch (mForwarder->GetCompositorBackendType()) {
     case LayersBackend::LAYERS_NONE: aName.AssignLiteral("None"); return;
     case LayersBackend::LAYERS_BASIC: aName.AssignLiteral("Basic"); return;
     case LayersBackend::LAYERS_OPENGL: aName.AssignLiteral("OpenGL"); return;
-    case LayersBackend::LAYERS_D3D9: aName.AssignLiteral("Direct3D 9"); return;
     case LayersBackend::LAYERS_D3D11: {
 #ifdef XP_WIN
       if (DeviceManagerDx::Get()->IsWARP()) {
         aName.AssignLiteral("Direct3D 11 WARP");
       } else {
         aName.AssignLiteral("Direct3D 11");
       }
 #endif
--- a/gfx/layers/client/ContentClient.cpp
+++ b/gfx/layers/client/ContentClient.cpp
@@ -56,17 +56,16 @@ static TextureFlags TextureFlagsForRotat
   return result;
 }
 
 /* static */ already_AddRefed<ContentClient>
 ContentClient::CreateContentClient(CompositableForwarder* aForwarder)
 {
   LayersBackend backend = aForwarder->GetCompositorBackendType();
   if (backend != LayersBackend::LAYERS_OPENGL &&
-      backend != LayersBackend::LAYERS_D3D9 &&
       backend != LayersBackend::LAYERS_D3D11 &&
       backend != LayersBackend::LAYERS_WR &&
       backend != LayersBackend::LAYERS_BASIC) {
     return nullptr;
   }
 
   bool useDoubleBuffering = false;
 
--- a/gfx/layers/ipc/CompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CompositorBridgeParent.cpp
@@ -1574,17 +1574,17 @@ CompositorBridgeParent::RecvAdoptChild(c
 }
 
 PWebRenderBridgeParent*
 CompositorBridgeParent::AllocPWebRenderBridgeParent(const wr::PipelineId& aPipelineId,
                                                     const LayoutDeviceIntSize& aSize,
                                                     TextureFactoryIdentifier* aTextureFactoryIdentifier,
                                                     uint32_t* aIdNamespace)
 {
-#ifndef MOZ_ENABLE_WEBRENDER
+#ifndef MOZ_BUILD_WEBRENDER
   // Extra guard since this in the parent process and we don't want a malicious
   // child process invoking this codepath before it's ready
   MOZ_RELEASE_ASSERT(false);
 #endif
   MOZ_ASSERT(aPipelineId.mHandle == mRootLayerTreeID);
   MOZ_ASSERT(!mWrBridge);
   MOZ_ASSERT(!mCompositor);
   MOZ_ASSERT(!mCompositorScheduler);
@@ -1609,17 +1609,17 @@ CompositorBridgeParent::AllocPWebRenderB
   sIndirectLayerTrees[pipelineHandle].mWrBridge = mWrBridge;
   *aTextureFactoryIdentifier = mWrBridge->GetTextureFactoryIdentifier();
   return mWrBridge;
 }
 
 bool
 CompositorBridgeParent::DeallocPWebRenderBridgeParent(PWebRenderBridgeParent* aActor)
 {
-#ifndef MOZ_ENABLE_WEBRENDER
+#ifndef MOZ_BUILD_WEBRENDER
   // Extra guard since this in the parent process and we don't want a malicious
   // child process invoking this codepath before it's ready
   MOZ_RELEASE_ASSERT(false);
 #endif
   WebRenderBridgeParent* parent = static_cast<WebRenderBridgeParent*>(aActor);
   {
     MonitorAutoLock lock(*sIndirectLayerTreesLock);
     auto it = sIndirectLayerTrees.find(parent->PipelineId().mHandle);
--- a/gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp
@@ -198,17 +198,17 @@ CrossProcessCompositorBridgeParent::Deal
 }
 
 PWebRenderBridgeParent*
 CrossProcessCompositorBridgeParent::AllocPWebRenderBridgeParent(const wr::PipelineId& aPipelineId,
                                                                 const LayoutDeviceIntSize& aSize,
                                                                 TextureFactoryIdentifier* aTextureFactoryIdentifier,
                                                                 uint32_t *aIdNamespace)
 {
-#ifndef MOZ_ENABLE_WEBRENDER
+#ifndef MOZ_BUILD_WEBRENDER
   // Extra guard since this in the parent process and we don't want a malicious
   // child process invoking this codepath before it's ready
   MOZ_RELEASE_ASSERT(false);
 #endif
   // Check to see if this child process has access to this layer tree.
   if (!LayerTreeOwnerTracker::Get()->IsMapped(aPipelineId.mHandle, OtherPid())) {
     NS_ERROR("Unexpected layers id in AllocPAPZCTreeManagerParent; dropping message...");
     return nullptr;
@@ -233,17 +233,17 @@ CrossProcessCompositorBridgeParent::Allo
   *aIdNamespace = parent->GetIdNameSpace();
 
   return parent;
 }
 
 bool
 CrossProcessCompositorBridgeParent::DeallocPWebRenderBridgeParent(PWebRenderBridgeParent* aActor)
 {
-#ifndef MOZ_ENABLE_WEBRENDER
+#ifndef MOZ_BUILD_WEBRENDER
   // Extra guard since this in the parent process and we don't want a malicious
   // child process invoking this codepath before it's ready
   MOZ_RELEASE_ASSERT(false);
 #endif
   WebRenderBridgeParent* parent = static_cast<WebRenderBridgeParent*>(aActor);
   EraseLayerState(parent->PipelineId().mHandle);
   parent->Release(); // IPDL reference
   return true;
--- a/gfx/skia/skia/src/core/SkScan_Path.cpp
+++ b/gfx/skia/skia/src/core/SkScan_Path.cpp
@@ -587,39 +587,45 @@ static bool clip_to_limit(const SkRegion
     if (limitR.contains(orig.getBounds())) {
         return false;
     }
     reduced->op(orig, limitR, SkRegion::kIntersect_Op);
     return true;
 }
 
 /**
-  * Variant of SkScalarRoundToInt, identical to SkDScalarRoundToInt except when the input fraction
-  * is 0.5. In this case only, round the value down. This is used to round the top and left
-  * of a rectangle, and corresponds to the way the scan converter treats the top and left edges.
+  * Variants of SkScalarRoundToInt, identical to SkDScalarRoundToInt except when the input fraction
+  * is 0.5. When SK_RASTERIZE_EVEN_ROUNDING is enabled, we must bias the result before rounding to
+  * account for potential FDot6 rounding edge-cases.
+  */
+#ifdef SK_RASTERIZE_EVEN_ROUNDING
+static const double kRoundBias = 0.5 / SK_FDot6One;
+#else
+static const double kRoundBias = 0.0;
+#endif
+
+/**
+  * Round the value down. This is used to round the top and left of a rectangle,
+  * and corresponds to the way the scan converter treats the top and left edges.
   */
 static inline int round_down_to_int(SkScalar x) {
     double xx = x;
-    xx += 0.5;
-    double floorXX = floor(xx);
-    return (int)floorXX - (xx == floorXX);
+    xx -= 0.5 + kRoundBias;
+    return (int)ceil(xx);
 }
 
-#ifdef SK_RASTERIZE_EVEN_ROUNDING
 /**
-  * Variant of SkDScalarRoundToInt that allows offseting the input by a small fraction
-  * while trying to preserve intermediate double-precision (rather than directly adding
-  * the bias to the input at lower single-precision).
+  * Round the value up. This is used to round the bottom and right of a rectangle,
+  * and corresponds to the way the scan converter treats the bottom and right edges.
   */
-static inline int round_biased_to_int(SkScalar x, SkScalar bias) {
+static inline int round_up_to_int(SkScalar x) {
     double xx = x;
-    xx += 0.5 + bias;
+    xx += 0.5 + kRoundBias;
     return (int)floor(xx);
 }
-#endif
 
 /**
   *  Variant of SkRect::round() that explicitly performs the rounding step (i.e. floor(x + 0.5))
   *  using double instead of SkScalar (float). It does this by calling SkDScalarRoundToInt(),
   *  which may be slower than calling SkScalarRountToInt(), but gives slightly more accurate
   *  results. Also rounds top and left using double, flooring when the fraction is exactly 0.5f.
   *
   *  e.g.
@@ -630,36 +636,31 @@ static inline int round_biased_to_int(Sk
   *      SkASSERT(0 == ileft);  // <--- succeeds
   *      SkScalar right = 0.49999997f;
   *      int iright = SkScalarRoundToInt(right);
   *      SkASSERT(0 == iright);  // <--- fails
   *      iright = SkDScalarRoundToInt(right);
   *      SkASSERT(0 == iright);  // <--- succeeds
   *
   *
-  *  If using SK_RASTERIZE_EVEN_ROUNDING, we need to ensure that bottom and right account for
-  *  edges bounded by this rect being rounded to FDot6 format before being later rounded to an
-  *  integer. For example, a value like 0.499 can be below 0.5, but round to 0.5 as FDot6, which
-  *  would finally round to the integer 1, instead of just rounding to 0.
+  *  If using SK_RASTERIZE_EVEN_ROUNDING, we need to ensure we account for edges bounded by this
+  *  rect being rounded to FDot6 format before being later rounded to an integer. For example, a
+  *  value like 0.499 can be below 0.5, but round to 0.5 as FDot6, which would finally round to
+  *  the integer 1, instead of just rounding to 0.
   *
   *  To handle this, a small bias of half an FDot6 increment is added before actually rounding to
   *  an integer value. This simulates the rounding of SkScalarRoundToFDot6 without incurring the
   *  range loss of converting to FDot6 format first, preserving the integer range for the SkIRect.
-  *  Thus, bottom and right are rounded in this manner (biased up), ensuring the rect is large enough.
-  *  Top and left can round as normal since they will round (biased down) to values less or equal
-  *  to the desired rect origin.
+  *  Thus, bottom and right are rounded in this manner (biased up), ensuring the rect is large
+  *  enough.
   */
 static void round_asymmetric_to_int(const SkRect& src, SkIRect* dst) {
     SkASSERT(dst);
     dst->set(round_down_to_int(src.fLeft), round_down_to_int(src.fTop),
-#ifdef SK_RASTERIZE_EVEN_ROUNDING
-             round_biased_to_int(src.fRight, 0.5f / SK_FDot6One), round_biased_to_int(src.fBottom, 0.5f / SK_FDot6One));
-#else
-             SkDScalarRoundToInt(src.fRight), SkDScalarRoundToInt(src.fBottom));
-#endif
+             round_up_to_int(src.fRight), round_up_to_int(src.fBottom));
 }
 
 void SkScan::FillPath(const SkPath& path, const SkRegion& origClip,
                       SkBlitter* blitter) {
     if (origClip.isEmpty()) {
         return;
     }
 
--- a/gfx/tests/gtest/TestCompositor.cpp
+++ b/gfx/tests/gtest/TestCompositor.cpp
@@ -58,19 +58,16 @@ static already_AddRefed<Compositor> Crea
                                    true);
     compositor->SetDestinationSurfaceSize(IntSize(gCompWidth, gCompHeight));
   } else if (backend == LayersBackend::LAYERS_BASIC) {
     compositor = new BasicCompositor(nullptr, widget);
 #ifdef XP_WIN
   } else if (backend == LayersBackend::LAYERS_D3D11) {
     //compositor = new CompositorD3D11();
     MOZ_CRASH(); // No support yet
-  } else if (backend == LayersBackend::LAYERS_D3D9) {
-    //compositor = new CompositorD3D9(this, mWidget);
-    MOZ_CRASH(); // No support yet
 #endif
   }
   nsCString failureReason;
   if (!compositor || !compositor->Initialize(&failureReason)) {
     printf_stderr("Failed to construct layer manager for the requested backend\n");
     abort();
   }
 
deleted file mode 100644
--- a/gfx/thebes/gfxFontconfigFonts.cpp
+++ /dev/null
@@ -1,2262 +0,0 @@
-/* -*- Mode: C++; tab-width: 20; 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 "prlink.h"
-#include "gfxTypes.h"
-
-#include "nsTArray.h"
-
-#include "gfxContext.h"
-#ifdef MOZ_WIDGET_GTK
-#include "gfxPlatformGtk.h"
-#endif
-#include "gfxFontconfigFonts.h"
-#include "gfxFT2FontBase.h"
-#include "gfxFT2Utils.h"
-#include "harfbuzz/hb.h"
-#include "harfbuzz/hb-glib.h"
-#include "harfbuzz/hb-ot.h"
-#include "nsUnicodeProperties.h"
-#include "nsUnicodeScriptCodes.h"
-#include "gfxFontconfigUtils.h"
-#include "gfxUserFontSet.h"
-#include "gfxFontConstants.h"
-#include "nsGkAtoms.h"
-#include "nsILanguageAtomService.h"
-#include "nsServiceManagerUtils.h"
-
-#include <cairo.h>
-#include <cairo-ft.h>
-#include "mozilla/gfx/HelpersCairo.h"
-
-#include <fontconfig/fcfreetype.h>
-#include <pango/pango.h>
-
-#include FT_TRUETYPE_TABLES_H
-
-#ifdef MOZ_WIDGET_GTK
-#include <gdk/gdk.h>
-#endif
-
-#include <math.h>
-
-using namespace mozilla;
-using namespace mozilla::unicode;
-
-#define PRINTING_FC_PROPERTY "gfx.printing"
-
-static PangoLanguage *GuessPangoLanguage(nsIAtom *aLanguage);
-
-static cairo_scaled_font_t *
-CreateScaledFont(FcPattern *aPattern, cairo_font_face_t *aFace);
-
-static FT_Library gFTLibrary;
-
-// FC_FAMILYLANG and FC_FULLNAME were introduced in fontconfig-2.2.97
-// and so fontconfig-2.3.0 (2005).
-#ifndef FC_FAMILYLANG
-#define FC_FAMILYLANG "familylang"
-#endif
-#ifndef FC_FULLNAME
-#define FC_FULLNAME "fullname"
-#endif
-
-static PRFuncPtr
-FindFunctionSymbol(const char *name)
-{
-    PRLibrary *lib = nullptr;
-    PRFuncPtr result = PR_FindFunctionSymbolAndLibrary(name, &lib);
-    if (lib) {
-        PR_UnloadLibrary(lib);
-    }
-
-    return result;
-}
-
-static bool HasChar(FcPattern *aFont, FcChar32 wc)
-{
-    FcCharSet *charset = nullptr;
-    FcPatternGetCharSet(aFont, FC_CHARSET, 0, &charset);
-
-    return charset && FcCharSetHasChar(charset, wc);
-}
-
-/**
- * gfxFcFontEntry:
- *
- * An abstract base class of for gfxFontEntry implementations used by
- * gfxFcFont and gfxUserFontSet.
- */
-
-class gfxFcFontEntry : public gfxFontEntry {
-public:
-    // For all FontEntrys attached to gfxFcFonts, there will be only one
-    // pattern in this array.  This is always a font pattern, not a fully
-    // resolved pattern.  gfxFcFont only uses this to construct a PangoFont.
-    //
-    // FontEntrys for src:local() fonts in gfxUserFontSet may return more than
-    // one pattern.  (See comment in gfxUserFcFontEntry.)
-    const nsTArray< nsCountedRef<FcPattern> >& GetPatterns()
-    {
-        return mPatterns;
-    }
-
-    static gfxFcFontEntry *LookupFontEntry(cairo_font_face_t *aFace)
-    {
-        return static_cast<gfxFcFontEntry*>
-            (cairo_font_face_get_user_data(aFace, &sFontEntryKey));
-    }
-
-    // override the gfxFontEntry impl to read the name from fontconfig
-    // instead of trying to get the 'name' table, as we don't implement
-    // GetFontTable() here
-    virtual nsString RealFaceName();
-
-    // This is needed to make gfxFontEntry::HasCharacter(aCh) work.
-    virtual bool TestCharacterMap(uint32_t aCh)
-    {
-        for (uint32_t i = 0; i < mPatterns.Length(); ++i) {
-            if (HasChar(mPatterns[i], aCh)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-protected:
-    explicit gfxFcFontEntry(const nsAString& aName)
-        : gfxFontEntry(aName)
-    {
-    }
-
-    // One pattern is the common case and some subclasses rely on successful
-    // addition of the first element to the array.
-    AutoTArray<nsCountedRef<FcPattern>,1> mPatterns;
-
-    static cairo_user_data_key_t sFontEntryKey;
-};
-
-cairo_user_data_key_t gfxFcFontEntry::sFontEntryKey;
-
-nsString
-gfxFcFontEntry::RealFaceName()
-{
-    FcChar8 *name;
-    if (!mPatterns.IsEmpty()) {
-        if (FcPatternGetString(mPatterns[0],
-                               FC_FULLNAME, 0, &name) == FcResultMatch) {
-            return NS_ConvertUTF8toUTF16((const char*)name);
-        }
-        if (FcPatternGetString(mPatterns[0],
-                               FC_FAMILY, 0, &name) == FcResultMatch) {
-            NS_ConvertUTF8toUTF16 result((const char*)name);
-            if (FcPatternGetString(mPatterns[0],
-                                   FC_STYLE, 0, &name) == FcResultMatch) {
-                result.Append(' ');
-                AppendUTF8toUTF16((const char*)name, result);
-            }
-            return result;
-        }
-    }
-    // fall back to gfxFontEntry implementation (only works for sfnt fonts)
-    return gfxFontEntry::RealFaceName();
-}
-
-/**
- * gfxSystemFcFontEntry:
- *
- * An implementation of gfxFcFontEntry used by gfxFcFonts for system fonts,
- * including those from regular family-name based font selection as well as
- * those from src:local().
- *
- * All gfxFcFonts using the same cairo_font_face_t share the same FontEntry. 
- */
-
-class gfxSystemFcFontEntry : public gfxFcFontEntry {
-public:
-    // For memory efficiency, aFontPattern should be a font pattern,
-    // not a fully resolved pattern.
-    gfxSystemFcFontEntry(cairo_font_face_t *aFontFace,
-                         FcPattern *aFontPattern,
-                         const nsAString& aName)
-        : gfxFcFontEntry(aName), mFontFace(aFontFace),
-          mFTFace(nullptr), mFTFaceInitialized(false)
-    {
-        cairo_font_face_reference(mFontFace);
-        cairo_font_face_set_user_data(mFontFace, &sFontEntryKey, this, nullptr);
-
-        // mPatterns is an AutoTArray with 1 space always available, so the
-        // AppendElement always succeeds.
-        // FIXME: Make this infallible after bug 968520 is done.
-        MOZ_ALWAYS_TRUE(mPatterns.AppendElement(fallible));
-        mPatterns[0] = aFontPattern;
-
-        FcChar8 *name;
-        if (FcPatternGetString(aFontPattern,
-                               FC_FAMILY, 0, &name) == FcResultMatch) {
-            mFamilyName = NS_ConvertUTF8toUTF16((const char*)name);
-        }
-    }
-
-    ~gfxSystemFcFontEntry()
-    {
-        cairo_font_face_set_user_data(mFontFace,
-                                      &sFontEntryKey,
-                                      nullptr,
-                                      nullptr);
-        cairo_font_face_destroy(mFontFace);
-    }
-
-    virtual void ForgetHBFace() override;
-    virtual void ReleaseGrFace(gr_face* aFace) override;
-
-protected:
-    virtual nsresult
-    CopyFontTable(uint32_t aTableTag, nsTArray<uint8_t>& aBuffer) override;
-
-    void MaybeReleaseFTFace();
-
-private:
-    cairo_font_face_t *mFontFace;
-    FT_Face            mFTFace;
-    bool               mFTFaceInitialized;
-};
-
-nsresult
-gfxSystemFcFontEntry::CopyFontTable(uint32_t aTableTag,
-                                    nsTArray<uint8_t>& aBuffer)
-{
-    if (!mFTFaceInitialized) {
-        mFTFaceInitialized = true;
-        FcChar8 *filename;
-        if (FcPatternGetString(mPatterns[0], FC_FILE, 0, &filename) != FcResultMatch) {
-            return NS_ERROR_FAILURE;
-        }
-        int index;
-        if (FcPatternGetInteger(mPatterns[0], FC_INDEX, 0, &index) != FcResultMatch) {
-            index = 0; // default to 0 if not found in pattern
-        }
-        if (FT_New_Face(gfxPangoFontGroup::GetFTLibrary(),
-                        (const char*)filename, index, &mFTFace) != 0) {
-            return NS_ERROR_FAILURE;
-        }
-    }
-
-    if (!mFTFace) {
-        return NS_ERROR_NOT_AVAILABLE;
-    }
-
-    FT_ULong length = 0;
-    if (FT_Load_Sfnt_Table(mFTFace, aTableTag, 0, nullptr, &length) != 0) {
-        return NS_ERROR_NOT_AVAILABLE;
-    }
-    if (!aBuffer.SetLength(length, fallible)) {
-        return NS_ERROR_OUT_OF_MEMORY;
-    }
-    if (FT_Load_Sfnt_Table(mFTFace, aTableTag, 0, aBuffer.Elements(), &length) != 0) {
-        aBuffer.Clear();
-        return NS_ERROR_FAILURE;
-    }
-
-    return NS_OK;
-}
-
-void
-gfxSystemFcFontEntry::MaybeReleaseFTFace()
-{
-    // don't release if either HB or Gr face still exists
-    if (mHBFace || mGrFace) {
-        return;
-    }
-    if (mFTFace) {
-        FT_Done_Face(mFTFace);
-        mFTFace = nullptr;
-    }
-    mFTFaceInitialized = false;
-}
-
-void
-gfxSystemFcFontEntry::ForgetHBFace()
-{
-    gfxFontEntry::ForgetHBFace();
-    MaybeReleaseFTFace();
-}
-
-void
-gfxSystemFcFontEntry::ReleaseGrFace(gr_face* aFace)
-{
-    gfxFontEntry::ReleaseGrFace(aFace);
-    MaybeReleaseFTFace();
-}
-
-// A namespace for @font-face family names in FcPatterns so that fontconfig
-// aliases do not pick up families from @font-face rules and so that
-// fontconfig rules can distinguish between web fonts and platform fonts.
-// http://lists.freedesktop.org/archives/fontconfig/2008-November/003037.html
-#define FONT_FACE_FAMILY_PREFIX "@font-face:"
-
-/**
- * gfxUserFcFontEntry:
- *
- * An abstract class for objects in a gfxUserFontSet that can provide
- * FcPattern* handles to fonts.
- *
- * Separate implementations of this class support local fonts from src:local()
- * and web fonts from src:url().
- */
-
-// There is a one-to-one correspondence between gfxUserFcFontEntry objects and
-// @font-face rules, but sometimes a one-to-many correspondence between font
-// entries and font patterns.
-//
-// http://www.w3.org/TR/2002/WD-css3-webfonts-20020802#font-descriptions
-// provided a font-size descriptor to specify the sizes supported by the face,
-// but the "Editor's Draft 27 June 2008"
-// http://dev.w3.org/csswg/css3-fonts/#font-resources does not provide such a
-// descriptor, and Mozilla does not recognize such a descriptor.
-//
-// Font face names used in src:local() also do not usually specify a size.
-//
-// PCF format fonts have each size in a different file, and each of these
-// files is referenced by its own pattern, but really these are each
-// different sizes of one face with one name.
-//
-// Multiple patterns in an entry also effectively deals with a set of
-// PostScript Type 1 font files that all have the same face name but are in
-// several files because of the limit on the number of glyphs in a Type 1 font
-// file.  (e.g. Computer Modern.)
-
-class gfxUserFcFontEntry : public gfxFcFontEntry {
-protected:
-    explicit gfxUserFcFontEntry(const nsAString& aFontName,
-                       uint16_t aWeight,
-                       int16_t aStretch,
-                       uint8_t aStyle)
-        : gfxFcFontEntry(aFontName)
-    {
-        mStyle = aStyle;
-        mWeight = aWeight;
-        mStretch = aStretch;
-    }
-
-    // Helper function to change a pattern so that it matches the CSS style
-    // descriptors and so gets properly sorted in font selection.  This also
-    // avoids synthetic style effects being added by the renderer when the
-    // style of the font itself does not match the descriptor provided by the
-    // author.
-    void AdjustPatternToCSS(FcPattern *aPattern);
-};
-
-void
-gfxUserFcFontEntry::AdjustPatternToCSS(FcPattern *aPattern)
-{
-    int fontWeight = -1;
-    FcPatternGetInteger(aPattern, FC_WEIGHT, 0, &fontWeight);
-    int cssWeight = gfxFontconfigUtils::FcWeightForBaseWeight(mWeight / 100);
-    if (cssWeight != fontWeight) {
-        FcPatternDel(aPattern, FC_WEIGHT);
-        FcPatternAddInteger(aPattern, FC_WEIGHT, cssWeight);
-    }
-
-    int fontSlant;
-    FcResult res = FcPatternGetInteger(aPattern, FC_SLANT, 0, &fontSlant);
-    // gfxFontEntry doesn't understand the difference between oblique
-    // and italic.
-    if (res != FcResultMatch ||
-        IsItalic() != (fontSlant != FC_SLANT_ROMAN)) {
-        FcPatternDel(aPattern, FC_SLANT);
-        FcPatternAddInteger(aPattern, FC_SLANT,
-                            IsItalic() ? FC_SLANT_OBLIQUE : FC_SLANT_ROMAN);
-    }
-
-    int fontWidth = -1;
-    FcPatternGetInteger(aPattern, FC_WIDTH, 0, &fontWidth);
-    int cssWidth = gfxFontconfigUtils::FcWidthForThebesStretch(mStretch);
-    if (cssWidth != fontWidth) {
-        FcPatternDel(aPattern, FC_WIDTH);
-        FcPatternAddInteger(aPattern, FC_WIDTH, cssWidth);
-    }
-
-    // Ensure that there is a fullname property (if there is a family
-    // property) so that fontconfig rules can identify the real name of the
-    // font, because the family property will be replaced.
-    FcChar8 *unused;
-    if (FcPatternGetString(aPattern,
-                           FC_FULLNAME, 0, &unused) == FcResultNoMatch) {
-        nsAutoCString fullname;
-        if (gfxFontconfigUtils::GetFullnameFromFamilyAndStyle(aPattern,
-                                                              &fullname)) {
-            FcPatternAddString(aPattern, FC_FULLNAME,
-                               gfxFontconfigUtils::ToFcChar8(fullname));
-        }
-    }
-
-    nsAutoCString family;
-    family.Append(FONT_FACE_FAMILY_PREFIX);
-    AppendUTF16toUTF8(Name(), family);
-
-    FcPatternDel(aPattern, FC_FAMILY);
-    FcPatternDel(aPattern, FC_FAMILYLANG);
-    FcPatternAddString(aPattern, FC_FAMILY,
-                       gfxFontconfigUtils::ToFcChar8(family));
-}
-
-/**
- * gfxLocalFcFontEntry:
- *
- * An implementation of gfxUserFcFontEntry for local fonts from src:local().
- *
- * This class is used only in gfxUserFontSet and for providing FcPattern*
- * handles to system fonts for font selection.  gfxFcFonts created from these
- * patterns will use gfxSystemFcFontEntrys, which may be shared with
- * gfxFcFonts from regular family-name based font selection.
- */
-
-class gfxLocalFcFontEntry : public gfxUserFcFontEntry {
-public:
-    gfxLocalFcFontEntry(const nsAString& aFontName,
-                        uint16_t aWeight,
-                        int16_t aStretch,
-                        uint8_t aStyle,
-                        const nsTArray< nsCountedRef<FcPattern> >& aPatterns)
-        : gfxUserFcFontEntry(aFontName, aWeight, aStretch, aStyle)
-    {
-        if (!mPatterns.SetCapacity(aPatterns.Length(), fallible))
-            return; // OOM
-
-        for (uint32_t i = 0; i < aPatterns.Length(); ++i) {
-            FcPattern *pattern = FcPatternDuplicate(aPatterns.ElementAt(i));
-            if (!pattern)
-                return; // OOM
-
-            AdjustPatternToCSS(pattern);
-
-            // FIXME: Make this infallible after bug 968520 is done.
-            MOZ_ALWAYS_TRUE(mPatterns.AppendElement(fallible));
-            mPatterns[i].own(pattern);
-        }
-        mIsLocalUserFont = true;
-    }
-};
-
-/**
- * gfxDownloadedFcFontEntry:
- *
- * An implementation of gfxFcFontEntry for web fonts from src:url().
- * 
- * When a cairo_font_face_t is created for these fonts, the cairo_font_face_t
- * keeps a reference to the FontEntry to keep the font data alive.
- */
-
-class gfxDownloadedFcFontEntry : public gfxUserFcFontEntry {
-public:
-    // This takes ownership of the face and its underlying data
-    gfxDownloadedFcFontEntry(const nsAString& aFontName,
-                             uint16_t aWeight,
-                             int16_t aStretch,
-                             uint8_t aStyle,
-                             const uint8_t *aData, FT_Face aFace)
-        : gfxUserFcFontEntry(aFontName, aWeight, aStretch, aStyle),
-          mFontData(aData), mFace(aFace)
-    {
-        NS_PRECONDITION(aFace != nullptr, "aFace is NULL!");
-        mIsDataUserFont = true;
-        InitPattern();
-    }
-
-    virtual ~gfxDownloadedFcFontEntry();
-
-    // Returns true on success
-    bool SetCairoFace(cairo_font_face_t *aFace);
-
-    virtual hb_blob_t* GetFontTable(uint32_t aTableTag) override;
-
-protected:
-    void InitPattern();
-
-    // mFontData holds the data used to instantiate the FT_Face;
-    // this has to persist until we are finished with the face,
-    // then be released with free().
-    const uint8_t* mFontData;
-
-    FT_Face mFace;
-};
-
-// A property for recording gfxDownloadedFcFontEntrys on FcPatterns.
-static const char *kFontEntryFcProp = "-moz-font-entry";
-
-static FcBool AddDownloadedFontEntry(FcPattern *aPattern,
-                                     gfxDownloadedFcFontEntry *aFontEntry)
-{
-    FcValue value;
-    value.type = FcTypeFTFace; // void* field of union
-    value.u.f = aFontEntry;
-
-    return FcPatternAdd(aPattern, kFontEntryFcProp, value, FcFalse);
-}
-
-static FcBool DelDownloadedFontEntry(FcPattern *aPattern)
-{
-    return FcPatternDel(aPattern, kFontEntryFcProp);
-}
-
-static gfxDownloadedFcFontEntry *GetDownloadedFontEntry(FcPattern *aPattern)
-{
-    FcValue value;
-    if (FcPatternGet(aPattern, kFontEntryFcProp, 0, &value) != FcResultMatch)
-        return nullptr;
-
-    if (value.type != FcTypeFTFace) {
-        NS_NOTREACHED("Wrong type for -moz-font-entry font property");
-        return nullptr;
-    }
-
-    return static_cast<gfxDownloadedFcFontEntry*>(value.u.f);
-}
-
-gfxDownloadedFcFontEntry::~gfxDownloadedFcFontEntry()
-{
-    if (mPatterns.Length() != 0) {
-        // Remove back reference to this font entry and the face in case
-        // anyone holds a reference to the pattern.
-        NS_ASSERTION(mPatterns.Length() == 1,
-                     "More than one pattern in gfxDownloadedFcFontEntry!");
-        DelDownloadedFontEntry(mPatterns[0]);
-        FcPatternDel(mPatterns[0], FC_FT_FACE);
-    }
-    FT_Done_Face(mFace);
-    free((void*)mFontData);
-}
-
-typedef FcPattern* (*QueryFaceFunction)(const FT_Face face,
-                                        const FcChar8 *file, int id,
-                                        FcBlanks *blanks);
-
-void
-gfxDownloadedFcFontEntry::InitPattern()
-{
-    static QueryFaceFunction sQueryFacePtr =
-        reinterpret_cast<QueryFaceFunction>
-        (FindFunctionSymbol("FcFreeTypeQueryFace"));
-    FcPattern *pattern;
-
-    // FcFreeTypeQueryFace is the same function used to construct patterns for
-    // system fonts and so is the preferred function to use for this purpose.
-    // This will set up the langset property, which helps with sorting, and
-    // the foundry, fullname, and fontversion properties, which properly
-    // identify the font to fontconfig rules.  However, FcFreeTypeQueryFace is
-    // available only from fontconfig-2.4.2 (December 2006).  (CentOS 5.0 has
-    // fontconfig-2.4.1.)
-    if (sQueryFacePtr) {
-        // The "file" argument cannot be nullptr (in fontconfig-2.6.0 at
-        // least). The dummy file passed here is removed below.
-        //
-        // When fontconfig scans the system fonts, FcConfigGetBlanks(nullptr)
-        // is passed as the "blanks" argument, which provides that unexpectedly
-        // blank glyphs are elided.  Here, however, we pass nullptr for
-        // "blanks", effectively assuming that, if the font has a blank glyph,
-        // then the author intends any associated character to be rendered
-        // blank.
-        pattern =
-            (*sQueryFacePtr)(mFace,
-                             gfxFontconfigUtils::ToFcChar8(""),
-                             0,
-                             nullptr);
-        if (!pattern)
-            // Either OOM, or fontconfig chose to skip this font because it
-            // has "no encoded characters", which I think means "BDF and PCF
-            // fonts which are not in Unicode (or the effectively equivalent
-            // ISO Latin-1) encoding".
-            return;
-
-        // These properties don't make sense for this face without a file.
-        FcPatternDel(pattern, FC_FILE);
-        FcPatternDel(pattern, FC_INDEX);
-
-    } else {
-        // Do the minimum necessary to construct a pattern for sorting.
-
-        // FC_CHARSET is vital to determine which characters are supported.
-        nsAutoRef<FcCharSet> charset(FcFreeTypeCharSet(mFace, nullptr));
-        // If there are no characters then assume we don't know how to read
-        // this font.
-        if (!charset || FcCharSetCount(charset) == 0)
-            return;
-
-        pattern = FcPatternCreate();
-        FcPatternAddCharSet(pattern, FC_CHARSET, charset);
-
-        // FC_PIXEL_SIZE can be important for font selection of fixed-size
-        // fonts.
-        if (!(mFace->face_flags & FT_FACE_FLAG_SCALABLE)) {
-            for (FT_Int i = 0; i < mFace->num_fixed_sizes; ++i) {
-#if HAVE_FT_BITMAP_SIZE_Y_PPEM
-                double size = FLOAT_FROM_26_6(mFace->available_sizes[i].y_ppem);
-#else
-                double size = mFace->available_sizes[i].height;
-#endif
-                FcPatternAddDouble (pattern, FC_PIXEL_SIZE, size);
-            }
-
-            // Not sure whether this is important;
-            // imitating FcFreeTypeQueryFace:
-            FcPatternAddBool (pattern, FC_ANTIALIAS, FcFalse);
-        }
-
-        // Setting up the FC_LANGSET property is very difficult with the APIs
-        // available prior to FcFreeTypeQueryFace.  Having no FC_LANGSET
-        // property seems better than having a property with an empty LangSet.
-        // With no FC_LANGSET property, fontconfig sort functions will
-        // consider this face to have the same priority as (otherwise equal)
-        // faces that have support for the primary requested language, but
-        // will not consider any language to have been satisfied (and so will
-        // continue to look for a face with language support in fallback
-        // fonts).
-    }
-
-    AdjustPatternToCSS(pattern);
-
-    FcPatternAddFTFace(pattern, FC_FT_FACE, mFace);
-    AddDownloadedFontEntry(pattern, this);
-
-    // There is never more than one pattern
-    // FIXME: Make this infallible after bug 968520 is done.
-    MOZ_ALWAYS_TRUE(mPatterns.AppendElement(fallible));
-    mPatterns[0].own(pattern);
-}
-
-static void ReleaseDownloadedFontEntry(void *data)
-{
-    gfxDownloadedFcFontEntry *downloadedFontEntry =
-        static_cast<gfxDownloadedFcFontEntry*>(data);
-    NS_RELEASE(downloadedFontEntry);
-}
-
-bool gfxDownloadedFcFontEntry::SetCairoFace(cairo_font_face_t *aFace)
-{
-    if (CAIRO_STATUS_SUCCESS !=
-        cairo_font_face_set_user_data(aFace, &sFontEntryKey, this,
-                                      ReleaseDownloadedFontEntry))
-        return false;
-
-    // Hold a reference to this font entry to keep the font face data.
-    NS_ADDREF(this);
-    return true;
-}
-
-hb_blob_t *
-gfxDownloadedFcFontEntry::GetFontTable(uint32_t aTableTag)
-{
-    // The entry already owns the (sanitized) sfnt data in mFontData,
-    // so we can just return a blob that "wraps" the appropriate chunk of it.
-    // The blob should not attempt to free its data, as the entire sfnt data
-    // will be freed when the font entry is deleted.
-    return gfxFontUtils::GetTableFromFontData(mFontData, aTableTag);
-}
-
-/*
- * gfxFcFont
- *
- * This is a gfxFont implementation using a CAIRO_FONT_TYPE_FT
- * cairo_scaled_font created from an FcPattern.
- */
-
-class gfxFcFont : public gfxFontconfigFontBase {
-public:
-    virtual ~gfxFcFont();
-    static already_AddRefed<gfxFcFont>
-    GetOrMakeFont(FcPattern *aRequestedPattern, FcPattern *aFontPattern,
-                  const gfxFontStyle *aFontStyle);
-
-    // return a cloned font resized and offset to simulate sub/superscript glyphs
-    virtual already_AddRefed<gfxFont>
-    GetSubSuperscriptFont(int32_t aAppUnitsPerDevPixel) override;
-
-protected:
-    virtual already_AddRefed<gfxFont> MakeScaledFont(gfxFontStyle *aFontStyle,
-                                                     gfxFloat aFontScale);
-    virtual already_AddRefed<gfxFont> GetSmallCapsFont() override;
-
-private:
-    gfxFcFont(cairo_scaled_font_t *aCairoFont,
-              FcPattern *aPattern,
-              gfxFcFontEntry *aFontEntry,
-              const gfxFontStyle *aFontStyle);
-
-    // key for locating a gfxFcFont corresponding to a cairo_scaled_font
-    static cairo_user_data_key_t sGfxFontKey;
-};
-
-/**
- * gfxFcFontSet:
- *
- * Translation from a desired FcPattern to a sorted set of font references
- * (fontconfig cache data) and (when needed) fonts.
- */
-
-class gfxFcFontSet final {
-public:
-    NS_INLINE_DECL_REFCOUNTING(gfxFcFontSet)
-    
-    explicit gfxFcFontSet(FcPattern *aPattern,
-                               gfxUserFontSet *aUserFontSet)
-        : mSortPattern(aPattern), mUserFontSet(aUserFontSet),
-          mFcFontsTrimmed(0),
-          mHaveFallbackFonts(false)
-    {
-        bool waitForUserFont;
-        mFcFontSet = SortPreferredFonts(waitForUserFont);
-        mWaitingForUserFont = waitForUserFont;
-    }
-
-    // A reference is held by the FontSet.
-    // The caller may add a ref to keep the font alive longer than the FontSet.
-    gfxFcFont *GetFontAt(uint32_t i, const gfxFontStyle *aFontStyle)
-    {
-        if (i >= mFonts.Length() || !mFonts[i].mFont) { 
-            // GetFontPatternAt sets up mFonts
-            FcPattern *fontPattern = GetFontPatternAt(i);
-            if (!fontPattern)
-                return nullptr;
-
-            mFonts[i].mFont =
-                gfxFcFont::GetOrMakeFont(mSortPattern, fontPattern,
-                                         aFontStyle);
-        }
-        return mFonts[i].mFont;
-    }
-
-    FcPattern *GetFontPatternAt(uint32_t i);
-
-    bool WaitingForUserFont() const {
-        return mWaitingForUserFont;
-    }
-
-private:
-    // Private destructor, to discourage deletion outside of Release():
-    ~gfxFcFontSet()
-    {
-    }
-
-    nsReturnRef<FcFontSet> SortPreferredFonts(bool& aWaitForUserFont);
-    nsReturnRef<FcFontSet> SortFallbackFonts();
-
-    struct FontEntry {
-        explicit FontEntry(FcPattern *aPattern) : mPattern(aPattern) {}
-        nsCountedRef<FcPattern> mPattern;
-        RefPtr<gfxFcFont> mFont;
-    };
-
-    struct LangSupportEntry {
-        LangSupportEntry(FcChar8 *aLang, FcLangResult aSupport) :
-            mLang(aLang), mBestSupport(aSupport) {}
-        FcChar8 *mLang;
-        FcLangResult mBestSupport;
-    };
-
-public:
-    // public for nsTArray
-    class LangComparator {
-    public:
-        bool Equals(const LangSupportEntry& a, const FcChar8 *b) const
-        {
-            return FcStrCmpIgnoreCase(a.mLang, b) == 0;
-        }
-    };
-
-private:
-    // The requested pattern
-    nsCountedRef<FcPattern> mSortPattern;
-    // Fonts from @font-face rules
-    RefPtr<gfxUserFontSet> mUserFontSet;
-    // A (trimmed) list of font patterns and fonts that is built up as
-    // required.
-    nsTArray<FontEntry> mFonts;
-    // Holds a list of font patterns that will be trimmed.  This is first set
-    // to a list of preferred fonts.  Then, if/when all the preferred fonts
-    // have been trimmed and added to mFonts, this is set to a list of
-    // fallback fonts.
-    nsAutoRef<FcFontSet> mFcFontSet;
-    // The set of characters supported by the fonts in mFonts.
-    nsAutoRef<FcCharSet> mCharSet;
-    // The index of the next font in mFcFontSet that has not yet been
-    // considered for mFonts.
-    int mFcFontsTrimmed;
-    // True iff fallback fonts are either stored in mFcFontSet or have been
-    // trimmed and added to mFonts (so that mFcFontSet is nullptr).
-    bool mHaveFallbackFonts;
-    // True iff there was a user font set with pending downloads,
-    // so the set may be updated when downloads complete
-    bool mWaitingForUserFont;
-};
-
-// Find the FcPattern for an @font-face font suitable for CSS family |aFamily|
-// and style |aStyle| properties.
-static const nsTArray< nsCountedRef<FcPattern> >*
-FindFontPatterns(gfxUserFontSet *mUserFontSet,
-                 const nsACString &aFamily, uint8_t aStyle,
-                 uint16_t aWeight, int16_t aStretch,
-                 bool& aWaitForUserFont)
-{
-    // Convert to UTF16
-    NS_ConvertUTF8toUTF16 utf16Family(aFamily);
-
-    // needsBold is not used here.  Instead synthetic bold is enabled through
-    // FcFontRenderPrepare when the weight in the requested pattern is
-    // compared against the weight in the font pattern.
-    bool needsBold;
-
-    gfxFontStyle style;
-    style.style = aStyle;
-    style.weight = aWeight;
-    style.stretch = aStretch;
-
-    gfxUserFcFontEntry *fontEntry = nullptr;
-    gfxFontFamily *family = mUserFontSet->LookupFamily(utf16Family);
-    if (family) {
-        gfxUserFontEntry* userFontEntry =
-            mUserFontSet->FindUserFontEntryAndLoad(family, style, needsBold,
-                                                   aWaitForUserFont);
-        if (userFontEntry) {
-            fontEntry = static_cast<gfxUserFcFontEntry*>
-                (userFontEntry->GetPlatformFontEntry());
-        }
-
-        // Accept synthetic oblique for italic and oblique.
-        // xxx - this isn't really ideal behavior, for docs that only use a
-        //       single italic face it will also pull down the normal face
-        //       and probably never use it
-        if (!fontEntry && aStyle != NS_FONT_STYLE_NORMAL) {
-            style.style = NS_FONT_STYLE_NORMAL;
-            userFontEntry =
-                mUserFontSet->FindUserFontEntryAndLoad(family, style,
-                                                       needsBold,
-                                                       aWaitForUserFont);
-            if (userFontEntry) {
-                fontEntry = static_cast<gfxUserFcFontEntry*>
-                    (userFontEntry->GetPlatformFontEntry());
-            }
-        }
-    }
-
-    if (!fontEntry) {
-        return nullptr;
-    }
-
-    return &fontEntry->GetPatterns();
-}
-
-typedef FcBool (*FcPatternRemoveFunction)(FcPattern *p, const char *object,
-                                          int id);
-
-// FcPatternRemove is available in fontconfig-2.3.0 (2005)
-static FcBool
-moz_FcPatternRemove(FcPattern *p, const char *object, int id)
-{
-    static FcPatternRemoveFunction sFcPatternRemovePtr =
-        reinterpret_cast<FcPatternRemoveFunction>
-        (FindFunctionSymbol("FcPatternRemove"));
-
-    if (!sFcPatternRemovePtr)
-        return FcFalse;
-
-    return (*sFcPatternRemovePtr)(p, object, id);
-}
-
-// fontconfig prefers a matching family or lang to pixelsize of bitmap
-// fonts.  CSS suggests a tolerance of 20% on pixelsize.
-static bool
-SizeIsAcceptable(FcPattern *aFont, double aRequestedSize)
-{
-    double size;
-    int v = 0;
-    while (FcPatternGetDouble(aFont,
-                              FC_PIXEL_SIZE, v, &size) == FcResultMatch) {
-        ++v;
-        if (5.0 * fabs(size - aRequestedSize) < aRequestedSize)
-            return true;
-    }
-
-    // No size means scalable
-    return v == 0;
-}
-
-// Sorting only the preferred fonts first usually saves having to sort through
-// every font on the system.
-nsReturnRef<FcFontSet>
-gfxFcFontSet::SortPreferredFonts(bool &aWaitForUserFont)
-{
-    aWaitForUserFont = false;
-
-    gfxFontconfigUtils *utils = gfxFontconfigUtils::GetFontconfigUtils();
-    if (!utils)
-        return nsReturnRef<FcFontSet>();
-
-    // The list of families in mSortPattern has values with both weak and
-    // strong bindings.  Values with strong bindings should be preferred.
-    // Values with weak bindings are default fonts that should be considered
-    // only when the font provides the best support for a requested language
-    // or after other fonts have satisfied all the requested languages.
-    //
-    // There are no direct fontconfig APIs to get the binding type.  The
-    // binding only takes effect in the sort and match functions.
-
-    // |requiredLangs| is a list of requested languages that have not yet been
-    // satisfied.  gfxFontconfigUtils only sets one FC_LANG property value,
-    // but FcConfigSubstitute may add more values (e.g. prepending "en" to
-    // "ja" will use western fonts to render Latin/Arabic numerals in Japanese
-    // text.)
-    AutoTArray<LangSupportEntry,10> requiredLangs;
-    for (int v = 0; ; ++v) {
-        FcChar8 *lang;
-        FcResult result = FcPatternGetString(mSortPattern, FC_LANG, v, &lang);
-        if (result != FcResultMatch) {
-            // No need to check FcPatternGetLangSet() because
-            // gfxFontconfigUtils sets only a string value for FC_LANG and
-            // FcConfigSubstitute cannot add LangSets.
-            NS_ASSERTION(result != FcResultTypeMismatch,
-                         "Expected a string for FC_LANG");
-            break;
-        }
-
-        if (!requiredLangs.Contains(lang, LangComparator())) {
-            FcLangResult bestLangSupport = utils->GetBestLangSupport(lang);
-            if (bestLangSupport != FcLangDifferentLang) {
-                requiredLangs.
-                    AppendElement(LangSupportEntry(lang, bestLangSupport));
-            }
-        }
-    }
-
-    nsAutoRef<FcFontSet> fontSet(FcFontSetCreate());
-    if (!fontSet)
-        return fontSet.out();
-
-    // FcDefaultSubstitute() ensures a slant on mSortPattern, but, if that ever
-    // doesn't happen, Roman will be used.
-    int requestedSlant = FC_SLANT_ROMAN;
-    FcPatternGetInteger(mSortPattern, FC_SLANT, 0, &requestedSlant);
-    double requestedSize = -1.0;
-    FcPatternGetDouble(mSortPattern, FC_PIXEL_SIZE, 0, &requestedSize);
-
-    nsTHashtable<gfxFontconfigUtils::DepFcStrEntry> existingFamilies(32);
-    FcChar8 *family;
-    for (int v = 0;
-         FcPatternGetString(mSortPattern,
-                            FC_FAMILY, v, &family) == FcResultMatch; ++v) {
-        const nsTArray< nsCountedRef<FcPattern> > *familyFonts = nullptr;
-
-        // Is this an @font-face family?
-        bool isUserFont = false;
-        if (mUserFontSet) {
-            // Have some @font-face definitions
-
-            nsDependentCString cFamily(gfxFontconfigUtils::ToCString(family));
-            NS_NAMED_LITERAL_CSTRING(userPrefix, FONT_FACE_FAMILY_PREFIX);
-
-            if (StringBeginsWith(cFamily, userPrefix)) {
-                isUserFont = true;
-
-                // Trim off the prefix
-                nsDependentCSubstring cssFamily(cFamily, userPrefix.Length());
-
-                uint8_t thebesStyle =
-                    gfxFontconfigUtils::FcSlantToThebesStyle(requestedSlant);
-                uint16_t thebesWeight =
-                    gfxFontconfigUtils::GetThebesWeight(mSortPattern);
-                int16_t thebesStretch =
-                    gfxFontconfigUtils::GetThebesStretch(mSortPattern);
-
-                bool waitForUserFont;
-                familyFonts = FindFontPatterns(mUserFontSet, cssFamily,
-                                               thebesStyle,
-                                               thebesWeight, thebesStretch,
-                                               waitForUserFont);
-                if (waitForUserFont) {
-                    aWaitForUserFont = true;
-                }
-            }
-        }
-
-        if (!isUserFont) {
-            familyFonts = &utils->GetFontsForFamily(family);
-        }
-
-        if (!familyFonts || familyFonts->Length() == 0) {
-            // There are no fonts matching this family, so there is no point
-            // in searching for this family in the FontSort.
-            //
-            // Perhaps the original pattern should be retained for
-            // FcFontRenderPrepare.  However, the only a useful config
-