Changeset 286855 in webkit
- Timestamp:
- Dec 10, 2021 9:16:51 AM (7 months ago)
- Location:
- trunk
- Files:
-
- 23 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/fast/forms/radio/ValidityState-valueMissing-radio-expected.txt (modified) (1 diff)
-
LayoutTests/fast/forms/radio/ValidityState-valueMissing-radio.html (modified) (2 diffs)
-
LayoutTests/fast/forms/radio/radio-live-validation-style-expected.txt (modified) (1 diff)
-
LayoutTests/fast/forms/radio/radio-live-validation-style.html (modified) (1 diff)
-
LayoutTests/imported/w3c/ChangeLog (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valid-expected.txt (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valueMissing-expected.txt (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/radio-expected.txt (modified) (1 diff)
-
LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valid-expected.txt (modified) (1 diff)
-
LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valueMissing-expected.txt (modified) (1 diff)
-
LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valid-expected.txt (modified) (1 diff)
-
LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valueMissing-expected.txt (modified) (1 diff)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/dom/ContainerNode.h (modified) (1 diff)
-
Source/WebCore/dom/ElementTraversal.h (modified) (2 diffs)
-
Source/WebCore/dom/TypedElementDescendantIterator.h (modified) (3 diffs)
-
Source/WebCore/html/HTMLFormControlElement.cpp (modified) (1 diff)
-
Source/WebCore/html/HTMLFormControlElement.h (modified) (1 diff)
-
Source/WebCore/html/HTMLInputElement.cpp (modified) (5 diffs)
-
Source/WebCore/html/InputType.h (modified) (1 diff)
-
Source/WebCore/html/RadioInputType.cpp (modified) (2 diffs)
-
Source/WebCore/html/RadioInputType.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r286854 r286855 1 2021-12-10 Chris Dumez <cdumez@apple.com> 2 3 Radio buttons with no form owner are not grouped 4 https://bugs.webkit.org/show_bug.cgi?id=220502 5 <rdar://problem/73300895> 6 7 Reviewed by Darin Adler. 8 9 * fast/forms/radio/ValidityState-valueMissing-radio-expected.txt: 10 * fast/forms/radio/ValidityState-valueMissing-radio.html: 11 * fast/forms/radio/radio-live-validation-style-expected.txt: 12 * fast/forms/radio/radio-live-validation-style.html: 13 Update existing tests to reflect behavior change. I have verified that our behavior on those tests 14 is aligned with both Firefox and Chrome. 15 16 * platform/mac-wk2/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valid-expected.txt: 17 * platform/mac-wk2/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valueMissing-expected.txt: 18 Rebaseline WPT tests now that more checks are passing. 19 1 20 2021-12-10 Youenn Fablet <youenn@apple.com> 2 21 -
trunk/LayoutTests/fast/forms/radio/ValidityState-valueMissing-radio-expected.txt
r108612 r286855 41 41 42 42 Not in a radio button group 43 PASS requiredButton.validity.valueMissing is false43 PASS requiredButton.validity.valueMissing is true 44 44 PASS requiredButton.validity.valueMissing is true 45 45 PASS button.validity.valueMissing is true 46 46 PASS button.validity.valueMissing is false 47 PASS requiredButton.validity.valueMissing is false47 PASS requiredButton.validity.valueMissing is true 48 48 PASS successfullyParsed is true 49 49 -
trunk/LayoutTests/fast/forms/radio/ValidityState-valueMissing-radio.html
r155268 r286855 72 72 requiredButton.name = 'victim'; 73 73 requiredButton.required = true; 74 shouldBe False('requiredButton.validity.valueMissing');74 shouldBeTrue('requiredButton.validity.valueMissing'); 75 75 76 76 parent.innerHTML = '<input name=victim type=radio required><input name=victim type=radio>'; … … 82 82 shouldBeFalse('button.validity.valueMissing'); 83 83 parent.removeChild(requiredButton); 84 shouldBe False('requiredButton.validity.valueMissing');84 shouldBeTrue('requiredButton.validity.valueMissing'); 85 85 86 86 </script> -
trunk/LayoutTests/fast/forms/radio/radio-live-validation-style-expected.txt
r174336 r286855 8 8 PASS parent.removeChild($("radio2")); backgroundOf($("radio1")) is invalidColor 9 9 PASS $("radio1").remove(); radio2.matches(":valid") is false 10 PASS radio2.remove(); radio2.matches(":valid") is true10 PASS radio2.remove(); radio2.matches(":valid") is false 11 11 12 12 Removing a checked radio button from a required radio button group by name attribute change: -
trunk/LayoutTests/fast/forms/radio/radio-live-validation-style.html
r174336 r286855 36 36 var radio2 = $('radio2'); 37 37 shouldBeFalse('$("radio1").remove(); radio2.matches(":valid")'); 38 shouldBe True('radio2.remove(); radio2.matches(":valid")');38 shouldBeFalse('radio2.remove(); radio2.matches(":valid")'); 39 39 debug(''); 40 40 -
trunk/LayoutTests/imported/w3c/ChangeLog
r286853 r286855 1 2021-12-10 Chris Dumez <cdumez@apple.com> 2 3 Radio buttons with no form owner are not grouped 4 https://bugs.webkit.org/show_bug.cgi?id=220502 5 <rdar://problem/73300895> 6 7 Reviewed by Darin Adler. 8 9 Rebaseline WPT tests now that more checks are passing. 10 11 * web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valid-expected.txt: 12 * web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valueMissing-expected.txt: 13 * web-platform-tests/html/semantics/forms/the-input-element/radio-expected.txt: 14 1 15 2021-12-10 Patrick Griffis <pgriffis@igalia.com> 2 16 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valid-expected.txt
r286482 r286855 24 24 PASS [INPUT in NUMBER status] validity.valid must be false if validity.valueMissing is true 25 25 PASS [INPUT in CHECKBOX status] validity.valid must be false if validity.valueMissing is true 26 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 gottrue26 PASS [INPUT in RADIO status] validity.valid must be false if validity.valueMissing is true 27 27 PASS [INPUT in FILE status] validity.valid must be false if validity.valueMissing is true 28 28 PASS [select] validity.valid must be false if validity.valueMissing is true -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valueMissing-expected.txt
r286482 r286855 39 39 PASS [INPUT in RADIO status] The required attribute is not set 40 40 PASS [INPUT in RADIO status] The checked attribute is true 41 FAIL [INPUT in RADIO status] The checked attribute is false assert_true: The validity.valueMissing should be true. expected true gotfalse41 PASS [INPUT in RADIO status] The checked attribute is false 42 42 PASS [INPUT in RADIO status] The checked attribute is false and the name attribute is empty 43 43 PASS [INPUT in FILE status] The required attribute is not set -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/radio-expected.txt
r279427 r286855 8 8 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 9 9 PASS moving radio input element out of or into a form should still work as expected 10 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 11 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 10 PASS Radio buttons in an orphan tree should make a group 11 PASS Radio buttons in different groups (because they have different form owners or no form owner) do not affect each other's checkedness 12 12 PASS Radio buttons in different groups (because they are not in the same tree) do not affect each other's checkedness 13 13 PASS Radio buttons in different groups (because they have different name attribute values, or no name attribute) do not affect each other's checkedness -
trunk/LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valid-expected.txt
r286482 r286855 39 39 PASS [INPUT in NUMBER status] validity.valid must be false if validity.valueMissing is true 40 40 PASS [INPUT in CHECKBOX status] validity.valid must be false if validity.valueMissing is true 41 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 gottrue41 PASS [INPUT in RADIO status] validity.valid must be false if validity.valueMissing is true 42 42 PASS [INPUT in FILE status] validity.valid must be false if validity.valueMissing is true 43 43 PASS [select] validity.valid must be false if validity.valueMissing is true -
trunk/LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valueMissing-expected.txt
r286482 r286855 85 85 PASS [INPUT in RADIO status] The required attribute is not set 86 86 PASS [INPUT in RADIO status] The checked attribute is true 87 FAIL [INPUT in RADIO status] The checked attribute is false assert_true: The validity.valueMissing should be true. expected true gotfalse87 PASS [INPUT in RADIO status] The checked attribute is false 88 88 PASS [INPUT in RADIO status] The checked attribute is false and the name attribute is empty 89 89 PASS [INPUT in FILE status] The required attribute is not set -
trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valid-expected.txt
r286482 r286855 39 39 PASS [INPUT in NUMBER status] validity.valid must be false if validity.valueMissing is true 40 40 PASS [INPUT in CHECKBOX status] validity.valid must be false if validity.valueMissing is true 41 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 gottrue41 PASS [INPUT in RADIO status] validity.valid must be false if validity.valueMissing is true 42 42 PASS [INPUT in FILE status] validity.valid must be false if validity.valueMissing is true 43 43 PASS [select] validity.valid must be false if validity.valueMissing is true -
trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valueMissing-expected.txt
r286482 r286855 85 85 PASS [INPUT in RADIO status] The required attribute is not set 86 86 PASS [INPUT in RADIO status] The checked attribute is true 87 FAIL [INPUT in RADIO status] The checked attribute is false assert_true: The validity.valueMissing should be true. expected true gotfalse87 PASS [INPUT in RADIO status] The checked attribute is false 88 88 PASS [INPUT in RADIO status] The checked attribute is false and the name attribute is empty 89 89 PASS [INPUT in FILE status] The required attribute is not set -
trunk/Source/WebCore/ChangeLog
r286853 r286855 1 2021-12-10 Chris Dumez <cdumez@apple.com> 2 3 Radio buttons with no form owner are not grouped 4 https://bugs.webkit.org/show_bug.cgi?id=220502 5 <rdar://problem/73300895> 6 7 Reviewed by Darin Adler. 8 9 Per the HTML specification and to match the behavior of both Gecko and Blink, 10 radio buttons should still be grouped, even if they are disconnected and not 11 owned by a form. 12 13 This patch aligns our behavior with Gecko and Blink and is based on the following 14 Blink commit: 15 - https://chromium-review.googlesource.com/c/chromium/src/+/1988087 16 17 No new tests, rebaselined existing tests. 18 19 * dom/ContainerNode.h: 20 (WebCore::ContainerNode::rootNode const): 21 * dom/ElementTraversal.h: 22 (WebCore::Traversal<ElementType>::inclusiveFirstWithin): 23 * html/HTMLInputElement.cpp: 24 (WebCore::HTMLInputElement::setChecked): 25 (WebCore::HTMLInputElement::didChangeForm): 26 (WebCore::HTMLInputElement::insertedIntoAncestor): 27 (WebCore::HTMLInputElement::removedFromAncestor): 28 (WebCore::HTMLInputElement::checkedRadioButtonForGroup const): 29 * html/InputType.h: 30 (WebCore::InputType::willUpdateCheckedness): 31 * html/RadioInputType.cpp: 32 (WebCore::RadioInputType::valueMissing const): 33 (WebCore::RadioInputType::willUpdateCheckedness): 34 * html/RadioInputType.h: 35 1 36 2021-12-10 Patrick Griffis <pgriffis@igalia.com> 2 37 -
trunk/Source/WebCore/dom/ContainerNode.h
r286091 r286855 60 60 void stringReplaceAll(const String&); 61 61 void replaceAll(Node*); 62 63 ContainerNode& rootNode() const { return downcast<ContainerNode>(Node::rootNode()); } 62 64 63 65 // These methods are only used during parsing. -
trunk/Source/WebCore/dom/ElementTraversal.h
r208179 r286855 44 44 static ElementType* lastWithin(const Node&); 45 45 static ElementType* lastWithin(const ContainerNode&); 46 static ElementType* inclusiveFirstWithin(Node&); 47 static ElementType* inclusiveFirstWithin(ContainerNode&); 48 static ElementType* inclusiveLastWithin(Node&); 49 static ElementType* inclusiveLastWithin(ContainerNode&); 46 50 47 51 // Pre-order traversal skipping non-ElementType nodes. … … 236 240 237 241 template <typename ElementType> 242 inline ElementType* Traversal<ElementType>::inclusiveFirstWithin(ContainerNode& current) 243 { 244 if (is<ElementType>(current)) 245 return &downcast<ElementType>(current); 246 return firstWithin(current); 247 } 248 249 template <typename ElementType> 250 inline ElementType* Traversal<ElementType>::inclusiveFirstWithin(Node& current) 251 { 252 if (is<ElementType>(current)) 253 return &downcast<ElementType>(current); 254 return firstWithin(current); 255 } 256 257 template <typename ElementType> 258 inline ElementType* Traversal<ElementType>::inclusiveLastWithin(ContainerNode& current) 259 { 260 if (is<ElementType>(current)) 261 return &downcast<ElementType>(current); 262 return lastWithin(current); 263 } 264 265 template <typename ElementType> 266 inline ElementType* Traversal<ElementType>::inclusiveLastWithin(Node& current) 267 { 268 if (is<ElementType>(current)) 269 return &downcast<ElementType>(current); 270 return lastWithin(current); 271 } 272 273 template <typename ElementType> 238 274 inline ElementType* Traversal<ElementType>::firstWithin(const ContainerNode& current) { return firstWithinTemplate(current); } 239 275 template <typename ElementType> -
trunk/Source/WebCore/dom/TypedElementDescendantIterator.h
r257192 r286855 69 69 }; 70 70 71 template<typename ElementType> class InclusiveElementDescendantRange { 72 public: 73 InclusiveElementDescendantRange(const ContainerNode& root); 74 ElementDescendantIterator<ElementType> begin() const; 75 static constexpr std::nullptr_t end() { return nullptr; } 76 ElementDescendantIterator<ElementType> beginAt(ElementType&) const; 77 ElementDescendantIterator<ElementType> from(Element&) const; 78 79 ElementType* first() const; 80 ElementType* last() const; 81 82 private: 83 const ContainerNode& m_root; 84 }; 85 71 86 template<typename ElementType> class DoubleElementDescendantRange { 72 87 public: … … 172 187 } 173 188 189 // InclusiveElementDescendantRange 190 191 template<typename ElementType> InclusiveElementDescendantRange<ElementType>::InclusiveElementDescendantRange(const ContainerNode& root) 192 : m_root(root) 193 { 194 } 195 196 template<typename ElementType> ElementDescendantIterator<ElementType> InclusiveElementDescendantRange<ElementType>::begin() const 197 { 198 return ElementDescendantIterator<ElementType>(m_root, Traversal<ElementType>::inclusiveFirstWithin(const_cast<ContainerNode&>(m_root))); 199 } 200 201 template<typename ElementType> ElementDescendantIterator<ElementType> InclusiveElementDescendantRange<ElementType>::beginAt(ElementType& descendant) const 202 { 203 ASSERT(&m_root == &descendant || descendant.isDescendantOf(m_root)); 204 return ElementDescendantIterator<ElementType>(m_root, &descendant); 205 } 206 207 template<typename ElementType> ElementDescendantIterator<ElementType> InclusiveElementDescendantRange<ElementType>::from(Element& descendant) const 208 { 209 ASSERT(&m_root == &descendant || descendant.isDescendantOf(m_root)); 210 if (is<ElementType>(descendant)) 211 return ElementDescendantIterator<ElementType>(m_root, downcast<ElementType>(&descendant)); 212 ElementType* next = Traversal<ElementType>::next(descendant, &m_root); 213 return ElementDescendantIterator<ElementType>(m_root, next); 214 } 215 216 template<typename ElementType> ElementType* InclusiveElementDescendantRange<ElementType>::first() const 217 { 218 return Traversal<ElementType>::inclusiveFirstWithin(m_root); 219 } 220 221 template<typename ElementType> ElementType* InclusiveElementDescendantRange<ElementType>::last() const 222 { 223 return Traversal<ElementType>::inclusiveLastWithin(m_root); 224 } 225 174 226 // DoubleElementDescendantRange 175 227 … … 252 304 } 253 305 306 template<typename ElementType> InclusiveElementDescendantRange<ElementType> inclusiveDescendantsOfType(ContainerNode& root) 307 { 308 return InclusiveElementDescendantRange<ElementType>(root); 309 } 310 254 311 template<typename ElementType> ElementDescendantRange<const ElementType> descendantsOfType(const ContainerNode& root) 255 312 { -
trunk/Source/WebCore/html/HTMLFormControlElement.cpp
r285575 r286855 302 302 } 303 303 304 bool HTMLFormControlElement::isRequired() const305 {306 return m_isRequired;307 }308 309 304 void HTMLFormControlElement::didRecalcStyle(Style::Change) 310 305 { -
trunk/Source/WebCore/html/HTMLFormControlElement.h
r286447 r286855 77 77 bool isEnumeratable() const override { return false; } 78 78 79 bool isRequired() const ;79 bool isRequired() const { return m_isRequired; } 80 80 81 81 const AtomString& type() const { return formControlType(); } -
trunk/Source/WebCore/html/HTMLInputElement.cpp
r286560 r286855 69 69 #include "StyleGeneratedImage.h" 70 70 #include "TextControlInnerElements.h" 71 #include "TypedElementDescendantIterator.h" 71 72 #include <wtf/IsoMallocInlines.h> 72 73 #include <wtf/Language.h> … … 980 981 return; 981 982 983 m_inputType->willUpdateCheckedness(nowChecked); 984 982 985 m_dirtyCheckednessFlag = true; 983 986 m_isChecked = nowChecked; … … 1577 1580 void HTMLInputElement::didChangeForm() 1578 1581 { 1582 addToRadioButtonGroup(); 1579 1583 HTMLTextFormControlElement::didChangeForm(); 1580 addToRadioButtonGroup();1581 1584 } 1582 1585 1583 1586 Node::InsertedIntoAncestorResult HTMLInputElement::insertedIntoAncestor(InsertionType insertionType, ContainerNode& parentOfInsertedTree) 1584 1587 { 1588 if (isRadioButton()) 1589 updateValidity(); 1585 1590 HTMLTextFormControlElement::insertedIntoAncestor(insertionType, parentOfInsertedTree); 1586 1591 #if ENABLE(DATALIST_ELEMENT) … … 1609 1614 HTMLTextFormControlElement::removedFromAncestor(removalType, oldParentOfRemovedTree); 1610 1615 ASSERT(!isConnected()); 1616 if (removalType.disconnectedFromDocument && !form() && isRadioButton()) 1617 updateValidity(); 1611 1618 #if ENABLE(DATALIST_ELEMENT) 1612 1619 resetListAttributeTargetObserver(); … … 1957 1964 RefPtr<HTMLInputElement> HTMLInputElement::checkedRadioButtonForGroup() const 1958 1965 { 1966 if (checked()) 1967 return const_cast<HTMLInputElement*>(this); 1968 1969 auto& name = this->name(); 1959 1970 if (RadioButtonGroups* buttons = radioButtonGroups()) 1960 return buttons->checkedButtonForGroup(name()); 1971 return buttons->checkedButtonForGroup(name); 1972 1973 if (name.isEmpty()) 1974 return nullptr; 1975 1976 // The input is not managed by a RadioButtonGroups, we'll need to traverse the tree. 1977 for (auto& descendant : descendantsOfType<HTMLInputElement>(rootNode())) { 1978 if (descendant.checked() && descendant.isRadioButton() && !descendant.form() && name == descendant.name()) 1979 return &descendant; 1980 } 1961 1981 return nullptr; 1962 1982 } -
trunk/Source/WebCore/html/InputType.h
r286560 r286855 364 364 virtual bool isFocusingWithDataListDropdown() const { return false; }; 365 365 #endif 366 virtual void willUpdateCheckedness(bool /*nowChecked*/) { } 366 367 367 368 // Parses the specified string for the type, and return -
trunk/Source/WebCore/html/RadioInputType.cpp
r272097 r286855 33 33 #include "NodeTraversal.h" 34 34 #include "SpatialNavigation.h" 35 #include "TypedElementDescendantIterator.h" 35 36 36 37 namespace WebCore { … … 46 47 { 47 48 ASSERT(element()); 48 return element()->isInRequiredRadioButtonGroup() && !element()->checkedRadioButtonForGroup(); 49 auto& name = element()->name(); 50 if (auto* buttons = element()->radioButtonGroups()) 51 return !buttons->checkedButtonForGroup(name) && buttons->isInRequiredGroup(*element()); 52 53 if (name.isEmpty()) 54 return false; 55 56 bool isRequired = false; 57 for (auto& input : inclusiveDescendantsOfType<HTMLInputElement>(element()->rootNode())) { 58 if (!input.isRadioButton() || input.form() || input.name() != name) 59 continue; 60 if (input.checked()) 61 return false; 62 if (input.isRequired()) 63 isRequired = true; 64 } 65 return isRequired; 66 } 67 68 void RadioInputType::willUpdateCheckedness(bool nowChecked) 69 { 70 if (!nowChecked) 71 return; 72 if (element()->radioButtonGroups()) { 73 // Buttons in RadioButtonGroups are handled in HTMLInputElement::setChecked(). 74 return; 75 } 76 if (auto input = element()->checkedRadioButtonForGroup()) 77 input->setChecked(false); 49 78 } 50 79 -
trunk/Source/WebCore/html/RadioInputType.h
r272097 r286855 53 53 void didDispatchClick(Event&, const InputElementClickState&) final; 54 54 bool matchesIndeterminatePseudoClass() const final; 55 void willUpdateCheckedness(bool nowChecked) final; 55 56 }; 56 57
Note: See TracChangeset
for help on using the changeset viewer.