LibWeb: Don't group radio buttons from different trees together

Previously, we were searching for other radio buttons from the document
root, rather than the element root.
This commit is contained in:
Tim Ledbetter 2024-09-10 23:51:24 +01:00 committed by Andreas Kling
parent a7578164d4
commit 67981af276
Notes: github-actions[bot] 2024-09-11 06:00:20 +00:00
3 changed files with 31 additions and 3 deletions

View file

@ -0,0 +1,4 @@
Radio button 1 initial checkedness: true
Radio button 2 initial checkedness: false
Radio button 1 checkedness: false
Radio button 2 checkedness: true

View file

@ -0,0 +1,23 @@
<!DOCTYPE html>
<script src="../include.js"></script>
<script>
test(() => {
const container = document.createElement("div");
container.innerHTML =
`<form>
<input type="radio" name="group1" id="radio1" checked>
<input type="radio" name="group1" id="radio2">
</form>`;
const radio1 = container.querySelector("#radio1");
const radio2 = container.querySelector("#radio2");
println(`Radio button 1 initial checkedness: ${radio1.checked}`);
println(`Radio button 2 initial checkedness: ${radio2.checked}`);
radio2.checked = true;
println(`Radio button 1 checkedness: ${radio1.checked}`);
println(`Radio button 2 checkedness: ${radio2.checked}`);
});
</script>

View file

@ -1546,8 +1546,9 @@ static bool is_in_same_radio_button_group(HTML::HTMLInputElement const& a, HTML:
// other input elements b that fulfill all of the following conditions:
return (
// - Both a and b are in the same tree.
&a.root() == &b.root()
// - The input element b's type attribute is in the Radio Button state.
a.type_state() == b.type_state()
&& a.type_state() == b.type_state()
&& b.type_state() == HTMLInputElement::TypeAttributeState::RadioButton
// - Either a and b have the same form owner, or they both have no form owner.
&& a.form() == b.form()
@ -1570,7 +1571,7 @@ void HTMLInputElement::set_checked_within_group()
if (!name().has_value() || name()->is_empty())
return;
document().for_each_in_inclusive_subtree_of_type<HTML::HTMLInputElement>([&](auto& element) {
root().for_each_in_inclusive_subtree_of_type<HTML::HTMLInputElement>([&](auto& element) {
if (element.checked() && &element != this && is_in_same_radio_button_group(*this, element))
element.set_checked(false, ChangeSource::User);
return TraversalDecision::Continue;
@ -1597,7 +1598,7 @@ void HTMLInputElement::legacy_pre_activation_behavior()
// has its checkedness set to true, if any, and then set this element's
// checkedness to true.
if (type_state() == TypeAttributeState::RadioButton) {
document().for_each_in_inclusive_subtree_of_type<HTML::HTMLInputElement>([&](auto& element) {
root().for_each_in_inclusive_subtree_of_type<HTML::HTMLInputElement>([&](auto& element) {
if (element.checked() && is_in_same_radio_button_group(*this, element)) {
m_legacy_pre_activation_behavior_checked_element_in_group = &element;
return TraversalDecision::Break;