diff --git a/dom/url/URLSearchParams.cpp b/dom/url/URLSearchParams.cpp index f762299f8..e2172ea0e 100644 --- a/dom/url/URLSearchParams.cpp +++ b/dom/url/URLSearchParams.cpp @@ -448,6 +448,15 @@ URLSearchParams::GetValueAtIndex(uint32_t aIndex) const return mParams->GetValueAtIndex(aIndex); } +void +URLSearchParams::Sort(ErrorResult& aRv) +{ + aRv = mParams->Sort(); + if (!aRv.Failed()) { + NotifyObserver(); + } +} + // Helper functions for structured cloning inline bool ReadString(JSStructuredCloneReader* aReader, nsString& aString) @@ -472,6 +481,39 @@ ReadString(JSStructuredCloneReader* aReader, nsString& aString) return true; } +nsresult +URLParams::Sort() +{ + // Unfortunately we cannot use nsTArray<>.Sort() because it doesn't keep the + // correct order of the values for equal keys. + + // Let's sort the keys, without duplicates. + FallibleTArray keys; + for (const Param& param : mParams) { + if (!keys.Contains(param.mKey) && + !keys.InsertElementSorted(param.mKey, fallible)) { + return NS_ERROR_OUT_OF_MEMORY; + } + } + + FallibleTArray params; + + // Here we recreate the array starting from the sorted keys. + for (uint32_t keyId = 0, keysLength = keys.Length(); keyId < keysLength; + ++keyId) { + const nsString& key = keys[keyId]; + for (const Param& param : mParams) { + if (param.mKey.Equals(key) && + !params.AppendElement(param, fallible)) { + return NS_ERROR_OUT_OF_MEMORY; + } + } + } + + mParams.SwapElements(params); + return NS_OK; +} + inline bool WriteString(JSStructuredCloneWriter* aWriter, const nsString& aString) { diff --git a/dom/url/URLSearchParams.h b/dom/url/URLSearchParams.h index 9fefd78dd..e02c1179f 100644 --- a/dom/url/URLSearchParams.h +++ b/dom/url/URLSearchParams.h @@ -70,7 +70,7 @@ public: void Get(const nsAString& aName, nsString& aRetval); - void GetAll(const nsAString& aName, nsTArray& aRetval); + void GetAll(const nsAString& aName, nsTArray& aRetval); void Set(const nsAString& aName, const nsAString& aValue); @@ -103,6 +103,8 @@ public: return mParams[aIndex].mValue; } + nsresult Sort(); + bool ReadStructuredClone(JSStructuredCloneReader* aReader); @@ -171,6 +173,8 @@ public: const nsAString& GetKeyAtIndex(uint32_t aIndex) const; const nsAString& GetValueAtIndex(uint32_t aIndex) const; + void Sort(ErrorResult& aRv); + void Stringify(nsString& aRetval) const { Serialize(aRetval); diff --git a/dom/webidl/URLSearchParams.webidl b/dom/webidl/URLSearchParams.webidl index b93f4e8b1..2828d81dd 100644 --- a/dom/webidl/URLSearchParams.webidl +++ b/dom/webidl/URLSearchParams.webidl @@ -22,6 +22,10 @@ interface URLSearchParams { sequence getAll(USVString name); boolean has(USVString name); void set(USVString name, USVString value); + + [Throws] + void sort(); + iterable; stringifier; };