From d7998c5dbdbe98000554a432f47565d41f8b095c Mon Sep 17 00:00:00 2001 From: Luke Wilde Date: Tue, 25 Jan 2022 20:38:55 +0000 Subject: [PATCH] LibWeb: Accept array pairs in URLSearchParams constructor --- .../Libraries/LibWeb/URL/URLSearchParams.cpp | 31 ++++++++++++++++--- .../Libraries/LibWeb/URL/URLSearchParams.h | 2 +- .../Libraries/LibWeb/URL/URLSearchParams.idl | 2 +- 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/Userland/Libraries/LibWeb/URL/URLSearchParams.cpp b/Userland/Libraries/LibWeb/URL/URLSearchParams.cpp index 5b7e29aa4f..48cb919917 100644 --- a/Userland/Libraries/LibWeb/URL/URLSearchParams.cpp +++ b/Userland/Libraries/LibWeb/URL/URLSearchParams.cpp @@ -66,24 +66,45 @@ Vector url_decode(StringView input) return output; } -DOM::ExceptionOr> URLSearchParams::create_with_global_object(Bindings::WindowObject&, String const& init) +DOM::ExceptionOr> URLSearchParams::create_with_global_object(Bindings::WindowObject&, Variant>, String> const& init) { // 1. If init is a string and starts with U+003F (?), then remove the first code point from init. - StringView stripped_init = init.substring_view(init.starts_with('?')); + // NOTE: We do this when we know that it's a string on step 3 of initialization. + // 2. Initialize this with init. // URLSearchParams init from this point forward - // TODO // 1. If init is a sequence, then for each pair in init: - // a. If pair does not contain exactly two items, then throw a TypeError. - // b. Append a new name-value pair whose name is pair’s first item, and value is pair’s second item, to query’s list. + if (init.has>>()) { + auto const& init_sequence = init.get>>(); + + Vector list; + list.ensure_capacity(init_sequence.size()); + + for (auto const& pair : init_sequence) { + // a. If pair does not contain exactly two items, then throw a TypeError. + if (pair.size() != 2) + return DOM::SimpleException { DOM::SimpleExceptionType::TypeError, String::formatted("Expected only 2 items in pair, got {}", pair.size()) }; + + // b. Append a new name-value pair whose name is pair’s first item, and value is pair’s second item, to query’s list. + list.append(QueryParam { .name = pair[0], .value = pair[1] }); + } + + return URLSearchParams::create(move(list)); + } // TODO // 2. Otherwise, if init is a record, then for each name → value of init, append a new name-value pair whose name is name and value is value, to query’s list. // 3. Otherwise: // a. Assert: init is a string. + // NOTE: `get` performs `VERIFY(has())` + auto const& init_string = init.get(); + + // See NOTE at the start of this function. + StringView stripped_init = init_string.substring_view(init_string.starts_with('?')); + // b. Set query’s list to the result of parsing init. return URLSearchParams::create(url_decode(stripped_init)); } diff --git a/Userland/Libraries/LibWeb/URL/URLSearchParams.h b/Userland/Libraries/LibWeb/URL/URLSearchParams.h index 94b07509e9..22f44a5a97 100644 --- a/Userland/Libraries/LibWeb/URL/URLSearchParams.h +++ b/Userland/Libraries/LibWeb/URL/URLSearchParams.h @@ -30,7 +30,7 @@ public: return adopt_ref(*new URLSearchParams(move(list))); } - static DOM::ExceptionOr> create_with_global_object(Bindings::WindowObject&, const String& init); + static DOM::ExceptionOr> create_with_global_object(Bindings::WindowObject&, Variant>, String> const& init); void append(String const& name, String const& value); void delete_(String const& name); diff --git a/Userland/Libraries/LibWeb/URL/URLSearchParams.idl b/Userland/Libraries/LibWeb/URL/URLSearchParams.idl index 68a6a7b1f9..e552a248b4 100644 --- a/Userland/Libraries/LibWeb/URL/URLSearchParams.idl +++ b/Userland/Libraries/LibWeb/URL/URLSearchParams.idl @@ -1,7 +1,7 @@ interface URLSearchParams { // FIXME: the real type of init is (sequence> or record or USVString) - constructor(optional USVString init = ""); + constructor(optional (sequence> or USVString) init = ""); undefined append(USVString name, USVString value); undefined delete(USVString name);