Title: [288734] trunk
Revision
288734
Author
[email protected]
Date
2022-01-27 23:58:57 -0800 (Thu, 27 Jan 2022)

Log Message

Radio buttons with no form owner are not grouped
https://bugs.webkit.org/show_bug.cgi?id=220502
<rdar://problem/73300895>

Reviewed by Darin Adler.

LayoutTests/imported/w3c:

Rebaseline WPT tests now that more checks are passing.

* web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valid-expected.txt:
* web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valueMissing-expected.txt:
* web-platform-tests/html/semantics/forms/the-input-element/radio-expected.txt:

Source/WebCore:

Per the HTML specification and to match the behavior of both Gecko and Blink,
radio buttons should still be grouped, even if they are disconnected and not
owned by a form.

This patch aligns our behavior with Gecko and Blink and is based on the following
Blink commit:
- https://chromium-review.googlesource.com/c/chromium/src/+/1988087

No new tests, rebaselined existing tests.

* html/HTMLInputElement.cpp:
(WebCore::HTMLInputElement::setChecked):
(WebCore::HTMLInputElement::didChangeForm):
(WebCore::HTMLInputElement::insertedIntoAncestor):
(WebCore::HTMLInputElement::removedFromAncestor):
(WebCore::HTMLInputElement::checkedRadioButtonForGroup const):
* html/InputType.h:
(WebCore::InputType::willUpdateCheckedness):
* html/RadioInputType.cpp:
(WebCore::RadioInputType::valueMissing const):
(WebCore::RadioInputType::willUpdateCheckedness):
* html/RadioInputType.h:

LayoutTests:

* fast/forms/radio/ValidityState-valueMissing-radio-expected.txt:
* fast/forms/radio/ValidityState-valueMissing-radio.html:
* fast/forms/radio/radio-live-validation-style-expected.txt:
* fast/forms/radio/radio-live-validation-style.html:
Update existing tests to reflect behavior change. I have verified that our behavior on those tests
is aligned with both Firefox and Chrome.

* platform/gtk/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valid-expected.txt:
* platform/gtk/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valueMissing-expected.txt:
* platform/ios-wk2/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valid-expected.txt:
* platform/ios-wk2/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valueMissing-expected.txt:
* platform/mac-wk2/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valid-expected.txt:
* platform/mac-wk2/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valueMissing-expected.txt:
Rebaseline existing WPT tests now that more checks are passing.

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (288733 => 288734)


--- trunk/LayoutTests/ChangeLog	2022-01-28 07:33:35 UTC (rev 288733)
+++ trunk/LayoutTests/ChangeLog	2022-01-28 07:58:57 UTC (rev 288734)
@@ -1,3 +1,26 @@
+2022-01-27  Chris Dumez  <[email protected]>
+
+        Radio buttons with no form owner are not grouped
+        https://bugs.webkit.org/show_bug.cgi?id=220502
+        <rdar://problem/73300895>
+
+        Reviewed by Darin Adler.
+
+        * fast/forms/radio/ValidityState-valueMissing-radio-expected.txt:
+        * fast/forms/radio/ValidityState-valueMissing-radio.html:
+        * fast/forms/radio/radio-live-validation-style-expected.txt:
+        * fast/forms/radio/radio-live-validation-style.html:
+        Update existing tests to reflect behavior change. I have verified that our behavior on those tests
+        is aligned with both Firefox and Chrome.
+
+        * platform/gtk/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valid-expected.txt:
+        * platform/gtk/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valueMissing-expected.txt:
+        * platform/ios-wk2/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valid-expected.txt:
+        * platform/ios-wk2/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valueMissing-expected.txt:
+        * platform/mac-wk2/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valid-expected.txt:
+        * platform/mac-wk2/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valueMissing-expected.txt:
+        Rebaseline existing WPT tests now that more checks are passing.
+
 2022-01-27  Antoine Quint  <[email protected]>
 
         [Model] Allow disabling interaction

Modified: trunk/LayoutTests/fast/forms/radio/ValidityState-valueMissing-radio-expected.txt (288733 => 288734)


--- trunk/LayoutTests/fast/forms/radio/ValidityState-valueMissing-radio-expected.txt	2022-01-28 07:33:35 UTC (rev 288733)
+++ trunk/LayoutTests/fast/forms/radio/ValidityState-valueMissing-radio-expected.txt	2022-01-28 07:58:57 UTC (rev 288734)
@@ -40,11 +40,11 @@
 PASS inputs[2].validity.valueMissing is false
 
 Not in a radio button group
-PASS requiredButton.validity.valueMissing is false
 PASS requiredButton.validity.valueMissing is true
+PASS requiredButton.validity.valueMissing is true
 PASS button.validity.valueMissing is true
 PASS button.validity.valueMissing is false
-PASS requiredButton.validity.valueMissing is false
+PASS requiredButton.validity.valueMissing is true
 PASS successfullyParsed is true
 
 TEST COMPLETE

Modified: trunk/LayoutTests/fast/forms/radio/ValidityState-valueMissing-radio.html (288733 => 288734)


--- trunk/LayoutTests/fast/forms/radio/ValidityState-valueMissing-radio.html	2022-01-28 07:33:35 UTC (rev 288733)
+++ trunk/LayoutTests/fast/forms/radio/ValidityState-valueMissing-radio.html	2022-01-28 07:58:57 UTC (rev 288734)
@@ -71,7 +71,7 @@
 requiredButton.type = 'radio';
 requiredButton.name = 'victim';
 requiredButton.required = true;
-shouldBeFalse('requiredButton.validity.valueMissing');
+shouldBeTrue('requiredButton.validity.valueMissing');
 
 parent.innerHTML = '<input name=victim type=radio required><input name=victim type=radio>';
 requiredButton = document.getElementsByName('victim')[0];
@@ -81,7 +81,7 @@
 parent.removeChild(button);
 shouldBeFalse('button.validity.valueMissing');
 parent.removeChild(requiredButton);
-shouldBeFalse('requiredButton.validity.valueMissing');
+shouldBeTrue('requiredButton.validity.valueMissing');
 
 </script>
 <script src=""

Modified: trunk/LayoutTests/fast/forms/radio/radio-live-validation-style-expected.txt (288733 => 288734)


--- trunk/LayoutTests/fast/forms/radio/radio-live-validation-style-expected.txt	2022-01-28 07:33:35 UTC (rev 288733)
+++ trunk/LayoutTests/fast/forms/radio/radio-live-validation-style-expected.txt	2022-01-28 07:58:57 UTC (rev 288734)
@@ -7,7 +7,7 @@
 PASS backgroundOf($("radio1")) is validColor
 PASS parent.removeChild($("radio2")); backgroundOf($("radio1")) is invalidColor
 PASS $("radio1").remove(); radio2.matches(":valid") is false
-PASS radio2.remove(); radio2.matches(":valid") is true
+PASS radio2.remove(); radio2.matches(":valid") is false
 
 Removing a checked radio button from a required radio button group by name attribute change:
 PASS $("radio2").name = "group2"; backgroundOf($("radio1")) is invalidColor

Modified: trunk/LayoutTests/fast/forms/radio/radio-live-validation-style.html (288733 => 288734)


--- trunk/LayoutTests/fast/forms/radio/radio-live-validation-style.html	2022-01-28 07:33:35 UTC (rev 288733)
+++ trunk/LayoutTests/fast/forms/radio/radio-live-validation-style.html	2022-01-28 07:58:57 UTC (rev 288734)
@@ -35,7 +35,7 @@
     '<input type=radio name=group1 required id=radio3>';
 var radio2 = $('radio2');
 shouldBeFalse('$("radio1").remove(); radio2.matches(":valid")');
-shouldBeTrue('radio2.remove(); radio2.matches(":valid")');
+shouldBeFalse('radio2.remove(); radio2.matches(":valid")');
 debug('');
 
 debug('Removing a checked radio button from a required radio button group by name attribute change:');

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (288733 => 288734)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2022-01-28 07:33:35 UTC (rev 288733)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2022-01-28 07:58:57 UTC (rev 288734)
@@ -1,5 +1,19 @@
 2022-01-27  Chris Dumez  <[email protected]>
 
+        Radio buttons with no form owner are not grouped
+        https://bugs.webkit.org/show_bug.cgi?id=220502
+        <rdar://problem/73300895>
+
+        Reviewed by Darin Adler.
+
+        Rebaseline WPT tests now that more checks are passing.
+
+        * web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valid-expected.txt:
+        * web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valueMissing-expected.txt:
+        * web-platform-tests/html/semantics/forms/the-input-element/radio-expected.txt:
+
+2022-01-27  Chris Dumez  <[email protected]>
+
         Geolocation API should callback with error if doc is not fully active
         https://bugs.webkit.org/show_bug.cgi?id=228319
         <rdar://problem/81450315>

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valid-expected.txt (288733 => 288734)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valid-expected.txt	2022-01-28 07:33:35 UTC (rev 288733)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valid-expected.txt	2022-01-28 07:58:57 UTC (rev 288734)
@@ -23,7 +23,7 @@
 PASS [INPUT in NUMBER status] validity.valid must be false if validity.stepMismatch is true
 PASS [INPUT in NUMBER status] validity.valid must be false if validity.valueMissing is true
 PASS [INPUT in CHECKBOX status] validity.valid must be false if validity.valueMissing is true
-FAIL [INPUT in RADIO status] validity.valid must be false if validity.valueMissing is true assert_false: The validity.valid should be false. expected false got true
+PASS [INPUT in RADIO status] validity.valid must be false if validity.valueMissing is true
 PASS [INPUT in FILE status] validity.valid must be false if validity.valueMissing is true
 PASS [select]  validity.valid must be false if validity.valueMissing is true
 PASS [textarea]  validity.valid must be false if validity.valueMissing is true

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valueMissing-expected.txt (288733 => 288734)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valueMissing-expected.txt	2022-01-28 07:33:35 UTC (rev 288733)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valueMissing-expected.txt	2022-01-28 07:58:57 UTC (rev 288734)
@@ -38,7 +38,7 @@
 PASS [INPUT in CHECKBOX status] The checked attribute is false
 PASS [INPUT in RADIO status] The required attribute is not set
 PASS [INPUT in RADIO status] The checked attribute is true
-FAIL [INPUT in RADIO status] The checked attribute is false assert_true: The validity.valueMissing should be true. expected true got false
+PASS [INPUT in RADIO status] The checked attribute is false
 PASS [INPUT in RADIO status] The checked attribute is false and the name attribute is empty
 PASS [INPUT in FILE status] The required attribute is not set
 PASS [INPUT in FILE status] The Files attribute is null

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/radio-expected.txt (288733 => 288734)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/radio-expected.txt	2022-01-28 07:33:35 UTC (rev 288733)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/radio-expected.txt	2022-01-28 07:58:57 UTC (rev 288734)
@@ -7,8 +7,8 @@
 PASS radio inputs with non-ASCII name attributes belong to the same radio button group
 PASS changing the name of a radio input element and setting its checkedness to true makes all the other elements' checkedness in the same radio button group be set to false
 PASS moving radio input element out of or into a form should still work as expected
-FAIL Radio buttons in an orphan tree should make a group assert_false: The second radio should be unchecked after setting checked expected false got true
-FAIL Radio buttons in different groups (because they have different form owners or no form owner) do not affect each other's checkedness assert_false: radio5 should be unchecked expected false got true
+PASS Radio buttons in an orphan tree should make a group
+PASS Radio buttons in different groups (because they have different form owners or no form owner) do not affect each other's checkedness
 PASS Radio buttons in different groups (because they are not in the same tree) do not affect each other's checkedness
 PASS Radio buttons in different groups (because they have different name attribute values, or no name attribute) do not affect each other's checkedness
 

Modified: trunk/LayoutTests/platform/gtk/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valid-expected.txt (288733 => 288734)


--- trunk/LayoutTests/platform/gtk/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valid-expected.txt	2022-01-28 07:33:35 UTC (rev 288733)
+++ trunk/LayoutTests/platform/gtk/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valid-expected.txt	2022-01-28 07:58:57 UTC (rev 288734)
@@ -38,7 +38,7 @@
 PASS [INPUT in NUMBER status] validity.valid must be false if validity.stepMismatch is true
 PASS [INPUT in NUMBER status] validity.valid must be false if validity.valueMissing is true
 PASS [INPUT in CHECKBOX status] validity.valid must be false if validity.valueMissing is true
-FAIL [INPUT in RADIO status] validity.valid must be false if validity.valueMissing is true assert_false: The validity.valid should be false. expected false got true
+PASS [INPUT in RADIO status] validity.valid must be false if validity.valueMissing is true
 PASS [INPUT in FILE status] validity.valid must be false if validity.valueMissing is true
 PASS [select]  validity.valid must be false if validity.valueMissing is true
 PASS [textarea]  validity.valid must be false if validity.valueMissing is true

Modified: trunk/LayoutTests/platform/gtk/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valueMissing-expected.txt (288733 => 288734)


--- trunk/LayoutTests/platform/gtk/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valueMissing-expected.txt	2022-01-28 07:33:35 UTC (rev 288733)
+++ trunk/LayoutTests/platform/gtk/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valueMissing-expected.txt	2022-01-28 07:58:57 UTC (rev 288734)
@@ -84,7 +84,7 @@
 PASS [INPUT in CHECKBOX status] The checked attribute is false
 PASS [INPUT in RADIO status] The required attribute is not set
 PASS [INPUT in RADIO status] The checked attribute is true
-FAIL [INPUT in RADIO status] The checked attribute is false assert_true: The validity.valueMissing should be true. expected true got false
+PASS [INPUT in RADIO status] The checked attribute is false
 PASS [INPUT in RADIO status] The checked attribute is false and the name attribute is empty
 PASS [INPUT in FILE status] The required attribute is not set
 PASS [INPUT in FILE status] The Files attribute is null

Modified: trunk/LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valid-expected.txt (288733 => 288734)


--- trunk/LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valid-expected.txt	2022-01-28 07:33:35 UTC (rev 288733)
+++ trunk/LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valid-expected.txt	2022-01-28 07:58:57 UTC (rev 288734)
@@ -38,7 +38,7 @@
 PASS [INPUT in NUMBER status] validity.valid must be false if validity.stepMismatch is true
 PASS [INPUT in NUMBER status] validity.valid must be false if validity.valueMissing is true
 PASS [INPUT in CHECKBOX status] validity.valid must be false if validity.valueMissing is true
-FAIL [INPUT in RADIO status] validity.valid must be false if validity.valueMissing is true assert_false: The validity.valid should be false. expected false got true
+PASS [INPUT in RADIO status] validity.valid must be false if validity.valueMissing is true
 PASS [INPUT in FILE status] validity.valid must be false if validity.valueMissing is true
 PASS [select]  validity.valid must be false if validity.valueMissing is true
 PASS [textarea]  validity.valid must be false if validity.valueMissing is true

Modified: trunk/LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valueMissing-expected.txt (288733 => 288734)


--- trunk/LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valueMissing-expected.txt	2022-01-28 07:33:35 UTC (rev 288733)
+++ trunk/LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valueMissing-expected.txt	2022-01-28 07:58:57 UTC (rev 288734)
@@ -84,7 +84,7 @@
 PASS [INPUT in CHECKBOX status] The checked attribute is false
 PASS [INPUT in RADIO status] The required attribute is not set
 PASS [INPUT in RADIO status] The checked attribute is true
-FAIL [INPUT in RADIO status] The checked attribute is false assert_true: The validity.valueMissing should be true. expected true got false
+PASS [INPUT in RADIO status] The checked attribute is false
 PASS [INPUT in RADIO status] The checked attribute is false and the name attribute is empty
 PASS [INPUT in FILE status] The required attribute is not set
 PASS [INPUT in FILE status] The Files attribute is null

Modified: trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valid-expected.txt (288733 => 288734)


--- trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valid-expected.txt	2022-01-28 07:33:35 UTC (rev 288733)
+++ trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valid-expected.txt	2022-01-28 07:58:57 UTC (rev 288734)
@@ -38,7 +38,7 @@
 PASS [INPUT in NUMBER status] validity.valid must be false if validity.stepMismatch is true
 PASS [INPUT in NUMBER status] validity.valid must be false if validity.valueMissing is true
 PASS [INPUT in CHECKBOX status] validity.valid must be false if validity.valueMissing is true
-FAIL [INPUT in RADIO status] validity.valid must be false if validity.valueMissing is true assert_false: The validity.valid should be false. expected false got true
+PASS [INPUT in RADIO status] validity.valid must be false if validity.valueMissing is true
 PASS [INPUT in FILE status] validity.valid must be false if validity.valueMissing is true
 PASS [select]  validity.valid must be false if validity.valueMissing is true
 PASS [textarea]  validity.valid must be false if validity.valueMissing is true

Modified: trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valueMissing-expected.txt (288733 => 288734)


--- trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valueMissing-expected.txt	2022-01-28 07:33:35 UTC (rev 288733)
+++ trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valueMissing-expected.txt	2022-01-28 07:58:57 UTC (rev 288734)
@@ -84,7 +84,7 @@
 PASS [INPUT in CHECKBOX status] The checked attribute is false
 PASS [INPUT in RADIO status] The required attribute is not set
 PASS [INPUT in RADIO status] The checked attribute is true
-FAIL [INPUT in RADIO status] The checked attribute is false assert_true: The validity.valueMissing should be true. expected true got false
+PASS [INPUT in RADIO status] The checked attribute is false
 PASS [INPUT in RADIO status] The checked attribute is false and the name attribute is empty
 PASS [INPUT in FILE status] The required attribute is not set
 PASS [INPUT in FILE status] The Files attribute is null

Modified: trunk/Source/WebCore/ChangeLog (288733 => 288734)


--- trunk/Source/WebCore/ChangeLog	2022-01-28 07:33:35 UTC (rev 288733)
+++ trunk/Source/WebCore/ChangeLog	2022-01-28 07:58:57 UTC (rev 288734)
@@ -1,3 +1,34 @@
+2022-01-27  Chris Dumez  <[email protected]>
+
+        Radio buttons with no form owner are not grouped
+        https://bugs.webkit.org/show_bug.cgi?id=220502
+        <rdar://problem/73300895>
+
+        Reviewed by Darin Adler.
+
+        Per the HTML specification and to match the behavior of both Gecko and Blink,
+        radio buttons should still be grouped, even if they are disconnected and not
+        owned by a form.
+
+        This patch aligns our behavior with Gecko and Blink and is based on the following
+        Blink commit:
+        - https://chromium-review.googlesource.com/c/chromium/src/+/1988087
+
+        No new tests, rebaselined existing tests.
+
+        * html/HTMLInputElement.cpp:
+        (WebCore::HTMLInputElement::setChecked):
+        (WebCore::HTMLInputElement::didChangeForm):
+        (WebCore::HTMLInputElement::insertedIntoAncestor):
+        (WebCore::HTMLInputElement::removedFromAncestor):
+        (WebCore::HTMLInputElement::checkedRadioButtonForGroup const):
+        * html/InputType.h:
+        (WebCore::InputType::willUpdateCheckedness):
+        * html/RadioInputType.cpp:
+        (WebCore::RadioInputType::valueMissing const):
+        (WebCore::RadioInputType::willUpdateCheckedness):
+        * html/RadioInputType.h:
+
 2022-01-27  Diego Pino Garcia  <[email protected]>
 
         [WPE] Unreviewed, fix non-unified build after r288672

Modified: trunk/Source/WebCore/html/HTMLInputElement.cpp (288733 => 288734)


--- trunk/Source/WebCore/html/HTMLInputElement.cpp	2022-01-28 07:33:35 UTC (rev 288733)
+++ trunk/Source/WebCore/html/HTMLInputElement.cpp	2022-01-28 07:58:57 UTC (rev 288734)
@@ -61,6 +61,7 @@
 #include "Page.h"
 #include "PlatformMouseEvent.h"
 #include "PseudoClassChangeInvalidation.h"
+#include "RadioInputType.h"
 #include "RenderTextControlSingleLine.h"
 #include "RenderTheme.h"
 #include "ScopedEventQueue.h"
@@ -980,6 +981,8 @@
     if (checked() == isChecked)
         return;
 
+    m_inputType->willUpdateCheckedness(isChecked);
+
     Style::PseudoClassChangeInvalidation checkedInvalidation(*this, CSSSelector::PseudoClassChecked, isChecked);
 
     m_dirtyCheckednessFlag = true;
@@ -1586,6 +1589,8 @@
 #if ENABLE(DATALIST_ELEMENT)
     resetListAttributeTargetObserver();
 #endif
+    if (isRadioButton())
+        updateValidity();
     return InsertedIntoAncestorResult::NeedsPostInsertionCallback;
 }
 
@@ -1608,6 +1613,8 @@
         removeFromRadioButtonGroup();
     HTMLTextFormControlElement::removedFromAncestor(removalType, oldParentOfRemovedTree);
     ASSERT(!isConnected());
+    if (removalType.disconnectedFromDocument && !form() && isRadioButton())
+        updateValidity();
 #if ENABLE(DATALIST_ELEMENT)
     resetListAttributeTargetObserver();
 #endif
@@ -1956,9 +1963,31 @@
 
 RefPtr<HTMLInputElement> HTMLInputElement::checkedRadioButtonForGroup() const
 {
+    ASSERT(isRadioButton());
+
+    if (checked())
+        return const_cast<HTMLInputElement*>(this);
+
+    auto& name = this->name();
     if (RadioButtonGroups* buttons = radioButtonGroups())
-        return buttons->checkedButtonForGroup(name());
-    return nullptr;
+        return buttons->checkedButtonForGroup(name);
+
+    if (name.isEmpty())
+        return nullptr;
+
+    ASSERT(!isConnected());
+    ASSERT(!form());
+
+    // The input is not managed by a RadioButtonGroups, we'll need to traverse the tree.
+    RefPtr<HTMLInputElement> checkedRadio;
+    RadioInputType::forEachButtonInDetachedGroup(rootNode(), name, [&](auto& input) {
+        if (input.checked()) {
+            checkedRadio = &input;
+            return false;
+        }
+        return true;
+    });
+    return checkedRadio;
 }
 
 RadioButtonGroups* HTMLInputElement::radioButtonGroups() const

Modified: trunk/Source/WebCore/html/InputType.h (288733 => 288734)


--- trunk/Source/WebCore/html/InputType.h	2022-01-28 07:33:35 UTC (rev 288733)
+++ trunk/Source/WebCore/html/InputType.h	2022-01-28 07:58:57 UTC (rev 288734)
@@ -363,6 +363,7 @@
 #if ENABLE(DATALIST_ELEMENT)
     virtual bool isFocusingWithDataListDropdown() const { return false; };
 #endif
+    virtual void willUpdateCheckedness(bool /*nowChecked*/) { }
 
     // Parses the specified string for the type, and return
     // the Decimal value for the parsing result if the parsing

Modified: trunk/Source/WebCore/html/RadioInputType.cpp (288733 => 288734)


--- trunk/Source/WebCore/html/RadioInputType.cpp	2022-01-28 07:33:35 UTC (rev 288733)
+++ trunk/Source/WebCore/html/RadioInputType.cpp	2022-01-28 07:58:57 UTC (rev 288734)
@@ -46,9 +46,63 @@
 bool RadioInputType::valueMissing(const String&) const
 {
     ASSERT(element());
-    return element()->isInRequiredRadioButtonGroup() && !element()->checkedRadioButtonForGroup();
+    auto& name = element()->name();
+    if (auto* buttons = element()->radioButtonGroups())
+        return !buttons->checkedButtonForGroup(name) && buttons->isInRequiredGroup(*element());
+
+    if (name.isEmpty())
+        return false;
+
+    ASSERT(!element()->isConnected());
+    ASSERT(!element()->form());
+
+    bool isRequired = false;
+    bool foundCheckedRadio = false;
+    forEachButtonInDetachedGroup(element()->rootNode(), name, [&](auto& input) {
+        if (input.checked()) {
+            foundCheckedRadio = true;
+            return false;
+        }
+        if (input.isRequired())
+            isRequired = true;
+        return true;
+    });
+    return isRequired && !foundCheckedRadio;
 }
 
+void RadioInputType::forEachButtonInDetachedGroup(ContainerNode& rootNode, const String& groupName, const Function<bool(HTMLInputElement&)>& apply)
+{
+    ASSERT(!groupName.isEmpty());
+
+    for (auto* descendant = Traversal<HTMLElement>::inclusiveFirstWithin(rootNode); descendant;) {
+        if (is<HTMLFormElement>(*descendant)) {
+            // No need to consider the descendants of a <form> since they will have a form owner and we're only
+            // interested in <input> elements without a form owner.
+            descendant = Traversal<HTMLElement>::nextSkippingChildren(*descendant, &rootNode);
+            continue;
+        }
+        auto* input = dynamicDowncast<HTMLInputElement>(*descendant);
+        if (input && input->isRadioButton() && !input->form() && input->name() == groupName) {
+            bool shouldContinue = apply(*input);
+            if (!shouldContinue)
+                return;
+        }
+        descendant = Traversal<HTMLElement>::next(*descendant, &rootNode);
+    }
+}
+
+void RadioInputType::willUpdateCheckedness(bool nowChecked)
+{
+    if (!nowChecked)
+        return;
+    if (element()->radioButtonGroups()) {
+        // Buttons in RadioButtonGroups are handled in HTMLInputElement::setChecked().
+        return;
+    }
+    if (auto input = element()->checkedRadioButtonForGroup())
+        input->setChecked(false);
+}
+
 String RadioInputType::valueMissingText() const
 {
     return validationMessageValueMissingForRadioText();

Modified: trunk/Source/WebCore/html/RadioInputType.h (288733 => 288734)


--- trunk/Source/WebCore/html/RadioInputType.h	2022-01-28 07:33:35 UTC (rev 288733)
+++ trunk/Source/WebCore/html/RadioInputType.h	2022-01-28 07:58:57 UTC (rev 288734)
@@ -40,6 +40,8 @@
 public:
     explicit RadioInputType(HTMLInputElement& element) : BaseCheckableInputType(Type::Radio, element) { }
 
+    static void forEachButtonInDetachedGroup(ContainerNode& rootName, const String& groupName, const Function<bool(HTMLInputElement&)>&);
+
 private:
     const AtomString& formControlType() const final;
     bool valueMissing(const String&) const final;
@@ -52,6 +54,7 @@
     void willDispatchClick(InputElementClickState&) final;
     void didDispatchClick(Event&, const InputElementClickState&) final;
     bool matchesIndeterminatePseudoClass() const final;
+    void willUpdateCheckedness(bool nowChecked) final;
 };
 
 } // namespace WebCore
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to