From 952433052e66ecc79057159f12f1d0e19ee1fa3c Mon Sep 17 00:00:00 2001 From: Pavel Shliak Date: Fri, 20 Dec 2024 21:26:49 +0400 Subject: [PATCH] LibWeb: Update FormData constructor to reflect the spec --- Libraries/LibWeb/XHR/FormData.cpp | 30 +++++- Libraries/LibWeb/XHR/FormData.h | 2 +- Libraries/LibWeb/XHR/FormData.idl | 2 +- .../xhr/formdata/constructor-submitter.txt | 15 +++ .../xhr/formdata/constructor-submitter.html | 100 ++++++++++++++++++ 5 files changed, 143 insertions(+), 6 deletions(-) create mode 100644 Tests/LibWeb/Text/expected/wpt-import/xhr/formdata/constructor-submitter.txt create mode 100644 Tests/LibWeb/Text/input/wpt-import/xhr/formdata/constructor-submitter.html diff --git a/Libraries/LibWeb/XHR/FormData.cpp b/Libraries/LibWeb/XHR/FormData.cpp index 3c1421f75b17..ef26f842a87f 100644 --- a/Libraries/LibWeb/XHR/FormData.cpp +++ b/Libraries/LibWeb/XHR/FormData.cpp @@ -9,7 +9,9 @@ #include #include #include +#include #include +#include #include #include @@ -18,17 +20,37 @@ namespace Web::XHR { GC_DEFINE_ALLOCATOR(FormData); // https://xhr.spec.whatwg.org/#dom-formdata -WebIDL::ExceptionOr> FormData::construct_impl(JS::Realm& realm, GC::Ptr form) +WebIDL::ExceptionOr> FormData::construct_impl(JS::Realm& realm, GC::Ptr form, Optional> submitter) { Vector list; // 1. If form is given, then: if (form) { - // 1. Let list be the result of constructing the entry list for form. + // 1. If submitter is non-null, then: + if (submitter.has_value() && submitter.value()) { + auto& submitter_element = submitter.value(); + + // 1. If submitter is not a submit button, then throw a TypeError. + if (!is(*submitter_element)) { + return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Submitter is not associated with a form."sv }; + } + auto* form_associated_element = dynamic_cast(submitter_element.ptr()); + + if (!form_associated_element->is_submit_button()) { + return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Submitter is not a valid submit button."sv }; + } + // 2. If submitter’s form owner is not form, then throw a "NotFoundError" DOMException. + auto* form_owner = form_associated_element->form(); + if (form_owner && form_owner != form) { + return WebIDL::NotFoundError::create(realm, "Submitter does not belong to the provided form."_string); + } + } + + // 2. Let list be the result of constructing the entry list for form. auto entry_list = TRY(construct_entry_list(realm, *form)); - // 2. If list is null, then throw an "InvalidStateError" DOMException. + // 3. If list is null, then throw an "InvalidStateError" DOMException. if (!entry_list.has_value()) return WebIDL::InvalidStateError::create(realm, "Form element does not contain any entries."_string); - // 3. Set this’s entry list to list. + // 4. Set this’s entry list to list. list = entry_list.release_value(); } diff --git a/Libraries/LibWeb/XHR/FormData.h b/Libraries/LibWeb/XHR/FormData.h index fc37565dd819..a185bba9ce68 100644 --- a/Libraries/LibWeb/XHR/FormData.h +++ b/Libraries/LibWeb/XHR/FormData.h @@ -24,7 +24,7 @@ class FormData : public Bindings::PlatformObject { public: virtual ~FormData() override; - static WebIDL::ExceptionOr> construct_impl(JS::Realm&, GC::Ptr form = {}); + static WebIDL::ExceptionOr> construct_impl(JS::Realm&, GC::Ptr form = {}, Optional> submitter = {}); static WebIDL::ExceptionOr> construct_impl(JS::Realm&, Vector entry_list); static WebIDL::ExceptionOr> create(JS::Realm&, Vector entry_list); diff --git a/Libraries/LibWeb/XHR/FormData.idl b/Libraries/LibWeb/XHR/FormData.idl index fb844b2e7a8f..aa6f86a6d625 100644 --- a/Libraries/LibWeb/XHR/FormData.idl +++ b/Libraries/LibWeb/XHR/FormData.idl @@ -11,7 +11,7 @@ typedef (File or USVString) FormDataEntryValue; // https://xhr.spec.whatwg.org/#interface-formdata [Exposed=(Window,Worker)] interface FormData { - constructor(optional HTMLFormElement form); + constructor(optional HTMLFormElement form, optional HTMLElement? submitter = null); undefined append(USVString name, USVString value); undefined append(USVString name, Blob blobValue, optional USVString filename); diff --git a/Tests/LibWeb/Text/expected/wpt-import/xhr/formdata/constructor-submitter.txt b/Tests/LibWeb/Text/expected/wpt-import/xhr/formdata/constructor-submitter.txt new file mode 100644 index 000000000000..51492179cd02 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/xhr/formdata/constructor-submitter.txt @@ -0,0 +1,15 @@ +Harness status: OK + +Found 9 tests + +6 Pass +3 Fail +Pass FormData construction should allow a null submitter +Pass FormData construction should allow an undefined form and an undefined submitter +Pass FormData construction should allow an undefined form and a null submitter +Pass FormData construction should throw a TypeError if a non-null submitter is not a submit button +Pass FormData construction should throw a 'NotFoundError' DOMException if a non-null submitter is not owned by the form +Fail The constructed FormData object should contain an in-tree-order entry for a named submit button submitter +Pass The constructed FormData object should not contain an entry for an unnamed submit button submitter +Fail The constructed FormData object should contain in-tree-order entries for an activated Image Button submitter +Fail The constructed FormData object should contain in-tree-order entries for an unactivated Image Button submitter \ No newline at end of file diff --git a/Tests/LibWeb/Text/input/wpt-import/xhr/formdata/constructor-submitter.html b/Tests/LibWeb/Text/input/wpt-import/xhr/formdata/constructor-submitter.html new file mode 100644 index 000000000000..5e1626e97bf3 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/xhr/formdata/constructor-submitter.html @@ -0,0 +1,100 @@ + + + + + + + + +
+ + + + + + + + +
+ +
+ +
+ +