LibWeb/HTML: Implement and use "optional value"

Corresponds to f3444c23ff

Also import a test.
This commit is contained in:
Sam Atkins 2025-07-08 11:28:10 +01:00 committed by Tim Ledbetter
commit af17f38bbf
Notes: github-actions[bot] 2025-07-08 16:10:58 +00:00
9 changed files with 228 additions and 7 deletions

View file

@ -126,6 +126,7 @@ public:
bool suffering_from_a_custom_error() const;
virtual String value() const { return String {}; }
virtual Optional<String> 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<FormAssociatedElement&>(*this).form_associated_element_to_html_element(); }

View file

@ -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<String> 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;

View file

@ -76,6 +76,7 @@ public:
virtual Optional<ARIA::Role> default_role() const override { return ARIA::Role::button; }
virtual String value() const override;
virtual Optional<String> optional_value() const override;
virtual bool has_activation_behavior() const override;
virtual void activation_behavior(DOM::Event const&) override;

View file

@ -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<FormAssociatedElement>(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<FormAssociatedElement>(invoker).optional_value();
request_close_the_dialog(optional_value, invoker);
}

View file

@ -225,9 +225,10 @@ WebIDL::ExceptionOr<void> HTMLFormElement::submit_form(GC::Ref<HTMLElement> 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<FormAssociatedElement>(*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);

View file

@ -659,6 +659,18 @@ String HTMLInputElement::value() const
VERIFY_NOT_REACHED();
}
Optional<String> 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<void> HTMLInputElement::set_value(String const& value)
{
auto& realm = this->realm();

View file

@ -80,6 +80,7 @@ public:
String default_value() const { return get_attribute_value(HTML::AttributeNames::value); }
virtual String value() const override;
virtual Optional<String> optional_value() const override;
WebIDL::ExceptionOr<void> set_value(String const&);
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#concept-textarea/input-relevant-value