diff --git a/Libraries/LibWeb/HTML/HTMLInputElement.cpp b/Libraries/LibWeb/HTML/HTMLInputElement.cpp index 090e36da556..dd1a918b163 100644 --- a/Libraries/LibWeb/HTML/HTMLInputElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLInputElement.cpp @@ -1456,7 +1456,8 @@ void HTMLInputElement::type_attribute_changed(TypeAttributeState old_state, Type set_shadow_root(nullptr); create_shadow_tree_if_needed(); - // FIXME: 5. Signal a type change for the element. (The Radio Button state uses this, in particular.) + // 5. Signal a type change for the element. (The Radio Button state uses this, in particular.) + signal_a_type_change(); // 6. Invoke the value sanitization algorithm, if one is defined for the type attribute's new state. m_value = value_sanitization_algorithm(m_value); @@ -1475,6 +1476,23 @@ void HTMLInputElement::type_attribute_changed(TypeAttributeState old_state, Type } } +// https://html.spec.whatwg.org/multipage/input.html#radio-button-state-(type=radio):signal-a-type-change +void HTMLInputElement::signal_a_type_change() +{ + // https://html.spec.whatwg.org/multipage/input.html#radio-button-state-(type=radio) + // When any of the following phenomena occur, if the element's checkedness state is true after the occurrence, + // the checkedness state of all the other elements in the same radio button group must be set to false: + // ... + // - A type change is signalled for the element. + if (type_state() == TypeAttributeState::RadioButton && checked()) { + root().for_each_in_inclusive_subtree_of_type([&](auto& element) { + if (element.checked() && &element != this && is_in_same_radio_button_group(*this, element)) + element.set_checked(false); + return TraversalDecision::Continue; + }); + } +} + // https://html.spec.whatwg.org/multipage/input.html#attr-input-src WebIDL::ExceptionOr HTMLInputElement::handle_src_attribute(String const& value) { diff --git a/Libraries/LibWeb/HTML/HTMLInputElement.h b/Libraries/LibWeb/HTML/HTMLInputElement.h index 8ff7603eae4..8f2d7e1d37a 100644 --- a/Libraries/LibWeb/HTML/HTMLInputElement.h +++ b/Libraries/LibWeb/HTML/HTMLInputElement.h @@ -389,6 +389,8 @@ private: bool m_has_uncommitted_changes { false }; bool m_is_open { false }; + + void signal_a_type_change(); }; } diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/the-input-element/radio-morphed.txt b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/the-input-element/radio-morphed.txt new file mode 100644 index 00000000000..37afcf3afd3 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/the-input-element/radio-morphed.txt @@ -0,0 +1,6 @@ +Harness status: OK + +Found 1 tests + +1 Pass +Pass Setting type attribute must unset checkedness of other elements \ No newline at end of file diff --git a/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/the-input-element/radio-morphed.html b/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/the-input-element/radio-morphed.html new file mode 100644 index 00000000000..51718ff71f0 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/the-input-element/radio-morphed.html @@ -0,0 +1,17 @@ + +Morphed radio input + + + + + + + +