소스 검색

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.
Tim Ledbetter 10 달 전
부모
커밋
67981af276

+ 4 - 0
Tests/LibWeb/Text/expected/HTML/HTMLInputElement-radio-groups.txt

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

+ 23 - 0
Tests/LibWeb/Text/input/HTML/HTMLInputElement-radio-groups.html

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

+ 4 - 3
Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp

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