From ff1ef07160ee698ef47c058d2ed9b16e869fa668 Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Thu, 20 Feb 2025 17:01:28 +0000 Subject: [PATCH] LibWeb/HTML: Update HTMLButtonElement.type to match spec changes Corresponds to part of https://github.com/whatwg/html/pull/9841 and then https://github.com/whatwg/html/pull/11047 Adding `Auto` as a type state feels a little odd, as it's not an actual type allowed in HTML. However, it's the default state when the value is missing or invalid, which works out the same, as long as we never serialize "auto", which we don't. --- Libraries/LibWeb/HTML/AttributeNames.h | 2 + Libraries/LibWeb/HTML/HTMLButtonElement.cpp | 57 +++++++++++++++-- Libraries/LibWeb/HTML/HTMLButtonElement.h | 6 +- Libraries/LibWeb/HTML/HTMLButtonElement.idl | 2 +- .../button-type-reflection.txt | 27 ++++++++ .../button-type-reflection.html | 64 +++++++++++++++++++ 6 files changed, 149 insertions(+), 9 deletions(-) create mode 100644 Tests/LibWeb/Text/expected/wpt-import/html/semantics/the-button-element/command-and-commandfor/button-type-reflection.txt create mode 100644 Tests/LibWeb/Text/input/wpt-import/html/semantics/the-button-element/command-and-commandfor/button-type-reflection.html diff --git a/Libraries/LibWeb/HTML/AttributeNames.h b/Libraries/LibWeb/HTML/AttributeNames.h index 5dacd3d0880c..a868a9e2173d 100644 --- a/Libraries/LibWeb/HTML/AttributeNames.h +++ b/Libraries/LibWeb/HTML/AttributeNames.h @@ -51,6 +51,8 @@ namespace AttributeNames { __ENUMERATE_HTML_ATTRIBUTE(color, "color") \ __ENUMERATE_HTML_ATTRIBUTE(cols, "cols") \ __ENUMERATE_HTML_ATTRIBUTE(colspan, "colspan") \ + __ENUMERATE_HTML_ATTRIBUTE(command, "command") \ + __ENUMERATE_HTML_ATTRIBUTE(commandfor, "commandfor") \ __ENUMERATE_HTML_ATTRIBUTE(compact, "compact") \ __ENUMERATE_HTML_ATTRIBUTE(content, "content") \ __ENUMERATE_HTML_ATTRIBUTE(contenteditable, "contenteditable") \ diff --git a/Libraries/LibWeb/HTML/HTMLButtonElement.cpp b/Libraries/LibWeb/HTML/HTMLButtonElement.cpp index 22a7592ae4d9..e4fbcc9a7cb7 100644 --- a/Libraries/LibWeb/HTML/HTMLButtonElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLButtonElement.cpp @@ -37,12 +37,44 @@ HTMLButtonElement::TypeAttributeState HTMLButtonElement::type_state() const ENUMERATE_HTML_BUTTON_TYPE_ATTRIBUTES #undef __ENUMERATE_HTML_BUTTON_TYPE_ATTRIBUTE - // The missing value default and invalid value default are the Submit Button state. - return HTMLButtonElement::TypeAttributeState::Submit; + // The attribute's missing value default and invalid value default are both the Auto state. + // https://html.spec.whatwg.org/multipage/form-elements.html#attr-button-type-auto-state + return HTMLButtonElement::TypeAttributeState::Auto; } -WebIDL::ExceptionOr HTMLButtonElement::set_type(String const& type) +// https://html.spec.whatwg.org/multipage/form-elements.html#dom-button-type +String HTMLButtonElement::type_for_bindings() const { + // The type getter steps are: + // 1. If this is a submit button, then return "submit". + if (is_submit_button()) + return "submit"_string; + + // 2. Let state be this's type attribute. + auto state = type_state(); + + // 3. Assert: state is not in the Submit Button state. + VERIFY(state != TypeAttributeState::Submit); + + // 4. If state is in the Auto state, then return "button". + if (state == TypeAttributeState::Auto) + return "button"_string; + + // 5. Return the keyword value corresponding to state. + switch (state) { +#define __ENUMERATE_HTML_BUTTON_TYPE_ATTRIBUTE(keyword, state) \ + case TypeAttributeState::state: \ + return #keyword##_string; + ENUMERATE_HTML_BUTTON_TYPE_ATTRIBUTES +#undef __ENUMERATE_HTML_BUTTON_TYPE_ATTRIBUTE + } + VERIFY_NOT_REACHED(); +} + +// https://html.spec.whatwg.org/multipage/form-elements.html#dom-button-type +WebIDL::ExceptionOr HTMLButtonElement::set_type_for_bindings(String const& type) +{ + // The type setter steps are to set the type content attribute to the given value. return set_attribute(HTML::AttributeNames::type, type); } @@ -68,8 +100,17 @@ i32 HTMLButtonElement::default_tab_index_value() const // https://html.spec.whatwg.org/multipage/form-elements.html#the-button-element:concept-submit-button bool HTMLButtonElement::is_submit_button() const { - // A button element is said to be a submit button if the type attribute is in the Submit Button state. - return type_state() == TypeAttributeState::Submit; + // A button element is said to be a submit button if any of the following are true: + switch (type_state()) { + // - the type attribute is in the Auto state and both the command and commandfor content attributes are not present; or + case TypeAttributeState::Auto: + return !has_attribute(AttributeNames::command) && !has_attribute(AttributeNames::commandfor); + // - the type attribute is in the Submit Button state. + case TypeAttributeState::Submit: + return true; + default: + return false; + } } // https://html.spec.whatwg.org/multipage/form-elements.html#the-button-element:concept-fe-value @@ -106,7 +147,11 @@ void HTMLButtonElement::activation_behavior(DOM::Event const& event) } } - // 4. Run the popover target attribute activation behavior given element and event's target. + // FIXME: 4. Let target be the result of running element's get the commandfor associated element. + // FIXME: 5. If target is not null: + // ... + + // 6. Otherwise, run the popover target attribute activation behavior given element and event's target. if (event.target() && event.target()->is_dom_node()) PopoverInvokerElement::popover_target_activation_behaviour(*this, as(*event.target())); } diff --git a/Libraries/LibWeb/HTML/HTMLButtonElement.h b/Libraries/LibWeb/HTML/HTMLButtonElement.h index 44876b2a88ef..3a239914a82b 100644 --- a/Libraries/LibWeb/HTML/HTMLButtonElement.h +++ b/Libraries/LibWeb/HTML/HTMLButtonElement.h @@ -16,7 +16,8 @@ namespace Web::HTML { #define ENUMERATE_HTML_BUTTON_TYPE_ATTRIBUTES \ __ENUMERATE_HTML_BUTTON_TYPE_ATTRIBUTE(submit, Submit) \ __ENUMERATE_HTML_BUTTON_TYPE_ATTRIBUTE(reset, Reset) \ - __ENUMERATE_HTML_BUTTON_TYPE_ATTRIBUTE(button, Button) + __ENUMERATE_HTML_BUTTON_TYPE_ATTRIBUTE(button, Button) \ + __ENUMERATE_HTML_BUTTON_TYPE_ATTRIBUTE(auto, Auto) class HTMLButtonElement final : public HTMLElement @@ -38,7 +39,8 @@ class HTMLButtonElement final }; TypeAttributeState type_state() const; - WebIDL::ExceptionOr set_type(String const&); + String type_for_bindings() const; + WebIDL::ExceptionOr set_type_for_bindings(String const&); virtual void form_associated_element_attribute_changed(FlyString const& name, Optional const& value, Optional const& namespace_) override; diff --git a/Libraries/LibWeb/HTML/HTMLButtonElement.idl b/Libraries/LibWeb/HTML/HTMLButtonElement.idl index b1eaeacf3368..65e6fba987e1 100644 --- a/Libraries/LibWeb/HTML/HTMLButtonElement.idl +++ b/Libraries/LibWeb/HTML/HTMLButtonElement.idl @@ -23,7 +23,7 @@ interface HTMLButtonElement : HTMLElement { [CEReactions, Reflect=formnovalidate] attribute boolean formNoValidate; [CEReactions, Reflect=formtarget] attribute DOMString formTarget; [CEReactions, Reflect] attribute DOMString name; - [CEReactions, Reflect, Enumerated=ButtonTypeState] attribute DOMString type; + [CEReactions, ImplementedAs=type_for_bindings, Enumerated=ButtonTypeState] attribute DOMString type; [CEReactions, Reflect] attribute DOMString value; [FIXME] readonly attribute boolean willValidate; diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/semantics/the-button-element/command-and-commandfor/button-type-reflection.txt b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/the-button-element/command-and-commandfor/button-type-reflection.txt new file mode 100644 index 000000000000..e0fc007e3c59 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/the-button-element/command-and-commandfor/button-type-reflection.txt @@ -0,0 +1,27 @@ +Harness status: OK + +Found 21 tests + +18 Pass +3 Fail +Pass Button with id reset-in-form should reflect type correctly +Pass Button with id submit-in-form should reflect type correctly +Pass Button with id button-in-form should reflect type correctly +Fail Button with id invalid-in-form should reflect type correctly +Pass Button with id missing-in-form should reflect type correctly +Pass Button with id missing-in-form-command-only should reflect type correctly +Pass Button with id missing-in-form-commandfor-only should reflect type correctly +Pass Button with id reset-attr-form should reflect type correctly +Pass Button with id submit-attr-form should reflect type correctly +Pass Button with id button-attr-form should reflect type correctly +Fail Button with id invalid-attr-form should reflect type correctly +Pass Button with id missing-attr-form should reflect type correctly +Pass Button with id missing-attr-form-command-only should reflect type correctly +Pass Button with id missing-attr-form-commandfor-only should reflect type correctly +Pass Button with id reset-outside-form should reflect type correctly +Pass Button with id submit-outside-form should reflect type correctly +Pass Button with id button-outside-form should reflect type correctly +Fail Button with id invalid-outside-form should reflect type correctly +Pass Button with id missing-outside-form should reflect type correctly +Pass Button with id missing-outside-form-command-only should reflect type correctly +Pass Button with id missing-outside-form-commandfor-only should reflect type correctly \ No newline at end of file diff --git a/Tests/LibWeb/Text/input/wpt-import/html/semantics/the-button-element/command-and-commandfor/button-type-reflection.html b/Tests/LibWeb/Text/input/wpt-import/html/semantics/the-button-element/command-and-commandfor/button-type-reflection.html new file mode 100644 index 000000000000..042bb7ef9e5e --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/semantics/the-button-element/command-and-commandfor/button-type-reflection.html @@ -0,0 +1,64 @@ + + + + + + +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + +