Bug 1330678 - Construct URLSearchParams from sequence or from string, r=smaug
authorAndrea Marchesini <amarchesini@mozilla.com>
Tue, 17 Jan 2017 11:13:06 +0100
changeset 374649 293533db8cc7dca1e65ceeb386369795e9f99ec2
parent 374648 8fd2b8d8d76758c519cbca84b98771a94df17f47
child 374650 8a7cffb801da9bfcc871d32307ef4338d4074a99
push id6996
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 20:48:21 +0000
treeherdermozilla-beta@d89512dab048 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1330678
milestone53.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 1330678 - Construct URLSearchParams from sequence or from string, r=smaug
dom/url/URLSearchParams.cpp
dom/url/URLSearchParams.h
dom/url/tests/test_urlSearchParams.html
dom/url/tests/urlSearchParams_worker.js
dom/webidl/URLSearchParams.webidl
--- a/dom/url/URLSearchParams.cpp
+++ b/dom/url/URLSearchParams.cpp
@@ -309,65 +309,60 @@ NS_INTERFACE_MAP_END
 URLSearchParams::URLSearchParams(nsISupports* aParent,
                                  URLSearchParamsObserver* aObserver)
   : mParams(new URLParams())
   , mParent(aParent)
   , mObserver(aObserver)
 {
 }
 
-URLSearchParams::URLSearchParams(nsISupports* aParent,
-                                 const URLSearchParams& aOther)
-  : mParams(new URLParams(*aOther.mParams.get()))
-  , mParent(aParent)
-  , mObserver(nullptr)
-{
-}
-
 URLSearchParams::~URLSearchParams()
 {
   DeleteAll();
 }
 
 JSObject*
 URLSearchParams::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
   return URLSearchParamsBinding::Wrap(aCx, this, aGivenProto);
 }
 
 /* static */ already_AddRefed<URLSearchParams>
 URLSearchParams::Constructor(const GlobalObject& aGlobal,
-                             const nsAString& aInit,
+                             const USVStringSequenceSequenceOrUSVString& aInit,
                              ErrorResult& aRv)
 {
   RefPtr<URLSearchParams> sp =
     new URLSearchParams(aGlobal.GetAsSupports(), nullptr);
 
-  NS_ConvertUTF16toUTF8 input(aInit);
-
-  if (StringBeginsWith(input, NS_LITERAL_CSTRING("?"))) {
-    sp->ParseInput(Substring(input, 1, input.Length() - 1));
+  if (aInit.IsUSVString()) {
+    NS_ConvertUTF16toUTF8 input(aInit.GetAsUSVString());
+    if (StringBeginsWith(input, NS_LITERAL_CSTRING("?"))) {
+      sp->ParseInput(Substring(input, 1, input.Length() - 1));
+    } else {
+      sp->ParseInput(input);
+    }
+  } else if (aInit.IsUSVStringSequenceSequence()) {
+    const Sequence<Sequence<nsString>>& list =
+      aInit.GetAsUSVStringSequenceSequence();
+    for (uint32_t i = 0; i < list.Length(); ++i) {
+      const Sequence<nsString>& item = list[i];
+      if (item.Length() != 2) {
+        aRv.Throw(NS_ERROR_DOM_TYPE_ERR);
+        return nullptr;
+      }
+      sp->Append(item[0], item[1]);
+    }
   } else {
-    sp->ParseInput(input);
+    MOZ_CRASH("This should not happen.");
   }
 
   return sp.forget();
 }
 
-/* static */ already_AddRefed<URLSearchParams>
-URLSearchParams::Constructor(const GlobalObject& aGlobal,
-                             URLSearchParams& aInit,
-                             ErrorResult& aRv)
-{
-  RefPtr<URLSearchParams> sp =
-    new URLSearchParams(aGlobal.GetAsSupports(), aInit);
-
-  return sp.forget();
-}
-
 void
 URLSearchParams::ParseInput(const nsACString& aInput)
 {
   mParams->ParseInput(aInput);
 }
 
 void
 URLSearchParams::Get(const nsAString& aName, nsString& aRetval)
--- a/dom/url/URLSearchParams.h
+++ b/dom/url/URLSearchParams.h
@@ -15,16 +15,17 @@
 #include "nsISupports.h"
 #include "nsIUnicodeDecoder.h"
 #include "nsIXMLHttpRequest.h"
 
 namespace mozilla {
 namespace dom {
 
 class URLSearchParams;
+class USVStringSequenceSequenceOrUSVString;
 
 class URLSearchParamsObserver : public nsISupports
 {
 public:
   virtual ~URLSearchParamsObserver() {}
 
   virtual void URLSearchParamsUpdated(URLSearchParams* aFromThis) = 0;
 };
@@ -38,24 +39,16 @@ class URLParams final
 public:
   URLParams() {}
 
   ~URLParams()
   {
     DeleteAll();
   }
 
-  explicit URLParams(const URLParams& aOther)
-    : mParams(aOther.mParams)
-  {}
-
-  URLParams(const URLParams&& aOther)
-    : mParams(Move(aOther.mParams))
-  {}
-
   class ForEachIterator
   {
   public:
     virtual bool
     URLParamsIterator(const nsString& aName, const nsString& aValue) = 0;
   };
 
   void
@@ -139,34 +132,28 @@ public:
   NS_DECL_NSIXHRSENDABLE
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(URLSearchParams)
 
   explicit URLSearchParams(nsISupports* aParent,
                            URLSearchParamsObserver* aObserver=nullptr);
 
-  URLSearchParams(nsISupports* aParent,
-                  const URLSearchParams& aOther);
-
   // WebIDL methods
   nsISupports* GetParentObject() const
   {
     return mParent;
   }
 
   virtual JSObject*
   WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 
   static already_AddRefed<URLSearchParams>
-  Constructor(const GlobalObject& aGlobal, const nsAString& aInit,
-              ErrorResult& aRv);
-
-  static already_AddRefed<URLSearchParams>
-  Constructor(const GlobalObject& aGlobal, URLSearchParams& aInit,
+  Constructor(const GlobalObject& aGlobal,
+              const USVStringSequenceSequenceOrUSVString& aInit,
               ErrorResult& aRv);
 
   void ParseInput(const nsACString& aInput);
 
   void Serialize(nsAString& aValue) const;
 
   void Get(const nsAString& aName, nsString& aRetval);
 
--- a/dom/url/tests/test_urlSearchParams.html
+++ b/dom/url/tests/test_urlSearchParams.html
@@ -296,29 +296,59 @@ https://bugzilla.mozilla.org/show_bug.cg
        "Messing with copy of URLSearchParams should not affect URL");
     p.set("c", "d");
     is(url.href, "http://example.com/?c=d",
        "Messing with URLSearchParams should affect URL");
 
     runTest();
   }
 
+  function testCTORs() {
+    var a = new URLSearchParams("a=b");
+    is(a.get("a"), "b", "CTOR with string");
+
+    var b = new URLSearchParams([['a', 'b'], ['c', 'd']]);
+    is(b.get("a"), "b", "CTOR with sequence");
+    is(b.get("c"), "d", "CTOR with sequence");
+
+    ok(new URLSearchParams([]), "CTOR with empty sequence");
+
+    let result;
+    try {
+      result = new URLSearchParams([[1]]);
+    } catch(e) {
+      result = 42;
+    }
+
+    is(result, 42, "CTOR throws if the sequence doesn't contain exactly 2 elements");
+
+    try {
+      result = new URLSearchParams([[1,2,3]]);
+    } catch(e) {
+      result = 43;
+    }
+    is(result, 43, "CTOR throws if the sequence doesn't contain exactly 2 elements");
+
+    runTest();
+  }
+
   var tests = [
     testSimpleURLSearchParams,
     testCopyURLSearchParams,
     testParserURLSearchParams,
     testURL,
     testEncoding,
     testOrdering,
     testDelete,
     testGetNULL,
     testSet,
     testIterable,
     testZeroHandling,
     testCopyConstructor,
+    testCTORs,
   ];
 
   function runTest() {
     if (!tests.length) {
       SimpleTest.finish();
       return;
     }
 
--- a/dom/url/tests/urlSearchParams_worker.js
+++ b/dom/url/tests/urlSearchParams_worker.js
@@ -135,22 +135,52 @@ onmessage = function() {
 
       var url2 = new URL(url.href);
       is(url2.searchParams.get('a'), encoding[i][0], 'a is still there');
     }
 
     runTest();
   }
 
+  function testCTORs() {
+    var a = new URLSearchParams("a=b");
+    is(a.get("a"), "b", "CTOR with string");
+
+    var b = new URLSearchParams([['a', 'b'], ['c', 'd']]);
+    is(b.get("a"), "b", "CTOR with sequence");
+    is(b.get("c"), "d", "CTOR with sequence");
+
+    ok(new URLSearchParams([]), "CTOR with empty sequence");
+
+    let result;
+    try {
+      result = new URLSearchParams([[1]]);
+    } catch(e) {
+      result = 42;
+    }
+
+    is(result, 42, "CTOR throws if the sequence doesn't contain exactly 2 elements");
+
+    try {
+      result = new URLSearchParams([[1,2,3]]);
+    } catch(e) {
+      result = 43;
+    }
+    is(result, 43, "CTOR throws if the sequence doesn't contain exactly 2 elements");
+
+    runTest();
+  }
+
   var tests = [
     testSimpleURLSearchParams,
     testCopyURLSearchParams,
     testParserURLSearchParams,
     testURL,
     testEncoding,
+    testCTORs,
   ];
 
   function runTest() {
     if (!tests.length) {
       postMessage({type: 'finish' });
       return;
     }
 
--- a/dom/webidl/URLSearchParams.webidl
+++ b/dom/webidl/URLSearchParams.webidl
@@ -8,18 +8,17 @@
  *
  * To the extent possible under law, the editors have waived all copyright
  * and related or neighboring rights to this work. In addition, as of 17
  * February 2013, the editors have made this specification available under
  * the Open Web Foundation Agreement Version 1.0, which is available at
  * http://www.openwebfoundation.org/legal/the-owf-1-0-agreements/owfa-1-0.
  */
 
-[Constructor(optional USVString init = ""),
- Constructor(URLSearchParams init),
+[Constructor(optional (sequence<sequence<USVString>> or USVString) init = ""),
  Exposed=(Window,Worker,WorkerDebugger,System)]
 interface URLSearchParams {
   void append(USVString name, USVString value);
   void delete(USVString name);
   USVString? get(USVString name);
   sequence<USVString> getAll(USVString name);
   boolean has(USVString name);
   void set(USVString name, USVString value);