Changeset 202197 in webkit
- Timestamp:
- Jun 17, 2016 10:53:28 PM (8 years ago)
- Location:
- trunk
- Files:
-
- 8 added
- 1 deleted
- 21 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r202196 r202197 1 2016-06-17 Benjamin Poulain <benjamin@webkit.org> 2 3 :indeterminate pseudo-class should match radios whose group has no checked radio 4 https://bugs.webkit.org/show_bug.cgi?id=156270 5 6 Reviewed by Simon Fraser. 7 8 There are two important aspect to cover for this change: 9 1) The style is updated correctly when a Button Group composition change. 10 2) When the checkness changes for a Button Group, all its elements 11 are invalidated to match :indeterminate. 12 13 * fast/forms/radio/indeterminate-radio.html: 14 This test was verifying that the property "indeterminate" of the input element 15 is not reflected to the style through :indeterminate. 16 I updated the test to still verify that except that we now match :indeterminate 17 before changing the property. 18 19 * fast/css/pseudo-indeterminate-radio-buttons-basics-expected.html: Added. 20 * fast/css/pseudo-indeterminate-radio-buttons-basics.html: Added. 21 22 * fast/css/pseudo-indeterminate-with-radio-buttons-style-invalidation-expected.txt: Added. 23 * fast/css/pseudo-indeterminate-with-radio-buttons-style-invalidation.html: Added. 24 Verify that we don't invalidate everything when the checked button changes. 25 We only need to invalidate everything if the checked state of the whole group changes. 26 27 * fast/selectors/detached-radio-button-checked-and-indeterminate-states-expected.txt: Added. 28 * fast/selectors/detached-radio-button-checked-and-indeterminate-states.html: Added. 29 * fast/selectors/pseudo-indeterminate-with-radio-buttons-style-update-expected.txt: Added. 30 * fast/selectors/pseudo-indeterminate-with-radio-buttons-style-update.html: Added. 31 1 32 2016-06-17 Commit Queue <commit-queue@webkit.org> 2 33 -
trunk/LayoutTests/fast/forms/radio/indeterminate-radio.html
r121008 r202197 28 28 try 29 29 { 30 31 document.getElementsByTagName("input")[0].indeterminate = true;32 33 30 function ArrayContains(array, value, ci) 34 31 { … … 47 44 return false; 48 45 } 46 49 47 var target = document.getElementById("test"); 50 48 var val = getComputedStyle(target, null).getPropertyValue("color"); 51 var aExpectedValues = new Array("green", "#008000", "rgb(0, 128, 0)"); 49 var aExpectedValues = new Array("red", "#FF0000", "rgb(255, 0, 0)"); 50 let wasIndeterminate = ArrayContains(aExpectedValues, val, true); 52 51 53 if (ArrayContains(aExpectedValues, val, true)) 52 document.getElementsByTagName("input")[0].indeterminate = true; 53 54 if (wasIndeterminate && ArrayContains(aExpectedValues, val, true)) 54 55 { 55 56 -
trunk/LayoutTests/imported/w3c/ChangeLog
r202162 r202197 1 2016-06-17 Benjamin Poulain <benjamin@webkit.org> 2 3 :indeterminate pseudo-class should match radios whose group has no checked radio 4 https://bugs.webkit.org/show_bug.cgi?id=156270 5 6 Reviewed by Simon Fraser. 7 8 * web-platform-tests/html/semantics/selectors/pseudo-classes/indeterminate-expected.txt: 9 One more pass on official tests :) 10 1 11 2016-06-17 Youenn Fablet <youenn.fablet@crf.canon.fr> 2 12 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/selectors/pseudo-classes/indeterminate-expected.txt
r189476 r202197 1 1 2 2 3 FAIL ':progress' matches <input>s radio buttons whose radio button group contains no checked input and <progress> elements without value attribute assert_array_equals: lengths differ, expected 5 got 1 4 FAIL dynamically check a radio input in a radio button group assert_array_equals: lengths differ, expected 3 got 1 3 PASS ':progress' matches <input>s radio buttons whose radio button group contains no checked input and <progress> elements without value attribute 4 PASS dynamically check a radio input in a radio button group 5 5 FAIL click on radio4 which is in the indeterminate state assert_array_equals: lengths differ, expected 2 got 1 6 6 PASS adding a value to progress1 should put it in a determinate state -
trunk/Source/WebCore/ChangeLog
r202196 r202197 1 2016-06-17 Benjamin Poulain <benjamin@webkit.org> 2 3 :indeterminate pseudo-class should match radios whose group has no checked radio 4 https://bugs.webkit.org/show_bug.cgi?id=156270 5 6 Reviewed by Simon Fraser. 7 8 The pseudo-class ":indeterminate" is supposed to match radio buttons 9 for which the entire group has no checked button. 10 Spec: https://html.spec.whatwg.org/#pseudo-classes:selector-indeterminate 11 12 The change is straightforward with one non-obvious choice: 13 I added matchesIndeterminatePseudoClass() in addition to shouldAppearIndeterminate(). 14 15 The reason is shouldAppearIndeterminate() is used for styling and AX of elements 16 with an indeterminate states (check boxes and progress element). There is no such 17 UI for radio boxes. 18 I could have extended shouldAppearIndeterminate() to radio box 19 then filter out this case in RenderTheme. The problem is doing that would also requires 20 changes to the repaint logic to match :indeterminate. It seemed overkill to me to 21 change repaint() for a case that is never used in practice. 22 23 Tests: fast/css/pseudo-indeterminate-radio-buttons-basics.html 24 fast/css/pseudo-indeterminate-with-radio-buttons-style-invalidation.html 25 fast/selectors/detached-radio-button-checked-and-indeterminate-states.html 26 fast/selectors/pseudo-indeterminate-with-radio-buttons-style-update.html 27 28 * css/SelectorCheckerTestFunctions.h: 29 (WebCore::shouldAppearIndeterminate): 30 * dom/Element.cpp: 31 (WebCore::Element::matchesIndeterminatePseudoClass): 32 * dom/Element.h: 33 * dom/RadioButtonGroups.cpp: 34 (WebCore::RadioButtonGroup::setCheckedButton): 35 (WebCore::RadioButtonGroup::updateCheckedState): 36 (WebCore::RadioButtonGroup::remove): 37 (WebCore::RadioButtonGroup::setNeedsStyleRecalcForAllButtons): 38 (WebCore::RadioButtonGroups::hasCheckedButton): 39 * dom/RadioButtonGroups.h: 40 * html/CheckboxInputType.cpp: 41 (WebCore::CheckboxInputType::matchesIndeterminatePseudoClass): 42 (WebCore::CheckboxInputType::shouldAppearIndeterminate): 43 (WebCore::CheckboxInputType::supportsIndeterminateAppearance): Deleted. 44 * html/CheckboxInputType.h: 45 * html/HTMLInputElement.cpp: 46 (WebCore::HTMLInputElement::setChecked): 47 (WebCore::HTMLInputElement::matchesIndeterminatePseudoClass): 48 (WebCore::HTMLInputElement::shouldAppearIndeterminate): 49 (WebCore::HTMLInputElement::radioButtonGroups): 50 * html/HTMLInputElement.h: 51 * html/InputType.cpp: 52 (WebCore::InputType::matchesIndeterminatePseudoClass): 53 (WebCore::InputType::shouldAppearIndeterminate): 54 (WebCore::InputType::supportsIndeterminateAppearance): Deleted. 55 * html/InputType.h: 56 * html/RadioInputType.cpp: 57 (WebCore::RadioInputType::matchesIndeterminatePseudoClass): 58 (WebCore::RadioInputType::willDispatchClick): Deleted. 59 (WebCore::RadioInputType::didDispatchClick): Deleted. 60 (WebCore::RadioInputType::supportsIndeterminateAppearance): Deleted. 61 The iOS specific code is just plain wrong. 62 It was changing the indeterminate state of the input element. 63 The spec clearly says that state is only used by checkbox: 64 https://html.spec.whatwg.org/#dom-input-indeterminate 65 66 Moreover, the style update would not change the indeterminate state 67 of other buttons in the Button Group, which is just bizarre. 68 RenderThemeIOS does not make use of any of this with the current style. 69 70 * html/RadioInputType.h: 71 * style/StyleSharingResolver.cpp: 72 (WebCore::Style::SharingResolver::canShareStyleWithElement): 73 (WebCore::Style::canShareStyleWithControl): Deleted. 74 (WebCore::Style::SharingResolver::sharingCandidateHasIdenticalStyleAffectingAttributes): Deleted. 75 Style sharing is unified behind the selector matching which is neat. 76 1 77 2016-06-17 Commit Queue <commit-queue@webkit.org> 2 78 -
trunk/Source/WebCore/css/SelectorChecker.cpp
r202091 r202197 984 984 return isChecked(element); 985 985 case CSSSelector::PseudoClassIndeterminate: 986 return shouldAppearIndeterminate(element);986 return matchesIndeterminatePseudoClass(element); 987 987 case CSSSelector::PseudoClassRoot: 988 988 if (&element == element.document().documentElement()) -
trunk/Source/WebCore/css/SelectorCheckerTestFunctions.h
r197952 r202197 1 1 /* 2 * Copyright (C) 2014-201 5Apple Inc. All rights reserved.2 * Copyright (C) 2014-2016 Apple Inc. All rights reserved. 3 3 * Copyright (C) 2014 Dhi Aurrahman <diorahman@rockybars.com> 4 4 * … … 222 222 } 223 223 224 ALWAYS_INLINE bool shouldAppearIndeterminate(const Element& element)225 { 226 return element. shouldAppearIndeterminate();224 ALWAYS_INLINE bool matchesIndeterminatePseudoClass(const Element& element) 225 { 226 return element.matchesIndeterminatePseudoClass(); 227 227 } 228 228 -
trunk/Source/WebCore/cssjit/SelectorCompiler.cpp
r202091 r202197 559 559 return FunctionType::SimpleSelectorChecker; 560 560 case CSSSelector::PseudoClassIndeterminate: 561 fragment.unoptimizedPseudoClasses.append(JSC::FunctionPtr( shouldAppearIndeterminate));561 fragment.unoptimizedPseudoClasses.append(JSC::FunctionPtr(matchesIndeterminatePseudoClass)); 562 562 return FunctionType::SimpleSelectorChecker; 563 563 case CSSSelector::PseudoClassInvalid: -
trunk/Source/WebCore/dom/Element.cpp
r202160 r202197 5 5 * (C) 2001 Dirk Mueller (mueller@kde.org) 6 6 * (C) 2007 David Smith (catfish.man@gmail.com) 7 * Copyright (C) 2004-201 5Apple Inc. All rights reserved.7 * Copyright (C) 2004-2016 Apple Inc. All rights reserved. 8 8 * (C) 2007 Eric Seidel (eric@webkit.org) 9 9 * … … 2756 2756 } 2757 2757 2758 bool Element::matchesIndeterminatePseudoClass() const 2759 { 2760 return shouldAppearIndeterminate(); 2761 } 2762 2758 2763 bool Element::matches(const String& selector, ExceptionCode& ec) 2759 2764 { -
trunk/Source/WebCore/dom/Element.h
r202091 r202197 4 4 * (C) 2001 Peter Kelly (pmk@post.com) 5 5 * (C) 2001 Dirk Mueller (mueller@kde.org) 6 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2013, 2014 Apple Inc. All rights reserved.6 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2013, 2014, 2016 Apple Inc. All rights reserved. 7 7 * 8 8 * This library is free software; you can redistribute it and/or … … 387 387 388 388 virtual bool matchesReadWritePseudoClass() const; 389 virtual bool matchesIndeterminatePseudoClass() const; 389 390 bool matches(const String& selectors, ExceptionCode&); 390 391 Element* closest(const String& selectors, ExceptionCode&); -
trunk/Source/WebCore/dom/RadioButtonGroups.cpp
r201659 r202197 1 1 /* 2 * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.2 * Copyright (C) 2007, 2008, 2009, 2016 Apple Inc. All rights reserved. 3 3 * 4 4 * This library is free software; you can redistribute it and/or … … 43 43 44 44 private: 45 void setNeedsStyleRecalcForAllButtons(); 45 46 void updateValidityForAllButtons(); 46 47 bool isValid() const; 48 void changeCheckedButton(HTMLInputElement*); 47 49 void setCheckedButton(HTMLInputElement*); 48 50 … … 76 78 if (oldCheckedButton == button) 77 79 return; 80 81 bool hadCheckedButton = m_checkedButton; 82 bool willHaveCheckedButton = button; 83 if (hadCheckedButton != willHaveCheckedButton) 84 setNeedsStyleRecalcForAllButtons(); 85 78 86 m_checkedButton = button; 79 87 if (oldCheckedButton) … … 111 119 else { 112 120 if (m_checkedButton == button) 113 m_checkedButton = nullptr;121 setCheckedButton(nullptr); 114 122 } 115 123 if (wasValid != isValid()) … … 138 146 if (it == m_members.end()) 139 147 return; 148 140 149 bool wasValid = isValid(); 141 150 m_members.remove(it); … … 144 153 --m_requiredCount; 145 154 } 146 if (m_checkedButton == button) 147 m_checkedButton = nullptr; 155 if (m_checkedButton) { 156 button->setNeedsStyleRecalc(); 157 if (m_checkedButton == button) { 158 m_checkedButton = nullptr; 159 setNeedsStyleRecalcForAllButtons(); 160 } 161 } 148 162 149 163 if (m_members.isEmpty()) { … … 159 173 } 160 174 175 void RadioButtonGroup::setNeedsStyleRecalcForAllButtons() 176 { 177 for (auto& button : m_members) { 178 ASSERT(button->isRadioButton()); 179 button->setNeedsStyleRecalc(); 180 } 181 } 182 161 183 void RadioButtonGroup::updateValidityForAllButtons() 162 184 { … … 249 271 RadioButtonGroup* group = m_nameToGroupMap->get(name.impl()); 250 272 return group ? group->checkedButton() : nullptr; 273 } 274 275 bool RadioButtonGroups::hasCheckedButton(const HTMLInputElement* element) const 276 { 277 ASSERT(element->isRadioButton()); 278 const AtomicString& name = element->name(); 279 if (name.isEmpty() || !m_nameToGroupMap) 280 return element->checked(); 281 282 const RadioButtonGroup* group = m_nameToGroupMap->get(name.impl()); 283 return group->checkedButton(); 251 284 } 252 285 -
trunk/Source/WebCore/dom/RadioButtonGroups.h
r201659 r202197 40 40 void removeButton(HTMLInputElement*); 41 41 HTMLInputElement* checkedButtonForGroup(const AtomicString& groupName) const; 42 bool hasCheckedButton(const HTMLInputElement*) const; 42 43 bool isInRequiredGroup(HTMLInputElement*) const; 43 44 Vector<HTMLInputElement*> groupMembers(const HTMLInputElement&) const; -
trunk/Source/WebCore/html/CheckboxInputType.cpp
r158171 r202197 93 93 } 94 94 95 bool CheckboxInputType:: supportsIndeterminateAppearance() const95 bool CheckboxInputType::matchesIndeterminatePseudoClass() const 96 96 { 97 return true; 97 return shouldAppearIndeterminate(); 98 } 99 100 bool CheckboxInputType::shouldAppearIndeterminate() const 101 { 102 return element().indeterminate(); 98 103 } 99 104 -
trunk/Source/WebCore/html/CheckboxInputType.h
r197563 r202197 48 48 void didDispatchClick(Event*, const InputElementClickState&) override; 49 49 bool isCheckbox() const override; 50 bool supportsIndeterminateAppearance() const override; 50 bool matchesIndeterminatePseudoClass() const override; 51 bool shouldAppearIndeterminate() const override; 51 52 }; 52 53 -
trunk/Source/WebCore/html/HTMLInputElement.cpp
r202159 r202197 862 862 863 863 if (RadioButtonGroups* buttons = radioButtonGroups()) 864 864 buttons->updateCheckedState(this); 865 865 if (renderer() && renderer()->style().hasAppearance()) 866 866 renderer()->theme().stateChanged(*renderer(), ControlStates::CheckedState); … … 1764 1764 } 1765 1765 1766 bool HTMLInputElement::matchesIndeterminatePseudoClass() const 1767 { 1768 // For input elements, matchesIndeterminatePseudoClass() 1769 // is not equivalent to shouldAppearIndeterminate() because of radio button. 1770 // 1771 // A group of radio button without any checked button is indeterminate 1772 // for the :indeterminate selector. On the other hand, RenderTheme 1773 // currently only supports single element being indeterminate. 1774 // Because of this, radio is indetermindate for CSS but not for render theme. 1775 return m_inputType->matchesIndeterminatePseudoClass(); 1776 } 1777 1766 1778 bool HTMLInputElement::shouldAppearIndeterminate() const 1767 1779 { 1768 return m_inputType->s upportsIndeterminateAppearance() && indeterminate();1780 return m_inputType->shouldAppearIndeterminate(); 1769 1781 } 1770 1782 … … 1802 1814 { 1803 1815 if (!isRadioButton()) 1804 return 0;1816 return nullptr; 1805 1817 if (HTMLFormElement* formElement = form()) 1806 1818 return &formElement->radioButtonGroups(); 1807 1819 if (inDocument()) 1808 1820 return &document().formController().radioButtonGroups(); 1809 return 0;1821 return nullptr; 1810 1822 } 1811 1823 -
trunk/Source/WebCore/html/HTMLInputElement.h
r201942 r202197 3 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 4 4 * (C) 2000 Dirk Mueller (mueller@kde.org) 5 * Copyright (C) 2004, 2005, 2006, 2007, 2010 Apple Inc. All rights reserved.5 * Copyright (C) 2004, 2005, 2006, 2007, 2010, 2016 Apple Inc. All rights reserved. 6 6 * Copyright (C) 2012 Samsung Electronics. All rights reserved. 7 7 * … … 163 163 // shouldAppearChecked is used by the rendering tree/CSS while checked() is used by JS to determine checked state 164 164 bool shouldAppearChecked() const; 165 bool matchesIndeterminatePseudoClass() const final; 165 166 bool shouldAppearIndeterminate() const final; 166 167 … … 275 276 HTMLInputElement* checkedRadioButtonForGroup() const; 276 277 bool isInRequiredRadioButtonGroup(); 278 // Returns null if this isn't associated with any radio button group. 279 RadioButtonGroups* radioButtonGroups() const; 277 280 278 281 // Functions for InputType classes. … … 423 426 void updateValueIfNeeded(); 424 427 425 // Returns null if this isn't associated with any radio button group.426 RadioButtonGroups* radioButtonGroups() const;427 428 void addToRadioButtonGroup(); 428 429 void removeFromRadioButtonGroup(); -
trunk/Source/WebCore/html/InputType.cpp
r202143 r202197 967 967 #endif 968 968 969 bool InputType::supportsIndeterminateAppearance() const 969 bool InputType::matchesIndeterminatePseudoClass() const 970 { 971 return false; 972 } 973 974 bool InputType::shouldAppearIndeterminate() const 970 975 { 971 976 return false; -
trunk/Source/WebCore/html/InputType.h
r200041 r202197 268 268 virtual void updateAutoFillButton(); 269 269 virtual String defaultToolTip() const; 270 virtual bool supportsIndeterminateAppearance() const; 270 virtual bool matchesIndeterminatePseudoClass() const; 271 virtual bool shouldAppearIndeterminate() const; 271 272 virtual bool supportsSelectionAPI() const; 272 273 virtual Color valueAsColor() const; -
trunk/Source/WebCore/html/RadioInputType.cpp
r195524 r202197 1 1 /* 2 * Copyright (C) 2005, 2011 Apple Inc. All rights reserved.2 * Copyright (C) 2005, 2011, 2016 Apple Inc. All rights reserved. 3 3 * Copyright (C) 2010 Google Inc. All rights reserved. 4 4 * … … 152 152 state.checkedRadioButton = element().checkedRadioButtonForGroup(); 153 153 154 #if PLATFORM(IOS)155 state.indeterminate = element().indeterminate();156 157 if (element().indeterminate())158 element().setIndeterminate(false);159 #endif160 161 154 element().setChecked(true, DispatchChangeEvent); 162 155 } … … 174 167 checkedRadioButton->setChecked(true); 175 168 } 176 177 #if PLATFORM(IOS)178 element().setIndeterminate(state.indeterminate);179 #endif180 181 169 } 182 170 … … 190 178 } 191 179 192 bool RadioInputType:: supportsIndeterminateAppearance() const180 bool RadioInputType::matchesIndeterminatePseudoClass() const 193 181 { 194 #if PLATFORM(IOS) 195 return true; 196 #else 197 return false; 198 #endif 182 const HTMLInputElement& element = this->element(); 183 if (const RadioButtonGroups* radioButtonGroups = element.radioButtonGroups()) 184 return !radioButtonGroups->hasCheckedButton(&element); 185 return !element.checked(); 199 186 } 200 187 -
trunk/Source/WebCore/html/RadioInputType.h
r197563 r202197 1 1 /* 2 2 * Copyright (C) 2010 Google Inc. All rights reserved. 3 * Copyright (C) 2016 Apple Inc. All rights reserved. 3 4 * 4 5 * Redistribution and use in source and binary forms, with or without … … 52 53 void didDispatchClick(Event*, const InputElementClickState&) override; 53 54 bool isRadioButton() const override; 54 bool supportsIndeterminateAppearance() const override;55 bool matchesIndeterminatePseudoClass() const override; 55 56 }; 56 57 -
trunk/Source/WebCore/style/StyleSharingResolver.cpp
r202091 r202197 180 180 if (thisInputElement.shouldAppearChecked() != otherInputElement.shouldAppearChecked()) 181 181 return false; 182 if (thisInputElement.shouldAppearIndeterminate() != otherInputElement.shouldAppearIndeterminate())183 return false;184 182 if (thisInputElement.isRequired() != otherInputElement.isRequired()) 185 183 return false; … … 282 280 283 281 if (element.matchesInvalidPseudoClass() != element.matchesValidPseudoClass()) 282 return false; 283 284 if (candidateElement.matchesIndeterminatePseudoClass() != element.matchesIndeterminatePseudoClass()) 284 285 return false; 285 286 … … 330 331 return false; 331 332 332 if (element.hasTagName(HTMLNames::progressTag)) {333 if (element.shouldAppearIndeterminate() != sharingCandidate.shouldAppearIndeterminate())334 return false;335 }336 337 333 return true; 338 334 }
Note: See TracChangeset
for help on using the changeset viewer.