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
+
+
+
+
+
+
+
+