Bug 1082734 - Remove URL.searchParams to avoid the stealing of data from future cross-origin sites, r=bz
☠☠ backed out by c9d867500a39 ☠ ☠
authorAndrea Marchesini <amarchesini@mozilla.com>
Thu, 23 Oct 2014 12:48:44 +0100
changeset 211863 2340c1d21e94d56517970e03ad993d692d2a5af2
parent 211862 dc8d30fd13e7cb05a73e492126ad0f6b5592da93
child 211864 6a917dc8e60cd06161a2657361cacbcc6cd48cf9
push id50832
push useramarchesini@mozilla.com
push dateThu, 23 Oct 2014 11:49:06 +0000
treeherdermozilla-inbound@2340c1d21e94 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs1082734
milestone36.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 1082734 - Remove URL.searchParams to avoid the stealing of data from future cross-origin sites, r=bz
browser/components/loop/test/mochitest/loop_fxa.sjs
content/base/src/Link.cpp
content/base/src/Link.h
content/html/content/src/HTMLAnchorElement.cpp
content/html/content/src/HTMLAreaElement.cpp
content/html/content/src/HTMLLinkElement.cpp
content/svg/content/src/SVGAElement.cpp
docshell/base/nsDocShell.cpp
docshell/base/nsDocShell.h
docshell/base/nsIDocShell.idl
dom/base/URL.cpp
dom/base/URL.h
dom/base/URLSearchParams.cpp
dom/base/URLSearchParams.h
dom/base/nsLocation.cpp
dom/base/nsLocation.h
dom/base/test/mochitest.ini
dom/base/test/test_location_searchParams.html
dom/base/test/test_urlSearchParams.html
dom/webidl/Location.webidl
dom/webidl/URLUtils.webidl
dom/workers/URL.cpp
dom/workers/URL.h
dom/workers/test/urlSearchParams_worker.js
mobile/android/chrome/content/WebcompatReporter.js
services/fxaccounts/FxAccountsOAuthClient.jsm
toolkit/components/places/tests/cpp/mock_Link.h
--- a/browser/components/loop/test/mochitest/loop_fxa.sjs
+++ b/browser/components/loop/test/mochitest/loop_fxa.sjs
@@ -6,17 +6,17 @@
  */
 
 "use strict";
 
 const REQUIRED_PARAMS = ["client_id", "content_uri", "oauth_uri", "profile_uri", "state"];
 const HAWK_TOKEN_LENGTH = 64;
 
 Components.utils.import("resource://gre/modules/NetUtil.jsm");
-Components.utils.importGlobalProperties(["URL"]);
+Components.utils.importGlobalProperties(["URL", "URLSearchParams"]);
 
 /**
  * Entry point for HTTP requests.
  */
 function handleRequest(request, response) {
   // Convert the query string to a path with a placeholder base of example.com
   let url = new URL(request.queryString.replace(/%3F.*/,""), "http://www.example.com");
   dump("loop_fxa.sjs request for: " + url.pathname + "\n");
@@ -220,17 +220,18 @@ function delete_registration(request, re
     return;
   }
 
   // Do some query string munging due to the SJS file using a base with a trailing "?"
   // making the path become a query parameter. This is because we aren't actually
   // registering endpoints at the root of the hostname e.g. /registration.
   let url = new URL(request.queryString.replace(/%3F.*/,""), "http://www.example.com");
   let registration = JSON.parse(getSharedState("/registration"));
-  if (registration.simplePushURL == url.searchParams.get("simplePushURL")) {
+  let searchParams = new URLSearchParams(url.search.substr(1));
+  if (registration.simplePushURL == searchParams.get("simplePushURL")) {
     setSharedState("/registration", "");
   } else {
     response.setStatusLine(request.httpVersion, 400, "Bad Request");
   }
 }
 
 /**
  * GET /get_registration
--- a/content/base/src/Link.cpp
+++ b/content/base/src/Link.cpp
@@ -210,23 +210,16 @@ Link::SetPathname(const nsAString &aPath
 
   (void)url->SetFilePath(NS_ConvertUTF16toUTF8(aPathname));
   SetHrefAttribute(uri);
 }
 
 void
 Link::SetSearch(const nsAString& aSearch, ErrorResult& aError)
 {
-  SetSearchInternal(aSearch);
-  UpdateURLSearchParams();
-}
-
-void
-Link::SetSearchInternal(const nsAString& aSearch)
-{
   nsCOMPtr<nsIURI> uri(GetURIToMutate());
   nsCOMPtr<nsIURL> url(do_QueryInterface(uri));
   if (!url) {
     // Ignore failures to be compatible with NS4.
     return;
   }
 
   (void)url->SetQuery(NS_ConvertUTF16toUTF8(aSearch));
@@ -473,17 +466,16 @@ Link::ResetLinkState(bool aNotify, bool 
     UnregisterFromHistory();
   }
 
   // If we have an href, we should register with the history.
   mNeedsRegistration = aHasHref;
 
   // If we've cached the URI, reset always invalidates it.
   mCachedURI = nullptr;
-  UpdateURLSearchParams();
 
   // Update our state back to the default.
   mLinkState = defaultState;
 
   // We have to be very careful here: if aNotify is false we do NOT
   // want to call UpdateState, because that will call into LinkState()
   // and try to start off loads, etc.  But ResetLinkState is called
   // with aNotify false when things are in inconsistent states, so
@@ -562,89 +554,10 @@ Link::SizeOfExcludingThis(mozilla::Mallo
 
   // The following members don't need to be measured:
   // - mElement, because it is a pointer-to-self used to avoid QIs
   // - mHistory, because it is non-owning
 
   return n;
 }
 
-URLSearchParams*
-Link::SearchParams()
-{
-  CreateSearchParamsIfNeeded();
-  return mSearchParams;
-}
-
-void
-Link::SetSearchParams(URLSearchParams& aSearchParams)
-{
-  if (mSearchParams) {
-    mSearchParams->RemoveObserver(this);
-  }
-
-  mSearchParams = &aSearchParams;
-  mSearchParams->AddObserver(this);
-
-  nsAutoString search;
-  mSearchParams->Serialize(search);
-  SetSearchInternal(search);
-}
-
-void
-Link::URLSearchParamsUpdated(URLSearchParams* aSearchParams)
-{
-  MOZ_ASSERT(mSearchParams);
-  MOZ_ASSERT(mSearchParams == aSearchParams);
-
-  nsString search;
-  mSearchParams->Serialize(search);
-  SetSearchInternal(search);
-}
-
-void
-Link::UpdateURLSearchParams()
-{
-  if (!mSearchParams) {
-    return;
-  }
-
-  nsAutoCString search;
-  nsCOMPtr<nsIURI> uri(GetURI());
-  nsCOMPtr<nsIURL> url(do_QueryInterface(uri));
-  if (url) {
-    nsresult rv = url->GetQuery(search);
-    if (NS_FAILED(rv)) {
-      NS_WARNING("Failed to get the query from a nsIURL.");
-    }
-  }
-
-  mSearchParams->ParseInput(search, this);
-}
-
-void
-Link::CreateSearchParamsIfNeeded()
-{
-  if (!mSearchParams) {
-    mSearchParams = new URLSearchParams();
-    mSearchParams->AddObserver(this);
-    UpdateURLSearchParams();
-  }
-}
-
-void
-Link::Unlink()
-{
-  if (mSearchParams) {
-    mSearchParams->RemoveObserver(this);
-    mSearchParams = nullptr;
-  }
-}
-
-void
-Link::Traverse(nsCycleCollectionTraversalCallback &cb)
-{
-  Link* tmp = this;
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSearchParams);
-}
-
 } // namespace dom
 } // namespace mozilla
--- a/content/base/src/Link.h
+++ b/content/base/src/Link.h
@@ -8,32 +8,31 @@
  * This is the base class for all link classes.
  */
 
 #ifndef mozilla_dom_Link_h__
 #define mozilla_dom_Link_h__
 
 #include "mozilla/IHistory.h"
 #include "mozilla/MemoryReporting.h"
-#include "mozilla/dom/URLSearchParams.h"
 #include "nsIContent.h" // for nsLinkState
 
 namespace mozilla {
 
 class EventStates;
 
 namespace dom {
 
 class Element;
 
 #define MOZILLA_DOM_LINK_IMPLEMENTATION_IID               \
 { 0xb25edee6, 0xdd35, 0x4f8b,                             \
   { 0xab, 0x90, 0x66, 0xd0, 0xbd, 0x3c, 0x22, 0xd5 } }
 
-class Link : public URLSearchParamsObserver
+class Link : public nsISupports
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(MOZILLA_DOM_LINK_IMPLEMENTATION_IID)
 
   /**
    * aElement is the element pointer corresponding to this link.
    */
   explicit Link(Element* aElement);
@@ -59,28 +58,26 @@ public:
    */
   void SetProtocol(const nsAString &aProtocol, ErrorResult& aError);
   void SetUsername(const nsAString &aUsername, ErrorResult& aError);
   void SetPassword(const nsAString &aPassword, ErrorResult& aError);
   void SetHost(const nsAString &aHost, ErrorResult& aError);
   void SetHostname(const nsAString &aHostname, ErrorResult& aError);
   void SetPathname(const nsAString &aPathname, ErrorResult& aError);
   void SetSearch(const nsAString &aSearch, ErrorResult& aError);
-  void SetSearchParams(mozilla::dom::URLSearchParams& aSearchParams);
   void SetPort(const nsAString &aPort, ErrorResult& aError);
   void SetHash(const nsAString &aHash, ErrorResult& aError);
   void GetOrigin(nsAString &aOrigin, ErrorResult& aError);
   void GetProtocol(nsAString &_protocol, ErrorResult& aError);
   void GetUsername(nsAString &aUsername, ErrorResult& aError);
   void GetPassword(nsAString &aPassword, ErrorResult& aError);
   void GetHost(nsAString &_host, ErrorResult& aError);
   void GetHostname(nsAString &_hostname, ErrorResult& aError);
   void GetPathname(nsAString &_pathname, ErrorResult& aError);
   void GetSearch(nsAString &_search, ErrorResult& aError);
-  URLSearchParams* SearchParams();
   void GetPort(nsAString &_port, ErrorResult& aError);
   void GetHash(nsAString &_hash, ErrorResult& aError);
 
   /**
    * Invalidates any link caching, and resets the state to the default.
    *
    * @param aNotify
    *        true if ResetLinkState should notify the owning document about style
@@ -109,19 +106,16 @@ public:
    */
   virtual bool HasDeferredDNSPrefetchRequest() { return true; }
 
   virtual size_t
     SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
 
   bool ElementHasHref() const;
 
-  // URLSearchParamsObserver
-  void URLSearchParamsUpdated(URLSearchParams* aSearchParams) MOZ_OVERRIDE;
-
 protected:
   virtual ~Link();
 
   /**
    * Return true if the link has associated URI.
    */
   bool HasURI() const
   {
@@ -130,52 +124,39 @@ protected:
     }
 
     return !!GetURI();
   }
 
   nsIURI* GetCachedURI() const { return mCachedURI; }
   bool HasCachedURI() const { return !!mCachedURI; }
 
-  void UpdateURLSearchParams();
-
-  // CC methods
-  void Unlink();
-  void Traverse(nsCycleCollectionTraversalCallback &cb);
-
 private:
   /**
    * Unregisters from History so this node no longer gets notifications about
    * changes to visitedness.
    */
   void UnregisterFromHistory();
 
   already_AddRefed<nsIURI> GetURIToMutate();
   void SetHrefAttribute(nsIURI *aURI);
 
-  void CreateSearchParamsIfNeeded();
-
-  void SetSearchInternal(const nsAString& aSearch);
-
   mutable nsCOMPtr<nsIURI> mCachedURI;
 
   Element * const mElement;
 
   // Strong reference to History.  The link has to unregister before History
   // can disappear.
   nsCOMPtr<IHistory> mHistory;
 
   uint16_t mLinkState;
 
   bool mNeedsRegistration;
 
   bool mRegistered;
-
-protected:
-  nsRefPtr<URLSearchParams> mSearchParams;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(Link, MOZILLA_DOM_LINK_IMPLEMENTATION_IID)
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_Link_h__
--- a/content/html/content/src/HTMLAnchorElement.cpp
+++ b/content/html/content/src/HTMLAnchorElement.cpp
@@ -51,23 +51,21 @@ NS_INTERFACE_TABLE_TAIL_INHERITING(nsGen
 
 NS_IMPL_ADDREF_INHERITED(HTMLAnchorElement, Element)
 NS_IMPL_RELEASE_INHERITED(HTMLAnchorElement, Element)
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(HTMLAnchorElement)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLAnchorElement,
                                                   nsGenericHTMLElement)
-  tmp->Link::Traverse(cb);
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRelList)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLAnchorElement,
                                                 nsGenericHTMLElement)
-  tmp->Link::Unlink();
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mRelList)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_ELEMENT_CLONE(HTMLAnchorElement)
 
 JSObject*
 HTMLAnchorElement::WrapNode(JSContext *aCx)
 {
--- a/content/html/content/src/HTMLAreaElement.cpp
+++ b/content/html/content/src/HTMLAreaElement.cpp
@@ -35,23 +35,21 @@ NS_INTERFACE_TABLE_TAIL_INHERITING(nsGen
 
 NS_IMPL_ADDREF_INHERITED(HTMLAreaElement, Element)
 NS_IMPL_RELEASE_INHERITED(HTMLAreaElement, Element)
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(HTMLAreaElement)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLAreaElement,
                                                   nsGenericHTMLElement)
-  tmp->Link::Traverse(cb);
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRelList)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLAreaElement,
                                                 nsGenericHTMLElement)
-  tmp->Link::Unlink();
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mRelList)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_ELEMENT_CLONE(HTMLAreaElement)
 
 
 NS_IMPL_STRING_ATTR(HTMLAreaElement, Alt, alt)
 NS_IMPL_STRING_ATTR(HTMLAreaElement, Coords, coords)
--- a/content/html/content/src/HTMLLinkElement.cpp
+++ b/content/html/content/src/HTMLLinkElement.cpp
@@ -45,25 +45,23 @@ HTMLLinkElement::~HTMLLinkElement()
 {
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(HTMLLinkElement)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLLinkElement,
                                                   nsGenericHTMLElement)
   tmp->nsStyleLinkElement::Traverse(cb);
-  tmp->Link::Traverse(cb);
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRelList)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mImportLoader)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLLinkElement,
                                                 nsGenericHTMLElement)
   tmp->nsStyleLinkElement::Unlink();
-  tmp->Link::Unlink();
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mRelList)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mImportLoader)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_ADDREF_INHERITED(HTMLLinkElement, Element)
 NS_IMPL_RELEASE_INHERITED(HTMLLinkElement, Element)
 
 
--- a/content/svg/content/src/SVGAElement.cpp
+++ b/content/svg/content/src/SVGAElement.cpp
@@ -43,22 +43,20 @@ NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION
                                nsIDOMSVGElement,
                                Link)
 NS_INTERFACE_TABLE_TAIL_INHERITING(SVGAElementBase)
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(SVGAElement)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(SVGAElement,
                                                   SVGAElementBase)
-  tmp->Link::Traverse(cb);
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(SVGAElement,
                                                 SVGAElementBase)
-  tmp->Link::Unlink();
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_ADDREF_INHERITED(SVGAElement, SVGAElementBase)
 NS_IMPL_RELEASE_INHERITED(SVGAElement, SVGAElementBase)
 
 //----------------------------------------------------------------------
 // Implementation
 
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -188,17 +188,16 @@
 #include "nsIStringBundle.h"
 #include "nsISupportsArray.h"
 #include "nsIURIFixup.h"
 #include "nsIURILoader.h"
 #include "nsIWebBrowserFind.h"
 #include "nsIWidget.h"
 #include "mozilla/dom/EncodingUtils.h"
 #include "mozilla/dom/ScriptSettings.h"
-#include "mozilla/dom/URLSearchParams.h"
 
 #ifdef MOZ_TOOLKIT_SEARCH
 #include "nsIBrowserSearchService.h"
 #endif
 
 static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
 
 #if defined(DEBUG_bryner) || defined(DEBUG_chb)
@@ -1955,34 +1954,16 @@ nsDocShell::SetCurrentURI(nsIURI *aURI, 
     {
         // This is the root docshell
         isRoot = true;
     }
     if (mLSHE) {
         mLSHE->GetIsSubFrame(&isSubFrame);
     }
 
-    // nsDocShell owns a URLSearchParams that is used by
-    // window.location.searchParams to be in sync with the current location.
-    if (!mURLSearchParams) {
-      mURLSearchParams = new URLSearchParams();
-    }
-
-    nsAutoCString search;
-
-    nsCOMPtr<nsIURL> url(do_QueryInterface(mCurrentURI));
-    if (url) {
-      nsresult rv = url->GetQuery(search);
-      if (NS_FAILED(rv)) {
-        NS_WARNING("Failed to get the query from a nsIURL.");
-      }
-    }
-
-    mURLSearchParams->ParseInput(search, nullptr);
-
     if (!isSubFrame && !isRoot) {
       /* 
        * We don't want to send OnLocationChange notifications when
        * a subframe is being loaded for the first time, while
        * visiting a frameset page
        */
       return false; 
     }
@@ -5626,21 +5607,16 @@ nsDocShell::Destroy()
         mContentViewer = nullptr;
     }
 
     nsDocLoader::Destroy();
     
     mParentWidget = nullptr;
     mCurrentURI = nullptr;
 
-    if (mURLSearchParams) {
-      mURLSearchParams->RemoveObservers();
-      mURLSearchParams = nullptr;
-    }
-
     if (mScriptGlobal) {
         mScriptGlobal->DetachFromDocShell();
         mScriptGlobal = nullptr;
     }
 
     if (mSessionHistory) {
         // We want to destroy these content viewers now rather than
         // letting their destruction wait for the session history
@@ -13549,22 +13525,16 @@ nsDocShell::SetOpenedRemote(nsITabParent
 
 nsITabParent*
 nsDocShell::GetOpenedRemote()
 {
   nsCOMPtr<nsITabParent> openedRemote(do_QueryReferent(mOpenedRemote));
   return openedRemote;
 }
 
-URLSearchParams*
-nsDocShell::GetURLSearchParams()
-{
-  return mURLSearchParams;
-}
-
 void
 nsDocShell::MaybeNotifyKeywordSearchLoading(const nsString &aProvider,
                                             const nsString &aKeyword) {
 
   if (aProvider.IsEmpty()) {
     return;
   }
 
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -52,17 +52,16 @@
 #include "nsCRT.h"
 #include "prtime.h"
 #include "nsRect.h"
 #include "Units.h"
 
 namespace mozilla {
 namespace dom {
 class EventTarget;
-class URLSearchParams;
 }
 }
 
 class nsDocShell;
 class nsDOMNavigationTiming;
 class nsGlobalWindow;
 class nsIController;
 class nsIScrollableFrame;
@@ -792,19 +791,16 @@ protected:
 
     // Set in LoadErrorPage from the method argument and used later
     // in CreateContentViewer. We have to delay an shistory entry creation
     // for which these objects are needed.
     nsCOMPtr<nsIURI>           mFailedURI;
     nsCOMPtr<nsIChannel>       mFailedChannel;
     uint32_t                   mFailedLoadType;
 
-    // window.location.searchParams is updated in sync with this object.
-    nsRefPtr<mozilla::dom::URLSearchParams> mURLSearchParams;
-
     // Set in DoURILoad when either the LOAD_RELOAD_ALLOW_MIXED_CONTENT flag or
     // the LOAD_NORMAL_ALLOW_MIXED_CONTENT flag is set.
     // Checked in nsMixedContentBlocker, to see if the channels match.
     nsCOMPtr<nsIChannel>       mMixedContentChannel;
 
     // WEAK REFERENCES BELOW HERE.
     // Note these are intentionally not addrefd.  Doing so will create a cycle.
     // For that reasons don't use nsCOMPtr.
--- a/docshell/base/nsIDocShell.idl
+++ b/docshell/base/nsIDocShell.idl
@@ -7,31 +7,24 @@
 #include "domstubs.idl"
 #include "nsIDocShellTreeItem.idl"
 
 %{ C++
 #include "js/TypeDecls.h"
 class nsPresContext;
 class nsIPresShell;
 
-namespace mozilla {
-namespace dom {
-class URLSearchParams;
-}
-}
-
 %}
 
 /**
  * The nsIDocShell interface.
  */
 
 [ptr] native nsPresContext(nsPresContext);
 [ptr] native nsIPresShell(nsIPresShell);
-[ptr] native URLSearchParams(mozilla::dom::URLSearchParams);
 
 interface nsIURI;
 interface nsIChannel;
 interface nsIContentViewer;
 interface nsIURIContentListener;
 interface nsIDOMEventTarget;
 interface nsIDocShellLoadInfo;
 interface nsIEditor;
@@ -49,17 +42,17 @@ interface nsIWebBrowserPrint;
 interface nsIVariant;
 interface nsIPrivacyTransitionObserver;
 interface nsIReflowObserver;
 interface nsIScrollObserver;
 interface nsITabParent;
  
 typedef unsigned long nsLoadFlags;
 
-[scriptable, builtinclass, uuid(da8f78f1-8f20-4d6d-be56-fe53e177b630)]
+[scriptable, builtinclass, uuid(cecf29f4-3eee-41ff-a76b-b36c73e271b1)]
 interface nsIDocShell : nsIDocShellTreeItem
 {
   /**
    * Loads a given URI.  This will give priority to loading the requested URI
    * in the object implementing	this interface.  If it can't be loaded here
    * however, the URL dispatcher will go through its normal process of content
    * loading.
    *
@@ -1018,18 +1011,15 @@ interface nsIDocShell : nsIDocShellTreeI
 
   /**
    * See the documentation for setOpener and getOpener about why we
    * don't use attribute here instead.
    */
   [noscript,notxpcom,nostdcall] void setOpenedRemote(in nsITabParent aOpenedRemote);
   [noscript,notxpcom,nostdcall] nsITabParent getOpenedRemote();
 
-  // URLSearchParams for the window.location is owned by the docShell.
-  [noscript,notxpcom] URLSearchParams getURLSearchParams();
-
   /**
    * This attribute determines whether a document which is not about:blank has
    * already be loaded by this docShell.
    */
   [infallible] readonly attribute boolean hasLoadedNonBlankURI;
 
 };
--- a/dom/base/URL.cpp
+++ b/dom/base/URL.cpp
@@ -19,24 +19,19 @@
 #include "nsIURL.h"
 
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(URL)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(URL)
-  if (tmp->mSearchParams) {
-    tmp->mSearchParams->RemoveObserver(tmp);
-    NS_IMPL_CYCLE_COLLECTION_UNLINK(mSearchParams)
-  }
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(URL)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSearchParams)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(URL)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(URL)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(URL)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
@@ -228,17 +223,16 @@ URL::SetHref(const nsAString& aHref, Err
   rv = ioService->NewURI(href, nullptr, nullptr, getter_AddRefs(uri));
   if (NS_FAILED(rv)) {
     nsAutoString label(aHref);
     aRv.ThrowTypeError(MSG_INVALID_URL, &label);
     return;
   }
 
   mURI = uri;
-  UpdateURLSearchParams();
 }
 
 void
 URL::GetOrigin(nsString& aOrigin, ErrorResult& aRv) const
 {
   nsCOMPtr<nsIURIWithPrincipal> uriWithPrincipal = do_QueryInterface(mURI);
   if (uriWithPrincipal) {
     nsCOMPtr<nsIPrincipal> principal;
@@ -344,46 +338,16 @@ URL::GetHost(nsString& aHost, ErrorResul
 
 void
 URL::SetHost(const nsAString& aHost, ErrorResult& aRv)
 {
   mURI->SetHostPort(NS_ConvertUTF16toUTF8(aHost));
 }
 
 void
-URL::URLSearchParamsUpdated(URLSearchParams* aSearchParams)
-{
-  MOZ_ASSERT(mSearchParams);
-  MOZ_ASSERT(mSearchParams == aSearchParams);
-
-  nsAutoString search;
-  mSearchParams->Serialize(search);
-  SetSearchInternal(search);
-}
-
-void
-URL::UpdateURLSearchParams()
-{
-  if (!mSearchParams) {
-    return;
-  }
-
-  nsAutoCString search;
-  nsCOMPtr<nsIURL> url(do_QueryInterface(mURI));
-  if (url) {
-    nsresult rv = url->GetQuery(search);
-    if (NS_FAILED(rv)) {
-      NS_WARNING("Failed to get the query from a nsIURL.");
-    }
-  }
-
-  mSearchParams->ParseInput(search, this);
-}
-
-void
 URL::GetHostname(nsString& aHostname, ErrorResult& aRv) const
 {
   aHostname.Truncate();
   nsContentUtils::GetHostOrIPv6WithBrackets(mURI, aHostname);
 }
 
 void
 URL::SetHostname(const nsAString& aHostname, ErrorResult& aRv)
@@ -473,55 +437,25 @@ URL::GetSearch(nsString& aSearch, ErrorR
   if (NS_SUCCEEDED(rv) && !search.IsEmpty()) {
     CopyUTF8toUTF16(NS_LITERAL_CSTRING("?") + search, aSearch);
   }
 }
 
 void
 URL::SetSearch(const nsAString& aSearch, ErrorResult& aRv)
 {
-  SetSearchInternal(aSearch);
-  UpdateURLSearchParams();
-}
-
-void
-URL::SetSearchInternal(const nsAString& aSearch)
-{
   nsCOMPtr<nsIURL> url(do_QueryInterface(mURI));
   if (!url) {
     // Ignore failures to be compatible with NS4.
     return;
   }
 
   url->SetQuery(NS_ConvertUTF16toUTF8(aSearch));
 }
 
-URLSearchParams*
-URL::SearchParams()
-{
-  CreateSearchParamsIfNeeded();
-  return mSearchParams;
-}
-
-void
-URL::SetSearchParams(URLSearchParams& aSearchParams)
-{
-  if (mSearchParams) {
-    mSearchParams->RemoveObserver(this);
-  }
-
-  // the observer will be cleared using the cycle collector.
-  mSearchParams = &aSearchParams;
-  mSearchParams->AddObserver(this);
-
-  nsAutoString search;
-  mSearchParams->Serialize(search);
-  SetSearchInternal(search);
-}
-
 void
 URL::GetHash(nsString& aHash, ErrorResult& aRv) const
 {
   aHash.Truncate();
 
   nsAutoCString ref;
   nsresult rv = mURI->GetRef(ref);
   if (NS_SUCCEEDED(rv) && !ref.IsEmpty()) {
@@ -540,20 +474,10 @@ URL::SetHash(const nsAString& aHash, Err
 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();
-    mSearchParams->AddObserver(this);
-    UpdateURLSearchParams();
-  }
-}
-
 }
 }
--- a/dom/base/URL.h
+++ b/dom/base/URL.h
@@ -1,17 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #ifndef URL_h___
 #define URL_h___
 
 #include "mozilla/dom/BindingDeclarations.h"
-#include "mozilla/dom/URLSearchParams.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsAutoPtr.h"
 #include "nsString.h"
 
 class nsIDOMBlob;
 class nsIPrincipal;
 class nsISupports;
 class nsIURI;
@@ -27,17 +26,17 @@ class File;
 class MediaSource;
 class GlobalObject;
 struct objectURLOptions;
 
 namespace workers {
 class URLProxy;
 }
 
-class URL MOZ_FINAL : public URLSearchParamsObserver
+class URL MOZ_FINAL : public nsISupports
 {
   ~URL() {}
 
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS(URL)
 
   explicit URL(nsIURI* aURI);
@@ -104,53 +103,39 @@ public:
   void GetPathname(nsString& aPathname, ErrorResult& aRv) const;
 
   void SetPathname(const nsAString& aPathname, ErrorResult& aRv);
 
   void GetSearch(nsString& aRetval, ErrorResult& aRv) const;
 
   void SetSearch(const nsAString& aArg, ErrorResult& aRv);
 
-  URLSearchParams* SearchParams();
-
-  void SetSearchParams(URLSearchParams& aSearchParams);
-
   void GetHash(nsString& aRetval, ErrorResult& aRv) const;
 
   void SetHash(const nsAString& aArg, ErrorResult& aRv);
 
   void Stringify(nsString& aRetval, ErrorResult& aRv) const
   {
     GetHref(aRetval, aRv);
   }
 
-  // URLSearchParamsObserver
-  void URLSearchParamsUpdated(URLSearchParams* aSearchParams) MOZ_OVERRIDE;
-
 private:
   nsIURI* GetURI() const
   {
     return mURI;
   }
 
-  void CreateSearchParamsIfNeeded();
-
-  void SetSearchInternal(const nsAString& aSearch);
-
-  void UpdateURLSearchParams();
-
   static void CreateObjectURLInternal(const GlobalObject& aGlobal,
                                       nsISupports* aObject,
                                       const nsACString& aScheme,
                                       const objectURLOptions& aOptions,
                                       nsString& aResult,
                                       ErrorResult& aError);
 
   nsCOMPtr<nsIURI> mURI;
-  nsRefPtr<URLSearchParams> mSearchParams;
 
   friend class mozilla::dom::workers::URLProxy;
 };
 
 bool IsChromeURI(nsIURI* aURI);
 
 }
 }
--- a/dom/base/URLSearchParams.cpp
+++ b/dom/base/URLSearchParams.cpp
@@ -6,17 +6,17 @@
 #include "URLSearchParams.h"
 #include "mozilla/dom/URLSearchParamsBinding.h"
 #include "mozilla/dom/EncodingUtils.h"
 #include "nsDOMString.h"
 
 namespace mozilla {
 namespace dom {
 
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(URLSearchParams, mObservers)
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(URLSearchParams)
 NS_IMPL_CYCLE_COLLECTING_ADDREF(URLSearchParams)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(URLSearchParams)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(URLSearchParams)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
@@ -36,33 +36,32 @@ URLSearchParams::WrapObject(JSContext* a
 }
 
 /* static */ already_AddRefed<URLSearchParams>
 URLSearchParams::Constructor(const GlobalObject& aGlobal,
                              const nsAString& aInit,
                              ErrorResult& aRv)
 {
   nsRefPtr<URLSearchParams> sp = new URLSearchParams();
-  sp->ParseInput(NS_ConvertUTF16toUTF8(aInit), nullptr);
+  sp->ParseInput(NS_ConvertUTF16toUTF8(aInit));
   return sp.forget();
 }
 
 /* static */ already_AddRefed<URLSearchParams>
 URLSearchParams::Constructor(const GlobalObject& aGlobal,
                              URLSearchParams& aInit,
                              ErrorResult& aRv)
 {
   nsRefPtr<URLSearchParams> sp = new URLSearchParams();
   sp->mSearchParams = aInit.mSearchParams;
   return sp.forget();
 }
 
 void
-URLSearchParams::ParseInput(const nsACString& aInput,
-                            URLSearchParamsObserver* aObserver)
+URLSearchParams::ParseInput(const nsACString& aInput)
 {
   // Remove all the existing data before parsing a new input.
   DeleteAll();
 
   nsACString::const_iterator start, end;
   aInput.BeginReading(start);
   aInput.EndReading(end);
   nsACString::const_iterator iter(start);
@@ -100,20 +99,18 @@ URLSearchParams::ParseInput(const nsACSt
     }
 
     nsAutoString decodedName;
     DecodeString(name, decodedName);
 
     nsAutoString decodedValue;
     DecodeString(value, decodedValue);
 
-    AppendInternal(decodedName, decodedValue);
+    Append(decodedName, decodedValue);
   }
-
-  NotifyObservers(aObserver);
 }
 
 void
 URLSearchParams::DecodeString(const nsACString& aInput, nsAString& aOutput)
 {
   nsACString::const_iterator start, end;
   aInput.BeginReading(start);
   aInput.EndReading(end);
@@ -203,37 +200,16 @@ URLSearchParams::ConvertString(const nsA
   }
 
   if (newOutputLength < outputLength) {
     aOutput.Truncate(newOutputLength);
   }
 }
 
 void
-URLSearchParams::AddObserver(URLSearchParamsObserver* aObserver)
-{
-  MOZ_ASSERT(aObserver);
-  MOZ_ASSERT(!mObservers.Contains(aObserver));
-  mObservers.AppendElement(aObserver);
-}
-
-void
-URLSearchParams::RemoveObserver(URLSearchParamsObserver* aObserver)
-{
-  MOZ_ASSERT(aObserver);
-  mObservers.RemoveElement(aObserver);
-}
-
-void
-URLSearchParams::RemoveObservers()
-{
-  mObservers.Clear();
-}
-
-void
 URLSearchParams::Get(const nsAString& aName, nsString& aRetval)
 {
   SetDOMStringToNull(aRetval);
 
   for (uint32_t i = 0, len = mSearchParams.Length(); i < len; ++i) {
     if (mSearchParams[i].mKey.Equals(aName)) {
       aRetval.Assign(mSearchParams[i].mValue);
       break;
@@ -273,30 +249,21 @@ URLSearchParams::Set(const nsAString& aN
   }
 
   if (!param) {
     param = mSearchParams.AppendElement();
     param->mKey = aName;
   }
 
   param->mValue = aValue;
-
-  NotifyObservers(nullptr);
 }
 
 void
 URLSearchParams::Append(const nsAString& aName, const nsAString& aValue)
 {
-  AppendInternal(aName, aValue);
-  NotifyObservers(nullptr);
-}
-
-void
-URLSearchParams::AppendInternal(const nsAString& aName, const nsAString& aValue)
-{
   Param* param = mSearchParams.AppendElement();
   param->mKey = aName;
   param->mValue = aValue;
 }
 
 bool
 URLSearchParams::Has(const nsAString& aName)
 {
@@ -307,29 +274,23 @@ URLSearchParams::Has(const nsAString& aN
   }
 
   return false;
 }
 
 void
 URLSearchParams::Delete(const nsAString& aName)
 {
-  bool found = false;
   for (uint32_t i = 0; i < mSearchParams.Length();) {
     if (mSearchParams[i].mKey.Equals(aName)) {
       mSearchParams.RemoveElementAt(i);
-      found = true;
     } else {
       ++i;
     }
   }
-
-  if (found) {
-    NotifyObservers(nullptr);
-  }
 }
 
 void
 URLSearchParams::DeleteAll()
 {
   mSearchParams.Clear();
 }
 
@@ -373,20 +334,10 @@ URLSearchParams::Serialize(nsAString& aV
     }
 
     SerializeString(NS_ConvertUTF16toUTF8(mSearchParams[i].mKey), aValue);
     aValue.Append('=');
     SerializeString(NS_ConvertUTF16toUTF8(mSearchParams[i].mValue), aValue);
   }
 }
 
-void
-URLSearchParams::NotifyObservers(URLSearchParamsObserver* aExceptObserver)
-{
-  for (uint32_t i = 0; i < mObservers.Length(); ++i) {
-    if (mObservers[i] != aExceptObserver) {
-      mObservers[i]->URLSearchParamsUpdated(this);
-    }
-  }
-}
-
 } // namespace dom
 } // namespace mozilla
--- a/dom/base/URLSearchParams.h
+++ b/dom/base/URLSearchParams.h
@@ -13,24 +13,16 @@
 #include "nsISupports.h"
 #include "nsIUnicodeDecoder.h"
 
 namespace mozilla {
 namespace dom {
 
 class URLSearchParams;
 
-class URLSearchParamsObserver : public nsISupports
-{
-public:
-  virtual ~URLSearchParamsObserver() {}
-
-  virtual void URLSearchParamsUpdated(URLSearchParams* aFromThis) = 0;
-};
-
 class URLSearchParams MOZ_FINAL : public nsISupports,
                                   public nsWrapperCache
 {
   ~URLSearchParams();
 
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(URLSearchParams)
@@ -49,22 +41,17 @@ public:
   static already_AddRefed<URLSearchParams>
   Constructor(const GlobalObject& aGlobal, const nsAString& aInit,
               ErrorResult& aRv);
 
   static already_AddRefed<URLSearchParams>
   Constructor(const GlobalObject& aGlobal, URLSearchParams& aInit,
               ErrorResult& aRv);
 
-  void ParseInput(const nsACString& aInput,
-                  URLSearchParamsObserver* aObserver);
-
-  void AddObserver(URLSearchParamsObserver* aObserver);
-  void RemoveObserver(URLSearchParamsObserver* aObserver);
-  void RemoveObservers();
+  void ParseInput(const nsACString& aInput);
 
   void Serialize(nsAString& aValue) const;
 
   void Get(const nsAString& aName, nsString& aRetval);
 
   void GetAll(const nsAString& aName, nsTArray<nsString >& aRetval);
 
   void Set(const nsAString& aName, const nsAString& aValue);
@@ -76,33 +63,28 @@ public:
   void Delete(const nsAString& aName);
 
   void Stringify(nsString& aRetval) const
   {
     Serialize(aRetval);
   }
 
 private:
-  void AppendInternal(const nsAString& aName, const nsAString& aValue);
-
   void DeleteAll();
 
   void DecodeString(const nsACString& aInput, nsAString& aOutput);
   void ConvertString(const nsACString& aInput, nsAString& aOutput);
 
-  void NotifyObservers(URLSearchParamsObserver* aExceptObserver);
-
   struct Param
   {
     nsString mKey;
     nsString mValue;
   };
 
   nsTArray<Param> mSearchParams;
 
-  nsTArray<nsRefPtr<URLSearchParamsObserver>> mObservers;
   nsCOMPtr<nsIUnicodeDecoder> mDecoder;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif /* mozilla_dom_URLSearchParams_h */
--- a/dom/base/nsLocation.cpp
+++ b/dom/base/nsLocation.cpp
@@ -56,37 +56,33 @@ nsLocation::nsLocation(nsPIDOMWindow* aW
   MOZ_ASSERT(aDocShell);
   MOZ_ASSERT(mInnerWindow->IsInnerWindow());
 
   mDocShell = do_GetWeakReference(aDocShell);
 }
 
 nsLocation::~nsLocation()
 {
-  RemoveURLSearchParams();
 }
 
 // QueryInterface implementation for nsLocation
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsLocation)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsIDOMLocation)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMLocation)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsLocation)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsLocation)
-  tmp->RemoveURLSearchParams();
-
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mInnerWindow);
   NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsLocation)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSearchParams)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mInnerWindow)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(nsLocation)
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsLocation)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsLocation)
@@ -1041,124 +1037,8 @@ nsLocation::CallerSubsumes()
   return subsumes;
 }
 
 JSObject*
 nsLocation::WrapObject(JSContext* aCx)
 {
   return LocationBinding::Wrap(aCx, this);
 }
-
-URLSearchParams*
-nsLocation::GetDocShellSearchParams()
-{
-  nsCOMPtr<nsIDocShell> docShell = GetDocShell();
-  if (!docShell) {
-    return nullptr;
-  }
-
-  return docShell->GetURLSearchParams();
-}
-
-URLSearchParams*
-nsLocation::SearchParams()
-{
-  if (!mSearchParams) {
-    // We must register this object to the URLSearchParams of the docshell in
-    // order to receive updates.
-    nsRefPtr<URLSearchParams> searchParams = GetDocShellSearchParams();
-    if (searchParams) {
-      searchParams->AddObserver(this);
-    }
-
-    mSearchParams = new URLSearchParams();
-    mSearchParams->AddObserver(this);
-    UpdateURLSearchParams();
-  }
-
-  return mSearchParams;
-}
-
-void
-nsLocation::SetSearchParams(URLSearchParams& aSearchParams)
-{
-  if (mSearchParams) {
-    mSearchParams->RemoveObserver(this);
-  }
-
-  // the observer will be cleared using the cycle collector.
-  mSearchParams = &aSearchParams;
-  mSearchParams->AddObserver(this);
-
-  nsAutoString search;
-  mSearchParams->Serialize(search);
-  SetSearchInternal(search);
-
-  // We don't need to inform the docShell about this new SearchParams because
-  // setting the new value the docShell will refresh its value automatically.
-}
-
-void
-nsLocation::URLSearchParamsUpdated(URLSearchParams* aSearchParams)
-{
-  MOZ_ASSERT(mSearchParams);
-
-  // This change comes from content.
-  if (aSearchParams == mSearchParams) {
-    nsAutoString search;
-    mSearchParams->Serialize(search);
-    SetSearchInternal(search);
-    return;
-  }
-
-  // This change comes from the docShell.
-#ifdef DEBUG
-  {
-    nsRefPtr<URLSearchParams> searchParams = GetDocShellSearchParams();
-    MOZ_ASSERT(searchParams);
-    MOZ_ASSERT(aSearchParams == searchParams);
-  }
-#endif
-
-  nsAutoString search;
-  aSearchParams->Serialize(search);
-  mSearchParams->ParseInput(NS_ConvertUTF16toUTF8(search), this);
-}
-
-void
-nsLocation::UpdateURLSearchParams()
-{
-  if (!mSearchParams) {
-    return;
-  }
-
-  nsAutoCString search;
-
-  nsCOMPtr<nsIURI> uri;
-  nsresult rv = GetURI(getter_AddRefs(uri));
-  if (NS_WARN_IF(NS_FAILED(rv)) || NS_WARN_IF(!uri)) {
-    return;
-  }
-
-  nsCOMPtr<nsIURL> url(do_QueryInterface(uri));
-  if (url) {
-    nsresult rv = url->GetQuery(search);
-    if (NS_FAILED(rv)) {
-      NS_WARNING("Failed to get the query from a nsIURL.");
-    }
-  }
-
-  mSearchParams->ParseInput(search, this);
-}
-
-void
-nsLocation::RemoveURLSearchParams()
-{
-  if (mSearchParams) {
-    mSearchParams->RemoveObserver(this);
-    mSearchParams = nullptr;
-
-    nsRefPtr<URLSearchParams> docShellSearchParams = GetDocShellSearchParams();
-    if (docShellSearchParams) {
-      docShellSearchParams->RemoveObserver(this);
-    }
-  }
-}
--- a/dom/base/nsLocation.h
+++ b/dom/base/nsLocation.h
@@ -9,30 +9,28 @@
 
 #include "nsIDOMLocation.h"
 #include "nsString.h"
 #include "nsIWeakReferenceUtils.h"
 #include "nsWrapperCache.h"
 #include "nsCycleCollectionParticipant.h"
 #include "js/TypeDecls.h"
 #include "mozilla/ErrorResult.h"
-#include "mozilla/dom/URLSearchParams.h"
 #include "nsPIDOMWindow.h"
 
 class nsIURI;
 class nsIDocShell;
 class nsIDocShellLoadInfo;
 
 //*****************************************************************************
 // nsLocation: Script "location" object
 //*****************************************************************************
 
 class nsLocation MOZ_FINAL : public nsIDOMLocation
                            , public nsWrapperCache
-                           , public mozilla::dom::URLSearchParamsObserver
 {
   typedef mozilla::ErrorResult ErrorResult;
 
 public:
   nsLocation(nsPIDOMWindow* aWindow, nsIDocShell *aDocShell);
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsLocation,
@@ -117,20 +115,16 @@ public:
   {
     aError = GetSearch(aSeach);
   }
   void SetSearch(const nsAString& aSeach, ErrorResult& aError)
   {
     aError = SetSearch(aSeach);
   }
 
-  mozilla::dom::URLSearchParams* SearchParams();
-
-  void SetSearchParams(mozilla::dom::URLSearchParams& aSearchParams);
-
   void GetHash(nsAString& aHash, ErrorResult& aError)
   {
     aError = GetHash(aHash);
   }
   void SetHash(const nsAString& aHash, ErrorResult& aError)
   {
     aError = SetHash(aHash);
   }
@@ -139,27 +133,20 @@ public:
     GetHref(aRetval, aError);
   }
   nsPIDOMWindow* GetParentObject() const
   {
     return mInnerWindow;
   }
   virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
 
-  // URLSearchParamsObserver
-  void URLSearchParamsUpdated(mozilla::dom::URLSearchParams* aSearchParams) MOZ_OVERRIDE;
-
 protected:
   virtual ~nsLocation();
 
   nsresult SetSearchInternal(const nsAString& aSearch);
-  void UpdateURLSearchParams();
-  void RemoveURLSearchParams();
-
-  mozilla::dom::URLSearchParams* GetDocShellSearchParams();
 
   // In the case of jar: uris, we sometimes want the place the jar was
   // fetched from as the URI instead of the jar: uri itself.  Pass in
   // true for aGetInnermostURI when that's the case.
   nsresult GetURI(nsIURI** aURL, bool aGetInnermostURI = false);
   nsresult GetWritableURI(nsIURI** aURL);
   nsresult SetURI(nsIURI* aURL, bool aReplace = false);
   nsresult SetHrefWithBase(const nsAString& aHref, nsIURI* aBase,
@@ -168,14 +155,13 @@ protected:
                               bool aReplace);
 
   nsresult GetSourceBaseURL(JSContext* cx, nsIURI** sourceURL);
   nsresult CheckURL(nsIURI *url, nsIDocShellLoadInfo** aLoadInfo);
   bool CallerSubsumes();
 
   nsString mCachedHash;
   nsCOMPtr<nsPIDOMWindow> mInnerWindow;
-  nsRefPtr<mozilla::dom::URLSearchParams> mSearchParams;
   nsWeakPtr mDocShell;
 };
 
 #endif // nsLocation_h__
 
--- a/dom/base/test/mochitest.ini
+++ b/dom/base/test/mochitest.ini
@@ -45,17 +45,16 @@ skip-if = buildapp == 'mulet' || buildap
 [test_gsp-standards.html]
 [test_getFeature_with_perm.html]
 [test_getFeature_without_perm.html]
 [test_hasFeature.html]
 [test_history_document_open.html]
 [test_history_state_null.html]
 [test_Image_constructor.html]
 [test_innersize_scrollport.html]
-[test_location_searchParams.html]
 [test_messageChannel.html]
 [test_messageChannel_cloning.html]
 [test_messageChannel_pingpong.html]
 [test_messageChannel_post.html]
 [test_messageChannel_pref.html]
 [test_messageChannel_start.html]
 [test_messagemanager_targetchain.html]
 [test_messageChannel_transferable.html]
deleted file mode 100644
--- a/dom/base/test/test_location_searchParams.html
+++ /dev/null
@@ -1,89 +0,0 @@
-
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=1037715
--->
-<head>
-  <meta charset="utf-8">
-  <title>Test for Bug 1037715</title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
-  <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1037715">Mozilla Bug 1037715</a>
-  <iframe id="a"></iframe>
-  <script type="application/javascript">
-
-var l;
-
-var iframe = document.getElementById('a');
-function onload0() {
-  iframe.removeEventListener('load', onload0);
-
-  l = iframe.contentWindow.location;
-  is(l.searchParams.get('a'), 'test0', 'l.searchParams value is ok');
-
-  info('changing location from JS...');
-  iframe.addEventListener('load', onload1);
-  iframe.contentWindow.location.href = 'file_empty.html?a=test1';
-}
-
-function onload1() {
-  iframe.removeEventListener('load', onload1);
-
-  var ll = iframe.contentWindow.location;
-  is(ll.searchParams.get('a'), 'test1', 'location.searchParams value is ok');
-  is(l.searchParams.get('a'), 'test1', 'l.searchParams value is ok');
-  isnot(ll.searchParams, l.searchParams, '2 different objects.');
-
-  info('changing location using l.searchParams...');
-  iframe.addEventListener('load', onload2);
-  l.searchParams.set('a', 'test2');
-}
-
-function onload2() {
-  iframe.removeEventListener('load', onload2);
-
-  var ll = iframe.contentWindow.location;
-  is(ll.searchParams.get('a'), 'test2', 'location.searchParams value is ok');
-  is(l.searchParams.get('a'), 'test2', 'l.searchParams value is ok');
-  isnot(ll.searchParams, l.searchParams, '2 different objects.');
-
-  info('changing iframe.src...');
-  iframe.addEventListener('load', onload3);
-  l.search = 'a=test3';
-}
-
-function onload3() {
-  iframe.removeEventListener('load', onload3);
-
-  var ll = iframe.contentWindow.location;
-  is(ll.searchParams.get('a'), 'test3', 'location.searchParams value is ok');
-  is(l.searchParams.get('a'), 'test3', 'l.searchParams value is ok');
-  isnot(ll.searchParams, l.searchParams, '2 different objects.');
-
-  info('changing iframe.src...');
-  iframe.addEventListener('load', onload4);
-  iframe.src = 'file_empty.html?a=test4';
-}
-
-function onload4() {
-  iframe.removeEventListener('load', onload4);
-
-  var ll = iframe.contentWindow.location;
-  is(ll.searchParams.get('a'), 'test4', 'location.searchParams value is ok');
-  is(l.searchParams.get('a'), 'test4', 'l.searchParams value is ok');
-  isnot(ll.searchParams, l.searchParams, '2 different objects.');
-
-  SimpleTest.finish();
-}
-
-iframe.addEventListener('load', onload0);
-iframe.src = "file_empty.html?a=test0";
-SimpleTest.waitForExplicitFinish();
-
-  </script>
-
-</body>
-</html>
--- a/dom/base/test/test_urlSearchParams.html
+++ b/dom/base/test/test_urlSearchParams.html
@@ -108,151 +108,31 @@ https://bugzilla.mozilla.org/show_bug.cg
           is(all[k], checks[i].data[key][k], "value matches");
         }
       }
     }
 
     runTest();
   }
 
-  function testURL() {
-    var url = new URL('http://www.example.net?a=b&c=d');
-    ok(url.searchParams, "URL searchParams exists!");
-    ok(url.searchParams.has('a'), "URL.searchParams.has('a')");
-    is(url.searchParams.get('a'), 'b', "URL.searchParams.get('a')");
-    ok(url.searchParams.has('c'), "URL.searchParams.has('c')");
-    is(url.searchParams.get('c'), 'd', "URL.searchParams.get('c')");
-
-    url.searchParams.set('e', 'f');
-    ok(url.href.indexOf('e=f') != 1, 'URL right');
-
-    var u = new URLSearchParams();
-    u.append('foo', 'bar');
-    url.searchParams = u;
-    is(url.searchParams, u, "URL.searchParams is the same object");
-    is(url.searchParams.get('foo'), 'bar', "URL.searchParams.get('foo')");
-    is(url.href, 'http://www.example.net/?foo=bar', 'URL right');
-
-    try {
-      url.searchParams = null;
-      ok(false, "URLSearchParams is not nullable");
-    } catch(e) {
-      ok(true, "URLSearchParams is not nullable");
-    }
-
-    var url2 = new URL('http://www.example.net?e=f');
-    url.searchParams = url2.searchParams;
-    is(url.searchParams, url2.searchParams, "URL.searchParams is not the same object");
-    is(url.searchParams.get('e'), 'f', "URL.searchParams.get('e')");
-
-    url.href = "http://www.example.net?bar=foo";
-    is(url.searchParams.get('bar'), 'foo', "URL.searchParams.get('bar')");
-
-    runTest();
-  }
-
-  function testElement(e) {
-    ok(e, 'element exists');
-    ok(e.searchParams, "e.searchParams exists!");
-    ok(e.searchParams.has('a'), "e.searchParams.has('a')");
-    is(e.searchParams.get('a'), 'b', "e.searchParams.get('a')");
-    ok(e.searchParams.has('c'), "e.searchParams.has('c')");
-    is(e.searchParams.get('c'), 'd', "e.searchParams.get('c')");
-
-    e.searchParams.set('e', 'f');
-    ok(e.href.indexOf('e=f') != 1, 'e is right');
-
-    var u = new URLSearchParams();
-    u.append('foo', 'bar');
-    e.searchParams = u;
-    is(e.searchParams, u, "e.searchParams is the same object");
-    is(e.searchParams.get('foo'), 'bar', "e.searchParams.get('foo')");
-    is(e.href, 'http://www.example.net/?foo=bar', 'e is right');
-
-    try {
-      e.searchParams = null;
-      ok(false, "URLSearchParams is not nullable");
-    } catch(e) {
-      ok(true, "URLSearchParams is not nullable");
-    }
-
-    var url2 = new URL('http://www.example.net?e=f');
-    e.searchParams = url2.searchParams;
-    is(e.searchParams, url2.searchParams, "e.searchParams is not the same object");
-    is(e.searchParams.get('e'), 'f', "e.searchParams.get('e')");
-
-    e.href = "http://www.example.net?bar=foo";
-    is(e.searchParams.get('bar'), 'foo', "e.searchParams.get('bar')");
-
-    e.setAttribute('href', "http://www.example.net?bar2=foo2");
-    is(e.searchParams.get('bar2'), 'foo2', "e.searchParams.get('bar2')");
-
-    runTest();
-  }
-
   function testEncoding() {
     var encoding = [ [ '1', '1' ],
                      [ 'a b', 'a+b' ],
                      [ '<>', '%3C%3E' ],
                      [ '\u0541', '%D5%81'] ];
 
     for (var i = 0; i < encoding.length; ++i) {
       var a = new URLSearchParams();
       a.set('a', encoding[i][0]);
-
-      var url = new URL('http://www.example.net');
-      url.searchParams = a;
-      is(url.href, 'http://www.example.net/?a=' + encoding[i][1]);
-
-      var url2 = new URL(url.href);
-      is(url2.searchParams.get('a'), encoding[i][0], 'a is still there');
+      is(a + "", "a=" + encoding[i][1]);
     }
 
     runTest();
   }
 
-  function testMultiURL() {
-    var a = new URL('http://www.example.net?a=b&c=d');
-    var b = new URL('http://www.example.net?e=f');
-    var c = document.createElement('a');
-    var d = document.createElement('area');
-    ok(a.searchParams.has('a'), "a.searchParams.has('a')");
-    ok(a.searchParams.has('c'), "a.searchParams.has('c')");
-    ok(b.searchParams.has('e'), "b.searchParams.has('e')");
-    ok(c.searchParams, "c.searchParams");
-    ok(d.searchParams, "d.searchParams");
-
-    var u = new URLSearchParams();
-    a.searchParams = b.searchParams = c.searchParams = d.searchParams = u;
-    is(a.searchParams, u, "a.searchParams === u");
-    is(b.searchParams, u, "b.searchParams === u");
-    is(c.searchParams, u, "c.searchParams === u");
-    is(d.searchParams, u, "d.searchParams === u");
-    ok(!a.searchParams.has('a'), "!a.searchParams.has('a')");
-    ok(!a.searchParams.has('c'), "!a.searchParams.has('c')");
-    ok(!b.searchParams.has('e'), "!b.searchParams.has('e')");
-
-    u.append('foo', 'bar');
-    is(a.searchParams.get('foo'), 'bar', "a has foo=bar");
-    is(b.searchParams.get('foo'), 'bar', "b has foo=bar");
-    is(c.searchParams.get('foo'), 'bar', "c has foo=bar");
-    is(d.searchParams.get('foo'), 'bar', "d has foo=bar");
-    is(a + "", b + "", "stringify a == b");
-    is(c.searchParams + "", b.searchParams + "", "stringify c.searchParams == b.searchParams");
-    is(d.searchParams + "", b.searchParams + "", "stringify d.searchParams == b.searchParams");
-
-    a.search = "?bar=foo";
-    is(a.searchParams.get('bar'), 'foo', "a has bar=foo");
-    is(b.searchParams.get('bar'), 'foo', "b has bar=foo");
-    is(c.searchParams.get('bar'), 'foo', "c has bar=foo");
-    is(d.searchParams.get('bar'), 'foo', "d has bar=foo");
-
-    runTest();
-  }
-
   function testOrdering() {
     var a = new URLSearchParams("a=1&a=2&b=3&c=4&c=5&a=6");
     is(a.toString(), "a=1&a=2&b=3&c=4&c=5&a=6", "Order is correct");
     is(a.getAll('a').length, 3, "Correct length of getAll()");
 
     var b = new URLSearchParams();
     b.append('a', '1');
     b.append('b', '2');
@@ -273,73 +153,65 @@ https://bugzilla.mozilla.org/show_bug.cg
     is(a.toString(), "b=3&c=4&c=5", "Order is correct");
 
     runTest();
   }
 
   function testGetNULL() {
       
     var u = new URLSearchParams();
-    is(typeof u.get(''), "object", "typeof URL.searchParams.get('')");
-    is(u.get(''), null, "URL.searchParams.get('') should be null");
-
-    var url = new URL('http://www.example.net?a=b');
-    is(url.searchParams.get('b'), null, "URL.searchParams.get('b') should be null");
-    is(url.searchParams.get('a'), 'b', "URL.searchParams.get('a')");
+    is(typeof u.get(''), "object", "typeof searchParams.get('')");
+    is(u.get(''), null, "searchParams.get('') should be null");
 
     runTest();
   }
 
   function testSet() {
     var u = new URLSearchParams();
     u.set('a','b');
     u.set('e','c');
     u.set('i','d');
     u.set('o','f');
     u.set('u','g');
 
-    is(u.get('a'), 'b', "URL.searchParams.get('a') should return b");
+    is(u.get('a'), 'b', "searchParams.get('a') should return b");
     is(u.getAll('a').length, 1, "URLSearchParams.getAll('a').length should be 1");
 
     u.set('a','h1');
     u.set('a','h2');
     u.set('a','h3');
     u.set('a','h4');
-    is(u.get('a'), 'h4', "URL.searchParams.get('a') should return h4");
+    is(u.get('a'), 'h4', "searchParams.get('a') should return h4");
     is(u.getAll('a').length, 1, "URLSearchParams.getAll('a').length should be 1");
 
-    is(u.get('e'), 'c', "URL.searchParams.get('e') should return c");
-    is(u.get('i'), 'd', "URL.searchParams.get('i') should return d");
-    is(u.get('o'), 'f', "URL.searchParams.get('o') should return f");
-    is(u.get('u'), 'g', "URL.searchParams.get('u') should return g");
+    is(u.get('e'), 'c', "searchParams.get('e') should return c");
+    is(u.get('i'), 'd', "searchParams.get('i') should return d");
+    is(u.get('o'), 'f', "searchParams.get('o') should return f");
+    is(u.get('u'), 'g', "searchParams.get('u') should return g");
 
     is(u.getAll('e').length, 1, "URLSearchParams.getAll('e').length should be 1");
     is(u.getAll('i').length, 1, "URLSearchParams.getAll('i').length should be 1");
     is(u.getAll('o').length, 1, "URLSearchParams.getAll('o').length should be 1");
     is(u.getAll('u').length, 1, "URLSearchParams.getAll('u').length should be 1");
 
     u = new URLSearchParams("name1=value1&name1=value2&name1=value3");
-    is(u.get('name1'), 'value1', "URL.searchParams.get('name1') should return value1");
+    is(u.get('name1'), 'value1', "searchParams.get('name1') should return value1");
     is(u.getAll('name1').length, 3, "URLSearchParams.getAll('name1').length should be 3");
     u.set('name1','firstPair');
-    is(u.get('name1'), 'firstPair', "URL.searchParams.get('name1') should return firstPair");
+    is(u.get('name1'), 'firstPair', "searchParams.get('name1') should return firstPair");
     is(u.getAll('name1').length, 1, "URLSearchParams.getAll('name1').length should be 1");
 
     runTest();
   }
 
   var tests = [
     testSimpleURLSearchParams,
     testCopyURLSearchParams,
     testParserURLSearchParams,
-    testURL,
-    function() { testElement(document.getElementById('anchor')) },
-    function() { testElement(document.getElementById('area')) },
     testEncoding,
-    testMultiURL,
     testOrdering,
     testDelete,
     testGetNULL,
     testSet
   ];
 
   function runTest() {
     if (!tests.length) {
--- a/dom/webidl/Location.webidl
+++ b/dom/webidl/Location.webidl
@@ -16,10 +16,10 @@ interface Location {
   [Throws]
   void assign(DOMString url);
   [Throws, CrossOriginCallable]
   void replace(DOMString url);
   // XXXbz there is no forceget argument in the spec!  See bug 1037721.
   [Throws]
   void reload(optional boolean forceget = false);
 };
-// No support for .searchParams on Location yet.  See bug 1037715.
+
 Location implements URLUtils;
--- a/dom/webidl/URLUtils.webidl
+++ b/dom/webidl/URLUtils.webidl
@@ -35,17 +35,17 @@ interface URLUtils {
            attribute ScalarValueString hostname;
   [Throws]
            attribute ScalarValueString port;
   [Throws]
            attribute ScalarValueString pathname;
   [Throws]
            attribute ScalarValueString search;
 
-           attribute URLSearchParams searchParams;
+   // Bug 1082734 - attribute URLSearchParams searchParams;
 
   [Throws]
            attribute ScalarValueString hash;
 
   // Bug 824857 should remove this.
   [Throws]
   stringifier;
 };
--- a/dom/workers/URL.cpp
+++ b/dom/workers/URL.cpp
@@ -7,17 +7,16 @@
 
 #include "nsIDocument.h"
 #include "nsIIOService.h"
 #include "nsPIDOMWindow.h"
 
 #include "mozilla/dom/File.h"
 #include "mozilla/dom/URL.h"
 #include "mozilla/dom/URLBinding.h"
-#include "mozilla/dom/URLSearchParams.h"
 #include "nsGlobalWindow.h"
 #include "nsHostObjectProtocolHandler.h"
 #include "nsNetCID.h"
 #include "nsServiceManagerUtils.h"
 #include "nsThreadUtils.h"
 
 #include "WorkerPrivate.h"
 #include "WorkerRunnable.h"
@@ -455,17 +454,17 @@ public:
 
 private:
   const nsString mValue;
   SetterType mType;
   nsRefPtr<URLProxy> mURLProxy;
   mozilla::ErrorResult& mRv;
 };
 
-NS_IMPL_CYCLE_COLLECTION(URL, mSearchParams)
+NS_IMPL_CYCLE_COLLECTION_0(URL)
 
 // The reason for using worker::URL is to have different refcnt logging than
 // for main thread URL.
 NS_IMPL_CYCLE_COLLECTING_ADDREF(workers::URL)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(workers::URL)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(URL)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
@@ -566,18 +565,16 @@ URL::SetHref(const nsAString& aHref, Err
 {
   nsRefPtr<SetterRunnable> runnable =
     new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHref, aHref,
                        mURLProxy, aRv);
 
   if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
     JS_ReportPendingException(mWorkerPrivate->GetJSContext());
   }
-
-  UpdateURLSearchParams();
 }
 
 void
 URL::GetOrigin(nsString& aOrigin, ErrorResult& aRv) const
 {
   nsRefPtr<GetterRunnable> runnable =
     new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterOrigin, aOrigin,
                        mURLProxy);
@@ -772,55 +769,26 @@ URL::GetSearch(nsString& aSearch, ErrorR
   if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
     JS_ReportPendingException(mWorkerPrivate->GetJSContext());
   }
 }
 
 void
 URL::SetSearch(const nsAString& aSearch, ErrorResult& aRv)
 {
-  SetSearchInternal(aSearch);
-  UpdateURLSearchParams();
-}
-
-void
-URL::SetSearchInternal(const nsAString& aSearch)
-{
   ErrorResult rv;
   nsRefPtr<SetterRunnable> runnable =
     new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterSearch,
                        aSearch, mURLProxy, rv);
 
   if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
     JS_ReportPendingException(mWorkerPrivate->GetJSContext());
   }
 }
 
-mozilla::dom::URLSearchParams*
-URL::SearchParams()
-{
-  CreateSearchParamsIfNeeded();
-  return mSearchParams;
-}
-
-void
-URL::SetSearchParams(URLSearchParams& aSearchParams)
-{
-  if (mSearchParams) {
-    mSearchParams->RemoveObserver(this);
-  }
-
-  mSearchParams = &aSearchParams;
-  mSearchParams->AddObserver(this);
-
-  nsString search;
-  mSearchParams->Serialize(search);
-  SetSearchInternal(search);
-}
-
 void
 URL::GetHash(nsString& aHash, ErrorResult& aRv) const
 {
   nsRefPtr<GetterRunnable> runnable =
     new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHash, aHash,
                        mURLProxy);
 
   if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
@@ -881,41 +849,9 @@ URL::RevokeObjectURL(const GlobalObject&
   nsRefPtr<RevokeURLRunnable> runnable =
     new RevokeURLRunnable(workerPrivate, aUrl);
 
   if (!runnable->Dispatch(cx)) {
     JS_ReportPendingException(cx);
   }
 }
 
-void
-URL::URLSearchParamsUpdated(URLSearchParams* aSearchParams)
-{
-  MOZ_ASSERT(mSearchParams);
-  MOZ_ASSERT(mSearchParams == aSearchParams);
-
-  nsString search;
-  mSearchParams->Serialize(search);
-  SetSearchInternal(search);
-}
-
-void
-URL::UpdateURLSearchParams()
-{
-  if (mSearchParams) {
-    nsString search;
-    ErrorResult rv;
-    GetSearch(search, rv);
-    mSearchParams->ParseInput(NS_ConvertUTF16toUTF8(Substring(search, 1)), this);
-  }
-}
-
-void
-URL::CreateSearchParamsIfNeeded()
-{
-  if (!mSearchParams) {
-    mSearchParams = new URLSearchParams();
-    mSearchParams->AddObserver(this);
-    UpdateURLSearchParams();
-  }
-}
-
 END_WORKERS_NAMESPACE
--- a/dom/workers/URL.h
+++ b/dom/workers/URL.h
@@ -6,35 +6,33 @@
 
 #ifndef mozilla_dom_workers_url_h__
 #define mozilla_dom_workers_url_h__
 
 #include "Workers.h"
 
 #include "mozilla/ErrorResult.h"
 #include "mozilla/dom/BindingDeclarations.h"
-#include "mozilla/dom/URLSearchParams.h"
+#include "nsCycleCollectionParticipant.h"
 
 class nsIPrincipal;
 
 namespace mozilla {
 namespace dom {
 class File;
 struct objectURLOptions;
 }
 }
 
 BEGIN_WORKERS_NAMESPACE
 
 class URLProxy;
 
-class URL MOZ_FINAL : public mozilla::dom::URLSearchParamsObserver
+class URL MOZ_FINAL : public nsISupports
 {
-  typedef mozilla::dom::URLSearchParams URLSearchParams;
-
   ~URL();
 
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS(URL)
 
   URL(WorkerPrivate* aWorkerPrivate, URLProxy* aURLProxy);
 
@@ -103,44 +101,30 @@ public:
   void GetPathname(nsString& aPathname, ErrorResult& aRv) const;
 
   void SetPathname(const nsAString& aPathname, ErrorResult& aRv);
 
   void GetSearch(nsString& aSearch, ErrorResult& aRv) const;
 
   void SetSearch(const nsAString& aSearch, ErrorResult& aRv);
 
-  URLSearchParams* SearchParams();
-
-  void SetSearchParams(URLSearchParams& aSearchParams);
-
   void GetHash(nsString& aHost, ErrorResult& aRv) const;
 
   void SetHash(const nsAString& aHash, ErrorResult& aRv);
 
   void Stringify(nsString& aRetval, ErrorResult& aRv) const
   {
     GetHref(aRetval, aRv);
   }
 
-  // IURLSearchParamsObserver
-  void URLSearchParamsUpdated(URLSearchParams* aSearchParams) MOZ_OVERRIDE;
-
 private:
   URLProxy* GetURLProxy() const
   {
     return mURLProxy;
   }
 
-  void CreateSearchParamsIfNeeded();
-
-  void SetSearchInternal(const nsAString& aSearch);
-
-  void UpdateURLSearchParams();
-
   WorkerPrivate* mWorkerPrivate;
   nsRefPtr<URLProxy> mURLProxy;
-  nsRefPtr<URLSearchParams> mSearchParams;
 };
 
 END_WORKERS_NAMESPACE
 
 #endif /* mozilla_dom_workers_url_h__ */
--- a/dom/workers/test/urlSearchParams_worker.js
+++ b/dom/workers/test/urlSearchParams_worker.js
@@ -100,106 +100,36 @@ onmessage = function() {
           is(all[k], checks[i].data[key][k], "value matches");
         }
       }
     }
 
     runTest();
   }
 
-  function testURL() {
-    var url = new URL('http://www.example.net?a=b&c=d');
-    ok(url.searchParams, "URL searchParams exists!");
-    ok(url.searchParams.has('a'), "URL.searchParams.has('a')");
-    is(url.searchParams.get('a'), 'b', "URL.searchParams.get('a')");
-    ok(url.searchParams.has('c'), "URL.searchParams.has('c')");
-    is(url.searchParams.get('c'), 'd', "URL.searchParams.get('c')");
-
-    url.searchParams.set('e', 'f');
-    ok(url.href.indexOf('e=f') != 1, 'URL right');
-
-    var u = new URLSearchParams();
-    u.append('foo', 'bar');
-    url.searchParams = u;
-    is(url.searchParams, u, "URL.searchParams is the same object");
-    is(url.searchParams.get('foo'), 'bar', "URL.searchParams.get('foo')");
-    is(url.href, 'http://www.example.net/?foo=bar', 'URL right');
-
-    try {
-      url.searchParams = null;
-      ok(false, "URLSearchParams is not nullable");
-    } catch(e) {
-      ok(true, "URLSearchParams is not nullable");
-    }
-
-    var url2 = new URL('http://www.example.net?e=f');
-    url.searchParams = url2.searchParams;
-    is(url.searchParams, url2.searchParams, "URL.searchParams is not the same object");
-    is(url.searchParams.get('e'), 'f', "URL.searchParams.get('e')");
-
-    url.href = "http://www.example.net?bar=foo";
-    is(url.searchParams.get('bar'), 'foo', "URL.searchParams.get('bar')");
-
-    runTest();
-  }
-
   function testEncoding() {
     var encoding = [ [ '1', '1' ],
                      [ 'a b', 'a+b' ],
                      [ '<>', '%3C%3E' ],
                      [ '\u0541', '%D5%81'] ];
 
     for (var i = 0; i < encoding.length; ++i) {
       var a = new URLSearchParams();
       a.set('a', encoding[i][0]);
-
-      var url = new URL('http://www.example.net');
-      url.searchParams = a;
-      is(url.href, 'http://www.example.net/?a=' + encoding[i][1]);
-
-      var url2 = new URL(url.href);
-      is(url2.searchParams.get('a'), encoding[i][0], 'a is still there');
+      is(a + "", 'a=' + encoding[i][1]);
     }
 
     runTest();
   }
 
-  function testMultiURL() {
-    var a = new URL('http://www.example.net?a=b&c=d');
-    var b = new URL('http://www.example.net?e=f');
-    ok(a.searchParams.has('a'), "a.searchParams.has('a')");
-    ok(a.searchParams.has('c'), "a.searchParams.has('c')");
-    ok(b.searchParams.has('e'), "b.searchParams.has('e')");
-
-    var u = new URLSearchParams();
-    a.searchParams = b.searchParams = u;
-    is(a.searchParams, u, "a.searchParams === u");
-    is(b.searchParams, u, "b.searchParams === u");
-    ok(!a.searchParams.has('a'), "!a.searchParams.has('a')");
-    ok(!a.searchParams.has('c'), "!a.searchParams.has('c')");
-    ok(!b.searchParams.has('e'), "!b.searchParams.has('e')");
-
-    u.append('foo', 'bar');
-    is(a.searchParams.get('foo'), 'bar', "a has foo=bar");
-    is(b.searchParams.get('foo'), 'bar', "b has foo=bar");
-    is(a + "", b + "", "stringify a == b");
-
-    a.search = "?bar=foo";
-    is(a.searchParams.get('bar'), 'foo', "a has bar=foo");
-    is(b.searchParams.get('bar'), 'foo', "b has bar=foo");
-
-    runTest();
-  }
   var tests = [
     testSimpleURLSearchParams,
     testCopyURLSearchParams,
     testParserURLSearchParams,
-    testURL,
-    testEncoding,
-    testMultiURL
+    testEncoding
   ];
 
   function runTest() {
     if (!tests.length) {
       postMessage({type: 'finish' });
       return;
     }
 
--- a/mobile/android/chrome/content/WebcompatReporter.js
+++ b/mobile/android/chrome/content/WebcompatReporter.js
@@ -2,16 +2,18 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
+Cu.importGlobalProperties(["URL", "URLSearchParams"]);
+
 var WebcompatReporter = {
   menuItem: null,
   menuItemEnabled: null,
   init: function() {
     Services.obs.addObserver(this, "DesktopMode:Change", false);
     Services.obs.addObserver(this, "content-page-shown", false);
     this.addMenuItem();
   },
@@ -71,17 +73,19 @@ var WebcompatReporter = {
         callback: () => this.reportIssue(currentURI)
       }
     };
     NativeWindow.toast.show(message, "long", options);
   },
 
   reportIssue: function(url) {
     let webcompatURL = new URL("http://webcompat.com/");
-    webcompatURL.searchParams.append("open", "1");
-    webcompatURL.searchParams.append("url", url);
+    let searchParams = new URLSearchParams();
+    searchParams.append("open", "1");
+    searchParams.append("url", url);
+    webcompatURL.search = searchParams.toString();
     BrowserApp.addTab(webcompatURL.href);
   }
 };
 
 XPCOMUtils.defineLazyGetter(WebcompatReporter, "strings", function() {
   return Services.strings.createBundle("chrome://browser/locale/webcompatReporter.properties");
 });
--- a/services/fxaccounts/FxAccountsOAuthClient.jsm
+++ b/services/fxaccounts/FxAccountsOAuthClient.jsm
@@ -12,17 +12,17 @@ this.EXPORTED_SYMBOLS = ["FxAccountsOAut
 const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Log.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/FxAccountsCommon.js");
 XPCOMUtils.defineLazyModuleGetter(this, "WebChannel",
                                   "resource://gre/modules/WebChannel.jsm");
-Cu.importGlobalProperties(["URL"]);
+Cu.importGlobalProperties(["URL", "URLSearchParams"]);
 
 /**
  * Create a new FxAccountsOAuthClient for browser some service.
  *
  * @param {Object} options Options
  *   @param {Object} options.parameters
  *   Opaque alphanumeric token to be included in verification links
  *     @param {String} options.parameters.client_id
@@ -49,23 +49,23 @@ this.FxAccountsOAuthClient = function(op
   let authorizationEndpoint = options.authorizationEndpoint || "/authorization";
 
   try {
     this._fxaOAuthStartUrl = new URL(this.parameters.oauth_uri + authorizationEndpoint + "?");
   } catch (e) {
     throw new Error("Invalid OAuth Url");
   }
 
-  let params = this._fxaOAuthStartUrl.searchParams;
+  let params = new URLSearchParams(this._fxaOAuthStartUrl.search.substr(1));
   params.append("client_id", this.parameters.client_id);
   params.append("state", this.parameters.state);
   params.append("scope", this.parameters.scope || "");
   params.append("action", this.parameters.action || "signin");
   params.append("webChannelId", this._webChannelId);
-
+  this._fxaOAuthStartUrl.search = params;
 };
 
 this.FxAccountsOAuthClient.prototype = {
   /**
    * Function that gets called once the OAuth flow is complete.
    * The callback will receive null as it's argument if there is a state mismatch or an object with
    * code and state properties otherwise.
    */
--- a/toolkit/components/places/tests/cpp/mock_Link.h
+++ b/toolkit/components/places/tests/cpp/mock_Link.h
@@ -8,17 +8,16 @@
  * This is a mock Link object which can be used in tests.
  */
 
 #ifndef mock_Link_h__
 #define mock_Link_h__
 
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/dom/Link.h"
-#include "mozilla/dom/URLSearchParams.h"
 
 class mock_Link : public mozilla::dom::Link
 {
 public:
   NS_DECL_ISUPPORTS
 
   explicit mock_Link(void (*aHandlerFunction)(nsLinkState),
                      bool aRunNextTest = true)
@@ -112,134 +111,12 @@ Link::GetURI() const
 
 size_t
 Link::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
 {
   NS_NOTREACHED("Unexpected call to Link::SizeOfExcludingThis");
   return 0;
 }
 
-void
-Link::URLSearchParamsUpdated(URLSearchParams* aSearchParams)
-{
-  NS_NOTREACHED("Unexpected call to Link::URLSearchParamsUpdated");
-}
-
-void
-Link::UpdateURLSearchParams()
-{
-  NS_NOTREACHED("Unexpected call to Link::UpdateURLSearchParams");
-}
-
-NS_IMPL_CYCLE_COLLECTION_CLASS(URLSearchParams)
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(URLSearchParams)
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(URLSearchParams)
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(URLSearchParams)
-
-NS_IMPL_CYCLE_COLLECTING_ADDREF(URLSearchParams)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(URLSearchParams)
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(URLSearchParams)
-  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
-  NS_INTERFACE_MAP_ENTRY(nsISupports)
-NS_INTERFACE_MAP_END
-
-
-URLSearchParams::URLSearchParams()
-{
-}
-
-URLSearchParams::~URLSearchParams()
-{
-}
-
-JSObject*
-URLSearchParams::WrapObject(JSContext* aCx)
-{
-  return nullptr;
-}
-
-void
-URLSearchParams::ParseInput(const nsACString& aInput,
-                            URLSearchParamsObserver* aObserver)
-{
-  NS_NOTREACHED("Unexpected call to URLSearchParams::ParseInput");
-}
-
-void
-URLSearchParams::AddObserver(URLSearchParamsObserver* aObserver)
-{
-  NS_NOTREACHED("Unexpected call to URLSearchParams::SetObserver");
-}
-
-void
-URLSearchParams::RemoveObserver(URLSearchParamsObserver* aObserver)
-{
-  NS_NOTREACHED("Unexpected call to URLSearchParams::SetObserver");
-}
-
-void
-URLSearchParams::Serialize(nsAString& aValue) const
-{
-  NS_NOTREACHED("Unexpected call to URLSearchParams::Serialize");
-}
-
-void
-URLSearchParams::Get(const nsAString& aName, nsString& aRetval)
-{
-  NS_NOTREACHED("Unexpected call to URLSearchParams::Get");
-}
-
-void
-URLSearchParams::GetAll(const nsAString& aName, nsTArray<nsString >& aRetval)
-{
-  NS_NOTREACHED("Unexpected call to URLSearchParams::GetAll");
-}
-
-void
-URLSearchParams::Set(const nsAString& aName, const nsAString& aValue)
-{
-  NS_NOTREACHED("Unexpected call to URLSearchParams::Set");
-}
-
-void
-URLSearchParams::Append(const nsAString& aName, const nsAString& aValue)
-{
-  NS_NOTREACHED("Unexpected call to URLSearchParams::Append");
-}
-
-void
-URLSearchParams::AppendInternal(const nsAString& aName, const nsAString& aValue)
-{
-  NS_NOTREACHED("Unexpected call to URLSearchParams::AppendInternal");
-}
-
-bool
-URLSearchParams::Has(const nsAString& aName)
-{
-  NS_NOTREACHED("Unexpected call to URLSearchParams::Has");
-  return false;
-}
-
-void
-URLSearchParams::Delete(const nsAString& aName)
-{
-  NS_NOTREACHED("Unexpected call to URLSearchParams::Delete");
-}
-
-void
-URLSearchParams::DeleteAll()
-{
-  NS_NOTREACHED("Unexpected call to URLSearchParams::DeleteAll");
-}
-
-void
-URLSearchParams::NotifyObservers(URLSearchParamsObserver* aExceptObserver)
-{
-  NS_NOTREACHED("Unexpected call to URLSearchParams::NotifyObservers");
-}
-
 } // namespace dom
 } // namespace mozilla
 
 #endif // mock_Link_h__