diff --git a/Tests/LibWeb/Text/expected/Fetch/fetch-response-url-encoded.txt b/Tests/LibWeb/Text/expected/Fetch/fetch-response-url-encoded.txt
new file mode 100644
index 00000000000..f10581337e3
--- /dev/null
+++ b/Tests/LibWeb/Text/expected/Fetch/fetch-response-url-encoded.txt
@@ -0,0 +1,3 @@
+value-a
+value-b
+value-c1,value-c2
diff --git a/Tests/LibWeb/Text/input/Fetch/fetch-response-url-encoded.html b/Tests/LibWeb/Text/input/Fetch/fetch-response-url-encoded.html
new file mode 100644
index 00000000000..37f2fc88b86
--- /dev/null
+++ b/Tests/LibWeb/Text/input/Fetch/fetch-response-url-encoded.html
@@ -0,0 +1,17 @@
+
+
diff --git a/Userland/Libraries/LibWeb/Fetch/Body.cpp b/Userland/Libraries/LibWeb/Fetch/Body.cpp
index faf8636ddb9..09619416c33 100644
--- a/Userland/Libraries/LibWeb/Fetch/Body.cpp
+++ b/Userland/Libraries/LibWeb/Fetch/Body.cpp
@@ -15,6 +15,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -23,6 +24,7 @@
#include
#include
#include
+#include
namespace Web::Fetch {
@@ -143,10 +145,15 @@ WebIDL::ExceptionOr package_data(JS::Realm& realm, ByteBuffer bytes,
}
// Otherwise, if mimeType’s essence is "application/x-www-form-urlencoded", then:
else if (mime_type.has_value() && mime_type->essence() == "application/x-www-form-urlencoded"sv) {
- // FIXME: 1. Let entries be the result of parsing bytes.
- // FIXME: 2. If entries is failure, then throw a TypeError.
- // FIXME: 3. Return a new FormData object whose entry list is entries.
- return JS::js_null();
+ // 1. Let entries be the result of parsing bytes.
+ auto entries = DOMURL::url_decode(StringView { bytes });
+
+ // 2. If entries is failure, then throw a TypeError.
+ if (entries.is_error())
+ return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, entries.error().string_literal() };
+
+ // 3. Return a new FormData object whose entry list is entries.
+ return TRY(XHR::FormData::create(realm, entries.release_value()));
}
// Otherwise, throw a TypeError.
else {
diff --git a/Userland/Libraries/LibWeb/XHR/FormData.cpp b/Userland/Libraries/LibWeb/XHR/FormData.cpp
index 7165449fbb5..f1ae609f215 100644
--- a/Userland/Libraries/LibWeb/XHR/FormData.cpp
+++ b/Userland/Libraries/LibWeb/XHR/FormData.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2023, Kenneth Myhra
+ * Copyright (c) 2023-2024, Kenneth Myhra
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@@ -40,6 +40,16 @@ WebIDL::ExceptionOr> FormData::construct_impl(JS::Rea
return realm.heap().allocate(realm, realm, move(entry_list));
}
+WebIDL::ExceptionOr> FormData::create(JS::Realm& realm, Vector entry_list)
+{
+ Vector list;
+ list.ensure_capacity(entry_list.size());
+ for (auto& entry : entry_list)
+ list.unchecked_append({ .name = move(entry.name), .value = move(entry.value) });
+
+ return construct_impl(realm, move(list));
+}
+
FormData::FormData(JS::Realm& realm, Vector entry_list)
: PlatformObject(realm)
, m_entry_list(move(entry_list))
diff --git a/Userland/Libraries/LibWeb/XHR/FormData.h b/Userland/Libraries/LibWeb/XHR/FormData.h
index f607ba27cbc..7ed5fe3517b 100644
--- a/Userland/Libraries/LibWeb/XHR/FormData.h
+++ b/Userland/Libraries/LibWeb/XHR/FormData.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2023, Kenneth Myhra
+ * Copyright (c) 2023-2024, Kenneth Myhra
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@@ -8,6 +8,7 @@
#include
#include
+#include
#include
#include
#include
@@ -26,6 +27,8 @@ public:
static WebIDL::ExceptionOr> construct_impl(JS::Realm&, JS::GCPtr form = {});
static WebIDL::ExceptionOr> construct_impl(JS::Realm&, Vector entry_list);
+ static WebIDL::ExceptionOr> create(JS::Realm&, Vector entry_list);
+
WebIDL::ExceptionOr append(String const& name, String const& value);
WebIDL::ExceptionOr append(String const& name, JS::NonnullGCPtr const& blob_value, Optional const& filename = {});
void delete_(String const& name);