Bug 1368955 - Split URL.cpp in URLMainThread.{cpp,h} and URLWorker.{cpp,h}, r=qdot
authorAndrea Marchesini <amarchesini@mozilla.com>
Wed, 31 May 2017 21:18:56 +0200
changeset 409776 7d9c81795eeda760c11c4c8eb217cfecb7699d01
parent 409775 cadb789ebd3972c8e5f65bff0fc12ae61e162e69
child 409777 b0ebe9dd56aeae5db543e72156886bf2404d90c1
push id7391
push usermtabara@mozilla.com
push dateMon, 12 Jun 2017 13:08:53 +0000
treeherdermozilla-beta@2191d7f87e2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersqdot
bugs1368955
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
Bug 1368955 - Split URL.cpp in URLMainThread.{cpp,h} and URLWorker.{cpp,h}, r=qdot
dom/url/URL.cpp
dom/url/URLMainThread.cpp
dom/url/URLMainThread.h
dom/url/URLWorker.cpp
dom/url/URLWorker.h
dom/url/moz.build
--- a/dom/url/URL.cpp
+++ b/dom/url/URL.cpp
@@ -1,1600 +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,
-              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,
-                           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,
-              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> 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();
-  }
-
-  bool
-  MainThreadRun()
-  {
-    AssertIsOnMainThread();
-
-    ErrorResult rv;
-    RefPtr<URLMainThread> url;
-    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,
-                       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)
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,147 +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,
-              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;
-};
+} // 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);
   }
@@ -232,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());
@@ -281,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);
 }
@@ -559,1167 +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,
-              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> 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();
-  }
-
-  bool
-  MainThreadRun()
-  {
-    AssertIsOnMainThread();
-
-    ErrorResult rv;
-    RefPtr<URLMainThread> url;
-    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,
-                       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,
-                 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,66 +1,22 @@
 /* -*- 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,
               const Optional<nsAString>& aBase, ErrorResult& aRv);
 
@@ -69,48 +25,35 @@ public:
               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
@@ -168,1558 +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,
-                           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,
-              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> 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();
-  }
-
-  bool
-  MainThreadRun()
-  {
-    AssertIsOnMainThread();
-
-    ErrorResult rv;
-    RefPtr<URLMainThread> url;
-    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,
-                       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,
-                 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,586 +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,
-              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,
-                           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());
@@ -609,121 +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,
-              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:
@@ -879,17 +217,17 @@ 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> 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)
   {
@@ -914,54 +252,54 @@ public:
       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,
@@ -974,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)
   {
@@ -1051,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,
@@ -1073,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)
@@ -1157,30 +495,30 @@ 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();
 }
 
@@ -1579,147 +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,
-                 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)
+URLWorker::URLProxy*
+URLWorker::GetURLProxy() const
 {
-  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,628 +1,33 @@
 /* -*- 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,
-              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,
-                           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));
-}
-
-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:
+  class URLProxy;
+
   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);
 
@@ -633,17 +38,17 @@ public:
   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);
+  URLWorker(workers::WorkerPrivate* aWorkerPrivate, URLProxy* aURLProxy);
 
   virtual void
   GetHref(nsAString& aHref, ErrorResult& aRv) const override;
 
   virtual void
   SetHref(const nsAString& aHref, ErrorResult& aRv) override;
 
   virtual void
@@ -701,1025 +106,21 @@ public:
   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;
-  }
+  GetURLProxy() const;
 
 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> 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();
-  }
-
-  bool
-  MainThreadRun()
-  {
-    AssertIsOnMainThread();
-
-    ErrorResult rv;
-    RefPtr<URLMainThread> url;
-    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,
-                       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,
-                 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_URLWorker_h
--- a/dom/url/moz.build
+++ b/dom/url/moz.build
@@ -9,17 +9,19 @@ with Files("**"):
 
 EXPORTS.mozilla.dom += [
     'URL.h',
     'URLSearchParams.h',
 ]
 
 UNIFIED_SOURCES += [
     'URL.cpp',
+    'URLMainThread.cpp',
     'URLSearchParams.cpp',
+    'URLWorker.cpp',
 ]
 
 LOCAL_INCLUDES += [
     '../workers',
 ]
 
 MOCHITEST_MANIFESTS += ['tests/mochitest.ini']
 MOCHITEST_CHROME_MANIFESTS += [ 'tests/chrome.ini' ]