Merge m-c to autoland. a=merge
authorRyan VanderMeulen <ryanvm@gmail.com>
Wed, 31 May 2017 20:50:21 -0400
changeset 361691 5ecd65c9136b6b3c924f91679f89b9e3577c3dbc
parent 361690 f11d37b8446bdb8e81d5a510142c68526c978a98 (current diff)
parent 361674 a8f378825e81daff1279a7d6e940b610912ee6dc (diff)
child 361692 42d88860d41af43de19935ccff75f3901422879c
push id31939
push usercbook@mozilla.com
push dateThu, 01 Jun 2017 11:49:28 +0000
treeherdermozilla-central@d96110d76619 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
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 m-c to autoland. a=merge CLOSED TREE
browser/base/content/tabbrowser.xml
browser/base/content/usercontext.svg
browser/installer/package-manifest.in
dom/browser-element/mochitest/browserElement_SetVisible.js
dom/browser-element/mochitest/browserElement_SetVisibleFrames.js
dom/browser-element/mochitest/browserElement_SetVisibleFrames2.js
dom/browser-element/mochitest/browserElement_VisibilityChange.js
dom/browser-element/mochitest/file_browserElement_SetVisibleFrames2_Outer.html
dom/browser-element/mochitest/file_browserElement_SetVisibleFrames_Outer.html
dom/browser-element/mochitest/priority/chrome.ini
dom/browser-element/mochitest/priority/file_MultipleFrames.html
dom/browser-element/mochitest/priority/file_NestedFramesOuter.html
dom/browser-element/mochitest/priority/file_WebGLContextLost.html
dom/browser-element/mochitest/priority/mochitest.ini
dom/browser-element/mochitest/priority/silence.ogg
dom/browser-element/mochitest/priority/test_Background.html
dom/browser-element/mochitest/priority/test_MultipleFrames.html
dom/browser-element/mochitest/priority/test_NestedFrames.html
dom/browser-element/mochitest/priority/test_Simple.html
dom/browser-element/mochitest/priority/test_Visibility.html
dom/browser-element/mochitest/priority/test_WebGLContextLost.html
dom/browser-element/mochitest/test_browserElement_inproc_SetVisible.html
dom/browser-element/mochitest/test_browserElement_inproc_SetVisibleFrames.html
dom/browser-element/mochitest/test_browserElement_inproc_SetVisibleFrames2.html
dom/browser-element/mochitest/test_browserElement_inproc_VisibilityChange.html
dom/browser-element/mochitest/test_browserElement_oop_SetVisible.html
dom/browser-element/mochitest/test_browserElement_oop_SetVisibleFrames.html
dom/browser-element/mochitest/test_browserElement_oop_SetVisibleFrames2.html
dom/browser-element/mochitest/test_browserElement_oop_VisibilityChange.html
dom/ipc/ContentParent.cpp
layout/base/FrameProperties.cpp
testing/web-platform/meta/html/semantics/forms/the-option-element/option-element-constructor.html.ini
--- a/accessible/base/MarkupMap.h
+++ b/accessible/base/MarkupMap.h
@@ -90,16 +90,20 @@ MARKUPMAP(h4,
 MARKUPMAP(h5,
           New_HyperText,
           roles::HEADING)
 
 MARKUPMAP(h6,
           New_HyperText,
           roles::HEADING)
 
+MARKUPMAP(input,
+          New_HTMLInput,
+          0)
+
 MARKUPMAP(label,
           New_HTMLLabel,
           roles::LABEL)
 
 MARKUPMAP(legend,
           New_HTMLLegend,
           roles::LABEL)
 
--- a/accessible/base/nsAccessibilityService.cpp
+++ b/accessible/base/nsAccessibilityService.cpp
@@ -190,16 +190,29 @@ New_HTMLDefinition(nsIContent* aContent,
   if (aContext->IsList())
     return new HyperTextAccessibleWrap(aContent, aContext->Document());
   return nullptr;
 }
 
 static Accessible* New_HTMLLabel(nsIContent* aContent, Accessible* aContext)
   { return new HTMLLabelAccessible(aContent, aContext->Document()); }
 
+static Accessible* New_HTMLInput(nsIContent* aContent, Accessible* aContext)
+{
+  if (aContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
+                            nsGkAtoms::checkbox, eIgnoreCase)) {
+    return new HTMLCheckboxAccessible(aContent, aContext->Document());
+  }
+  if (aContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
+                            nsGkAtoms::radio, eIgnoreCase)) {
+    return new HTMLRadioButtonAccessible(aContent, aContext->Document());
+  }
+  return nullptr;
+}
+
 static Accessible* New_HTMLOutput(nsIContent* aContent, Accessible* aContext)
   { return new HTMLOutputAccessible(aContent, aContext->Document()); }
 
 static Accessible* New_HTMLProgress(nsIContent* aContent, Accessible* aContext)
   { return new HTMLProgressMeterAccessible(aContent, aContext->Document()); }
 
 static Accessible* New_HTMLSummary(nsIContent* aContent, Accessible* aContext)
   { return new HTMLSummaryAccessible(aContent, aContext->Document()); }
--- a/accessible/tests/mochitest/events/test_scroll.xul
+++ b/accessible/tests/mochitest/events/test_scroll.xul
@@ -59,17 +59,23 @@
       ];
 
       this.unexpectedEventSeq = [
         new invokerChecker(EVENT_SCROLLING_START, getAnchorJumpInTabDocument, 1)
       ];
 
       this.invoke = function loadTabInBackground_invoke()
       {
-        tabBrowser().loadOneTab(aURL, null, "", null, true);
+        tabBrowser().loadOneTab(aURL, {
+          referrerURI: null,
+          charset: "",
+          postData: null,
+          inBackground: true,
+          triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
+        });
       }
 
       this.getID = function loadTabInBackground_getID()
       {
         return "load tab in background: " + aURL;
       }
     }
 
--- a/accessible/tests/mochitest/relations/test_embeds.xul
+++ b/accessible/tests/mochitest/relations/test_embeds.xul
@@ -51,17 +51,23 @@
         return "load uri " + aURI;
       }
     }
 
     function loadOneTab(aURI)
     {
       this.invoke = function loadOneTab_invoke()
       {
-        tabBrowser().loadOneTab(aURI, null, null, null, false);
+        tabBrowser().loadOneTab(aURI, {
+          referrerURI: null,
+          charset: null,
+          postData: null,
+          inBackground: false,
+          triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
+        });
       }
 
       this.eventSeq = [
         new invokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, currentTabDocument)
       ];
 
       this.finalCheck = function loadURI_finalCheck()
       {
--- a/accessible/tests/mochitest/states/test_visibility.html
+++ b/accessible/tests/mochitest/states/test_visibility.html
@@ -48,17 +48,23 @@
     function addTabInvoker(aURL, aFunc)
     {
       this.eventSeq = [
         new invokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, tabDocumentAt, 1)
       ];
 
       this.invoke = function addTabInvoker_invoke()
       {
-        tabBrowser().loadOneTab(aURL, null, "", null, false);
+        tabBrowser().loadOneTab(aURL, {
+          referrerURI: null,
+          charset: "",
+          postData: null,
+          inBackground: false,
+          triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
+        });
       }
 
       this.finalCheck = function addTabInvoker_finalCheck()
       {
         aFunc.call();
       }
 
       this.getID = function addTabInvoker_getID()
--- a/browser/base/content/browser-social.js
+++ b/browser/base/content/browser-social.js
@@ -1,14 +1,14 @@
 /* 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/. */
 
 /* eslint-env mozilla/browser-window */
-/* global OpenGraphBuilder:false, DynamicResizeWatcher:false */
+/* global OpenGraphBuilder:false, DynamicResizeWatcher:false, Utils:false*/
 
 // the "exported" symbols
 var SocialUI,
     SocialShare,
     SocialActivationListener;
 
 (function() {
 "use strict";
@@ -20,16 +20,22 @@ XPCOMUtils.defineLazyGetter(this, "OpenG
 });
 
 XPCOMUtils.defineLazyGetter(this, "DynamicResizeWatcher", function() {
   let tmp = {};
   Cu.import("resource:///modules/Social.jsm", tmp);
   return tmp.DynamicResizeWatcher;
 });
 
+XPCOMUtils.defineLazyGetter(this, "Utils", function() {
+  let tmp = {};
+  Cu.import("resource://gre/modules/sessionstore/Utils.jsm", tmp);
+  return tmp.Utils;
+});
+
 let messageManager = window.messageManager;
 let openUILinkIn = window.openUILinkIn;
 
 SocialUI = {
   _initialized: false,
 
   // Called on delayed startup to initialize the UI
   init: function SocialUI_init() {
@@ -198,17 +204,21 @@ SocialActivationListener = {
           SocialShare.populateProviderMenu();
           if (SocialShare.panel.state == "open") {
             SocialShare.sharePage(provider.origin);
           }
         }
         if (provider.postActivationURL) {
           // if activated from an open share panel, we load the landing page in
           // a background tab
-          gBrowser.loadOneTab(provider.postActivationURL, {inBackground: SocialShare.panel.state == "open"});
+          let triggeringPrincipal = Utils.deserializePrincipal(aMessage.data.triggeringPrincipal);
+          gBrowser.loadOneTab(provider.postActivationURL, {
+            inBackground: SocialShare.panel.state == "open",
+            triggeringPrincipal,
+          });
         }
       });
     }, options);
   }
 }
 
 SocialShare = {
   get _dynamicResizer() {
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -2286,21 +2286,24 @@ function delayedOpenWindow(chrome, flags
   // window.arguments[1] be an integer instead of null.
   setTimeout(function() { openDialog(chrome, "_blank", flags, href, null, null, postData); }, 10);
 }
 
 /* Required because the tab needs time to set up its content viewers and get the load of
    the URI kicked off before becoming the active content area. */
 function delayedOpenTab(aUrl, aReferrer, aCharset, aPostData, aAllowThirdPartyFixup) {
   gBrowser.loadOneTab(aUrl, {
-                      referrerURI: aReferrer,
-                      charset: aCharset,
-                      postData: aPostData,
-                      inBackground: false,
-                      allowThirdPartyFixup: aAllowThirdPartyFixup});
+    referrerURI: aReferrer,
+    charset: aCharset,
+    postData: aPostData,
+    inBackground: false,
+    allowThirdPartyFixup: aAllowThirdPartyFixup,
+    // Bug 1367168: only use systemPrincipal till we can remove that function
+    triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
+  });
 }
 
 var gLastOpenDirectory = {
   _lastDir: null,
   get path() {
     if (!this._lastDir || !this._lastDir.exists()) {
       try {
         this._lastDir = gPrefService.getComplexValue("browser.open.lastDir",
@@ -2598,17 +2601,18 @@ function BrowserViewSourceOfDocument(aAr
       // descriptor for the tab (when possible) or fallback to the network if
       // that fails.  Either way, the view source module will manage the tab's
       // location, so use "about:blank" here to avoid unnecessary redundant
       // requests.
       let tab = tabBrowser.loadOneTab("about:blank", {
         relatedToCurrent: true,
         inBackground: false,
         preferredRemoteType,
-        sameProcessAsFrameLoader: args.browser ? args.browser.frameLoader : null
+        sameProcessAsFrameLoader: args.browser ? args.browser.frameLoader : null,
+        triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
       });
       args.viewSourceBrowser = tabBrowser.getBrowserForTab(tab);
       top.gViewSourceUtils.viewSourceInBrowser(args);
     } else {
       top.gViewSourceUtils.viewSource(args);
     }
   }
 
@@ -3407,17 +3411,18 @@ var PrintPreviewListener = {
   _lastRequestedPrintPreviewTab: null,
 
   _createPPBrowser() {
     let browser = this.getSourceBrowser();
     let preferredRemoteType = browser.remoteType;
     return gBrowser.loadOneTab("about:printpreview", {
       inBackground: true,
       preferredRemoteType,
-      sameProcessAsFrameLoader: browser.frameLoader
+      sameProcessAsFrameLoader: browser.frameLoader,
+      triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
     });
   },
   getPrintPreviewBrowser() {
     if (!this._printPreviewTab) {
       this._printPreviewTab = this._createPPBrowser();
     }
     gBrowser._allowTabChange = true;
     this._lastRequestedPrintPreviewTab = gBrowser.selectedTab = this._printPreviewTab;
@@ -3432,17 +3437,18 @@ var PrintPreviewListener = {
     this._lastRequestedPrintPreviewTab = gBrowser.selectedTab = this._simplifiedPrintPreviewTab;
     gBrowser._allowTabChange = false;
     return gBrowser.getBrowserForTab(this._simplifiedPrintPreviewTab);
   },
   createSimplifiedBrowser() {
     let browser = this.getSourceBrowser();
     this._simplifyPageTab = gBrowser.loadOneTab("about:printpreview", {
       inBackground: true,
-      sameProcessAsFrameLoader: browser.frameLoader
+      sameProcessAsFrameLoader: browser.frameLoader,
+      triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
      });
     return this.getSimplifiedSourceBrowser();
   },
   getSourceBrowser() {
     if (!this._tabBeforePrintPreview) {
       this._tabBeforePrintPreview = gBrowser.selectedTab;
     }
     return this._tabBeforePrintPreview.linkedBrowser;
--- a/browser/base/content/content.js
+++ b/browser/base/content/content.js
@@ -36,16 +36,18 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
   "resource://gre/modules/PrivateBrowsingUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "FormSubmitObserver",
   "resource:///modules/FormSubmitObserver.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "PageMetadata",
   "resource://gre/modules/PageMetadata.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "PlacesUIUtils",
   "resource:///modules/PlacesUIUtils.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Utils",
+  "resource://gre/modules/sessionstore/Utils.jsm");
 XPCOMUtils.defineLazyGetter(this, "PageMenuChild", function() {
   let tmp = {};
   Cu.import("resource://gre/modules/PageMenu.jsm", tmp);
   return new tmp.PageMenuChild();
 });
 XPCOMUtils.defineLazyModuleGetter(this, "WebNavigationFrames",
   "resource://gre/modules/WebNavigationFrames.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Feeds",
@@ -803,17 +805,18 @@ addEventListener("ActivateSocialFeature"
   } else {
     Cu.reportError("Social Service manifest not available");
     return;
   }
 
   sendAsyncMessage("Social:Activation", {
     url: ownerDocument.location.href,
     origin: ownerDocument.nodePrincipal.origin,
-    manifest: data
+    manifest: data,
+    triggeringPrincipal: Utils.serializePrincipal(ownerDocument.nodePrincipal),
   });
 }, true, true);
 
 addMessageListener("ContextMenu:SaveVideoFrameAsImage", (message) => {
   let video = message.objects.target;
   let canvas = content.document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
   canvas.width = video.videoWidth;
   canvas.height = video.videoHeight;
--- a/browser/base/content/nsContextMenu.js
+++ b/browser/base/content/nsContextMenu.js
@@ -1174,17 +1174,18 @@ nsContextMenu.prototype = {
       // In the case of popups, we need to find a non-popup browser window.
       if (!tabBrowser || !window.toolbar.visible) {
         // This returns only non-popup browser windows by default.
         let browserWindow = RecentWindow.getMostRecentBrowserWindow();
         tabBrowser = browserWindow.gBrowser;
       }
       let tab = tabBrowser.loadOneTab("about:blank", {
         relatedToCurrent: true,
-        inBackground: false
+        inBackground: false,
+        triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
       });
       return tabBrowser.getBrowserForTab(tab);
     }
 
     let target = aContext == "mathml" ? this.target : null;
     top.gViewSourceUtils.viewPartialSourceInBrowser(gBrowser.selectedBrowser, target, openSelectionFn);
   },
 
--- a/browser/base/content/tab-content.js
+++ b/browser/base/content/tab-content.js
@@ -11,16 +11,18 @@ var {classes: Cc, interfaces: Ci, utils:
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "E10SUtils",
   "resource:///modules/E10SUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "BrowserUtils",
   "resource://gre/modules/BrowserUtils.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Utils",
+  "resource://gre/modules/sessionstore/Utils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
   "resource://gre/modules/PrivateBrowsingUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "AboutReader",
   "resource://gre/modules/AboutReader.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "ReaderMode",
   "resource://gre/modules/ReaderMode.jsm");
 XPCOMUtils.defineLazyGetter(this, "SimpleServiceDiscovery", function() {
   let ssdp = Cu.import("resource://gre/modules/SimpleServiceDiscovery.jsm", {}).SimpleServiceDiscovery;
@@ -652,27 +654,28 @@ let PrerenderContentHandler = {
             break;
           }
         }
         break;
       }
     }
   },
 
-  startPrerenderingDocument(aHref, aReferrer) {
+  startPrerenderingDocument(aHref, aReferrer, aTriggeringPrincipal) {
     // XXX: Make this constant a pref
     if (this._pending.length >= 2) {
       return;
     }
 
     let id = ++this._idMonotonic;
     sendAsyncMessage("Prerender:Request", {
       href: aHref.spec,
       referrer: aReferrer ? aReferrer.spec : null,
       id,
+      triggeringPrincipal: Utils.serializePrincipal(aTriggeringPrincipal),
     });
 
     this._pending.push({
       href: aHref,
       referrer: aReferrer,
       id,
       success: null,
       failure: null,
@@ -724,19 +727,19 @@ var WebBrowserChrome = {
   },
 
   // Try to reload the currently active or currently loading page in a new process.
   reloadInFreshProcess(aDocShell, aURI, aReferrer, aTriggeringPrincipal, aLoadFlags) {
     E10SUtils.redirectLoad(aDocShell, aURI, aReferrer, aTriggeringPrincipal, true, aLoadFlags);
     return true;
   },
 
-  startPrerenderingDocument(aHref, aReferrer) {
+  startPrerenderingDocument(aHref, aReferrer, aTriggeringPrincipal) {
     if (PrerenderContentHandler.initialized) {
-      PrerenderContentHandler.startPrerenderingDocument(aHref, aReferrer);
+      PrerenderContentHandler.startPrerenderingDocument(aHref, aReferrer, aTriggeringPrincipal);
     }
   },
 
   shouldSwitchToPrerenderedDocument(aHref, aReferrer, aSuccess, aFailure) {
     if (PrerenderContentHandler.initialized) {
       return PrerenderContentHandler.shouldSwitchToPrerenderedDocument(
         aHref, aReferrer, aSuccess, aFailure);
     }
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -5217,16 +5217,17 @@
 
               let newTab = this.loadOneTab(data.href, {
                 referrerURI: (data.referrer ? makeURI(data.referrer) : null),
                 referrerPolicy: Ci.nsIHttpChannel.REFERRER_POLICY_UNSET,
                 postData: null,
                 allowThirdPartyFixup: true,
                 relatedToCurrent: true,
                 isPrerendered: true,
+                triggeringPrincipal: Utils.deserializePrincipal(data.triggeringPrincipal),
               });
               let partialSHistory = newTab.linkedBrowser.frameLoader.partialSHistory;
               groupedSHistory.addPrerenderingPartialSHistory(partialSHistory, data.id);
               break;
             }
 
             case "Prerender:Cancel": {
               let groupedSHistory = browser.frameLoader.groupedSHistory;
--- a/browser/base/content/test/performance/browser.ini
+++ b/browser/base/content/test/performance/browser.ini
@@ -1,7 +1,8 @@
 [DEFAULT]
 support-files =
   head.js
+[browser_startup.js]
 [browser_tabclose_reflows.js]
 [browser_tabopen_reflows.js]
 [browser_toolbariconcolor_restyles.js]
 [browser_windowopen_reflows.js]
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/performance/browser_startup.js
@@ -0,0 +1,135 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/* This test records at which phase of startup the JS components and modules
+ * are first loaded.
+ * If you made changes that cause this test to fail, it's likely because you
+ * are loading more JS code during startup.
+ * Most code has no reason to run off of the app-startup notification
+ * (this is very early, before we have selected the user profile, so
+ *  preferences aren't accessible yet).
+ * If your code isn't strictly required to show the first browser window,
+ * it shouldn't be loaded before we are done with first paint.
+ * Finally, if your code isn't really needed during startup, it should not be
+ * loaded before we have started handling user events.
+ */
+
+"use strict";
+
+const startupPhases = {
+  // For app-startup, we have a whitelist of acceptable JS files.
+  // Anything loaded during app-startup must have a compelling reason
+  // to run before we have even selected the user profile.
+  // Consider loading your code after first paint instead,
+  // eg. from nsBrowserGlue.js' _onFirstWindowLoaded method).
+  "before profile selection": {whitelist: {
+    components: new Set([
+      "nsBrowserGlue.js",
+      "MainProcessSingleton.js",
+
+      // Bugs to fix: The following components shouldn't be initialized that early.
+      "WebContentConverter.js",
+      "nsSessionStartup.js",
+      "PushComponents.js",
+    ]),
+    modules: new Set([
+      "resource://gre/modules/AppConstants.jsm",
+      "resource://gre/modules/XPCOMUtils.jsm",
+      "resource://gre/modules/Services.jsm",
+
+      // Bugs to fix: Probably loaded too early, needs investigation.
+      "resource://gre/modules/Log.jsm",
+      "resource://gre/modules/AsyncPrefs.jsm",
+      "resource://gre/modules/RemotePageManager.jsm",
+      "resource://gre/modules/TelemetryStopwatch.jsm",
+      "resource://gre/modules/PrivateBrowsingUtils.jsm",
+      "resource://gre/modules/Promise.jsm"
+    ])
+  }},
+
+  // For the following phases of startup we have only a black list for now
+
+  // We are at this phase after creating the first browser window (ie. after final-ui-startup).
+  "before opening first browser window": {blacklist: {
+    components: new Set([
+      "nsSearchService.js",
+    ])
+  }},
+
+  // We reach this phase right after showing the first browser window.
+  // This means that anything already loaded at this point has been loaded
+  // before first paint and delayed it.
+  "before first paint": {},
+
+  // We are at this phase once we are ready to handle user events.
+  // Anything loaded at this phase or before gets in the way of the user
+  // interacting with the first browser window.
+  "before handling user events": {},
+}
+
+function test() {
+  if (!AppConstants.NIGHTLY_BUILD && !AppConstants.DEBUG) {
+    ok(!("@mozilla.org/test/startuprecorder;1" in Cc),
+       "the startup recorder component shouldn't exist in this non-nightly non-debug build.");
+    return;
+  }
+
+  let data = Cc["@mozilla.org/test/startuprecorder;1"].getService().wrappedJSObject.data;
+  // Keep only the file name for components, as the path is an absolute file
+  // URL rather than a resource:// URL like for modules.
+  for (let phase in data) {
+    data[phase].components =
+      data[phase].components.map(f => f.replace(/.*\//, ""))
+                            .filter(c => c != "startupRecorder.js");
+  }
+
+  // This block only adds debug output to help find the next bugs to file,
+  // it doesn't contribute to the actual test.
+  SimpleTest.requestCompleteLog();
+  let previous;
+  for (let phase in data) {
+    for (let scriptType in data[phase]) {
+      for (let f of data[phase][scriptType]) {
+        // phases are ordered, so if a script wasn't loaded yet at the immediate
+        // previous phase, it wasn't loaded during any of the previous phases
+        // either, and is new in the current phase.
+        if (!previous || !data[previous][scriptType].includes(f))
+          info(`${scriptType} loaded ${phase}: ${f}`);
+      }
+    }
+    previous = phase;
+  }
+
+  for (let phase in startupPhases) {
+    let loadedList = data[phase];
+    let whitelist = startupPhases[phase].whitelist || null;
+    if (whitelist) {
+      for (let scriptType in loadedList) {
+        loadedList[scriptType] = loadedList[scriptType].filter(c => {
+          if (!whitelist[scriptType].has(c))
+            return true;
+          whitelist[scriptType].delete(c);
+          return false;
+        });
+        is(loadedList[scriptType].length, 0,
+           `should have no unexpected ${scriptType} loaded ${phase}`);
+        for (let script of loadedList[scriptType]) {
+          ok(false, `unexpected ${scriptType}: ${script}`);
+        }
+        is(whitelist[scriptType].size, 0,
+           `all ${scriptType} whitelist entries should have been used`);
+        for (let script of whitelist[scriptType]) {
+          ok(false, `unused ${scriptType} whitelist entry: ${script}`);
+        }
+      }
+    }
+    let blacklist = startupPhases[phase].blacklist || null;
+    if (blacklist) {
+      for (let scriptType in blacklist) {
+        for (let file of blacklist[scriptType]) {
+          ok(!loadedList[scriptType].includes(file), `${file} is not allowed ${phase}`);
+        }
+      }
+    }
+  }
+}
new file mode 100644
--- /dev/null
+++ b/browser/base/content/usercontext-briefcase.svg
@@ -0,0 +1,9 @@
+<!-- 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/. -->
+<svg xmlns="http://www.w3.org/2000/svg"
+     width="32" height="32" viewBox="0 0 32 32">
+  <path fill="context-fill" fill-rule="evenodd"
+        d="M22,9.99887085 L21.635468,10 L29.0034652,10 C29.5538362,10 30,10.4449463 30,10.9933977 L30,27.0066023 C30,27.5552407 29.5601869,28 29.0034652,28 L2.99653482,28 C2.44616384,28 2,27.5550537 2,27.0066023 L2,10.9933977 C2,10.4447593 2.43981314,10 2.99653482,10 L8,10 L8,7.99922997 C8,5.79051625 10.0426627,4 12.5635454,4 L19.4364546,4 C21.9568311,4 24,5.79246765 24,7.99922997 L24,9.99267578 L22,9.99887085 L22,10 L10,10 L10,7.99922997 C10,6.89421235 11.0713286,6 12.3917227,6 L19.6082773,6 C20.9273761,6 22,6.89552665 22,7.99922997 L22,9.99887085 Z"/>
+</svg>
+
new file mode 100644
--- /dev/null
+++ b/browser/base/content/usercontext-cart.svg
@@ -0,0 +1,9 @@
+<!-- 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/. -->
+<svg xmlns="http://www.w3.org/2000/svg"
+     width="32" height="32" viewBox="0 0 32 32">
+  <path fill="context-fill" fill-rule="evenodd"
+        d="M20.8195396,14 L15.1804604,14 L15.1804604,14 L15.8471271,18 L20.1528729,18 L20.8195396,14 Z M22.8471271,14 L27.6125741,14 L27.6125741,14 L26.2792408,18 L22.1804604,18 L22.8471271,14 Z M21.1528729,12 L14.8471271,12 L14.8471271,12 L14.1804604,8 L21.8195396,8 L21.1528729,12 Z M23.1804604,12 L28.2792408,12 L28.2792408,12 L29.6125741,8 L23.8471271,8 L23.1804604,12 Z M13.1528729,14 L8.47703296,14 L10.077033,18 L10.077033,18 L13.8195396,18 L13.1528729,14 Z M12.8195396,12 L7.67703296,12 L6.07703296,8 L12.1528729,8 L12.8195396,12 L12.8195396,12 Z M31.7207592,8 L32,8 L32,6 L31,6 L5.27703296,6 L5.27703296,6 L4,2.8074176 L4,2 L3,2 L1,2 L0,2 L0,4 L1,4 L2.32296704,4 L9.78931928,22.6658806 L9.78931928,22.6658806 C8.71085924,23.3823847 8,24.6081773 8,26 C8,28.209139 9.790861,30 12,30 C14.209139,30 16,28.209139 16,26 C16,25.2714257 15.8052114,24.5883467 15.4648712,24 L22.5351288,24 C22.1947886,24.5883467 22,25.2714257 22,26 C22,28.209139 23.790861,30 26,30 C28.209139,30 30,28.209139 30,26 C30,23.790861 28.209139,22 26,22 L11.677033,22 L10.877033,20 L27,20 L28,20 L28,19.1622777 L31.7207592,8 L31.7207592,8 Z M26,28 C27.1045695,28 28,27.1045695 28,26 C28,24.8954305 27.1045695,24 26,24 C24.8954305,24 24,24.8954305 24,26 C24,27.1045695 24.8954305,28 26,28 Z M12,28 C13.1045695,28 14,27.1045695 14,26 C14,24.8954305 13.1045695,24 12,24 C10.8954305,24 10,24.8954305 10,26 C10,27.1045695 10.8954305,28 12,28 Z"/>
+</svg>
+
new file mode 100644
--- /dev/null
+++ b/browser/base/content/usercontext-circle.svg
@@ -0,0 +1,8 @@
+<!-- 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/. -->
+<svg xmlns="http://www.w3.org/2000/svg"
+     width="32" height="32" viewBox="0 0 32 32">
+  <circle fill="context-fill" cx="16" cy="16" r="16"/>
+</svg>
+
new file mode 100644
--- /dev/null
+++ b/browser/base/content/usercontext-dollar.svg
@@ -0,0 +1,8 @@
+<!-- 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/. -->
+<svg xmlns="http://www.w3.org/2000/svg"
+     width="32" height="32" viewBox="0 0 32 32">
+  <path fill="context-fill" d="M17.3857868,14.0527919 C14.2304569,13.0862944 13.4913706,12.4609137 13.4913706,11.0964467 C13.4913706,9.61827411 14.7137056,8.85076142 16.4192893,8.85076142 C17.9827411,8.85076142 19.3187817,9.33401015 20.5979695,10.4994924 L22.4456853,8.42436548 C21.1664975,7.20203046 19.3187819,6.26535905 17,6.00952148 L17,2 L15,2 L15,6.00952148 C12.3827412,6.43591742 9.76751269,8.53807107 9.76751269,11.3238579 C9.76751269,14.1664975 11.4730964,15.786802 15.4812183,17.0091371 C18.4375635,17.9187817 19.2335025,18.6294416 19.2335025,20.2213198 C19.2335025,22.0690355 17.7553299,23.035533 15.7370558,23.035533 C13.7756345,23.035533 12.2406091,22.3248731 10.9329949,21.1025381 L9,23.2345178 C10.4213198,24.6274112 12.8659899,25.8324934 15,26.0030518 L15,30 L17,30 L17,26.0030518 C20.7116753,25.4060974 22.9857868,22.893401 22.9857868,20.022335 C22.9857868,16.4690355 20.7116751,15.1045685 17.3857868,14.0527919 Z"/>
+</svg>
+
new file mode 100644
--- /dev/null
+++ b/browser/base/content/usercontext-fingerprint.svg
@@ -0,0 +1,8 @@
+<!-- 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/. -->
+<svg xmlns="http://www.w3.org/2000/svg"
+     width="32" height="32" viewBox="0 0 32 32">
+  <path fill="context-fill" d="M7.17741905,12 C7.10965537,12 7.041327,11.9953181 6.97243393,11.985018 C6.33263187,11.8918489 5.90515601,11.3862071 6.01809547,10.8552833 C7.41798011,4.26321358 12.2613889,2.57493207 15.0238882,2.15590491 C19.6448063,1.45690206 24.3408291,3.21541158 25.8344535,5.29743816 C26.1664955,5.76047488 25.9835336,6.35881757 25.4244832,6.63364321 C24.8654329,6.9098734 24.1437497,6.75583996 23.8122724,6.29327142 C22.8923805,5.01043967 19.1749781,3.51130562 15.4479759,4.07406612 C12.8080159,4.474834 9.43056132,6.03623689 8.33561323,11.1942506 C8.23453242,11.666651 7.73816348,12 7.17741905,12 Z M16.63127,26 C16.1452186,26 15.6509104,25.9658335 15.147795,25.8938767 C10.637921,25.257137 6.71207921,21.8114952 6.01575422,17.8807924 C5.91171832,17.2932317 6.33391695,16.7382846 6.95813239,16.6404441 C7.58454965,16.5343208 8.17298555,16.9406954 8.27757192,17.5272206 C8.80876054,20.5255916 11.9766264,23.26409 15.4885263,23.7610576 C17.3975027,24.02766 20.959494,23.8221432 23.3220449,19.3789425 C24.4625867,17.2331815 23.0049831,11.881462 19.9521622,9.34692739 C18.2380468,7.92384005 16.4573263,7.76905536 14.6628445,8.89499751 C13.26469,9.77142052 11.8070864,12.2857658 11.8665355,14.6287608 C11.9127737,16.4835887 12.8386382,17.9325598 14.6171568,18.9363308 C15.2210054,19.2764429 16.9411759,19.4933486 17.9424527,18.8296898 C18.7257495,18.3104622 18.9591422,17.2761485 18.6365758,15.7583267 C18.3822659,14.5650869 17.2219077,12.4452096 16.6664991,12.3711821 C16.6692513,12.3722175 16.4666841,12.4312324 16.1276041,12.9095636 C15.8545786,13.2936782 15.58981,14.7297074 15.9476054,15.3581643 C16.0142104,15.4761941 16.0725586,15.5465978 16.3202632,15.5465978 C16.9532859,15.5465978 17.46686,16.0290705 17.46686,16.6249139 C17.46686,17.2207573 16.9543868,17.7042653 16.3213641,17.7042653 C15.2644914,17.7042653 14.4140391,17.2336992 13.9268868,16.3774655 C13.1083609,14.9388479 13.5536787,12.6548678 14.2202791,11.7137354 C15.2540327,10.2564816 16.3631986,10.1151564 17.1123672,10.2564816 C19.7066595,10.7389543 20.8763754,15.2908666 20.8857331,15.3359043 C21.5303153,18.3648181 20.3594985,19.8665919 19.264094,20.593407 C17.4151172,21.8192603 14.6920186,21.493643 13.4380832,20.7859819 C10.3280151,19.0310652 9.62013053,16.497566 9.5744428,14.6805283 C9.49022326,11.3643051 11.4779146,8.30018945 13.391845,7.10021984 C16.0417332,5.43848454 18.9877658,5.66781436 21.4714167,7.72919442 C25.1176276,10.7565552 27.0871539,17.1229168 25.3746898,20.3433702 C23.4326862,23.9950465 20.2983981,26 16.63127,26 Z M16.0845157,30 C14.9348455,30 13.9050564,29.8557557 13.0394288,29.6610017 C10.2114238,29.0257442 7.58700058,27.4599412 6.18892823,25.5735955 C5.84440518,25.1078371 5.98426642,24.4803503 6.50105099,24.1700066 C7.01675554,23.8596629 7.71552172,23.986423 8.06112477,24.4507244 C9.89498097,26.9252176 15.9397944,29.9781448 22.2508301,26.1937972 C22.7676147,25.8844249 23.4658409,26.0087566 23.8109039,26.474515 C24.155427,26.9397877 24.0161057,27.5672745 23.4993212,27.8776182 C20.7987573,29.4963593 18.2315746,30 16.0845157,30 Z"/>
+</svg>
+
deleted file mode 100644
--- a/browser/base/content/usercontext.svg
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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/. -->
-<svg xmlns="http://www.w3.org/2000/svg"
-     xmlns:xlink="http://www.w3.org/1999/xlink"
-     width="32" height="32" viewBox="0 0 32 32">
-  <style>
-    path, circle {
-      fill: menutext;
-    }
-    path:not(:target),
-    circle:not(:target) {
-      display: none;
-    }
-  </style>
-  <path id="dollar" d="M17.3857868,14.0527919 C14.2304569,13.0862944 13.4913706,12.4609137 13.4913706,11.0964467 C13.4913706,9.61827411 14.7137056,8.85076142 16.4192893,8.85076142 C17.9827411,8.85076142 19.3187817,9.33401015 20.5979695,10.4994924 L22.4456853,8.42436548 C21.1664975,7.20203046 19.3187819,6.26535905 17,6.00952148 L17,2 L15,2 L15,6.00952148 C12.3827412,6.43591742 9.76751269,8.53807107 9.76751269,11.3238579 C9.76751269,14.1664975 11.4730964,15.786802 15.4812183,17.0091371 C18.4375635,17.9187817 19.2335025,18.6294416 19.2335025,20.2213198 C19.2335025,22.0690355 17.7553299,23.035533 15.7370558,23.035533 C13.7756345,23.035533 12.2406091,22.3248731 10.9329949,21.1025381 L9,23.2345178 C10.4213198,24.6274112 12.8659899,25.8324934 15,26.0030518 L15,30 L17,30 L17,26.0030518 C20.7116753,25.4060974 22.9857868,22.893401 22.9857868,20.022335 C22.9857868,16.4690355 20.7116751,15.1045685 17.3857868,14.0527919 Z"/>
-  <path id="briefcase" fill-rule="evenodd" d="M22,9.99887085 L21.635468,10 L29.0034652,10 C29.5538362,10 30,10.4449463 30,10.9933977 L30,27.0066023 C30,27.5552407 29.5601869,28 29.0034652,28 L2.99653482,28 C2.44616384,28 2,27.5550537 2,27.0066023 L2,10.9933977 C2,10.4447593 2.43981314,10 2.99653482,10 L8,10 L8,7.99922997 C8,5.79051625 10.0426627,4 12.5635454,4 L19.4364546,4 C21.9568311,4 24,5.79246765 24,7.99922997 L24,9.99267578 L22,9.99887085 L22,10 L10,10 L10,7.99922997 C10,6.89421235 11.0713286,6 12.3917227,6 L19.6082773,6 C20.9273761,6 22,6.89552665 22,7.99922997 L22,9.99887085 Z"/>
-  <path id="fingerprint" d="M7.17741905,12 C7.10965537,12 7.041327,11.9953181 6.97243393,11.985018 C6.33263187,11.8918489 5.90515601,11.3862071 6.01809547,10.8552833 C7.41798011,4.26321358 12.2613889,2.57493207 15.0238882,2.15590491 C19.6448063,1.45690206 24.3408291,3.21541158 25.8344535,5.29743816 C26.1664955,5.76047488 25.9835336,6.35881757 25.4244832,6.63364321 C24.8654329,6.9098734 24.1437497,6.75583996 23.8122724,6.29327142 C22.8923805,5.01043967 19.1749781,3.51130562 15.4479759,4.07406612 C12.8080159,4.474834 9.43056132,6.03623689 8.33561323,11.1942506 C8.23453242,11.666651 7.73816348,12 7.17741905,12 Z M16.63127,26 C16.1452186,26 15.6509104,25.9658335 15.147795,25.8938767 C10.637921,25.257137 6.71207921,21.8114952 6.01575422,17.8807924 C5.91171832,17.2932317 6.33391695,16.7382846 6.95813239,16.6404441 C7.58454965,16.5343208 8.17298555,16.9406954 8.27757192,17.5272206 C8.80876054,20.5255916 11.9766264,23.26409 15.4885263,23.7610576 C17.3975027,24.02766 20.959494,23.8221432 23.3220449,19.3789425 C24.4625867,17.2331815 23.0049831,11.881462 19.9521622,9.34692739 C18.2380468,7.92384005 16.4573263,7.76905536 14.6628445,8.89499751 C13.26469,9.77142052 11.8070864,12.2857658 11.8665355,14.6287608 C11.9127737,16.4835887 12.8386382,17.9325598 14.6171568,18.9363308 C15.2210054,19.2764429 16.9411759,19.4933486 17.9424527,18.8296898 C18.7257495,18.3104622 18.9591422,17.2761485 18.6365758,15.7583267 C18.3822659,14.5650869 17.2219077,12.4452096 16.6664991,12.3711821 C16.6692513,12.3722175 16.4666841,12.4312324 16.1276041,12.9095636 C15.8545786,13.2936782 15.58981,14.7297074 15.9476054,15.3581643 C16.0142104,15.4761941 16.0725586,15.5465978 16.3202632,15.5465978 C16.9532859,15.5465978 17.46686,16.0290705 17.46686,16.6249139 C17.46686,17.2207573 16.9543868,17.7042653 16.3213641,17.7042653 C15.2644914,17.7042653 14.4140391,17.2336992 13.9268868,16.3774655 C13.1083609,14.9388479 13.5536787,12.6548678 14.2202791,11.7137354 C15.2540327,10.2564816 16.3631986,10.1151564 17.1123672,10.2564816 C19.7066595,10.7389543 20.8763754,15.2908666 20.8857331,15.3359043 C21.5303153,18.3648181 20.3594985,19.8665919 19.264094,20.593407 C17.4151172,21.8192603 14.6920186,21.493643 13.4380832,20.7859819 C10.3280151,19.0310652 9.62013053,16.497566 9.5744428,14.6805283 C9.49022326,11.3643051 11.4779146,8.30018945 13.391845,7.10021984 C16.0417332,5.43848454 18.9877658,5.66781436 21.4714167,7.72919442 C25.1176276,10.7565552 27.0871539,17.1229168 25.3746898,20.3433702 C23.4326862,23.9950465 20.2983981,26 16.63127,26 Z M16.0845157,30 C14.9348455,30 13.9050564,29.8557557 13.0394288,29.6610017 C10.2114238,29.0257442 7.58700058,27.4599412 6.18892823,25.5735955 C5.84440518,25.1078371 5.98426642,24.4803503 6.50105099,24.1700066 C7.01675554,23.8596629 7.71552172,23.986423 8.06112477,24.4507244 C9.89498097,26.9252176 15.9397944,29.9781448 22.2508301,26.1937972 C22.7676147,25.8844249 23.4658409,26.0087566 23.8109039,26.474515 C24.155427,26.9397877 24.0161057,27.5672745 23.4993212,27.8776182 C20.7987573,29.4963593 18.2315746,30 16.0845157,30 Z"/>
-  <path id="cart" fill-rule="evenodd" d="M20.8195396,14 L15.1804604,14 L15.1804604,14 L15.8471271,18 L20.1528729,18 L20.8195396,14 Z M22.8471271,14 L27.6125741,14 L27.6125741,14 L26.2792408,18 L22.1804604,18 L22.8471271,14 Z M21.1528729,12 L14.8471271,12 L14.8471271,12 L14.1804604,8 L21.8195396,8 L21.1528729,12 Z M23.1804604,12 L28.2792408,12 L28.2792408,12 L29.6125741,8 L23.8471271,8 L23.1804604,12 Z M13.1528729,14 L8.47703296,14 L10.077033,18 L10.077033,18 L13.8195396,18 L13.1528729,14 Z M12.8195396,12 L7.67703296,12 L6.07703296,8 L12.1528729,8 L12.8195396,12 L12.8195396,12 Z M31.7207592,8 L32,8 L32,6 L31,6 L5.27703296,6 L5.27703296,6 L4,2.8074176 L4,2 L3,2 L1,2 L0,2 L0,4 L1,4 L2.32296704,4 L9.78931928,22.6658806 L9.78931928,22.6658806 C8.71085924,23.3823847 8,24.6081773 8,26 C8,28.209139 9.790861,30 12,30 C14.209139,30 16,28.209139 16,26 C16,25.2714257 15.8052114,24.5883467 15.4648712,24 L22.5351288,24 C22.1947886,24.5883467 22,25.2714257 22,26 C22,28.209139 23.790861,30 26,30 C28.209139,30 30,28.209139 30,26 C30,23.790861 28.209139,22 26,22 L11.677033,22 L10.877033,20 L27,20 L28,20 L28,19.1622777 L31.7207592,8 L31.7207592,8 Z M26,28 C27.1045695,28 28,27.1045695 28,26 C28,24.8954305 27.1045695,24 26,24 C24.8954305,24 24,24.8954305 24,26 C24,27.1045695 24.8954305,28 26,28 Z M12,28 C13.1045695,28 14,27.1045695 14,26 C14,24.8954305 13.1045695,24 12,24 C10.8954305,24 10,24.8954305 10,26 C10,27.1045695 10.8954305,28 12,28 Z"/>
-  <circle id="circle" r="16" cx="16" cy="16" fill-rule="evenodd" />
-</svg>
-
--- a/browser/base/jar.mn
+++ b/browser/base/jar.mn
@@ -133,17 +133,21 @@ browser.jar:
         content/browser/sanitizeDialog.js             (content/sanitizeDialog.js)
         content/browser/sanitizeDialog.css            (content/sanitizeDialog.css)
         content/browser/contentSearchUI.js            (content/contentSearchUI.js)
         content/browser/contentSearchUI.css           (content/contentSearchUI.css)
         content/browser/tabbrowser.css                (content/tabbrowser.css)
         content/browser/tabbrowser.xml                (content/tabbrowser.xml)
 *       content/browser/urlbarBindings.xml            (content/urlbarBindings.xml)
         content/browser/utilityOverlay.js             (content/utilityOverlay.js)
-        content/browser/usercontext.svg               (content/usercontext.svg)
+        content/browser/usercontext-briefcase.svg     (content/usercontext-briefcase.svg)
+        content/browser/usercontext-cart.svg          (content/usercontext-cart.svg)
+        content/browser/usercontext-circle.svg        (content/usercontext-circle.svg)
+        content/browser/usercontext-dollar.svg        (content/usercontext-dollar.svg)
+        content/browser/usercontext-fingerprint.svg   (content/usercontext-fingerprint.svg)
         content/browser/web-panels.js                 (content/web-panels.js)
 *       content/browser/web-panels.xul                (content/web-panels.xul)
         content/browser/webext-panels.js              (content/webext-panels.js)
 *       content/browser/webext-panels.xul             (content/webext-panels.xul)
 *       content/browser/baseMenuOverlay.xul           (content/baseMenuOverlay.xul)
         content/browser/nsContextMenu.js              (content/nsContextMenu.js)
 # XXX: We should exclude this one as well (bug 71895)
 *       content/browser/hiddenWindow.xul              (content/hiddenWindow.xul)
--- a/browser/components/contextualidentity/content/usercontext.css
+++ b/browser/components/contextualidentity/content/usercontext.css
@@ -34,33 +34,33 @@
 }
 
 [data-identity-color="purple"] {
   --identity-tab-color: #7a2f7a;
   --identity-icon-color: #7a2f7a;
 }
 
 [data-identity-icon="fingerprint"] {
-  --identity-icon: url("chrome://browser/content/usercontext.svg#fingerprint");
+  --identity-icon: url("chrome://browser/content/usercontext-fingerprint.svg");
 }
 
 [data-identity-icon="briefcase"] {
-  --identity-icon: url("chrome://browser/content/usercontext.svg#briefcase");
+  --identity-icon: url("chrome://browser/content/usercontext-briefcase.svg");
 }
 
 [data-identity-icon="dollar"] {
-  --identity-icon: url("chrome://browser/content/usercontext.svg#dollar");
+  --identity-icon: url("chrome://browser/content/usercontext-dollar.svg");
 }
 
 [data-identity-icon="cart"] {
-  --identity-icon: url("chrome://browser/content/usercontext.svg#cart");
+  --identity-icon: url("chrome://browser/content/usercontext-cart.svg");
 }
 
 [data-identity-icon="circle"] {
-  --identity-icon: url("chrome://browser/content/usercontext.svg#circle");
+  --identity-icon: url("chrome://browser/content/usercontext-circle.svg");
 }
 
 #userContext-indicator {
   height: 16px;
   width: 16px;
 }
 
 #userContext-label {
@@ -78,14 +78,14 @@
   background-repeat: no-repeat;
 }
 
 .userContext-icon,
 .menuitem-iconic[data-usercontextid] > .menu-iconic-left > .menu-iconic-icon,
 .subviewbutton[usercontextid] > .toolbarbutton-icon,
 #userContext-indicator {
   background-image: var(--identity-icon);
-  filter: url(chrome://global/skin/filters.svg#fill);
+  -moz-context-properties: fill;
   fill: var(--identity-icon-color);
   background-size: contain;
   background-repeat: no-repeat;
   background-position: center center;
 }
--- a/browser/components/customizableui/CustomizeMode.jsm
+++ b/browser/components/customizableui/CustomizeMode.jsm
@@ -213,20 +213,22 @@ CustomizeMode.prototype = {
     // Exiting; want to re-enter once we've done that.
     if (this._handler.isExitingCustomizeMode) {
       log.debug("Attempted to enter while we're in the middle of exiting. " +
                 "We'll exit after we've entered");
       return;
     }
 
     if (!gTab) {
-      this.setTab(this.browser.loadOneTab("about:blank",
-                                          { inBackground: false,
-                                            forceNotRemote: true,
-                                            skipAnimation: true }));
+      this.setTab(this.browser.loadOneTab("about:blank", {
+        inBackground: false,
+        forceNotRemote: true,
+        skipAnimation: true,
+        triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
+      }));
       return;
     }
     if (!gTab.selected) {
       // This will force another .enter() to be called via the
       // onlocationchange handler of the tabbrowser, so we return early.
       gTab.ownerGlobal.gBrowser.selectedTab = gTab;
       return;
     }
--- a/browser/components/moz.build
+++ b/browser/components/moz.build
@@ -61,16 +61,18 @@ XPIDL_MODULE = 'browsercompsbase'
 
 EXTRA_PP_COMPONENTS += [
     'BrowserComponents.manifest',
 ]
 
 EXTRA_COMPONENTS += [
     'nsBrowserContentHandler.js',
     'nsBrowserGlue.js',
+    'tests/startupRecorder.js',
+    'tests/testComponents.manifest',
 ]
 
 EXTRA_JS_MODULES += [
     'distribution.js',
 ]
 
 BROWSER_CHROME_MANIFESTS += [
     'safebrowsing/content/test/browser.ini',
new file mode 100644
--- /dev/null
+++ b/browser/components/tests/startupRecorder.js
@@ -0,0 +1,71 @@
+/* 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/. */
+
+const {classes: Cc, utils: Cu, interfaces: Ci} = Components;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
+
+/**
+  * The startupRecorder component observes notifications at various stages of
+  * startup and records the set of JS components and modules that were already
+  * loaded at each of these points.
+  * The records are meant to be used by startup tests in
+  * browser/base/content/test/performance
+  * This component only exists in nightly and debug builds, it doesn't ship in
+  * our release builds.
+  */
+function startupRecorder() {
+  this.wrappedJSObject = this;
+  this.loader = Cc["@mozilla.org/moz/jsloader;1"].getService(Ci.xpcIJSModuleLoader);
+  this.data = {};
+}
+startupRecorder.prototype = {
+  classID: Components.ID("{11c095b2-e42e-4bdf-9dd0-aed87595f6a4}"),
+
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
+
+  record(name) {
+    this.data[name] = {
+      components: this.loader.loadedComponents(),
+      modules: this.loader.loadedModules()
+    };
+  },
+
+  observe(subject, topic, data) {
+
+    if (topic == "app-startup") {
+      // We can't ensure our observer will be called first or last, so the list of
+      // topics we observe here should avoid the topics used to trigger things
+      // during startup (eg. the topics observed by nsBrowserGlue.js).
+      let topics = [
+        "profile-do-change", // This catches stuff loaded during app-startup
+        "toplevel-window-ready", // Catches stuff from final-ui-startup
+        "widget-first-paint",
+        "sessionstore-windows-restored",
+      ];
+      for (let t of topics)
+        Services.obs.addObserver(this, t);
+      return;
+    }
+
+    Services.obs.removeObserver(this, topic);
+
+    if (topic == "sessionstore-windows-restored") {
+      // We use idleDispatch here to record the set of loaded scripts after we
+      // are fully done with startup and ready to react to user events.
+      Services.tm.mainThread.idleDispatch(
+        this.record.bind(this, "before handling user events"));
+    } else {
+      const topicsToNames = {
+        "profile-do-change": "before profile selection",
+        "toplevel-window-ready": "before opening first browser window",
+        "widget-first-paint": "before first paint",
+      };
+      this.record(topicsToNames[topic]);
+    }
+  }
+};
+
+this.NSGetFactory = XPCOMUtils.generateNSGetFactory([startupRecorder]);
new file mode 100644
--- /dev/null
+++ b/browser/components/tests/testComponents.manifest
@@ -0,0 +1,5 @@
+# This component restricts its registration for the app-startup category
+# to the browser app so it doesn't get loaded in xpcshell.
+component {11c095b2-e42e-4bdf-9dd0-aed87595f6a4} startupRecorder.js
+contract @mozilla.org/test/startuprecorder;1 {11c095b2-e42e-4bdf-9dd0-aed87595f6a4}
+category app-startup startupRecorder service,@mozilla.org/test/startuprecorder;1 application={ec8030f7-c20a-464f-9b0e-13a3a9e97384}
--- a/browser/extensions/webcompat-reporter/content/WebCompatReporter.jsm
+++ b/browser/extensions/webcompat-reporter/content/WebCompatReporter.jsm
@@ -116,17 +116,17 @@ let WebCompatReporter = {
   openWebCompatTab([gBrowser, tabData]) {
     const SCREENSHOT_MESSAGE = "WebCompat:SendScreenshot";
     const FRAMESCRIPT = "chrome://webcompat-reporter/content/wc-frame.js";
     let win = Services.wm.getMostRecentWindow("navigator:browser");
     const WEBCOMPAT_ORIGIN = new win.URL(WebCompatReporter.endpoint).origin;
 
     let tab = gBrowser.loadOneTab(
       `${WebCompatReporter.endpoint}?url=${encodeURIComponent(tabData.url)}&src=desktop-reporter`,
-      {inBackground: false});
+      {inBackground: false, triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()});
 
     // If we successfully got a screenshot blob, add a listener to know when
     // the new tab is loaded before sending it over.
     if (tabData && tabData.blob) {
       let browser = gBrowser.getBrowserForTab(tab);
       let loadedListener = {
         QueryInterface: XPCOMUtils.generateQI(["nsIWebProgressListener",
           "nsISupportsWeakReference"]),
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -563,16 +563,21 @@
 #endif
 
 #if defined(ENABLE_TESTS) && defined(MOZ_DEBUG)
 @RESPATH@/components/TestInterfaceJS.js
 @RESPATH@/components/TestInterfaceJS.manifest
 @RESPATH@/components/TestInterfaceJSMaplike.js
 #endif
 
+#if defined(MOZ_DEBUG) || defined(NIGHTLY_BUILD)
+@RESPATH@/browser/components/testComponents.manifest
+@RESPATH@/browser/components/startupRecorder.js
+#endif
+
 ; [Extensions]
 @RESPATH@/components/extensions-toolkit.manifest
 @RESPATH@/browser/components/extensions-browser.manifest
 
 ; Modules
 @RESPATH@/browser/modules/*
 @RESPATH@/modules/*
 
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -11013,16 +11013,38 @@ nsDocShell::DoURILoad(nsIURI* aURI,
 
   nsCOMPtr<nsILoadInfo> loadInfo =
     (aContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT) ?
       new LoadInfo(loadingWindow, aTriggeringPrincipal,
                    securityFlags) :
       new LoadInfo(loadingPrincipal, aTriggeringPrincipal, loadingNode,
                    securityFlags, aContentPolicyType);
 
+  if (aContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT) {
+    enum TopLevelDataState {
+      DATA_NAVIGATED = 0,
+      DATA_TYPED = 1,
+      NO_DATA = 2,
+    };
+    bool isDataURI = (NS_SUCCEEDED(aURI->SchemeIs("data", &isDataURI)) && isDataURI);
+    if (isDataURI) {
+      // In all cases where the toplevel document is navigated to a data: URI
+      // the triggeringPrincipal is a CodeBasePrincipal. In all other cases
+      // e.g. typing a data: URL into the URL-Bar or also clicking a bookmark 
+      // uses a SystemPrincipal as the triggeringPrincipal.
+      if (aTriggeringPrincipal->GetIsCodebasePrincipal()) {
+        Telemetry::Accumulate(Telemetry::DOCUMENT_DATA_URI_LOADS, DATA_NAVIGATED);
+      } else {
+        Telemetry::Accumulate(Telemetry::DOCUMENT_DATA_URI_LOADS, DATA_TYPED);
+      }
+    } else {
+      Telemetry::Accumulate(Telemetry::DOCUMENT_DATA_URI_LOADS, NO_DATA);
+    }
+  }
+
   if (aPrincipalToInherit) {
     loadInfo->SetPrincipalToInherit(aPrincipalToInherit);
   }
 
   // We have to do this in case our OriginAttributes are different from the
   // OriginAttributes of the parent document. Or in case there isn't a
   // parent document.
   bool isTopLevelDoc = mItemType == typeContent &&
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -4004,25 +4004,36 @@ Element::ClearDataset()
 
 nsDataHashtable<nsRefPtrHashKey<DOMIntersectionObserver>, int32_t>*
 Element::RegisteredIntersectionObservers()
 {
   nsDOMSlots* slots = DOMSlots();
   return &slots->mRegisteredIntersectionObservers;
 }
 
+enum nsPreviousIntersectionThreshold {
+  eUninitialized = -2,
+  eNonIntersecting = -1
+};
+
 void
 Element::RegisterIntersectionObserver(DOMIntersectionObserver* aObserver)
 {
   nsDataHashtable<nsRefPtrHashKey<DOMIntersectionObserver>, int32_t>* observers =
     RegisteredIntersectionObservers();
   if (observers->Contains(aObserver)) {
     return;
   }
-  RegisteredIntersectionObservers()->Put(aObserver, -1);
+
+  // Value can be:
+  //   -2:   Makes sure next calculated threshold always differs, leading to a
+  //         notification task being scheduled.
+  //   -1:   Non-intersecting.
+  //   >= 0: Intersecting, valid index of aObserver->mThresholds.
+  RegisteredIntersectionObservers()->Put(aObserver, eUninitialized);
 }
 
 void
 Element::UnregisterIntersectionObserver(DOMIntersectionObserver* aObserver)
 {
   nsDataHashtable<nsRefPtrHashKey<DOMIntersectionObserver>, int32_t>* observers =
     RegisteredIntersectionObservers();
   observers->Remove(aObserver);
--- a/dom/base/nsContentSink.h
+++ b/dom/base/nsContentSink.h
@@ -68,19 +68,16 @@ extern mozilla::LazyLogModule gContentSi
 #else
 #define SINK_TRACE(_lm, _bit, _args)
 #endif
 
 #undef SINK_NO_INCREMENTAL
 
 //----------------------------------------------------------------------
 
-// 1/2 second fudge factor for window creation
-#define NS_DELAY_FOR_WINDOW_CREATION  500000
-
 class nsContentSink : public nsICSSLoaderObserver,
                       public nsSupportsWeakReference,
                       public nsStubDocumentObserver,
                       public nsITimerCallback,
                       public nsINamed
 {
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsContentSink,
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -3140,17 +3140,17 @@ nsIDocument::PrerenderHref(nsIURI* aHref
 
   TabChild* tabChild = TabChild::GetFrom(docShell);
   NS_ENSURE_TRUE(tabChild, false);
 
   nsCOMPtr<nsIWebBrowserChrome3> wbc3;
   tabChild->GetWebBrowserChrome(getter_AddRefs(wbc3));
   NS_ENSURE_TRUE(wbc3, false);
 
-  rv = wbc3->StartPrerenderingDocument(aHref, referrer);
+  rv = wbc3->StartPrerenderingDocument(aHref, referrer, NodePrincipal());
   NS_ENSURE_SUCCESS(rv, false);
 
   return true;
 }
 
 NS_IMETHODIMP
 nsDocument::GetApplicationCache(nsIApplicationCache **aApplicationCache)
 {
@@ -12333,17 +12333,18 @@ nsIDocument::DocAddSizeOfExcludingThis(n
     nsINode::SizeOfExcludingThis(aWindowSizes->mMallocSizeOf);
 
   if (mPresShell) {
     mPresShell->AddSizeOfIncludingThis(aWindowSizes->mMallocSizeOf,
                                        &aWindowSizes->mArenaStats,
                                        &aWindowSizes->mLayoutPresShellSize,
                                        &aWindowSizes->mLayoutStyleSetsSize,
                                        &aWindowSizes->mLayoutTextRunsSize,
-                                       &aWindowSizes->mLayoutPresContextSize);
+                                       &aWindowSizes->mLayoutPresContextSize,
+                                       &aWindowSizes->mLayoutFramePropertiesSize);
   }
 
   aWindowSizes->mPropertyTablesSize +=
     mPropertyTable.SizeOfExcludingThis(aWindowSizes->mMallocSizeOf);
   for (uint32_t i = 0, count = mExtraPropertyTables.Length();
        i < count; ++i) {
     aWindowSizes->mPropertyTablesSize +=
       mExtraPropertyTables[i]->SizeOfIncludingThis(aWindowSizes->mMallocSizeOf);
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -173,17 +173,16 @@ nsFrameLoader::nsFrameLoader(Element* aO
   , mInShow(false)
   , mHideCalled(false)
   , mNetworkCreated(aNetworkCreated)
   , mRemoteBrowserShown(false)
   , mRemoteFrame(false)
   , mClipSubdocument(true)
   , mClampScrollPosition(true)
   , mObservingOwnerContent(false)
-  , mVisible(true)
 {
   mRemoteFrame = ShouldUseRemoteProcess();
   MOZ_ASSERT(!mRemoteFrame || !aOpener,
              "Cannot pass aOpener for a remote frame!");
 }
 
 nsFrameLoader::~nsFrameLoader()
 {
@@ -3490,39 +3489,16 @@ nsFrameLoader::Print(uint64_t aOuterWind
     return NS_ERROR_FAILURE;
   }
 
   return webBrowserPrint->Print(aPrintSettings, aProgressListener);
 #endif
   return NS_OK;
 }
 
-/* [infallible] */ NS_IMETHODIMP
-nsFrameLoader::SetVisible(bool aVisible)
-{
-  if (mVisible == aVisible) {
-    return NS_OK;
-  }
-
-  mVisible = aVisible;
-  nsCOMPtr<nsIObserverService> os = services::GetObserverService();
-  if (os) {
-    os->NotifyObservers(NS_ISUPPORTS_CAST(nsIFrameLoader*, this),
-                        "frameloader-visible-changed", nullptr);
-  }
-  return NS_OK;
-}
-
-/* [infallible] */ NS_IMETHODIMP
-nsFrameLoader::GetVisible(bool* aVisible)
-{
-  *aVisible = mVisible;
-  return NS_OK;
-}
-
 NS_IMETHODIMP
 nsFrameLoader::GetTabParent(nsITabParent** aTabParent)
 {
   nsCOMPtr<nsITabParent> tp = mRemoteBrowser;
   tp.forget(aTabParent);
   return NS_OK;
 }
 
--- a/dom/base/nsFrameLoader.h
+++ b/dom/base/nsFrameLoader.h
@@ -370,16 +370,12 @@ private:
   bool mNetworkCreated : 1;
 
   bool mRemoteBrowserShown : 1;
   bool mRemoteFrame : 1;
   bool mClipSubdocument : 1;
   bool mClampScrollPosition : 1;
   bool mObservingOwnerContent : 1;
 
-  // Backs nsIFrameLoader::{Get,Set}Visible.  Visibility state here relates to
-  // whether this frameloader's <iframe mozbrowser> is setVisible(true)'ed, and
-  // doesn't necessarily correlate with docshell/document visibility.
-  bool mVisible : 1;
   bool mFreshProcess : 1;
 };
 
 #endif
--- a/dom/base/nsIFrameLoader.idl
+++ b/dom/base/nsIFrameLoader.idl
@@ -218,25 +218,16 @@ interface nsIFrameLoader : nsISupports
 
   /**
    * Cached childID of the ContentParent owning the TabParent in this frame
    * loader. This can be used to obtain the childID after the TabParent died.
    */
   readonly attribute unsigned long long childID;
 
   /**
-   * Get or set this frame loader's visibility.
-   *
-   * The notion of "visibility" here is separate from the notion of a
-   * window/docshell's visibility.  This field is mostly here so that we can
-   * have a notion of visibility in the parent process when frames are OOP.
-   */
-  [infallible] attribute boolean visible;
-
-  /**
    * Find out whether the owner content really is a mozbrowser. <xul:browser>
    * is not considered to be a mozbrowser frame.
    */
   readonly attribute boolean ownerIsMozBrowserFrame;
 
   /**
    * The last known width of the frame. Reading this property will not trigger
    * a reflow, and therefore may not reflect the current state of things. It
--- a/dom/base/nsWindowMemoryReporter.cpp
+++ b/dom/base/nsWindowMemoryReporter.cpp
@@ -395,16 +395,22 @@ CollectWindowReports(nsGlobalWindow *aWi
   aWindowTotalSizes->mLayoutTextRunsSize += windowSizes.mLayoutTextRunsSize;
 
   REPORT_SIZE("/layout/pres-contexts", windowSizes.mLayoutPresContextSize,
          "Memory used for the PresContext in the PresShell's frame "
          "within a window.");
   aWindowTotalSizes->mLayoutPresContextSize +=
     windowSizes.mLayoutPresContextSize;
 
+  REPORT_SIZE("/layout/frame-properties", windowSizes.mLayoutFramePropertiesSize,
+         "Memory used for frame properties attached to frames "
+         "within a window.");
+  aWindowTotalSizes->mLayoutFramePropertiesSize +=
+    windowSizes.mLayoutFramePropertiesSize;
+
   // There are many different kinds of frames, but it is very likely
   // that only a few matter.  Implement a cutoff so we don't bloat
   // about:memory with many uninteresting entries.
   const size_t FRAME_SUNDRIES_THRESHOLD =
     js::MemoryReportingSundriesThreshold();
 
   size_t frameSundriesSize = 0;
 #define FRAME_ID(classname, ...)                                        \
@@ -560,16 +566,19 @@ nsWindowMemoryReporter::CollectReports(n
          "This is the sum of all windows' 'layout/style-sets' numbers.");
 
   REPORT("window-objects/layout/text-runs", windowTotalSizes.mLayoutTextRunsSize,
          "This is the sum of all windows' 'layout/text-runs' numbers.");
 
   REPORT("window-objects/layout/pres-contexts", windowTotalSizes.mLayoutPresContextSize,
          "This is the sum of all windows' 'layout/pres-contexts' numbers.");
 
+  REPORT("window-objects/layout/frame-properties", windowTotalSizes.mLayoutFramePropertiesSize,
+         "This is the sum of all windows' 'layout/frame-properties' numbers.");
+
   size_t frameTotal = 0;
 #define FRAME_ID(classname, ...)                \
   frameTotal += windowTotalSizes.mArenaStats.FRAME_ID_STAT_FIELD(classname);
 #define ABSTRACT_FRAME_ID(...)
 #include "nsFrameIdList.h"
 #undef FRAME_ID
 #undef ABSTRACT_FRAME_ID
 
--- a/dom/base/nsWindowMemoryReporter.h
+++ b/dom/base/nsWindowMemoryReporter.h
@@ -28,16 +28,17 @@ class nsWindowSizes {
   macro(DOM,   mDOMCommentNodesSize) \
   macro(DOM,   mDOMEventTargetsSize) \
   macro(DOM,   mDOMOtherSize) \
   macro(Style, mStyleSheetsSize) \
   macro(Other, mLayoutPresShellSize) \
   macro(Style, mLayoutStyleSetsSize) \
   macro(Other, mLayoutTextRunsSize) \
   macro(Other, mLayoutPresContextSize) \
+  macro(Other, mLayoutFramePropertiesSize) \
   macro(Other, mPropertyTablesSize) \
 
 public:
   explicit nsWindowSizes(mozilla::MallocSizeOf aMallocSizeOf)
     :
       #define ZERO_SIZE(kind, mSize)  mSize(0),
       FOR_EACH_SIZE(ZERO_SIZE)
       #undef ZERO_SIZE
--- a/dom/base/test/mozbrowser_api_utils.js
+++ b/dom/base/test/mozbrowser_api_utils.js
@@ -1,15 +1,11 @@
 const FRAME_URL = "http://example.org/";
 
 const METHODS = {
-  setVisible: {},
-  getVisible: {},
-  setActive: {},
-  getActive: {},
   addNextPaintListener: {},
   removeNextPaintListener: {},
   sendMouseEvent: {},
   sendTouchEvent: {},
   goBack: {},
   goForward: {},
   reload: {},
   stop: {},
--- a/dom/base/test/test_intersectionobservers.html
+++ b/dom/base/test/test_intersectionobservers.html
@@ -317,26 +317,26 @@ limitations under the License.
           expect(observer).to.be(io);
           expect(this).to.be(io);
           done();
         }, {root: rootEl});
         io.observe(targetEl1);
       });
 
 
-      it('does not trigger if target does not intersect when observing begins',
+      it('does trigger if target does not intersect when observing begins',
           function(done) {
 
         var spy = sinon.spy();
         io = new IntersectionObserver(spy, {root: rootEl});
 
         targetEl2.style.top = '-40px';
         io.observe(targetEl2);
         callDelayed(function() {
-          expect(spy.callCount).to.be(0);
+          expect(spy.callCount).to.be(1);
           done();
         }, ASYNC_TIMEOUT);
       });
 
 
       it('does not trigger if target is not a descendant of the intersection root in the containing block chain',
           function(done) {
 
@@ -520,17 +520,17 @@ limitations under the License.
             targetEl3.style.top = '0px';
             targetEl3.style.left = '205px';
             io.observe(targetEl1);
             io.observe(targetEl2);
             io.observe(targetEl3);
             spy.waitForNotification(function() {
               expect(spy.callCount).to.be(1);
               var records = sortRecords(spy.lastCall.args[0]);
-              expect(records.length).to.be(2);
+              expect(records.length).to.be(3);
               expect(records[0].target).to.be(targetEl1);
               expect(records[0].intersectionRatio).to.be(0.25);
               expect(records[1].target).to.be(targetEl2);
               expect(records[1].intersectionRatio).to.be(0.75);
               done();
             });
           },
           function(done) {
@@ -625,59 +625,59 @@ limitations under the License.
             io.observe(targetEl1);
             io.observe(targetEl2);
             io.observe(targetEl3);
             io.observe(targetEl4);
           },
           function(done) {
             io = new IntersectionObserver(function(records) {
               records = sortRecords(records);
-              expect(records.length).to.be(3);
+              expect(records.length).to.be(4);
               expect(records[0].target).to.be(targetEl1);
               expect(records[0].intersectionRatio).to.be(0.5);
-              expect(records[1].target).to.be(targetEl3);
-              expect(records[1].intersectionRatio).to.be(0.5);
-              expect(records[2].target).to.be(targetEl4);
+              expect(records[2].target).to.be(targetEl3);
               expect(records[2].intersectionRatio).to.be(0.5);
+              expect(records[3].target).to.be(targetEl4);
+              expect(records[3].intersectionRatio).to.be(0.5);
               io.disconnect();
               done();
             }, {root: rootEl, rootMargin: '-10px 10%'});
 
             io.observe(targetEl1);
             io.observe(targetEl2);
             io.observe(targetEl3);
             io.observe(targetEl4);
           },
           function(done) {
             io = new IntersectionObserver(function(records) {
               records = sortRecords(records);
-              expect(records.length).to.be(2);
+              expect(records.length).to.be(4);
               expect(records[0].target).to.be(targetEl1);
               expect(records[0].intersectionRatio).to.be(0.5);
-              expect(records[1].target).to.be(targetEl4);
-              expect(records[1].intersectionRatio).to.be(0.5);
+              expect(records[3].target).to.be(targetEl4);
+              expect(records[3].intersectionRatio).to.be(0.5);
               io.disconnect();
               done();
             }, {root: rootEl, rootMargin: '-5% -2.5% 0px'});
 
             io.observe(targetEl1);
             io.observe(targetEl2);
             io.observe(targetEl3);
             io.observe(targetEl4);
           },
           function(done) {
             io = new IntersectionObserver(function(records) {
               records = sortRecords(records);
-              expect(records.length).to.be(3);
+              expect(records.length).to.be(4);
               expect(records[0].target).to.be(targetEl1);
               expect(records[0].intersectionRatio).to.be(0.5);
               expect(records[1].target).to.be(targetEl2);
               expect(records[1].intersectionRatio).to.be(0.5);
-              expect(records[2].target).to.be(targetEl4);
-              expect(records[2].intersectionRatio).to.be(0.25);
+              expect(records[3].target).to.be(targetEl4);
+              expect(records[3].intersectionRatio).to.be(0.25);
               io.disconnect();
               done();
             }, {root: rootEl, rootMargin: '5% -2.5% -10px -190px'});
 
             io.observe(targetEl1);
             io.observe(targetEl2);
             io.observe(targetEl3);
             io.observe(targetEl4);
@@ -697,19 +697,19 @@ limitations under the License.
             targetEl1.style.left = '-21px';
             targetEl2.style.top = '-20px';
             targetEl2.style.left = '0px';
             io.observe(targetEl1);
             io.observe(targetEl2);
             spy.waitForNotification(function() {
               expect(spy.callCount).to.be(1);
               var records = sortRecords(spy.lastCall.args[0]);
-              expect(records.length).to.be(1);
-              expect(records[0].intersectionRatio).to.be(0);
-              expect(records[0].target).to.be(targetEl2);
+              expect(records.length).to.be(2);
+              expect(records[1].intersectionRatio).to.be(0);
+              expect(records[1].target).to.be(targetEl2);
               done();
             });
           },
           function(done) {
             targetEl1.style.top = '0px';
             targetEl1.style.left = '-20px';
             targetEl2.style.top = '-21px';
             targetEl2.style.left = '0px';
@@ -809,57 +809,57 @@ limitations under the License.
         runSequence([
           function(done) {
             io.observe(targetEl1);
             callDelayed(done, 0);
           },
           function(done) {
             document.getElementById('fixtures').appendChild(rootEl);
             callDelayed(function() {
-              expect(spy.callCount).to.be(0);
+              expect(spy.callCount).to.be(1);
               done();
             }, ASYNC_TIMEOUT);
           },
           function(done) {
             parentEl.insertBefore(targetEl1, targetEl2);
             spy.waitForNotification(function() {
-              expect(spy.callCount).to.be(1);
+              expect(spy.callCount).to.be(2);
               var records = sortRecords(spy.lastCall.args[0]);
               expect(records.length).to.be(1);
               expect(records[0].intersectionRatio).to.be(1);
               expect(records[0].target).to.be(targetEl1);
               done();
             });
           },
           function(done) {
             grandParentEl.remove();
             spy.waitForNotification(function() {
-              expect(spy.callCount).to.be(2);
+              expect(spy.callCount).to.be(3);
               var records = sortRecords(spy.lastCall.args[0]);
               expect(records.length).to.be(1);
               expect(records[0].intersectionRatio).to.be(0);
               expect(records[0].target).to.be(targetEl1);
               done();
             });
           },
           function(done) {
             rootEl.appendChild(targetEl1);
             spy.waitForNotification(function() {
-              expect(spy.callCount).to.be(3);
+              expect(spy.callCount).to.be(4);
               var records = sortRecords(spy.lastCall.args[0]);
               expect(records.length).to.be(1);
               expect(records[0].intersectionRatio).to.be(1);
               expect(records[0].target).to.be(targetEl1);
               done();
             });
           },
           function(done) {
             rootEl.remove();
             spy.waitForNotification(function() {
-              expect(spy.callCount).to.be(4);
+              expect(spy.callCount).to.be(5);
               var records = sortRecords(spy.lastCall.args[0]);
               expect(records.length).to.be(1);
               expect(records[0].intersectionRatio).to.be(0);
               expect(records[0].target).to.be(targetEl1);
               done();
             });
           }
         ], done);
@@ -880,17 +880,23 @@ limitations under the License.
       });
 
 
       it('supports CSS transitions and transforms', function(done) {
 
         targetEl1.style.top = '220px';
         targetEl1.style.left = '220px';
 
+        var callCount = 0;
+
         io = new IntersectionObserver(function(records) {
+          callCount++;
+          if (callCount <= 1) {
+            return;
+          }
           expect(records.length).to.be(1);
           expect(records[0].intersectionRatio).to.be(1);
           done();
         }, {root: rootEl, threshold: [1]});
 
         io.observe(targetEl1);
         callDelayed(function() {
           targetEl1.style.transform = 'translateX(-40px) translateY(-40px)';
--- a/dom/base/test/test_websocket_basic.html
+++ b/dom/base/test/test_websocket_basic.html
@@ -233,23 +233,57 @@ function testWebSocket5() {
     is(this.bufferedAmount, 0, "[5] Length of empty buffer after closing");
 
     var msg = "test message to be buffered";
     this.send(msg);
     is(this.bufferedAmount, msg.length, "[5] Length of buffered message sent after closing");
 
     gTestElement.textContent += "\ntestWebSocket5() completed";
 
-    SimpleTest.executeSoon(SimpleTest.finish);
+    SimpleTest.executeSoon(testWebSocket6);
   };
   ws.onerror = function(e) {
     ok(false, "[5] onerror() should not have been called!");
     gTestElement.textContent += "\nonerror() should not have been called!";
     SimpleTest.executeSoon(SimpleTest.finish);
   };
 }
 
+function testWebSocket6() {
+  gTestElement.textContent = "Running testWebSocket6()";
+
+  var msgReceived = false;
+  ws = new WebSocket(kUrl, "test");
+  ws.onopen = function(e) {
+    gTestElement.textContent += "\nSending ©";
+    ws.send("©");
+    gTestElement.textContent += " end";
+    ws.send("end");
+  };
+  ws.onclose = function(e) {
+    ok(msgReceived, "[6] Number of received messages");
+    ok(e.wasClean, "[6] Connection closed cleanly");
+
+    SimpleTest.executeSoon(SimpleTest.finish);
+  };
+  ws.onerror = function(e) {
+    ok(false, "[6] onerror() should not have been called!");
+    gTestElement.textContent += "\nonerror() should not have been called!";
+    SimpleTest.executeSoon(SimpleTest.finish);
+  };
+
+  ws.onmessage = function(e) {
+    if (msgReceived) {
+      is(e.data, "end", "[6] Received message");
+    } else {
+      gTestElement.textContent += "\nReceived: " + e.data;
+      is(e.data, "©", "[6] Received message");
+      msgReceived = true;
+    }
+  };
+}
+
 SimpleTest.waitForExplicitFinish();
 
 </script>
 </pre>
 </body>
 </html>
--- a/dom/browser-element/BrowserElementChildPreload.js
+++ b/dom/browser-element/BrowserElementChildPreload.js
@@ -111,25 +111,16 @@ var LISTENED_SYSTEM_EVENTS = [
  */
 
 var global = this;
 
 function BrowserElementChild() {
   // Maps outer window id --> weak ref to window.  Used by modal dialog code.
   this._windowIDDict = {};
 
-  // _forcedVisible corresponds to the visibility state our owner has set on us
-  // (via iframe.setVisible).  ownerVisible corresponds to whether the docShell
-  // whose window owns this element is visible.
-  //
-  // Our docShell is visible iff _forcedVisible and _ownerVisible are both
-  // true.
-  this._forcedVisible = true;
-  this._ownerVisible = true;
-
   this._nextPaintHandler = null;
 
   this._isContentWindowCreated = false;
 
   this._init();
 };
 
 BrowserElementChild.prototype = {
@@ -281,18 +272,16 @@ BrowserElementChild.prototype = {
 
   receiveMessage: function(message) {
     let self = this;
 
     let mmCalls = {
       "purge-history": this._recvPurgeHistory,
       "get-screenshot": this._recvGetScreenshot,
       "get-contentdimensions": this._recvGetContentDimensions,
-      "set-visible": this._recvSetVisible,
-      "get-visible": this._recvVisible,
       "send-mouse-event": this._recvSendMouseEvent,
       "send-touch-event": this._recvSendTouchEvent,
       "get-can-go-back": this._recvCanGoBack,
       "get-can-go-forward": this._recvCanGoForward,
       "go-back": this._recvGoBack,
       "go-forward": this._recvGoForward,
       "reload": this._recvReload,
       "stop": this._recvStop,
@@ -1226,45 +1215,23 @@ BrowserElementChild.prototype = {
     // "Copy Image" menu item
     if (copyableElements.image) {
       menuObj.items.push({id: 'copy-image'});
     }
 
     return menuObj;
   },
 
-  _recvSetVisible: function(data) {
-    debug("Received setVisible message: (" + data.json.visible + ")");
-    if (this._forcedVisible == data.json.visible) {
-      return;
-    }
-
-    this._forcedVisible = data.json.visible;
-    this._updateVisibility();
-  },
-
-  _recvVisible: function(data) {
-    sendAsyncMsg('got-visible', {
-      id: data.json.id,
-      successRv: docShell.isActive
-    });
-  },
-
   /**
    * Called when the window which contains this iframe becomes hidden or
    * visible.
    */
   _recvOwnerVisibilityChange: function(data) {
     debug("Received ownerVisibilityChange: (" + data.json.visible + ")");
-    this._ownerVisible = data.json.visible;
-    this._updateVisibility();
-  },
-
-  _updateVisibility: function() {
-    var visible = this._forcedVisible && this._ownerVisible;
+    var visible = data.json.visible;
     if (docShell && docShell.isActive !== visible) {
       docShell.isActive = visible;
       sendAsyncMsg('visibilitychange', {visible: visible});
 
       // Ensure painting is not frozen if the app goes visible.
       if (visible && this._paintFrozenTimer) {
         this.notify();
       }
--- a/dom/browser-element/BrowserElementParent.js
+++ b/dom/browser-element/BrowserElementParent.js
@@ -523,36 +523,16 @@ BrowserElementParent.prototype = {
     }
     else {
       debug("Got error in gotDOMRequestResult.");
       Services.DOMRequest.fireErrorAsync(req,
         Cu.cloneInto(data.json.errorMsg, this._window));
     }
   },
 
-  setVisible: defineNoReturnMethod(function(visible) {
-    this._sendAsyncMsg('set-visible', {visible: visible});
-    this._frameLoader.visible = visible;
-  }),
-
-  getVisible: defineDOMRequestMethod('get-visible'),
-
-  setActive: defineNoReturnMethod(function(active) {
-    this._frameLoader.visible = active;
-  }),
-
-  getActive: function() {
-    if (!this._isAlive()) {
-      throw Components.Exception("Dead content process",
-                                 Cr.NS_ERROR_DOM_INVALID_STATE_ERR);
-    }
-
-    return this._frameLoader.visible;
-  },
-
   getChildProcessOffset: function() {
     let offset = { x: 0, y: 0 };
     let tabParent = this._frameLoader.tabParent;
     if (tabParent) {
       let offsetX = {};
       let offsetY = {};
       tabParent.getChildProcessOffset(offsetX, offsetY);
       offset.x = offsetX.value;
@@ -879,21 +859,16 @@ BrowserElementParent.prototype = {
    */
   _ownerVisibilityChange: function() {
     this._sendAsyncMsg('owner-visibility-change',
                        {visible: !this._window.document.hidden});
   },
 
   /*
    * Called when the child notices that its visibility has changed.
-   *
-   * This is sometimes redundant; for example, the child's visibility may
-   * change in response to a setVisible request that we made here!  But it's
-   * not always redundant; for example, the child's visibility may change in
-   * response to its parent docshell being hidden.
    */
   _childVisibilityChange: function(data) {
     debug("_childVisibilityChange(" + data.json.visible + ")");
     this._frameLoader.visible = data.json.visible;
 
     this._fireEventFromMsg(data);
   },
 
deleted file mode 100644
--- a/dom/browser-element/mochitest/browserElement_SetVisible.js
+++ /dev/null
@@ -1,75 +0,0 @@
-/* Any copyright is dedicated to the public domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test the setVisible property for mozbrowser
-"use strict";
-
-SimpleTest.waitForExplicitFinish();
-SimpleTest.requestFlakyTimeout("untriaged");
-browserElementTestHelpers.setEnabledPref(true);
-
-var iframeScript = function() {
-  content.document.addEventListener("visibilitychange", function() {
-    sendAsyncMessage('test:visibilitychange', {
-      hidden: content.document.hidden
-    });
-  });
-}
-
-function runTest() {
-  var mm;
-  var numEvents = 0;
-  var iframe1 = document.createElement('iframe');
-  iframe1.setAttribute('mozbrowser', 'true');
-  iframe1.src = 'data:text/html,1';
-
-  document.body.appendChild(iframe1);
-
-  function recvVisibilityChanged(msg) {
-    msg = SpecialPowers.wrap(msg);
-    numEvents++;
-    if (numEvents === 1) {
-      ok(true, 'iframe recieved visibility changed');
-      ok(msg.json.hidden === true, 'hidden attribute correctly set');
-      iframe1.setVisible(false);
-      iframe1.setVisible(true);
-    } else if (numEvents === 2) {
-      ok(msg.json.hidden === false, 'hidden attribute correctly set');
-      // Allow some time in case we generate too many events
-      setTimeout(function() {
-        mm.removeMessageListener('test:visibilitychange', recvVisibilityChanged);
-        SimpleTest.finish();
-      }, 100);
-    } else {
-      ok(false, 'Too many visibilitychange events');
-    }
-  }
-
-  function iframeLoaded() {
-    testGetVisible();
-  }
-
-  function testGetVisible() {
-    iframe1.setVisible(false);
-    iframe1.getVisible().onsuccess = function(evt) {
-      ok(evt.target.result === false, 'getVisible() responds false after setVisible(false)');
-
-      iframe1.setVisible(true);
-      iframe1.getVisible().onsuccess = function(evt) {
-        ok(evt.target.result === true, 'getVisible() responds true after setVisible(true)');
-        testVisibilityChanges();
-      };
-    };
-  }
-
-  function testVisibilityChanges() {
-    mm = SpecialPowers.getBrowserFrameMessageManager(iframe1);
-    mm.addMessageListener('test:visibilitychange', recvVisibilityChanged);
-    mm.loadFrameScript('data:,(' + iframeScript.toString() + ')();', false);
-    iframe1.setVisible(false);
-  }
-
-  iframe1.addEventListener('mozbrowserloadend', iframeLoaded);
-}
-
-addEventListener('testready', runTest);
deleted file mode 100644
--- a/dom/browser-element/mochitest/browserElement_SetVisibleFrames.js
+++ /dev/null
@@ -1,89 +0,0 @@
-/* Any copyright is dedicated to the public domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Bug 762939 - Test that visibility propagates down properly through
-// hierarchies of <iframe mozbrowser>.
-//
-// In this test, we modify the parent's visibility and check that the child's
-// visibility is changed as appopriate.  We test modifying the child's
-// visibility in a separate testcase.
-
-"use strict";
-
-SimpleTest.waitForExplicitFinish();
-browserElementTestHelpers.setEnabledPref(true);
-
-var iframe;
-
-function runTest() {
-  iframe = document.createElement('iframe');
-  iframe.setAttribute('mozbrowser', 'true');
-
-  // Our test involves three <iframe mozbrowser>'s, parent, child1, and child2.
-  // child1 and child2 are contained inside parent.  child1 is visibile, and
-  // child2 is not.
-  //
-  // For the purposes of this test, we want there to be a process barrier
-  // between child{1,2} and parent.  Therefore parent must be a non-remote
-  // <iframe mozbrowser>, until bug 761935 is resolved and we can have nested
-  // content processes.
-  iframe.remote = false;
-
-  iframe.addEventListener('mozbrowsershowmodalprompt', checkMessage);
-  expectMessage('parent:ready', test1);
-
-  document.body.appendChild(iframe);
-  iframe.src = 'file_browserElement_SetVisibleFrames_Outer.html';
-}
-
-function test1() {
-  expectMessage('child1:hidden', getVisibleTest1);
-  iframe.setVisible(false);
-}
-
-function getVisibleTest1() {
-  iframe.getVisible().onsuccess = function(evt) {
-    ok(evt.target.result === false, 'getVisible shows a hidden frame');
-    test2();
-  };
-}
-
-function test2() {
-  expectMessage('child1:visible', getVisibleTest2);
-  iframe.setVisible(true);
-}
-
-function getVisibleTest2() {
-  iframe.getVisible().onsuccess = function(evt) {
-    ok(evt.target.result === true, 'getVisible shows a displayed frame');
-    finish();
-  };
-}
-
-function finish() {
-  // We need to remove this listener because when this test finishes and the
-  // iframe containing this document is navigated, we'll fire a
-  // visibilitychange(false) event on all child iframes.  That's OK and
-  // expected, but if we don't remove our listener, then we'll end up causing
-  // the /next/ test to fail!
-  iframe.removeEventListener('mozbrowsershowmodalprompt', checkMessage);
-  SimpleTest.finish();
-}
-
-var expectedMsg = null;
-var expectedMsgCallback = null;
-function expectMessage(msg, next) {
-  expectedMsg = msg;
-  expectedMsgCallback = next;
-}
-
-function checkMessage(e) {
-  var msg = e.detail.message;
-  is(msg, expectedMsg);
-  if (msg == expectedMsg) {
-    expectedMsg = null;
-    SimpleTest.executeSoon(function() { expectedMsgCallback() });
-  }
-}
-
-addEventListener('testready', runTest);
deleted file mode 100644
--- a/dom/browser-element/mochitest/browserElement_SetVisibleFrames2.js
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Any copyright is dedicated to the public domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Bug 762939 - Test that setting a <iframe mozbrowser> to invisible / visible
-// inside an invisible <iframe mozbrowser> doesn't trigger any events.
-
-"use strict";
-
-SimpleTest.waitForExplicitFinish();
-browserElementTestHelpers.setEnabledPref(true);
-
-function runTest() {
-  var iframe = document.createElement('iframe');
-  iframe.setAttribute('mozbrowser', 'true');
-
-  // We need remote = false here until bug 761935 is fixed; see
-  // SetVisibleFrames.js for an explanation.
-  iframe.remote = false;
-
-  iframe.addEventListener('mozbrowserloadend', function(e) {
-    iframe.setVisible(false);
-    iframe.src = 'file_browserElement_SetVisibleFrames2_Outer.html';
-  }, {once: true});
-
-  iframe.addEventListener('mozbrowsershowmodalprompt', function(e) {
-    if (e.detail.message == 'parent:finish') {
-      ok(true, "Got parent:finish");
-
-      // Give any extra events a chance to fire, then end the test.
-      SimpleTest.executeSoon(function() {
-        SimpleTest.executeSoon(function() {
-          SimpleTest.executeSoon(function() {
-            SimpleTest.executeSoon(function() {
-              SimpleTest.executeSoon(function() {
-                finish();
-              });
-            });
-          });
-        });
-      });
-    }
-    else {
-      ok(false, "Got unexpected message: " + e.detail.message);
-    }
-  });
-
-  document.body.appendChild(iframe);
-}
-
-function finish() {
-  SimpleTest.finish();
-}
-
-addEventListener('testready', runTest);
deleted file mode 100644
--- a/dom/browser-element/mochitest/browserElement_VisibilityChange.js
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Any copyright is dedicated to the public domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test that the onmozbrowservisibilitychange event works.
-'use strict';
-
-SimpleTest.waitForExplicitFinish();
-browserElementTestHelpers.setEnabledPref(true);
-
-var iframe1 = null;
-function runTest() {
-  iframe1 = document.createElement('iframe');
-  iframe1.setAttribute('mozbrowser', 'true');
-  document.body.appendChild(iframe1);
-
-  iframe1.src = 'data:text/html,<html><head><title>Title</title></head><body></body></html>';
-  checkVisibilityFalse();
-}
-
-function checkVisibilityFalse() {
-  iframe1.addEventListener('mozbrowservisibilitychange', function onvisibilitychange(e) {
-    iframe1.removeEventListener(e.type, onvisibilitychange);
-
-    is(e.detail.visible, false, 'Visibility should be false');
-    checkVisibilityTrue();
-  });
-
-  iframe1.setVisible(false);
-}
-
-function checkVisibilityTrue() {
-  iframe1.addEventListener('mozbrowservisibilitychange', function onvisibilitychange(e) {
-    iframe1.removeEventListener(e.type, onvisibilitychange);
-
-    is(e.detail.visible, true, 'Visibility should be true');
-    SimpleTest.finish();
-  });
-
-  iframe1.setVisible(true);
-}
-
-addEventListener('testready', runTest);
--- a/dom/browser-element/mochitest/chrome.ini
+++ b/dom/browser-element/mochitest/chrome.ini
@@ -15,27 +15,20 @@ support-files =
   browserElement_GetContentDimensions.js
   browserElement_GetScreenshot.js
   browserElement_GetScreenshotDppx.js
   browserElement_getWebManifest.js
   browserElement_NextPaint.js
   browserElement_PurgeHistory.js
   browserElement_ReloadPostRequest.js
   browserElement_SendEvent.js
-  browserElement_SetVisible.js
-  browserElement_SetVisibleFrames.js
-  browserElement_SetVisibleFrames2.js
   browserElement_Stop.js
-  browserElement_VisibilityChange.js
   file_browserElement_ExecuteScript.html
   file_browserElement_NextPaint.html
   file_browserElement_SendEvent.html
-  file_browserElement_SetVisibleFrames2_Outer.html
-  file_browserElement_SetVisibleFrames_Inner.html
-  file_browserElement_SetVisibleFrames_Outer.html
   file_bug709759.sjs
   file_empty.html
   file_post_request.html
   file_web_manifest.html
   file_web_manifest.json
   file_illegal_web_manifest.html
 
 [test_browserElement_inproc_AudioPlayback.html]
@@ -50,13 +43,9 @@ skip-if = true # bug 1332850, bug 133286
 [test_browserElement_inproc_GetScreenshot.html]
 [test_browserElement_inproc_GetScreenshotDppx.html]
 [test_browserElement_inproc_getWebManifest.html]
 [test_browserElement_inproc_NextPaint.html]
 [test_browserElement_inproc_PurgeHistory.html]
 [test_browserElement_inproc_ReloadPostRequest.html]
 disabled = no modal prompt on POST reload for chrome window
 [test_browserElement_inproc_SendEvent.html]
-[test_browserElement_inproc_SetVisible.html]
-[test_browserElement_inproc_SetVisibleFrames.html]
-[test_browserElement_inproc_SetVisibleFrames2.html]
 [test_browserElement_inproc_Stop.html]
-[test_browserElement_inproc_VisibilityChange.html]
deleted file mode 100644
--- a/dom/browser-element/mochitest/file_browserElement_SetVisibleFrames2_Outer.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<html>
-<body>
-<script>
-
-var iframe = document.createElement('iframe');
-iframe.setAttribute("mozbrowser", "true");
-
-iframe.addEventListener('mozbrowsershowmodalprompt', function(e) {
-  if (e.detail.message == 'child:ready') {
-    setTimeout(function() {
-      iframe.setVisible(false);
-      iframe.setVisible(true);
-      setTimeout(function() {
-        alert('parent:finish');
-      }, 0);
-    }, 0);
-  }
-});
-
-document.body.appendChild(iframe);
-iframe.src = 'file_browserElement_SetVisibleFrames_Inner.html?child';
-
-</script>
-</body>
-</html>
deleted file mode 100644
--- a/dom/browser-element/mochitest/file_browserElement_SetVisibleFrames_Outer.html
+++ /dev/null
@@ -1,45 +0,0 @@
-<html>
-<body>
-
-<script>
-
-var numPrompts = 0;
-function handlePrompt(e) {
-  numPrompts++;
-
-  // The first two prompts should be "child1:ready" and "child2:ready".  Once
-  // we get both of these, forward the child's prompt up to our parent.
-  if (numPrompts == 2) {
-    // This has to happen here, because setVisibile doesn't exist on the iframe
-    // until BrowserElementChild.js is loaded in it.  (That's pretty broken...)
-    iframe2.setVisible(false);
-  }
-  else if (numPrompts == 3) {
-    if (e.detail.message != 'child2:hidden') {
-      alert("parent:fail Didn't get expected 'child2:hidden'.");
-    }
-
-    alert('parent:ready');
-  }
-  else if (numPrompts == 4 || numPrompts == 5) {
-    alert(e.detail.message);
-  }
-}
-
-var iframe1 = document.createElement('iframe');
-iframe1.setAttribute("mozbrowser", "true");
-iframe1.addEventListener('mozbrowsershowmodalprompt', handlePrompt);
-
-var iframe2 = document.createElement('iframe');
-iframe2.setAttribute("mozbrowser", "true");
-iframe2.addEventListener('mozbrowsershowmodalprompt', handlePrompt);
-
-iframe1.src = 'file_browserElement_SetVisibleFrames_Inner.html?child1';
-iframe2.src = 'file_browserElement_SetVisibleFrames_Inner.html?child2';
-document.body.appendChild(iframe1);
-document.body.appendChild(iframe2);
-
-</script>
-
-</body>
-</html>
--- a/dom/browser-element/mochitest/mochitest-oop.ini
+++ b/dom/browser-element/mochitest/mochitest-oop.ini
@@ -75,30 +75,22 @@ disabled = Disabling some OOP tests for 
 [test_browserElement_oop_ReloadPostRequest.html]
 disabled = Disabling some OOP tests for WebIDL scope changes (bug 1310706 for re-enabling)
 [test_browserElement_oop_RemoveBrowserElement.html]
 [test_browserElement_oop_ScrollEvent.html]
 [test_browserElement_oop_SecurityChange.html]
 skip-if = toolkit == 'android' #TIMED_OUT, bug 766586
 [test_browserElement_oop_SendEvent.html]
 disabled = Disabling some OOP tests for WebIDL scope changes (bug 1310706 for re-enabling)
-[test_browserElement_oop_SetVisible.html]
-disabled = Disabling some OOP tests for WebIDL scope changes (bug 1310706 for re-enabling)
-[test_browserElement_oop_SetVisibleFrames.html]
-disabled = Disabling some OOP tests for WebIDL scope changes (bug 1310706 for re-enabling)
-[test_browserElement_oop_SetVisibleFrames2.html]
-disabled = Disabling some OOP tests for WebIDL scope changes (bug 1310706 for re-enabling)
 [test_browserElement_oop_Stop.html]
 disabled = Disabling some OOP tests for WebIDL scope changes (bug 1310706 for re-enabling)
 [test_browserElement_oop_TargetBlank.html]
 [test_browserElement_oop_TargetTop.html]
 [test_browserElement_oop_Titlechange.html]
 [test_browserElement_oop_TopBarrier.html]
-[test_browserElement_oop_VisibilityChange.html]
-disabled = Disabling some OOP tests for WebIDL scope changes (bug 1310706 for re-enabling)
 [test_browserElement_oop_XFrameOptions.html]
 [test_browserElement_oop_XFrameOptionsAllowFrom.html]
 #skip-if = asan # bug 1189592 - should be OK when ASAN mochitests are on Ubuntu 16.04
 disabled = Disabling some OOP tests for WebIDL scope changes (bug 1310706 for re-enabling)
 [test_browserElement_oop_XFrameOptionsDeny.html]
 disabled = Disabling some OOP tests for WebIDL scope changes (bug 1310706 for re-enabling)
 [test_browserElement_oop_XFrameOptionsSameOrigin.html]
 [test_browserElement_oop_ContextmenuEvents.html]
deleted file mode 100644
--- a/dom/browser-element/mochitest/priority/chrome.ini
+++ /dev/null
@@ -1,16 +0,0 @@
-[DEFAULT]
-# Good luck running these tests on anything but desktop Linux.
-run-if = os == 'linux' && buildapp == 'browser' && !e10s
-support-files =
-  file_MultipleFrames.html
-  file_NestedFramesOuter.html
-  file_WebGLContextLost.html
-  silence.ogg
-  !/dom/browser-element/mochitest/browserElementTestHelpers.js
-  !/dom/browser-element/mochitest/file_empty.html
-
-[test_Activity.html]
-[test_Background.html]
-[test_MultipleFrames.html]
-[test_NestedFrames.html]
-[test_Visibility.html]
deleted file mode 100644
--- a/dom/browser-element/mochitest/priority/file_MultipleFrames.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<html>
-<body>
-<p>file_MultipleFrames.html</p>
-
-<script>
-addEventListener('load', function() {
-  setTimeout(function() {
-    window.open('../file_empty.html');
-  }, 0);
-});
-</script>
-
-</body>
-</html>
deleted file mode 100644
--- a/dom/browser-element/mochitest/priority/file_NestedFramesOuter.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<html>
-<body>
-<p>file_NestedFramesOuter.html</p>
-<script>
-
-addEventListener('load', function() {
-  setTimeout(createIframe, 0);
-});
-
-function createIframe()
-{
-  var iframe = document.createElement('iframe');
-  iframe.setAttribute('mozbrowser', true);
-  iframe.src = location.hash.substr(1);
-  document.body.appendChild(iframe);
-}
-
-</script>
-</body>
-</html>
deleted file mode 100644
--- a/dom/browser-element/mochitest/priority/file_WebGLContextLost.html
+++ /dev/null
@@ -1,22 +0,0 @@
-<html>
-<body>
-file_WebGLContextLost.html
-<canvas id='canvas'></canvas>
-
-<script>
-function runTest()
-{
-  var canvas = document.getElementById('canvas');
-  canvas.addEventListener('webglcontextlost', function() {
-    alert('webglcontextlost');
-  });
-
-  var context = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
-  context.viewport(0, 0, 10, 10);
-  alert('ready');
-}
-
-addEventListener('load', function() { setTimeout(runTest, 0) });
-</script>
-</body>
-</html>
deleted file mode 100644
--- a/dom/browser-element/mochitest/priority/mochitest.ini
+++ /dev/null
@@ -1,15 +0,0 @@
-[DEFAULT]
-# Good luck running these tests on anything but desktop Linux.
-run-if = os == 'linux' && buildapp == 'browser' && !e10s
-support-files =
-  silence.ogg
-  !/dom/browser-element/mochitest/browserElementTestHelpers.js
-  !/dom/browser-element/mochitest/file_empty.html
-
-# Note: ../browserElementTestHelpers.js makes all tests in this directory OOP,
-# because testing the process-priority manager without OOP frames does not make
-# much sense.
-
-[test_Simple.html]
-[test_WebGLContextLost.html]
-disabled = bug 865844
deleted file mode 100644
index 6e0b352a321ae89cc2f41a008c660c8bf421afc2..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
--- a/dom/browser-element/mochitest/priority/test_Background.html
+++ /dev/null
@@ -1,53 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-Test that calling setVisible('false') on an iframe causes its visibility to
-change.
--->
-<head>
-  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="application/javascript" src="../browserElementTestHelpers.js"></script>
-  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
-</head>
-<body>
-
-<script type="application/javascript">
-"use strict";
-
-SimpleTest.waitForExplicitFinish();
-browserElementTestHelpers.setEnabledPref(true);
-browserElementTestHelpers.enableProcessPriorityManager();
-
-function runTest() {
-  var iframe = document.createElement('iframe');
-  iframe.setAttribute('mozbrowser', true);
-
-  iframe.src = browserElementTestHelpers.emptyPage1;
-
-  var childID = null;
-  Promise.all([
-    expectOnlyOneProcessCreated('FOREGROUND').then(function(chid) {
-      childID = chid;
-    }),
-    expectMozbrowserEvent(iframe, 'loadend')
-  ]).then(function() {
-    var p = expectPriorityChange(childID, 'BACKGROUND');
-
-    // We wait until mozbrowserloadend before calling setVisible, because
-    // setVisible isn't available until mozbrowser has loaded.  In practice, that
-    // means we can call setVisible once we've gotten /any/ mozbrowser event.
-    iframe.setVisible(false);
-    return p;
-  }).then(function() {
-    var p = expectPriorityChange(childID, 'FOREGROUND');
-    iframe.setVisible(true);
-  }).then(SimpleTest.finish);
-
-  document.body.appendChild(iframe);
-}
-
-addEventListener('testready', runTest);
-
-</script>
-</body>
-</html>
deleted file mode 100644
--- a/dom/browser-element/mochitest/priority/test_MultipleFrames.html
+++ /dev/null
@@ -1,58 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-Test that when we remove one of a process's frames from the DOM, the process's
-priority is recomputed.
--->
-<head>
-  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="application/javascript" src="../browserElementTestHelpers.js"></script>
-  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
-</head>
-<body>
-
-<script type="application/javascript">
-"use strict";
-
-SimpleTest.waitForExplicitFinish();
-browserElementTestHelpers.setEnabledPref(true);
-browserElementTestHelpers.enableProcessPriorityManager();
-
-function runTest() {
-  var iframe = document.createElement('iframe');
-  iframe.setAttribute('mozbrowser', true);
-  iframe.src = 'file_MultipleFrames.html';
-
-  var childID = null;
-  var iframe2;
-  Promise.all([
-    expectProcessCreated('FOREGROUND').then(function(chid) {
-      childID = chid;
-    }),
-    new Promise(function(resolve, reject) {
-      iframe.addEventListener('mozbrowseropenwindow', function(e) {
-        iframe2 = e.detail.frameElement;
-        var p = expectMozbrowserEvent(iframe2, 'loadend');
-        document.body.appendChild(iframe2);
-        resolve(p);
-      });
-    })
-  ]).then(function() {
-    // At this point, the child process has been set to FOREGROUND, and the popup
-    // opened by file_MultipleFrames has finished loading.
-    //
-    // Now setVisible(false) the popup frame and remove the popup frame from the
-    // DOM.  This should cause the process to take on BACKGROUND priority.
-    var p = expectPriorityChange(childID, 'BACKGROUND');
-    iframe.setVisible(false);
-    document.body.removeChild(iframe2);
-    return p;
-  }).then(SimpleTest.finish);
-
-  document.body.appendChild(iframe);
-}
-
-addEventListener('testready', runTest);
-</script>
-</body>
-</html>
deleted file mode 100644
--- a/dom/browser-element/mochitest/priority/test_NestedFrames.html
+++ /dev/null
@@ -1,62 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-Test changing the visibility of an <iframe mozbrowser> changes the visibility
-(and thus the priority) of any <iframe mozbrowser>s it contains.
--->
-<head>
-  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="application/javascript" src="../browserElementTestHelpers.js"></script>
-  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
-</head>
-<body>
-
-<script type="application/javascript">
-"use strict";
-
-SimpleTest.waitForExplicitFinish();
-browserElementTestHelpers.setEnabledPref(true);
-browserElementTestHelpers.enableProcessPriorityManager();
-
-function runTest() {
-  // Set up the following hierarchy of frames:
-  //
-  //   <iframe mozbrowser remote=false src='file_NestedFramesOuter.html'>
-  //     <iframe mozbrowser remote=true src='file_empty.html'>
-  //
-  // When we change the visibility of the outer iframe, it should change the
-  // priority of the inner one.
-
-  var iframe = document.createElement('iframe');
-  iframe.setAttribute('mozbrowser', true);
-  iframe.setAttribute('remote', false);
-  iframe.src = 'file_NestedFramesOuter.html#' + browserElementTestHelpers.emptyPage1;
-
-  // Note that this is the process corresponding to the /inner/ iframe.  The
-  // outer iframe runs in-process (because it has remote=false).
-  var childID = null;
-  Promise.all(
-    [expectOnlyOneProcessCreated('FOREGROUND').then(function(child) {
-       childID = child;
-     }),
-     expectMozbrowserEvent(iframe, 'loadend')]
-  ).then(function() {
-    // Send the outer iframe into the background.  This should change the
-    // priority of the inner frame's process to BACKGROUND.
-    var p = expectPriorityChange(childID, 'BACKGROUND');
-    iframe.setVisible(false);
-    return p;
-  }).then(function() {
-    var p = expectPriorityChange(childID, 'FOREGROUND');
-    iframe.setVisible(true);
-    return p;
-  }).then(SimpleTest.finish);
-
-  document.body.appendChild(iframe);
-}
-
-addEventListener('testready', runTest);
-
-</script>
-</body>
-</html>
deleted file mode 100644
--- a/dom/browser-element/mochitest/priority/test_Simple.html
+++ /dev/null
@@ -1,59 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-A simple test of the process priority manager.
-
-https://bugzilla.mozilla.org/show_bug.cgi?id=844323
-
-Note: If you run this test alone (i.e. not as part of the larger mochitest
-suite), you may see some IPC assertions, e.g. "Can't allocate graphics
-resources."
-
-What appears to be happening is that we close the Firefox window before the
-frame we create in this tab finishes starting up.  Then the frame finishes
-loading, and it tries to show itself.  But it's too late to show a remote frame
-at that point, so we kill the child process.
-
-In other words, I think these errors are nothing to worry about.
--->
-<head>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="application/javascript" src="../browserElementTestHelpers.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
-
-<script type="application/javascript">
-"use strict";
-
-SimpleTest.waitForExplicitFinish();
-browserElementTestHelpers.setEnabledPref(true);
-browserElementTestHelpers.addPermission();
-browserElementTestHelpers.enableProcessPriorityManager();
-
-var allCompleted = 0;
-var allExpected  = 2;
-function finish() {
-  allCompleted++;
-  if (allCompleted === allExpected) {
-    SimpleTest.finish();
-  }
-}
-
-function runTest() {
-  var iframeLoaded = false;
-  var iframe = document.createElement('iframe');
-  iframe.setAttribute('mozbrowser', true);
-  iframe.src = browserElementTestHelpers.emptyPage1;
-
-  iframe.addEventListener('mozbrowserloadend', finish);
-  expectProcessCreated('FOREGROUND').then(finish);
-
-  document.body.appendChild(iframe);
-}
-
-addEventListener('testready', runTest);
-
-</script>
-</body>
-</html>
deleted file mode 100644
--- a/dom/browser-element/mochitest/priority/test_Visibility.html
+++ /dev/null
@@ -1,51 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-Test that setVisible() changes a process's priority.
--->
-<head>
-  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="application/javascript" src="../browserElementTestHelpers.js"></script>
-  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
-</head>
-<body>
-
-<script type="application/javascript">
-"use strict";
-
-SimpleTest.waitForExplicitFinish();
-browserElementTestHelpers.setEnabledPref(true);
-browserElementTestHelpers.enableProcessPriorityManager();
-
-function runTest() {
-  var iframe = document.createElement('iframe');
-  iframe.setAttribute('mozbrowser', true);
-  iframe.src = browserElementTestHelpers.emptyPage1;
-
-  var childID = null;
-  Promise.all([
-    expectOnlyOneProcessCreated('FOREGROUND').then(function(chid) {
-      childID = chid;
-    }),
-    expectMozbrowserEvent(iframe, 'loadend')
-  ]).then(function() {
-    // Mark the frame as not visible.  This should cause its priority to drop
-    // to BACKGROUND.
-    var p = expectPriorityChange(childID, 'BACKGROUND');
-    iframe.setVisible(false);
-    return p;
-  }).then(function() {
-    // Mark the frame as visible again.  This should cause its priority change
-    // back to FOREGROUND.
-    var p = expectPriorityChange(childID, 'FOREGROUND');
-    iframe.setVisible(true);
-    return p;
-  }).then(SimpleTest.finish);
-
-  document.body.appendChild(iframe);
-}
-
-addEventListener('testready', runTest);
-</script>
-</body>
-</html>
deleted file mode 100644
--- a/dom/browser-element/mochitest/priority/test_WebGLContextLost.html
+++ /dev/null
@@ -1,99 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-Test that calling setVisible('false') and then sending a low-memory
-notification causes a WebGL context loss event.
--->
-<head>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="application/javascript" src="../browserElementTestHelpers.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
-
-<script type="application/javascript">
-"use strict";
-
-SimpleTest.waitForExplicitFinish();
-browserElementTestHelpers.setEnabledPref(true);
-browserElementTestHelpers.addPermission();
-browserElementTestHelpers.enableProcessPriorityManager();
-
-function runTest() {
-  var iframe = document.createElement('iframe');
-  iframe.setAttribute('mozbrowser', true);
-  iframe.src = 'file_WebGLContextLost.html';
-
-  // We use this to ensure that we don't call SimpleTest.finish() twice.
-  var finished = false;
-  function finishOnce() {
-    if (!finished) {
-      SimpleTest.finish();
-      finished = true;
-    }
-  }
-
-  expectMozbrowserEvent(iframe, 'error').then(function(e) {
-    if (finished) {
-      // We don't care if the frame dies after the test finishes.
-      return;
-    }
-    todo(false, "child process is crashing; this probably indicates that " +
-         "something is wrong with WebGL in child processes on your machine.");
-    is(e.detail.type, 'fatal');
-  }).then(finishOnce);
-
-  var childID = null;
-  Promise.all([
-    expectOnlyOneProcessCreated('FOREGROUND').then(function(chid) {
-      childID = chid;
-    }),
-    expectMozbrowserEvent(iframe, 'loadend'),
-    expectMozbrowserEvent(iframe, 'showmodalprompt').then(function(e) {
-      is(e.detail.message, 'ready');
-    })
-  ]).then(function() {
-    // Fire a low-memory notification once the process goes into the background
-    // due to the setVisible(false) call below.
-    expectPriorityChange(childID, 'BACKGROUND').then(function() {
-      SimpleTest.executeSoon(function() {
-        var os = SpecialPowers.Cc["@mozilla.org/observer-service;1"]
-                              .getService(SpecialPowers.Ci.nsIObserverService);
-        os.notifyObservers(null, "memory-pressure", "low-memory");
-        ok(true, 'Successfully notified observers.');
-      });
-    });
-
-    // This test isn't the only possible source of a low-memory notification; the
-    // browser can fire one whenever it likes.  So it's fine if we lose the
-    // WebGL context before we fire the low-memory notification ourself.
-
-    var p = expectMozbrowserEvent(iframe, 'showmodalprompt').then(function(e) {
-      is(e.detail.message, 'webglcontextlost');
-    });
-
-    iframe.setVisible(false);
-    return p;
-  }).then(finishOnce);
-
-  document.body.appendChild(iframe);
-}
-
-addEventListener('testready', function() {
-  // At the time this test was written, webgl was blocklisted inside child
-  // processes on desktop Linux.  The issue is that we spawn a child process to
-  // read driver info, but we only did this on the main prrocess.  Child
-  // processes never read the driver info themselves, nor do they get it from
-  // their parent, so they refuse to start up WebGL.
-  //
-  // This isn't a problem on B2G because we force WebGL on there.  But it
-  // obviously makes this test difficult.  bjacob says forcing WebGL on here
-  // shouldn't hurt things, and anyway this setting mirrors what we do on B2G,
-  // which is what we're trying to test!
-  SpecialPowers.pushPrefEnv({set: [["webgl.force-enabled", true]]},
-                            runTest);
-});
-
-</script>
-</body>
-</html>
deleted file mode 100644
--- a/dom/browser-element/mochitest/test_browserElement_inproc_SetVisible.html
+++ /dev/null
@@ -1,19 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=702880
--->
- <head>
-  <title>Test for Bug 702880</title>
-  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="application/javascript" src="browserElementTestHelpers.js"></script>
-  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=753595">Mozilla Bug 702880</a>
-
-<script type="application/javascript" src='browserElement_SetVisible.js'>
-</script>
-
-</body>
-</html>
deleted file mode 100644
--- a/dom/browser-element/mochitest/test_browserElement_inproc_SetVisibleFrames.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <title>Test for Bug 762939</title>
-  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="application/javascript" src="browserElementTestHelpers.js"></script>
-  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<script type="application/javascript" src="browserElement_SetVisibleFrames.js">
-</script>
-</body>
-</html>
deleted file mode 100644
--- a/dom/browser-element/mochitest/test_browserElement_inproc_SetVisibleFrames2.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <title>Test for Bug 762939</title>
-  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="application/javascript" src="browserElementTestHelpers.js"></script>
-  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<script type="application/javascript" src="browserElement_SetVisibleFrames2.js">
-</script>
-</body>
-</html>
deleted file mode 100644
--- a/dom/browser-element/mochitest/test_browserElement_inproc_VisibilityChange.html
+++ /dev/null
@@ -1,19 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=868816
--->
-<head>
-  <title>Test for Bug 868816</title>
-  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="application/javascript" src="browserElementTestHelpers.js"></script>
-  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=868816">Mozilla Bug 868816</a>
-
-<script type="application/javascript" src='browserElement_VisibilityChange.js'>
-</script>
-
-</body>
-</html>
deleted file mode 100644
--- a/dom/browser-element/mochitest/test_browserElement_oop_SetVisible.html
+++ /dev/null
@@ -1,19 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=702880
--->
- <head>
-  <title>Test for Bug 702880</title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="application/javascript" src="browserElementTestHelpers.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=753595">Mozilla Bug 702880</a>
-
-<script type="application/javascript" src='browserElement_SetVisible.js'>
-</script>
-
-</body>
-</html>
deleted file mode 100644
--- a/dom/browser-element/mochitest/test_browserElement_oop_SetVisibleFrames.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <title>Test for Bug 762939</title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="application/javascript" src="browserElementTestHelpers.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<script type="application/javascript" src="browserElement_SetVisibleFrames.js">
-</script>
-</body>
-</html>
\ No newline at end of file
deleted file mode 100644
--- a/dom/browser-element/mochitest/test_browserElement_oop_SetVisibleFrames2.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <title>Test for Bug 762939</title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="application/javascript" src="browserElementTestHelpers.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<script type="application/javascript" src="browserElement_SetVisibleFrames2.js">
-</script>
-</body>
-</html>
\ No newline at end of file
deleted file mode 100644
--- a/dom/browser-element/mochitest/test_browserElement_oop_VisibilityChange.html
+++ /dev/null
@@ -1,19 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=868816
--->
-<head>
-  <title>Test for Bug 868816</title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="application/javascript" src="browserElementTestHelpers.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=868816">Mozilla Bug 868816</a>
-
-<script type="application/javascript" src='browserElement_VisibilityChange.js'>
-</script>
-
-</body>
-</html>
--- a/dom/browser-element/moz.build
+++ b/dom/browser-element/moz.build
@@ -42,15 +42,13 @@ LOCAL_INCLUDES += [
     '/dom/',
     '/dom/base',
     '/dom/ipc',
 ]
 
 MOCHITEST_MANIFESTS += [
     'mochitest/mochitest-oop.ini',
     'mochitest/mochitest.ini',
-    'mochitest/priority/mochitest.ini',
 ]
 
 MOCHITEST_CHROME_MANIFESTS += [
     'mochitest/chrome.ini',
-    'mochitest/priority/chrome.ini',
 ]
--- a/dom/browser-element/nsIBrowserElementAPI.idl
+++ b/dom/browser-element/nsIBrowserElementAPI.idl
@@ -37,21 +37,16 @@ interface nsIBrowserElementAPI : nsISupp
 
   /**
    * Notify frame scripts that support the API to destroy.
    */
   void destroyFrameScripts();
 
   void setFrameLoader(in nsIFrameLoader frameLoader);
 
-  void setVisible(in boolean visible);
-  nsIDOMDOMRequest getVisible();
-  void setActive(in boolean active);
-  boolean getActive();
-
   void sendMouseEvent(in DOMString type,
                       in uint32_t x,
                       in uint32_t y,
                       in uint32_t button,
                       in uint32_t clickCount,
                       in uint32_t mifiers);
   void sendTouchEvent(in DOMString aType,
                       [const, array, size_is(count)] in uint32_t aIdentifiers,
--- a/dom/html/HTMLOptionElement.cpp
+++ b/dom/html/HTMLOptionElement.cpp
@@ -146,21 +146,16 @@ HTMLOptionElement::Index()
   int32_t index = defaultIndex;
   MOZ_ALWAYS_SUCCEEDS(options->GetOptionIndex(this, 0, true, &index));
   return index;
 }
 
 bool
 HTMLOptionElement::Selected() const
 {
-  // If we haven't been explictly selected or deselected, use our default value
-  if (!mSelectedChanged) {
-    return DefaultSelected();
-  }
-
   return mIsSelected;
 }
 
 bool
 HTMLOptionElement::DefaultSelected() const
 {
   return HasAttr(kNameSpaceID_None, nsGkAtoms::selected);
 }
@@ -188,42 +183,35 @@ HTMLOptionElement::BeforeSetAttr(int32_t
                                                     aValue, aNotify);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (aNamespaceID != kNameSpaceID_None || aName != nsGkAtoms::selected ||
       mSelectedChanged) {
     return NS_OK;
   }
 
-  bool defaultSelected = aValue;
-  // First make sure we actually set our mIsSelected state to reflect our new
-  // defaultSelected state.  If that turns out to be wrong,
-  // SetOptionsSelectedByIndex will fix it up.  But otherwise we can end up in a
-  // situation where mIsSelected is still false, but mSelectedChanged becomes
-  // true (later in this method, when we compare mIsSelected to
-  // defaultSelected), and then we start returning false for Selected() even
-  // though we're actually selected.
-  mIsSelected = defaultSelected;
-
   // We just changed out selected state (since we look at the "selected"
   // attribute when mSelectedChanged is false).  Let's tell our select about
   // it.
   HTMLSelectElement* selectInt = GetSelect();
   if (!selectInt) {
+    // If option is a child of select, SetOptionsSelectedByIndex will set
+    // mIsSelected if needed.
+    mIsSelected = aValue;
     return NS_OK;
   }
 
   NS_ASSERTION(!mSelectedChanged, "Shouldn't be here");
 
   bool inSetDefaultSelected = mIsInSetDefaultSelected;
   mIsInSetDefaultSelected = true;
 
   int32_t index = Index();
   uint32_t mask = HTMLSelectElement::SET_DISABLED;
-  if (defaultSelected) {
+  if (aValue) {
     mask |= HTMLSelectElement::IS_SELECTED;
   }
 
   if (aNotify) {
     mask |= HTMLSelectElement::NOTIFY;
   }
 
   // This can end up calling SetSelectedInternal if our selected state needs to
@@ -231,18 +219,18 @@ HTMLOptionElement::BeforeSetAttr(int32_t
   // SetOptionsSelectedByIndex that might depend on it working don't get
   // confused.
   selectInt->SetOptionsSelectedByIndex(index, index, mask);
 
   // Now reset our members; when we finish the attr set we'll end up with the
   // rigt selected state.
   mIsInSetDefaultSelected = inSetDefaultSelected;
   // mIsSelected might have been changed by SetOptionsSelectedByIndex.  Possibly
-  // more than once; make sure our mSelectedChanged state is set correctly.
-  mSelectedChanged = mIsSelected != defaultSelected;
+  // more than once; make sure our mSelectedChanged state is set back correctly.
+  mSelectedChanged = false;
 
   return NS_OK;
 }
 
 nsresult
 HTMLOptionElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
                                 const nsAttrValue* aValue,
                                 const nsAttrValue* aOldValue, bool aNotify)
@@ -421,23 +409,23 @@ HTMLOptionElement::Option(const GlobalOb
     // aNotify == false.
     aError = option->SetAttr(kNameSpaceID_None, nsGkAtoms::selected,
                              EmptyString(), false);
     if (aError.Failed()) {
       return nullptr;
     }
   }
 
-  if (aSelected) {
-    option->SetSelected(true, aError);
-    if (aError.Failed()) {
-      return nullptr;
-    }
+  option->SetSelected(aSelected, aError);
+  if (aError.Failed()) {
+    return nullptr;
   }
 
+  option->SetSelectedChanged(false);
+
   return option.forget();
 }
 
 nsresult
 HTMLOptionElement::CopyInnerTo(Element* aDest, bool aPreallocateChildren)
 {
   nsresult rv = nsGenericHTMLElement::CopyInnerTo(aDest, aPreallocateChildren);
   NS_ENSURE_SUCCESS(rv, rv);
--- a/dom/html/nsBrowserElement.cpp
+++ b/dom/html/nsBrowserElement.cpp
@@ -62,72 +62,16 @@ nsBrowserElement::DestroyBrowserElementF
 {
   if (!mBrowserElementAPI) {
     return;
   }
   mBrowserElementAPI->DestroyFrameScripts();
 }
 
 void
-nsBrowserElement::SetVisible(bool aVisible, ErrorResult& aRv)
-{
-  NS_ENSURE_TRUE_VOID(IsBrowserElementOrThrow(aRv));
-
-  nsresult rv = mBrowserElementAPI->SetVisible(aVisible);
-
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
-  }
-}
-
-already_AddRefed<DOMRequest>
-nsBrowserElement::GetVisible(ErrorResult& aRv)
-{
-  NS_ENSURE_TRUE(IsBrowserElementOrThrow(aRv), nullptr);
-
-  nsCOMPtr<nsIDOMDOMRequest> req;
-  nsresult rv = mBrowserElementAPI->GetVisible(getter_AddRefs(req));
-
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
-    return nullptr;
-  }
-
-  return req.forget().downcast<DOMRequest>();
-}
-
-void
-nsBrowserElement::SetActive(bool aVisible, ErrorResult& aRv)
-{
-  NS_ENSURE_TRUE_VOID(IsBrowserElementOrThrow(aRv));
-
-  nsresult rv = mBrowserElementAPI->SetActive(aVisible);
-
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
-  }
-}
-
-bool
-nsBrowserElement::GetActive(ErrorResult& aRv)
-{
-  NS_ENSURE_TRUE(IsBrowserElementOrThrow(aRv), false);
-
-  bool isActive;
-  nsresult rv = mBrowserElementAPI->GetActive(&isActive);
-
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
-    return false;
-  }
-
-  return isActive;
-}
-
-void
 nsBrowserElement::SendMouseEvent(const nsAString& aType,
                                  uint32_t aX,
                                  uint32_t aY,
                                  uint32_t aButton,
                                  uint32_t aClickCount,
                                  uint32_t aModifiers,
                                  ErrorResult& aRv)
 {
--- a/dom/html/nsBrowserElement.h
+++ b/dom/html/nsBrowserElement.h
@@ -31,21 +31,16 @@ class ErrorResult;
  * A helper class for browser-element frames
  */
 class nsBrowserElement
 {
 public:
   nsBrowserElement() {}
   virtual ~nsBrowserElement() {}
 
-  void SetVisible(bool aVisible, ErrorResult& aRv);
-  already_AddRefed<dom::DOMRequest> GetVisible(ErrorResult& aRv);
-  void SetActive(bool aActive, ErrorResult& aRv);
-  bool GetActive(ErrorResult& aRv);
-
   void SendMouseEvent(const nsAString& aType,
                       uint32_t aX,
                       uint32_t aY,
                       uint32_t aButton,
                       uint32_t aClickCount,
                       uint32_t aModifiers,
                       ErrorResult& aRv);
   void SendTouchEvent(const nsAString& aType,
--- a/dom/html/test/test_bug596511.html
+++ b/dom/html/test/test_bug596511.html
@@ -181,17 +181,17 @@ function checkInvalidWhenValueMissing(el
    * Everything should be the same except moving the selection.
    */
   select.multiple = false;
   select.size = 4;
   checkSufferingFromBeingMissing(select);
 
   // Setting defaultSelected to true should not make the option selected
   select.add(new Option("", "", true), null);
-  checkSufferingFromBeingMissing(select, true);
+  checkSufferingFromBeingMissing(select);
   select.remove(0);
 
   select.add(new Option("", "", true, true), null);
   checkNotSufferingFromBeingMissing(select);
 
   select.add(new Option("foo", "foo"), null);
   select.remove(0);
   checkSufferingFromBeingMissing(select);
@@ -205,23 +205,23 @@ function checkInvalidWhenValueMissing(el
    * Multiple, any size.
    * We can select more than one element and at least needs a value.
    */
   select.multiple = true;
   select.size = 4;
   checkSufferingFromBeingMissing(select);
 
   select.add(new Option("", "", true), null);
-  checkSufferingFromBeingMissing(select, true);
+  checkSufferingFromBeingMissing(select);
 
   select.add(new Option("", "", true), null);
-  checkSufferingFromBeingMissing(select, true);
+  checkSufferingFromBeingMissing(select);
 
   select.add(new Option("foo"), null);
-  checkSufferingFromBeingMissing(select, true);
+  checkSufferingFromBeingMissing(select);
 
   select.options[2].selected = true;
   checkNotSufferingFromBeingMissing(select);
 }
 
 var select = document.createElement("select");
 var content = document.getElementById('content');
 content.appendChild(select);
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -1383,40 +1383,16 @@ NS_IMETHODIMP
 RemoteWindowContext::OpenURI(nsIURI* aURI)
 {
   mTabParent->LoadURL(aURI);
   return NS_OK;
 }
 
 } // namespace
 
-bool
-ContentParent::SetPriorityAndCheckIsAlive(ProcessPriority aPriority)
-{
-  ProcessPriorityManager::SetProcessPriority(this, aPriority);
-
-  // Now that we've set this process's priority, check whether the process is
-  // still alive.  Hopefully we've set the priority to FOREGROUND*, so the
-  // process won't unexpectedly crash after this point!
-  //
-  // Bug 943174: use waitid() with WNOWAIT so that, if the process
-  // did exit, we won't consume its zombie and confuse the
-  // GeckoChildProcessHost dtor.
-#ifdef MOZ_WIDGET_GONK
-  siginfo_t info;
-  info.si_pid = 0;
-  if (waitid(P_PID, Pid(), &info, WNOWAIT | WNOHANG | WEXITED) == 0
-    && info.si_pid != 0) {
-    return false;
-  }
-#endif
-
-  return true;
-}
-
 void
 ContentParent::ShutDownProcess(ShutDownMethod aMethod)
 {
   if (mScriptableHelper) {
     static_cast<ScriptableCPInfo*>(mScriptableHelper.get())->ProcessDied();
     mScriptableHelper = nullptr;
   }
 
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -726,22 +726,16 @@ private:
 
   void Init();
 
   // Some information could be sent to content very early, it
   // should be send from this function. This function should only be
   // called after the process has been transformed to browser.
   void ForwardKnownInfo();
 
-  // Set the child process's priority and then check whether the child is
-  // still alive.  Returns true if the process is still alive, and false
-  // otherwise.  If you pass a FOREGROUND* priority here, it's (hopefully)
-  // unlikely that the process will be killed after this point.
-  bool SetPriorityAndCheckIsAlive(hal::ProcessPriority aPriority);
-
   /**
    * Decide whether the process should be kept alive even when it would normally
    * be shut down, for example when all its tabs are closed.
    */
   bool ShouldKeepProcessAlive() const;
 
   /**
    * Mark this ContentParent as "troubled". This means that it is still alive,
--- a/dom/ipc/ProcessPriorityManager.cpp
+++ b/dom/ipc/ProcessPriorityManager.cpp
@@ -131,21 +131,16 @@ public:
   /**
    * If a magic testing-only pref is set, notify the observer service on the
    * given topic with the given data.  This is used for testing
    */
   void FireTestOnlyObserverNotification(const char* aTopic,
                                         const nsACString& aData = EmptyCString());
 
   /**
-   * Does one of the child processes have priority FOREGROUND_HIGH?
-   */
-  bool ChildProcessHasHighPriority();
-
-  /**
    * This must be called by a ParticularProcessPriorityManager when it changes
    * its priority.
    */
   void NotifyProcessPriorityChanged(
     ParticularProcessPriorityManager* aParticularManager,
     hal::ProcessPriority aOldPriority);
 
   /**
@@ -202,17 +197,16 @@ class ProcessPriorityManagerChild final
 public:
   static void StaticInit();
   static ProcessPriorityManagerChild* Singleton();
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSIOBSERVER
 
   bool CurrentProcessIsForeground();
-  bool CurrentProcessIsHighPriority();
 
 private:
   static StaticRefPtr<ProcessPriorityManagerChild> sSingleton;
 
   ProcessPriorityManagerChild();
   ~ProcessPriorityManagerChild() {}
   DISALLOW_EVIL_CONSTRUCTORS(ProcessPriorityManagerChild);
 
@@ -252,21 +246,18 @@ public:
    * returns an empty string.
    *
    * The reference returned here is guaranteed to be live until the next call
    * to NameWithComma() or until the ParticularProcessPriorityManager is
    * destroyed, whichever comes first.
    */
   const nsAutoCString& NameWithComma();
 
-  bool IsExpectingSystemMessage();
-
   void OnRemoteBrowserFrameShown(nsISupports* aSubject);
   void OnTabParentDestroyed(nsISupports* aSubject);
-  void OnFrameloaderVisibleChanged(nsISupports* aSubject);
   void OnActivityOpened(const char16_t* aData);
   void OnActivityClosed(const char16_t* aData);
 
   ProcessPriority CurrentPriority();
   ProcessPriority ComputePriority();
 
   enum TimeoutPref {
     BACKGROUND_PERCEIVABLE_GRACE_PERIOD,
@@ -511,22 +502,16 @@ ProcessPriorityManagerImpl::ObserveConte
     pppm->ShutDown();
 
     mParticularManagers.Remove(childID);
 
     mHighPriorityChildIDs.RemoveEntry(childID);
   }
 }
 
-bool
-ProcessPriorityManagerImpl::ChildProcessHasHighPriority( void )
-{
-  return mHighPriorityChildIDs.Count() > 0;
-}
-
 void
 ProcessPriorityManagerImpl::NotifyProcessPriorityChanged(
   ParticularProcessPriorityManager* aParticularManager,
   ProcessPriority aOldPriority)
 {
   ProcessPriority newPriority = aParticularManager->CurrentPriority();
 
   if (newPriority >= PROCESS_PRIORITY_FOREGROUND_HIGH &&
@@ -587,17 +572,16 @@ void
 ParticularProcessPriorityManager::Init()
 {
   RegisterWakeLockObserver(this);
 
   nsCOMPtr<nsIObserverService> os = services::GetObserverService();
   if (os) {
     os->AddObserver(this, "remote-browser-shown", /* ownsWeak */ true);
     os->AddObserver(this, "ipc:browser-destroyed", /* ownsWeak */ true);
-    os->AddObserver(this, "frameloader-visible-changed", /* ownsWeak */ true);
     os->AddObserver(this, "activity-opened", /* ownsWeak */ true);
     os->AddObserver(this, "activity-closed", /* ownsWeak */ true);
   }
 
   // This process may already hold the CPU lock; for example, our parent may
   // have acquired it on our behalf.
   WakeLockInformation info1, info2;
   GetWakeLockInfo(NS_LITERAL_STRING("cpu"), &info1);
@@ -661,18 +645,16 @@ ParticularProcessPriorityManager::Observ
   }
 
   nsDependentCString topic(aTopic);
 
   if (topic.EqualsLiteral("remote-browser-shown")) {
     OnRemoteBrowserFrameShown(aSubject);
   } else if (topic.EqualsLiteral("ipc:browser-destroyed")) {
     OnTabParentDestroyed(aSubject);
-  } else if (topic.EqualsLiteral("frameloader-visible-changed")) {
-    OnFrameloaderVisibleChanged(aSubject);
   } else if (topic.EqualsLiteral("activity-opened")) {
     OnActivityOpened(aData);
   } else if (topic.EqualsLiteral("activity-closed")) {
     OnActivityClosed(aData);
   } else {
     MOZ_ASSERT(false);
   }
 
@@ -751,48 +733,16 @@ ParticularProcessPriorityManager::OnTabP
   if (TabParent::GetFrom(tp)->Manager() != mContentParent) {
     return;
   }
 
   ResetPriority();
 }
 
 void
-ParticularProcessPriorityManager::OnFrameloaderVisibleChanged(nsISupports* aSubject)
-{
-  nsCOMPtr<nsIFrameLoader> fl = do_QueryInterface(aSubject);
-  NS_ENSURE_TRUE_VOID(fl);
-
-  TabParent* tp = TabParent::GetFrom(fl);
-  if (!tp) {
-    return;
-  }
-
-  MOZ_ASSERT(XRE_IsParentProcess());
-  if (tp->Manager() != mContentParent) {
-    return;
-  }
-
-  // Most of the time when something changes in a process we call
-  // ResetPriority(), giving a grace period before downgrading its priority.
-  // But notice that here don't give a grace period: We call ResetPriorityNow()
-  // instead.
-  //
-  // We do this because we're reacting here to a setVisibility() call, which is
-  // an explicit signal from the process embedder that we should re-prioritize
-  // a process.  If we gave a grace period in response to setVisibility()
-  // calls, it would be impossible for the embedder to explicitly prioritize
-  // processes and prevent e.g. the case where we switch which process is in
-  // the foreground and, during the old fg processs's grace period, it OOMs the
-  // new fg process.
-
-  ResetPriorityNow();
-}
-
-void
 ParticularProcessPriorityManager::OnActivityOpened(const char16_t* aData)
 {
   uint64_t childID = nsCRT::atoll(NS_ConvertUTF16toUTF8(aData).get());
 
   if (ChildID() == childID) {
     LOGP("Marking as activity opener");
     mIsActivityOpener = true;
     ResetPriority();
@@ -869,57 +819,29 @@ NS_IMETHODIMP
 ParticularProcessPriorityManager::Notify(nsITimer* aTimer)
 {
   LOGP("Reset priority timer callback; about to ResetPriorityNow.");
   ResetPriorityNow();
   mResetPriorityTimer = nullptr;
   return NS_OK;
 }
 
-bool
-ParticularProcessPriorityManager::IsExpectingSystemMessage()
-{
-  const ManagedContainer<PBrowserParent>& browsers =
-    mContentParent->ManagedPBrowserParent();
-  for (auto iter = browsers.ConstIter(); !iter.Done(); iter.Next()) {
-    TabParent* tp = TabParent::GetFrom(iter.Get()->GetKey());
-    nsCOMPtr<nsIMozBrowserFrame> bf = do_QueryInterface(tp->GetOwnerElement());
-    if (!bf) {
-      continue;
-    }
-  }
-
-  return false;
-}
-
 ProcessPriority
 ParticularProcessPriorityManager::CurrentPriority()
 {
   return mPriority;
 }
 
 ProcessPriority
 ParticularProcessPriorityManager::ComputePriority()
 {
-  bool isVisible = false;
-  const ManagedContainer<PBrowserParent>& browsers =
-    mContentParent->ManagedPBrowserParent();
-  for (auto iter = browsers.ConstIter(); !iter.Done(); iter.Next()) {
-    if (TabParent::GetFrom(iter.Get()->GetKey())->IsVisible()) {
-      isVisible = true;
-      break;
-    }
-  }
+  // TODO...
+  return PROCESS_PRIORITY_FOREGROUND;
 
-  if (isVisible) {
-    return PROCESS_PRIORITY_FOREGROUND;
-  }
-
-  if ((mHoldsCPUWakeLock || mHoldsHighPriorityWakeLock) &&
-      IsExpectingSystemMessage()) {
+  if (mHoldsCPUWakeLock || mHoldsHighPriorityWakeLock) {
     return PROCESS_PRIORITY_BACKGROUND_PERCEIVABLE;
   }
 
   return mIsActivityOpener ? PROCESS_PRIORITY_BACKGROUND_PERCEIVABLE
                            : PROCESS_PRIORITY_BACKGROUND;
 }
 
 void
@@ -1050,18 +972,17 @@ ProcessPriorityManagerChild::StaticInit(
 
 /* static */ ProcessPriorityManagerChild*
 ProcessPriorityManagerChild::Singleton()
 {
   StaticInit();
   return sSingleton;
 }
 
-NS_IMPL_ISUPPORTS(ProcessPriorityManagerChild,
-                  nsIObserver)
+NS_IMPL_ISUPPORTS(ProcessPriorityManagerChild, nsIObserver)
 
 ProcessPriorityManagerChild::ProcessPriorityManagerChild()
 {
   if (XRE_IsParentProcess()) {
     mCachedPriority = PROCESS_PRIORITY_MASTER;
   } else {
     mCachedPriority = PROCESS_PRIORITY_UNKNOWN;
   }
@@ -1075,20 +996,19 @@ ProcessPriorityManagerChild::Init()
   if (!XRE_IsParentProcess()) {
     nsCOMPtr<nsIObserverService> os = services::GetObserverService();
     NS_ENSURE_TRUE_VOID(os);
     os->AddObserver(this, "ipc:process-priority-changed", /* weak = */ false);
   }
 }
 
 NS_IMETHODIMP
-ProcessPriorityManagerChild::Observe(
-  nsISupports* aSubject,
-  const char* aTopic,
-  const char16_t* aData)
+ProcessPriorityManagerChild::Observe(nsISupports* aSubject,
+                                     const char* aTopic,
+                                     const char16_t* aData)
 {
   MOZ_ASSERT(!strcmp(aTopic, "ipc:process-priority-changed"));
 
   nsCOMPtr<nsIPropertyBag2> props = do_QueryInterface(aSubject);
   NS_ENSURE_TRUE(props, NS_OK);
 
   int32_t priority = static_cast<int32_t>(PROCESS_PRIORITY_UNKNOWN);
   props->GetPropertyAsInt32(NS_LITERAL_STRING("priority"), &priority);
@@ -1101,23 +1021,16 @@ ProcessPriorityManagerChild::Observe(
 
 bool
 ProcessPriorityManagerChild::CurrentProcessIsForeground()
 {
   return mCachedPriority == PROCESS_PRIORITY_UNKNOWN ||
          mCachedPriority >= PROCESS_PRIORITY_FOREGROUND;
 }
 
-bool
-ProcessPriorityManagerChild::CurrentProcessIsHighPriority()
-{
-  return mCachedPriority == PROCESS_PRIORITY_UNKNOWN ||
-         mCachedPriority >= PROCESS_PRIORITY_FOREGROUND_HIGH;
-}
-
 } // namespace
 
 namespace mozilla {
 
 /* static */ void
 ProcessPriorityManager::Init()
 {
   ProcessPriorityManagerImpl::StaticInit();
@@ -1140,23 +1053,9 @@ ProcessPriorityManager::SetProcessPriori
 
 /* static */ bool
 ProcessPriorityManager::CurrentProcessIsForeground()
 {
   return ProcessPriorityManagerChild::Singleton()->
     CurrentProcessIsForeground();
 }
 
-/* static */ bool
-ProcessPriorityManager::AnyProcessHasHighPriority()
-{
-  ProcessPriorityManagerImpl* singleton =
-    ProcessPriorityManagerImpl::GetSingleton();
-
-  if (singleton) {
-    return singleton->ChildProcessHasHighPriority();
-  } else {
-    return ProcessPriorityManagerChild::Singleton()->
-      CurrentProcessIsHighPriority();
-  }
-}
-
 } // namespace mozilla
--- a/dom/ipc/ProcessPriorityManager.h
+++ b/dom/ipc/ProcessPriorityManager.h
@@ -63,22 +63,16 @@ public:
    * Returns true iff this process's priority is FOREGROUND*.
    *
    * Note that because process priorities are set in the main process, it's
    * possible for this method to return a stale value.  So be careful about
    * what you use this for.
    */
   static bool CurrentProcessIsForeground();
 
-  /**
-   * Returns true if one or more processes with FOREGROUND_HIGH priority are
-   * present, false otherwise.
-   */
-  static bool AnyProcessHasHighPriority();
-
 private:
   ProcessPriorityManager();
   DISALLOW_EVIL_CONSTRUCTORS(ProcessPriorityManager);
 };
 
 } // namespace mozilla
 
 #endif
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -315,27 +315,16 @@ TabParent::RemoveWindowListeners()
     nsCOMPtr<EventTarget> eventTarget = window->GetTopWindowRoot();
     if (eventTarget) {
       eventTarget->RemoveEventListener(NS_LITERAL_STRING("MozUpdateWindowPos"),
                                        this, false);
     }
   }
 }
 
-bool
-TabParent::IsVisible() const
-{
-  RefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
-  if (!frameLoader) {
-    return false;
-  }
-
-  return frameLoader->GetVisible();
-}
-
 void
 TabParent::DestroyInternal()
 {
   IMEStateManager::OnTabParentDestroying(this);
 
   RemoveWindowListeners();
 
 #ifdef ACCESSIBILITY
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -113,24 +113,16 @@ public:
 
   Element* GetOwnerElement() const { return mFrameElement; }
   already_AddRefed<nsPIDOMWindowOuter> GetParentWindowOuter();
 
   void SetOwnerElement(Element* aElement);
 
   void CacheFrameLoader(nsFrameLoader* aFrameLoader);
 
-  /**
-   * Returns true iff this TabParent's nsIFrameLoader is visible.
-   *
-   * The frameloader's visibility can be independent of e.g. its docshell's
-   * visibility.
-   */
-  bool IsVisible() const;
-
   nsIBrowserDOMWindow *GetBrowserDOMWindow() const { return mBrowserDOMWindow; }
 
   void SetBrowserDOMWindow(nsIBrowserDOMWindow* aBrowserDOMWindow)
   {
     mBrowserDOMWindow = aBrowserDOMWindow;
   }
 
   void SetHasContentOpener(bool aHasContentOpener);
--- a/dom/url/URL.cpp
+++ b/dom/url/URL.cpp
@@ -1,1647 +1,26 @@
 /* -*- 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 "URL.h"
+#include "URLMainThread.h"
+#include "URLWorker.h"
 
-#include "DOMMediaStream.h"
-#include "mozilla/dom/File.h"
-#include "mozilla/dom/MediaSource.h"
+#include "MainThreadUtils.h"
 #include "mozilla/dom/URLBinding.h"
-#include "mozilla/ipc/BackgroundChild.h"
-#include "nsContentUtils.h"
-#include "nsEscape.h"
-#include "nsHostObjectProtocolHandler.h"
-#include "nsIIOService.h"
-#include "nsIURL.h"
-#include "nsNetCID.h"
-#include "nsNetUtil.h"
-#include "nsServiceManagerUtils.h"
-#include "WorkerPrivate.h"
-#include "WorkerRunnable.h"
-#include "WorkerScope.h"
+#include "mozilla/dom/BindingUtils.h"
+#include "nsIDocument.h"
 
 namespace mozilla {
 namespace dom {
 
-///////////////////////////////////////////////////////////////////////////////
-// URL for main-thread
-///////////////////////////////////////////////////////////////////////////////
-
-namespace {
-
-template<typename T>
-void
-CreateObjectURLInternal(const GlobalObject& aGlobal, T aObject,
-                        nsAString& aResult, ErrorResult& aRv)
-{
-  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
-  if (NS_WARN_IF(!global)) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return;
-  }
-
-  nsCOMPtr<nsIPrincipal> principal =
-    nsContentUtils::ObjectPrincipal(aGlobal.Get());
-
-  nsAutoCString url;
-  aRv = nsHostObjectProtocolHandler::AddDataEntry(aObject, principal, url);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  global->RegisterHostObjectURI(url);
-  CopyASCIItoUTF16(url, aResult);
-}
-
-// The URL implementation for the main-thread
-class URLMainThread final : public URL
-{
-public:
-  static already_AddRefed<URLMainThread>
-  Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-              URL& aBase, ErrorResult& aRv);
-
-  static already_AddRefed<URLMainThread>
-  Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-              const Optional<nsAString>& aBase, ErrorResult& aRv);
-
-  static already_AddRefed<URLMainThread>
-  Constructor(nsISupports* aParent, const nsAString& aURL,
-              const nsAString& aBase, ErrorResult& aRv);
-
-  static already_AddRefed<URLMainThread>
-  Constructor(nsISupports* aParent, const nsAString& aURL, nsIURI* aBase,
-              ErrorResult& aRv);
-
-  static void
-  CreateObjectURL(const GlobalObject& aGlobal, Blob& aBlob,
-                  nsAString& aResult, ErrorResult& aRv)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-    CreateObjectURLInternal(aGlobal, aBlob.Impl(), aResult, aRv);
-  }
-
-  static void
-  CreateObjectURL(const GlobalObject& aGlobal, DOMMediaStream& aStream,
-                  nsAString& aResult, ErrorResult& aRv)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-    CreateObjectURLInternal(aGlobal, &aStream, aResult, aRv);
-  }
-
-  static void
-  CreateObjectURL(const GlobalObject& aGlobal, MediaSource& aSource,
-                  nsAString& aResult, ErrorResult& aRv);
-
-  static void
-  RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aURL,
-                  ErrorResult& aRv);
-
-  static bool
-  IsValidURL(const GlobalObject& aGlobal, const nsAString& aURL,
-             ErrorResult& aRv);
-
-  URLMainThread(nsISupports* aParent, already_AddRefed<nsIURI> aURI)
-    : URL(aParent)
-    , mURI(aURI)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-  }
-
-  virtual void
-  GetHref(nsAString& aHref, ErrorResult& aRv) const override;
-
-  virtual void
-  SetHref(const nsAString& aHref, ErrorResult& aRv) override;
-
-  virtual void
-  GetOrigin(nsAString& aOrigin, ErrorResult& aRv) const override;
-
-  virtual void
-  GetProtocol(nsAString& aProtocol, ErrorResult& aRv) const override;
-
-  virtual void
-  SetProtocol(const nsAString& aProtocol, ErrorResult& aRv) override;
-
-  virtual void
-  GetUsername(nsAString& aUsername, ErrorResult& aRv) const override;
-
-  virtual void
-  SetUsername(const nsAString& aUsername, ErrorResult& aRv) override;
-
-  virtual void
-  GetPassword(nsAString& aPassword, ErrorResult& aRv) const override;
-
-  virtual void
-  SetPassword(const nsAString& aPassword, ErrorResult& aRv) override;
-
-  virtual void
-  GetHost(nsAString& aHost, ErrorResult& aRv) const override;
-
-  virtual void
-  SetHost(const nsAString& aHost, ErrorResult& aRv) override;
-
-  virtual void
-  GetHostname(nsAString& aHostname, ErrorResult& aRv) const override;
-
-  virtual void
-  SetHostname(const nsAString& aHostname, ErrorResult& aRv) override;
-
-  virtual void
-  GetPort(nsAString& aPort, ErrorResult& aRv) const override;
-
-  virtual void
-  SetPort(const nsAString& aPort, ErrorResult& aRv) override;
-
-  virtual void
-  GetPathname(nsAString& aPathname, ErrorResult& aRv) const override;
-
-  virtual void
-  SetPathname(const nsAString& aPathname, ErrorResult& aRv) override;
-
-  virtual void
-  GetSearch(nsAString& aSearch, ErrorResult& aRv) const override;
-
-  virtual void
-  GetHash(nsAString& aHost, ErrorResult& aRv) const override;
-
-  virtual void
-  SetHash(const nsAString& aHash, ErrorResult& aRv) override;
-
-  virtual void UpdateURLSearchParams() override;
-
-  virtual void
-  SetSearchInternal(const nsAString& aSearch, ErrorResult& aRv) override;
-
-  nsIURI*
-  GetURI() const
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-    return mURI;
-  }
-
-private:
-  ~URLMainThread()
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-  }
-
-  nsCOMPtr<nsIURI> mURI;
-};
-
-/* static */ already_AddRefed<URLMainThread>
-URLMainThread::Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-                           URL& aBase, ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  URLMainThread& base = static_cast<URLMainThread&>(aBase);
-  return Constructor(aGlobal.GetAsSupports(), aURL, base.GetURI(), aRv);
-}
-
-/* static */ already_AddRefed<URLMainThread>
-URLMainThread::Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-                           const Optional<nsAString>& aBase, ErrorResult& aRv)
-{
-  if (aBase.WasPassed()) {
-    return Constructor(aGlobal.GetAsSupports(), aURL, aBase.Value(), aRv);
-  }
-
-  return Constructor(aGlobal.GetAsSupports(), aURL, nullptr, aRv);
-}
-
-/* static */ already_AddRefed<URLMainThread>
-URLMainThread::Constructor(nsISupports* aParent, const nsAString& aURL,
-                           const nsAString& aBase, ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  nsCOMPtr<nsIURI> baseUri;
-  nsresult rv = NS_NewURI(getter_AddRefs(baseUri), aBase, nullptr, nullptr,
-                          nsContentUtils::GetIOService());
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    aRv.ThrowTypeError<MSG_INVALID_URL>(aBase);
-    return nullptr;
-  }
-
-  return Constructor(aParent, aURL, baseUri, aRv);
-}
-
-/* static */ already_AddRefed<URLMainThread>
-URLMainThread::Constructor(nsISupports* aParent, const nsAString& aURL,
-                           nsIURI* aBase, ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  nsCOMPtr<nsIURI> uri;
-  nsresult rv = NS_NewURI(getter_AddRefs(uri), aURL, nullptr, aBase,
-                          nsContentUtils::GetIOService());
-  if (NS_FAILED(rv)) {
-    // No need to warn in this case. It's common to use the URL constructor
-    // to determine if a URL is valid and an exception will be propagated.
-    aRv.ThrowTypeError<MSG_INVALID_URL>(aURL);
-    return nullptr;
-  }
-
-  RefPtr<URLMainThread> url = new URLMainThread(aParent, uri.forget());
-  return url.forget();
-}
-
-/* static */ void
-URLMainThread::CreateObjectURL(const GlobalObject& aGlobal,
-                               MediaSource& aSource,
-                               nsAString& aResult, ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  nsCOMPtr<nsIPrincipal> principal =
-    nsContentUtils::ObjectPrincipal(aGlobal.Get());
-
-  nsAutoCString url;
-  aRv = nsHostObjectProtocolHandler::AddDataEntry(&aSource, principal, url);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  nsCOMPtr<nsIRunnable> revocation = NS_NewRunnableFunction(
-    [url] {
-      nsHostObjectProtocolHandler::RemoveDataEntry(url);
-    });
-
-  nsContentUtils::RunInStableState(revocation.forget());
-
-  CopyASCIItoUTF16(url, aResult);
-}
-
-/* static */ void
-URLMainThread::RevokeObjectURL(const GlobalObject& aGlobal,
-                               const nsAString& aURL, ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
-  if (!global) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return;
-  }
-
-  nsIPrincipal* principal = nsContentUtils::ObjectPrincipal(aGlobal.Get());
-
-  NS_LossyConvertUTF16toASCII asciiurl(aURL);
-
-  nsIPrincipal* urlPrincipal =
-    nsHostObjectProtocolHandler::GetDataEntryPrincipal(asciiurl);
-
-  if (urlPrincipal && principal->Subsumes(urlPrincipal)) {
-    global->UnregisterHostObjectURI(asciiurl);
-    nsHostObjectProtocolHandler::RemoveDataEntry(asciiurl);
-  }
-}
-
-/* static */ bool
-URLMainThread::IsValidURL(const GlobalObject& aGlobal, const nsAString& aURL,
-                          ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  NS_LossyConvertUTF16toASCII asciiurl(aURL);
-  return nsHostObjectProtocolHandler::HasDataEntry(asciiurl);
-}
-
-void
-URLMainThread::GetHref(nsAString& aHref, ErrorResult& aRv) const
-{
-  aHref.Truncate();
-
-  nsAutoCString href;
-  nsresult rv = mURI->GetSpec(href);
-  if (NS_SUCCEEDED(rv)) {
-    CopyUTF8toUTF16(href, aHref);
-  }
-}
-
-void
-URLMainThread::SetHref(const nsAString& aHref, ErrorResult& aRv)
-{
-  NS_ConvertUTF16toUTF8 href(aHref);
-
-  nsresult rv;
-  nsCOMPtr<nsIIOService> ioService(do_GetService(NS_IOSERVICE_CONTRACTID, &rv));
-  if (NS_FAILED(rv)) {
-    aRv.Throw(rv);
-    return;
-  }
-
-  nsCOMPtr<nsIURI> uri;
-  rv = ioService->NewURI(href, nullptr, nullptr, getter_AddRefs(uri));
-  if (NS_FAILED(rv)) {
-    aRv.ThrowTypeError<MSG_INVALID_URL>(aHref);
-    return;
-  }
-
-  mURI = uri;
-  UpdateURLSearchParams();
-}
-
-void
-URLMainThread::GetOrigin(nsAString& aOrigin, ErrorResult& aRv) const
-{
-  nsContentUtils::GetUTFOrigin(mURI, aOrigin);
-}
-
-void
-URLMainThread::GetProtocol(nsAString& aProtocol, ErrorResult& aRv) const
-{
-  nsAutoCString protocol;
-  if (NS_SUCCEEDED(mURI->GetScheme(protocol))) {
-    aProtocol.Truncate();
-  }
-
-  CopyASCIItoUTF16(protocol, aProtocol);
-  aProtocol.Append(char16_t(':'));
-}
-
-void
-URLMainThread::SetProtocol(const nsAString& aProtocol, ErrorResult& aRv)
-{
-  nsAString::const_iterator start, end;
-  aProtocol.BeginReading(start);
-  aProtocol.EndReading(end);
-  nsAString::const_iterator iter(start);
-
-  FindCharInReadable(':', iter, end);
-
-  // Changing the protocol of a URL, changes the "nature" of the URI
-  // implementation. In order to do this properly, we have to serialize the
-  // existing URL and reparse it in a new object.
-  nsCOMPtr<nsIURI> clone;
-  nsresult rv = mURI->Clone(getter_AddRefs(clone));
-  if (NS_WARN_IF(NS_FAILED(rv)) || !clone) {
-    return;
-  }
-
-  rv = clone->SetScheme(NS_ConvertUTF16toUTF8(Substring(start, iter)));
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return;
-  }
-
-  nsAutoCString href;
-  rv = clone->GetSpec(href);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return;
-  }
-
-  nsCOMPtr<nsIURI> uri;
-  rv = NS_NewURI(getter_AddRefs(uri), href);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return;
-  }
-
-  mURI = uri;
-}
-
-#define URL_GETTER( value, func ) \
-  value.Truncate();               \
-  nsAutoCString tmp;              \
-  nsresult rv = mURI->func(tmp);  \
-  if (NS_SUCCEEDED(rv)) {         \
-    CopyUTF8toUTF16(tmp, value);  \
-  }
-
-void
-URLMainThread::GetUsername(nsAString& aUsername, ErrorResult& aRv) const
-{
-  URL_GETTER(aUsername, GetUsername);
-}
-
-void
-URLMainThread::SetUsername(const nsAString& aUsername, ErrorResult& aRv)
-{
-  mURI->SetUsername(NS_ConvertUTF16toUTF8(aUsername));
-}
-
-void
-URLMainThread::GetPassword(nsAString& aPassword, ErrorResult& aRv) const
-{
-  URL_GETTER(aPassword, GetPassword);
-}
-
-void
-URLMainThread::SetPassword(const nsAString& aPassword, ErrorResult& aRv)
-{
-  mURI->SetPassword(NS_ConvertUTF16toUTF8(aPassword));
-}
-
-void
-URLMainThread::GetHost(nsAString& aHost, ErrorResult& aRv) const
-{
-  URL_GETTER(aHost, GetHostPort);
-}
-
-void
-URLMainThread::SetHost(const nsAString& aHost, ErrorResult& aRv)
-{
-  mURI->SetHostPort(NS_ConvertUTF16toUTF8(aHost));
-}
-
-void
-URLMainThread::UpdateURLSearchParams()
-{
-  if (!mSearchParams) {
-    return;
-  }
-
-  nsAutoCString search;
-  nsCOMPtr<nsIURL> url(do_QueryInterface(mURI));
-  if (url) {
-    nsresult rv = url->GetQuery(search);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      search.Truncate();
-    }
-  }
-
-  mSearchParams->ParseInput(search);
-}
-
-void
-URLMainThread::GetHostname(nsAString& aHostname, ErrorResult& aRv) const
-{
-  aHostname.Truncate();
-  nsContentUtils::GetHostOrIPv6WithBrackets(mURI, aHostname);
-}
-
-void
-URLMainThread::SetHostname(const nsAString& aHostname, ErrorResult& aRv)
-{
-  // nsStandardURL returns NS_ERROR_UNEXPECTED for an empty hostname
-  // The return code is silently ignored
-  mURI->SetHost(NS_ConvertUTF16toUTF8(aHostname));
-}
-
-void
-URLMainThread::GetPort(nsAString& aPort, ErrorResult& aRv) const
-{
-  aPort.Truncate();
-
-  int32_t port;
-  nsresult rv = mURI->GetPort(&port);
-  if (NS_SUCCEEDED(rv) && port != -1) {
-    nsAutoString portStr;
-    portStr.AppendInt(port, 10);
-    aPort.Assign(portStr);
-  }
-}
-
-void
-URLMainThread::SetPort(const nsAString& aPort, ErrorResult& aRv)
-{
-  nsresult rv;
-  nsAutoString portStr(aPort);
-  int32_t port = -1;
-
-  // nsIURI uses -1 as default value.
-  if (!portStr.IsEmpty()) {
-    port = portStr.ToInteger(&rv);
-    if (NS_FAILED(rv)) {
-      return;
-    }
-  }
-
-  mURI->SetPort(port);
-}
-
-void
-URLMainThread::GetPathname(nsAString& aPathname, ErrorResult& aRv) const
-{
-  aPathname.Truncate();
-
-  // Do not throw!  Not having a valid URI or URL should result in an empty
-  // string.
-
-  nsAutoCString file;
-  nsresult rv = mURI->GetFilePath(file);
-  if (NS_SUCCEEDED(rv)) {
-    CopyUTF8toUTF16(file, aPathname);
-  }
-}
-
-void
-URLMainThread::SetPathname(const nsAString& aPathname, ErrorResult& aRv)
-{
-  // Do not throw!
-
-  mURI->SetFilePath(NS_ConvertUTF16toUTF8(aPathname));
-}
-
-void
-URLMainThread::GetSearch(nsAString& aSearch, ErrorResult& aRv) const
-{
-  aSearch.Truncate();
-
-  // Do not throw!  Not having a valid URI or URL should result in an empty
-  // string.
-
-  nsAutoCString search;
-  nsresult rv;
-
-  rv = mURI->GetQuery(search);
-  if (NS_SUCCEEDED(rv) && !search.IsEmpty()) {
-    CopyUTF8toUTF16(NS_LITERAL_CSTRING("?") + search, aSearch);
-  }
-}
-
-void
-URLMainThread::GetHash(nsAString& aHash, ErrorResult& aRv) const
-{
-  aHash.Truncate();
-
-  nsAutoCString ref;
-  nsresult rv = mURI->GetRef(ref);
-  if (NS_SUCCEEDED(rv) && !ref.IsEmpty()) {
-    aHash.Assign(char16_t('#'));
-    AppendUTF8toUTF16(ref, aHash);
-  }
-}
-
-void
-URLMainThread::SetHash(const nsAString& aHash, ErrorResult& aRv)
-{
-  mURI->SetRef(NS_ConvertUTF16toUTF8(aHash));
-}
-
-void
-URLMainThread::SetSearchInternal(const nsAString& aSearch, ErrorResult& aRv)
-{
-  // Ignore failures to be compatible with NS4.
-
-  mURI->SetQuery(NS_ConvertUTF16toUTF8(aSearch));
-}
-
-} // anonymous namespace
-
-///////////////////////////////////////////////////////////////////////////////
-// URL for Workers
-///////////////////////////////////////////////////////////////////////////////
-
-namespace {
-
-using namespace workers;
-
-// Proxy class to forward all the requests to a URLMainThread object.
-class URLProxy final
-{
-public:
-  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(URLProxy)
-
-  explicit URLProxy(already_AddRefed<URLMainThread> aURL)
-    : mURL(aURL)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-  }
-
-  URLMainThread* URL()
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-    return mURL;
-  }
-
-  nsIURI* URI()
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-    return mURL->GetURI();
-  }
-
-  void ReleaseURI()
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-    mURL = nullptr;
-  }
-
-private:
-  // Private destructor, to discourage deletion outside of Release():
-  ~URLProxy()
-  {
-     MOZ_ASSERT(!mURL);
-  }
-
-  RefPtr<URLMainThread> mURL;
-};
-
-// URLWorker implements the URL object in workers.
-class URLWorker final : public URL
-{
-public:
-  static already_AddRefed<URLWorker>
-  Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-              URL& aBase, ErrorResult& aRv);
-
-  static already_AddRefed<URLWorker>
-  Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-              const Optional<nsAString>& aBase, ErrorResult& aRv);
-
-  static already_AddRefed<URLWorker>
-  Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-              const nsAString& aBase, ErrorResult& aRv);
-
-  static void
-  CreateObjectURL(const GlobalObject& aGlobal, Blob& aBlob,
-                  nsAString& aResult, mozilla::ErrorResult& aRv);
-
-  static void
-  RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aUrl,
-                  ErrorResult& aRv);
-
-  static bool
-  IsValidURL(const GlobalObject& aGlobal, const nsAString& aUrl,
-             ErrorResult& aRv);
-
-  URLWorker(WorkerPrivate* aWorkerPrivate, URLProxy* aURLProxy);
-
-  virtual void
-  GetHref(nsAString& aHref, ErrorResult& aRv) const override;
-
-  virtual void
-  SetHref(const nsAString& aHref, ErrorResult& aRv) override;
-
-  virtual void
-  GetOrigin(nsAString& aOrigin, ErrorResult& aRv) const override;
-
-  virtual void
-  GetProtocol(nsAString& aProtocol, ErrorResult& aRv) const override;
-
-  virtual void
-  SetProtocol(const nsAString& aProtocol, ErrorResult& aRv) override;
-
-  virtual void
-  GetUsername(nsAString& aUsername, ErrorResult& aRv) const override;
-
-  virtual void
-  SetUsername(const nsAString& aUsername, ErrorResult& aRv) override;
-
-  virtual void
-  GetPassword(nsAString& aPassword, ErrorResult& aRv) const override;
-
-  virtual void
-  SetPassword(const nsAString& aPassword, ErrorResult& aRv) override;
-
-  virtual void
-  GetHost(nsAString& aHost, ErrorResult& aRv) const override;
-
-  virtual void
-  SetHost(const nsAString& aHost, ErrorResult& aRv) override;
-
-  virtual void
-  GetHostname(nsAString& aHostname, ErrorResult& aRv) const override;
-
-  virtual void
-  SetHostname(const nsAString& aHostname, ErrorResult& aRv) override;
-
-  virtual void
-  GetPort(nsAString& aPort, ErrorResult& aRv) const override;
-
-  virtual void
-  SetPort(const nsAString& aPort, ErrorResult& aRv) override;
-
-  virtual void
-  GetPathname(nsAString& aPathname, ErrorResult& aRv) const override;
-
-  virtual void
-  SetPathname(const nsAString& aPathname, ErrorResult& aRv) override;
-
-  virtual void
-  GetSearch(nsAString& aSearch, ErrorResult& aRv) const override;
-
-  virtual void
-  GetHash(nsAString& aHost, ErrorResult& aRv) const override;
-
-  virtual void
-  SetHash(const nsAString& aHash, ErrorResult& aRv) override;
-
-  virtual void UpdateURLSearchParams() override;
-
-  virtual void
-  SetSearchInternal(const nsAString& aSearch, ErrorResult& aRv) override;
-
-  URLProxy*
-  GetURLProxy() const
-  {
-    mWorkerPrivate->AssertIsOnWorkerThread();
-    return mURLProxy;
-  }
-
-private:
-  ~URLWorker();
-
-  workers::WorkerPrivate* mWorkerPrivate;
-  RefPtr<URLProxy> mURLProxy;
-};
-
-// This class creates an URL from a DOM Blob on the main thread.
-class CreateURLRunnable : public WorkerMainThreadRunnable
-{
-private:
-  BlobImpl* mBlobImpl;
-  nsAString& mURL;
-
-public:
-  CreateURLRunnable(WorkerPrivate* aWorkerPrivate, BlobImpl* aBlobImpl,
-                    nsAString& aURL)
-  : WorkerMainThreadRunnable(aWorkerPrivate,
-                             NS_LITERAL_CSTRING("URL :: CreateURL"))
-  , mBlobImpl(aBlobImpl)
-  , mURL(aURL)
-  {
-    MOZ_ASSERT(aBlobImpl);
-
-    DebugOnly<bool> isMutable;
-    MOZ_ASSERT(NS_SUCCEEDED(aBlobImpl->GetMutable(&isMutable)));
-    MOZ_ASSERT(!isMutable);
-  }
-
-  bool
-  MainThreadRun()
-  {
-    using namespace mozilla::ipc;
-
-    AssertIsOnMainThread();
-
-    DebugOnly<bool> isMutable;
-    MOZ_ASSERT(NS_SUCCEEDED(mBlobImpl->GetMutable(&isMutable)));
-    MOZ_ASSERT(!isMutable);
-
-    nsCOMPtr<nsIPrincipal> principal = mWorkerPrivate->GetPrincipal();
-
-    nsAutoCString url;
-    nsresult rv =
-      nsHostObjectProtocolHandler::AddDataEntry(mBlobImpl, principal, url);
-
-    if (NS_FAILED(rv)) {
-      NS_WARNING("Failed to add data entry for the blob!");
-      SetDOMStringToNull(mURL);
-      return false;
-    }
-
-    if (!mWorkerPrivate->IsSharedWorker() &&
-        !mWorkerPrivate->IsServiceWorker()) {
-      // Walk up to top worker object.
-      WorkerPrivate* wp = mWorkerPrivate;
-      while (WorkerPrivate* parent = wp->GetParent()) {
-        wp = parent;
-      }
-
-      nsCOMPtr<nsIScriptContext> sc = wp->GetScriptContext();
-      // We could not have a ScriptContext in JSM code. In this case, we leak.
-      if (sc) {
-        nsCOMPtr<nsIGlobalObject> global = sc->GetGlobalObject();
-        MOZ_ASSERT(global);
-
-        global->RegisterHostObjectURI(url);
-      }
-    }
-
-    mURL = NS_ConvertUTF8toUTF16(url);
-    return true;
-  }
-};
-
-// This class revokes an URL on the main thread.
-class RevokeURLRunnable : public WorkerMainThreadRunnable
-{
-private:
-  const nsString mURL;
-
-public:
-  RevokeURLRunnable(WorkerPrivate* aWorkerPrivate,
-                    const nsAString& aURL)
-  : WorkerMainThreadRunnable(aWorkerPrivate,
-                             NS_LITERAL_CSTRING("URL :: RevokeURL"))
-  , mURL(aURL)
-  {}
-
-  bool
-  MainThreadRun()
-  {
-    AssertIsOnMainThread();
-
-    NS_ConvertUTF16toUTF8 url(mURL);
-
-    nsIPrincipal* urlPrincipal =
-      nsHostObjectProtocolHandler::GetDataEntryPrincipal(url);
-
-    nsCOMPtr<nsIPrincipal> principal = mWorkerPrivate->GetPrincipal();
-
-    bool subsumes;
-    if (urlPrincipal &&
-        NS_SUCCEEDED(principal->Subsumes(urlPrincipal, &subsumes)) &&
-        subsumes) {
-      nsHostObjectProtocolHandler::RemoveDataEntry(url);
-    }
-
-    if (!mWorkerPrivate->IsSharedWorker() &&
-        !mWorkerPrivate->IsServiceWorker()) {
-      // Walk up to top worker object.
-      WorkerPrivate* wp = mWorkerPrivate;
-      while (WorkerPrivate* parent = wp->GetParent()) {
-        wp = parent;
-      }
-
-      nsCOMPtr<nsIScriptContext> sc = wp->GetScriptContext();
-      // We could not have a ScriptContext in JSM code. In this case, we leak.
-      if (sc) {
-        nsCOMPtr<nsIGlobalObject> global = sc->GetGlobalObject();
-        MOZ_ASSERT(global);
-
-        global->UnregisterHostObjectURI(url);
-      }
-    }
-
-    return true;
-  }
-};
-
-// This class checks if an URL is valid on the main thread.
-class IsValidURLRunnable : public WorkerMainThreadRunnable
-{
-private:
-  const nsString mURL;
-  bool mValid;
-
-public:
-  IsValidURLRunnable(WorkerPrivate* aWorkerPrivate,
-                     const nsAString& aURL)
-  : WorkerMainThreadRunnable(aWorkerPrivate,
-                             NS_LITERAL_CSTRING("URL :: IsValidURL"))
-  , mURL(aURL)
-  , mValid(false)
-  {}
-
-  bool
-  MainThreadRun()
-  {
-    AssertIsOnMainThread();
-
-    NS_ConvertUTF16toUTF8 url(mURL);
-    mValid = nsHostObjectProtocolHandler::HasDataEntry(url);
-
-    return true;
-  }
-
-  bool
-  IsValidURL() const
-  {
-    return mValid;
-  }
-};
-
-// This class creates a URL object on the main thread.
-class ConstructorRunnable : public WorkerMainThreadRunnable
-{
-private:
-  const nsString mURL;
-
-  nsString mBase; // IsVoid() if we have no base URI string.
-  RefPtr<URLProxy> mBaseProxy;
-
-  RefPtr<URLProxy> mRetval;
-
-public:
-  ConstructorRunnable(WorkerPrivate* aWorkerPrivate,
-                      const nsAString& aURL, const Optional<nsAString>& aBase)
-  : WorkerMainThreadRunnable(aWorkerPrivate,
-                             NS_LITERAL_CSTRING("URL :: Constructor"))
-  , mURL(aURL)
-  {
-    if (aBase.WasPassed()) {
-      mBase = aBase.Value();
-    } else {
-      mBase.SetIsVoid(true);
-    }
-    mWorkerPrivate->AssertIsOnWorkerThread();
-  }
-
-  ConstructorRunnable(WorkerPrivate* aWorkerPrivate,
-                      const nsAString& aURL, URLProxy* aBaseProxy)
-  : WorkerMainThreadRunnable(aWorkerPrivate,
-                             NS_LITERAL_CSTRING("URL :: Constructor with BaseURL"))
-  , mURL(aURL)
-  , mBaseProxy(aBaseProxy)
-  {
-    mBase.SetIsVoid(true);
-    mWorkerPrivate->AssertIsOnWorkerThread();
-  }
-
-  bool
-  MainThreadRun()
-  {
-    AssertIsOnMainThread();
-
-    ErrorResult rv;
-    RefPtr<URLMainThread> url;
-    if (mBaseProxy) {
-      url = URLMainThread::Constructor(nullptr, mURL, mBaseProxy->URI(), rv);
-    } else if (!mBase.IsVoid()) {
-      url = URLMainThread::Constructor(nullptr, mURL, mBase, rv);
-    } else {
-      url = URLMainThread::Constructor(nullptr, mURL, nullptr, rv);
-    }
-
-    if (rv.Failed()) {
-      rv.SuppressException();
-      return true;
-    }
-
-    mRetval = new URLProxy(url.forget());
-    return true;
-  }
-
-  URLProxy*
-  GetURLProxy(ErrorResult& aRv) const
-  {
-    MOZ_ASSERT(mWorkerPrivate);
-    mWorkerPrivate->AssertIsOnWorkerThread();
-
-    if (!mRetval) {
-      aRv.ThrowTypeError<MSG_INVALID_URL>(mURL);
-    }
-
-    return mRetval;
-  }
-};
-
-class TeardownURLRunnable : public Runnable
-{
-public:
-  explicit TeardownURLRunnable(URLProxy* aURLProxy)
-    : mURLProxy(aURLProxy)
-  {
-  }
-
-  NS_IMETHOD Run()
-  {
-    AssertIsOnMainThread();
-
-    mURLProxy->ReleaseURI();
-    mURLProxy = nullptr;
-
-    return NS_OK;
-  }
-
-private:
-  RefPtr<URLProxy> mURLProxy;
-};
-
-// This class is the generic getter for any URL property.
-class GetterRunnable : public WorkerMainThreadRunnable
-{
-public:
-  enum GetterType {
-    GetterHref,
-    GetterOrigin,
-    GetterProtocol,
-    GetterUsername,
-    GetterPassword,
-    GetterHost,
-    GetterHostname,
-    GetterPort,
-    GetterPathname,
-    GetterSearch,
-    GetterHash,
-  };
-
-  GetterRunnable(WorkerPrivate* aWorkerPrivate,
-                 GetterType aType, nsAString& aValue,
-                 URLProxy* aURLProxy)
-  : WorkerMainThreadRunnable(aWorkerPrivate,
-                             // We can have telemetry keys for each getter when
-                             // needed.
-                             NS_LITERAL_CSTRING("URL :: getter"))
-  , mValue(aValue)
-  , mType(aType)
-  , mURLProxy(aURLProxy)
-  {
-    mWorkerPrivate->AssertIsOnWorkerThread();
-  }
-
-  bool
-  MainThreadRun()
-  {
-    AssertIsOnMainThread();
-    ErrorResult rv;
-
-    switch (mType) {
-      case GetterHref:
-        mURLProxy->URL()->GetHref(mValue, rv);
-        break;
-
-      case GetterOrigin:
-        mURLProxy->URL()->GetOrigin(mValue, rv);
-        break;
-
-      case GetterProtocol:
-        mURLProxy->URL()->GetProtocol(mValue, rv);
-        break;
-
-      case GetterUsername:
-        mURLProxy->URL()->GetUsername(mValue, rv);
-        break;
-
-      case GetterPassword:
-        mURLProxy->URL()->GetPassword(mValue, rv);
-        break;
-
-      case GetterHost:
-        mURLProxy->URL()->GetHost(mValue, rv);
-        break;
-
-      case GetterHostname:
-        mURLProxy->URL()->GetHostname(mValue, rv);
-        break;
-
-      case GetterPort:
-        mURLProxy->URL()->GetPort(mValue, rv);
-        break;
-
-      case GetterPathname:
-        mURLProxy->URL()->GetPathname(mValue, rv);
-        break;
-
-      case GetterSearch:
-        mURLProxy->URL()->GetSearch(mValue, rv);
-        break;
-
-      case GetterHash:
-        mURLProxy->URL()->GetHash(mValue, rv);
-        break;
-    }
-
-    MOZ_ASSERT(!rv.Failed(), "Main-thread getters do not fail.");
-    return true;
-  }
-
-  void
-  Dispatch(ErrorResult& aRv)
-  {
-    WorkerMainThreadRunnable::Dispatch(Terminating, aRv);
-  }
-
-private:
-  nsAString& mValue;
-  GetterType mType;
-  RefPtr<URLProxy> mURLProxy;
-};
-
-// This class is the generic setter for any URL property.
-class SetterRunnable : public WorkerMainThreadRunnable
-{
-public:
-  enum SetterType {
-    SetterHref,
-    SetterProtocol,
-    SetterUsername,
-    SetterPassword,
-    SetterHost,
-    SetterHostname,
-    SetterPort,
-    SetterPathname,
-    SetterSearch,
-    SetterHash,
-  };
-
-  SetterRunnable(WorkerPrivate* aWorkerPrivate,
-                 SetterType aType, const nsAString& aValue,
-                 URLProxy* aURLProxy)
-  : WorkerMainThreadRunnable(aWorkerPrivate,
-                             // We can have telemetry keys for each setter when
-                             // needed.
-                             NS_LITERAL_CSTRING("URL :: setter"))
-  , mValue(aValue)
-  , mType(aType)
-  , mURLProxy(aURLProxy)
-  , mFailed(false)
-  {
-    mWorkerPrivate->AssertIsOnWorkerThread();
-  }
-
-  bool
-  MainThreadRun()
-  {
-    AssertIsOnMainThread();
-    ErrorResult rv;
-
-    switch (mType) {
-      case SetterHref: {
-        mURLProxy->URL()->SetHref(mValue, rv);
-        break;
-      }
-
-      case SetterProtocol:
-        mURLProxy->URL()->SetProtocol(mValue, rv);
-        break;
-
-      case SetterUsername:
-        mURLProxy->URL()->SetUsername(mValue, rv);
-        break;
-
-      case SetterPassword:
-        mURLProxy->URL()->SetPassword(mValue, rv);
-        break;
-
-      case SetterHost:
-        mURLProxy->URL()->SetHost(mValue, rv);
-        break;
-
-      case SetterHostname:
-        mURLProxy->URL()->SetHostname(mValue, rv);
-        break;
-
-      case SetterPort:
-        mURLProxy->URL()->SetPort(mValue, rv);
-        break;
-
-      case SetterPathname:
-        mURLProxy->URL()->SetPathname(mValue, rv);
-        break;
-
-      case SetterSearch:
-        mURLProxy->URL()->SetSearch(mValue, rv);
-        break;
-
-      case SetterHash:
-        mURLProxy->URL()->SetHash(mValue, rv);
-        break;
-    }
-
-    if (NS_WARN_IF(rv.Failed())) {
-      rv.SuppressException();
-      mFailed = true;
-    }
-
-    return true;
-  }
-
-  bool Failed() const
-  {
-    return mFailed;
-  }
-
-  void
-  Dispatch(ErrorResult& aRv)
-  {
-    WorkerMainThreadRunnable::Dispatch(Terminating, aRv);
-  }
-
-private:
-  const nsString mValue;
-  SetterType mType;
-  RefPtr<URLProxy> mURLProxy;
-  bool mFailed;
-};
-
-already_AddRefed<URLWorker>
-FinishConstructor(JSContext* aCx, WorkerPrivate* aPrivate,
-                  ConstructorRunnable* aRunnable, ErrorResult& aRv)
-{
-  aRunnable->Dispatch(Terminating, aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return nullptr;
-  }
-
-  RefPtr<URLProxy> proxy = aRunnable->GetURLProxy(aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return nullptr;
-  }
-
-  RefPtr<URLWorker> url = new URLWorker(aPrivate, proxy);
-  return url.forget();
-}
-
-/* static */ already_AddRefed<URLWorker>
-URLWorker::Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-                       URL& aBase, ErrorResult& aRv)
-{
-  MOZ_ASSERT(!NS_IsMainThread());
-
-  JSContext* cx = aGlobal.Context();
-  WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
-
-  URLWorker& base = static_cast<URLWorker&>(aBase);
-  RefPtr<ConstructorRunnable> runnable =
-    new ConstructorRunnable(workerPrivate, aURL, base.GetURLProxy());
-
-  return FinishConstructor(cx, workerPrivate, runnable, aRv);
-}
-
-/* static */ already_AddRefed<URLWorker>
-URLWorker::Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-                       const Optional<nsAString>& aBase, ErrorResult& aRv)
-{
-  JSContext* cx = aGlobal.Context();
-  WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
-
-  RefPtr<ConstructorRunnable> runnable =
-    new ConstructorRunnable(workerPrivate, aURL, aBase);
-
-  return FinishConstructor(cx, workerPrivate, runnable, aRv);
-}
-
-/* static */ already_AddRefed<URLWorker>
-URLWorker::Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-                       const nsAString& aBase, ErrorResult& aRv)
-{
-  JSContext* cx = aGlobal.Context();
-  WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
-
-  Optional<nsAString> base;
-  base = &aBase;
-
-  RefPtr<ConstructorRunnable> runnable =
-    new ConstructorRunnable(workerPrivate, aURL, base);
-
-  return FinishConstructor(cx, workerPrivate, runnable, aRv);
-}
-
-/* static */ void
-URLWorker::CreateObjectURL(const GlobalObject& aGlobal, Blob& aBlob,
-                           nsAString& aResult, mozilla::ErrorResult& aRv)
-{
-  JSContext* cx = aGlobal.Context();
-  WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
-
-  RefPtr<BlobImpl> blobImpl = aBlob.Impl();
-  MOZ_ASSERT(blobImpl);
-
-  aRv = blobImpl->SetMutable(false);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  RefPtr<CreateURLRunnable> runnable =
-    new CreateURLRunnable(workerPrivate, blobImpl, aResult);
-
-  runnable->Dispatch(Terminating, aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  if (workerPrivate->IsSharedWorker() || workerPrivate->IsServiceWorker()) {
-    WorkerGlobalScope* scope = workerPrivate->GlobalScope();
-    MOZ_ASSERT(scope);
-
-    scope->RegisterHostObjectURI(NS_ConvertUTF16toUTF8(aResult));
-  }
-}
-
-/* static */ void
-URLWorker::RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aUrl,
-                           ErrorResult& aRv)
-{
-  JSContext* cx = aGlobal.Context();
-  WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
-
-  RefPtr<RevokeURLRunnable> runnable =
-    new RevokeURLRunnable(workerPrivate, aUrl);
-
-  runnable->Dispatch(Terminating, aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  if (workerPrivate->IsSharedWorker() || workerPrivate->IsServiceWorker()) {
-    WorkerGlobalScope* scope = workerPrivate->GlobalScope();
-    MOZ_ASSERT(scope);
-
-    scope->UnregisterHostObjectURI(NS_ConvertUTF16toUTF8(aUrl));
-  }
-}
-
-/* static */ bool
-URLWorker::IsValidURL(const GlobalObject& aGlobal, const nsAString& aUrl,
-                      ErrorResult& aRv)
-{
-  JSContext* cx = aGlobal.Context();
-  WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
-
-  RefPtr<IsValidURLRunnable> runnable =
-    new IsValidURLRunnable(workerPrivate, aUrl);
-
-  runnable->Dispatch(Terminating, aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return false;
-  }
-
-  return runnable->IsValidURL();
-}
-
-URLWorker::URLWorker(WorkerPrivate* aWorkerPrivate, URLProxy* aURLProxy)
-  : URL(nullptr)
-  , mWorkerPrivate(aWorkerPrivate)
-  , mURLProxy(aURLProxy)
-{}
-
-URLWorker::~URLWorker()
-{
-  if (mURLProxy) {
-    mWorkerPrivate->AssertIsOnWorkerThread();
-
-    RefPtr<TeardownURLRunnable> runnable =
-      new TeardownURLRunnable(mURLProxy);
-    mURLProxy = nullptr;
-
-    if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
-      NS_ERROR("Failed to dispatch teardown runnable!");
-    }
-  }
-}
-
-void
-URLWorker::GetHref(nsAString& aHref, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHref, aHref,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URLWorker::SetHref(const nsAString& aHref, ErrorResult& aRv)
-{
-  RefPtr<SetterRunnable> runnable =
-    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHref, aHref,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  if (runnable->Failed()) {
-    aRv.ThrowTypeError<MSG_INVALID_URL>(aHref);
-    return;
-  }
-
-  UpdateURLSearchParams();
-}
-
-void
-URLWorker::GetOrigin(nsAString& aOrigin, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterOrigin, aOrigin,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URLWorker::GetProtocol(nsAString& aProtocol, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterProtocol, aProtocol,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URLWorker::SetProtocol(const nsAString& aProtocol, ErrorResult& aRv)
-{
-  RefPtr<SetterRunnable> runnable =
-    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterProtocol,
-                       aProtocol, mURLProxy);
-
-  runnable->Dispatch(aRv);
-
-  MOZ_ASSERT(!runnable->Failed());
-}
-
-void
-URLWorker::GetUsername(nsAString& aUsername, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterUsername, aUsername,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URLWorker::SetUsername(const nsAString& aUsername, ErrorResult& aRv)
-{
-  RefPtr<SetterRunnable> runnable =
-    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterUsername,
-                       aUsername, mURLProxy);
-
-  runnable->Dispatch(aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  MOZ_ASSERT(!runnable->Failed());
-}
-
-void
-URLWorker::GetPassword(nsAString& aPassword, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterPassword, aPassword,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URLWorker::SetPassword(const nsAString& aPassword, ErrorResult& aRv)
-{
-  RefPtr<SetterRunnable> runnable =
-    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterPassword,
-                       aPassword, mURLProxy);
-
-  runnable->Dispatch(aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  MOZ_ASSERT(!runnable->Failed());
-}
-
-void
-URLWorker::GetHost(nsAString& aHost, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHost, aHost,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URLWorker::SetHost(const nsAString& aHost, ErrorResult& aRv)
-{
-  RefPtr<SetterRunnable> runnable =
-    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHost,
-                       aHost, mURLProxy);
-
-  runnable->Dispatch(aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  MOZ_ASSERT(!runnable->Failed());
-}
-
-void
-URLWorker::GetHostname(nsAString& aHostname, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHostname, aHostname,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URLWorker::SetHostname(const nsAString& aHostname, ErrorResult& aRv)
-{
-  RefPtr<SetterRunnable> runnable =
-    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHostname,
-                       aHostname, mURLProxy);
-
-  runnable->Dispatch(aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  MOZ_ASSERT(!runnable->Failed());
-}
-
-void
-URLWorker::GetPort(nsAString& aPort, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterPort, aPort,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URLWorker::SetPort(const nsAString& aPort, ErrorResult& aRv)
-{
-  RefPtr<SetterRunnable> runnable =
-    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterPort,
-                       aPort, mURLProxy);
-
-  runnable->Dispatch(aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  MOZ_ASSERT(!runnable->Failed());
-}
-
-void
-URLWorker::GetPathname(nsAString& aPathname, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterPathname,
-                       aPathname, mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URLWorker::SetPathname(const nsAString& aPathname, ErrorResult& aRv)
-{
-  RefPtr<SetterRunnable> runnable =
-    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterPathname,
-                       aPathname, mURLProxy);
-
-  runnable->Dispatch(aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  MOZ_ASSERT(!runnable->Failed());
-}
-
-void
-URLWorker::GetSearch(nsAString& aSearch, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterSearch, aSearch,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URLWorker::GetHash(nsAString& aHash, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHash, aHash,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URLWorker::SetHash(const nsAString& aHash, ErrorResult& aRv)
-{
-  RefPtr<SetterRunnable> runnable =
-    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHash,
-                       aHash, mURLProxy);
-
-  runnable->Dispatch(aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  MOZ_ASSERT(!runnable->Failed());
-}
-
-void
-URLWorker::SetSearchInternal(const nsAString& aSearch, ErrorResult& aRv)
-{
-  RefPtr<SetterRunnable> runnable =
-    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterSearch,
-                       aSearch, mURLProxy);
-
-  runnable->Dispatch(aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  MOZ_ASSERT(!runnable->Failed());
-}
-
-void
-URLWorker::UpdateURLSearchParams()
-{
-  if (mSearchParams) {
-    nsAutoString search;
-
-    ErrorResult rv;
-    GetSearch(search, rv);
-    if (NS_WARN_IF(rv.Failed())) {
-      rv.SuppressException();
-    }
-
-    mSearchParams->ParseInput(NS_ConvertUTF16toUTF8(Substring(search, 1)));
-  }
-}
-
-} // anonymous namespace
-
-///////////////////////////////////////////////////////////////////////////////
-// Base class for URL
-///////////////////////////////////////////////////////////////////////////////
-
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(URL, mParent, mSearchParams)
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(URL)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(URL)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(URL)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
@@ -1650,27 +29,16 @@ NS_INTERFACE_MAP_END
 JSObject*
 URL::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
   return URLBinding::Wrap(aCx, this, aGivenProto);
 }
 
 /* static */ already_AddRefed<URL>
 URL::Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-                 URL& aBase, ErrorResult& aRv)
-{
-  if (NS_IsMainThread()) {
-    return URLMainThread::Constructor(aGlobal, aURL, aBase, aRv);
-  }
-
-  return URLWorker::Constructor(aGlobal, aURL, aBase, aRv);
-}
-
-/* static */ already_AddRefed<URL>
-URL::Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
                  const Optional<nsAString>& aBase, ErrorResult& aRv)
 {
   if (NS_IsMainThread()) {
     return URLMainThread::Constructor(aGlobal, aURL, aBase, aRv);
   }
 
   return URLWorker::Constructor(aGlobal, aURL, aBase, aRv);
 }
--- a/dom/url/URL.h
+++ b/dom/url/URL.h
@@ -44,20 +44,16 @@ public:
     return mParent;
   }
 
   virtual JSObject*
   WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 
   static already_AddRefed<URL>
   Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-              URL& aBase, ErrorResult& aRv);
-
-  static already_AddRefed<URL>
-  Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
               const Optional<nsAString>& aBase, ErrorResult& aRv);
 
   // Helper for Fetch API
   static already_AddRefed<URL>
   WorkerConstructor(const GlobalObject& aGlobal, const nsAString& aURL,
                     const nsAString& aBase, ErrorResult& aRv);
 
 
copy from dom/url/URL.cpp
copy to dom/url/URLMainThread.cpp
--- a/dom/url/URL.cpp
+++ b/dom/url/URLMainThread.cpp
@@ -1,40 +1,26 @@
 /* -*- 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 "URL.h"
+#include "URLMainThread.h"
 
-#include "DOMMediaStream.h"
-#include "mozilla/dom/File.h"
-#include "mozilla/dom/MediaSource.h"
-#include "mozilla/dom/URLBinding.h"
-#include "mozilla/ipc/BackgroundChild.h"
+#include "mozilla/dom/BindingUtils.h"
+#include "mozilla/dom/Blob.h"
 #include "nsContentUtils.h"
-#include "nsEscape.h"
 #include "nsHostObjectProtocolHandler.h"
-#include "nsIIOService.h"
 #include "nsIURL.h"
-#include "nsNetCID.h"
 #include "nsNetUtil.h"
-#include "nsServiceManagerUtils.h"
-#include "WorkerPrivate.h"
-#include "WorkerRunnable.h"
-#include "WorkerScope.h"
 
 namespace mozilla {
 namespace dom {
 
-///////////////////////////////////////////////////////////////////////////////
-// URL for main-thread
-///////////////////////////////////////////////////////////////////////////////
-
 namespace {
 
 template<typename T>
 void
 CreateObjectURLInternal(const GlobalObject& aGlobal, T aObject,
                         nsAString& aResult, ErrorResult& aRv)
 {
   nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
@@ -51,160 +37,17 @@ CreateObjectURLInternal(const GlobalObje
   if (NS_WARN_IF(aRv.Failed())) {
     return;
   }
 
   global->RegisterHostObjectURI(url);
   CopyASCIItoUTF16(url, aResult);
 }
 
-// The URL implementation for the main-thread
-class URLMainThread final : public URL
-{
-public:
-  static already_AddRefed<URLMainThread>
-  Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-              URL& aBase, ErrorResult& aRv);
-
-  static already_AddRefed<URLMainThread>
-  Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-              const Optional<nsAString>& aBase, ErrorResult& aRv);
-
-  static already_AddRefed<URLMainThread>
-  Constructor(nsISupports* aParent, const nsAString& aURL,
-              const nsAString& aBase, ErrorResult& aRv);
-
-  static already_AddRefed<URLMainThread>
-  Constructor(nsISupports* aParent, const nsAString& aURL, nsIURI* aBase,
-              ErrorResult& aRv);
-
-  static void
-  CreateObjectURL(const GlobalObject& aGlobal, Blob& aBlob,
-                  nsAString& aResult, ErrorResult& aRv)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-    CreateObjectURLInternal(aGlobal, aBlob.Impl(), aResult, aRv);
-  }
-
-  static void
-  CreateObjectURL(const GlobalObject& aGlobal, DOMMediaStream& aStream,
-                  nsAString& aResult, ErrorResult& aRv)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-    CreateObjectURLInternal(aGlobal, &aStream, aResult, aRv);
-  }
-
-  static void
-  CreateObjectURL(const GlobalObject& aGlobal, MediaSource& aSource,
-                  nsAString& aResult, ErrorResult& aRv);
-
-  static void
-  RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aURL,
-                  ErrorResult& aRv);
-
-  static bool
-  IsValidURL(const GlobalObject& aGlobal, const nsAString& aURL,
-             ErrorResult& aRv);
-
-  URLMainThread(nsISupports* aParent, already_AddRefed<nsIURI> aURI)
-    : URL(aParent)
-    , mURI(aURI)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-  }
-
-  virtual void
-  GetHref(nsAString& aHref, ErrorResult& aRv) const override;
-
-  virtual void
-  SetHref(const nsAString& aHref, ErrorResult& aRv) override;
-
-  virtual void
-  GetOrigin(nsAString& aOrigin, ErrorResult& aRv) const override;
-
-  virtual void
-  GetProtocol(nsAString& aProtocol, ErrorResult& aRv) const override;
-
-  virtual void
-  SetProtocol(const nsAString& aProtocol, ErrorResult& aRv) override;
-
-  virtual void
-  GetUsername(nsAString& aUsername, ErrorResult& aRv) const override;
-
-  virtual void
-  SetUsername(const nsAString& aUsername, ErrorResult& aRv) override;
-
-  virtual void
-  GetPassword(nsAString& aPassword, ErrorResult& aRv) const override;
-
-  virtual void
-  SetPassword(const nsAString& aPassword, ErrorResult& aRv) override;
-
-  virtual void
-  GetHost(nsAString& aHost, ErrorResult& aRv) const override;
-
-  virtual void
-  SetHost(const nsAString& aHost, ErrorResult& aRv) override;
-
-  virtual void
-  GetHostname(nsAString& aHostname, ErrorResult& aRv) const override;
-
-  virtual void
-  SetHostname(const nsAString& aHostname, ErrorResult& aRv) override;
-
-  virtual void
-  GetPort(nsAString& aPort, ErrorResult& aRv) const override;
-
-  virtual void
-  SetPort(const nsAString& aPort, ErrorResult& aRv) override;
-
-  virtual void
-  GetPathname(nsAString& aPathname, ErrorResult& aRv) const override;
-
-  virtual void
-  SetPathname(const nsAString& aPathname, ErrorResult& aRv) override;
-
-  virtual void
-  GetSearch(nsAString& aSearch, ErrorResult& aRv) const override;
-
-  virtual void
-  GetHash(nsAString& aHost, ErrorResult& aRv) const override;
-
-  virtual void
-  SetHash(const nsAString& aHash, ErrorResult& aRv) override;
-
-  virtual void UpdateURLSearchParams() override;
-
-  virtual void
-  SetSearchInternal(const nsAString& aSearch, ErrorResult& aRv) override;
-
-  nsIURI*
-  GetURI() const
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-    return mURI;
-  }
-
-private:
-  ~URLMainThread()
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-  }
-
-  nsCOMPtr<nsIURI> mURI;
-};
-
-/* static */ already_AddRefed<URLMainThread>
-URLMainThread::Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-                           URL& aBase, ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  URLMainThread& base = static_cast<URLMainThread&>(aBase);
-  return Constructor(aGlobal.GetAsSupports(), aURL, base.GetURI(), aRv);
-}
+} // anonymous namespace
 
 /* static */ already_AddRefed<URLMainThread>
 URLMainThread::Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
                            const Optional<nsAString>& aBase, ErrorResult& aRv)
 {
   if (aBase.WasPassed()) {
     return Constructor(aGlobal.GetAsSupports(), aURL, aBase.Value(), aRv);
   }
@@ -245,16 +88,33 @@ URLMainThread::Constructor(nsISupports* 
     return nullptr;
   }
 
   RefPtr<URLMainThread> url = new URLMainThread(aParent, uri.forget());
   return url.forget();
 }
 
 /* static */ void
+URLMainThread::CreateObjectURL(const GlobalObject& aGlobal, Blob& aBlob,
+                               nsAString& aResult, ErrorResult& aRv)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  CreateObjectURLInternal(aGlobal, aBlob.Impl(), aResult, aRv);
+}
+
+/* static */ void
+URLMainThread::CreateObjectURL(const GlobalObject& aGlobal,
+                               DOMMediaStream& aStream,
+                               nsAString& aResult, ErrorResult& aRv)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  CreateObjectURLInternal(aGlobal, &aStream, aResult, aRv);
+}
+
+/* static */ void
 URLMainThread::CreateObjectURL(const GlobalObject& aGlobal,
                                MediaSource& aSource,
                                nsAString& aResult, ErrorResult& aRv)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsCOMPtr<nsIPrincipal> principal =
     nsContentUtils::ObjectPrincipal(aGlobal.Get());
@@ -294,16 +154,29 @@ URLMainThread::RevokeObjectURL(const Glo
     nsHostObjectProtocolHandler::GetDataEntryPrincipal(asciiurl);
 
   if (urlPrincipal && principal->Subsumes(urlPrincipal)) {
     global->UnregisterHostObjectURI(asciiurl);
     nsHostObjectProtocolHandler::RemoveDataEntry(asciiurl);
   }
 }
 
+URLMainThread::URLMainThread(nsISupports* aParent,
+                             already_AddRefed<nsIURI> aURI)
+  : URL(aParent)
+  , mURI(aURI)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+}
+
+URLMainThread::~URLMainThread()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+}
+
 /* static */ bool
 URLMainThread::IsValidURL(const GlobalObject& aGlobal, const nsAString& aURL,
                           ErrorResult& aRv)
 {
   MOZ_ASSERT(NS_IsMainThread());
   NS_LossyConvertUTF16toASCII asciiurl(aURL);
   return nsHostObjectProtocolHandler::HasDataEntry(asciiurl);
 }
@@ -572,1212 +445,17 @@ URLMainThread::SetHash(const nsAString& 
 void
 URLMainThread::SetSearchInternal(const nsAString& aSearch, ErrorResult& aRv)
 {
   // Ignore failures to be compatible with NS4.
 
   mURI->SetQuery(NS_ConvertUTF16toUTF8(aSearch));
 }
 
-} // anonymous namespace
-
-///////////////////////////////////////////////////////////////////////////////
-// URL for Workers
-///////////////////////////////////////////////////////////////////////////////
-
-namespace {
-
-using namespace workers;
-
-// Proxy class to forward all the requests to a URLMainThread object.
-class URLProxy final
-{
-public:
-  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(URLProxy)
-
-  explicit URLProxy(already_AddRefed<URLMainThread> aURL)
-    : mURL(aURL)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-  }
-
-  URLMainThread* URL()
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-    return mURL;
-  }
-
-  nsIURI* URI()
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-    return mURL->GetURI();
-  }
-
-  void ReleaseURI()
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-    mURL = nullptr;
-  }
-
-private:
-  // Private destructor, to discourage deletion outside of Release():
-  ~URLProxy()
-  {
-     MOZ_ASSERT(!mURL);
-  }
-
-  RefPtr<URLMainThread> mURL;
-};
-
-// URLWorker implements the URL object in workers.
-class URLWorker final : public URL
-{
-public:
-  static already_AddRefed<URLWorker>
-  Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-              URL& aBase, ErrorResult& aRv);
-
-  static already_AddRefed<URLWorker>
-  Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-              const Optional<nsAString>& aBase, ErrorResult& aRv);
-
-  static already_AddRefed<URLWorker>
-  Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-              const nsAString& aBase, ErrorResult& aRv);
-
-  static void
-  CreateObjectURL(const GlobalObject& aGlobal, Blob& aBlob,
-                  nsAString& aResult, mozilla::ErrorResult& aRv);
-
-  static void
-  RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aUrl,
-                  ErrorResult& aRv);
-
-  static bool
-  IsValidURL(const GlobalObject& aGlobal, const nsAString& aUrl,
-             ErrorResult& aRv);
-
-  URLWorker(WorkerPrivate* aWorkerPrivate, URLProxy* aURLProxy);
-
-  virtual void
-  GetHref(nsAString& aHref, ErrorResult& aRv) const override;
-
-  virtual void
-  SetHref(const nsAString& aHref, ErrorResult& aRv) override;
-
-  virtual void
-  GetOrigin(nsAString& aOrigin, ErrorResult& aRv) const override;
-
-  virtual void
-  GetProtocol(nsAString& aProtocol, ErrorResult& aRv) const override;
-
-  virtual void
-  SetProtocol(const nsAString& aProtocol, ErrorResult& aRv) override;
-
-  virtual void
-  GetUsername(nsAString& aUsername, ErrorResult& aRv) const override;
-
-  virtual void
-  SetUsername(const nsAString& aUsername, ErrorResult& aRv) override;
-
-  virtual void
-  GetPassword(nsAString& aPassword, ErrorResult& aRv) const override;
-
-  virtual void
-  SetPassword(const nsAString& aPassword, ErrorResult& aRv) override;
-
-  virtual void
-  GetHost(nsAString& aHost, ErrorResult& aRv) const override;
-
-  virtual void
-  SetHost(const nsAString& aHost, ErrorResult& aRv) override;
-
-  virtual void
-  GetHostname(nsAString& aHostname, ErrorResult& aRv) const override;
-
-  virtual void
-  SetHostname(const nsAString& aHostname, ErrorResult& aRv) override;
-
-  virtual void
-  GetPort(nsAString& aPort, ErrorResult& aRv) const override;
-
-  virtual void
-  SetPort(const nsAString& aPort, ErrorResult& aRv) override;
-
-  virtual void
-  GetPathname(nsAString& aPathname, ErrorResult& aRv) const override;
-
-  virtual void
-  SetPathname(const nsAString& aPathname, ErrorResult& aRv) override;
-
-  virtual void
-  GetSearch(nsAString& aSearch, ErrorResult& aRv) const override;
-
-  virtual void
-  GetHash(nsAString& aHost, ErrorResult& aRv) const override;
-
-  virtual void
-  SetHash(const nsAString& aHash, ErrorResult& aRv) override;
-
-  virtual void UpdateURLSearchParams() override;
-
-  virtual void
-  SetSearchInternal(const nsAString& aSearch, ErrorResult& aRv) override;
-
-  URLProxy*
-  GetURLProxy() const
-  {
-    mWorkerPrivate->AssertIsOnWorkerThread();
-    return mURLProxy;
-  }
-
-private:
-  ~URLWorker();
-
-  workers::WorkerPrivate* mWorkerPrivate;
-  RefPtr<URLProxy> mURLProxy;
-};
-
-// This class creates an URL from a DOM Blob on the main thread.
-class CreateURLRunnable : public WorkerMainThreadRunnable
-{
-private:
-  BlobImpl* mBlobImpl;
-  nsAString& mURL;
-
-public:
-  CreateURLRunnable(WorkerPrivate* aWorkerPrivate, BlobImpl* aBlobImpl,
-                    nsAString& aURL)
-  : WorkerMainThreadRunnable(aWorkerPrivate,
-                             NS_LITERAL_CSTRING("URL :: CreateURL"))
-  , mBlobImpl(aBlobImpl)
-  , mURL(aURL)
-  {
-    MOZ_ASSERT(aBlobImpl);
-
-    DebugOnly<bool> isMutable;
-    MOZ_ASSERT(NS_SUCCEEDED(aBlobImpl->GetMutable(&isMutable)));
-    MOZ_ASSERT(!isMutable);
-  }
-
-  bool
-  MainThreadRun()
-  {
-    using namespace mozilla::ipc;
-
-    AssertIsOnMainThread();
-
-    DebugOnly<bool> isMutable;
-    MOZ_ASSERT(NS_SUCCEEDED(mBlobImpl->GetMutable(&isMutable)));
-    MOZ_ASSERT(!isMutable);
-
-    nsCOMPtr<nsIPrincipal> principal = mWorkerPrivate->GetPrincipal();
-
-    nsAutoCString url;
-    nsresult rv =
-      nsHostObjectProtocolHandler::AddDataEntry(mBlobImpl, principal, url);
-
-    if (NS_FAILED(rv)) {
-      NS_WARNING("Failed to add data entry for the blob!");
-      SetDOMStringToNull(mURL);
-      return false;
-    }
-
-    if (!mWorkerPrivate->IsSharedWorker() &&
-        !mWorkerPrivate->IsServiceWorker()) {
-      // Walk up to top worker object.
-      WorkerPrivate* wp = mWorkerPrivate;
-      while (WorkerPrivate* parent = wp->GetParent()) {
-        wp = parent;
-      }
-
-      nsCOMPtr<nsIScriptContext> sc = wp->GetScriptContext();
-      // We could not have a ScriptContext in JSM code. In this case, we leak.
-      if (sc) {
-        nsCOMPtr<nsIGlobalObject> global = sc->GetGlobalObject();
-        MOZ_ASSERT(global);
-
-        global->RegisterHostObjectURI(url);
-      }
-    }
-
-    mURL = NS_ConvertUTF8toUTF16(url);
-    return true;
-  }
-};
-
-// This class revokes an URL on the main thread.
-class RevokeURLRunnable : public WorkerMainThreadRunnable
-{
-private:
-  const nsString mURL;
-
-public:
-  RevokeURLRunnable(WorkerPrivate* aWorkerPrivate,
-                    const nsAString& aURL)
-  : WorkerMainThreadRunnable(aWorkerPrivate,
-                             NS_LITERAL_CSTRING("URL :: RevokeURL"))
-  , mURL(aURL)
-  {}
-
-  bool
-  MainThreadRun()
-  {
-    AssertIsOnMainThread();
-
-    NS_ConvertUTF16toUTF8 url(mURL);
-
-    nsIPrincipal* urlPrincipal =
-      nsHostObjectProtocolHandler::GetDataEntryPrincipal(url);
-
-    nsCOMPtr<nsIPrincipal> principal = mWorkerPrivate->GetPrincipal();
-
-    bool subsumes;
-    if (urlPrincipal &&
-        NS_SUCCEEDED(principal->Subsumes(urlPrincipal, &subsumes)) &&
-        subsumes) {
-      nsHostObjectProtocolHandler::RemoveDataEntry(url);
-    }
-
-    if (!mWorkerPrivate->IsSharedWorker() &&
-        !mWorkerPrivate->IsServiceWorker()) {
-      // Walk up to top worker object.
-      WorkerPrivate* wp = mWorkerPrivate;
-      while (WorkerPrivate* parent = wp->GetParent()) {
-        wp = parent;
-      }
-
-      nsCOMPtr<nsIScriptContext> sc = wp->GetScriptContext();
-      // We could not have a ScriptContext in JSM code. In this case, we leak.
-      if (sc) {
-        nsCOMPtr<nsIGlobalObject> global = sc->GetGlobalObject();
-        MOZ_ASSERT(global);
-
-        global->UnregisterHostObjectURI(url);
-      }
-    }
-
-    return true;
-  }
-};
-
-// This class checks if an URL is valid on the main thread.
-class IsValidURLRunnable : public WorkerMainThreadRunnable
-{
-private:
-  const nsString mURL;
-  bool mValid;
-
-public:
-  IsValidURLRunnable(WorkerPrivate* aWorkerPrivate,
-                     const nsAString& aURL)
-  : WorkerMainThreadRunnable(aWorkerPrivate,
-                             NS_LITERAL_CSTRING("URL :: IsValidURL"))
-  , mURL(aURL)
-  , mValid(false)
-  {}
-
-  bool
-  MainThreadRun()
-  {
-    AssertIsOnMainThread();
-
-    NS_ConvertUTF16toUTF8 url(mURL);
-    mValid = nsHostObjectProtocolHandler::HasDataEntry(url);
-
-    return true;
-  }
-
-  bool
-  IsValidURL() const
-  {
-    return mValid;
-  }
-};
-
-// This class creates a URL object on the main thread.
-class ConstructorRunnable : public WorkerMainThreadRunnable
-{
-private:
-  const nsString mURL;
-
-  nsString mBase; // IsVoid() if we have no base URI string.
-  RefPtr<URLProxy> mBaseProxy;
-
-  RefPtr<URLProxy> mRetval;
-
-public:
-  ConstructorRunnable(WorkerPrivate* aWorkerPrivate,
-                      const nsAString& aURL, const Optional<nsAString>& aBase)
-  : WorkerMainThreadRunnable(aWorkerPrivate,
-                             NS_LITERAL_CSTRING("URL :: Constructor"))
-  , mURL(aURL)
-  {
-    if (aBase.WasPassed()) {
-      mBase = aBase.Value();
-    } else {
-      mBase.SetIsVoid(true);
-    }
-    mWorkerPrivate->AssertIsOnWorkerThread();
-  }
-
-  ConstructorRunnable(WorkerPrivate* aWorkerPrivate,
-                      const nsAString& aURL, URLProxy* aBaseProxy)
-  : WorkerMainThreadRunnable(aWorkerPrivate,
-                             NS_LITERAL_CSTRING("URL :: Constructor with BaseURL"))
-  , mURL(aURL)
-  , mBaseProxy(aBaseProxy)
-  {
-    mBase.SetIsVoid(true);
-    mWorkerPrivate->AssertIsOnWorkerThread();
-  }
-
-  bool
-  MainThreadRun()
-  {
-    AssertIsOnMainThread();
-
-    ErrorResult rv;
-    RefPtr<URLMainThread> url;
-    if (mBaseProxy) {
-      url = URLMainThread::Constructor(nullptr, mURL, mBaseProxy->URI(), rv);
-    } else if (!mBase.IsVoid()) {
-      url = URLMainThread::Constructor(nullptr, mURL, mBase, rv);
-    } else {
-      url = URLMainThread::Constructor(nullptr, mURL, nullptr, rv);
-    }
-
-    if (rv.Failed()) {
-      rv.SuppressException();
-      return true;
-    }
-
-    mRetval = new URLProxy(url.forget());
-    return true;
-  }
-
-  URLProxy*
-  GetURLProxy(ErrorResult& aRv) const
-  {
-    MOZ_ASSERT(mWorkerPrivate);
-    mWorkerPrivate->AssertIsOnWorkerThread();
-
-    if (!mRetval) {
-      aRv.ThrowTypeError<MSG_INVALID_URL>(mURL);
-    }
-
-    return mRetval;
-  }
-};
-
-class TeardownURLRunnable : public Runnable
-{
-public:
-  explicit TeardownURLRunnable(URLProxy* aURLProxy)
-    : mURLProxy(aURLProxy)
-  {
-  }
-
-  NS_IMETHOD Run()
-  {
-    AssertIsOnMainThread();
-
-    mURLProxy->ReleaseURI();
-    mURLProxy = nullptr;
-
-    return NS_OK;
-  }
-
-private:
-  RefPtr<URLProxy> mURLProxy;
-};
-
-// This class is the generic getter for any URL property.
-class GetterRunnable : public WorkerMainThreadRunnable
-{
-public:
-  enum GetterType {
-    GetterHref,
-    GetterOrigin,
-    GetterProtocol,
-    GetterUsername,
-    GetterPassword,
-    GetterHost,
-    GetterHostname,
-    GetterPort,
-    GetterPathname,
-    GetterSearch,
-    GetterHash,
-  };
-
-  GetterRunnable(WorkerPrivate* aWorkerPrivate,
-                 GetterType aType, nsAString& aValue,
-                 URLProxy* aURLProxy)
-  : WorkerMainThreadRunnable(aWorkerPrivate,
-                             // We can have telemetry keys for each getter when
-                             // needed.
-                             NS_LITERAL_CSTRING("URL :: getter"))
-  , mValue(aValue)
-  , mType(aType)
-  , mURLProxy(aURLProxy)
-  {
-    mWorkerPrivate->AssertIsOnWorkerThread();
-  }
-
-  bool
-  MainThreadRun()
-  {
-    AssertIsOnMainThread();
-    ErrorResult rv;
-
-    switch (mType) {
-      case GetterHref:
-        mURLProxy->URL()->GetHref(mValue, rv);
-        break;
-
-      case GetterOrigin:
-        mURLProxy->URL()->GetOrigin(mValue, rv);
-        break;
-
-      case GetterProtocol:
-        mURLProxy->URL()->GetProtocol(mValue, rv);
-        break;
-
-      case GetterUsername:
-        mURLProxy->URL()->GetUsername(mValue, rv);
-        break;
-
-      case GetterPassword:
-        mURLProxy->URL()->GetPassword(mValue, rv);
-        break;
-
-      case GetterHost:
-        mURLProxy->URL()->GetHost(mValue, rv);
-        break;
-
-      case GetterHostname:
-        mURLProxy->URL()->GetHostname(mValue, rv);
-        break;
-
-      case GetterPort:
-        mURLProxy->URL()->GetPort(mValue, rv);
-        break;
-
-      case GetterPathname:
-        mURLProxy->URL()->GetPathname(mValue, rv);
-        break;
-
-      case GetterSearch:
-        mURLProxy->URL()->GetSearch(mValue, rv);
-        break;
-
-      case GetterHash:
-        mURLProxy->URL()->GetHash(mValue, rv);
-        break;
-    }
-
-    MOZ_ASSERT(!rv.Failed(), "Main-thread getters do not fail.");
-    return true;
-  }
-
-  void
-  Dispatch(ErrorResult& aRv)
-  {
-    WorkerMainThreadRunnable::Dispatch(Terminating, aRv);
-  }
-
-private:
-  nsAString& mValue;
-  GetterType mType;
-  RefPtr<URLProxy> mURLProxy;
-};
-
-// This class is the generic setter for any URL property.
-class SetterRunnable : public WorkerMainThreadRunnable
-{
-public:
-  enum SetterType {
-    SetterHref,
-    SetterProtocol,
-    SetterUsername,
-    SetterPassword,
-    SetterHost,
-    SetterHostname,
-    SetterPort,
-    SetterPathname,
-    SetterSearch,
-    SetterHash,
-  };
-
-  SetterRunnable(WorkerPrivate* aWorkerPrivate,
-                 SetterType aType, const nsAString& aValue,
-                 URLProxy* aURLProxy)
-  : WorkerMainThreadRunnable(aWorkerPrivate,
-                             // We can have telemetry keys for each setter when
-                             // needed.
-                             NS_LITERAL_CSTRING("URL :: setter"))
-  , mValue(aValue)
-  , mType(aType)
-  , mURLProxy(aURLProxy)
-  , mFailed(false)
-  {
-    mWorkerPrivate->AssertIsOnWorkerThread();
-  }
-
-  bool
-  MainThreadRun()
-  {
-    AssertIsOnMainThread();
-    ErrorResult rv;
-
-    switch (mType) {
-      case SetterHref: {
-        mURLProxy->URL()->SetHref(mValue, rv);
-        break;
-      }
-
-      case SetterProtocol:
-        mURLProxy->URL()->SetProtocol(mValue, rv);
-        break;
-
-      case SetterUsername:
-        mURLProxy->URL()->SetUsername(mValue, rv);
-        break;
-
-      case SetterPassword:
-        mURLProxy->URL()->SetPassword(mValue, rv);
-        break;
-
-      case SetterHost:
-        mURLProxy->URL()->SetHost(mValue, rv);
-        break;
-
-      case SetterHostname:
-        mURLProxy->URL()->SetHostname(mValue, rv);
-        break;
-
-      case SetterPort:
-        mURLProxy->URL()->SetPort(mValue, rv);
-        break;
-
-      case SetterPathname:
-        mURLProxy->URL()->SetPathname(mValue, rv);
-        break;
-
-      case SetterSearch:
-        mURLProxy->URL()->SetSearch(mValue, rv);
-        break;
-
-      case SetterHash:
-        mURLProxy->URL()->SetHash(mValue, rv);
-        break;
-    }
-
-    if (NS_WARN_IF(rv.Failed())) {
-      rv.SuppressException();
-      mFailed = true;
-    }
-
-    return true;
-  }
-
-  bool Failed() const
-  {
-    return mFailed;
-  }
-
-  void
-  Dispatch(ErrorResult& aRv)
-  {
-    WorkerMainThreadRunnable::Dispatch(Terminating, aRv);
-  }
-
-private:
-  const nsString mValue;
-  SetterType mType;
-  RefPtr<URLProxy> mURLProxy;
-  bool mFailed;
-};
-
-already_AddRefed<URLWorker>
-FinishConstructor(JSContext* aCx, WorkerPrivate* aPrivate,
-                  ConstructorRunnable* aRunnable, ErrorResult& aRv)
-{
-  aRunnable->Dispatch(Terminating, aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return nullptr;
-  }
-
-  RefPtr<URLProxy> proxy = aRunnable->GetURLProxy(aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return nullptr;
-  }
-
-  RefPtr<URLWorker> url = new URLWorker(aPrivate, proxy);
-  return url.forget();
-}
-
-/* static */ already_AddRefed<URLWorker>
-URLWorker::Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-                       URL& aBase, ErrorResult& aRv)
-{
-  MOZ_ASSERT(!NS_IsMainThread());
-
-  JSContext* cx = aGlobal.Context();
-  WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
-
-  URLWorker& base = static_cast<URLWorker&>(aBase);
-  RefPtr<ConstructorRunnable> runnable =
-    new ConstructorRunnable(workerPrivate, aURL, base.GetURLProxy());
-
-  return FinishConstructor(cx, workerPrivate, runnable, aRv);
-}
-
-/* static */ already_AddRefed<URLWorker>
-URLWorker::Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-                       const Optional<nsAString>& aBase, ErrorResult& aRv)
-{
-  JSContext* cx = aGlobal.Context();
-  WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
-
-  RefPtr<ConstructorRunnable> runnable =
-    new ConstructorRunnable(workerPrivate, aURL, aBase);
-
-  return FinishConstructor(cx, workerPrivate, runnable, aRv);
-}
-
-/* static */ already_AddRefed<URLWorker>
-URLWorker::Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-                       const nsAString& aBase, ErrorResult& aRv)
-{
-  JSContext* cx = aGlobal.Context();
-  WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
-
-  Optional<nsAString> base;
-  base = &aBase;
-
-  RefPtr<ConstructorRunnable> runnable =
-    new ConstructorRunnable(workerPrivate, aURL, base);
-
-  return FinishConstructor(cx, workerPrivate, runnable, aRv);
-}
-
-/* static */ void
-URLWorker::CreateObjectURL(const GlobalObject& aGlobal, Blob& aBlob,
-                           nsAString& aResult, mozilla::ErrorResult& aRv)
-{
-  JSContext* cx = aGlobal.Context();
-  WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
-
-  RefPtr<BlobImpl> blobImpl = aBlob.Impl();
-  MOZ_ASSERT(blobImpl);
-
-  aRv = blobImpl->SetMutable(false);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  RefPtr<CreateURLRunnable> runnable =
-    new CreateURLRunnable(workerPrivate, blobImpl, aResult);
-
-  runnable->Dispatch(Terminating, aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  if (workerPrivate->IsSharedWorker() || workerPrivate->IsServiceWorker()) {
-    WorkerGlobalScope* scope = workerPrivate->GlobalScope();
-    MOZ_ASSERT(scope);
-
-    scope->RegisterHostObjectURI(NS_ConvertUTF16toUTF8(aResult));
-  }
-}
-
-/* static */ void
-URLWorker::RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aUrl,
-                           ErrorResult& aRv)
-{
-  JSContext* cx = aGlobal.Context();
-  WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
-
-  RefPtr<RevokeURLRunnable> runnable =
-    new RevokeURLRunnable(workerPrivate, aUrl);
-
-  runnable->Dispatch(Terminating, aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  if (workerPrivate->IsSharedWorker() || workerPrivate->IsServiceWorker()) {
-    WorkerGlobalScope* scope = workerPrivate->GlobalScope();
-    MOZ_ASSERT(scope);
-
-    scope->UnregisterHostObjectURI(NS_ConvertUTF16toUTF8(aUrl));
-  }
-}
-
-/* static */ bool
-URLWorker::IsValidURL(const GlobalObject& aGlobal, const nsAString& aUrl,
-                      ErrorResult& aRv)
-{
-  JSContext* cx = aGlobal.Context();
-  WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
-
-  RefPtr<IsValidURLRunnable> runnable =
-    new IsValidURLRunnable(workerPrivate, aUrl);
-
-  runnable->Dispatch(Terminating, aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return false;
-  }
-
-  return runnable->IsValidURL();
-}
-
-URLWorker::URLWorker(WorkerPrivate* aWorkerPrivate, URLProxy* aURLProxy)
-  : URL(nullptr)
-  , mWorkerPrivate(aWorkerPrivate)
-  , mURLProxy(aURLProxy)
-{}
-
-URLWorker::~URLWorker()
-{
-  if (mURLProxy) {
-    mWorkerPrivate->AssertIsOnWorkerThread();
-
-    RefPtr<TeardownURLRunnable> runnable =
-      new TeardownURLRunnable(mURLProxy);
-    mURLProxy = nullptr;
-
-    if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
-      NS_ERROR("Failed to dispatch teardown runnable!");
-    }
-  }
-}
-
-void
-URLWorker::GetHref(nsAString& aHref, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHref, aHref,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URLWorker::SetHref(const nsAString& aHref, ErrorResult& aRv)
-{
-  RefPtr<SetterRunnable> runnable =
-    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHref, aHref,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  if (runnable->Failed()) {
-    aRv.ThrowTypeError<MSG_INVALID_URL>(aHref);
-    return;
-  }
-
-  UpdateURLSearchParams();
-}
-
-void
-URLWorker::GetOrigin(nsAString& aOrigin, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterOrigin, aOrigin,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URLWorker::GetProtocol(nsAString& aProtocol, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterProtocol, aProtocol,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URLWorker::SetProtocol(const nsAString& aProtocol, ErrorResult& aRv)
-{
-  RefPtr<SetterRunnable> runnable =
-    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterProtocol,
-                       aProtocol, mURLProxy);
-
-  runnable->Dispatch(aRv);
-
-  MOZ_ASSERT(!runnable->Failed());
-}
-
-void
-URLWorker::GetUsername(nsAString& aUsername, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterUsername, aUsername,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URLWorker::SetUsername(const nsAString& aUsername, ErrorResult& aRv)
-{
-  RefPtr<SetterRunnable> runnable =
-    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterUsername,
-                       aUsername, mURLProxy);
-
-  runnable->Dispatch(aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  MOZ_ASSERT(!runnable->Failed());
-}
-
-void
-URLWorker::GetPassword(nsAString& aPassword, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterPassword, aPassword,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URLWorker::SetPassword(const nsAString& aPassword, ErrorResult& aRv)
-{
-  RefPtr<SetterRunnable> runnable =
-    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterPassword,
-                       aPassword, mURLProxy);
-
-  runnable->Dispatch(aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  MOZ_ASSERT(!runnable->Failed());
-}
-
-void
-URLWorker::GetHost(nsAString& aHost, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHost, aHost,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URLWorker::SetHost(const nsAString& aHost, ErrorResult& aRv)
-{
-  RefPtr<SetterRunnable> runnable =
-    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHost,
-                       aHost, mURLProxy);
-
-  runnable->Dispatch(aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  MOZ_ASSERT(!runnable->Failed());
-}
-
-void
-URLWorker::GetHostname(nsAString& aHostname, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHostname, aHostname,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URLWorker::SetHostname(const nsAString& aHostname, ErrorResult& aRv)
-{
-  RefPtr<SetterRunnable> runnable =
-    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHostname,
-                       aHostname, mURLProxy);
-
-  runnable->Dispatch(aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  MOZ_ASSERT(!runnable->Failed());
-}
-
-void
-URLWorker::GetPort(nsAString& aPort, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterPort, aPort,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URLWorker::SetPort(const nsAString& aPort, ErrorResult& aRv)
-{
-  RefPtr<SetterRunnable> runnable =
-    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterPort,
-                       aPort, mURLProxy);
-
-  runnable->Dispatch(aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  MOZ_ASSERT(!runnable->Failed());
-}
-
-void
-URLWorker::GetPathname(nsAString& aPathname, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterPathname,
-                       aPathname, mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URLWorker::SetPathname(const nsAString& aPathname, ErrorResult& aRv)
-{
-  RefPtr<SetterRunnable> runnable =
-    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterPathname,
-                       aPathname, mURLProxy);
-
-  runnable->Dispatch(aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  MOZ_ASSERT(!runnable->Failed());
-}
-
-void
-URLWorker::GetSearch(nsAString& aSearch, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterSearch, aSearch,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URLWorker::GetHash(nsAString& aHash, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHash, aHash,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URLWorker::SetHash(const nsAString& aHash, ErrorResult& aRv)
-{
-  RefPtr<SetterRunnable> runnable =
-    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHash,
-                       aHash, mURLProxy);
-
-  runnable->Dispatch(aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  MOZ_ASSERT(!runnable->Failed());
-}
-
-void
-URLWorker::SetSearchInternal(const nsAString& aSearch, ErrorResult& aRv)
-{
-  RefPtr<SetterRunnable> runnable =
-    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterSearch,
-                       aSearch, mURLProxy);
-
-  runnable->Dispatch(aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  MOZ_ASSERT(!runnable->Failed());
-}
-
-void
-URLWorker::UpdateURLSearchParams()
-{
-  if (mSearchParams) {
-    nsAutoString search;
-
-    ErrorResult rv;
-    GetSearch(search, rv);
-    if (NS_WARN_IF(rv.Failed())) {
-      rv.SuppressException();
-    }
-
-    mSearchParams->ParseInput(NS_ConvertUTF16toUTF8(Substring(search, 1)));
-  }
-}
-
-} // anonymous namespace
-
-///////////////////////////////////////////////////////////////////////////////
-// Base class for URL
-///////////////////////////////////////////////////////////////////////////////
-
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(URL, mParent, mSearchParams)
-
-NS_IMPL_CYCLE_COLLECTING_ADDREF(URL)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(URL)
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(URL)
-  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
-  NS_INTERFACE_MAP_ENTRY(nsISupports)
-NS_INTERFACE_MAP_END
-
-JSObject*
-URL::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
-{
-  return URLBinding::Wrap(aCx, this, aGivenProto);
-}
-
-/* static */ already_AddRefed<URL>
-URL::Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-                 URL& aBase, ErrorResult& aRv)
-{
-  if (NS_IsMainThread()) {
-    return URLMainThread::Constructor(aGlobal, aURL, aBase, aRv);
-  }
-
-  return URLWorker::Constructor(aGlobal, aURL, aBase, aRv);
-}
-
-/* static */ already_AddRefed<URL>
-URL::Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-                 const Optional<nsAString>& aBase, ErrorResult& aRv)
-{
-  if (NS_IsMainThread()) {
-    return URLMainThread::Constructor(aGlobal, aURL, aBase, aRv);
-  }
-
-  return URLWorker::Constructor(aGlobal, aURL, aBase, aRv);
-}
-
-/* static */ already_AddRefed<URL>
-URL::WorkerConstructor(const GlobalObject& aGlobal, const nsAString& aURL,
-                       const nsAString& aBase, ErrorResult& aRv)
-{
-  return URLWorker::Constructor(aGlobal, aURL, aBase, aRv);
-}
-
-void
-URL::CreateObjectURL(const GlobalObject& aGlobal, Blob& aBlob,
-                     nsAString& aResult, ErrorResult& aRv)
-{
-  if (NS_IsMainThread()) {
-    URLMainThread::CreateObjectURL(aGlobal, aBlob, aResult, aRv);
-  } else {
-    URLWorker::CreateObjectURL(aGlobal, aBlob, aResult, aRv);
-  }
-}
-
-void
-URL::CreateObjectURL(const GlobalObject& aGlobal, DOMMediaStream& aStream,
-                     nsAString& aResult, ErrorResult& aRv)
+nsIURI*
+URLMainThread::GetURI() const
 {
   MOZ_ASSERT(NS_IsMainThread());
-
-  DeprecationWarning(aGlobal, nsIDocument::eURLCreateObjectURL_MediaStream);
-
-  URLMainThread::CreateObjectURL(aGlobal, aStream, aResult, aRv);
-}
-
-void
-URL::CreateObjectURL(const GlobalObject& aGlobal, MediaSource& aSource,
-                     nsAString& aResult, ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  URLMainThread::CreateObjectURL(aGlobal, aSource, aResult, aRv);
-}
-
-void
-URL::RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aURL,
-                     ErrorResult& aRv)
-{
-  if (NS_IsMainThread()) {
-    URLMainThread::RevokeObjectURL(aGlobal, aURL, aRv);
-  } else {
-    URLWorker::RevokeObjectURL(aGlobal, aURL, aRv);
-  }
-}
-
-bool
-URL::IsValidURL(const GlobalObject& aGlobal, const nsAString& aURL,
-                ErrorResult& aRv)
-{
-  if (NS_IsMainThread()) {
-    return URLMainThread::IsValidURL(aGlobal, aURL, aRv);
-  }
-  return URLWorker::IsValidURL(aGlobal, aURL, aRv);
-}
-
-URLSearchParams*
-URL::SearchParams()
-{
-  CreateSearchParamsIfNeeded();
-  return mSearchParams;
-}
-
-bool IsChromeURI(nsIURI* aURI)
-{
-  bool isChrome = false;
-  if (NS_SUCCEEDED(aURI->SchemeIs("chrome", &isChrome)))
-      return isChrome;
-  return false;
-}
-
-void
-URL::CreateSearchParamsIfNeeded()
-{
-  if (!mSearchParams) {
-    mSearchParams = new URLSearchParams(mParent, this);
-    UpdateURLSearchParams();
-  }
-}
-
-void
-URL::SetSearch(const nsAString& aSearch, ErrorResult& aRv)
-{
-  SetSearchInternal(aSearch, aRv);
-  UpdateURLSearchParams();
-}
-
-void
-URL::URLSearchParamsUpdated(URLSearchParams* aSearchParams)
-{
-  MOZ_ASSERT(mSearchParams);
-  MOZ_ASSERT(mSearchParams == aSearchParams);
-
-  nsAutoString search;
-  mSearchParams->Serialize(search);
-
-  ErrorResult rv;
-  SetSearchInternal(search, rv);
-  NS_WARNING_ASSERTION(!rv.Failed(), "SetSearchInternal failed");
-  rv.SuppressException();
+  return mURI;
 }
 
 } // namespace dom
 } // namespace mozilla
copy from dom/url/URL.cpp
copy to dom/url/URLMainThread.h
--- a/dom/url/URL.cpp
+++ b/dom/url/URLMainThread.h
@@ -1,120 +1,59 @@
 /* -*- 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 "URL.h"
+#ifndef mozilla_dom_URLMainThread_h
+#define mozilla_dom_URLMainThread_h
 
-#include "DOMMediaStream.h"
-#include "mozilla/dom/File.h"
-#include "mozilla/dom/MediaSource.h"
-#include "mozilla/dom/URLBinding.h"
-#include "mozilla/ipc/BackgroundChild.h"
-#include "nsContentUtils.h"
-#include "nsEscape.h"
-#include "nsHostObjectProtocolHandler.h"
-#include "nsIIOService.h"
-#include "nsIURL.h"
-#include "nsNetCID.h"
-#include "nsNetUtil.h"
-#include "nsServiceManagerUtils.h"
-#include "WorkerPrivate.h"
-#include "WorkerRunnable.h"
-#include "WorkerScope.h"
+#include "URL.h"
 
 namespace mozilla {
 namespace dom {
 
-///////////////////////////////////////////////////////////////////////////////
-// URL for main-thread
-///////////////////////////////////////////////////////////////////////////////
-
-namespace {
-
-template<typename T>
-void
-CreateObjectURLInternal(const GlobalObject& aGlobal, T aObject,
-                        nsAString& aResult, ErrorResult& aRv)
-{
-  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
-  if (NS_WARN_IF(!global)) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return;
-  }
-
-  nsCOMPtr<nsIPrincipal> principal =
-    nsContentUtils::ObjectPrincipal(aGlobal.Get());
-
-  nsAutoCString url;
-  aRv = nsHostObjectProtocolHandler::AddDataEntry(aObject, principal, url);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  global->RegisterHostObjectURI(url);
-  CopyASCIItoUTF16(url, aResult);
-}
-
 // The URL implementation for the main-thread
 class URLMainThread final : public URL
 {
 public:
   static already_AddRefed<URLMainThread>
   Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-              URL& aBase, ErrorResult& aRv);
-
-  static already_AddRefed<URLMainThread>
-  Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
               const Optional<nsAString>& aBase, ErrorResult& aRv);
 
   static already_AddRefed<URLMainThread>
   Constructor(nsISupports* aParent, const nsAString& aURL,
               const nsAString& aBase, ErrorResult& aRv);
 
   static already_AddRefed<URLMainThread>
   Constructor(nsISupports* aParent, const nsAString& aURL, nsIURI* aBase,
               ErrorResult& aRv);
 
   static void
   CreateObjectURL(const GlobalObject& aGlobal, Blob& aBlob,
-                  nsAString& aResult, ErrorResult& aRv)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-    CreateObjectURLInternal(aGlobal, aBlob.Impl(), aResult, aRv);
-  }
+                  nsAString& aResult, ErrorResult& aRv);
 
   static void
   CreateObjectURL(const GlobalObject& aGlobal, DOMMediaStream& aStream,
-                  nsAString& aResult, ErrorResult& aRv)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-    CreateObjectURLInternal(aGlobal, &aStream, aResult, aRv);
-  }
+                  nsAString& aResult, ErrorResult& aRv);
 
   static void
   CreateObjectURL(const GlobalObject& aGlobal, MediaSource& aSource,
                   nsAString& aResult, ErrorResult& aRv);
 
   static void
   RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aURL,
                   ErrorResult& aRv);
 
   static bool
   IsValidURL(const GlobalObject& aGlobal, const nsAString& aURL,
              ErrorResult& aRv);
 
-  URLMainThread(nsISupports* aParent, already_AddRefed<nsIURI> aURI)
-    : URL(aParent)
-    , mURI(aURI)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-  }
+  URLMainThread(nsISupports* aParent, already_AddRefed<nsIURI> aURI);
 
   virtual void
   GetHref(nsAString& aHref, ErrorResult& aRv) const override;
 
   virtual void
   SetHref(const nsAString& aHref, ErrorResult& aRv) override;
 
   virtual void
@@ -172,1612 +111,20 @@ public:
   SetHash(const nsAString& aHash, ErrorResult& aRv) override;
 
   virtual void UpdateURLSearchParams() override;
 
   virtual void
   SetSearchInternal(const nsAString& aSearch, ErrorResult& aRv) override;
 
   nsIURI*
-  GetURI() const
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-    return mURI;
-  }
+  GetURI() const;
 
 private:
-  ~URLMainThread()
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-  }
+  ~URLMainThread();
 
   nsCOMPtr<nsIURI> mURI;
 };
 
-/* static */ already_AddRefed<URLMainThread>
-URLMainThread::Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-                           URL& aBase, ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  URLMainThread& base = static_cast<URLMainThread&>(aBase);
-  return Constructor(aGlobal.GetAsSupports(), aURL, base.GetURI(), aRv);
-}
-
-/* static */ already_AddRefed<URLMainThread>
-URLMainThread::Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-                           const Optional<nsAString>& aBase, ErrorResult& aRv)
-{
-  if (aBase.WasPassed()) {
-    return Constructor(aGlobal.GetAsSupports(), aURL, aBase.Value(), aRv);
-  }
-
-  return Constructor(aGlobal.GetAsSupports(), aURL, nullptr, aRv);
-}
-
-/* static */ already_AddRefed<URLMainThread>
-URLMainThread::Constructor(nsISupports* aParent, const nsAString& aURL,
-                           const nsAString& aBase, ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  nsCOMPtr<nsIURI> baseUri;
-  nsresult rv = NS_NewURI(getter_AddRefs(baseUri), aBase, nullptr, nullptr,
-                          nsContentUtils::GetIOService());
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    aRv.ThrowTypeError<MSG_INVALID_URL>(aBase);
-    return nullptr;
-  }
-
-  return Constructor(aParent, aURL, baseUri, aRv);
-}
-
-/* static */ already_AddRefed<URLMainThread>
-URLMainThread::Constructor(nsISupports* aParent, const nsAString& aURL,
-                           nsIURI* aBase, ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  nsCOMPtr<nsIURI> uri;
-  nsresult rv = NS_NewURI(getter_AddRefs(uri), aURL, nullptr, aBase,
-                          nsContentUtils::GetIOService());
-  if (NS_FAILED(rv)) {
-    // No need to warn in this case. It's common to use the URL constructor
-    // to determine if a URL is valid and an exception will be propagated.
-    aRv.ThrowTypeError<MSG_INVALID_URL>(aURL);
-    return nullptr;
-  }
-
-  RefPtr<URLMainThread> url = new URLMainThread(aParent, uri.forget());
-  return url.forget();
-}
-
-/* static */ void
-URLMainThread::CreateObjectURL(const GlobalObject& aGlobal,
-                               MediaSource& aSource,
-                               nsAString& aResult, ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  nsCOMPtr<nsIPrincipal> principal =
-    nsContentUtils::ObjectPrincipal(aGlobal.Get());
-
-  nsAutoCString url;
-  aRv = nsHostObjectProtocolHandler::AddDataEntry(&aSource, principal, url);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  nsCOMPtr<nsIRunnable> revocation = NS_NewRunnableFunction(
-    [url] {
-      nsHostObjectProtocolHandler::RemoveDataEntry(url);
-    });
-
-  nsContentUtils::RunInStableState(revocation.forget());
-
-  CopyASCIItoUTF16(url, aResult);
-}
-
-/* static */ void
-URLMainThread::RevokeObjectURL(const GlobalObject& aGlobal,
-                               const nsAString& aURL, ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
-  if (!global) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return;
-  }
-
-  nsIPrincipal* principal = nsContentUtils::ObjectPrincipal(aGlobal.Get());
-
-  NS_LossyConvertUTF16toASCII asciiurl(aURL);
-
-  nsIPrincipal* urlPrincipal =
-    nsHostObjectProtocolHandler::GetDataEntryPrincipal(asciiurl);
-
-  if (urlPrincipal && principal->Subsumes(urlPrincipal)) {
-    global->UnregisterHostObjectURI(asciiurl);
-    nsHostObjectProtocolHandler::RemoveDataEntry(asciiurl);
-  }
-}
-
-/* static */ bool
-URLMainThread::IsValidURL(const GlobalObject& aGlobal, const nsAString& aURL,
-                          ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  NS_LossyConvertUTF16toASCII asciiurl(aURL);
-  return nsHostObjectProtocolHandler::HasDataEntry(asciiurl);
-}
-
-void
-URLMainThread::GetHref(nsAString& aHref, ErrorResult& aRv) const
-{
-  aHref.Truncate();
-
-  nsAutoCString href;
-  nsresult rv = mURI->GetSpec(href);
-  if (NS_SUCCEEDED(rv)) {
-    CopyUTF8toUTF16(href, aHref);
-  }
-}
-
-void
-URLMainThread::SetHref(const nsAString& aHref, ErrorResult& aRv)
-{
-  NS_ConvertUTF16toUTF8 href(aHref);
-
-  nsresult rv;
-  nsCOMPtr<nsIIOService> ioService(do_GetService(NS_IOSERVICE_CONTRACTID, &rv));
-  if (NS_FAILED(rv)) {
-    aRv.Throw(rv);
-    return;
-  }
-
-  nsCOMPtr<nsIURI> uri;
-  rv = ioService->NewURI(href, nullptr, nullptr, getter_AddRefs(uri));
-  if (NS_FAILED(rv)) {
-    aRv.ThrowTypeError<MSG_INVALID_URL>(aHref);
-    return;
-  }
-
-  mURI = uri;
-  UpdateURLSearchParams();
-}
-
-void
-URLMainThread::GetOrigin(nsAString& aOrigin, ErrorResult& aRv) const
-{
-  nsContentUtils::GetUTFOrigin(mURI, aOrigin);
-}
-
-void
-URLMainThread::GetProtocol(nsAString& aProtocol, ErrorResult& aRv) const
-{
-  nsAutoCString protocol;
-  if (NS_SUCCEEDED(mURI->GetScheme(protocol))) {
-    aProtocol.Truncate();
-  }
-
-  CopyASCIItoUTF16(protocol, aProtocol);
-  aProtocol.Append(char16_t(':'));
-}
-
-void
-URLMainThread::SetProtocol(const nsAString& aProtocol, ErrorResult& aRv)
-{
-  nsAString::const_iterator start, end;
-  aProtocol.BeginReading(start);
-  aProtocol.EndReading(end);
-  nsAString::const_iterator iter(start);
-
-  FindCharInReadable(':', iter, end);
-
-  // Changing the protocol of a URL, changes the "nature" of the URI
-  // implementation. In order to do this properly, we have to serialize the
-  // existing URL and reparse it in a new object.
-  nsCOMPtr<nsIURI> clone;
-  nsresult rv = mURI->Clone(getter_AddRefs(clone));
-  if (NS_WARN_IF(NS_FAILED(rv)) || !clone) {
-    return;
-  }
-
-  rv = clone->SetScheme(NS_ConvertUTF16toUTF8(Substring(start, iter)));
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return;
-  }
-
-  nsAutoCString href;
-  rv = clone->GetSpec(href);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return;
-  }
-
-  nsCOMPtr<nsIURI> uri;
-  rv = NS_NewURI(getter_AddRefs(uri), href);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return;
-  }
-
-  mURI = uri;
-}
-
-#define URL_GETTER( value, func ) \
-  value.Truncate();               \
-  nsAutoCString tmp;              \
-  nsresult rv = mURI->func(tmp);  \
-  if (NS_SUCCEEDED(rv)) {         \
-    CopyUTF8toUTF16(tmp, value);  \
-  }
-
-void
-URLMainThread::GetUsername(nsAString& aUsername, ErrorResult& aRv) const
-{
-  URL_GETTER(aUsername, GetUsername);
-}
-
-void
-URLMainThread::SetUsername(const nsAString& aUsername, ErrorResult& aRv)
-{
-  mURI->SetUsername(NS_ConvertUTF16toUTF8(aUsername));
-}
-
-void
-URLMainThread::GetPassword(nsAString& aPassword, ErrorResult& aRv) const
-{
-  URL_GETTER(aPassword, GetPassword);
-}
-
-void
-URLMainThread::SetPassword(const nsAString& aPassword, ErrorResult& aRv)
-{
-  mURI->SetPassword(NS_ConvertUTF16toUTF8(aPassword));
-}
-
-void
-URLMainThread::GetHost(nsAString& aHost, ErrorResult& aRv) const
-{
-  URL_GETTER(aHost, GetHostPort);
-}
-
-void
-URLMainThread::SetHost(const nsAString& aHost, ErrorResult& aRv)
-{
-  mURI->SetHostPort(NS_ConvertUTF16toUTF8(aHost));
-}
-
-void
-URLMainThread::UpdateURLSearchParams()
-{
-  if (!mSearchParams) {
-    return;
-  }
-
-  nsAutoCString search;
-  nsCOMPtr<nsIURL> url(do_QueryInterface(mURI));
-  if (url) {
-    nsresult rv = url->GetQuery(search);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      search.Truncate();
-    }
-  }
-
-  mSearchParams->ParseInput(search);
-}
-
-void
-URLMainThread::GetHostname(nsAString& aHostname, ErrorResult& aRv) const
-{
-  aHostname.Truncate();
-  nsContentUtils::GetHostOrIPv6WithBrackets(mURI, aHostname);
-}
-
-void
-URLMainThread::SetHostname(const nsAString& aHostname, ErrorResult& aRv)
-{
-  // nsStandardURL returns NS_ERROR_UNEXPECTED for an empty hostname
-  // The return code is silently ignored
-  mURI->SetHost(NS_ConvertUTF16toUTF8(aHostname));
-}
-
-void
-URLMainThread::GetPort(nsAString& aPort, ErrorResult& aRv) const
-{
-  aPort.Truncate();
-
-  int32_t port;
-  nsresult rv = mURI->GetPort(&port);
-  if (NS_SUCCEEDED(rv) && port != -1) {
-    nsAutoString portStr;
-    portStr.AppendInt(port, 10);
-    aPort.Assign(portStr);
-  }
-}
-
-void
-URLMainThread::SetPort(const nsAString& aPort, ErrorResult& aRv)
-{
-  nsresult rv;
-  nsAutoString portStr(aPort);
-  int32_t port = -1;
-
-  // nsIURI uses -1 as default value.
-  if (!portStr.IsEmpty()) {
-    port = portStr.ToInteger(&rv);
-    if (NS_FAILED(rv)) {
-      return;
-    }
-  }
-
-  mURI->SetPort(port);
-}
-
-void
-URLMainThread::GetPathname(nsAString& aPathname, ErrorResult& aRv) const
-{
-  aPathname.Truncate();
-
-  // Do not throw!  Not having a valid URI or URL should result in an empty
-  // string.
-
-  nsAutoCString file;
-  nsresult rv = mURI->GetFilePath(file);
-  if (NS_SUCCEEDED(rv)) {
-    CopyUTF8toUTF16(file, aPathname);
-  }
-}
-
-void
-URLMainThread::SetPathname(const nsAString& aPathname, ErrorResult& aRv)
-{
-  // Do not throw!
-
-  mURI->SetFilePath(NS_ConvertUTF16toUTF8(aPathname));
-}
-
-void
-URLMainThread::GetSearch(nsAString& aSearch, ErrorResult& aRv) const
-{
-  aSearch.Truncate();
-
-  // Do not throw!  Not having a valid URI or URL should result in an empty
-  // string.
-
-  nsAutoCString search;
-  nsresult rv;
-
-  rv = mURI->GetQuery(search);
-  if (NS_SUCCEEDED(rv) && !search.IsEmpty()) {
-    CopyUTF8toUTF16(NS_LITERAL_CSTRING("?") + search, aSearch);
-  }
-}
-
-void
-URLMainThread::GetHash(nsAString& aHash, ErrorResult& aRv) const
-{
-  aHash.Truncate();
-
-  nsAutoCString ref;
-  nsresult rv = mURI->GetRef(ref);
-  if (NS_SUCCEEDED(rv) && !ref.IsEmpty()) {
-    aHash.Assign(char16_t('#'));
-    AppendUTF8toUTF16(ref, aHash);
-  }
-}
-
-void
-URLMainThread::SetHash(const nsAString& aHash, ErrorResult& aRv)
-{
-  mURI->SetRef(NS_ConvertUTF16toUTF8(aHash));
-}
-
-void
-URLMainThread::SetSearchInternal(const nsAString& aSearch, ErrorResult& aRv)
-{
-  // Ignore failures to be compatible with NS4.
-
-  mURI->SetQuery(NS_ConvertUTF16toUTF8(aSearch));
-}
-
-} // anonymous namespace
-
-///////////////////////////////////////////////////////////////////////////////
-// URL for Workers
-///////////////////////////////////////////////////////////////////////////////
-
-namespace {
-
-using namespace workers;
-
-// Proxy class to forward all the requests to a URLMainThread object.
-class URLProxy final
-{
-public:
-  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(URLProxy)
-
-  explicit URLProxy(already_AddRefed<URLMainThread> aURL)
-    : mURL(aURL)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-  }
-
-  URLMainThread* URL()
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-    return mURL;
-  }
-
-  nsIURI* URI()
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-    return mURL->GetURI();
-  }
-
-  void ReleaseURI()
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-    mURL = nullptr;
-  }
-
-private:
-  // Private destructor, to discourage deletion outside of Release():
-  ~URLProxy()
-  {
-     MOZ_ASSERT(!mURL);
-  }
-
-  RefPtr<URLMainThread> mURL;
-};
-
-// URLWorker implements the URL object in workers.
-class URLWorker final : public URL
-{
-public:
-  static already_AddRefed<URLWorker>
-  Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-              URL& aBase, ErrorResult& aRv);
-
-  static already_AddRefed<URLWorker>
-  Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-              const Optional<nsAString>& aBase, ErrorResult& aRv);
-
-  static already_AddRefed<URLWorker>
-  Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-              const nsAString& aBase, ErrorResult& aRv);
-
-  static void
-  CreateObjectURL(const GlobalObject& aGlobal, Blob& aBlob,
-                  nsAString& aResult, mozilla::ErrorResult& aRv);
-
-  static void
-  RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aUrl,
-                  ErrorResult& aRv);
-
-  static bool
-  IsValidURL(const GlobalObject& aGlobal, const nsAString& aUrl,
-             ErrorResult& aRv);
-
-  URLWorker(WorkerPrivate* aWorkerPrivate, URLProxy* aURLProxy);
-
-  virtual void
-  GetHref(nsAString& aHref, ErrorResult& aRv) const override;
-
-  virtual void
-  SetHref(const nsAString& aHref, ErrorResult& aRv) override;
-
-  virtual void
-  GetOrigin(nsAString& aOrigin, ErrorResult& aRv) const override;
-
-  virtual void
-  GetProtocol(nsAString& aProtocol, ErrorResult& aRv) const override;
-
-  virtual void
-  SetProtocol(const nsAString& aProtocol, ErrorResult& aRv) override;
-
-  virtual void
-  GetUsername(nsAString& aUsername, ErrorResult& aRv) const override;
-
-  virtual void
-  SetUsername(const nsAString& aUsername, ErrorResult& aRv) override;
-
-  virtual void
-  GetPassword(nsAString& aPassword, ErrorResult& aRv) const override;
-
-  virtual void
-  SetPassword(const nsAString& aPassword, ErrorResult& aRv) override;
-
-  virtual void
-  GetHost(nsAString& aHost, ErrorResult& aRv) const override;
-
-  virtual void
-  SetHost(const nsAString& aHost, ErrorResult& aRv) override;
-
-  virtual void
-  GetHostname(nsAString& aHostname, ErrorResult& aRv) const override;
-
-  virtual void
-  SetHostname(const nsAString& aHostname, ErrorResult& aRv) override;
-
-  virtual void
-  GetPort(nsAString& aPort, ErrorResult& aRv) const override;
-
-  virtual void
-  SetPort(const nsAString& aPort, ErrorResult& aRv) override;
-
-  virtual void
-  GetPathname(nsAString& aPathname, ErrorResult& aRv) const override;
-
-  virtual void
-  SetPathname(const nsAString& aPathname, ErrorResult& aRv) override;
-
-  virtual void
-  GetSearch(nsAString& aSearch, ErrorResult& aRv) const override;
-
-  virtual void
-  GetHash(nsAString& aHost, ErrorResult& aRv) const override;
-
-  virtual void
-  SetHash(const nsAString& aHash, ErrorResult& aRv) override;
-
-  virtual void UpdateURLSearchParams() override;
-
-  virtual void
-  SetSearchInternal(const nsAString& aSearch, ErrorResult& aRv) override;
-
-  URLProxy*
-  GetURLProxy() const
-  {
-    mWorkerPrivate->AssertIsOnWorkerThread();
-    return mURLProxy;
-  }
-
-private:
-  ~URLWorker();
-
-  workers::WorkerPrivate* mWorkerPrivate;
-  RefPtr<URLProxy> mURLProxy;
-};
-
-// This class creates an URL from a DOM Blob on the main thread.
-class CreateURLRunnable : public WorkerMainThreadRunnable
-{
-private:
-  BlobImpl* mBlobImpl;
-  nsAString& mURL;
-
-public:
-  CreateURLRunnable(WorkerPrivate* aWorkerPrivate, BlobImpl* aBlobImpl,
-                    nsAString& aURL)
-  : WorkerMainThreadRunnable(aWorkerPrivate,
-                             NS_LITERAL_CSTRING("URL :: CreateURL"))
-  , mBlobImpl(aBlobImpl)
-  , mURL(aURL)
-  {
-    MOZ_ASSERT(aBlobImpl);
-
-    DebugOnly<bool> isMutable;
-    MOZ_ASSERT(NS_SUCCEEDED(aBlobImpl->GetMutable(&isMutable)));
-    MOZ_ASSERT(!isMutable);
-  }
-
-  bool
-  MainThreadRun()
-  {
-    using namespace mozilla::ipc;
-
-    AssertIsOnMainThread();
-
-    DebugOnly<bool> isMutable;
-    MOZ_ASSERT(NS_SUCCEEDED(mBlobImpl->GetMutable(&isMutable)));
-    MOZ_ASSERT(!isMutable);
-
-    nsCOMPtr<nsIPrincipal> principal = mWorkerPrivate->GetPrincipal();
-
-    nsAutoCString url;
-    nsresult rv =
-      nsHostObjectProtocolHandler::AddDataEntry(mBlobImpl, principal, url);
-
-    if (NS_FAILED(rv)) {
-      NS_WARNING("Failed to add data entry for the blob!");
-      SetDOMStringToNull(mURL);
-      return false;
-    }
-
-    if (!mWorkerPrivate->IsSharedWorker() &&
-        !mWorkerPrivate->IsServiceWorker()) {
-      // Walk up to top worker object.
-      WorkerPrivate* wp = mWorkerPrivate;
-      while (WorkerPrivate* parent = wp->GetParent()) {
-        wp = parent;
-      }
-
-      nsCOMPtr<nsIScriptContext> sc = wp->GetScriptContext();
-      // We could not have a ScriptContext in JSM code. In this case, we leak.
-      if (sc) {
-        nsCOMPtr<nsIGlobalObject> global = sc->GetGlobalObject();
-        MOZ_ASSERT(global);
-
-        global->RegisterHostObjectURI(url);
-      }
-    }
-
-    mURL = NS_ConvertUTF8toUTF16(url);
-    return true;
-  }
-};
-
-// This class revokes an URL on the main thread.
-class RevokeURLRunnable : public WorkerMainThreadRunnable
-{
-private:
-  const nsString mURL;
-
-public:
-  RevokeURLRunnable(WorkerPrivate* aWorkerPrivate,
-                    const nsAString& aURL)
-  : WorkerMainThreadRunnable(aWorkerPrivate,
-                             NS_LITERAL_CSTRING("URL :: RevokeURL"))
-  , mURL(aURL)
-  {}
-
-  bool
-  MainThreadRun()
-  {
-    AssertIsOnMainThread();
-
-    NS_ConvertUTF16toUTF8 url(mURL);
-
-    nsIPrincipal* urlPrincipal =
-      nsHostObjectProtocolHandler::GetDataEntryPrincipal(url);
-
-    nsCOMPtr<nsIPrincipal> principal = mWorkerPrivate->GetPrincipal();
-
-    bool subsumes;
-    if (urlPrincipal &&
-        NS_SUCCEEDED(principal->Subsumes(urlPrincipal, &subsumes)) &&
-        subsumes) {
-      nsHostObjectProtocolHandler::RemoveDataEntry(url);
-    }
-
-    if (!mWorkerPrivate->IsSharedWorker() &&
-        !mWorkerPrivate->IsServiceWorker()) {
-      // Walk up to top worker object.
-      WorkerPrivate* wp = mWorkerPrivate;
-      while (WorkerPrivate* parent = wp->GetParent()) {
-        wp = parent;
-      }
-
-      nsCOMPtr<nsIScriptContext> sc = wp->GetScriptContext();
-      // We could not have a ScriptContext in JSM code. In this case, we leak.
-      if (sc) {
-        nsCOMPtr<nsIGlobalObject> global = sc->GetGlobalObject();
-        MOZ_ASSERT(global);
-
-        global->UnregisterHostObjectURI(url);
-      }
-    }
-
-    return true;
-  }
-};
-
-// This class checks if an URL is valid on the main thread.
-class IsValidURLRunnable : public WorkerMainThreadRunnable
-{
-private:
-  const nsString mURL;
-  bool mValid;
-
-public:
-  IsValidURLRunnable(WorkerPrivate* aWorkerPrivate,
-                     const nsAString& aURL)
-  : WorkerMainThreadRunnable(aWorkerPrivate,
-                             NS_LITERAL_CSTRING("URL :: IsValidURL"))
-  , mURL(aURL)
-  , mValid(false)
-  {}
-
-  bool
-  MainThreadRun()
-  {
-    AssertIsOnMainThread();
-
-    NS_ConvertUTF16toUTF8 url(mURL);
-    mValid = nsHostObjectProtocolHandler::HasDataEntry(url);
-
-    return true;
-  }
-
-  bool
-  IsValidURL() const
-  {
-    return mValid;
-  }
-};
-
-// This class creates a URL object on the main thread.
-class ConstructorRunnable : public WorkerMainThreadRunnable
-{
-private:
-  const nsString mURL;
-
-  nsString mBase; // IsVoid() if we have no base URI string.
-  RefPtr<URLProxy> mBaseProxy;
-
-  RefPtr<URLProxy> mRetval;
-
-public:
-  ConstructorRunnable(WorkerPrivate* aWorkerPrivate,
-                      const nsAString& aURL, const Optional<nsAString>& aBase)
-  : WorkerMainThreadRunnable(aWorkerPrivate,
-                             NS_LITERAL_CSTRING("URL :: Constructor"))
-  , mURL(aURL)
-  {
-    if (aBase.WasPassed()) {
-      mBase = aBase.Value();
-    } else {
-      mBase.SetIsVoid(true);
-    }
-    mWorkerPrivate->AssertIsOnWorkerThread();
-  }
-
-  ConstructorRunnable(WorkerPrivate* aWorkerPrivate,
-                      const nsAString& aURL, URLProxy* aBaseProxy)
-  : WorkerMainThreadRunnable(aWorkerPrivate,
-                             NS_LITERAL_CSTRING("URL :: Constructor with BaseURL"))
-  , mURL(aURL)
-  , mBaseProxy(aBaseProxy)
-  {
-    mBase.SetIsVoid(true);
-    mWorkerPrivate->AssertIsOnWorkerThread();
-  }
-
-  bool
-  MainThreadRun()
-  {
-    AssertIsOnMainThread();
-
-    ErrorResult rv;
-    RefPtr<URLMainThread> url;
-    if (mBaseProxy) {
-      url = URLMainThread::Constructor(nullptr, mURL, mBaseProxy->URI(), rv);
-    } else if (!mBase.IsVoid()) {
-      url = URLMainThread::Constructor(nullptr, mURL, mBase, rv);
-    } else {
-      url = URLMainThread::Constructor(nullptr, mURL, nullptr, rv);
-    }
-
-    if (rv.Failed()) {
-      rv.SuppressException();
-      return true;
-    }
-
-    mRetval = new URLProxy(url.forget());
-    return true;
-  }
-
-  URLProxy*
-  GetURLProxy(ErrorResult& aRv) const
-  {
-    MOZ_ASSERT(mWorkerPrivate);
-    mWorkerPrivate->AssertIsOnWorkerThread();
-
-    if (!mRetval) {
-      aRv.ThrowTypeError<MSG_INVALID_URL>(mURL);
-    }
-
-    return mRetval;
-  }
-};
-
-class TeardownURLRunnable : public Runnable
-{
-public:
-  explicit TeardownURLRunnable(URLProxy* aURLProxy)
-    : mURLProxy(aURLProxy)
-  {
-  }
-
-  NS_IMETHOD Run()
-  {
-    AssertIsOnMainThread();
-
-    mURLProxy->ReleaseURI();
-    mURLProxy = nullptr;
-
-    return NS_OK;
-  }
-
-private:
-  RefPtr<URLProxy> mURLProxy;
-};
-
-// This class is the generic getter for any URL property.
-class GetterRunnable : public WorkerMainThreadRunnable
-{
-public:
-  enum GetterType {
-    GetterHref,
-    GetterOrigin,
-    GetterProtocol,
-    GetterUsername,
-    GetterPassword,
-    GetterHost,
-    GetterHostname,
-    GetterPort,
-    GetterPathname,
-    GetterSearch,
-    GetterHash,
-  };
-
-  GetterRunnable(WorkerPrivate* aWorkerPrivate,
-                 GetterType aType, nsAString& aValue,
-                 URLProxy* aURLProxy)
-  : WorkerMainThreadRunnable(aWorkerPrivate,
-                             // We can have telemetry keys for each getter when
-                             // needed.
-                             NS_LITERAL_CSTRING("URL :: getter"))
-  , mValue(aValue)
-  , mType(aType)
-  , mURLProxy(aURLProxy)
-  {
-    mWorkerPrivate->AssertIsOnWorkerThread();
-  }
-
-  bool
-  MainThreadRun()
-  {
-    AssertIsOnMainThread();
-    ErrorResult rv;
-
-    switch (mType) {
-      case GetterHref:
-        mURLProxy->URL()->GetHref(mValue, rv);
-        break;
-
-      case GetterOrigin:
-        mURLProxy->URL()->GetOrigin(mValue, rv);
-        break;
-
-      case GetterProtocol:
-        mURLProxy->URL()->GetProtocol(mValue, rv);
-        break;
-
-      case GetterUsername:
-        mURLProxy->URL()->GetUsername(mValue, rv);
-        break;
-
-      case GetterPassword:
-        mURLProxy->URL()->GetPassword(mValue, rv);
-        break;
-
-      case GetterHost:
-        mURLProxy->URL()->GetHost(mValue, rv);
-        break;
-
-      case GetterHostname:
-        mURLProxy->URL()->GetHostname(mValue, rv);
-        break;
-
-      case GetterPort:
-        mURLProxy->URL()->GetPort(mValue, rv);
-        break;
-
-      case GetterPathname:
-        mURLProxy->URL()->GetPathname(mValue, rv);
-        break;
-
-      case GetterSearch:
-        mURLProxy->URL()->GetSearch(mValue, rv);
-        break;
-
-      case GetterHash:
-        mURLProxy->URL()->GetHash(mValue, rv);
-        break;
-    }
-
-    MOZ_ASSERT(!rv.Failed(), "Main-thread getters do not fail.");
-    return true;
-  }
-
-  void
-  Dispatch(ErrorResult& aRv)
-  {
-    WorkerMainThreadRunnable::Dispatch(Terminating, aRv);
-  }
-
-private:
-  nsAString& mValue;
-  GetterType mType;
-  RefPtr<URLProxy> mURLProxy;
-};
-
-// This class is the generic setter for any URL property.
-class SetterRunnable : public WorkerMainThreadRunnable
-{
-public:
-  enum SetterType {
-    SetterHref,
-    SetterProtocol,
-    SetterUsername,
-    SetterPassword,
-    SetterHost,
-    SetterHostname,
-    SetterPort,
-    SetterPathname,
-    SetterSearch,
-    SetterHash,
-  };
-
-  SetterRunnable(WorkerPrivate* aWorkerPrivate,
-                 SetterType aType, const nsAString& aValue,
-                 URLProxy* aURLProxy)
-  : WorkerMainThreadRunnable(aWorkerPrivate,
-                             // We can have telemetry keys for each setter when
-                             // needed.
-                             NS_LITERAL_CSTRING("URL :: setter"))
-  , mValue(aValue)
-  , mType(aType)
-  , mURLProxy(aURLProxy)
-  , mFailed(false)
-  {
-    mWorkerPrivate->AssertIsOnWorkerThread();
-  }
-
-  bool
-  MainThreadRun()
-  {
-    AssertIsOnMainThread();
-    ErrorResult rv;
-
-    switch (mType) {
-      case SetterHref: {
-        mURLProxy->URL()->SetHref(mValue, rv);
-        break;
-      }
-
-      case SetterProtocol:
-        mURLProxy->URL()->SetProtocol(mValue, rv);
-        break;
-
-      case SetterUsername:
-        mURLProxy->URL()->SetUsername(mValue, rv);
-        break;
-
-      case SetterPassword:
-        mURLProxy->URL()->SetPassword(mValue, rv);
-        break;
-
-      case SetterHost:
-        mURLProxy->URL()->SetHost(mValue, rv);
-        break;
-
-      case SetterHostname:
-        mURLProxy->URL()->SetHostname(mValue, rv);
-        break;
-
-      case SetterPort:
-        mURLProxy->URL()->SetPort(mValue, rv);
-        break;
-
-      case SetterPathname:
-        mURLProxy->URL()->SetPathname(mValue, rv);
-        break;
-
-      case SetterSearch:
-        mURLProxy->URL()->SetSearch(mValue, rv);
-        break;
-
-      case SetterHash:
-        mURLProxy->URL()->SetHash(mValue, rv);
-        break;
-    }
-
-    if (NS_WARN_IF(rv.Failed())) {
-      rv.SuppressException();
-      mFailed = true;
-    }
-
-    return true;
-  }
-
-  bool Failed() const
-  {
-    return mFailed;
-  }
-
-  void
-  Dispatch(ErrorResult& aRv)
-  {
-    WorkerMainThreadRunnable::Dispatch(Terminating, aRv);
-  }
-
-private:
-  const nsString mValue;
-  SetterType mType;
-  RefPtr<URLProxy> mURLProxy;
-  bool mFailed;
-};
-
-already_AddRefed<URLWorker>
-FinishConstructor(JSContext* aCx, WorkerPrivate* aPrivate,
-                  ConstructorRunnable* aRunnable, ErrorResult& aRv)
-{
-  aRunnable->Dispatch(Terminating, aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return nullptr;
-  }
-
-  RefPtr<URLProxy> proxy = aRunnable->GetURLProxy(aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return nullptr;
-  }
-
-  RefPtr<URLWorker> url = new URLWorker(aPrivate, proxy);
-  return url.forget();
-}
-
-/* static */ already_AddRefed<URLWorker>
-URLWorker::Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-                       URL& aBase, ErrorResult& aRv)
-{
-  MOZ_ASSERT(!NS_IsMainThread());
-
-  JSContext* cx = aGlobal.Context();
-  WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
-
-  URLWorker& base = static_cast<URLWorker&>(aBase);
-  RefPtr<ConstructorRunnable> runnable =
-    new ConstructorRunnable(workerPrivate, aURL, base.GetURLProxy());
-
-  return FinishConstructor(cx, workerPrivate, runnable, aRv);
-}
-
-/* static */ already_AddRefed<URLWorker>
-URLWorker::Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-                       const Optional<nsAString>& aBase, ErrorResult& aRv)
-{
-  JSContext* cx = aGlobal.Context();
-  WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
-
-  RefPtr<ConstructorRunnable> runnable =
-    new ConstructorRunnable(workerPrivate, aURL, aBase);
-
-  return FinishConstructor(cx, workerPrivate, runnable, aRv);
-}
-
-/* static */ already_AddRefed<URLWorker>
-URLWorker::Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-                       const nsAString& aBase, ErrorResult& aRv)
-{
-  JSContext* cx = aGlobal.Context();
-  WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
-
-  Optional<nsAString> base;
-  base = &aBase;
-
-  RefPtr<ConstructorRunnable> runnable =
-    new ConstructorRunnable(workerPrivate, aURL, base);
-
-  return FinishConstructor(cx, workerPrivate, runnable, aRv);
-}
-
-/* static */ void
-URLWorker::CreateObjectURL(const GlobalObject& aGlobal, Blob& aBlob,
-                           nsAString& aResult, mozilla::ErrorResult& aRv)
-{
-  JSContext* cx = aGlobal.Context();
-  WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
-
-  RefPtr<BlobImpl> blobImpl = aBlob.Impl();
-  MOZ_ASSERT(blobImpl);
-
-  aRv = blobImpl->SetMutable(false);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  RefPtr<CreateURLRunnable> runnable =
-    new CreateURLRunnable(workerPrivate, blobImpl, aResult);
-
-  runnable->Dispatch(Terminating, aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  if (workerPrivate->IsSharedWorker() || workerPrivate->IsServiceWorker()) {
-    WorkerGlobalScope* scope = workerPrivate->GlobalScope();
-    MOZ_ASSERT(scope);
-
-    scope->RegisterHostObjectURI(NS_ConvertUTF16toUTF8(aResult));
-  }
-}
-
-/* static */ void
-URLWorker::RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aUrl,
-                           ErrorResult& aRv)
-{
-  JSContext* cx = aGlobal.Context();
-  WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
-
-  RefPtr<RevokeURLRunnable> runnable =
-    new RevokeURLRunnable(workerPrivate, aUrl);
-
-  runnable->Dispatch(Terminating, aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  if (workerPrivate->IsSharedWorker() || workerPrivate->IsServiceWorker()) {
-    WorkerGlobalScope* scope = workerPrivate->GlobalScope();
-    MOZ_ASSERT(scope);
-
-    scope->UnregisterHostObjectURI(NS_ConvertUTF16toUTF8(aUrl));
-  }
-}
-
-/* static */ bool
-URLWorker::IsValidURL(const GlobalObject& aGlobal, const nsAString& aUrl,
-                      ErrorResult& aRv)
-{
-  JSContext* cx = aGlobal.Context();
-  WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
-
-  RefPtr<IsValidURLRunnable> runnable =
-    new IsValidURLRunnable(workerPrivate, aUrl);
-
-  runnable->Dispatch(Terminating, aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return false;
-  }
-
-  return runnable->IsValidURL();
-}
-
-URLWorker::URLWorker(WorkerPrivate* aWorkerPrivate, URLProxy* aURLProxy)
-  : URL(nullptr)
-  , mWorkerPrivate(aWorkerPrivate)
-  , mURLProxy(aURLProxy)
-{}
-
-URLWorker::~URLWorker()
-{
-  if (mURLProxy) {
-    mWorkerPrivate->AssertIsOnWorkerThread();
-
-    RefPtr<TeardownURLRunnable> runnable =
-      new TeardownURLRunnable(mURLProxy);
-    mURLProxy = nullptr;
-
-    if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
-      NS_ERROR("Failed to dispatch teardown runnable!");
-    }
-  }
-}
-
-void
-URLWorker::GetHref(nsAString& aHref, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHref, aHref,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URLWorker::SetHref(const nsAString& aHref, ErrorResult& aRv)
-{
-  RefPtr<SetterRunnable> runnable =
-    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHref, aHref,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  if (runnable->Failed()) {
-    aRv.ThrowTypeError<MSG_INVALID_URL>(aHref);
-    return;
-  }
-
-  UpdateURLSearchParams();
-}
-
-void
-URLWorker::GetOrigin(nsAString& aOrigin, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterOrigin, aOrigin,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URLWorker::GetProtocol(nsAString& aProtocol, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterProtocol, aProtocol,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URLWorker::SetProtocol(const nsAString& aProtocol, ErrorResult& aRv)
-{
-  RefPtr<SetterRunnable> runnable =
-    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterProtocol,
-                       aProtocol, mURLProxy);
-
-  runnable->Dispatch(aRv);
-
-  MOZ_ASSERT(!runnable->Failed());
-}
-
-void
-URLWorker::GetUsername(nsAString& aUsername, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterUsername, aUsername,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URLWorker::SetUsername(const nsAString& aUsername, ErrorResult& aRv)
-{
-  RefPtr<SetterRunnable> runnable =
-    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterUsername,
-                       aUsername, mURLProxy);
-
-  runnable->Dispatch(aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  MOZ_ASSERT(!runnable->Failed());
-}
-
-void
-URLWorker::GetPassword(nsAString& aPassword, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterPassword, aPassword,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URLWorker::SetPassword(const nsAString& aPassword, ErrorResult& aRv)
-{
-  RefPtr<SetterRunnable> runnable =
-    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterPassword,
-                       aPassword, mURLProxy);
-
-  runnable->Dispatch(aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  MOZ_ASSERT(!runnable->Failed());
-}
-
-void
-URLWorker::GetHost(nsAString& aHost, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHost, aHost,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URLWorker::SetHost(const nsAString& aHost, ErrorResult& aRv)
-{
-  RefPtr<SetterRunnable> runnable =
-    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHost,
-                       aHost, mURLProxy);
-
-  runnable->Dispatch(aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  MOZ_ASSERT(!runnable->Failed());
-}
-
-void
-URLWorker::GetHostname(nsAString& aHostname, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHostname, aHostname,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URLWorker::SetHostname(const nsAString& aHostname, ErrorResult& aRv)
-{
-  RefPtr<SetterRunnable> runnable =
-    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHostname,
-                       aHostname, mURLProxy);
-
-  runnable->Dispatch(aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  MOZ_ASSERT(!runnable->Failed());
-}
-
-void
-URLWorker::GetPort(nsAString& aPort, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterPort, aPort,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URLWorker::SetPort(const nsAString& aPort, ErrorResult& aRv)
-{
-  RefPtr<SetterRunnable> runnable =
-    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterPort,
-                       aPort, mURLProxy);
-
-  runnable->Dispatch(aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  MOZ_ASSERT(!runnable->Failed());
-}
-
-void
-URLWorker::GetPathname(nsAString& aPathname, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterPathname,
-                       aPathname, mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URLWorker::SetPathname(const nsAString& aPathname, ErrorResult& aRv)
-{
-  RefPtr<SetterRunnable> runnable =
-    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterPathname,
-                       aPathname, mURLProxy);
-
-  runnable->Dispatch(aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  MOZ_ASSERT(!runnable->Failed());
-}
-
-void
-URLWorker::GetSearch(nsAString& aSearch, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterSearch, aSearch,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URLWorker::GetHash(nsAString& aHash, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHash, aHash,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URLWorker::SetHash(const nsAString& aHash, ErrorResult& aRv)
-{
-  RefPtr<SetterRunnable> runnable =
-    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHash,
-                       aHash, mURLProxy);
-
-  runnable->Dispatch(aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  MOZ_ASSERT(!runnable->Failed());
-}
-
-void
-URLWorker::SetSearchInternal(const nsAString& aSearch, ErrorResult& aRv)
-{
-  RefPtr<SetterRunnable> runnable =
-    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterSearch,
-                       aSearch, mURLProxy);
-
-  runnable->Dispatch(aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  MOZ_ASSERT(!runnable->Failed());
-}
-
-void
-URLWorker::UpdateURLSearchParams()
-{
-  if (mSearchParams) {
-    nsAutoString search;
-
-    ErrorResult rv;
-    GetSearch(search, rv);
-    if (NS_WARN_IF(rv.Failed())) {
-      rv.SuppressException();
-    }
-
-    mSearchParams->ParseInput(NS_ConvertUTF16toUTF8(Substring(search, 1)));
-  }
-}
-
-} // anonymous namespace
-
-///////////////////////////////////////////////////////////////////////////////
-// Base class for URL
-///////////////////////////////////////////////////////////////////////////////
-
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(URL, mParent, mSearchParams)
-
-NS_IMPL_CYCLE_COLLECTING_ADDREF(URL)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(URL)
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(URL)
-  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
-  NS_INTERFACE_MAP_ENTRY(nsISupports)
-NS_INTERFACE_MAP_END
-
-JSObject*
-URL::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
-{
-  return URLBinding::Wrap(aCx, this, aGivenProto);
-}
-
-/* static */ already_AddRefed<URL>
-URL::Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-                 URL& aBase, ErrorResult& aRv)
-{
-  if (NS_IsMainThread()) {
-    return URLMainThread::Constructor(aGlobal, aURL, aBase, aRv);
-  }
-
-  return URLWorker::Constructor(aGlobal, aURL, aBase, aRv);
-}
-
-/* static */ already_AddRefed<URL>
-URL::Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-                 const Optional<nsAString>& aBase, ErrorResult& aRv)
-{
-  if (NS_IsMainThread()) {
-    return URLMainThread::Constructor(aGlobal, aURL, aBase, aRv);
-  }
-
-  return URLWorker::Constructor(aGlobal, aURL, aBase, aRv);
-}
-
-/* static */ already_AddRefed<URL>
-URL::WorkerConstructor(const GlobalObject& aGlobal, const nsAString& aURL,
-                       const nsAString& aBase, ErrorResult& aRv)
-{
-  return URLWorker::Constructor(aGlobal, aURL, aBase, aRv);
-}
-
-void
-URL::CreateObjectURL(const GlobalObject& aGlobal, Blob& aBlob,
-                     nsAString& aResult, ErrorResult& aRv)
-{
-  if (NS_IsMainThread()) {
-    URLMainThread::CreateObjectURL(aGlobal, aBlob, aResult, aRv);
-  } else {
-    URLWorker::CreateObjectURL(aGlobal, aBlob, aResult, aRv);
-  }
-}
-
-void
-URL::CreateObjectURL(const GlobalObject& aGlobal, DOMMediaStream& aStream,
-                     nsAString& aResult, ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  DeprecationWarning(aGlobal, nsIDocument::eURLCreateObjectURL_MediaStream);
-
-  URLMainThread::CreateObjectURL(aGlobal, aStream, aResult, aRv);
-}
-
-void
-URL::CreateObjectURL(const GlobalObject& aGlobal, MediaSource& aSource,
-                     nsAString& aResult, ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  URLMainThread::CreateObjectURL(aGlobal, aSource, aResult, aRv);
-}
-
-void
-URL::RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aURL,
-                     ErrorResult& aRv)
-{
-  if (NS_IsMainThread()) {
-    URLMainThread::RevokeObjectURL(aGlobal, aURL, aRv);
-  } else {
-    URLWorker::RevokeObjectURL(aGlobal, aURL, aRv);
-  }
-}
-
-bool
-URL::IsValidURL(const GlobalObject& aGlobal, const nsAString& aURL,
-                ErrorResult& aRv)
-{
-  if (NS_IsMainThread()) {
-    return URLMainThread::IsValidURL(aGlobal, aURL, aRv);
-  }
-  return URLWorker::IsValidURL(aGlobal, aURL, aRv);
-}
-
-URLSearchParams*
-URL::SearchParams()
-{
-  CreateSearchParamsIfNeeded();
-  return mSearchParams;
-}
-
-bool IsChromeURI(nsIURI* aURI)
-{
-  bool isChrome = false;
-  if (NS_SUCCEEDED(aURI->SchemeIs("chrome", &isChrome)))
-      return isChrome;
-  return false;
-}
-
-void
-URL::CreateSearchParamsIfNeeded()
-{
-  if (!mSearchParams) {
-    mSearchParams = new URLSearchParams(mParent, this);
-    UpdateURLSearchParams();
-  }
-}
-
-void
-URL::SetSearch(const nsAString& aSearch, ErrorResult& aRv)
-{
-  SetSearchInternal(aSearch, aRv);
-  UpdateURLSearchParams();
-}
-
-void
-URL::URLSearchParamsUpdated(URLSearchParams* aSearchParams)
-{
-  MOZ_ASSERT(mSearchParams);
-  MOZ_ASSERT(mSearchParams == aSearchParams);
-
-  nsAutoString search;
-  mSearchParams->Serialize(search);
-
-  ErrorResult rv;
-  SetSearchInternal(search, rv);
-  NS_WARNING_ASSERTION(!rv.Failed(), "SetSearchInternal failed");
-  rv.SuppressException();
-}
-
 } // namespace dom
 } // namespace mozilla
+
+#endif // mozilla_dom_URLMainThread_h
copy from dom/url/URL.cpp
copy to dom/url/URLWorker.cpp
--- a/dom/url/URL.cpp
+++ b/dom/url/URLWorker.cpp
@@ -1,599 +1,29 @@
 /* -*- 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 "URL.h"
+#include "URLWorker.h"
 
-#include "DOMMediaStream.h"
-#include "mozilla/dom/File.h"
-#include "mozilla/dom/MediaSource.h"
-#include "mozilla/dom/URLBinding.h"
-#include "mozilla/ipc/BackgroundChild.h"
-#include "nsContentUtils.h"
-#include "nsEscape.h"
+#include "mozilla/dom/Blob.h"
 #include "nsHostObjectProtocolHandler.h"
-#include "nsIIOService.h"
-#include "nsIURL.h"
-#include "nsNetCID.h"
-#include "nsNetUtil.h"
-#include "nsServiceManagerUtils.h"
 #include "WorkerPrivate.h"
 #include "WorkerRunnable.h"
 #include "WorkerScope.h"
 
 namespace mozilla {
 namespace dom {
 
-///////////////////////////////////////////////////////////////////////////////
-// URL for main-thread
-///////////////////////////////////////////////////////////////////////////////
-
-namespace {
-
-template<typename T>
-void
-CreateObjectURLInternal(const GlobalObject& aGlobal, T aObject,
-                        nsAString& aResult, ErrorResult& aRv)
-{
-  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
-  if (NS_WARN_IF(!global)) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return;
-  }
-
-  nsCOMPtr<nsIPrincipal> principal =
-    nsContentUtils::ObjectPrincipal(aGlobal.Get());
-
-  nsAutoCString url;
-  aRv = nsHostObjectProtocolHandler::AddDataEntry(aObject, principal, url);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  global->RegisterHostObjectURI(url);
-  CopyASCIItoUTF16(url, aResult);
-}
-
-// The URL implementation for the main-thread
-class URLMainThread final : public URL
-{
-public:
-  static already_AddRefed<URLMainThread>
-  Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-              URL& aBase, ErrorResult& aRv);
-
-  static already_AddRefed<URLMainThread>
-  Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-              const Optional<nsAString>& aBase, ErrorResult& aRv);
-
-  static already_AddRefed<URLMainThread>
-  Constructor(nsISupports* aParent, const nsAString& aURL,
-              const nsAString& aBase, ErrorResult& aRv);
-
-  static already_AddRefed<URLMainThread>
-  Constructor(nsISupports* aParent, const nsAString& aURL, nsIURI* aBase,
-              ErrorResult& aRv);
-
-  static void
-  CreateObjectURL(const GlobalObject& aGlobal, Blob& aBlob,
-                  nsAString& aResult, ErrorResult& aRv)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-    CreateObjectURLInternal(aGlobal, aBlob.Impl(), aResult, aRv);
-  }
-
-  static void
-  CreateObjectURL(const GlobalObject& aGlobal, DOMMediaStream& aStream,
-                  nsAString& aResult, ErrorResult& aRv)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-    CreateObjectURLInternal(aGlobal, &aStream, aResult, aRv);
-  }
-
-  static void
-  CreateObjectURL(const GlobalObject& aGlobal, MediaSource& aSource,
-                  nsAString& aResult, ErrorResult& aRv);
-
-  static void
-  RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aURL,
-                  ErrorResult& aRv);
-
-  static bool
-  IsValidURL(const GlobalObject& aGlobal, const nsAString& aURL,
-             ErrorResult& aRv);
-
-  URLMainThread(nsISupports* aParent, already_AddRefed<nsIURI> aURI)
-    : URL(aParent)
-    , mURI(aURI)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-  }
-
-  virtual void
-  GetHref(nsAString& aHref, ErrorResult& aRv) const override;
-
-  virtual void
-  SetHref(const nsAString& aHref, ErrorResult& aRv) override;
-
-  virtual void
-  GetOrigin(nsAString& aOrigin, ErrorResult& aRv) const override;
-
-  virtual void
-  GetProtocol(nsAString& aProtocol, ErrorResult& aRv) const override;
-
-  virtual void
-  SetProtocol(const nsAString& aProtocol, ErrorResult& aRv) override;
-
-  virtual void
-  GetUsername(nsAString& aUsername, ErrorResult& aRv) const override;
-
-  virtual void
-  SetUsername(const nsAString& aUsername, ErrorResult& aRv) override;
-
-  virtual void
-  GetPassword(nsAString& aPassword, ErrorResult& aRv) const override;
-
-  virtual void
-  SetPassword(const nsAString& aPassword, ErrorResult& aRv) override;
-
-  virtual void
-  GetHost(nsAString& aHost, ErrorResult& aRv) const override;
-
-  virtual void
-  SetHost(const nsAString& aHost, ErrorResult& aRv) override;
-
-  virtual void
-  GetHostname(nsAString& aHostname, ErrorResult& aRv) const override;
-
-  virtual void
-  SetHostname(const nsAString& aHostname, ErrorResult& aRv) override;
-
-  virtual void
-  GetPort(nsAString& aPort, ErrorResult& aRv) const override;
-
-  virtual void
-  SetPort(const nsAString& aPort, ErrorResult& aRv) override;
-
-  virtual void
-  GetPathname(nsAString& aPathname, ErrorResult& aRv) const override;
-
-  virtual void
-  SetPathname(const nsAString& aPathname, ErrorResult& aRv) override;
-
-  virtual void
-  GetSearch(nsAString& aSearch, ErrorResult& aRv) const override;
-
-  virtual void
-  GetHash(nsAString& aHost, ErrorResult& aRv) const override;
-
-  virtual void
-  SetHash(const nsAString& aHash, ErrorResult& aRv) override;
-
-  virtual void UpdateURLSearchParams() override;
-
-  virtual void
-  SetSearchInternal(const nsAString& aSearch, ErrorResult& aRv) override;
-
-  nsIURI*
-  GetURI() const
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-    return mURI;
-  }
-
-private:
-  ~URLMainThread()
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-  }
-
-  nsCOMPtr<nsIURI> mURI;
-};
-
-/* static */ already_AddRefed<URLMainThread>
-URLMainThread::Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-                           URL& aBase, ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  URLMainThread& base = static_cast<URLMainThread&>(aBase);
-  return Constructor(aGlobal.GetAsSupports(), aURL, base.GetURI(), aRv);
-}
-
-/* static */ already_AddRefed<URLMainThread>
-URLMainThread::Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-                           const Optional<nsAString>& aBase, ErrorResult& aRv)
-{
-  if (aBase.WasPassed()) {
-    return Constructor(aGlobal.GetAsSupports(), aURL, aBase.Value(), aRv);
-  }
-
-  return Constructor(aGlobal.GetAsSupports(), aURL, nullptr, aRv);
-}
-
-/* static */ already_AddRefed<URLMainThread>
-URLMainThread::Constructor(nsISupports* aParent, const nsAString& aURL,
-                           const nsAString& aBase, ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  nsCOMPtr<nsIURI> baseUri;
-  nsresult rv = NS_NewURI(getter_AddRefs(baseUri), aBase, nullptr, nullptr,
-                          nsContentUtils::GetIOService());
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    aRv.ThrowTypeError<MSG_INVALID_URL>(aBase);
-    return nullptr;
-  }
-
-  return Constructor(aParent, aURL, baseUri, aRv);
-}
-
-/* static */ already_AddRefed<URLMainThread>
-URLMainThread::Constructor(nsISupports* aParent, const nsAString& aURL,
-                           nsIURI* aBase, ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  nsCOMPtr<nsIURI> uri;
-  nsresult rv = NS_NewURI(getter_AddRefs(uri), aURL, nullptr, aBase,
-                          nsContentUtils::GetIOService());
-  if (NS_FAILED(rv)) {
-    // No need to warn in this case. It's common to use the URL constructor
-    // to determine if a URL is valid and an exception will be propagated.
-    aRv.ThrowTypeError<MSG_INVALID_URL>(aURL);
-    return nullptr;
-  }
-
-  RefPtr<URLMainThread> url = new URLMainThread(aParent, uri.forget());
-  return url.forget();
-}
-
-/* static */ void
-URLMainThread::CreateObjectURL(const GlobalObject& aGlobal,
-                               MediaSource& aSource,
-                               nsAString& aResult, ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  nsCOMPtr<nsIPrincipal> principal =
-    nsContentUtils::ObjectPrincipal(aGlobal.Get());
-
-  nsAutoCString url;
-  aRv = nsHostObjectProtocolHandler::AddDataEntry(&aSource, principal, url);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  nsCOMPtr<nsIRunnable> revocation = NS_NewRunnableFunction(
-    [url] {
-      nsHostObjectProtocolHandler::RemoveDataEntry(url);
-    });
-
-  nsContentUtils::RunInStableState(revocation.forget());
-
-  CopyASCIItoUTF16(url, aResult);
-}
-
-/* static */ void
-URLMainThread::RevokeObjectURL(const GlobalObject& aGlobal,
-                               const nsAString& aURL, ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
-  if (!global) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return;
-  }
-
-  nsIPrincipal* principal = nsContentUtils::ObjectPrincipal(aGlobal.Get());
-
-  NS_LossyConvertUTF16toASCII asciiurl(aURL);
-
-  nsIPrincipal* urlPrincipal =
-    nsHostObjectProtocolHandler::GetDataEntryPrincipal(asciiurl);
-
-  if (urlPrincipal && principal->Subsumes(urlPrincipal)) {
-    global->UnregisterHostObjectURI(asciiurl);
-    nsHostObjectProtocolHandler::RemoveDataEntry(asciiurl);
-  }
-}
-
-/* static */ bool
-URLMainThread::IsValidURL(const GlobalObject& aGlobal, const nsAString& aURL,
-                          ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  NS_LossyConvertUTF16toASCII asciiurl(aURL);
-  return nsHostObjectProtocolHandler::HasDataEntry(asciiurl);
-}
-
-void
-URLMainThread::GetHref(nsAString& aHref, ErrorResult& aRv) const
-{
-  aHref.Truncate();
-
-  nsAutoCString href;
-  nsresult rv = mURI->GetSpec(href);
-  if (NS_SUCCEEDED(rv)) {
-    CopyUTF8toUTF16(href, aHref);
-  }
-}
-
-void
-URLMainThread::SetHref(const nsAString& aHref, ErrorResult& aRv)
-{
-  NS_ConvertUTF16toUTF8 href(aHref);
-
-  nsresult rv;
-  nsCOMPtr<nsIIOService> ioService(do_GetService(NS_IOSERVICE_CONTRACTID, &rv));
-  if (NS_FAILED(rv)) {
-    aRv.Throw(rv);
-    return;
-  }
-
-  nsCOMPtr<nsIURI> uri;
-  rv = ioService->NewURI(href, nullptr, nullptr, getter_AddRefs(uri));
-  if (NS_FAILED(rv)) {
-    aRv.ThrowTypeError<MSG_INVALID_URL>(aHref);
-    return;
-  }
-
-  mURI = uri;
-  UpdateURLSearchParams();
-}
-
-void
-URLMainThread::GetOrigin(nsAString& aOrigin, ErrorResult& aRv) const
-{
-  nsContentUtils::GetUTFOrigin(mURI, aOrigin);
-}
-
-void
-URLMainThread::GetProtocol(nsAString& aProtocol, ErrorResult& aRv) const
-{
-  nsAutoCString protocol;
-  if (NS_SUCCEEDED(mURI->GetScheme(protocol))) {
-    aProtocol.Truncate();
-  }
-
-  CopyASCIItoUTF16(protocol, aProtocol);
-  aProtocol.Append(char16_t(':'));
-}
-
-void
-URLMainThread::SetProtocol(const nsAString& aProtocol, ErrorResult& aRv)
-{
-  nsAString::const_iterator start, end;
-  aProtocol.BeginReading(start);
-  aProtocol.EndReading(end);
-  nsAString::const_iterator iter(start);
-
-  FindCharInReadable(':', iter, end);
-
-  // Changing the protocol of a URL, changes the "nature" of the URI
-  // implementation. In order to do this properly, we have to serialize the
-  // existing URL and reparse it in a new object.
-  nsCOMPtr<nsIURI> clone;
-  nsresult rv = mURI->Clone(getter_AddRefs(clone));
-  if (NS_WARN_IF(NS_FAILED(rv)) || !clone) {
-    return;
-  }
-
-  rv = clone->SetScheme(NS_ConvertUTF16toUTF8(Substring(start, iter)));
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return;
-  }
-
-  nsAutoCString href;
-  rv = clone->GetSpec(href);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return;
-  }
-
-  nsCOMPtr<nsIURI> uri;
-  rv = NS_NewURI(getter_AddRefs(uri), href);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return;
-  }
-
-  mURI = uri;
-}
-
-#define URL_GETTER( value, func ) \
-  value.Truncate();               \
-  nsAutoCString tmp;              \
-  nsresult rv = mURI->func(tmp);  \
-  if (NS_SUCCEEDED(rv)) {         \
-    CopyUTF8toUTF16(tmp, value);  \
-  }
-
-void
-URLMainThread::GetUsername(nsAString& aUsername, ErrorResult& aRv) const
-{
-  URL_GETTER(aUsername, GetUsername);
-}
-
-void
-URLMainThread::SetUsername(const nsAString& aUsername, ErrorResult& aRv)
-{
-  mURI->SetUsername(NS_ConvertUTF16toUTF8(aUsername));
-}
-
-void
-URLMainThread::GetPassword(nsAString& aPassword, ErrorResult& aRv) const
-{
-  URL_GETTER(aPassword, GetPassword);
-}
-
-void
-URLMainThread::SetPassword(const nsAString& aPassword, ErrorResult& aRv)
-{
-  mURI->SetPassword(NS_ConvertUTF16toUTF8(aPassword));
-}
-
-void
-URLMainThread::GetHost(nsAString& aHost, ErrorResult& aRv) const
-{
-  URL_GETTER(aHost, GetHostPort);
-}
-
-void
-URLMainThread::SetHost(const nsAString& aHost, ErrorResult& aRv)
-{
-  mURI->SetHostPort(NS_ConvertUTF16toUTF8(aHost));
-}
-
-void
-URLMainThread::UpdateURLSearchParams()
-{
-  if (!mSearchParams) {
-    return;
-  }
-
-  nsAutoCString search;
-  nsCOMPtr<nsIURL> url(do_QueryInterface(mURI));
-  if (url) {
-    nsresult rv = url->GetQuery(search);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      search.Truncate();
-    }
-  }
-
-  mSearchParams->ParseInput(search);
-}
-
-void
-URLMainThread::GetHostname(nsAString& aHostname, ErrorResult& aRv) const
-{
-  aHostname.Truncate();
-  nsContentUtils::GetHostOrIPv6WithBrackets(mURI, aHostname);
-}
-
-void
-URLMainThread::SetHostname(const nsAString& aHostname, ErrorResult& aRv)
-{
-  // nsStandardURL returns NS_ERROR_UNEXPECTED for an empty hostname
-  // The return code is silently ignored
-  mURI->SetHost(NS_ConvertUTF16toUTF8(aHostname));
-}
-
-void
-URLMainThread::GetPort(nsAString& aPort, ErrorResult& aRv) const
-{
-  aPort.Truncate();
-
-  int32_t port;
-  nsresult rv = mURI->GetPort(&port);
-  if (NS_SUCCEEDED(rv) && port != -1) {
-    nsAutoString portStr;
-    portStr.AppendInt(port, 10);
-    aPort.Assign(portStr);
-  }
-}
-
-void
-URLMainThread::SetPort(const nsAString& aPort, ErrorResult& aRv)
-{
-  nsresult rv;
-  nsAutoString portStr(aPort);
-  int32_t port = -1;
-
-  // nsIURI uses -1 as default value.
-  if (!portStr.IsEmpty()) {
-    port = portStr.ToInteger(&rv);
-    if (NS_FAILED(rv)) {
-      return;
-    }
-  }
-
-  mURI->SetPort(port);
-}
-
-void
-URLMainThread::GetPathname(nsAString& aPathname, ErrorResult& aRv) const
-{
-  aPathname.Truncate();
-
-  // Do not throw!  Not having a valid URI or URL should result in an empty
-  // string.
-
-  nsAutoCString file;
-  nsresult rv = mURI->GetFilePath(file);
-  if (NS_SUCCEEDED(rv)) {
-    CopyUTF8toUTF16(file, aPathname);
-  }
-}
-
-void
-URLMainThread::SetPathname(const nsAString& aPathname, ErrorResult& aRv)
-{
-  // Do not throw!
-
-  mURI->SetFilePath(NS_ConvertUTF16toUTF8(aPathname));
-}
-
-void
-URLMainThread::GetSearch(nsAString& aSearch, ErrorResult& aRv) const
-{
-  aSearch.Truncate();
-
-  // Do not throw!  Not having a valid URI or URL should result in an empty
-  // string.
-
-  nsAutoCString search;
-  nsresult rv;
-
-  rv = mURI->GetQuery(search);
-  if (NS_SUCCEEDED(rv) && !search.IsEmpty()) {
-    CopyUTF8toUTF16(NS_LITERAL_CSTRING("?") + search, aSearch);
-  }
-}
-
-void
-URLMainThread::GetHash(nsAString& aHash, ErrorResult& aRv) const
-{
-  aHash.Truncate();
-
-  nsAutoCString ref;
-  nsresult rv = mURI->GetRef(ref);
-  if (NS_SUCCEEDED(rv) && !ref.IsEmpty()) {
-    aHash.Assign(char16_t('#'));
-    AppendUTF8toUTF16(ref, aHash);
-  }
-}
-
-void
-URLMainThread::SetHash(const nsAString& aHash, ErrorResult& aRv)
-{
-  mURI->SetRef(NS_ConvertUTF16toUTF8(aHash));
-}
-
-void
-URLMainThread::SetSearchInternal(const nsAString& aSearch, ErrorResult& aRv)
-{
-  // Ignore failures to be compatible with NS4.
-
-  mURI->SetQuery(NS_ConvertUTF16toUTF8(aSearch));
-}
-
-} // anonymous namespace
-
-///////////////////////////////////////////////////////////////////////////////
-// URL for Workers
-///////////////////////////////////////////////////////////////////////////////
-
-namespace {
-
 using namespace workers;
 
 // Proxy class to forward all the requests to a URLMainThread object.
-class URLProxy final
+class URLWorker::URLProxy final
 {
 public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(URLProxy)
 
   explicit URLProxy(already_AddRefed<URLMainThread> aURL)
     : mURL(aURL)
   {
     MOZ_ASSERT(NS_IsMainThread());
@@ -622,125 +52,16 @@ private:
   ~URLProxy()
   {
      MOZ_ASSERT(!mURL);
   }
 
   RefPtr<URLMainThread> mURL;
 };
 
-// URLWorker implements the URL object in workers.
-class URLWorker final : public URL
-{
-public:
-  static already_AddRefed<URLWorker>
-  Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-              URL& aBase, ErrorResult& aRv);
-
-  static already_AddRefed<URLWorker>
-  Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-              const Optional<nsAString>& aBase, ErrorResult& aRv);
-
-  static already_AddRefed<URLWorker>
-  Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-              const nsAString& aBase, ErrorResult& aRv);
-
-  static void
-  CreateObjectURL(const GlobalObject& aGlobal, Blob& aBlob,
-                  nsAString& aResult, mozilla::ErrorResult& aRv);
-
-  static void
-  RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aUrl,
-                  ErrorResult& aRv);
-
-  static bool
-  IsValidURL(const GlobalObject& aGlobal, const nsAString& aUrl,
-             ErrorResult& aRv);
-
-  URLWorker(WorkerPrivate* aWorkerPrivate, URLProxy* aURLProxy);
-
-  virtual void
-  GetHref(nsAString& aHref, ErrorResult& aRv) const override;
-
-  virtual void
-  SetHref(const nsAString& aHref, ErrorResult& aRv) override;
-
-  virtual void
-  GetOrigin(nsAString& aOrigin, ErrorResult& aRv) const override;
-
-  virtual void
-  GetProtocol(nsAString& aProtocol, ErrorResult& aRv) const override;
-
-  virtual void
-  SetProtocol(const nsAString& aProtocol, ErrorResult& aRv) override;
-
-  virtual void
-  GetUsername(nsAString& aUsername, ErrorResult& aRv) const override;
-
-  virtual void
-  SetUsername(const nsAString& aUsername, ErrorResult& aRv) override;
-
-  virtual void
-  GetPassword(nsAString& aPassword, ErrorResult& aRv) const override;
-
-  virtual void
-  SetPassword(const nsAString& aPassword, ErrorResult& aRv) override;
-
-  virtual void
-  GetHost(nsAString& aHost, ErrorResult& aRv) const override;
-
-  virtual void
-  SetHost(const nsAString& aHost, ErrorResult& aRv) override;
-
-  virtual void
-  GetHostname(nsAString& aHostname, ErrorResult& aRv) const override;
-
-  virtual void
-  SetHostname(const nsAString& aHostname, ErrorResult& aRv) override;
-
-  virtual void
-  GetPort(nsAString& aPort, ErrorResult& aRv) const override;
-
-  virtual void
-  SetPort(const nsAString& aPort, ErrorResult& aRv) override;
-
-  virtual void
-  GetPathname(nsAString& aPathname, ErrorResult& aRv) const override;
-
-  virtual void
-  SetPathname(const nsAString& aPathname, ErrorResult& aRv) override;
-
-  virtual void
-  GetSearch(nsAString& aSearch, ErrorResult& aRv) const override;
-
-  virtual void
-  GetHash(nsAString& aHost, ErrorResult& aRv) const override;
-
-  virtual void
-  SetHash(const nsAString& aHash, ErrorResult& aRv) override;
-
-  virtual void UpdateURLSearchParams() override;
-
-  virtual void
-  SetSearchInternal(const nsAString& aSearch, ErrorResult& aRv) override;
-
-  URLProxy*
-  GetURLProxy() const
-  {
-    mWorkerPrivate->AssertIsOnWorkerThread();
-    return mURLProxy;
-  }
-
-private:
-  ~URLWorker();
-
-  workers::WorkerPrivate* mWorkerPrivate;
-  RefPtr<URLProxy> mURLProxy;
-};
-
 // This class creates an URL from a DOM Blob on the main thread.
 class CreateURLRunnable : public WorkerMainThreadRunnable
 {
 private:
   BlobImpl* mBlobImpl;
   nsAString& mURL;
 
 public:
@@ -895,104 +216,90 @@ public:
 
 // This class creates a URL object on the main thread.
 class ConstructorRunnable : public WorkerMainThreadRunnable
 {
 private:
   const nsString mURL;
 
   nsString mBase; // IsVoid() if we have no base URI string.
-  RefPtr<URLProxy> mBaseProxy;
 
-  RefPtr<URLProxy> mRetval;
+  RefPtr<URLWorker::URLProxy> mRetval;
 
 public:
   ConstructorRunnable(WorkerPrivate* aWorkerPrivate,
                       const nsAString& aURL, const Optional<nsAString>& aBase)
   : WorkerMainThreadRunnable(aWorkerPrivate,
                              NS_LITERAL_CSTRING("URL :: Constructor"))
   , mURL(aURL)
   {
     if (aBase.WasPassed()) {
       mBase = aBase.Value();
     } else {
       mBase.SetIsVoid(true);
     }
     mWorkerPrivate->AssertIsOnWorkerThread();
   }
 
-  ConstructorRunnable(WorkerPrivate* aWorkerPrivate,
-                      const nsAString& aURL, URLProxy* aBaseProxy)
-  : WorkerMainThreadRunnable(aWorkerPrivate,
-                             NS_LITERAL_CSTRING("URL :: Constructor with BaseURL"))
-  , mURL(aURL)
-  , mBaseProxy(aBaseProxy)
-  {
-    mBase.SetIsVoid(true);
-    mWorkerPrivate->AssertIsOnWorkerThread();
-  }
-
   bool
   MainThreadRun()
   {
     AssertIsOnMainThread();
 
     ErrorResult rv;
     RefPtr<URLMainThread> url;
-    if (mBaseProxy) {
-      url = URLMainThread::Constructor(nullptr, mURL, mBaseProxy->URI(), rv);
-    } else if (!mBase.IsVoid()) {
+    if (!mBase.IsVoid()) {
       url = URLMainThread::Constructor(nullptr, mURL, mBase, rv);
     } else {
       url = URLMainThread::Constructor(nullptr, mURL, nullptr, rv);
     }
 
     if (rv.Failed()) {
       rv.SuppressException();
       return true;
     }
 
-    mRetval = new URLProxy(url.forget());
+    mRetval = new URLWorker::URLProxy(url.forget());
     return true;
   }
 
-  URLProxy*
+  URLWorker::URLProxy*
   GetURLProxy(ErrorResult& aRv) const
   {
     MOZ_ASSERT(mWorkerPrivate);
     mWorkerPrivate->AssertIsOnWorkerThread();
 
     if (!mRetval) {
       aRv.ThrowTypeError<MSG_INVALID_URL>(mURL);
     }
 
     return mRetval;
   }
 };
 
 class TeardownURLRunnable : public Runnable
 {
 public:
-  explicit TeardownURLRunnable(URLProxy* aURLProxy)
+  explicit TeardownURLRunnable(URLWorker::URLProxy* aURLProxy)
     : mURLProxy(aURLProxy)
   {
   }
 
   NS_IMETHOD Run()
   {
     AssertIsOnMainThread();
 
     mURLProxy->ReleaseURI();
     mURLProxy = nullptr;
 
     return NS_OK;
   }
 
 private:
-  RefPtr<URLProxy> mURLProxy;
+  RefPtr<URLWorker::URLProxy> mURLProxy;
 };
 
 // This class is the generic getter for any URL property.
 class GetterRunnable : public WorkerMainThreadRunnable
 {
 public:
   enum GetterType {
     GetterHref,
@@ -1005,17 +312,17 @@ public:
     GetterPort,
     GetterPathname,
     GetterSearch,
     GetterHash,
   };
 
   GetterRunnable(WorkerPrivate* aWorkerPrivate,
                  GetterType aType, nsAString& aValue,
-                 URLProxy* aURLProxy)
+                 URLWorker::URLProxy* aURLProxy)
   : WorkerMainThreadRunnable(aWorkerPrivate,
                              // We can have telemetry keys for each getter when
                              // needed.
                              NS_LITERAL_CSTRING("URL :: getter"))
   , mValue(aValue)
   , mType(aType)
   , mURLProxy(aURLProxy)
   {
@@ -1082,17 +389,17 @@ public:
   Dispatch(ErrorResult& aRv)
   {
     WorkerMainThreadRunnable::Dispatch(Terminating, aRv);
   }
 
 private:
   nsAString& mValue;
   GetterType mType;
-  RefPtr<URLProxy> mURLProxy;
+  RefPtr<URLWorker::URLProxy> mURLProxy;
 };
 
 // This class is the generic setter for any URL property.
 class SetterRunnable : public WorkerMainThreadRunnable
 {
 public:
   enum SetterType {
     SetterHref,
@@ -1104,17 +411,17 @@ public:
     SetterPort,
     SetterPathname,
     SetterSearch,
     SetterHash,
   };
 
   SetterRunnable(WorkerPrivate* aWorkerPrivate,
                  SetterType aType, const nsAString& aValue,
-                 URLProxy* aURLProxy)
+                 URLWorker::URLProxy* aURLProxy)
   : WorkerMainThreadRunnable(aWorkerPrivate,
                              // We can have telemetry keys for each setter when
                              // needed.
                              NS_LITERAL_CSTRING("URL :: setter"))
   , mValue(aValue)
   , mType(aType)
   , mURLProxy(aURLProxy)
   , mFailed(false)
@@ -1188,56 +495,40 @@ public:
   Dispatch(ErrorResult& aRv)
   {
     WorkerMainThreadRunnable::Dispatch(Terminating, aRv);
   }
 
 private:
   const nsString mValue;
   SetterType mType;
-  RefPtr<URLProxy> mURLProxy;
+  RefPtr<URLWorker::URLProxy> mURLProxy;
   bool mFailed;
 };
 
 already_AddRefed<URLWorker>
 FinishConstructor(JSContext* aCx, WorkerPrivate* aPrivate,
                   ConstructorRunnable* aRunnable, ErrorResult& aRv)
 {
   aRunnable->Dispatch(Terminating, aRv);
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
 
-  RefPtr<URLProxy> proxy = aRunnable->GetURLProxy(aRv);
+  RefPtr<URLWorker::URLProxy> proxy = aRunnable->GetURLProxy(aRv);
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
 
   RefPtr<URLWorker> url = new URLWorker(aPrivate, proxy);
   return url.forget();
 }
 
 /* static */ already_AddRefed<URLWorker>
 URLWorker::Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-                       URL& aBase, ErrorResult& aRv)
-{
-  MOZ_ASSERT(!NS_IsMainThread());
-
-  JSContext* cx = aGlobal.Context();
-  WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
-
-  URLWorker& base = static_cast<URLWorker&>(aBase);
-  RefPtr<ConstructorRunnable> runnable =
-    new ConstructorRunnable(workerPrivate, aURL, base.GetURLProxy());
-
-  return FinishConstructor(cx, workerPrivate, runnable, aRv);
-}
-
-/* static */ already_AddRefed<URLWorker>
-URLWorker::Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
                        const Optional<nsAString>& aBase, ErrorResult& aRv)
 {
   JSContext* cx = aGlobal.Context();
   WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
 
   RefPtr<ConstructorRunnable> runnable =
     new ConstructorRunnable(workerPrivate, aURL, aBase);
 
@@ -1626,158 +917,17 @@ URLWorker::UpdateURLSearchParams()
     if (NS_WARN_IF(rv.Failed())) {
       rv.SuppressException();
     }
 
     mSearchParams->ParseInput(NS_ConvertUTF16toUTF8(Substring(search, 1)));
   }
 }
 
-} // anonymous namespace
-
-///////////////////////////////////////////////////////////////////////////////
-// Base class for URL
-///////////////////////////////////////////////////////////////////////////////
-
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(URL, mParent, mSearchParams)
-
-NS_IMPL_CYCLE_COLLECTING_ADDREF(URL)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(URL)
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(URL)
-  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
-  NS_INTERFACE_MAP_ENTRY(nsISupports)
-NS_INTERFACE_MAP_END
-
-JSObject*
-URL::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
-{
-  return URLBinding::Wrap(aCx, this, aGivenProto);
-}
-
-/* static */ already_AddRefed<URL>
-URL::Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-                 URL& aBase, ErrorResult& aRv)
-{
-  if (NS_IsMainThread()) {
-    return URLMainThread::Constructor(aGlobal, aURL, aBase, aRv);
-  }
-
-  return URLWorker::Constructor(aGlobal, aURL, aBase, aRv);
-}
-
-/* static */ already_AddRefed<URL>
-URL::Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-                 const Optional<nsAString>& aBase, ErrorResult& aRv)
-{
-  if (NS_IsMainThread()) {
-    return URLMainThread::Constructor(aGlobal, aURL, aBase, aRv);
-  }
-
-  return URLWorker::Constructor(aGlobal, aURL, aBase, aRv);
-}
-
-/* static */ already_AddRefed<URL>
-URL::WorkerConstructor(const GlobalObject& aGlobal, const nsAString& aURL,
-                       const nsAString& aBase, ErrorResult& aRv)
-{
-  return URLWorker::Constructor(aGlobal, aURL, aBase, aRv);
-}
-
-void
-URL::CreateObjectURL(const GlobalObject& aGlobal, Blob& aBlob,
-                     nsAString& aResult, ErrorResult& aRv)
-{
-  if (NS_IsMainThread()) {
-    URLMainThread::CreateObjectURL(aGlobal, aBlob, aResult, aRv);
-  } else {
-    URLWorker::CreateObjectURL(aGlobal, aBlob, aResult, aRv);
-  }
-}
-
-void
-URL::CreateObjectURL(const GlobalObject& aGlobal, DOMMediaStream& aStream,
-                     nsAString& aResult, ErrorResult& aRv)
+URLWorker::URLProxy*
+URLWorker::GetURLProxy() const
 {
-  MOZ_ASSERT(NS_IsMainThread());
-
-  DeprecationWarning(aGlobal, nsIDocument::eURLCreateObjectURL_MediaStream);
-
-  URLMainThread::CreateObjectURL(aGlobal, aStream, aResult, aRv);
-}
-
-void
-URL::CreateObjectURL(const GlobalObject& aGlobal, MediaSource& aSource,
-                     nsAString& aResult, ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  URLMainThread::CreateObjectURL(aGlobal, aSource, aResult, aRv);
-}
-
-void
-URL::RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aURL,
-                     ErrorResult& aRv)
-{
-  if (NS_IsMainThread()) {
-    URLMainThread::RevokeObjectURL(aGlobal, aURL, aRv);
-  } else {
-    URLWorker::RevokeObjectURL(aGlobal, aURL, aRv);
-  }
-}
-
-bool
-URL::IsValidURL(const GlobalObject& aGlobal, const nsAString& aURL,
-                ErrorResult& aRv)
-{
-  if (NS_IsMainThread()) {
-    return URLMainThread::IsValidURL(aGlobal, aURL, aRv);
-  }
-  return URLWorker::IsValidURL(aGlobal, aURL, aRv);
-}
-
-URLSearchParams*
-URL::SearchParams()
-{
-  CreateSearchParamsIfNeeded();
-  return mSearchParams;
-}
-
-bool IsChromeURI(nsIURI* aURI)
-{
-  bool isChrome = false;
-  if (NS_SUCCEEDED(aURI->SchemeIs("chrome", &isChrome)))
-      return isChrome;
-  return false;
-}
-
-void
-URL::CreateSearchParamsIfNeeded()
-{
-  if (!mSearchParams) {
-    mSearchParams = new URLSearchParams(mParent, this);
-    UpdateURLSearchParams();
-  }
-}
-
-void
-URL::SetSearch(const nsAString& aSearch, ErrorResult& aRv)
-{
-  SetSearchInternal(aSearch, aRv);
-  UpdateURLSearchParams();
-}
-
-void
-URL::URLSearchParamsUpdated(URLSearchParams* aSearchParams)
-{
-  MOZ_ASSERT(mSearchParams);
-  MOZ_ASSERT(mSearchParams == aSearchParams);
-
-  nsAutoString search;
-  mSearchParams->Serialize(search);
-
-  ErrorResult rv;
-  SetSearchInternal(search, rv);
-  NS_WARNING_ASSERTION(!rv.Failed(), "SetSearchInternal failed");
-  rv.SuppressException();
+  mWorkerPrivate->AssertIsOnWorkerThread();
+  return mURLProxy;
 }
 
 } // namespace dom
 } // namespace mozilla
copy from dom/url/URL.cpp
copy to dom/url/URLWorker.h
--- a/dom/url/URL.cpp
+++ b/dom/url/URLWorker.h
@@ -1,644 +1,32 @@
 /* -*- 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 "URL.h"
+#ifndef mozilla_dom_URLWorker_h
+#define mozilla_dom_URLWorker_h
 
-#include "DOMMediaStream.h"
-#include "mozilla/dom/File.h"
-#include "mozilla/dom/MediaSource.h"
-#include "mozilla/dom/URLBinding.h"
-#include "mozilla/ipc/BackgroundChild.h"
-#include "nsContentUtils.h"
-#include "nsEscape.h"
-#include "nsHostObjectProtocolHandler.h"
-#include "nsIIOService.h"
-#include "nsIURL.h"
-#include "nsNetCID.h"
-#include "nsNetUtil.h"
-#include "nsServiceManagerUtils.h"
-#include "WorkerPrivate.h"
-#include "WorkerRunnable.h"
-#include "WorkerScope.h"
+#include "URL.h"
+#include "URLMainThread.h"
 
 namespace mozilla {
 namespace dom {
 
-///////////////////////////////////////////////////////////////////////////////
-// URL for main-thread
-///////////////////////////////////////////////////////////////////////////////
-
-namespace {
-
-template<typename T>
-void
-CreateObjectURLInternal(const GlobalObject& aGlobal, T aObject,
-                        nsAString& aResult, ErrorResult& aRv)
-{
-  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
-  if (NS_WARN_IF(!global)) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return;
-  }
-
-  nsCOMPtr<nsIPrincipal> principal =
-    nsContentUtils::ObjectPrincipal(aGlobal.Get());
-
-  nsAutoCString url;
-  aRv = nsHostObjectProtocolHandler::AddDataEntry(aObject, principal, url);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  global->RegisterHostObjectURI(url);
-  CopyASCIItoUTF16(url, aResult);
-}
-
-// The URL implementation for the main-thread
-class URLMainThread final : public URL
-{
-public:
-  static already_AddRefed<URLMainThread>
-  Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-              URL& aBase, ErrorResult& aRv);
-
-  static already_AddRefed<URLMainThread>
-  Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-              const Optional<nsAString>& aBase, ErrorResult& aRv);
-
-  static already_AddRefed<URLMainThread>
-  Constructor(nsISupports* aParent, const nsAString& aURL,
-              const nsAString& aBase, ErrorResult& aRv);
-
-  static already_AddRefed<URLMainThread>
-  Constructor(nsISupports* aParent, const nsAString& aURL, nsIURI* aBase,
-              ErrorResult& aRv);
-
-  static void
-  CreateObjectURL(const GlobalObject& aGlobal, Blob& aBlob,
-                  nsAString& aResult, ErrorResult& aRv)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-    CreateObjectURLInternal(aGlobal, aBlob.Impl(), aResult, aRv);
-  }
-
-  static void
-  CreateObjectURL(const GlobalObject& aGlobal, DOMMediaStream& aStream,
-                  nsAString& aResult, ErrorResult& aRv)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-    CreateObjectURLInternal(aGlobal, &aStream, aResult, aRv);
-  }
-
-  static void
-  CreateObjectURL(const GlobalObject& aGlobal, MediaSource& aSource,
-                  nsAString& aResult, ErrorResult& aRv);
-
-  static void
-  RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aURL,
-                  ErrorResult& aRv);
-
-  static bool
-  IsValidURL(const GlobalObject& aGlobal, const nsAString& aURL,
-             ErrorResult& aRv);
-
-  URLMainThread(nsISupports* aParent, already_AddRefed<nsIURI> aURI)
-    : URL(aParent)
-    , mURI(aURI)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-  }
-
-  virtual void
-  GetHref(nsAString& aHref, ErrorResult& aRv) const override;
-
-  virtual void
-  SetHref(const nsAString& aHref, ErrorResult& aRv) override;
-
-  virtual void
-  GetOrigin(nsAString& aOrigin, ErrorResult& aRv) const override;
-
-  virtual void
-  GetProtocol(nsAString& aProtocol, ErrorResult& aRv) const override;
-
-  virtual void
-  SetProtocol(const nsAString& aProtocol, ErrorResult& aRv) override;
-
-  virtual void
-  GetUsername(nsAString& aUsername, ErrorResult& aRv) const override;
-
-  virtual void
-  SetUsername(const nsAString& aUsername, ErrorResult& aRv) override;
-
-  virtual void
-  GetPassword(nsAString& aPassword, ErrorResult& aRv) const override;
-
-  virtual void
-  SetPassword(const nsAString& aPassword, ErrorResult& aRv) override;
-
-  virtual void
-  GetHost(nsAString& aHost, ErrorResult& aRv) const override;
-
-  virtual void
-  SetHost(const nsAString& aHost, ErrorResult& aRv) override;
-
-  virtual void
-  GetHostname(nsAString& aHostname, ErrorResult& aRv) const override;
-
-  virtual void
-  SetHostname(const nsAString& aHostname, ErrorResult& aRv) override;
-
-  virtual void
-  GetPort(nsAString& aPort, ErrorResult& aRv) const override;
-
-  virtual void
-  SetPort(const nsAString& aPort, ErrorResult& aRv) override;
-
-  virtual void
-  GetPathname(nsAString& aPathname, ErrorResult& aRv) const override;
-
-  virtual void
-  SetPathname(const nsAString& aPathname, ErrorResult& aRv) override;
-
-  virtual void
-  GetSearch(nsAString& aSearch, ErrorResult& aRv) const override;
-
-  virtual void
-  GetHash(nsAString& aHost, ErrorResult& aRv) const override;
-
-  virtual void
-  SetHash(const nsAString& aHash, ErrorResult& aRv) override;
-
-  virtual void UpdateURLSearchParams() override;
-
-  virtual void
-  SetSearchInternal(const nsAString& aSearch, ErrorResult& aRv) override;
-
-  nsIURI*
-  GetURI() const
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-    return mURI;
-  }
-
-private:
-  ~URLMainThread()
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-  }
-
-  nsCOMPtr<nsIURI> mURI;
-};
-
-/* static */ already_AddRefed<URLMainThread>
-URLMainThread::Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-                           URL& aBase, ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  URLMainThread& base = static_cast<URLMainThread&>(aBase);
-  return Constructor(aGlobal.GetAsSupports(), aURL, base.GetURI(), aRv);
-}
-
-/* static */ already_AddRefed<URLMainThread>
-URLMainThread::Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
-                           const Optional<nsAString>& aBase, ErrorResult& aRv)
-{
-  if (aBase.WasPassed()) {
-    return Constructor(aGlobal.GetAsSupports(), aURL, aBase.Value(), aRv);
-  }
-
-  return Constructor(aGlobal.GetAsSupports(), aURL, nullptr, aRv);
-}
-
-/* static */ already_AddRefed<URLMainThread>
-URLMainThread::Constructor(nsISupports* aParent, const nsAString& aURL,
-                           const nsAString& aBase, ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  nsCOMPtr<nsIURI> baseUri;
-  nsresult rv = NS_NewURI(getter_AddRefs(baseUri), aBase, nullptr, nullptr,
-                          nsContentUtils::GetIOService());
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    aRv.ThrowTypeError<MSG_INVALID_URL>(aBase);
-    return nullptr;
-  }
-
-  return Constructor(aParent, aURL, baseUri, aRv);
-}
-
-/* static */ already_AddRefed<URLMainThread>
-URLMainThread::Constructor(nsISupports* aParent, const nsAString& aURL,
-                           nsIURI* aBase, ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  nsCOMPtr<nsIURI> uri;
-  nsresult rv = NS_NewURI(getter_AddRefs(uri), aURL, nullptr, aBase,
-                          nsContentUtils::GetIOService());
-  if (NS_FAILED(rv)) {
-    // No need to warn in this case. It's common to use the URL constructor
-    // to determine if a URL is valid and an exception will be propagated.
-    aRv.ThrowTypeError<MSG_INVALID_URL>(aURL);
-    return nullptr;
-  }
-
-  RefPtr<URLMainThread> url = new URLMainThread(aParent, uri.forget());
-  return url.forget();
-}
-
-/* static */ void
-URLMainThread::CreateObjectURL(const GlobalObject& aGlobal,
-                               MediaSource& aSource,
-                               nsAString& aResult, ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  nsCOMPtr<nsIPrincipal> principal =
-    nsContentUtils::ObjectPrincipal(aGlobal.Get());
-
-  nsAutoCString url;
-  aRv = nsHostObjectProtocolHandler::AddDataEntry(&aSource, principal, url);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  nsCOMPtr<nsIRunnable> revocation = NS_NewRunnableFunction(
-    [url] {
-      nsHostObjectProtocolHandler::RemoveDataEntry(url);
-    });
-
-  nsContentUtils::RunInStableState(revocation.forget());
-
-  CopyASCIItoUTF16(url, aResult);
-}
-
-/* static */ void
-URLMainThread::RevokeObjectURL(const GlobalObject& aGlobal,
-                               const nsAString& aURL, ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
-  if (!global) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return;
-  }
-
-  nsIPrincipal* principal = nsContentUtils::ObjectPrincipal(aGlobal.Get());
-
-  NS_LossyConvertUTF16toASCII asciiurl(aURL);
-
-  nsIPrincipal* urlPrincipal =
-    nsHostObjectProtocolHandler::GetDataEntryPrincipal(asciiurl);
-
-  if (urlPrincipal && principal->Subsumes(urlPrincipal)) {
-    global->UnregisterHostObjectURI(asciiurl);
-    nsHostObjectProtocolHandler::RemoveDataEntry(asciiurl);
-  }
-}
-
-/* static */ bool
-URLMainThread::IsValidURL(const GlobalObject& aGlobal, const nsAString& aURL,
-                          ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  NS_LossyConvertUTF16toASCII asciiurl(aURL);
-  return nsHostObjectProtocolHandler::HasDataEntry(asciiurl);
-}
-
-void
-URLMainThread::GetHref(nsAString& aHref, ErrorResult& aRv) const
-{
-  aHref.Truncate();
-
-  nsAutoCString href;
-  nsresult rv = mURI->GetSpec(href);
-  if (NS_SUCCEEDED(rv)) {
-    CopyUTF8toUTF16(href, aHref);
-  }
+namespace workers {
+class WorkerPrivate;
 }
 
-void
-URLMainThread::SetHref(const nsAString& aHref, ErrorResult& aRv)
-{
-  NS_ConvertUTF16toUTF8 href(aHref);
-
-  nsresult rv;
-  nsCOMPtr<nsIIOService> ioService(do_GetService(NS_IOSERVICE_CONTRACTID, &rv));
-  if (NS_FAILED(rv)) {
-    aRv.Throw(rv);
-    return;
-  }
-
-  nsCOMPtr<nsIURI> uri;
-  rv = ioService->NewURI(href, nullptr, nullptr, getter_AddRefs(uri));
-  if (NS_FAILED(rv)) {
-    aRv.ThrowTypeError<MSG_INVALID_URL>(aHref);
-    return;
-  }
-
-  mURI = uri;
-  UpdateURLSearchParams();
-}
-
-void
-URLMainThread::GetOrigin(nsAString& aOrigin, ErrorResult& aRv) const
-{
-  nsContentUtils::GetUTFOrigin(mURI, aOrigin);
-}
-
-void
-URLMainThread::GetProtocol(nsAString& aProtocol, ErrorResult& aRv) const
-{
-  nsAutoCString protocol;
-  if (NS_SUCCEEDED(mURI->GetScheme(protocol))) {
-    aProtocol.Truncate();
-  }
-
-  CopyASCIItoUTF16(protocol, aProtocol);
-  aProtocol.Append(char16_t(':'));
-}
-
-void
-URLMainThread::SetProtocol(const nsAString& aProtocol, ErrorResult& aRv)
-{
-  nsAString::const_iterator start, end;
-  aProtocol.BeginReading(start);
-  aProtocol.EndReading(end);
-  nsAString::const_iterator iter(start);
-
-  FindCharInReadable(':', iter, end);
-
-  // Changing the protocol of a URL, changes the "nature" of the URI
-  // implementation. In order to do this properly, we have to serialize the
-  // existing URL and reparse it in a new object.
-  nsCOMPtr<nsIURI> clone;
-  nsresult rv = mURI->Clone(getter_AddRefs(clone));
-  if (NS_WARN_IF(NS_FAILED(rv)) || !clone) {
-    return;
-  }
-
-  rv = clone->SetScheme(NS_ConvertUTF16toUTF8(Substring(start, iter)));
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return;
-  }
-
-  nsAutoCString href;
-  rv = clone->GetSpec(href);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return;
-  }
-
-  nsCOMPtr<nsIURI> uri;
-  rv = NS_NewURI(getter_AddRefs(uri), href);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return;
-  }
-
-  mURI = uri;
-}
-
-#define URL_GETTER( value, func ) \
-  value.Truncate();               \
-  nsAutoCString tmp;              \
-  nsresult rv = mURI->func(tmp);  \
-  if (NS_SUCCEEDED(rv)) {         \
-    CopyUTF8toUTF16(tmp, value);  \
-  }
-
-void
-URLMainThread::GetUsername(nsAString& aUsername, ErrorResult& aRv) const
-{
-  URL_GETTER(aUsername, GetUsername);
-}
-
-void
-URLMainThread::SetUsername(const nsAString& aUsername, ErrorResult& aRv)
-{
-  mURI->SetUsername(NS_ConvertUTF16toUTF8(aUsername));
-}
-
-void
-URLMainThread::GetPassword(nsAString& aPassword, ErrorResult& aRv) const
-{
-  URL_GETTER(aPassword, GetPassword);
-}
-
-void
-URLMainThread::SetPassword(const nsAString& aPassword, ErrorResult& aRv)
-{
-  mURI->SetPassword(NS_ConvertUTF16toUTF8(aPassword));
-}
-
-void
-URLMainThread::GetHost(nsAString& aHost, ErrorResult& aRv) const
-{
-  URL_GETTER(aHost, GetHostPort);
-}
-
-void
-URLMainThread::SetHost(const nsAString& aHost, ErrorResult& aRv)
-{
-  mURI->SetHostPort(NS_ConvertUTF16toUTF8(aHost));
-}
-
-void
-URLMainThread::UpdateURLSearchParams()
-{
-  if (!mSearchParams) {
-    return;
-  }
-
-  nsAutoCString search;
-  nsCOMPtr<nsIURL> url(do_QueryInterface(mURI));
-  if (url) {
-    nsresult rv = url->GetQuery(search);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      search.Truncate();
-    }
-  }
-
-  mSearchParams->ParseInput(search);
-}
-
-void
-URLMainThread::GetHostname(nsAString& aHostname, ErrorResult& aRv) const
-{
-  aHostname.Truncate();
-  nsContentUtils::GetHostOrIPv6WithBrackets(mURI, aHostname);
-}
-
-void
-URLMainThread::SetHostname(const nsAString& aHostname, ErrorResult& aRv)
-{
-  // nsStandardURL returns NS_ERROR_UNEXPECTED for an empty hostname
-  // The return code is silently ignored
-  mURI->SetHost(NS_ConvertUTF16toUTF8(aHostname));
-}
-
-void
-URLMainThread::GetPort(nsAString& aPort, ErrorResult& aRv) const
-{
-  aPort.Truncate();
-
-  int32_t port;
-  nsresult rv = mURI->GetPort(&port);
-  if (NS_SUCCEEDED(rv) && port != -1) {
-    nsAutoString portStr;
-    portStr.AppendInt(port, 10);
-    aPort.Assign(portStr);
-  }
-}
-
-void
-URLMainThread::SetPort(const nsAString& aPort, ErrorResult& aRv)
-{
-  nsresult rv;
-  nsAutoString portStr(aPort);
-  int32_t port = -1;
-
-  // nsIURI uses -1 as default value.
-  if (!portStr.IsEmpty()) {
-    port = portStr.ToInteger(&rv);
-    if (NS_FAILED(rv)) {
-      return;
-    }
-  }
-
-  mURI->SetPort(port);
-}
-
-void
-URLMainThread::GetPathname(nsAString& aPathname, ErrorResult& aRv) const
-{
-  aPathname.Truncate();
-
-  // Do not throw!  Not having a valid URI or URL should result in an empty
-  // string.
-
-  nsAutoCString file;
-  nsresult rv = mURI->GetFilePath(file);
-  if (NS_SUCCEEDED(rv)) {
-    CopyUTF8toUTF16(file, aPathname);
-  }
-}
-
-void
-URLMainThread::SetPathname(const nsAString& aPathname, ErrorResult& aRv)
-{
-  // Do not throw!
-
-  mURI->SetFilePath(NS_ConvertUTF16toUTF8(aPathname));
-}
-
-void
-URLMainThread::GetSearch(nsAString& aSearch, ErrorResult& aRv) const
-{
-  aSearch.Truncate();
-
-  // Do not throw!  Not having a valid URI or URL should result in an empty
-  // string.
-
-  nsAutoCString search;
-  nsresult rv;
-
-  rv = mURI->GetQuery(search);
-  if (NS_SUCCEEDED(rv) && !search.IsEmpty()) {
-    CopyUTF8toUTF16(NS_LITERAL_CSTRING("?") + search, aSearch);
-  }
-}
-
-void
-URLMainThread::GetHash(nsAString& aHash, ErrorResult& aRv) const
-{
-  aHash.Truncate();
-
-  nsAutoCString ref;
-  nsresult rv = mURI->GetRef(ref);
-  if (NS_SUCCEEDED(rv) && !ref.IsEmpty()) {
-    aHash.Assign(char16_t('#'));
-    AppendUTF8toUTF16(ref, aHash);
-  }
-}
-
-void
-URLMainThread::SetHash(const nsAString& aHash, ErrorResult& aRv)
-{
-  mURI->SetRef(NS_ConvertUTF16toUTF8(aHash));
<