From af17f38bbf633db82ebf10e10f0bd002e95c221b Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Tue, 8 Jul 2025 11:28:10 +0100 Subject: [PATCH] LibWeb/HTML: Implement and use "optional value" Corresponds to https://github.com/whatwg/html/commit/f3444c23ffba2eaba715db1c609253e5488fb530 Also import a test. --- Libraries/LibWeb/HTML/FormAssociatedElement.h | 1 + Libraries/LibWeb/HTML/HTMLButtonElement.cpp | 8 + Libraries/LibWeb/HTML/HTMLButtonElement.h | 1 + Libraries/LibWeb/HTML/HTMLDialogElement.cpp | 6 +- Libraries/LibWeb/HTML/HTMLFormElement.cpp | 7 +- Libraries/LibWeb/HTML/HTMLInputElement.cpp | 12 ++ Libraries/LibWeb/HTML/HTMLInputElement.h | 1 + .../dialog-form-submission.txt | 14 ++ .../dialog-form-submission.html | 185 ++++++++++++++++++ 9 files changed, 228 insertions(+), 7 deletions(-) create mode 100644 Tests/LibWeb/Text/expected/wpt-import/html/semantics/interactive-elements/the-dialog-element/dialog-form-submission.txt create mode 100644 Tests/LibWeb/Text/input/wpt-import/html/semantics/interactive-elements/the-dialog-element/dialog-form-submission.html diff --git a/Libraries/LibWeb/HTML/FormAssociatedElement.h b/Libraries/LibWeb/HTML/FormAssociatedElement.h index dc7d372c74e..6586417a893 100644 --- a/Libraries/LibWeb/HTML/FormAssociatedElement.h +++ b/Libraries/LibWeb/HTML/FormAssociatedElement.h @@ -126,6 +126,7 @@ public: bool suffering_from_a_custom_error() const; virtual String value() const { return String {}; } + virtual Optional optional_value() const { VERIFY_NOT_REACHED(); } virtual HTMLElement& form_associated_element_to_html_element() = 0; HTMLElement const& form_associated_element_to_html_element() const { return const_cast(*this).form_associated_element_to_html_element(); } diff --git a/Libraries/LibWeb/HTML/HTMLButtonElement.cpp b/Libraries/LibWeb/HTML/HTMLButtonElement.cpp index d3b33f1a62b..c9694c432b7 100644 --- a/Libraries/LibWeb/HTML/HTMLButtonElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLButtonElement.cpp @@ -119,9 +119,17 @@ bool HTMLButtonElement::is_submit_button() const // https://html.spec.whatwg.org/multipage/form-elements.html#the-button-element:concept-fe-value String HTMLButtonElement::value() const { + // The element's value is the value of the element's value attribute, if there is one; otherwise the empty string. return attribute(AttributeNames::value).value_or(String {}); } +// https://html.spec.whatwg.org/multipage/form-elements.html#the-button-element:concept-fe-optional-value +Optional HTMLButtonElement::optional_value() const +{ + // The element's optional value is the value of the element's value attribute, if there is one; otherwise null. + return attribute(AttributeNames::value); +} + bool HTMLButtonElement::has_activation_behavior() const { return true; diff --git a/Libraries/LibWeb/HTML/HTMLButtonElement.h b/Libraries/LibWeb/HTML/HTMLButtonElement.h index 8e0f751aa7a..acab0caa8ab 100644 --- a/Libraries/LibWeb/HTML/HTMLButtonElement.h +++ b/Libraries/LibWeb/HTML/HTMLButtonElement.h @@ -76,6 +76,7 @@ public: virtual Optional default_role() const override { return ARIA::Role::button; } virtual String value() const override; + virtual Optional optional_value() const override; virtual bool has_activation_behavior() const override; virtual void activation_behavior(DOM::Event const&) override; diff --git a/Libraries/LibWeb/HTML/HTMLDialogElement.cpp b/Libraries/LibWeb/HTML/HTMLDialogElement.cpp index d5ecbd8cb94..f9ea7ff1c39 100644 --- a/Libraries/LibWeb/HTML/HTMLDialogElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLDialogElement.cpp @@ -492,16 +492,14 @@ void HTMLDialogElement::invoker_command_steps(DOM::Element& invoker, String& com // 2. If command is in the Close state and element has an open attribute, // then close the dialog given element with invoker's optional value and invoker. if (command == "close" && has_attribute(AttributeNames::open)) { - // FIXME: This assumes invoker is a button. - auto optional_value = invoker.get_attribute(AttributeNames::value); + auto const optional_value = as(invoker).optional_value(); close_the_dialog(optional_value, invoker); } // 3. If command is in the Request Close state and element has an open attribute, // then request to close the dialog element with invoker's optional value and invoker. if (command == "request-close" && has_attribute(AttributeNames::open)) { - // FIXME: This assumes invoker is a button. - auto optional_value = invoker.get_attribute(AttributeNames::value); + auto const optional_value = as(invoker).optional_value(); request_close_the_dialog(optional_value, invoker); } diff --git a/Libraries/LibWeb/HTML/HTMLFormElement.cpp b/Libraries/LibWeb/HTML/HTMLFormElement.cpp index 7eff12ad86f..d03de51374b 100644 --- a/Libraries/LibWeb/HTML/HTMLFormElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLFormElement.cpp @@ -225,9 +225,10 @@ WebIDL::ExceptionOr HTMLFormElement::submit_form(GC::Ref subm } } - // 5. Otherwise, if submitter has a value, then set result to that value. - if (!result.has_value()) - result = submitter->get_attribute_value(AttributeNames::value); + // 5. Otherwise, if submitter is a submit button, then set result to submitter's optional value. + else if (auto* form_associated_element = as_if(*submitter); form_associated_element && form_associated_element->is_submit_button()) { + result = form_associated_element->optional_value(); + } // 6. Close the dialog subject with result and null. subject->close_the_dialog(move(result), nullptr); diff --git a/Libraries/LibWeb/HTML/HTMLInputElement.cpp b/Libraries/LibWeb/HTML/HTMLInputElement.cpp index 07f52efda41..5ea57f4a2de 100644 --- a/Libraries/LibWeb/HTML/HTMLInputElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLInputElement.cpp @@ -659,6 +659,18 @@ String HTMLInputElement::value() const VERIFY_NOT_REACHED(); } +Optional HTMLInputElement::optional_value() const +{ + switch (m_type) { + // https://html.spec.whatwg.org/multipage/input.html#submit-button-state-(type=submit):concept-fe-optional-value + case TypeAttributeState::SubmitButton: + // The element's optional value is the value of the element's value attribute, if there is one; otherwise null. + return get_attribute(AttributeNames::value); + default: + VERIFY_NOT_REACHED(); + } +} + WebIDL::ExceptionOr HTMLInputElement::set_value(String const& value) { auto& realm = this->realm(); diff --git a/Libraries/LibWeb/HTML/HTMLInputElement.h b/Libraries/LibWeb/HTML/HTMLInputElement.h index 1237ec81119..f5b501fac8a 100644 --- a/Libraries/LibWeb/HTML/HTMLInputElement.h +++ b/Libraries/LibWeb/HTML/HTMLInputElement.h @@ -80,6 +80,7 @@ public: String default_value() const { return get_attribute_value(HTML::AttributeNames::value); } virtual String value() const override; + virtual Optional optional_value() const override; WebIDL::ExceptionOr set_value(String const&); // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#concept-textarea/input-relevant-value diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/semantics/interactive-elements/the-dialog-element/dialog-form-submission.txt b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/interactive-elements/the-dialog-element/dialog-form-submission.txt new file mode 100644 index 00000000000..785c72cfd94 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/interactive-elements/the-dialog-element/dialog-form-submission.txt @@ -0,0 +1,14 @@ +Harness status: Error + +Found 8 tests + +6 Pass +2 Fail +Pass click the form submission button should close the dialog +Pass form submission should return correct value +Pass returnValue doesn't update when there's no value attribute. +Pass returnValue does update when there's an empty value attribute. +Fail input image button should return the coordinates +Pass formmethod attribute should use dialog form submission +Pass closing the dialog while submitting should stop the submission +Fail calling form.submit() in click handler of submit button should start the submission synchronously \ No newline at end of file diff --git a/Tests/LibWeb/Text/input/wpt-import/html/semantics/interactive-elements/the-dialog-element/dialog-form-submission.html b/Tests/LibWeb/Text/input/wpt-import/html/semantics/interactive-elements/the-dialog-element/dialog-form-submission.html new file mode 100644 index 00000000000..deaaffb7eeb --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/semantics/interactive-elements/the-dialog-element/dialog-form-submission.html @@ -0,0 +1,185 @@ + + + +Test dialog form submission + + + + + + + + +
+ + +
+
+ +
+
+ +