Diff
Modified: trunk/LayoutTests/ChangeLog (202196 => 202197)
--- trunk/LayoutTests/ChangeLog 2016-06-18 03:33:19 UTC (rev 202196)
+++ trunk/LayoutTests/ChangeLog 2016-06-18 05:53:28 UTC (rev 202197)
@@ -1,3 +1,34 @@
+2016-06-17 Benjamin Poulain <benja...@webkit.org>
+
+ :indeterminate pseudo-class should match radios whose group has no checked radio
+ https://bugs.webkit.org/show_bug.cgi?id=156270
+
+ Reviewed by Simon Fraser.
+
+ There are two important aspect to cover for this change:
+ 1) The style is updated correctly when a Button Group composition change.
+ 2) When the checkness changes for a Button Group, all its elements
+ are invalidated to match :indeterminate.
+
+ * fast/forms/radio/indeterminate-radio.html:
+ This test was verifying that the property "indeterminate" of the input element
+ is not reflected to the style through :indeterminate.
+ I updated the test to still verify that except that we now match :indeterminate
+ before changing the property.
+
+ * fast/css/pseudo-indeterminate-radio-buttons-basics-expected.html: Added.
+ * fast/css/pseudo-indeterminate-radio-buttons-basics.html: Added.
+
+ * fast/css/pseudo-indeterminate-with-radio-buttons-style-invalidation-expected.txt: Added.
+ * fast/css/pseudo-indeterminate-with-radio-buttons-style-invalidation.html: Added.
+ Verify that we don't invalidate everything when the checked button changes.
+ We only need to invalidate everything if the checked state of the whole group changes.
+
+ * fast/selectors/detached-radio-button-checked-and-indeterminate-states-expected.txt: Added.
+ * fast/selectors/detached-radio-button-checked-and-indeterminate-states.html: Added.
+ * fast/selectors/pseudo-indeterminate-with-radio-buttons-style-update-expected.txt: Added.
+ * fast/selectors/pseudo-indeterminate-with-radio-buttons-style-update.html: Added.
+
2016-06-17 Commit Queue <commit-qu...@webkit.org>
Unreviewed, rolling out r202152.
Added: trunk/LayoutTests/fast/css/pseudo-indeterminate-radio-buttons-basics-expected.html (0 => 202197)
--- trunk/LayoutTests/fast/css/pseudo-indeterminate-radio-buttons-basics-expected.html (rev 0)
+++ trunk/LayoutTests/fast/css/pseudo-indeterminate-radio-buttons-basics-expected.html 2016-06-18 05:53:28 UTC (rev 202197)
@@ -0,0 +1,206 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<style>
+ input {
+ background-color: blue;
+ width: 15px;
+ height: 15px;
+ -webkit-appearance: none;
+ }
+ .checked {
+ border: 2px solid red;
+ }
+ .indeterminate {
+ background-color: green;
+ }
+ .disabled {
+ border-left: 3px solid orange;
+ }
+</style>
+</head>
+<body>
+ <div>
+ <input type="radio" class="indeterminate">
+ <input type="radio" class="indeterminate">
+ <input type="radio" name="group1" class="indeterminate">
+ <input type="radio" name="group1" class="indeterminate">
+ <input type="radio" name="group2" class="indeterminate">
+ <span><input type="radio" name="group2" class="indeterminate"></span>
+ <input type="radio" name="group3">
+ <input type="radio" name="group3" checked>
+ <input type="radio" name="group4">
+ <span><input type="radio" name="group4" checked></span>
+ <input type="radio" disabled class="indeterminate disabled">
+ <input type="radio" name="group5" disabled class="indeterminate disabled">
+ <input type="radio" name="group5" disabled class="indeterminate disabled">
+ <input type="radio" name="group6" disabled class="indeterminate disabled">
+ <span><input type="radio" name="group6" disabled class="indeterminate disabled"></span>
+ <input type="radio" name="group7" disabled class="disabled">
+ <input type="radio" name="group7" checked disabled class="disabled">
+ <input type="radio" name="group8" disabled class="disabled">
+ <span><input type="radio" name="group8" checked disabled class="disabled"></span>
+ <input type="radio" readonly class="indeterminate">
+ <input type="radio" name="group9" readonly class="indeterminate">
+ <input type="radio" name="group9" readonly class="indeterminate">
+ <input type="radio" name="group10" readonly class="indeterminate">
+ <span><input type="radio" name="group10" readonly class="indeterminate"></span>
+ <input type="radio" name="group11" readonly>
+ <input type="radio" name="group11" checked readonly>
+ <input type="radio" name="group12" readonly>
+ <span><input type="radio" name="group12" checked readonly></span>
+ </div>
+ <form>
+ <input type="radio" class="indeterminate">
+ <input type="radio" class="indeterminate">
+ <input type="radio" name="group1" class="indeterminate">
+ <input type="radio" name="group1" class="indeterminate">
+ <input type="radio" name="group2" class="indeterminate">
+ <span><input type="radio" name="group2" class="indeterminate"></span>
+ <input type="radio" name="group3">
+ <input type="radio" name="group3" checked class="checked">
+ <input type="radio" name="group4">
+ <span><input type="radio" name="group4" checked class="checked"></span>
+ <input type="radio" disabled class="indeterminate disabled">
+ <input type="radio" name="group5" disabled class="indeterminate disabled">
+ <input type="radio" name="group5" disabled class="indeterminate disabled">
+ <input type="radio" name="group6" disabled class="indeterminate disabled">
+ <span><input type="radio" name="group6" disabled class="indeterminate disabled"></span>
+ <input type="radio" name="group7" disabled class="disabled">
+ <input type="radio" name="group7" checked disabled class="checked disabled">
+ <input type="radio" name="group8" disabled class="disabled">
+ <span><input type="radio" name="group8" checked disabled class="checked disabled"></span>
+ <input type="radio" readonly class="indeterminate">
+ <input type="radio" name="group9" readonly class="indeterminate">
+ <input type="radio" name="group9" readonly class="indeterminate">
+ <input type="radio" name="group10" readonly class="indeterminate">
+ <span><input type="radio" name="group10" readonly class="indeterminate"></span>
+ <input type="radio" name="group11" readonly>
+ <input type="radio" name="group11" checked readonly class="checked">
+ <input type="radio" name="group12" readonly>
+ <span><input type="radio" name="group12" checked readonly class="checked"></span>
+ </form>
+ <form disabled>
+ <input type="radio" class="indeterminate">
+ <input type="radio" class="indeterminate">
+ <input type="radio" name="group1" class="indeterminate">
+ <input type="radio" name="group1" class="indeterminate">
+ <input type="radio" name="group2" class="indeterminate">
+ <span><input type="radio" name="group2" class="indeterminate"></span>
+ <input type="radio" name="group3">
+ <input type="radio" name="group3" checked class="checked">
+ <input type="radio" name="group4">
+ <span><input type="radio" name="group4" checked class="checked"></span>
+ <input type="radio" disabled class="indeterminate disabled">
+ <input type="radio" name="group5" disabled class="indeterminate disabled">
+ <input type="radio" name="group5" disabled class="indeterminate disabled">
+ <input type="radio" name="group6" disabled class="indeterminate disabled">
+ <span><input type="radio" name="group6" disabled class="indeterminate disabled"></span>
+ <input type="radio" name="group7" disabled class="disabled">
+ <input type="radio" name="group7" checked disabled class="checked disabled">
+ <input type="radio" name="group8" disabled class="disabled">
+ <span><input type="radio" name="group8" checked disabled class="checked disabled"></span>
+ <input type="radio" readonly class="indeterminate">
+ <input type="radio" name="group9" readonly class="indeterminate">
+ <input type="radio" name="group9" readonly class="indeterminate">
+ <input type="radio" name="group10" readonly class="indeterminate">
+ <span><input type="radio" name="group10" readonly class="indeterminate"></span>
+ <input type="radio" name="group11" readonly>
+ <input type="radio" name="group11" checked readonly class="checked">
+ <input type="radio" name="group12" readonly>
+ <span><input type="radio" name="group12" checked readonly class="checked"></span>
+ </form>
+ <fieldset disabled class="disabled">
+ <input type="radio" class="indeterminate disabled">
+ <input type="radio" class="indeterminate disabled">
+ <input type="radio" name="group1" class="indeterminate disabled">
+ <input type="radio" name="group1" class="indeterminate disabled">
+ <input type="radio" name="group2" class="indeterminate disabled">
+ <span><input type="radio" name="group2" class="indeterminate disabled"></span>
+ <input type="radio" name="group3" class="disabled">
+ <input type="radio" name="group3" checked class="checked disabled">
+ <input type="radio" name="group4" class="disabled">
+ <span><input type="radio" name="group4" checked class="checked disabled"></span>
+ <input type="radio" disabled class="indeterminate disabled">
+ <input type="radio" name="group5" disabled class="indeterminate disabled">
+ <input type="radio" name="group5" disabled class="indeterminate disabled">
+ <input type="radio" name="group6" disabled class="indeterminate disabled">
+ <span><input type="radio" name="group6" disabled class="indeterminate disabled"></span>
+ <input type="radio" name="group7" disabled class="disabled">
+ <input type="radio" name="group7" checked disabled class="checked disabled">
+ <input type="radio" name="group8" disabled class="disabled">
+ <span><input type="radio" name="group8" checked disabled class="checked disabled"></span>
+ <input type="radio" readonly class="indeterminate disabled">
+ <input type="radio" name="group9" readonly class="indeterminate disabled">
+ <input type="radio" name="group9" readonly class="indeterminate disabled">
+ <input type="radio" name="group10" readonly class="indeterminate disabled">
+ <span><input type="radio" name="group10" readonly class="indeterminate disabled"></span>
+ <input type="radio" name="group11" readonly class="disabled">
+ <input type="radio" name="group11" checked readonly class="checked disabled">
+ <input type="radio" name="group12" readonly class="disabled">
+ <span><input type="radio" name="group12" checked readonly class="checked disabled"></span>
+ </fieldset>
+ <form>
+ <fieldset disabled class="disabled">
+ <input type="radio" class="indeterminate disabled">
+ <input type="radio" class="indeterminate disabled">
+ <input type="radio" name="group1" class="indeterminate disabled">
+ <input type="radio" name="group1" class="indeterminate disabled">
+ <input type="radio" name="group2" class="indeterminate disabled">
+ <span><input type="radio" name="group2" class="indeterminate disabled"></span>
+ <input type="radio" name="group3" class="disabled">
+ <input type="radio" name="group3" checked class="disabled">
+ <input type="radio" name="group4" class="disabled">
+ <span><input type="radio" name="group4" checked class="disabled"></span>
+ <input type="radio" disabled class="indeterminate disabled">
+ <input type="radio" name="group5" disabled class="indeterminate disabled">
+ <input type="radio" name="group5" disabled class="indeterminate disabled">
+ <input type="radio" name="group6" disabled class="indeterminate disabled">
+ <span><input type="radio" name="group6" disabled class="indeterminate disabled"></span>
+ <input type="radio" name="group7" disabled class="disabled">
+ <input type="radio" name="group7" checked disabled class="disabled">
+ <input type="radio" name="group8" disabled class="disabled">
+ <span><input type="radio" name="group8" checked disabled class="disabled"></span>
+ <input type="radio" readonly class="indeterminate disabled">
+ <input type="radio" name="group9" readonly class="indeterminate disabled">
+ <input type="radio" name="group9" readonly class="indeterminate disabled">
+ <input type="radio" name="group10" readonly class="indeterminate disabled">
+ <span><input type="radio" name="group10" readonly class="indeterminate disabled"></span>
+ <input type="radio" name="group11" readonly class="disabled">
+ <input type="radio" name="group11" checked readonly class="disabled">
+ <input type="radio" name="group12" readonly class="disabled">
+ <span><input type="radio" name="group12" checked readonly class="disabled"></span>
+ </fieldset>
+ <fieldset>
+ <input type="radio" class="indeterminate">
+ <input type="radio" class="indeterminate">
+ <input type="radio" name="group1" class="indeterminate">
+ <input type="radio" name="group1" class="indeterminate">
+ <input type="radio" name="group2" class="indeterminate">
+ <span><input type="radio" name="group2" class="indeterminate"></span>
+ <input type="radio" name="group3">
+ <input type="radio" name="group3" checked class="checked">
+ <input type="radio" name="group4">
+ <span><input type="radio" name="group4" checked class="checked"></span>
+ <input type="radio" disabled class="indeterminate disabled">
+ <input type="radio" name="group5" disabled class="indeterminate disabled">
+ <input type="radio" name="group5" disabled class="indeterminate disabled">
+ <input type="radio" name="group6" disabled class="indeterminate disabled">
+ <span><input type="radio" name="group6" disabled class="indeterminate disabled"></span>
+ <input type="radio" name="group7" disabled class="disabled">
+ <input type="radio" name="group7" checked disabled class="checked disabled">
+ <input type="radio" name="group8" disabled class="disabled">
+ <span><input type="radio" name="group8" checked disabled class="checked disabled"></span>
+ <input type="radio" readonly class="indeterminate">
+ <input type="radio" name="group9" readonly class="indeterminate">
+ <input type="radio" name="group9" readonly class="indeterminate">
+ <input type="radio" name="group10" readonly class="indeterminate">
+ <span><input type="radio" name="group10" readonly class="indeterminate"></span>
+ <input type="radio" name="group11" readonly>
+ <input type="radio" name="group11" checked readonly class="checked">
+ <input type="radio" name="group12" readonly>
+ <span><input type="radio" name="group12" checked readonly class="checked"></span>
+ </fieldset>
+ </form>
+</body>
+</html>
Added: trunk/LayoutTests/fast/css/pseudo-indeterminate-radio-buttons-basics.html (0 => 202197)
--- trunk/LayoutTests/fast/css/pseudo-indeterminate-radio-buttons-basics.html (rev 0)
+++ trunk/LayoutTests/fast/css/pseudo-indeterminate-radio-buttons-basics.html 2016-06-18 05:53:28 UTC (rev 202197)
@@ -0,0 +1,206 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<style>
+ input {
+ background-color: blue;
+ width: 15px;
+ height: 15px;
+ -webkit-appearance: none;
+ }
+ :checked {
+ border: 2px solid red;
+ }
+ :indeterminate {
+ background-color: green;
+ }
+ :disabled {
+ border-left: 3px solid orange;
+ }
+</style>
+</head>
+<body>
+ <div>
+ <input type="radio">
+ <input type="radio">
+ <input type="radio" name="group1">
+ <input type="radio" name="group1">
+ <input type="radio" name="group2">
+ <span><input type="radio" name="group2"></span>
+ <input type="radio" name="group3">
+ <input type="radio" name="group3" checked>
+ <input type="radio" name="group4">
+ <span><input type="radio" name="group4" checked></span>
+ <input type="radio" disabled>
+ <input type="radio" name="group5" disabled>
+ <input type="radio" name="group5" disabled>
+ <input type="radio" name="group6" disabled>
+ <span><input type="radio" name="group6" disabled></span>
+ <input type="radio" name="group7" disabled>
+ <input type="radio" name="group7" checked disabled>
+ <input type="radio" name="group8" disabled>
+ <span><input type="radio" name="group8" checked disabled></span>
+ <input type="radio" readonly>
+ <input type="radio" name="group9" readonly>
+ <input type="radio" name="group9" readonly>
+ <input type="radio" name="group10" readonly>
+ <span><input type="radio" name="group10" readonly></span>
+ <input type="radio" name="group11" readonly>
+ <input type="radio" name="group11" checked readonly>
+ <input type="radio" name="group12" readonly>
+ <span><input type="radio" name="group12" checked readonly></span>
+ </div>
+ <form>
+ <input type="radio">
+ <input type="radio">
+ <input type="radio" name="group1">
+ <input type="radio" name="group1">
+ <input type="radio" name="group2">
+ <span><input type="radio" name="group2"></span>
+ <input type="radio" name="group3">
+ <input type="radio" name="group3" checked>
+ <input type="radio" name="group4">
+ <span><input type="radio" name="group4" checked></span>
+ <input type="radio" disabled>
+ <input type="radio" name="group5" disabled>
+ <input type="radio" name="group5" disabled>
+ <input type="radio" name="group6" disabled>
+ <span><input type="radio" name="group6" disabled></span>
+ <input type="radio" name="group7" disabled>
+ <input type="radio" name="group7" checked disabled>
+ <input type="radio" name="group8" disabled>
+ <span><input type="radio" name="group8" checked disabled></span>
+ <input type="radio" readonly>
+ <input type="radio" name="group9" readonly>
+ <input type="radio" name="group9" readonly>
+ <input type="radio" name="group10" readonly>
+ <span><input type="radio" name="group10" readonly></span>
+ <input type="radio" name="group11" readonly>
+ <input type="radio" name="group11" checked readonly>
+ <input type="radio" name="group12" readonly>
+ <span><input type="radio" name="group12" checked readonly></span>
+ </form>
+ <form disabled>
+ <input type="radio">
+ <input type="radio">
+ <input type="radio" name="group1">
+ <input type="radio" name="group1">
+ <input type="radio" name="group2">
+ <span><input type="radio" name="group2"></span>
+ <input type="radio" name="group3">
+ <input type="radio" name="group3" checked>
+ <input type="radio" name="group4">
+ <span><input type="radio" name="group4" checked></span>
+ <input type="radio" disabled>
+ <input type="radio" name="group5" disabled>
+ <input type="radio" name="group5" disabled>
+ <input type="radio" name="group6" disabled>
+ <span><input type="radio" name="group6" disabled></span>
+ <input type="radio" name="group7" disabled>
+ <input type="radio" name="group7" checked disabled>
+ <input type="radio" name="group8" disabled>
+ <span><input type="radio" name="group8" checked disabled></span>
+ <input type="radio" readonly>
+ <input type="radio" name="group9" readonly>
+ <input type="radio" name="group9" readonly>
+ <input type="radio" name="group10" readonly>
+ <span><input type="radio" name="group10" readonly></span>
+ <input type="radio" name="group11" readonly>
+ <input type="radio" name="group11" checked readonly>
+ <input type="radio" name="group12" readonly>
+ <span><input type="radio" name="group12" checked readonly></span>
+ </form>
+ <fieldset disabled>
+ <input type="radio">
+ <input type="radio">
+ <input type="radio" name="group1">
+ <input type="radio" name="group1">
+ <input type="radio" name="group2">
+ <span><input type="radio" name="group2"></span>
+ <input type="radio" name="group3">
+ <input type="radio" name="group3" checked>
+ <input type="radio" name="group4">
+ <span><input type="radio" name="group4" checked></span>
+ <input type="radio" disabled>
+ <input type="radio" name="group5" disabled>
+ <input type="radio" name="group5" disabled>
+ <input type="radio" name="group6" disabled>
+ <span><input type="radio" name="group6" disabled></span>
+ <input type="radio" name="group7" disabled>
+ <input type="radio" name="group7" checked disabled>
+ <input type="radio" name="group8" disabled>
+ <span><input type="radio" name="group8" checked disabled></span>
+ <input type="radio" readonly>
+ <input type="radio" name="group9" readonly>
+ <input type="radio" name="group9" readonly>
+ <input type="radio" name="group10" readonly>
+ <span><input type="radio" name="group10" readonly></span>
+ <input type="radio" name="group11" readonly>
+ <input type="radio" name="group11" checked readonly>
+ <input type="radio" name="group12" readonly>
+ <span><input type="radio" name="group12" checked readonly></span>
+ </fieldset>
+ <form>
+ <fieldset disabled>
+ <input type="radio">
+ <input type="radio">
+ <input type="radio" name="group1">
+ <input type="radio" name="group1">
+ <input type="radio" name="group2">
+ <span><input type="radio" name="group2"></span>
+ <input type="radio" name="group3">
+ <input type="radio" name="group3" checked>
+ <input type="radio" name="group4">
+ <span><input type="radio" name="group4" checked></span>
+ <input type="radio" disabled>
+ <input type="radio" name="group5" disabled>
+ <input type="radio" name="group5" disabled>
+ <input type="radio" name="group6" disabled>
+ <span><input type="radio" name="group6" disabled></span>
+ <input type="radio" name="group7" disabled>
+ <input type="radio" name="group7" checked disabled>
+ <input type="radio" name="group8" disabled>
+ <span><input type="radio" name="group8" checked disabled></span>
+ <input type="radio" readonly>
+ <input type="radio" name="group9" readonly>
+ <input type="radio" name="group9" readonly>
+ <input type="radio" name="group10" readonly>
+ <span><input type="radio" name="group10" readonly></span>
+ <input type="radio" name="group11" readonly>
+ <input type="radio" name="group11" checked readonly>
+ <input type="radio" name="group12" readonly>
+ <span><input type="radio" name="group12" checked readonly></span>
+ </fieldset>
+ <fieldset>
+ <input type="radio">
+ <input type="radio">
+ <input type="radio" name="group1">
+ <input type="radio" name="group1">
+ <input type="radio" name="group2">
+ <span><input type="radio" name="group2"></span>
+ <input type="radio" name="group3">
+ <input type="radio" name="group3" checked>
+ <input type="radio" name="group4">
+ <span><input type="radio" name="group4" checked></span>
+ <input type="radio" disabled>
+ <input type="radio" name="group5" disabled>
+ <input type="radio" name="group5" disabled>
+ <input type="radio" name="group6" disabled>
+ <span><input type="radio" name="group6" disabled></span>
+ <input type="radio" name="group7" disabled>
+ <input type="radio" name="group7" checked disabled>
+ <input type="radio" name="group8" disabled>
+ <span><input type="radio" name="group8" checked disabled></span>
+ <input type="radio" readonly>
+ <input type="radio" name="group9" readonly>
+ <input type="radio" name="group9" readonly>
+ <input type="radio" name="group10" readonly>
+ <span><input type="radio" name="group10" readonly></span>
+ <input type="radio" name="group11" readonly>
+ <input type="radio" name="group11" checked readonly>
+ <input type="radio" name="group12" readonly>
+ <span><input type="radio" name="group12" checked readonly></span>
+ </fieldset>
+ </form>
+</body>
+</html>
Added: trunk/LayoutTests/fast/css/pseudo-indeterminate-with-radio-buttons-style-invalidation-expected.txt (0 => 202197)
--- trunk/LayoutTests/fast/css/pseudo-indeterminate-with-radio-buttons-style-invalidation-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/css/pseudo-indeterminate-with-radio-buttons-style-invalidation-expected.txt 2016-06-18 05:53:28 UTC (rev 202197)
@@ -0,0 +1,28 @@
+Verify that we do not invalidate more than needed to satisfy :indeterminate
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS elementsNeedingStyleRecalc() is []
+PASS elementsWithIndeterminateStyle() is ["radio1", "radio2", "radio3", "radio4", "radio5", "radio6", "radio7", "radio8", "radio9", "radio10"]
+PASS checkedElements() is []
+Check radio3
+PASS elementsNeedingStyleRecalc() is ["radio1", "radio2", "radio3", "radio4", "radio5"]
+PASS elementsWithIndeterminateStyle() is ["radio6", "radio7", "radio8", "radio9", "radio10"]
+PASS checkedElements() is ["radio3"]
+Check radio8
+PASS elementsNeedingStyleRecalc() is ["radio6", "radio7", "radio8", "radio9", "radio10"]
+PASS elementsWithIndeterminateStyle() is []
+PASS checkedElements() is ["radio3", "radio8"]
+Check radio4
+PASS elementsNeedingStyleRecalc() is ["radio3", "radio4"]
+PASS elementsWithIndeterminateStyle() is []
+PASS checkedElements() is ["radio4", "radio8"]
+Check radio9
+PASS elementsNeedingStyleRecalc() is ["radio8", "radio9"]
+PASS elementsWithIndeterminateStyle() is []
+PASS checkedElements() is ["radio4", "radio9"]
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/css/pseudo-indeterminate-with-radio-buttons-style-invalidation.html (0 => 202197)
--- trunk/LayoutTests/fast/css/pseudo-indeterminate-with-radio-buttons-style-invalidation.html (rev 0)
+++ trunk/LayoutTests/fast/css/pseudo-indeterminate-with-radio-buttons-style-invalidation.html 2016-06-18 05:53:28 UTC (rev 202197)
@@ -0,0 +1,106 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<style>
+ input {
+ background-color: rgb(1, 2, 3);
+ }
+ :indeterminate {
+ background-color: rgb(4, 5, 6);
+ }
+</style>
+</head>
+<body>
+ <div id="with-renderer">
+ <!-- With renderer -->
+ <input type="radio" name="group1" id="radio1">
+ <input type="radio" name="group1" id="radio2">
+ <input type="radio" name="group1" id="radio3">
+ <input type="radio" name="group1" id="radio4">
+ <input type="radio" name="group1" id="radio5">
+ </div>
+ <div style="display:none;">
+ <!-- Without renderer -->
+ <input type="radio" name="group2" id="radio6">
+ <input type="radio" name="group2" id="radio7">
+ <input type="radio" name="group2" id="radio8">
+ <input type="radio" name="group2" id="radio9">
+ <input type="radio" name="group2" id="radio10">
+ </div>
+</body>
+<script>
+
+description('Verify that we do not invalidate more than needed to satisfy :indeterminate');
+let allInputs = document.querySelectorAll("input");
+
+function elementsNeedingStyleRecalc() {
+ let elementsRequiringNeedStyleRecalc = []
+ for (let inputElement of allInputs) {
+ let needsStyleRecalc = window.internals.nodeNeedsStyleRecalc(inputElement);
+ if (needsStyleRecalc)
+ elementsRequiringNeedStyleRecalc.push(inputElement.id);
+ }
+ return elementsRequiringNeedStyleRecalc;
+}
+
+function elementsWithIndeterminateStyle() {
+ let elements = [];
+ for (let inputElement of allInputs) {
+ let backgroundColor = getComputedStyle(inputElement).backgroundColor;
+ if (backgroundColor === "rgb(4, 5, 6)")
+ elements.push(inputElement.id);
+ }
+ return elements;
+}
+
+function checkedElements() {
+ let elements = [];
+ for (let inputElement of allInputs) {
+ if (inputElement.checked)
+ elements.push(inputElement.id);
+ }
+ return elements;
+}
+
+// Force a layout to ensure we don't have dirty styles.
+var offsetTop = document.documentElement.offsetTop;
+
+// Initial state.
+shouldBe("elementsNeedingStyleRecalc()", '[]');
+shouldBe("elementsWithIndeterminateStyle()", '["radio1", "radio2", "radio3", "radio4", "radio5", "radio6", "radio7", "radio8", "radio9", "radio10"]');
+shouldBe("checkedElements()", '[]');
+
+// Check radio3. All the group1 require style recalc.
+debug("Check radio3");
+document.getElementById("radio3").checked = true;
+shouldBe("elementsNeedingStyleRecalc()", '["radio1", "radio2", "radio3", "radio4", "radio5"]');
+shouldBe("elementsWithIndeterminateStyle()", '["radio6", "radio7", "radio8", "radio9", "radio10"]');
+shouldBe("checkedElements()", '["radio3"]');
+
+// Check radio8. All the group1 require style recalc.
+debug("Check radio8");
+document.getElementById("radio8").checked = true;
+shouldBe("elementsNeedingStyleRecalc()", '["radio6", "radio7", "radio8", "radio9", "radio10"]');
+shouldBe("elementsWithIndeterminateStyle()", '[]');
+shouldBe("checkedElements()", '["radio3", "radio8"]');
+
+// Checking radio4, we should not need to invalidate anything but the two modified elements.
+debug("Check radio4");
+document.getElementById("radio4").checked = true;
+shouldBe("elementsNeedingStyleRecalc()", '["radio3", "radio4"]');
+shouldBe("elementsWithIndeterminateStyle()", '[]');
+shouldBe("checkedElements()", '["radio4", "radio8"]');
+
+// Checking radio9, we should not need to invalidate anything but the two modified elements.
+debug("Check radio9");
+document.getElementById("radio9").checked = true;
+shouldBe("elementsNeedingStyleRecalc()", '["radio8", "radio9"]');
+shouldBe("elementsWithIndeterminateStyle()", '[]');
+shouldBe("checkedElements()", '["radio4", "radio9"]');
+
+// Hide the elements to make the results prettier.
+document.getElementById("with-renderer").style.display = "none";
+</script>
+<script src=""
+</html>
Modified: trunk/LayoutTests/fast/forms/radio/indeterminate-radio.html (202196 => 202197)
--- trunk/LayoutTests/fast/forms/radio/indeterminate-radio.html 2016-06-18 03:33:19 UTC (rev 202196)
+++ trunk/LayoutTests/fast/forms/radio/indeterminate-radio.html 2016-06-18 05:53:28 UTC (rev 202197)
@@ -27,9 +27,6 @@
{
try
{
-
- document.getElementsByTagName("input")[0].indeterminate = true;
-
function ArrayContains(array, value, ci)
{
ci = ci == true ? true : false;
@@ -46,11 +43,15 @@
}
return false;
}
+
var target = document.getElementById("test");
var val = getComputedStyle(target, null).getPropertyValue("color");
- var aExpectedValues = new Array("green", "#008000", "rgb(0, 128, 0)");
+ var aExpectedValues = new Array("red", "#FF0000", "rgb(255, 0, 0)");
+ let wasIndeterminate = ArrayContains(aExpectedValues, val, true);
- if (ArrayContains(aExpectedValues, val, true))
+ document.getElementsByTagName("input")[0].indeterminate = true;
+
+ if (wasIndeterminate && ArrayContains(aExpectedValues, val, true))
{
document.getElementById("testresult").innerHTML = "Pass";
@@ -66,4 +67,4 @@
</body>
-</html>
\ No newline at end of file
+</html>
Added: trunk/LayoutTests/fast/selectors/detached-radio-button-checked-and-indeterminate-states-expected.txt (0 => 202197)
--- trunk/LayoutTests/fast/selectors/detached-radio-button-checked-and-indeterminate-states-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/selectors/detached-radio-button-checked-and-indeterminate-states-expected.txt 2016-06-18 05:53:28 UTC (rev 202197)
@@ -0,0 +1,148 @@
+Verify :indeterminate, :checked and the indeterminate property on radio button detached from the document.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Initial state
+PASS document.getElementById('radio1-in-document').indeterminate is false
+PASS document.getElementById('radio2-in-document').indeterminate is false
+PASS document.getElementById('radio3-in-document').indeterminate is false
+PASS document.getElementById('radio4-in-document').indeterminate is false
+PASS document.getElementById('radio1-in-document').checked is false
+PASS document.getElementById('radio2-in-document').checked is true
+PASS document.getElementById('radio3-in-document').checked is false
+PASS document.getElementById('radio4-in-document').checked is false
+PASS document.getElementById('radio1-in-document').matches(':indeterminate') is false
+PASS document.getElementById('radio2-in-document').matches(':indeterminate') is false
+PASS document.getElementById('radio3-in-document').matches(':indeterminate') is true
+PASS document.getElementById('radio4-in-document').matches(':indeterminate') is true
+PASS document.getElementById('radio1-in-document').matches(':checked') is false
+PASS document.getElementById('radio2-in-document').matches(':checked') is true
+PASS document.getElementById('radio3-in-document').matches(':checked') is false
+PASS document.getElementById('radio4-in-document').matches(':checked') is false
+PASS getComputedStyle(document.getElementById('radio1-in-document')).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById('radio2-in-document')).backgroundColor is "rgb(7, 8, 9)"
+PASS getComputedStyle(document.getElementById('radio3-in-document')).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById('radio4-in-document')).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById('radio1-in-document')).color is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById('radio2-in-document')).color is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById('radio3-in-document')).color is "rgb(10, 11, 12)"
+PASS getComputedStyle(document.getElementById('radio4-in-document')).color is "rgb(10, 11, 12)"
+Remove radio2-in-document from document, into variable radio2
+PASS document.querySelectorAll('radio2-in-document') is []
+PASS document.getElementById('radio1-in-document').indeterminate is false
+PASS radio2.indeterminate is false
+PASS document.getElementById('radio3-in-document').indeterminate is false
+PASS document.getElementById('radio4-in-document').indeterminate is false
+PASS document.getElementById('radio1-in-document').checked is false
+PASS radio2.checked is true
+PASS document.getElementById('radio3-in-document').checked is false
+PASS document.getElementById('radio4-in-document').checked is false
+PASS document.getElementById('radio1-in-document').matches(':indeterminate') is true
+PASS radio2.matches(':indeterminate') is false
+PASS document.getElementById('radio3-in-document').matches(':indeterminate') is true
+PASS document.getElementById('radio4-in-document').matches(':indeterminate') is true
+PASS document.getElementById('radio1-in-document').matches(':checked') is false
+PASS radio2.matches(':checked') is true
+PASS document.getElementById('radio3-in-document').matches(':checked') is false
+PASS document.getElementById('radio4-in-document').matches(':checked') is false
+PASS getComputedStyle(document.getElementById('radio1-in-document')).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(radio2).backgroundColor is ""
+PASS getComputedStyle(document.getElementById('radio3-in-document')).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById('radio4-in-document')).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById('radio1-in-document')).color is "rgb(10, 11, 12)"
+PASS getComputedStyle(radio2).color is ""
+PASS getComputedStyle(document.getElementById('radio3-in-document')).color is "rgb(10, 11, 12)"
+PASS getComputedStyle(document.getElementById('radio4-in-document')).color is "rgb(10, 11, 12)"
+Remove radio3-in-document from document, into variable radio3
+PASS document.querySelectorAll('radio3-in-document') is []
+PASS document.getElementById('radio1-in-document').indeterminate is false
+PASS radio2.indeterminate is false
+PASS radio3.indeterminate is false
+PASS document.getElementById('radio4-in-document').indeterminate is false
+PASS document.getElementById('radio1-in-document').checked is false
+PASS radio2.checked is true
+PASS radio3.checked is false
+PASS document.getElementById('radio4-in-document').checked is false
+PASS document.getElementById('radio1-in-document').matches(':indeterminate') is true
+PASS radio2.matches(':indeterminate') is false
+PASS radio3.matches(':indeterminate') is true
+PASS document.getElementById('radio4-in-document').matches(':indeterminate') is true
+PASS document.getElementById('radio1-in-document').matches(':checked') is false
+PASS radio2.matches(':checked') is true
+PASS radio3.matches(':checked') is false
+PASS document.getElementById('radio4-in-document').matches(':checked') is false
+PASS getComputedStyle(document.getElementById('radio1-in-document')).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(radio2).backgroundColor is ""
+PASS getComputedStyle(radio3).backgroundColor is ""
+PASS getComputedStyle(document.getElementById('radio4-in-document')).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById('radio1-in-document')).color is "rgb(10, 11, 12)"
+PASS getComputedStyle(radio2).color is ""
+PASS getComputedStyle(radio3).color is ""
+PASS getComputedStyle(document.getElementById('radio4-in-document')).color is "rgb(10, 11, 12)"
+Create new element named webkitRadio
+PASS document.getElementById('radio1-in-document').indeterminate is false
+PASS radio2.indeterminate is false
+PASS radio3.indeterminate is false
+PASS document.getElementById('radio4-in-document').indeterminate is false
+PASS webkitRadio.indeterminate is false
+PASS document.getElementById('radio1-in-document').checked is false
+PASS radio2.checked is true
+PASS radio3.checked is false
+PASS document.getElementById('radio4-in-document').checked is false
+PASS webkitRadio.checked is false
+PASS document.getElementById('radio1-in-document').matches(':indeterminate') is true
+PASS radio2.matches(':indeterminate') is false
+PASS radio3.matches(':indeterminate') is true
+PASS document.getElementById('radio4-in-document').matches(':indeterminate') is true
+PASS webkitRadio.matches(':indeterminate') is true
+PASS document.getElementById('radio1-in-document').matches(':checked') is false
+PASS radio2.matches(':checked') is true
+PASS radio3.matches(':checked') is false
+PASS document.getElementById('radio4-in-document').matches(':checked') is false
+PASS webkitRadio.matches(':checked') is false
+PASS getComputedStyle(document.getElementById('radio1-in-document')).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(radio2).backgroundColor is ""
+PASS getComputedStyle(radio3).backgroundColor is ""
+PASS getComputedStyle(document.getElementById('radio4-in-document')).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(webkitRadio).backgroundColor is ""
+PASS getComputedStyle(document.getElementById('radio1-in-document')).color is "rgb(10, 11, 12)"
+PASS getComputedStyle(radio2).color is ""
+PASS getComputedStyle(radio3).color is ""
+PASS getComputedStyle(document.getElementById('radio4-in-document')).color is "rgb(10, 11, 12)"
+PASS getComputedStyle(webkitRadio).color is ""
+Check webkitRadio
+PASS document.getElementById('radio1-in-document').indeterminate is false
+PASS radio2.indeterminate is false
+PASS radio3.indeterminate is false
+PASS document.getElementById('radio4-in-document').indeterminate is false
+PASS webkitRadio.indeterminate is false
+PASS document.getElementById('radio1-in-document').checked is false
+PASS radio2.checked is true
+PASS radio3.checked is false
+PASS document.getElementById('radio4-in-document').checked is false
+PASS webkitRadio.checked is true
+PASS document.getElementById('radio1-in-document').matches(':indeterminate') is true
+PASS radio2.matches(':indeterminate') is false
+PASS radio3.matches(':indeterminate') is true
+PASS document.getElementById('radio4-in-document').matches(':indeterminate') is true
+PASS webkitRadio.matches(':indeterminate') is false
+PASS document.getElementById('radio1-in-document').matches(':checked') is false
+PASS radio2.matches(':checked') is true
+PASS radio3.matches(':checked') is false
+PASS document.getElementById('radio4-in-document').matches(':checked') is false
+PASS webkitRadio.matches(':checked') is true
+PASS getComputedStyle(document.getElementById('radio1-in-document')).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(radio2).backgroundColor is ""
+PASS getComputedStyle(radio3).backgroundColor is ""
+PASS getComputedStyle(document.getElementById('radio4-in-document')).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(webkitRadio).backgroundColor is ""
+PASS getComputedStyle(document.getElementById('radio1-in-document')).color is "rgb(10, 11, 12)"
+PASS getComputedStyle(radio2).color is ""
+PASS getComputedStyle(radio3).color is ""
+PASS getComputedStyle(document.getElementById('radio4-in-document')).color is "rgb(10, 11, 12)"
+PASS getComputedStyle(webkitRadio).color is ""
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/selectors/detached-radio-button-checked-and-indeterminate-states.html (0 => 202197)
--- trunk/LayoutTests/fast/selectors/detached-radio-button-checked-and-indeterminate-states.html (rev 0)
+++ trunk/LayoutTests/fast/selectors/detached-radio-button-checked-and-indeterminate-states.html 2016-06-18 05:53:28 UTC (rev 202197)
@@ -0,0 +1,208 @@
+<!doctype html>
+<html>
+<head>
+<script src=""
+<style>
+ input {
+ background-color: rgb(1, 2, 3);
+ color: rgb(4, 5, 6);
+ }
+ :checked {
+ background-color: rgb(7, 8, 9);
+ }
+ :indeterminate {
+ color: rgb(10, 11, 12);
+ }
+</style>
+</head>
+<body>
+ <div id="testcases">
+ <input type="radio" name="group1" id="radio1-in-document">
+ <input type="radio" name="group1" id="radio2-in-document" checked>
+ <input type="radio" name="group2" id="radio3-in-document">
+ <input type="radio" name="group2" id="radio4-in-document">
+ </div>
+</body>
+<script>
+description('Verify :indeterminate, :checked and the indeterminate property on radio button detached from the document.');
+
+debug("Initial state");
+shouldBeFalse("document.getElementById('radio1-in-document').indeterminate");
+shouldBeFalse("document.getElementById('radio2-in-document').indeterminate");
+shouldBeFalse("document.getElementById('radio3-in-document').indeterminate");
+shouldBeFalse("document.getElementById('radio4-in-document').indeterminate");
+
+shouldBeFalse("document.getElementById('radio1-in-document').checked");
+shouldBeTrue("document.getElementById('radio2-in-document').checked");
+shouldBeFalse("document.getElementById('radio3-in-document').checked");
+shouldBeFalse("document.getElementById('radio4-in-document').checked");
+
+shouldBeFalse("document.getElementById('radio1-in-document').matches(':indeterminate')");
+shouldBeFalse("document.getElementById('radio2-in-document').matches(':indeterminate')");
+shouldBeTrue("document.getElementById('radio3-in-document').matches(':indeterminate')");
+shouldBeTrue("document.getElementById('radio4-in-document').matches(':indeterminate')");
+
+shouldBeFalse("document.getElementById('radio1-in-document').matches(':checked')");
+shouldBeTrue("document.getElementById('radio2-in-document').matches(':checked')");
+shouldBeFalse("document.getElementById('radio3-in-document').matches(':checked')");
+shouldBeFalse("document.getElementById('radio4-in-document').matches(':checked')");
+
+shouldBeEqualToString("getComputedStyle(document.getElementById('radio1-in-document')).backgroundColor", "rgb(1, 2, 3)");
+shouldBeEqualToString("getComputedStyle(document.getElementById('radio2-in-document')).backgroundColor", "rgb(7, 8, 9)");
+shouldBeEqualToString("getComputedStyle(document.getElementById('radio3-in-document')).backgroundColor", "rgb(1, 2, 3)");
+shouldBeEqualToString("getComputedStyle(document.getElementById('radio4-in-document')).backgroundColor", "rgb(1, 2, 3)");
+
+shouldBeEqualToString("getComputedStyle(document.getElementById('radio1-in-document')).color", "rgb(4, 5, 6)");
+shouldBeEqualToString("getComputedStyle(document.getElementById('radio2-in-document')).color", "rgb(4, 5, 6)");
+shouldBeEqualToString("getComputedStyle(document.getElementById('radio3-in-document')).color", "rgb(10, 11, 12)");
+shouldBeEqualToString("getComputedStyle(document.getElementById('radio4-in-document')).color", "rgb(10, 11, 12)");
+
+debug("Remove radio2-in-document from document, into variable radio2");
+let radio2 = document.getElementById('radio2-in-document');
+radio2.parentElement.removeChild(radio2);
+shouldBe("document.querySelectorAll('radio2-in-document')", "[]");
+shouldBeFalse("document.getElementById('radio1-in-document').indeterminate");
+shouldBeFalse("radio2.indeterminate");
+shouldBeFalse("document.getElementById('radio3-in-document').indeterminate");
+shouldBeFalse("document.getElementById('radio4-in-document').indeterminate");
+
+shouldBeFalse("document.getElementById('radio1-in-document').checked");
+shouldBeTrue("radio2.checked");
+shouldBeFalse("document.getElementById('radio3-in-document').checked");
+shouldBeFalse("document.getElementById('radio4-in-document').checked");
+
+shouldBeTrue("document.getElementById('radio1-in-document').matches(':indeterminate')");
+shouldBeFalse("radio2.matches(':indeterminate')");
+shouldBeTrue("document.getElementById('radio3-in-document').matches(':indeterminate')");
+shouldBeTrue("document.getElementById('radio4-in-document').matches(':indeterminate')");
+
+shouldBeFalse("document.getElementById('radio1-in-document').matches(':checked')");
+shouldBeTrue("radio2.matches(':checked')");
+shouldBeFalse("document.getElementById('radio3-in-document').matches(':checked')");
+shouldBeFalse("document.getElementById('radio4-in-document').matches(':checked')");
+
+shouldBeEqualToString("getComputedStyle(document.getElementById('radio1-in-document')).backgroundColor", "rgb(1, 2, 3)");
+shouldBeEqualToString("getComputedStyle(radio2).backgroundColor", "");
+shouldBeEqualToString("getComputedStyle(document.getElementById('radio3-in-document')).backgroundColor", "rgb(1, 2, 3)");
+shouldBeEqualToString("getComputedStyle(document.getElementById('radio4-in-document')).backgroundColor", "rgb(1, 2, 3)");
+
+shouldBeEqualToString("getComputedStyle(document.getElementById('radio1-in-document')).color", "rgb(10, 11, 12)");
+shouldBeEqualToString("getComputedStyle(radio2).color", "");
+shouldBeEqualToString("getComputedStyle(document.getElementById('radio3-in-document')).color", "rgb(10, 11, 12)");
+shouldBeEqualToString("getComputedStyle(document.getElementById('radio4-in-document')).color", "rgb(10, 11, 12)");
+
+debug("Remove radio3-in-document from document, into variable radio3");
+let radio3 = document.getElementById('radio3-in-document');
+radio3.parentElement.removeChild(radio3);
+shouldBe("document.querySelectorAll('radio3-in-document')", "[]");
+shouldBeFalse("document.getElementById('radio1-in-document').indeterminate");
+shouldBeFalse("radio2.indeterminate");
+shouldBeFalse("radio3.indeterminate");
+shouldBeFalse("document.getElementById('radio4-in-document').indeterminate");
+
+shouldBeFalse("document.getElementById('radio1-in-document').checked");
+shouldBeTrue("radio2.checked");
+shouldBeFalse("radio3.checked");
+shouldBeFalse("document.getElementById('radio4-in-document').checked");
+
+shouldBeTrue("document.getElementById('radio1-in-document').matches(':indeterminate')");
+shouldBeFalse("radio2.matches(':indeterminate')");
+shouldBeTrue("radio3.matches(':indeterminate')");
+shouldBeTrue("document.getElementById('radio4-in-document').matches(':indeterminate')");
+
+shouldBeFalse("document.getElementById('radio1-in-document').matches(':checked')");
+shouldBeTrue("radio2.matches(':checked')");
+shouldBeFalse("radio3.matches(':checked')");
+shouldBeFalse("document.getElementById('radio4-in-document').matches(':checked')");
+
+shouldBeEqualToString("getComputedStyle(document.getElementById('radio1-in-document')).backgroundColor", "rgb(1, 2, 3)");
+shouldBeEqualToString("getComputedStyle(radio2).backgroundColor", "");
+shouldBeEqualToString("getComputedStyle(radio3).backgroundColor", "");
+shouldBeEqualToString("getComputedStyle(document.getElementById('radio4-in-document')).backgroundColor", "rgb(1, 2, 3)");
+
+shouldBeEqualToString("getComputedStyle(document.getElementById('radio1-in-document')).color", "rgb(10, 11, 12)");
+shouldBeEqualToString("getComputedStyle(radio2).color", "");
+shouldBeEqualToString("getComputedStyle(radio3).color", "");
+shouldBeEqualToString("getComputedStyle(document.getElementById('radio4-in-document')).color", "rgb(10, 11, 12)");
+
+debug("Create new element named webkitRadio");
+let webkitRadio = document.createElement("input");
+webkitRadio.type = "radio";
+shouldBeFalse("document.getElementById('radio1-in-document').indeterminate");
+shouldBeFalse("radio2.indeterminate");
+shouldBeFalse("radio3.indeterminate");
+shouldBeFalse("document.getElementById('radio4-in-document').indeterminate");
+shouldBeFalse("webkitRadio.indeterminate");
+
+shouldBeFalse("document.getElementById('radio1-in-document').checked");
+shouldBeTrue("radio2.checked");
+shouldBeFalse("radio3.checked");
+shouldBeFalse("document.getElementById('radio4-in-document').checked");
+shouldBeFalse("webkitRadio.checked");
+
+shouldBeTrue("document.getElementById('radio1-in-document').matches(':indeterminate')");
+shouldBeFalse("radio2.matches(':indeterminate')");
+shouldBeTrue("radio3.matches(':indeterminate')");
+shouldBeTrue("document.getElementById('radio4-in-document').matches(':indeterminate')");
+shouldBeTrue("webkitRadio.matches(':indeterminate')");
+
+shouldBeFalse("document.getElementById('radio1-in-document').matches(':checked')");
+shouldBeTrue("radio2.matches(':checked')");
+shouldBeFalse("radio3.matches(':checked')");
+shouldBeFalse("document.getElementById('radio4-in-document').matches(':checked')");
+shouldBeFalse("webkitRadio.matches(':checked')");
+
+shouldBeEqualToString("getComputedStyle(document.getElementById('radio1-in-document')).backgroundColor", "rgb(1, 2, 3)");
+shouldBeEqualToString("getComputedStyle(radio2).backgroundColor", "");
+shouldBeEqualToString("getComputedStyle(radio3).backgroundColor", "");
+shouldBeEqualToString("getComputedStyle(document.getElementById('radio4-in-document')).backgroundColor", "rgb(1, 2, 3)");
+shouldBeEqualToString("getComputedStyle(webkitRadio).backgroundColor", "");
+
+shouldBeEqualToString("getComputedStyle(document.getElementById('radio1-in-document')).color", "rgb(10, 11, 12)");
+shouldBeEqualToString("getComputedStyle(radio2).color", "");
+shouldBeEqualToString("getComputedStyle(radio3).color", "");
+shouldBeEqualToString("getComputedStyle(document.getElementById('radio4-in-document')).color", "rgb(10, 11, 12)");
+shouldBeEqualToString("getComputedStyle(webkitRadio).color", "");
+
+debug("Check webkitRadio");
+webkitRadio.checked = true;
+shouldBeFalse("document.getElementById('radio1-in-document').indeterminate");
+shouldBeFalse("radio2.indeterminate");
+shouldBeFalse("radio3.indeterminate");
+shouldBeFalse("document.getElementById('radio4-in-document').indeterminate");
+shouldBeFalse("webkitRadio.indeterminate");
+
+shouldBeFalse("document.getElementById('radio1-in-document').checked");
+shouldBeTrue("radio2.checked");
+shouldBeFalse("radio3.checked");
+shouldBeFalse("document.getElementById('radio4-in-document').checked");
+shouldBeTrue("webkitRadio.checked");
+
+shouldBeTrue("document.getElementById('radio1-in-document').matches(':indeterminate')");
+shouldBeFalse("radio2.matches(':indeterminate')");
+shouldBeTrue("radio3.matches(':indeterminate')");
+shouldBeTrue("document.getElementById('radio4-in-document').matches(':indeterminate')");
+shouldBeFalse("webkitRadio.matches(':indeterminate')");
+
+shouldBeFalse("document.getElementById('radio1-in-document').matches(':checked')");
+shouldBeTrue("radio2.matches(':checked')");
+shouldBeFalse("radio3.matches(':checked')");
+shouldBeFalse("document.getElementById('radio4-in-document').matches(':checked')");
+shouldBeTrue("webkitRadio.matches(':checked')");
+
+shouldBeEqualToString("getComputedStyle(document.getElementById('radio1-in-document')).backgroundColor", "rgb(1, 2, 3)");
+shouldBeEqualToString("getComputedStyle(radio2).backgroundColor", "");
+shouldBeEqualToString("getComputedStyle(radio3).backgroundColor", "");
+shouldBeEqualToString("getComputedStyle(document.getElementById('radio4-in-document')).backgroundColor", "rgb(1, 2, 3)");
+shouldBeEqualToString("getComputedStyle(webkitRadio).backgroundColor", "");
+
+shouldBeEqualToString("getComputedStyle(document.getElementById('radio1-in-document')).color", "rgb(10, 11, 12)");
+shouldBeEqualToString("getComputedStyle(radio2).color", "");
+shouldBeEqualToString("getComputedStyle(radio3).color", "");
+shouldBeEqualToString("getComputedStyle(document.getElementById('radio4-in-document')).color", "rgb(10, 11, 12)");
+shouldBeEqualToString("getComputedStyle(webkitRadio).color", "");
+
+document.getElementById("testcases").style.display = "none";
+</script>
+<script src=""
+</html>
Added: trunk/LayoutTests/fast/selectors/pseudo-indeterminate-with-radio-buttons-style-update-expected.txt (0 => 202197)
--- trunk/LayoutTests/fast/selectors/pseudo-indeterminate-with-radio-buttons-style-update-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/selectors/pseudo-indeterminate-with-radio-buttons-style-update-expected.txt 2016-06-18 05:53:28 UTC (rev 202197)
@@ -0,0 +1,59 @@
+Verify we invalidate radio button groups to match :indeterminate when a button is checked/unchecked
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS elementsWithIndeterminateStyle() is ["radio1", "radio2", "radio3", "radio4", "radio5", "radio6", "radio7", "radio8", "radio9", "radio10"]
+PASS checkedElements() is []
+Check radio3
+PASS elementsWithIndeterminateStyle() is ["radio6", "radio7", "radio8", "radio9", "radio10"]
+PASS checkedElements() is ["radio3"]
+Check radio8
+PASS elementsWithIndeterminateStyle() is []
+PASS checkedElements() is ["radio3", "radio8"]
+Check radio4
+PASS elementsWithIndeterminateStyle() is []
+PASS checkedElements() is ["radio4", "radio8"]
+Check radio9
+PASS elementsWithIndeterminateStyle() is []
+PASS checkedElements() is ["radio4", "radio9"]
+Uncheck radio4
+PASS elementsWithIndeterminateStyle() is ["radio1", "radio2", "radio3", "radio4", "radio5"]
+PASS checkedElements() is ["radio9"]
+Uncheck radio9
+PASS elementsWithIndeterminateStyle() is ["radio1", "radio2", "radio3", "radio4", "radio5", "radio6", "radio7", "radio8", "radio9", "radio10"]
+PASS checkedElements() is []
+Check radio1
+PASS elementsWithIndeterminateStyle() is ["radio6", "radio7", "radio8", "radio9", "radio10"]
+PASS checkedElements() is ["radio1"]
+Check radio2
+PASS elementsWithIndeterminateStyle() is ["radio6", "radio7", "radio8", "radio9", "radio10"]
+PASS checkedElements() is ["radio2"]
+Remove radio3 from its group
+PASS elementsWithIndeterminateStyle() is ["radio3", "radio6", "radio7", "radio8", "radio9", "radio10"]
+PASS checkedElements() is ["radio2"]
+Remove radio6 from its group
+PASS elementsWithIndeterminateStyle() is ["radio3", "radio6", "radio7", "radio8", "radio9", "radio10"]
+PASS checkedElements() is ["radio2"]
+Remove radio2 from its group
+PASS elementsWithIndeterminateStyle() is ["radio1", "radio3", "radio4", "radio5", "radio6", "radio7", "radio8", "radio9", "radio10"]
+PASS checkedElements() is ["radio2"]
+Check radio7
+PASS elementsWithIndeterminateStyle() is ["radio1", "radio3", "radio4", "radio5", "radio6"]
+PASS checkedElements() is ["radio2", "radio7"]
+Check radio8
+PASS elementsWithIndeterminateStyle() is ["radio1", "radio3", "radio4", "radio5", "radio6"]
+PASS checkedElements() is ["radio2", "radio8"]
+Remove radio9 from its group
+PASS elementsWithIndeterminateStyle() is ["radio1", "radio3", "radio4", "radio5", "radio6", "radio9"]
+PASS checkedElements() is ["radio2", "radio8"]
+Remove radio8 from its group
+PASS elementsWithIndeterminateStyle() is ["radio1", "radio3", "radio4", "radio5", "radio6", "radio7", "radio9", "radio10"]
+PASS checkedElements() is ["radio2", "radio8"]
+Remove radio7 from its group
+PASS elementsWithIndeterminateStyle() is ["radio1", "radio3", "radio4", "radio5", "radio6", "radio7", "radio9", "radio10"]
+PASS checkedElements() is ["radio2", "radio8"]
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/selectors/pseudo-indeterminate-with-radio-buttons-style-update.html (0 => 202197)
--- trunk/LayoutTests/fast/selectors/pseudo-indeterminate-with-radio-buttons-style-update.html (rev 0)
+++ trunk/LayoutTests/fast/selectors/pseudo-indeterminate-with-radio-buttons-style-update.html 2016-06-18 05:53:28 UTC (rev 202197)
@@ -0,0 +1,148 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<style>
+ input {
+ background-color: rgb(1, 2, 3);
+ }
+ :indeterminate {
+ background-color: rgb(4, 5, 6);
+ }
+</style>
+</head>
+<body>
+ <div id="with-renderer">
+ <!-- With renderer -->
+ <input type="radio" name="group1" id="radio1">
+ <input type="radio" name="group1" id="radio2">
+ <input type="radio" name="group1" id="radio3">
+ <span>
+ <input type="radio" name="group1" id="radio4">
+ <input type="radio" name="group1" id="radio5">
+ </span>
+ </div>
+ <div style="display:none;">
+ <!-- Without renderer -->
+ <input type="radio" name="group2" id="radio6">
+ <span>
+ <input type="radio" name="group2" id="radio7">
+ <input type="radio" name="group2" id="radio8">
+ </span>
+ <input type="radio" name="group2" id="radio9">
+ <input type="radio" name="group2" id="radio10">
+ </div>
+</body>
+<script>
+
+description('Verify we invalidate radio button groups to match :indeterminate when a button is checked/unchecked');
+let allInputs = document.querySelectorAll("input");
+
+function elementsWithIndeterminateStyle() {
+ let elements = [];
+ for (let inputElement of allInputs) {
+ let backgroundColor = getComputedStyle(inputElement).backgroundColor;
+ if (backgroundColor === "rgb(4, 5, 6)")
+ elements.push(inputElement.id);
+ }
+ return elements;
+}
+
+function checkedElements() {
+ let elements = [];
+ for (let inputElement of allInputs) {
+ if (inputElement.checked)
+ elements.push(inputElement.id);
+ }
+ return elements;
+}
+
+shouldBe("elementsWithIndeterminateStyle()", '["radio1", "radio2", "radio3", "radio4", "radio5", "radio6", "radio7", "radio8", "radio9", "radio10"]');
+shouldBe("checkedElements()", '[]');
+
+debug("Check radio3");
+document.getElementById("radio3").checked = true;
+shouldBe("elementsWithIndeterminateStyle()", '["radio6", "radio7", "radio8", "radio9", "radio10"]');
+shouldBe("checkedElements()", '["radio3"]');
+
+debug("Check radio8");
+document.getElementById("radio8").checked = true;
+shouldBe("elementsWithIndeterminateStyle()", '[]');
+shouldBe("checkedElements()", '["radio3", "radio8"]');
+
+debug("Check radio4");
+document.getElementById("radio4").checked = true;
+shouldBe("elementsWithIndeterminateStyle()", '[]');
+shouldBe("checkedElements()", '["radio4", "radio8"]');
+
+debug("Check radio9");
+document.getElementById("radio9").checked = true;
+shouldBe("elementsWithIndeterminateStyle()", '[]');
+shouldBe("checkedElements()", '["radio4", "radio9"]');
+
+debug("Uncheck radio4");
+document.getElementById("radio4").checked = false;
+shouldBe("elementsWithIndeterminateStyle()", '["radio1", "radio2", "radio3", "radio4", "radio5"]');
+shouldBe("checkedElements()", '["radio9"]');
+
+debug("Uncheck radio9");
+document.getElementById("radio9").checked = false;
+shouldBe("elementsWithIndeterminateStyle()", '["radio1", "radio2", "radio3", "radio4", "radio5", "radio6", "radio7", "radio8", "radio9", "radio10"]');
+shouldBe("checkedElements()", '[]');
+
+debug("Check radio1");
+document.getElementById("radio1").checked = true;
+shouldBe("elementsWithIndeterminateStyle()", '["radio6", "radio7", "radio8", "radio9", "radio10"]');
+shouldBe("checkedElements()", '["radio1"]');
+
+debug("Check radio2");
+document.getElementById("radio2").checked = true;
+shouldBe("elementsWithIndeterminateStyle()", '["radio6", "radio7", "radio8", "radio9", "radio10"]');
+shouldBe("checkedElements()", '["radio2"]');
+
+debug("Remove radio3 from its group");
+document.getElementById("radio3").name = "";
+shouldBe("elementsWithIndeterminateStyle()", '["radio3", "radio6", "radio7", "radio8", "radio9", "radio10"]');
+shouldBe("checkedElements()", '["radio2"]');
+
+debug("Remove radio6 from its group");
+document.getElementById("radio6").name = "";
+shouldBe("elementsWithIndeterminateStyle()", '["radio3", "radio6", "radio7", "radio8", "radio9", "radio10"]');
+shouldBe("checkedElements()", '["radio2"]');
+
+debug("Remove radio2 from its group");
+document.getElementById("radio2").name = "";
+shouldBe("elementsWithIndeterminateStyle()", '["radio1", "radio3", "radio4", "radio5", "radio6", "radio7", "radio8", "radio9", "radio10"]');
+shouldBe("checkedElements()", '["radio2"]');
+
+debug("Check radio7");
+document.getElementById("radio7").checked = true;
+shouldBe("elementsWithIndeterminateStyle()", '["radio1", "radio3", "radio4", "radio5", "radio6"]');
+shouldBe("checkedElements()", '["radio2", "radio7"]');
+
+debug("Check radio8");
+document.getElementById("radio8").checked = true;
+shouldBe("elementsWithIndeterminateStyle()", '["radio1", "radio3", "radio4", "radio5", "radio6"]');
+shouldBe("checkedElements()", '["radio2", "radio8"]');
+
+debug("Remove radio9 from its group");
+document.getElementById("radio9").name = "";
+shouldBe("elementsWithIndeterminateStyle()", '["radio1", "radio3", "radio4", "radio5", "radio6", "radio9"]');
+shouldBe("checkedElements()", '["radio2", "radio8"]');
+
+debug("Remove radio8 from its group");
+document.getElementById("radio8").name = "";
+shouldBe("elementsWithIndeterminateStyle()", '["radio1", "radio3", "radio4", "radio5", "radio6", "radio7", "radio9", "radio10"]');
+shouldBe("checkedElements()", '["radio2", "radio8"]');
+
+debug("Remove radio7 from its group");
+document.getElementById("radio7").name = "";
+shouldBe("elementsWithIndeterminateStyle()", '["radio1", "radio3", "radio4", "radio5", "radio6", "radio7", "radio9", "radio10"]');
+shouldBe("checkedElements()", '["radio2", "radio8"]');
+
+
+// Hide the elements to make the results prettier.
+document.getElementById("with-renderer").style.display = "none";
+</script>
+<script src=""
+</html>
Modified: trunk/LayoutTests/imported/w3c/ChangeLog (202196 => 202197)
--- trunk/LayoutTests/imported/w3c/ChangeLog 2016-06-18 03:33:19 UTC (rev 202196)
+++ trunk/LayoutTests/imported/w3c/ChangeLog 2016-06-18 05:53:28 UTC (rev 202197)
@@ -1,3 +1,13 @@
+2016-06-17 Benjamin Poulain <benja...@webkit.org>
+
+ :indeterminate pseudo-class should match radios whose group has no checked radio
+ https://bugs.webkit.org/show_bug.cgi?id=156270
+
+ Reviewed by Simon Fraser.
+
+ * web-platform-tests/html/semantics/selectors/pseudo-classes/indeterminate-expected.txt:
+ One more pass on official tests :)
+
2016-06-17 Youenn Fablet <youenn.fab...@crf.canon.fr>
CORS preflight with a non-200 response should be a preflight failure
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/selectors/pseudo-classes/indeterminate-expected.txt (202196 => 202197)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/selectors/pseudo-classes/indeterminate-expected.txt 2016-06-18 03:33:19 UTC (rev 202196)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/selectors/pseudo-classes/indeterminate-expected.txt 2016-06-18 05:53:28 UTC (rev 202197)
@@ -1,7 +1,7 @@
-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
-FAIL dynamically check a radio input in a radio button group assert_array_equals: lengths differ, expected 3 got 1
+PASS ':progress' matches <input>s radio buttons whose radio button group contains no checked input and <progress> elements without value attribute
+PASS dynamically check a radio input in a radio button group
FAIL click on radio4 which is in the indeterminate state assert_array_equals: lengths differ, expected 2 got 1
PASS adding a value to progress1 should put it in a determinate state
PASS removing progress2's value should put it in an indeterminate state
Modified: trunk/Source/WebCore/ChangeLog (202196 => 202197)
--- trunk/Source/WebCore/ChangeLog 2016-06-18 03:33:19 UTC (rev 202196)
+++ trunk/Source/WebCore/ChangeLog 2016-06-18 05:53:28 UTC (rev 202197)
@@ -1,3 +1,79 @@
+2016-06-17 Benjamin Poulain <benja...@webkit.org>
+
+ :indeterminate pseudo-class should match radios whose group has no checked radio
+ https://bugs.webkit.org/show_bug.cgi?id=156270
+
+ Reviewed by Simon Fraser.
+
+ The pseudo-class ":indeterminate" is supposed to match radio buttons
+ for which the entire group has no checked button.
+ Spec: https://html.spec.whatwg.org/#pseudo-classes:selector-indeterminate
+
+ The change is straightforward with one non-obvious choice:
+ I added matchesIndeterminatePseudoClass() in addition to shouldAppearIndeterminate().
+
+ The reason is shouldAppearIndeterminate() is used for styling and AX of elements
+ with an indeterminate states (check boxes and progress element). There is no such
+ UI for radio boxes.
+ I could have extended shouldAppearIndeterminate() to radio box
+ then filter out this case in RenderTheme. The problem is doing that would also requires
+ changes to the repaint logic to match :indeterminate. It seemed overkill to me to
+ change repaint() for a case that is never used in practice.
+
+ Tests: fast/css/pseudo-indeterminate-radio-buttons-basics.html
+ fast/css/pseudo-indeterminate-with-radio-buttons-style-invalidation.html
+ fast/selectors/detached-radio-button-checked-and-indeterminate-states.html
+ fast/selectors/pseudo-indeterminate-with-radio-buttons-style-update.html
+
+ * css/SelectorCheckerTestFunctions.h:
+ (WebCore::shouldAppearIndeterminate):
+ * dom/Element.cpp:
+ (WebCore::Element::matchesIndeterminatePseudoClass):
+ * dom/Element.h:
+ * dom/RadioButtonGroups.cpp:
+ (WebCore::RadioButtonGroup::setCheckedButton):
+ (WebCore::RadioButtonGroup::updateCheckedState):
+ (WebCore::RadioButtonGroup::remove):
+ (WebCore::RadioButtonGroup::setNeedsStyleRecalcForAllButtons):
+ (WebCore::RadioButtonGroups::hasCheckedButton):
+ * dom/RadioButtonGroups.h:
+ * html/CheckboxInputType.cpp:
+ (WebCore::CheckboxInputType::matchesIndeterminatePseudoClass):
+ (WebCore::CheckboxInputType::shouldAppearIndeterminate):
+ (WebCore::CheckboxInputType::supportsIndeterminateAppearance): Deleted.
+ * html/CheckboxInputType.h:
+ * html/HTMLInputElement.cpp:
+ (WebCore::HTMLInputElement::setChecked):
+ (WebCore::HTMLInputElement::matchesIndeterminatePseudoClass):
+ (WebCore::HTMLInputElement::shouldAppearIndeterminate):
+ (WebCore::HTMLInputElement::radioButtonGroups):
+ * html/HTMLInputElement.h:
+ * html/InputType.cpp:
+ (WebCore::InputType::matchesIndeterminatePseudoClass):
+ (WebCore::InputType::shouldAppearIndeterminate):
+ (WebCore::InputType::supportsIndeterminateAppearance): Deleted.
+ * html/InputType.h:
+ * html/RadioInputType.cpp:
+ (WebCore::RadioInputType::matchesIndeterminatePseudoClass):
+ (WebCore::RadioInputType::willDispatchClick): Deleted.
+ (WebCore::RadioInputType::didDispatchClick): Deleted.
+ (WebCore::RadioInputType::supportsIndeterminateAppearance): Deleted.
+ The iOS specific code is just plain wrong.
+ It was changing the indeterminate state of the input element.
+ The spec clearly says that state is only used by checkbox:
+ https://html.spec.whatwg.org/#dom-input-indeterminate
+
+ Moreover, the style update would not change the indeterminate state
+ of other buttons in the Button Group, which is just bizarre.
+ RenderThemeIOS does not make use of any of this with the current style.
+
+ * html/RadioInputType.h:
+ * style/StyleSharingResolver.cpp:
+ (WebCore::Style::SharingResolver::canShareStyleWithElement):
+ (WebCore::Style::canShareStyleWithControl): Deleted.
+ (WebCore::Style::SharingResolver::sharingCandidateHasIdenticalStyleAffectingAttributes): Deleted.
+ Style sharing is unified behind the selector matching which is neat.
+
2016-06-17 Commit Queue <commit-qu...@webkit.org>
Unreviewed, rolling out r202152.
Modified: trunk/Source/WebCore/css/SelectorChecker.cpp (202196 => 202197)
--- trunk/Source/WebCore/css/SelectorChecker.cpp 2016-06-18 03:33:19 UTC (rev 202196)
+++ trunk/Source/WebCore/css/SelectorChecker.cpp 2016-06-18 05:53:28 UTC (rev 202197)
@@ -983,7 +983,7 @@
case CSSSelector::PseudoClassChecked:
return isChecked(element);
case CSSSelector::PseudoClassIndeterminate:
- return shouldAppearIndeterminate(element);
+ return matchesIndeterminatePseudoClass(element);
case CSSSelector::PseudoClassRoot:
if (&element == element.document().documentElement())
return true;
Modified: trunk/Source/WebCore/css/SelectorCheckerTestFunctions.h (202196 => 202197)
--- trunk/Source/WebCore/css/SelectorCheckerTestFunctions.h 2016-06-18 03:33:19 UTC (rev 202196)
+++ trunk/Source/WebCore/css/SelectorCheckerTestFunctions.h 2016-06-18 05:53:28 UTC (rev 202197)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2014-2016 Apple Inc. All rights reserved.
* Copyright (C) 2014 Dhi Aurrahman <diorah...@rockybars.com>
*
* Redistribution and use in source and binary forms, with or without
@@ -221,9 +221,9 @@
return element.matchesReadWritePseudoClass();
}
-ALWAYS_INLINE bool shouldAppearIndeterminate(const Element& element)
+ALWAYS_INLINE bool matchesIndeterminatePseudoClass(const Element& element)
{
- return element.shouldAppearIndeterminate();
+ return element.matchesIndeterminatePseudoClass();
}
ALWAYS_INLINE bool scrollbarMatchesEnabledPseudoClass(const SelectorChecker::CheckingContext& context)
Modified: trunk/Source/WebCore/cssjit/SelectorCompiler.cpp (202196 => 202197)
--- trunk/Source/WebCore/cssjit/SelectorCompiler.cpp 2016-06-18 03:33:19 UTC (rev 202196)
+++ trunk/Source/WebCore/cssjit/SelectorCompiler.cpp 2016-06-18 05:53:28 UTC (rev 202197)
@@ -558,7 +558,7 @@
fragment.unoptimizedPseudoClasses.append(JSC::FunctionPtr(isInRange));
return FunctionType::SimpleSelectorChecker;
case CSSSelector::PseudoClassIndeterminate:
- fragment.unoptimizedPseudoClasses.append(JSC::FunctionPtr(shouldAppearIndeterminate));
+ fragment.unoptimizedPseudoClasses.append(JSC::FunctionPtr(matchesIndeterminatePseudoClass));
return FunctionType::SimpleSelectorChecker;
case CSSSelector::PseudoClassInvalid:
fragment.unoptimizedPseudoClasses.append(JSC::FunctionPtr(isInvalid));
Modified: trunk/Source/WebCore/dom/Element.cpp (202196 => 202197)
--- trunk/Source/WebCore/dom/Element.cpp 2016-06-18 03:33:19 UTC (rev 202196)
+++ trunk/Source/WebCore/dom/Element.cpp 2016-06-18 05:53:28 UTC (rev 202197)
@@ -4,7 +4,7 @@
* (C) 2001 Peter Kelly (p...@post.com)
* (C) 2001 Dirk Mueller (muel...@kde.org)
* (C) 2007 David Smith (catfish....@gmail.com)
- * Copyright (C) 2004-2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2004-2016 Apple Inc. All rights reserved.
* (C) 2007 Eric Seidel (e...@webkit.org)
*
* This library is free software; you can redistribute it and/or
@@ -2755,6 +2755,11 @@
return false;
}
+bool Element::matchesIndeterminatePseudoClass() const
+{
+ return shouldAppearIndeterminate();
+}
+
bool Element::matches(const String& selector, ExceptionCode& ec)
{
SelectorQuery* selectorQuery = document().selectorQueryForString(selector, ec);
Modified: trunk/Source/WebCore/dom/Element.h (202196 => 202197)
--- trunk/Source/WebCore/dom/Element.h 2016-06-18 03:33:19 UTC (rev 202196)
+++ trunk/Source/WebCore/dom/Element.h 2016-06-18 05:53:28 UTC (rev 202197)
@@ -3,7 +3,7 @@
* (C) 1999 Antti Koivisto (koivi...@kde.org)
* (C) 2001 Peter Kelly (p...@post.com)
* (C) 2001 Dirk Mueller (muel...@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2013, 2014, 2016 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -386,6 +386,7 @@
void didShadowTreeAwareChildrenChange();
virtual bool matchesReadWritePseudoClass() const;
+ virtual bool matchesIndeterminatePseudoClass() const;
bool matches(const String& selectors, ExceptionCode&);
Element* closest(const String& selectors, ExceptionCode&);
virtual bool shouldAppearIndeterminate() const;
Modified: trunk/Source/WebCore/dom/RadioButtonGroups.cpp (202196 => 202197)
--- trunk/Source/WebCore/dom/RadioButtonGroups.cpp 2016-06-18 03:33:19 UTC (rev 202196)
+++ trunk/Source/WebCore/dom/RadioButtonGroups.cpp 2016-06-18 05:53:28 UTC (rev 202197)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 2009, 2016 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -42,8 +42,10 @@
Vector<HTMLInputElement*> members() const;
private:
+ void setNeedsStyleRecalcForAllButtons();
void updateValidityForAllButtons();
bool isValid() const;
+ void changeCheckedButton(HTMLInputElement*);
void setCheckedButton(HTMLInputElement*);
HashSet<HTMLInputElement*> m_members;
@@ -75,6 +77,12 @@
HTMLInputElement* oldCheckedButton = m_checkedButton;
if (oldCheckedButton == button)
return;
+
+ bool hadCheckedButton = m_checkedButton;
+ bool willHaveCheckedButton = button;
+ if (hadCheckedButton != willHaveCheckedButton)
+ setNeedsStyleRecalcForAllButtons();
+
m_checkedButton = button;
if (oldCheckedButton)
oldCheckedButton->setChecked(false);
@@ -110,7 +118,7 @@
setCheckedButton(button);
else {
if (m_checkedButton == button)
- m_checkedButton = nullptr;
+ setCheckedButton(nullptr);
}
if (wasValid != isValid())
updateValidityForAllButtons();
@@ -137,14 +145,20 @@
HashSet<HTMLInputElement*>::iterator it = m_members.find(button);
if (it == m_members.end())
return;
+
bool wasValid = isValid();
m_members.remove(it);
if (button->isRequired()) {
ASSERT(m_requiredCount);
--m_requiredCount;
}
- if (m_checkedButton == button)
- m_checkedButton = nullptr;
+ if (m_checkedButton) {
+ button->setNeedsStyleRecalc();
+ if (m_checkedButton == button) {
+ m_checkedButton = nullptr;
+ setNeedsStyleRecalcForAllButtons();
+ }
+ }
if (m_members.isEmpty()) {
ASSERT(!m_requiredCount);
@@ -158,6 +172,14 @@
}
}
+void RadioButtonGroup::setNeedsStyleRecalcForAllButtons()
+{
+ for (auto& button : m_members) {
+ ASSERT(button->isRadioButton());
+ button->setNeedsStyleRecalc();
+ }
+}
+
void RadioButtonGroup::updateValidityForAllButtons()
{
for (auto& button : m_members) {
@@ -250,6 +272,17 @@
return group ? group->checkedButton() : nullptr;
}
+bool RadioButtonGroups::hasCheckedButton(const HTMLInputElement* element) const
+{
+ ASSERT(element->isRadioButton());
+ const AtomicString& name = element->name();
+ if (name.isEmpty() || !m_nameToGroupMap)
+ return element->checked();
+
+ const RadioButtonGroup* group = m_nameToGroupMap->get(name.impl());
+ return group->checkedButton();
+}
+
bool RadioButtonGroups::isInRequiredGroup(HTMLInputElement* element) const
{
ASSERT(element->isRadioButton());
Modified: trunk/Source/WebCore/dom/RadioButtonGroups.h (202196 => 202197)
--- trunk/Source/WebCore/dom/RadioButtonGroups.h 2016-06-18 03:33:19 UTC (rev 202196)
+++ trunk/Source/WebCore/dom/RadioButtonGroups.h 2016-06-18 05:53:28 UTC (rev 202197)
@@ -39,6 +39,7 @@
void requiredAttributeChanged(HTMLInputElement*);
void removeButton(HTMLInputElement*);
HTMLInputElement* checkedButtonForGroup(const AtomicString& groupName) const;
+ bool hasCheckedButton(const HTMLInputElement*) const;
bool isInRequiredGroup(HTMLInputElement*) const;
Vector<HTMLInputElement*> groupMembers(const HTMLInputElement&) const;
Modified: trunk/Source/WebCore/html/CheckboxInputType.cpp (202196 => 202197)
--- trunk/Source/WebCore/html/CheckboxInputType.cpp 2016-06-18 03:33:19 UTC (rev 202196)
+++ trunk/Source/WebCore/html/CheckboxInputType.cpp 2016-06-18 05:53:28 UTC (rev 202197)
@@ -92,9 +92,14 @@
return true;
}
-bool CheckboxInputType::supportsIndeterminateAppearance() const
+bool CheckboxInputType::matchesIndeterminatePseudoClass() const
{
- return true;
+ return shouldAppearIndeterminate();
}
+bool CheckboxInputType::shouldAppearIndeterminate() const
+{
+ return element().indeterminate();
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/html/CheckboxInputType.h (202196 => 202197)
--- trunk/Source/WebCore/html/CheckboxInputType.h 2016-06-18 03:33:19 UTC (rev 202196)
+++ trunk/Source/WebCore/html/CheckboxInputType.h 2016-06-18 05:53:28 UTC (rev 202197)
@@ -47,7 +47,8 @@
void willDispatchClick(InputElementClickState&) override;
void didDispatchClick(Event*, const InputElementClickState&) override;
bool isCheckbox() const override;
- bool supportsIndeterminateAppearance() const override;
+ bool matchesIndeterminatePseudoClass() const override;
+ bool shouldAppearIndeterminate() const override;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/html/HTMLInputElement.cpp (202196 => 202197)
--- trunk/Source/WebCore/html/HTMLInputElement.cpp 2016-06-18 03:33:19 UTC (rev 202196)
+++ trunk/Source/WebCore/html/HTMLInputElement.cpp 2016-06-18 05:53:28 UTC (rev 202197)
@@ -861,7 +861,7 @@
setNeedsStyleRecalc();
if (RadioButtonGroups* buttons = radioButtonGroups())
- buttons->updateCheckedState(this);
+ buttons->updateCheckedState(this);
if (renderer() && renderer()->style().hasAppearance())
renderer()->theme().stateChanged(*renderer(), ControlStates::CheckedState);
updateValidity();
@@ -1763,9 +1763,21 @@
return m_inputType->defaultToolTip();
}
+bool HTMLInputElement::matchesIndeterminatePseudoClass() const
+{
+ // For input elements, matchesIndeterminatePseudoClass()
+ // is not equivalent to shouldAppearIndeterminate() because of radio button.
+ //
+ // A group of radio button without any checked button is indeterminate
+ // for the :indeterminate selector. On the other hand, RenderTheme
+ // currently only supports single element being indeterminate.
+ // Because of this, radio is indetermindate for CSS but not for render theme.
+ return m_inputType->matchesIndeterminatePseudoClass();
+}
+
bool HTMLInputElement::shouldAppearIndeterminate() const
{
- return m_inputType->supportsIndeterminateAppearance() && indeterminate();
+ return m_inputType->shouldAppearIndeterminate();
}
#if ENABLE(MEDIA_CAPTURE)
@@ -1801,12 +1813,12 @@
RadioButtonGroups* HTMLInputElement::radioButtonGroups() const
{
if (!isRadioButton())
- return 0;
+ return nullptr;
if (HTMLFormElement* formElement = form())
return &formElement->radioButtonGroups();
if (inDocument())
return &document().formController().radioButtonGroups();
- return 0;
+ return nullptr;
}
inline void HTMLInputElement::addToRadioButtonGroup()
Modified: trunk/Source/WebCore/html/HTMLInputElement.h (202196 => 202197)
--- trunk/Source/WebCore/html/HTMLInputElement.h 2016-06-18 03:33:19 UTC (rev 202196)
+++ trunk/Source/WebCore/html/HTMLInputElement.h 2016-06-18 05:53:28 UTC (rev 202197)
@@ -2,7 +2,7 @@
* Copyright (C) 1999 Lars Knoll (kn...@kde.org)
* (C) 1999 Antti Koivisto (koivi...@kde.org)
* (C) 2000 Dirk Mueller (muel...@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2010, 2016 Apple Inc. All rights reserved.
* Copyright (C) 2012 Samsung Electronics. All rights reserved.
*
* This library is free software; you can redistribute it and/or
@@ -162,6 +162,7 @@
void setIndeterminate(bool);
// shouldAppearChecked is used by the rendering tree/CSS while checked() is used by JS to determine checked state
bool shouldAppearChecked() const;
+ bool matchesIndeterminatePseudoClass() const final;
bool shouldAppearIndeterminate() const final;
unsigned size() const;
@@ -274,6 +275,8 @@
Vector<HTMLInputElement*> radioButtonGroup() const;
HTMLInputElement* checkedRadioButtonForGroup() const;
bool isInRequiredRadioButtonGroup();
+ // Returns null if this isn't associated with any radio button group.
+ RadioButtonGroups* radioButtonGroups() const;
// Functions for InputType classes.
void setValueInternal(const String&, TextFieldEventBehavior);
@@ -422,8 +425,6 @@
void maxLengthAttributeChanged(const AtomicString& newValue);
void updateValueIfNeeded();
- // Returns null if this isn't associated with any radio button group.
- RadioButtonGroups* radioButtonGroups() const;
void addToRadioButtonGroup();
void removeFromRadioButtonGroup();
Modified: trunk/Source/WebCore/html/InputType.cpp (202196 => 202197)
--- trunk/Source/WebCore/html/InputType.cpp 2016-06-18 03:33:19 UTC (rev 202196)
+++ trunk/Source/WebCore/html/InputType.cpp 2016-06-18 05:53:28 UTC (rev 202197)
@@ -966,11 +966,16 @@
}
#endif
-bool InputType::supportsIndeterminateAppearance() const
+bool InputType::matchesIndeterminatePseudoClass() const
{
return false;
}
+bool InputType::shouldAppearIndeterminate() const
+{
+ return false;
+}
+
bool InputType::supportsSelectionAPI() const
{
return false;
Modified: trunk/Source/WebCore/html/InputType.h (202196 => 202197)
--- trunk/Source/WebCore/html/InputType.h 2016-06-18 03:33:19 UTC (rev 202196)
+++ trunk/Source/WebCore/html/InputType.h 2016-06-18 05:53:28 UTC (rev 202197)
@@ -267,7 +267,8 @@
virtual void capsLockStateMayHaveChanged();
virtual void updateAutoFillButton();
virtual String defaultToolTip() const;
- virtual bool supportsIndeterminateAppearance() const;
+ virtual bool matchesIndeterminatePseudoClass() const;
+ virtual bool shouldAppearIndeterminate() const;
virtual bool supportsSelectionAPI() const;
virtual Color valueAsColor() const;
virtual void selectColor(const Color&);
Modified: trunk/Source/WebCore/html/RadioInputType.cpp (202196 => 202197)
--- trunk/Source/WebCore/html/RadioInputType.cpp 2016-06-18 03:33:19 UTC (rev 202196)
+++ trunk/Source/WebCore/html/RadioInputType.cpp 2016-06-18 05:53:28 UTC (rev 202197)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2005, 2011, 2016 Apple Inc. All rights reserved.
* Copyright (C) 2010 Google Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
@@ -151,13 +151,6 @@
state.checked = element().checked();
state.checkedRadioButton = element().checkedRadioButtonForGroup();
-#if PLATFORM(IOS)
- state.indeterminate = element().indeterminate();
-
- if (element().indeterminate())
- element().setIndeterminate(false);
-#endif
-
element().setChecked(true, DispatchChangeEvent);
}
@@ -173,11 +166,6 @@
&& checkedRadioButton->name() == element().name()) {
checkedRadioButton->setChecked(true);
}
-
-#if PLATFORM(IOS)
- element().setIndeterminate(state.indeterminate);
-#endif
-
}
// The work we did in willDispatchClick was default handling.
@@ -189,13 +177,12 @@
return true;
}
-bool RadioInputType::supportsIndeterminateAppearance() const
+bool RadioInputType::matchesIndeterminatePseudoClass() const
{
-#if PLATFORM(IOS)
- return true;
-#else
- return false;
-#endif
+ const HTMLInputElement& element = this->element();
+ if (const RadioButtonGroups* radioButtonGroups = element.radioButtonGroups())
+ return !radioButtonGroups->hasCheckedButton(&element);
+ return !element.checked();
}
} // namespace WebCore
Modified: trunk/Source/WebCore/html/RadioInputType.h (202196 => 202197)
--- trunk/Source/WebCore/html/RadioInputType.h 2016-06-18 03:33:19 UTC (rev 202196)
+++ trunk/Source/WebCore/html/RadioInputType.h 2016-06-18 05:53:28 UTC (rev 202197)
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2010 Google Inc. All rights reserved.
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -51,7 +52,7 @@
void willDispatchClick(InputElementClickState&) override;
void didDispatchClick(Event*, const InputElementClickState&) override;
bool isRadioButton() const override;
- bool supportsIndeterminateAppearance() const override;
+ bool matchesIndeterminatePseudoClass() const override;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/style/StyleSharingResolver.cpp (202196 => 202197)
--- trunk/Source/WebCore/style/StyleSharingResolver.cpp 2016-06-18 03:33:19 UTC (rev 202196)
+++ trunk/Source/WebCore/style/StyleSharingResolver.cpp 2016-06-18 05:53:28 UTC (rev 202197)
@@ -179,8 +179,6 @@
return false;
if (thisInputElement.shouldAppearChecked() != otherInputElement.shouldAppearChecked())
return false;
- if (thisInputElement.shouldAppearIndeterminate() != otherInputElement.shouldAppearIndeterminate())
- return false;
if (thisInputElement.isRequired() != otherInputElement.isRequired())
return false;
@@ -283,6 +281,9 @@
if (element.matchesInvalidPseudoClass() != element.matchesValidPseudoClass())
return false;
+ if (candidateElement.matchesIndeterminatePseudoClass() != element.matchesIndeterminatePseudoClass())
+ return false;
+
if (element.shadowRoot() && !element.shadowRoot()->styleResolver().ruleSets().authorStyle()->hostPseudoClassRules().isEmpty())
return false;
@@ -329,11 +330,6 @@
if (const_cast<StyledElement&>(element).presentationAttributeStyle() != const_cast<StyledElement&>(sharingCandidate).presentationAttributeStyle())
return false;
- if (element.hasTagName(HTMLNames::progressTag)) {
- if (element.shouldAppearIndeterminate() != sharingCandidate.shouldAppearIndeterminate())
- return false;
- }
-
return true;
}