Implement :valid and :invalid matching for the fieldset element
authorbenjamin@webkit.org <benjamin@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 17 Nov 2014 07:01:21 +0000 (07:01 +0000)
committerbenjamin@webkit.org <benjamin@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 17 Nov 2014 07:01:21 +0000 (07:01 +0000)
https://bugs.webkit.org/show_bug.cgi?id=138769

Reviewed by Darin Adler.

Source/WebCore:

In the latest HTML spec, the pseudo classes :valid and :invalid match
a fieldset element based on its descendants:
    https://html.spec.whatwg.org/#selector-valid
    https://html.spec.whatwg.org/#selector-invalid

This patch adds that behavior.

There are two key problems to solve with these pseudo classes on fieldset:
-Efficient matching.
-Style invalidation when any of the descendant changes.

To implement the style invalidation, I have modified HTMLFormControlElement
to notify its ancestor when its state changes.

The first change is making the state fully internal to HTMLFormControlElement,
we do not want subclass to be able to change the behavior and forget to update
the ancestors.

To achieve that encapsulation, the interface was changed a bit:
-Neither willValidate() nor isValidFormControlElement() inherit from Element.
 Instead, willValidate() is the implementation of FormAssociatedElement's interface
 and it is final. The method isValidFormControlElement() becomes completely internal
 to HTMLFormControlElement.
-Since willValidate() should no longer be re-implemented by subclass, the elements
 that were depending on it have been migrated to recalcWillValidate() to set
 the initial state as needed.

With the validity state fully encapsulated in HTMLFormControlElement, all I need
is a way to communicate that information to HTMLFieldSetElement ancestors.
This is done in two cases:
-The validity state changes.
-The tree changes in a way that would make the input element not a descendant
 of a HTMLFieldSetElement.

The invalidation is simply done by walking up the ancestors and adding the current
element to a "validity dependency list" on each HTMLFieldSetElement.

Tests: fast/css/pseudo-invalid-fieldset-invalidation-optimization.html
       fast/css/pseudo-invalid-fieldset-style-sharing.html
       fast/css/pseudo-invalid-fieldset.html
       fast/css/pseudo-valid-fieldset-invalidation-optimization.html
       fast/css/pseudo-valid-fieldset-style-sharing.html
       fast/css/pseudo-valid-fieldset.html
       fast/selectors/invalid-fieldset-style-update-1.html
       fast/selectors/invalid-fieldset-style-update-2.html
       fast/selectors/invalid-fieldset-style-update-3.html
       fast/selectors/invalid-fieldset-style-update-4.html
       fast/selectors/invalid-fieldset-style-update-5.html
       fast/selectors/valid-fieldset-style-update-1.html
       fast/selectors/valid-fieldset-style-update-2.html
       fast/selectors/valid-fieldset-style-update-3.html
       fast/selectors/valid-fieldset-style-update-4.html
       fast/selectors/valid-fieldset-style-update-5.html

* css/SelectorCheckerTestFunctions.h:
(WebCore::isInRange):
(WebCore::isOutOfRange):
(WebCore::isInvalid):
(WebCore::isValid):
The hack "ContainsValidityStyleRules" is in the way of correct styling
of FieldSet and Form.
It is not the right way to get stylesheet properties anyway.

* css/StyleResolver.cpp:
(WebCore::StyleResolver::canShareStyleWithControl):
Make sure style sharing does not incorrectly share style for fieldset elements.

* dom/Document.cpp:
(WebCore::Document::Document):
* dom/Document.h:
(WebCore::Document::containsValidityStyleRules): Deleted.
(WebCore::Document::setContainsValidityStyleRules): Deleted.
* dom/Element.h:
(WebCore::Element::matchesValidPseudoClass):
(WebCore::Element::matchesInvalidPseudoClass):
(WebCore::Element::willValidate): Deleted.
(WebCore::Element::isValidFormControlElement): Deleted.
* html/FormAssociatedElement.cpp:
(WebCore::FormAssociatedElement::customError):
* html/FormAssociatedElement.h:

* html/HTMLFieldSetElement.cpp:
(WebCore::HTMLFieldSetElement::matchesValidPseudoClass):
(WebCore::HTMLFieldSetElement::matchesInvalidPseudoClass):
(WebCore::HTMLFieldSetElement::addInvalidDescendant):
(WebCore::HTMLFieldSetElement::removeInvalidDescendant):
Each HTMLFormControlElement that has constraint validation adds or removes
itself from its HTMLFieldSetElement ancestors.

It should be possible to just keep track of a count instead of a HashSet.
I decided to got with the HashSet to make the code more robust and easier
to debug. A few assertions ensure that the HashSet is actually used as a counter.

* html/HTMLFieldSetElement.h:
* html/HTMLFormControlElement.cpp:
(WebCore::addInvalidElementToAncestorFromInsertionPoint):
(WebCore::removeInvalidElementToAncestorFromInsertionPoint):

(WebCore::HTMLFormControlElement::insertedInto):
(WebCore::HTMLFormControlElement::removedFrom):
One tricky part of those two functions is that we cannot use
matchesValidPseudoClass() or matchesInvalidPseudoClass().

The reason is that HTMLFieldSetElement is a subclass of HTMLFormControlElement
and it has its own definition of what Valid and Invalid mean when matching selectors.

In HTMLFormControlElement, we must use the internal state,
willValidate() and isValidFormControlElement() must be used directly.

(WebCore::HTMLFormControlElement::matchesValidPseudoClass):
(WebCore::HTMLFormControlElement::matchesInvalidPseudoClass):
(WebCore::HTMLFormControlElement::willValidate):
(WebCore::addInvalidElementToAncestors):
(WebCore::removeInvalidElementFromAncestors):
(WebCore::HTMLFormControlElement::setNeedsWillValidateCheck):
(WebCore::HTMLFormControlElement::setNeedsValidityCheck):
(WebCore::HTMLFormControlElement::isValidFormControlElement): Deleted.
* html/HTMLFormControlElement.h:
(WebCore::HTMLFormControlElement::isValidFormControlElement):
* html/HTMLKeygenElement.h:
* html/HTMLObjectElement.h:
* html/HTMLOutputElement.h:

LayoutTests:

There are many ways to change the validation state of a submittable element.
I included a series of test trying to exercises as many combination
as possible.

* fast/css/pseudo-valid-unapplied-expected.txt:
* fast/css/pseudo-valid-unapplied.html:
This test was checking that :valid and :invalid are not applied
to fieldset. Such results are incorrect with the latest specification.

* fast/css/pseudo-invalid-fieldset-expected.html: Added.
* fast/css/pseudo-invalid-fieldset-invalidation-optimization-expected.txt: Added.
* fast/css/pseudo-invalid-fieldset-invalidation-optimization.html: Added.
* fast/css/pseudo-invalid-fieldset-style-sharing-expected.html: Added.
* fast/css/pseudo-invalid-fieldset-style-sharing.html: Added.
* fast/css/pseudo-invalid-fieldset.html: Added.
* fast/css/pseudo-valid-fieldset-expected.html: Added.
* fast/css/pseudo-valid-fieldset-invalidation-optimization-expected.txt: Added.
* fast/css/pseudo-valid-fieldset-invalidation-optimization.html: Added.
* fast/css/pseudo-valid-fieldset-style-sharing-expected.html: Added.
* fast/css/pseudo-valid-fieldset-style-sharing.html: Added.
* fast/css/pseudo-valid-fieldset.html: Added.
* fast/selectors/invalid-fieldset-style-update-1-expected.txt: Added.
* fast/selectors/invalid-fieldset-style-update-1.html: Added.
* fast/selectors/invalid-fieldset-style-update-2-expected.txt: Added.
* fast/selectors/invalid-fieldset-style-update-2.html: Added.
* fast/selectors/invalid-fieldset-style-update-3-expected.txt: Added.
* fast/selectors/invalid-fieldset-style-update-3.html: Added.
* fast/selectors/invalid-fieldset-style-update-4-expected.txt: Added.
* fast/selectors/invalid-fieldset-style-update-4.html: Added.
* fast/selectors/invalid-fieldset-style-update-5-expected.txt: Added.
* fast/selectors/invalid-fieldset-style-update-5.html: Added.
* fast/selectors/valid-fieldset-style-update-1-expected.txt: Added.
* fast/selectors/valid-fieldset-style-update-1.html: Added.
* fast/selectors/valid-fieldset-style-update-2-expected.txt: Added.
* fast/selectors/valid-fieldset-style-update-2.html: Added.
* fast/selectors/valid-fieldset-style-update-3-expected.txt: Added.
* fast/selectors/valid-fieldset-style-update-3.html: Added.
* fast/selectors/valid-fieldset-style-update-4-expected.txt: Added.
* fast/selectors/valid-fieldset-style-update-4.html: Added.
* fast/selectors/valid-fieldset-style-update-5-expected.txt: Added.
* fast/selectors/valid-fieldset-style-update-5.html: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@176174 268f45cc-cd09-0410-ab3c-d52691b4dbfc

50 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/css/pseudo-invalid-fieldset-expected.html [new file with mode: 0644]
LayoutTests/fast/css/pseudo-invalid-fieldset-invalidation-optimization-expected.txt [new file with mode: 0644]
LayoutTests/fast/css/pseudo-invalid-fieldset-invalidation-optimization.html [new file with mode: 0644]
LayoutTests/fast/css/pseudo-invalid-fieldset-style-sharing-expected.html [new file with mode: 0644]
LayoutTests/fast/css/pseudo-invalid-fieldset-style-sharing.html [new file with mode: 0644]
LayoutTests/fast/css/pseudo-invalid-fieldset.html [new file with mode: 0644]
LayoutTests/fast/css/pseudo-valid-fieldset-expected.html [new file with mode: 0644]
LayoutTests/fast/css/pseudo-valid-fieldset-invalidation-optimization-expected.txt [new file with mode: 0644]
LayoutTests/fast/css/pseudo-valid-fieldset-invalidation-optimization.html [new file with mode: 0644]
LayoutTests/fast/css/pseudo-valid-fieldset-style-sharing-expected.html [new file with mode: 0644]
LayoutTests/fast/css/pseudo-valid-fieldset-style-sharing.html [new file with mode: 0644]
LayoutTests/fast/css/pseudo-valid-fieldset.html [new file with mode: 0644]
LayoutTests/fast/css/pseudo-valid-unapplied-expected.txt
LayoutTests/fast/css/pseudo-valid-unapplied.html
LayoutTests/fast/selectors/invalid-fieldset-style-update-1-expected.txt [new file with mode: 0644]
LayoutTests/fast/selectors/invalid-fieldset-style-update-1.html [new file with mode: 0644]
LayoutTests/fast/selectors/invalid-fieldset-style-update-2-expected.txt [new file with mode: 0644]
LayoutTests/fast/selectors/invalid-fieldset-style-update-2.html [new file with mode: 0644]
LayoutTests/fast/selectors/invalid-fieldset-style-update-3-expected.txt [new file with mode: 0644]
LayoutTests/fast/selectors/invalid-fieldset-style-update-3.html [new file with mode: 0644]
LayoutTests/fast/selectors/invalid-fieldset-style-update-4-expected.txt [new file with mode: 0644]
LayoutTests/fast/selectors/invalid-fieldset-style-update-4.html [new file with mode: 0644]
LayoutTests/fast/selectors/invalid-fieldset-style-update-5-expected.txt [new file with mode: 0644]
LayoutTests/fast/selectors/invalid-fieldset-style-update-5.html [new file with mode: 0644]
LayoutTests/fast/selectors/valid-fieldset-style-update-1-expected.txt [new file with mode: 0644]
LayoutTests/fast/selectors/valid-fieldset-style-update-1.html [new file with mode: 0644]
LayoutTests/fast/selectors/valid-fieldset-style-update-2-expected.txt [new file with mode: 0644]
LayoutTests/fast/selectors/valid-fieldset-style-update-2.html [new file with mode: 0644]
LayoutTests/fast/selectors/valid-fieldset-style-update-3-expected.txt [new file with mode: 0644]
LayoutTests/fast/selectors/valid-fieldset-style-update-3.html [new file with mode: 0644]
LayoutTests/fast/selectors/valid-fieldset-style-update-4-expected.txt [new file with mode: 0644]
LayoutTests/fast/selectors/valid-fieldset-style-update-4.html [new file with mode: 0644]
LayoutTests/fast/selectors/valid-fieldset-style-update-5-expected.txt [new file with mode: 0644]
LayoutTests/fast/selectors/valid-fieldset-style-update-5.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/css/SelectorCheckerTestFunctions.h
Source/WebCore/css/StyleResolver.cpp
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h
Source/WebCore/dom/Element.h
Source/WebCore/html/FormAssociatedElement.cpp
Source/WebCore/html/FormAssociatedElement.h
Source/WebCore/html/HTMLFieldSetElement.cpp
Source/WebCore/html/HTMLFieldSetElement.h
Source/WebCore/html/HTMLFormControlElement.cpp
Source/WebCore/html/HTMLFormControlElement.h
Source/WebCore/html/HTMLKeygenElement.h
Source/WebCore/html/HTMLObjectElement.h
Source/WebCore/html/HTMLOutputElement.h

index c46c6c6..b57555b 100644 (file)
@@ -1,3 +1,52 @@
+2014-11-16  Benjamin Poulain  <benjamin@webkit.org>
+
+        Implement :valid and :invalid matching for the fieldset element
+        https://bugs.webkit.org/show_bug.cgi?id=138769
+
+        Reviewed by Darin Adler.
+
+        There are many ways to change the validation state of a submittable element.
+        I included a series of test trying to exercises as many combination
+        as possible.
+
+        * fast/css/pseudo-valid-unapplied-expected.txt:
+        * fast/css/pseudo-valid-unapplied.html:
+        This test was checking that :valid and :invalid are not applied
+        to fieldset. Such results are incorrect with the latest specification.
+
+        * fast/css/pseudo-invalid-fieldset-expected.html: Added.
+        * fast/css/pseudo-invalid-fieldset-invalidation-optimization-expected.txt: Added.
+        * fast/css/pseudo-invalid-fieldset-invalidation-optimization.html: Added.
+        * fast/css/pseudo-invalid-fieldset-style-sharing-expected.html: Added.
+        * fast/css/pseudo-invalid-fieldset-style-sharing.html: Added.
+        * fast/css/pseudo-invalid-fieldset.html: Added.
+        * fast/css/pseudo-valid-fieldset-expected.html: Added.
+        * fast/css/pseudo-valid-fieldset-invalidation-optimization-expected.txt: Added.
+        * fast/css/pseudo-valid-fieldset-invalidation-optimization.html: Added.
+        * fast/css/pseudo-valid-fieldset-style-sharing-expected.html: Added.
+        * fast/css/pseudo-valid-fieldset-style-sharing.html: Added.
+        * fast/css/pseudo-valid-fieldset.html: Added.
+        * fast/selectors/invalid-fieldset-style-update-1-expected.txt: Added.
+        * fast/selectors/invalid-fieldset-style-update-1.html: Added.
+        * fast/selectors/invalid-fieldset-style-update-2-expected.txt: Added.
+        * fast/selectors/invalid-fieldset-style-update-2.html: Added.
+        * fast/selectors/invalid-fieldset-style-update-3-expected.txt: Added.
+        * fast/selectors/invalid-fieldset-style-update-3.html: Added.
+        * fast/selectors/invalid-fieldset-style-update-4-expected.txt: Added.
+        * fast/selectors/invalid-fieldset-style-update-4.html: Added.
+        * fast/selectors/invalid-fieldset-style-update-5-expected.txt: Added.
+        * fast/selectors/invalid-fieldset-style-update-5.html: Added.
+        * fast/selectors/valid-fieldset-style-update-1-expected.txt: Added.
+        * fast/selectors/valid-fieldset-style-update-1.html: Added.
+        * fast/selectors/valid-fieldset-style-update-2-expected.txt: Added.
+        * fast/selectors/valid-fieldset-style-update-2.html: Added.
+        * fast/selectors/valid-fieldset-style-update-3-expected.txt: Added.
+        * fast/selectors/valid-fieldset-style-update-3.html: Added.
+        * fast/selectors/valid-fieldset-style-update-4-expected.txt: Added.
+        * fast/selectors/valid-fieldset-style-update-4.html: Added.
+        * fast/selectors/valid-fieldset-style-update-5-expected.txt: Added.
+        * fast/selectors/valid-fieldset-style-update-5.html: Added.
+
 2014-11-16  Chris Dumez  <cdumez@apple.com>
 
         Crash when setting 'order' CSS property to a calculated value
diff --git a/LayoutTests/fast/css/pseudo-invalid-fieldset-expected.html b/LayoutTests/fast/css/pseudo-invalid-fieldset-expected.html
new file mode 100644 (file)
index 0000000..f041713
--- /dev/null
@@ -0,0 +1,175 @@
+<!doctype html>
+<html>
+<head>
+    <style>
+        /* Pack them to fit everything in 800*600 */
+        fieldset {
+            padding: 5px;
+            width: 100px;
+            float: left;
+        }
+    </style>
+</head>
+<body style="color: green;">
+    <p style="color: green;">Test the styling with the pseudo class :valid with the &lt;fieldset&gt; element.</p>
+
+    <!-- Fieldset by itself. -->
+    <fieldset style="color: green;">Text</fieldset>
+
+    <!-- Fieldset with a direct child inputs without any requirements. -->
+    <fieldset style="color: green;">
+        Text
+        <input style="color: green;">
+        <input style="color: green;" value>
+        <input style="color: green;" value="text">
+    </fieldset>
+
+    <!-- Fieldset with an indirect direct child inputs without any requirements. -->
+    <fieldset style="color: green;">
+        Text
+        <div style="color: green;">
+            Text
+            <div style="color: green;">
+                Text
+                <input style="color: green;">
+                <input style="color: green;" value>
+                <input style="color: green;" value="text">
+            </div>
+        </div>
+    </fieldset>
+
+    <!-- Fieldset with a direct child inputs with unsatisfied requirements. -->
+    <fieldset style="background-color: red;">
+        <input style="background-color: red;" required>
+        <input style="background-color: red;" required value>
+        <input style="background-color: red;" required value="">
+    </fieldset>
+
+    <!-- Fieldset with an indirect direct child inputs with unsatisfied requirements. -->
+    <fieldset style="background-color: red;">
+        Text
+        <div style="color: green;">
+            Text
+            <div style="color: green;">
+                Text
+                <input style="background-color: red;" required>
+                <input style="background-color: red;" required value>
+                <input style="background-color: red;" required value="">
+            </div>
+        </div>
+    </fieldset>
+
+    <!-- Fieldset with a direct child inputs with satisfied requirements. -->
+    <fieldset style="color: green;">
+        <input style="color: green;" required value="text">
+    </fieldset>
+
+    <!-- Fieldset with an indirect direct child inputs with satisfied requirements. -->
+    <fieldset style="color: green;">
+        Text
+        <div style="color: green;">
+            Text
+            <div style="color: green;">
+                Text
+                <input style="color: green;" required value="text">
+            </div>
+        </div>
+    </fieldset>
+
+    <!-- Fieldset with a direct child inputs with a mix of satisfied and unsatisfied requirements. -->
+    <fieldset style="background-color: red;">
+        <input style="background-color: red;" required>
+        <input style="background-color: red;" required value>
+        <input style="background-color: red;" required value="">
+        <input style="color: green;" required value="text">
+    </fieldset>
+
+    <!-- Fieldset with an indirect direct child inputs with satisfied and unsatisfied requirements. -->
+    <fieldset style="background-color: red;">
+        Text
+        <div style="color: green;">
+            Text
+            <div style="color: green;">
+                Text
+                <input style="background-color: red;" required>
+                <input style="background-color: red;" required value>
+                <input style="background-color: red;" required value="">
+                <input style="color: green;" required value="text">
+            </div>
+        </div>
+    </fieldset>
+
+    <!-- The cases above repeated with multiple nested fieldset -->
+    <fieldset style="color: green;">
+        <div style="color: green;">
+            <fieldset style="color: green;">
+                <fieldset style="color: green;">
+                    Text
+                    <div style="color: green;">
+                        Text
+                        <div style="color: green;">
+                            Text
+                            <input style="color: green;">
+                            <input style="color: green;" value>
+                            <input style="color: green;" value="text">
+                        </div>
+                    </div>
+                </fieldset>
+            </fieldset>
+        </div>
+    </fieldset>
+    <fieldset style="background-color: red;">
+        <div style="color: green;">
+            <fieldset style="background-color: red;">
+                <fieldset style="background-color: red;">
+                    Text
+                    <div style="color: green;">
+                        Text
+                        <div style="color: green;">
+                            Text
+                            <input style="background-color: red;" required>
+                            <input style="background-color: red;" required value>
+                            <input style="background-color: red;" required value="">
+                        </div>
+                    </div>
+                </fieldset>
+            </fieldset>
+        </div>
+    </fieldset>
+    <fieldset style="color: green;">
+        <div style="color: green;">
+            <fieldset style="color: green;">
+                <fieldset style="color: green;">
+                    Text
+                    <div style="color: green;">
+                        Text
+                        <div style="color: green;">
+                            Text
+                            <input style="color: green;" required value="text">
+                        </div>
+                    </div>
+                </fieldset>
+            </fieldset>
+        </div>
+    </fieldset>
+    <fieldset style="background-color: red;">
+        <div style="color: green;">
+            <fieldset style="background-color: red;">
+                <fieldset style="background-color: red;">
+                    Text
+                    <div style="color: green;">
+                        Text
+                        <div style="color: green;">
+                            Text
+                            <input style="background-color: red;" required>
+                            <input style="background-color: red;" required value>
+                            <input style="background-color: red;" required value="">
+                            <input style="color: green;" required value="text">
+                        </div>
+                    </div>
+                </fieldset>
+            </fieldset>
+        </div>
+    </fieldset>
+</body>
+</html>
diff --git a/LayoutTests/fast/css/pseudo-invalid-fieldset-invalidation-optimization-expected.txt b/LayoutTests/fast/css/pseudo-invalid-fieldset-invalidation-optimization-expected.txt
new file mode 100644 (file)
index 0000000..6731245
--- /dev/null
@@ -0,0 +1,29 @@
+Test that we do not invalidate the style of <fieldset> excessively when matching :invalid based on the descendants.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS window.internals.nodeNeedsStyleRecalc(document.getElementById("with-renderer")) is false
+PASS window.internals.nodeNeedsStyleRecalc(document.getElementById("without-renderer")) is false
+PASS getComputedStyle(document.getElementById("with-renderer")).color is "rgb(0, 0, 0)"
+PASS getComputedStyle(document.getElementById("without-renderer")).color is "rgb(0, 0, 0)"
+PASS window.internals.nodeNeedsStyleRecalc(document.getElementById("with-renderer")) is true
+PASS window.internals.nodeNeedsStyleRecalc(document.getElementById("without-renderer")) is true
+PASS getComputedStyle(document.getElementById("with-renderer")).color is "rgb(0, 1, 2)"
+PASS getComputedStyle(document.getElementById("without-renderer")).color is "rgb(0, 1, 2)"
+PASS window.internals.nodeNeedsStyleRecalc(document.getElementById("with-renderer")) is false
+PASS window.internals.nodeNeedsStyleRecalc(document.getElementById("without-renderer")) is false
+PASS getComputedStyle(document.getElementById("with-renderer")).color is "rgb(0, 1, 2)"
+PASS getComputedStyle(document.getElementById("without-renderer")).color is "rgb(0, 1, 2)"
+PASS window.internals.nodeNeedsStyleRecalc(document.getElementById("with-renderer")) is false
+PASS window.internals.nodeNeedsStyleRecalc(document.getElementById("without-renderer")) is false
+PASS getComputedStyle(document.getElementById("with-renderer")).color is "rgb(0, 1, 2)"
+PASS getComputedStyle(document.getElementById("without-renderer")).color is "rgb(0, 1, 2)"
+PASS window.internals.nodeNeedsStyleRecalc(document.getElementById("with-renderer")) is true
+PASS window.internals.nodeNeedsStyleRecalc(document.getElementById("without-renderer")) is true
+PASS getComputedStyle(document.getElementById("with-renderer")).color is "rgb(0, 0, 0)"
+PASS getComputedStyle(document.getElementById("without-renderer")).color is "rgb(0, 0, 0)"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/css/pseudo-invalid-fieldset-invalidation-optimization.html b/LayoutTests/fast/css/pseudo-invalid-fieldset-invalidation-optimization.html
new file mode 100644 (file)
index 0000000..81a41cb
--- /dev/null
@@ -0,0 +1,96 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+<style>
+fieldset {
+    color: black;
+}
+fieldset:invalid {
+    color: rgb(0, 1, 2);
+}
+</style>
+</head>
+<body>
+    <div>
+        <!-- With renderer -->
+        <fieldset id="with-renderer">
+            <input class="input1" required value="Valid">
+            <input class="input2" required value="Valid">
+            <input class="input3" required value="Valid">
+            <input class="input4" required value="Valid">
+        </fieldset>
+    </div>
+    <div style="display:none;">
+        <!-- Without renderer -->
+        <fieldset id="without-renderer">
+            <input class="input1" required value="Valid">
+            <input class="input2" required value="Valid">
+            <input class="input3" required value="Valid">
+            <input class="input4" required value="Valid">
+        </fieldset>
+    </div>
+</body>
+<script>
+
+description('Test that we do not invalidate the style of &lt;fieldset&gt; excessively when matching :invalid based on the descendants.');
+
+function shouldNeedStyleRecalc(expected) {
+    var testFunction = expected ? shouldBeTrue : shouldBeFalse;
+    testFunction('window.internals.nodeNeedsStyleRecalc(document.getElementById("with-renderer"))');
+    testFunction('window.internals.nodeNeedsStyleRecalc(document.getElementById("without-renderer"))');
+}
+
+function checkStyle(expectedColor) {
+    shouldBeEqualToString('getComputedStyle(document.getElementById("with-renderer")).color', expectedColor);
+    shouldBeEqualToString('getComputedStyle(document.getElementById("without-renderer")).color', expectedColor);
+}
+
+// Force a layout to ensure we don't have dirty styles.
+var offsetTop = document.documentElement.offsetTop;
+
+// Initial state.
+shouldNeedStyleRecalc(false);
+checkStyle('rgb(0, 0, 0)');
+
+// Make input3 invalid, the fieldset should also become invalid.
+var inputs3 = document.querySelectorAll('.input3');
+inputs3[0].value = '';
+inputs3[1].value = '';
+
+shouldNeedStyleRecalc(true);
+checkStyle('rgb(0, 1, 2)');
+
+// Making more fields invalid should not invalidate the fieldset's style.
+var inputs = document.querySelectorAll(':matches(.input2, .input4)');
+for (var i = 0; i < inputs.length; ++i)
+    inputs[i].value = '';
+
+shouldNeedStyleRecalc(false);
+checkStyle('rgb(0, 1, 2)');
+
+// Removing valid fields should not invalidate the style.
+var inputs1 = document.querySelectorAll(':matches(.input1)');
+for (var i = 0; i < inputs1.length; ++i)
+    inputs1[i].parentNode.removeChild(inputs1[i]);
+
+// Making all fields valid but one, fieldset still does not need to be invalidated.
+var inputs = document.querySelectorAll(':matches(.input2, .input3)');
+for (var i = 0; i < inputs.length; ++i)
+    inputs[i].removeAttribute('required');
+
+shouldNeedStyleRecalc(false);
+checkStyle('rgb(0, 1, 2)');
+
+// Making the last input valid. The style must update, fieldset must be invalidated.
+var inputs = document.querySelectorAll(':matches(.input4)');
+for (var i = 0; i < inputs.length; ++i)
+    inputs[i].removeAttribute('required');
+
+shouldNeedStyleRecalc(true);
+checkStyle('rgb(0, 0, 0)');
+
+document.getElementById("with-renderer").style.display = 'none';
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</html>
diff --git a/LayoutTests/fast/css/pseudo-invalid-fieldset-style-sharing-expected.html b/LayoutTests/fast/css/pseudo-invalid-fieldset-style-sharing-expected.html
new file mode 100644 (file)
index 0000000..88f9f26
--- /dev/null
@@ -0,0 +1,66 @@
+<!doctype html>
+<html>
+<head>
+    <style>
+        /* Pack them to fit everything in 800*600 */
+        fieldset {
+            padding: 5px;
+            width: 100px;
+            float: left;
+        }
+        fieldset:invalid {
+            style="background-color: blue;"
+        }
+    </style>
+</head>
+<body>
+    <p>Verify style sharing does not ignore :invalid affecting a &lt;fieldset&gt;.</p>
+
+    <!-- Empty fieldset are :valid, non-empty's :valid depend on the children. -->
+    <div>
+        <fieldset></fieldset>
+        <fieldset></fieldset>
+        <fieldset>
+            <textarea></textarea>
+        </fieldset>
+        <fieldset style="background-color: blue;">
+            <textarea style="background-color: red;" required></textarea>
+        </fieldset>
+        <fieldset>
+            <textarea required>Foobar</textarea>
+        </fieldset>
+
+        <fieldset></fieldset>
+    </div>
+
+    <!-- The style of field set varies with its required children. -->
+    <div>
+        <fieldset style="background-color: blue;">
+            <textarea style="background-color: red;" required></textarea>
+        </fieldset>
+        <fieldset style="background-color: blue;">
+            <textarea style="background-color: red;" required></textarea>
+        </fieldset>
+        <fieldset>
+            <textarea required>Foobar</textarea>
+        </fieldset>
+        <fieldset style="background-color: blue;">
+            <textarea style="background-color: red;" required></textarea>
+        </fieldset>
+    </div>
+    <div>
+        <fieldset>
+            <textarea required>Foobar</textarea>
+        </fieldset>
+        <fieldset style="background-color: blue;">
+            <textarea style="background-color: red;" required></textarea>
+        </fieldset>
+        <fieldset style="background-color: blue;">
+            <textarea style="background-color: red;" required></textarea>
+        </fieldset>
+        <fieldset style="background-color: blue;">
+            <textarea style="background-color: red;" required></textarea>
+        </fieldset>
+    </div>
+</body>
+</html>
diff --git a/LayoutTests/fast/css/pseudo-invalid-fieldset-style-sharing.html b/LayoutTests/fast/css/pseudo-invalid-fieldset-style-sharing.html
new file mode 100644 (file)
index 0000000..2a6f614
--- /dev/null
@@ -0,0 +1,69 @@
+<!doctype html>
+<html>
+<head>
+    <style>
+        /* Pack them to fit everything in 800*600 */
+        fieldset {
+            padding: 5px;
+            width: 100px;
+            float: left;
+        }
+        textarea:invalid {
+            background-color: red;
+        }
+        fieldset:invalid {
+            background-color: blue;
+        }
+    </style>
+</head>
+<body>
+    <p>Verify style sharing does not ignore :invalid affecting a &lt;fieldset&gt;.</p>
+
+    <!-- Empty fieldset are :valid, non-empty's :valid depend on the children. -->
+    <div>
+        <fieldset></fieldset>
+        <fieldset></fieldset>
+        <fieldset>
+            <textarea></textarea>
+        </fieldset>
+        <fieldset>
+            <textarea required></textarea>
+        </fieldset>
+        <fieldset>
+            <textarea required>Foobar</textarea>
+        </fieldset>
+
+        <fieldset></fieldset>
+    </div>
+
+    <!-- The style of field set varies with its required children. -->
+    <div>
+        <fieldset>
+            <textarea required></textarea>
+        </fieldset>
+        <fieldset>
+            <textarea required></textarea>
+        </fieldset>
+        <fieldset>
+            <textarea required>Foobar</textarea>
+        </fieldset>
+        <fieldset>
+            <textarea required></textarea>
+        </fieldset>
+    </div>
+    <div>
+        <fieldset>
+            <textarea required>Foobar</textarea>
+        </fieldset>
+        <fieldset>
+            <textarea required></textarea>
+        </fieldset>
+        <fieldset>
+            <textarea required></textarea>
+        </fieldset>
+        <fieldset>
+            <textarea required></textarea>
+        </fieldset>
+    </div>
+</body>
+</html>
diff --git a/LayoutTests/fast/css/pseudo-invalid-fieldset.html b/LayoutTests/fast/css/pseudo-invalid-fieldset.html
new file mode 100644 (file)
index 0000000..09d7938
--- /dev/null
@@ -0,0 +1,181 @@
+<!doctype html>
+<html>
+<head>
+    <style>
+        /* Pack them to fit everything in 800*600 */
+        fieldset {
+            padding: 5px;
+            width: 100px;
+            float: left;
+        }
+        :invalid {
+            background-color: red;
+        }
+        :not(:invalid) {
+            color: green;
+        }
+    </style>
+</head>
+<body>
+    <p>Test the styling with the pseudo class :valid with the &lt;fieldset&gt; element.</p>
+
+    <!-- Fieldset by itself. -->
+    <fieldset>Text</fieldset>
+
+    <!-- Fieldset with a direct child inputs without any requirements. -->
+    <fieldset>
+        Text
+        <input>
+        <input value>
+        <input value="text">
+    </fieldset>
+
+    <!-- Fieldset with an indirect direct child inputs without any requirements. -->
+    <fieldset>
+        Text
+        <div>
+            Text
+            <div>
+                Text
+                <input>
+                <input value>
+                <input value="text">
+            </div>
+        </div>
+    </fieldset>
+
+    <!-- Fieldset with a direct child inputs with unsatisfied requirements. -->
+    <fieldset>
+        <input required>
+        <input required value>
+        <input required value="">
+    </fieldset>
+
+    <!-- Fieldset with an indirect direct child inputs with unsatisfied requirements. -->
+    <fieldset>
+        Text
+        <div>
+            Text
+            <div>
+                Text
+                <input required>
+                <input required value>
+                <input required value="">
+            </div>
+        </div>
+    </fieldset>
+
+    <!-- Fieldset with a direct child inputs with satisfied requirements. -->
+    <fieldset>
+        <input required value="text">
+    </fieldset>
+
+    <!-- Fieldset with an indirect direct child inputs with satisfied requirements. -->
+    <fieldset>
+        Text
+        <div>
+            Text
+            <div>
+                Text
+                <input required value="text">
+            </div>
+        </div>
+    </fieldset>
+
+    <!-- Fieldset with a direct child inputs with a mix of satisfied and unsatisfied requirements. -->
+    <fieldset>
+        <input required>
+        <input required value>
+        <input required value="">
+        <input required value="text">
+    </fieldset>
+
+    <!-- Fieldset with an indirect direct child inputs with satisfied and unsatisfied requirements. -->
+    <fieldset>
+        Text
+        <div>
+            Text
+            <div>
+                Text
+                <input required>
+                <input required value>
+                <input required value="">
+                <input required value="text">
+            </div>
+        </div>
+    </fieldset>
+
+    <!-- The cases above repeated with multiple nested fieldset -->
+    <fieldset>
+        <div>
+            <fieldset>
+                <fieldset>
+                    Text
+                    <div>
+                        Text
+                        <div>
+                            Text
+                            <input>
+                            <input value>
+                            <input value="text">
+                        </div>
+                    </div>
+                </fieldset>
+            </fieldset>
+        </div>
+    </fieldset>
+    <fieldset>
+        <div>
+            <fieldset>
+                <fieldset>
+                    Text
+                    <div>
+                        Text
+                        <div>
+                            Text
+                            <input required>
+                            <input required value>
+                            <input required value="">
+                        </div>
+                    </div>
+                </fieldset>
+            </fieldset>
+        </div>
+    </fieldset>
+    <fieldset>
+        <div>
+            <fieldset>
+                <fieldset>
+                    Text
+                    <div>
+                        Text
+                        <div>
+                            Text
+                            <input required value="text">
+                        </div>
+                    </div>
+                </fieldset>
+            </fieldset>
+        </div>
+    </fieldset>
+    <fieldset>
+        <div>
+            <fieldset>
+                <fieldset>
+                    Text
+                    <div>
+                        Text
+                        <div>
+                            Text
+                            <input required>
+                            <input required value>
+                            <input required value="">
+                            <input required value="text">
+                        </div>
+                    </div>
+                </fieldset>
+            </fieldset>
+        </div>
+    </fieldset>
+</body>
+</html>
diff --git a/LayoutTests/fast/css/pseudo-valid-fieldset-expected.html b/LayoutTests/fast/css/pseudo-valid-fieldset-expected.html
new file mode 100644 (file)
index 0000000..5fc96e2
--- /dev/null
@@ -0,0 +1,174 @@
+<!doctype html>
+<html>
+<head>
+    <style>
+        fieldset {
+            padding: 5px;
+            width: 100px;
+            float: left;
+        }
+    </style>
+</head>
+<body style="color: red;">
+    <p style="color: red;">Test the styling with the pseudo class :valid with the &lt;fieldset&gt; element.</p>
+
+    <!-- Fieldset by itself. -->
+    <fieldset style="background-color: green;">Text</fieldset>
+
+    <!-- Fieldset with a direct child inputs without any requirements. -->
+    <fieldset style="background-color: green;">
+        Text
+        <input style="background-color: green;">
+        <input style="background-color: green;" value>
+        <input style="background-color: green;" value="text">
+    </fieldset>
+
+    <!-- Fieldset with an indirect direct child inputs without any requirements. -->
+    <fieldset style="background-color: green;">
+        Text
+        <div style="color: red;">
+            Text
+            <div style="color: red;">
+                Text
+                <input style="background-color: green;">
+                <input style="background-color: green;" value>
+                <input style="background-color: green;" value="text">
+            </div>
+        </div>
+    </fieldset>
+
+    <!-- Fieldset with a direct child inputs with unsatisfied requirements. -->
+    <fieldset style="color: red;">
+        <input style="color: red;" required>
+        <input style="color: red;" required value>
+        <input style="color: red;" required value="">
+    </fieldset>
+
+    <!-- Fieldset with an indirect direct child inputs with unsatisfied requirements. -->
+    <fieldset style="color: red;">
+        Text
+        <div style="color: red;">
+            Text
+            <div style="color: red;">
+                Text
+                <input style="color: red;" required>
+                <input style="color: red;" required value>
+                <input style="color: red;" required value="">
+            </div>
+        </div>
+    </fieldset>
+
+    <!-- Fieldset with a direct child inputs with satisfied requirements. -->
+    <fieldset style="background-color: green;">
+        <input style="background-color: green;" required value="text">
+    </fieldset>
+
+    <!-- Fieldset with an indirect direct child inputs with satisfied requirements. -->
+    <fieldset style="background-color: green;">
+        Text
+        <div style="color: red;">
+            Text
+            <div style="color: red;">
+                Text
+                <input style="background-color: green;" required value="text">
+            </div>
+        </div>
+    </fieldset>
+
+    <!-- Fieldset with a direct child inputs with a mix of satisfied and unsatisfied requirements. -->
+    <fieldset style="color: red;">
+        <input style="color: red;" required>
+        <input style="color: red;" required value>
+        <input style="color: red;" required value="">
+        <input style="background-color: green;" required value="text">
+    </fieldset>
+
+    <!-- Fieldset with an indirect direct child inputs with satisfied and unsatisfied requirements. -->
+    <fieldset style="color: red;">
+        Text
+        <div style="color: red;">
+            Text
+            <div style="color: red;">
+                Text
+                <input style="color: red;" required>
+                <input style="color: red;" required value>
+                <input style="color: red;" required value="">
+                <input style="background-color: green;" required value="text">
+            </div>
+        </div>
+    </fieldset>
+
+    <!-- The cases above repeated with multiple nested fieldset -->
+    <fieldset style="background-color: green;">
+        <div style="color: red;">
+            <fieldset style="background-color: green;">
+                <fieldset style="background-color: green;">
+                    Text
+                    <div style="color: red;">
+                        Text
+                        <div style="color: red;">
+                            Text
+                            <input style="background-color: green;">
+                            <input style="background-color: green;" value>
+                            <input style="background-color: green;" value="text">
+                        </div>
+                    </div>
+                </fieldset>
+            </fieldset>
+        </div>
+    </fieldset>
+    <fieldset style="color: red;">
+        <div style="color: red;">
+            <fieldset style="color: red;">
+                <fieldset style="color: red;">
+                    Text
+                    <div style="color: red;">
+                        Text
+                        <div style="color: red;">
+                            Text
+                            <input style="color: red;" required>
+                            <input style="color: red;" required value>
+                            <input style="color: red;" required value="">
+                        </div>
+                    </div>
+                </fieldset>
+            </fieldset>
+        </div>
+    </fieldset>
+    <fieldset style="background-color: green;">
+        <div style="color: red;">
+            <fieldset style="background-color: green;">
+                <fieldset style="background-color: green;">
+                    Text
+                    <div style="color: red;">
+                        Text
+                        <div style="color: red;">
+                            Text
+                            <input style="background-color: green;" required value="text">
+                        </div>
+                    </div>
+                </fieldset>
+            </fieldset>
+        </div>
+    </fieldset>
+    <fieldset style="color: red;">
+        <div style="color: red;">
+            <fieldset style="color: red;">
+                <fieldset style="color: red;">
+                    Text
+                    <div style="color: red;">
+                        Text
+                        <div style="color: red;">
+                            Text
+                            <input style="color: red;" required>
+                            <input style="color: red;" required value>
+                            <input style="color: red;" required value="">
+                            <input style="background-color: green;" required value="text">
+                        </div>
+                    </div>
+                </fieldset>
+            </fieldset>
+        </div>
+    </fieldset>
+</body>
+</html>
diff --git a/LayoutTests/fast/css/pseudo-valid-fieldset-invalidation-optimization-expected.txt b/LayoutTests/fast/css/pseudo-valid-fieldset-invalidation-optimization-expected.txt
new file mode 100644 (file)
index 0000000..652b551
--- /dev/null
@@ -0,0 +1,29 @@
+Test that we do not invalidate the style of <fieldset> excessively when matching :valid based on the descendants.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS window.internals.nodeNeedsStyleRecalc(document.getElementById("with-renderer")) is false
+PASS window.internals.nodeNeedsStyleRecalc(document.getElementById("without-renderer")) is false
+PASS getComputedStyle(document.getElementById("with-renderer")).color is "rgb(0, 1, 2)"
+PASS getComputedStyle(document.getElementById("without-renderer")).color is "rgb(0, 1, 2)"
+PASS window.internals.nodeNeedsStyleRecalc(document.getElementById("with-renderer")) is true
+PASS window.internals.nodeNeedsStyleRecalc(document.getElementById("without-renderer")) is true
+PASS getComputedStyle(document.getElementById("with-renderer")).color is "rgb(0, 0, 0)"
+PASS getComputedStyle(document.getElementById("without-renderer")).color is "rgb(0, 0, 0)"
+PASS window.internals.nodeNeedsStyleRecalc(document.getElementById("with-renderer")) is false
+PASS window.internals.nodeNeedsStyleRecalc(document.getElementById("without-renderer")) is false
+PASS getComputedStyle(document.getElementById("with-renderer")).color is "rgb(0, 0, 0)"
+PASS getComputedStyle(document.getElementById("without-renderer")).color is "rgb(0, 0, 0)"
+PASS window.internals.nodeNeedsStyleRecalc(document.getElementById("with-renderer")) is false
+PASS window.internals.nodeNeedsStyleRecalc(document.getElementById("without-renderer")) is false
+PASS getComputedStyle(document.getElementById("with-renderer")).color is "rgb(0, 0, 0)"
+PASS getComputedStyle(document.getElementById("without-renderer")).color is "rgb(0, 0, 0)"
+PASS window.internals.nodeNeedsStyleRecalc(document.getElementById("with-renderer")) is true
+PASS window.internals.nodeNeedsStyleRecalc(document.getElementById("without-renderer")) is true
+PASS getComputedStyle(document.getElementById("with-renderer")).color is "rgb(0, 1, 2)"
+PASS getComputedStyle(document.getElementById("without-renderer")).color is "rgb(0, 1, 2)"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/css/pseudo-valid-fieldset-invalidation-optimization.html b/LayoutTests/fast/css/pseudo-valid-fieldset-invalidation-optimization.html
new file mode 100644 (file)
index 0000000..9868814
--- /dev/null
@@ -0,0 +1,96 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+<style>
+fieldset {
+    color: black;
+}
+fieldset:valid {
+    color: rgb(0, 1, 2);
+}
+</style>
+</head>
+<body>
+    <div>
+        <!-- With renderer -->
+        <fieldset id="with-renderer">
+            <input class="input1" required value="Valid">
+            <input class="input2" required value="Valid">
+            <input class="input3" required value="Valid">
+            <input class="input4" required value="Valid">
+        </fieldset>
+    </div>
+    <div style="display:none;">
+        <!-- Without renderer -->
+        <fieldset id="without-renderer">
+            <input class="input1" required value="Valid">
+            <input class="input2" required value="Valid">
+            <input class="input3" required value="Valid">
+            <input class="input4" required value="Valid">
+        </fieldset>
+    </div>
+</body>
+<script>
+
+description('Test that we do not invalidate the style of &lt;fieldset&gt; excessively when matching :valid based on the descendants.');
+
+function shouldNeedStyleRecalc(expected) {
+    var testFunction = expected ? shouldBeTrue : shouldBeFalse;
+    testFunction('window.internals.nodeNeedsStyleRecalc(document.getElementById("with-renderer"))');
+    testFunction('window.internals.nodeNeedsStyleRecalc(document.getElementById("without-renderer"))');
+}
+
+function checkStyle(expectedColor) {
+    shouldBeEqualToString('getComputedStyle(document.getElementById("with-renderer")).color', expectedColor);
+    shouldBeEqualToString('getComputedStyle(document.getElementById("without-renderer")).color', expectedColor);
+}
+
+// Force a layout to ensure we don't have dirty styles.
+var offsetTop = document.documentElement.offsetTop;
+
+// Initial state.
+shouldNeedStyleRecalc(false);
+checkStyle('rgb(0, 1, 2)');
+
+// Make input3 invalid, the fieldset should also become invalid.
+var inputs3 = document.querySelectorAll('.input3');
+inputs3[0].value = '';
+inputs3[1].value = '';
+
+shouldNeedStyleRecalc(true);
+checkStyle('rgb(0, 0, 0)');
+
+// Making more fields invalid should not invalidate the fieldset's style.
+var inputs = document.querySelectorAll(':matches(.input2, .input4)');
+for (var i = 0; i < inputs.length; ++i)
+    inputs[i].value = '';
+
+shouldNeedStyleRecalc(false);
+checkStyle('rgb(0, 0, 0)');
+
+// Removing valid fields should not invalidate the style.
+var inputs1 = document.querySelectorAll(':matches(.input1)');
+for (var i = 0; i < inputs1.length; ++i)
+    inputs1[i].parentNode.removeChild(inputs1[i]);
+
+// Making all fields valid but one, fieldset still does not need to be invalidated.
+var inputs = document.querySelectorAll(':matches(.input2, .input3)');
+for (var i = 0; i < inputs.length; ++i)
+    inputs[i].removeAttribute('required');
+
+shouldNeedStyleRecalc(false);
+checkStyle('rgb(0, 0, 0)');
+
+// Making the last input valid. The style must update, fieldset must be invalidated.
+var inputs = document.querySelectorAll(':matches(.input4)');
+for (var i = 0; i < inputs.length; ++i)
+    inputs[i].removeAttribute('required');
+
+shouldNeedStyleRecalc(true);
+checkStyle('rgb(0, 1, 2)');
+
+document.getElementById("with-renderer").style.display = 'none';
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</html>
diff --git a/LayoutTests/fast/css/pseudo-valid-fieldset-style-sharing-expected.html b/LayoutTests/fast/css/pseudo-valid-fieldset-style-sharing-expected.html
new file mode 100644 (file)
index 0000000..7db84ea
--- /dev/null
@@ -0,0 +1,61 @@
+<!doctype html>
+<html>
+<head>
+    <style>
+        /* Pack them to fit everything in 800*600 */
+        fieldset {
+            padding: 5px;
+            width: 100px;
+            float: left;
+        }
+    </style>
+</head>
+<body>
+    <p>Verify style sharing does not ignore :valid affecting a &lt;fieldset&gt;.</p>
+
+    <div>
+        <fieldset style="background-color: lime;"></fieldset>
+        <fieldset style="background-color: lime;"></fieldset>
+        <fieldset style="background-color: lime;">
+            <textarea style="background-color: green;"></textarea>
+        </fieldset>
+        <fieldset>
+            <textarea required></textarea>
+        </fieldset>
+        <fieldset style="background-color: lime;">
+            <textarea style="background-color: green;" required>Foobar</textarea>
+        </fieldset>
+
+        <fieldset style="background-color: lime;"></fieldset>
+    </div>
+
+    <div>
+        <fieldset>
+            <textarea required></textarea>
+        </fieldset style="background-color: lime;">
+        <fieldset>
+            <textarea required></textarea>
+        </fieldset>
+        <fieldset style="background-color: lime;">
+            <textarea style="background-color: green;" required>Foobar</textarea>
+        </fieldset>
+        <fieldset>
+            <textarea required></textarea>
+        </fieldset>
+    </div>
+    <div>
+        <fieldset style="background-color: lime;">
+            <textarea style="background-color: green;" required>Foobar</textarea>
+        </fieldset>
+        <fieldset>
+            <textarea required></textarea>
+        </fieldset>
+        <fieldset>
+            <textarea required></textarea>
+        </fieldset>
+        <fieldset>
+            <textarea required></textarea>
+        </fieldset>
+    </div>
+</body>
+</html>
diff --git a/LayoutTests/fast/css/pseudo-valid-fieldset-style-sharing.html b/LayoutTests/fast/css/pseudo-valid-fieldset-style-sharing.html
new file mode 100644 (file)
index 0000000..f9e8787
--- /dev/null
@@ -0,0 +1,69 @@
+<!doctype html>
+<html>
+<head>
+    <style>
+        /* Pack them to fit everything in 800*600 */
+        fieldset {
+            padding: 5px;
+            width: 100px;
+            float: left;
+        }
+        textarea:valid {
+            background-color: green;
+        }
+        fieldset:valid {
+            background-color: lime;
+        }
+    </style>
+</head>
+<body>
+    <p>Verify style sharing does not ignore :valid affecting a &lt;fieldset&gt;.</p>
+
+    <!-- Empty fieldset are :valid, non-empty's :valid depend on the children. -->
+    <div>
+        <fieldset></fieldset>
+        <fieldset></fieldset>
+        <fieldset>
+            <textarea></textarea>
+        </fieldset>
+        <fieldset>
+            <textarea required></textarea>
+        </fieldset>
+        <fieldset>
+            <textarea required>Foobar</textarea>
+        </fieldset>
+
+        <fieldset></fieldset>
+    </div>
+
+    <!-- The style of field set varies with its required children. -->
+    <div>
+        <fieldset>
+            <textarea required></textarea>
+        </fieldset>
+        <fieldset>
+            <textarea required></textarea>
+        </fieldset>
+        <fieldset>
+            <textarea required>Foobar</textarea>
+        </fieldset>
+        <fieldset>
+            <textarea required></textarea>
+        </fieldset>
+    </div>
+    <div>
+        <fieldset>
+            <textarea required>Foobar</textarea>
+        </fieldset>
+        <fieldset>
+            <textarea required></textarea>
+        </fieldset>
+        <fieldset>
+            <textarea required></textarea>
+        </fieldset>
+        <fieldset>
+            <textarea required></textarea>
+        </fieldset>
+    </div>
+</body>
+</html>
diff --git a/LayoutTests/fast/css/pseudo-valid-fieldset.html b/LayoutTests/fast/css/pseudo-valid-fieldset.html
new file mode 100644 (file)
index 0000000..9b47b97
--- /dev/null
@@ -0,0 +1,181 @@
+<!doctype html>
+<html>
+<head>
+    <style>
+        /* Pack them to fit everything in 800*600 */
+        fieldset {
+            padding: 5px;
+            width: 100px;
+            float: left;
+        }
+        :valid {
+            background-color: green;
+        }
+        :not(:valid) {
+            color: red;
+        }
+    </style>
+</head>
+<body>
+    <p>Test the styling with the pseudo class :valid with the &lt;fieldset&gt; element.</p>
+
+    <!-- Fieldset by itself. -->
+    <fieldset>Text</fieldset>
+
+    <!-- Fieldset with a direct child inputs without any requirements. -->
+    <fieldset>
+        Text
+        <input>
+        <input value>
+        <input value="text">
+    </fieldset>
+
+    <!-- Fieldset with an indirect direct child inputs without any requirements. -->
+    <fieldset>
+        Text
+        <div>
+            Text
+            <div>
+                Text
+                <input>
+                <input value>
+                <input value="text">
+            </div>
+        </div>
+    </fieldset>
+
+    <!-- Fieldset with a direct child inputs with unsatisfied requirements. -->
+    <fieldset>
+        <input required>
+        <input required value>
+        <input required value="">
+    </fieldset>
+
+    <!-- Fieldset with an indirect direct child inputs with unsatisfied requirements. -->
+    <fieldset>
+        Text
+        <div>
+            Text
+            <div>
+                Text
+                <input required>
+                <input required value>
+                <input required value="">
+            </div>
+        </div>
+    </fieldset>
+
+    <!-- Fieldset with a direct child inputs with satisfied requirements. -->
+    <fieldset>
+        <input required value="text">
+    </fieldset>
+
+    <!-- Fieldset with an indirect direct child inputs with satisfied requirements. -->
+    <fieldset>
+        Text
+        <div>
+            Text
+            <div>
+                Text
+                <input required value="text">
+            </div>
+        </div>
+    </fieldset>
+
+    <!-- Fieldset with a direct child inputs with a mix of satisfied and unsatisfied requirements. -->
+    <fieldset>
+        <input required>
+        <input required value>
+        <input required value="">
+        <input required value="text">
+    </fieldset>
+
+    <!-- Fieldset with an indirect direct child inputs with satisfied and unsatisfied requirements. -->
+    <fieldset>
+        Text
+        <div>
+            Text
+            <div>
+                Text
+                <input required>
+                <input required value>
+                <input required value="">
+                <input required value="text">
+            </div>
+        </div>
+    </fieldset>
+
+    <!-- The cases above repeated with multiple nested fieldset -->
+    <fieldset>
+        <div>
+            <fieldset>
+                <fieldset>
+                    Text
+                    <div>
+                        Text
+                        <div>
+                            Text
+                            <input>
+                            <input value>
+                            <input value="text">
+                        </div>
+                    </div>
+                </fieldset>
+            </fieldset>
+        </div>
+    </fieldset>
+    <fieldset>
+        <div>
+            <fieldset>
+                <fieldset>
+                    Text
+                    <div>
+                        Text
+                        <div>
+                            Text
+                            <input required>
+                            <input required value>
+                            <input required value="">
+                        </div>
+                    </div>
+                </fieldset>
+            </fieldset>
+        </div>
+    </fieldset>
+    <fieldset>
+        <div>
+            <fieldset>
+                <fieldset>
+                    Text
+                    <div>
+                        Text
+                        <div>
+                            Text
+                            <input required value="text">
+                        </div>
+                    </div>
+                </fieldset>
+            </fieldset>
+        </div>
+    </fieldset>
+    <fieldset>
+        <div>
+            <fieldset>
+                <fieldset>
+                    Text
+                    <div>
+                        Text
+                        <div>
+                            Text
+                            <input required>
+                            <input required value>
+                            <input required value="">
+                            <input required value="text">
+                        </div>
+                    </div>
+                </fieldset>
+            </fieldset>
+        </div>
+    </fieldset>
+</body>
+</html>
index d760774..f3b9256 100644 (file)
@@ -9,7 +9,6 @@ PASS getBackgroundColor('input-button') is normalColor
 PASS getBackgroundColor('input-reset') is normalColor
 PASS getBackgroundColor('input-hidden') is normalColor
 PASS getBackgroundColor('input-image') is normalColor
-PASS getBackgroundColor('fieldset') is normalColor
 PASS getBackgroundColor('object') is normalColor
 PASS getBackgroundColor('button-button') is normalColor
 PASS getBackgroundColor('button-reset') is normalColor
index ba47868..f034101 100644 (file)
@@ -49,7 +49,6 @@ var names = [
     "input-reset",
     "input-hidden",
     "input-image",
-    "fieldset",
     "object",
     "button-button",
     "button-reset",
diff --git a/LayoutTests/fast/selectors/invalid-fieldset-style-update-1-expected.txt b/LayoutTests/fast/selectors/invalid-fieldset-style-update-1-expected.txt
new file mode 100644 (file)
index 0000000..89e0682
--- /dev/null
@@ -0,0 +1,259 @@
+Test style update for :invalid applied on a fieldset.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+
+Initial state
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+
+Make the text area valid.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+
+Back to invalid. We should be in the initial state.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+
+Move the invalid text area into fieldset3.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+
+Make the text area valid.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+
+Make the input invalid.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+
+Move text area as a child of fieldset1.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+
+Move text area as a child of div1.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+
+Make the text area invalid.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+
+Make the input valid.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+
+Make the text area valid, everything should be valid.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+
+Make the input invalid.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+
+Move fieldset2 inside div3
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+
+Destroy the content of div2
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/selectors/invalid-fieldset-style-update-1.html b/LayoutTests/fast/selectors/invalid-fieldset-style-update-1.html
new file mode 100644 (file)
index 0000000..c99aafc
--- /dev/null
@@ -0,0 +1,171 @@
+<!doctype html>
+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+<style>
+:matches(#with-renderer, #without-renderer) * {
+    background-color: rgb(1, 2, 3);
+}
+:matches(#with-renderer, #without-renderer) :invalid {
+    background-color: rgb(4, 5, 6);
+}
+</style>
+</head>
+<body>
+    <template id="test-source">
+        <fieldset class="fieldset1">
+            <div class="div1">
+                <fieldset class="fieldset2">
+                    <div class="div2">
+                        <input class="input1" required value="valid">
+                    </div>
+                </fieldset>
+                <textarea class="textarea1" required></textarea>
+            </div>
+        </fieldset>
+        <fieldset class="fieldset3">
+            <div class="div3">
+            </div>
+        </fieldset>
+    </template>
+    <div id="with-renderer"></div>
+    <div id="without-renderer" style="display:none;"></div>
+</body>
+<script>
+description('Test style update for :invalid applied on a fieldset.');
+
+var withRenderer = document.getElementById("with-renderer");
+var withoutRenderer = document.getElementById("without-renderer");
+var source = document.getElementById("test-source").content;
+
+withRenderer.appendChild(source.cloneNode(true));
+withoutRenderer.appendChild(source.cloneNode(true));
+
+function testStyleAtId(rootId, matchedClass) {
+    var allElements = document.getElementById(rootId).querySelectorAll('*');
+    for (var i = 0; i < allElements.length; ++i) {
+        var expectedStyle = matchedClass.indexOf(allElements[i].className) >= 0 ? 'rgb(4, 5, 6)' : 'rgb(1, 2, 3)';
+        shouldBeEqualToString('getComputedStyle(document.getElementById("' + rootId + '").querySelector(".' + allElements[i].className + '")).backgroundColor', expectedStyle);
+    }
+}
+
+function testStyle(matchedClass) {
+    testStyleAtId('with-renderer', matchedClass);
+    testStyleAtId('without-renderer', matchedClass);
+}
+
+function modifyTree(updateFunction) {
+    updateFunction(withRenderer);
+    updateFunction(withoutRenderer);
+}
+
+debug('');
+debug('Initial state');
+testStyle(['fieldset1', 'textarea1']);
+
+debug('');
+debug("Make the text area valid.");
+modifyTree(function(root) {
+    root.querySelector('.textarea1').value = "Valid";
+});
+testStyle([]);
+
+debug('');
+debug("Back to invalid. We should be in the initial state.");
+modifyTree(function(root) {
+    root.querySelector('.textarea1').value = "";
+});
+testStyle(['fieldset1', 'textarea1']);
+
+
+debug('');
+debug("Move the invalid text area into fieldset3.");
+modifyTree(function(root) {
+    var textArea = root.querySelector('.textarea1');
+    var fieldset3 = root.querySelector('.fieldset3');
+    fieldset3.appendChild(textArea);
+});
+testStyle(['fieldset3', 'textarea1']);
+
+debug('');
+debug("Make the text area valid.");
+modifyTree(function(root) {
+    root.querySelector('.textarea1').value = "Valid";
+});
+testStyle([]);
+
+debug('');
+debug("Make the input invalid.");
+modifyTree(function(root) {
+    root.querySelector('.input1').value = "";
+});
+testStyle(['fieldset1', 'fieldset2', 'input1']);
+
+debug('');
+debug("Move text area as a child of fieldset1.");
+modifyTree(function(root) {
+    var textArea = root.querySelector('.textarea1');
+    var fieldset1 = root.querySelector('.fieldset1');
+    fieldset1.appendChild(textArea);
+});
+testStyle(['fieldset1', 'fieldset2', 'input1']);
+
+debug('');
+debug("Move text area as a child of div1.");
+modifyTree(function(root) {
+    var textArea = root.querySelector('.textarea1');
+    var div1 = root.querySelector('.div1');
+    div1.appendChild(textArea);
+});
+testStyle(['fieldset1', 'fieldset2', 'input1']);
+
+debug('');
+debug("Make the text area invalid.");
+modifyTree(function(root) {
+    root.querySelector('.textarea1').value = "";
+});
+testStyle(['fieldset1', 'fieldset2', 'input1', 'textarea1']);
+
+debug('');
+debug("Make the input valid.");
+modifyTree(function(root) {
+    root.querySelector('.input1').value = "Valid";
+});
+testStyle(['fieldset1', 'textarea1']);
+
+debug('');
+debug("Make the text area valid, everything should be valid.");
+modifyTree(function(root) {
+    root.querySelector('.textarea1').value = "Valid";
+});
+testStyle([]);
+
+debug('');
+debug("Make the input invalid.");
+modifyTree(function(root) {
+    root.querySelector('.input1').value = "";
+});
+testStyle(['fieldset1', 'fieldset2', 'input1']);
+
+
+debug('');
+debug("Move fieldset2 inside div3");
+modifyTree(function(root) {
+    var fieldset2 = root.querySelector('.fieldset2');
+    var div3 = root.querySelector('.div3');
+    div3.appendChild(fieldset2);
+});
+testStyle(['fieldset3', 'fieldset2', 'input1']);
+
+debug('');
+debug("Destroy the content of div2");
+modifyTree(function(root) {
+    root.querySelector('.div2').textContent = '';
+});
+testStyle([]);
+
+// Remove the content otherwise it will appear in the results.
+withRenderer.style.display = 'none';
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</html>
diff --git a/LayoutTests/fast/selectors/invalid-fieldset-style-update-2-expected.txt b/LayoutTests/fast/selectors/invalid-fieldset-style-update-2-expected.txt
new file mode 100644 (file)
index 0000000..d2a966b
--- /dev/null
@@ -0,0 +1,369 @@
+Test style update for :invalid applied on a fieldset.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+
+Initial state
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input6")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input7")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input8")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input9")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input10")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input6")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input7")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input8")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input9")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input10")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button4")).backgroundColor is "rgb(1, 2, 3)"
+
+Change the type of input3 to something that validates.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input6")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input7")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input8")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input9")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input10")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input6")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input7")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input8")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input9")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input10")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button4")).backgroundColor is "rgb(1, 2, 3)"
+
+Change the type of input7 to something that validates.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input6")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input7")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input8")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input9")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input10")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input6")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input7")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input8")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input9")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input10")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button4")).backgroundColor is "rgb(1, 2, 3)"
+
+Change the type of input9 to something that does not validate.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input6")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input7")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input8")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input9")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input10")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input6")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input7")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input8")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input9")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input10")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button4")).backgroundColor is "rgb(1, 2, 3)"
+
+Change the type of input5 to something that does not validate.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input6")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input7")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input8")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input9")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input10")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input6")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input7")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input8")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input9")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input10")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button4")).backgroundColor is "rgb(1, 2, 3)"
+
+Change the type of input6 to something that does not validate.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input7")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input8")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input9")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input10")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input7")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input8")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input9")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input10")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button4")).backgroundColor is "rgb(1, 2, 3)"
+
+Change the type of input7 to something that does not validate.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input7")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input8")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input9")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input10")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input7")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input8")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input9")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input10")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button4")).backgroundColor is "rgb(1, 2, 3)"
+
+Change the type of input10 to something that does not validate.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input7")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input8")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input9")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input10")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input7")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input8")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input9")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input10")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button4")).backgroundColor is "rgb(1, 2, 3)"
+
+Disable the text area.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input7")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input8")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input9")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input10")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input7")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input8")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input9")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input10")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button4")).backgroundColor is "rgb(1, 2, 3)"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/selectors/invalid-fieldset-style-update-2.html b/LayoutTests/fast/selectors/invalid-fieldset-style-update-2.html
new file mode 100644 (file)
index 0000000..6447b5c
--- /dev/null
@@ -0,0 +1,136 @@
+<!doctype html>
+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+<style>
+:matches(#with-renderer, #without-renderer) * {
+    background-color: rgb(1, 2, 3);
+}
+:matches(#with-renderer, #without-renderer) :invalid {
+    background-color: rgb(4, 5, 6);
+}
+</style>
+</head>
+<body>
+    <template id="test-source">
+        <fieldset class="fieldset1">
+            <div class="div1">
+                <fieldset class="fieldset2">
+                    <div class="div2">
+                        <input class="input1" required value="valid">
+                        <input class="input2" type="button" required value="valid">
+                        <input class="input3" type="hidden" required value="valid">
+                        <input class="input4" type="email" required value="awesome@webkit.org">
+                        <input class="input5" type="password" required value="valid">
+                        <button class="button1">Base button</button>
+                        <button class="button2" type="submit">Submit button</button>
+                    </div>
+                </fieldset>
+                <textarea class="textarea1" required></textarea>
+                <input class="input6" required>
+                <input class="input7" type="button" required>
+                <input class="input8" type="hidden" required>
+                <input class="input9" type="email" required>
+                <input class="input10" type="password" required>
+                <button class="button3">Base button</button>
+                <button class="button4" type="submit">Submit button</button>
+            </div>
+        </fieldset>
+    </template>
+    <div id="with-renderer"></div>
+    <div id="without-renderer" style="display:none;"></div>
+</body>
+<script>
+description('Test style update for :invalid applied on a fieldset.');
+
+var withRenderer = document.getElementById("with-renderer");
+var withoutRenderer = document.getElementById("without-renderer");
+var source = document.getElementById("test-source").content;
+
+withRenderer.appendChild(source.cloneNode(true));
+withoutRenderer.appendChild(source.cloneNode(true));
+
+function testStyleAtId(rootId, matchedClass) {
+    var allElements = document.getElementById(rootId).querySelectorAll('*');
+    for (var i = 0; i < allElements.length; ++i) {
+        var expectedStyle = matchedClass.indexOf(allElements[i].className) >= 0 ? 'rgb(4, 5, 6)' : 'rgb(1, 2, 3)';
+        shouldBeEqualToString('getComputedStyle(document.getElementById("' + rootId + '").querySelector(".' + allElements[i].className + '")).backgroundColor', expectedStyle);
+    }
+}
+
+function testStyle(matchedClass) {
+    testStyleAtId('with-renderer', matchedClass);
+    testStyleAtId('without-renderer', matchedClass);
+}
+
+function modifyTree(updateFunction) {
+    updateFunction(withRenderer);
+    updateFunction(withoutRenderer);
+}
+
+debug('');
+debug('Initial state');
+testStyle(['fieldset1', 'textarea1', 'input6', 'input9', 'input10']);
+
+debug('');
+debug("Change the type of input3 to something that validates.");
+modifyTree(function(root) {
+    root.querySelector('.input3').type = "search";
+});
+testStyle(['fieldset1', 'textarea1', 'input6', 'input9', 'input10']);
+
+debug('');
+debug("Change the type of input7 to something that validates.");
+modifyTree(function(root) {
+    root.querySelector('.input7').type = "search";
+});
+testStyle(['fieldset1', 'textarea1', 'input6', 'input7', 'input9', 'input10']);
+
+debug('');
+debug("Change the type of input9 to something that does not validate.");
+modifyTree(function(root) {
+    root.querySelector('.input9').type = "hidden";
+});
+testStyle(['fieldset1', 'textarea1', 'input6', 'input7', 'input10']);
+
+debug('');
+debug("Change the type of input5 to something that does not validate.");
+modifyTree(function(root) {
+    root.querySelector('.input5').type = "button";
+});
+testStyle(['fieldset1', 'textarea1', 'input6', 'input7', 'input10']);
+
+// Change everything in the second half of controls without validation, eventually, fieldset1 should validate.
+debug('');
+debug("Change the type of input6 to something that does not validate.");
+modifyTree(function(root) {
+    root.querySelector('.input6').type = "button";
+});
+testStyle(['fieldset1', 'textarea1', 'input7', 'input10']);
+
+debug('');
+debug("Change the type of input7 to something that does not validate.");
+modifyTree(function(root) {
+    root.querySelector('.input7').type = "reset";
+});
+testStyle(['fieldset1', 'textarea1', 'input10']);
+
+debug('');
+debug("Change the type of input10 to something that does not validate.");
+modifyTree(function(root) {
+    root.querySelector('.input10').type = "reset";
+});
+testStyle(['fieldset1', 'textarea1']);
+
+debug('');
+debug("Disable the text area.");
+modifyTree(function(root) {
+    root.querySelector('.textarea1').setAttribute('disabled', '');
+});
+testStyle([]);
+
+// Remove the content otherwise it will appear in the results.
+withRenderer.style.display = 'none';
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</html>
diff --git a/LayoutTests/fast/selectors/invalid-fieldset-style-update-3-expected.txt b/LayoutTests/fast/selectors/invalid-fieldset-style-update-3-expected.txt
new file mode 100644 (file)
index 0000000..b4e1080
--- /dev/null
@@ -0,0 +1,195 @@
+Test style update for :invalid applied on a fieldset.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+
+Initial state
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+
+Add input1 to fieldset1.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+
+Add input2 to fieldset1.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+
+Add input3 to fieldset1.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+
+Add input4 to fieldset2.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+
+Add input5 to fieldset2.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+
+Add input6 to fieldset2.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+
+Enable fieldset2.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input5")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input5")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+
+Disable fieldset1.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input5")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input5")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+
+Remove input1
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input5")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input5")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+
+Remove input2
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input5")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input5")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+
+Remove input3
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input5")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input5")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+
+Remove input4
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input5")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input5")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+
+Remove input5
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+
+Remove input6
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/selectors/invalid-fieldset-style-update-3.html b/LayoutTests/fast/selectors/invalid-fieldset-style-update-3.html
new file mode 100644 (file)
index 0000000..88fb148
--- /dev/null
@@ -0,0 +1,183 @@
+<!doctype html>
+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+<style>
+:matches(#with-renderer, #without-renderer) * {
+    background-color: rgb(1, 2, 3);
+}
+:matches(#with-renderer, #without-renderer) :invalid {
+    background-color: rgb(4, 5, 6);
+}
+</style>
+</head>
+<body>
+    <template id="test-source">
+        <fieldset class="fieldset1">
+        </fieldset>
+        <fieldset class="fieldset2" disabled>
+        </fieldset>
+    </template>
+    <div id="with-renderer"></div>
+    <div id="without-renderer" style="display:none;"></div>
+</body>
+<script>
+description('Test style update for :invalid applied on a fieldset.');
+
+var withRenderer = document.getElementById("with-renderer");
+var withoutRenderer = document.getElementById("without-renderer");
+var source = document.getElementById("test-source").content;
+
+withRenderer.appendChild(source.cloneNode(true));
+withoutRenderer.appendChild(source.cloneNode(true));
+
+function testStyleAtId(rootId, matchedClass) {
+    var allElements = document.getElementById(rootId).querySelectorAll('*');
+    for (var i = 0; i < allElements.length; ++i) {
+        var expectedStyle = matchedClass.indexOf(allElements[i].className) >= 0 ? 'rgb(4, 5, 6)' : 'rgb(1, 2, 3)';
+        shouldBeEqualToString('getComputedStyle(document.getElementById("' + rootId + '").querySelector(".' + allElements[i].className + '")).backgroundColor', expectedStyle);
+    }
+}
+
+function testStyle(matchedClass) {
+    testStyleAtId('with-renderer', matchedClass);
+    testStyleAtId('without-renderer', matchedClass);
+}
+
+function modifyTree(updateFunction) {
+    updateFunction(withRenderer);
+    updateFunction(withoutRenderer);
+}
+
+debug('');
+debug('Initial state');
+testStyle([]);
+
+debug('');
+debug("Add input1 to fieldset1.");
+modifyTree(function(root) {
+    var input1 = document.createElement('input');
+    input1.className = 'input1';
+    root.querySelector('.fieldset1').appendChild(input1);
+});
+testStyle([]);
+
+debug('');
+debug("Add input2 to fieldset1.");
+modifyTree(function(root) {
+    var input2 = document.createElement('input');
+    input2.className = 'input2';
+    input2.setAttribute('required', '');
+    root.querySelector('.fieldset1').appendChild(input2);
+});
+testStyle(['fieldset1', 'input2']);
+
+debug('');
+debug("Add input3 to fieldset1.");
+modifyTree(function(root) {
+    var input3 = document.createElement('input');
+    input3.className = 'input3';
+    input3.setAttribute('required', '');
+    input3.value = "valid";
+    root.querySelector('.fieldset1').appendChild(input3);
+});
+testStyle(['fieldset1', 'input2']);
+
+debug('');
+debug("Add input4 to fieldset2.");
+modifyTree(function(root) {
+    var input4 = document.createElement('input');
+    input4.className = 'input4';
+    root.querySelector('.fieldset2').appendChild(input4);
+});
+testStyle(['fieldset1', 'input2']);
+
+debug('');
+debug("Add input5 to fieldset2.");
+modifyTree(function(root) {
+    var input5 = document.createElement('input');
+    input5.className = 'input5';
+    input5.setAttribute('required', '');
+    root.querySelector('.fieldset2').appendChild(input5);
+});
+testStyle(['fieldset1', 'input2']);
+
+debug('');
+debug("Add input6 to fieldset2.");
+modifyTree(function(root) {
+    var input6 = document.createElement('input');
+    input6.className = 'input6';
+    input6.setAttribute('required', '');
+    input6.value = "valid"
+    root.querySelector('.fieldset2').appendChild(input6);
+});
+testStyle(['fieldset1', 'input2']);
+
+debug('');
+debug("Enable fieldset2.");
+modifyTree(function(root) {
+    root.querySelector('.fieldset2').removeAttribute('disabled');
+});
+testStyle(['fieldset1', 'input2', 'fieldset2', 'input5']);
+
+debug('');
+debug("Disable fieldset1.");
+modifyTree(function(root) {
+    root.querySelector('.fieldset1').setAttribute('disabled', '');
+});
+testStyle(['fieldset2', 'input5']);
+
+debug('');
+debug("Remove input1");
+modifyTree(function(root) {
+    var input = root.querySelector('.input1');
+    input.parentNode.removeChild(input);
+});
+testStyle(['fieldset2', 'input5']);
+
+debug('');
+debug("Remove input2");
+modifyTree(function(root) {
+    var input = root.querySelector('.input2');
+    input.parentNode.removeChild(input);
+});
+testStyle(['fieldset2', 'input5']);
+
+debug('');
+debug("Remove input3");
+modifyTree(function(root) {
+    var input = root.querySelector('.input3');
+    input.parentNode.removeChild(input);
+});
+testStyle(['fieldset2', 'input5']);
+
+debug('');
+debug("Remove input4");
+modifyTree(function(root) {
+    var input = root.querySelector('.input4');
+    input.parentNode.removeChild(input);
+});
+testStyle(['fieldset2', 'input5']);
+
+debug('');
+debug("Remove input5");
+modifyTree(function(root) {
+    var input = root.querySelector('.input5');
+    input.parentNode.removeChild(input);
+});
+testStyle([]);
+
+debug('');
+debug("Remove input6");
+modifyTree(function(root) {
+    var input = root.querySelector('.input6');
+    input.parentNode.removeChild(input);
+});
+testStyle([]);
+
+
+// Remove the content otherwise it will appear in the results.
+withRenderer.style.display = 'none';
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</html>
diff --git a/LayoutTests/fast/selectors/invalid-fieldset-style-update-4-expected.txt b/LayoutTests/fast/selectors/invalid-fieldset-style-update-4-expected.txt
new file mode 100644 (file)
index 0000000..6553c5b
--- /dev/null
@@ -0,0 +1,191 @@
+Test style update for :invalid applied on a fieldset.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+
+Initial state
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+
+Add input1 to fieldset1.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+
+Disable input1.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+
+Re-enable input1.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+
+Make input1 readonly.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+
+Add input2 to fieldset2.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+
+Disable input2.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+
+Re-enable input2.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+
+Make input2 readonly.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+
+Add input3 to fieldset1.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+
+Disable input3.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+
+Re-enable input3.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+
+Make input3 readonly.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+
+Add input4 to fieldset2.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+
+Disable input4.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+
+Re-enable input4.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+
+Make input4 readonly.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/selectors/invalid-fieldset-style-update-4.html b/LayoutTests/fast/selectors/invalid-fieldset-style-update-4.html
new file mode 100644 (file)
index 0000000..9a331d2
--- /dev/null
@@ -0,0 +1,182 @@
+<!doctype html>
+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+<style>
+:matches(#with-renderer, #without-renderer) * {
+    background-color: rgb(1, 2, 3);
+}
+:matches(#with-renderer, #without-renderer) :invalid {
+    background-color: rgb(4, 5, 6);
+}
+</style>
+</head>
+<body>
+    <template id="test-source">
+        <fieldset class="fieldset1">
+        </fieldset>
+        <fieldset class="fieldset2" disabled>
+        </fieldset>
+    </template>
+    <div id="with-renderer"></div>
+    <div id="without-renderer" style="display:none;"></div>
+</body>
+<script>
+description('Test style update for :invalid applied on a fieldset.');
+
+var withRenderer = document.getElementById("with-renderer");
+var withoutRenderer = document.getElementById("without-renderer");
+var source = document.getElementById("test-source").content;
+
+withRenderer.appendChild(source.cloneNode(true));
+withoutRenderer.appendChild(source.cloneNode(true));
+
+function testStyleAtId(rootId, matchedClass) {
+    var allElements = document.getElementById(rootId).querySelectorAll('*');
+    for (var i = 0; i < allElements.length; ++i) {
+        var expectedStyle = matchedClass.indexOf(allElements[i].className) >= 0 ? 'rgb(4, 5, 6)' : 'rgb(1, 2, 3)';
+        shouldBeEqualToString('getComputedStyle(document.getElementById("' + rootId + '").querySelector(".' + allElements[i].className + '")).backgroundColor', expectedStyle);
+    }
+}
+
+function testStyle(matchedClass) {
+    testStyleAtId('with-renderer', matchedClass);
+    testStyleAtId('without-renderer', matchedClass);
+}
+
+function modifyTree(updateFunction) {
+    updateFunction(withRenderer);
+    updateFunction(withoutRenderer);
+}
+
+debug('');
+debug('Initial state');
+testStyle([]);
+
+debug('');
+debug("Add input1 to fieldset1.");
+modifyTree(function(root) {
+    var input1 = document.createElement('input');
+    input1.className = 'input1';
+    root.querySelector('.fieldset1').appendChild(input1);
+});
+testStyle([]);
+
+debug('');
+debug("Disable input1.");
+modifyTree(function(root) {
+    root.querySelector('.input1').setAttribute('disabled', '');
+});
+testStyle([]);
+
+debug('');
+debug("Re-enable input1.");
+modifyTree(function(root) {
+    root.querySelector('.input1').removeAttribute('disabled');
+});
+testStyle([]);
+
+debug('');
+debug("Make input1 readonly.");
+modifyTree(function(root) {
+    root.querySelector('.input1').setAttribute('readonly', '');
+});
+testStyle([]);
+
+debug('');
+debug("Add input2 to fieldset2.");
+modifyTree(function(root) {
+    var input2 = document.createElement('input');
+    input2.className = 'input2';
+    root.querySelector('.fieldset2').appendChild(input2);
+});
+testStyle([]);
+
+debug('');
+debug("Disable input2.");
+modifyTree(function(root) {
+    root.querySelector('.input2').setAttribute('disabled', '');
+});
+testStyle([]);
+
+debug('');
+debug("Re-enable input2.");
+modifyTree(function(root) {
+    root.querySelector('.input2').removeAttribute('disabled');
+});
+testStyle([]);
+
+debug('');
+debug("Make input2 readonly.");
+modifyTree(function(root) {
+    root.querySelector('.input2').setAttribute('readonly', '');
+});
+testStyle([]);
+
+debug('');
+debug("Add input3 to fieldset1.");
+modifyTree(function(root) {
+    var input3 = document.createElement('input');
+    input3.className = 'input3';
+    input3.setAttribute('required', '');
+    root.querySelector('.fieldset1').appendChild(input3);
+});
+testStyle(['fieldset1', 'input3']);
+
+debug('');
+debug("Disable input3.");
+modifyTree(function(root) {
+    root.querySelector('.input3').setAttribute('disabled', '');
+});
+testStyle([]);
+
+debug('');
+debug("Re-enable input3.");
+modifyTree(function(root) {
+    root.querySelector('.input3').removeAttribute('disabled');
+});
+testStyle(['fieldset1', 'input3']);
+
+debug('');
+debug("Make input3 readonly.");
+modifyTree(function(root) {
+    root.querySelector('.input3').setAttribute('readonly', '');
+});
+testStyle([]);
+
+debug('');
+debug("Add input4 to fieldset2.");
+modifyTree(function(root) {
+    var input4 = document.createElement('input');
+    input4.className = 'input4';
+    input4.setAttribute('required', '');
+    root.querySelector('.fieldset2').appendChild(input4);
+});
+testStyle([]);
+
+debug('');
+debug("Disable input4.");
+modifyTree(function(root) {
+    root.querySelector('.input4').setAttribute('disabled', '');
+});
+testStyle([]);
+
+debug('');
+debug("Re-enable input4.");
+modifyTree(function(root) {
+    root.querySelector('.input4').removeAttribute('disabled');
+});
+testStyle([]);
+
+debug('');
+debug("Make input4 readonly.");
+modifyTree(function(root) {
+    root.querySelector('.input4').setAttribute('readonly', '');
+});
+testStyle([]);
+
+// Remove the content otherwise it will appear in the results.
+withRenderer.style.display = 'none';
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</html>
diff --git a/LayoutTests/fast/selectors/invalid-fieldset-style-update-5-expected.txt b/LayoutTests/fast/selectors/invalid-fieldset-style-update-5-expected.txt
new file mode 100644 (file)
index 0000000..3c3d7bd
--- /dev/null
@@ -0,0 +1,23 @@
+Test style update for :invalid applied on a fieldset.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+
+Move fieldset2 inside div3
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/selectors/invalid-fieldset-style-update-5.html b/LayoutTests/fast/selectors/invalid-fieldset-style-update-5.html
new file mode 100644 (file)
index 0000000..e84f987
--- /dev/null
@@ -0,0 +1,73 @@
+<!doctype html>
+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+<style>
+:matches(#with-renderer, #without-renderer) * {
+    background-color: rgb(1, 2, 3);
+}
+:matches(#with-renderer, #without-renderer) :invalid {
+    background-color: rgb(4, 5, 6);
+}
+</style>
+</head>
+<body>
+    <template id="test-source">
+        <fieldset class="fieldset1">
+            <div class="div1">
+                <fieldset class="fieldset2">
+                    <div class="div2">
+                        <input class="input1" required value="">
+                    </div>
+                </fieldset>
+            </div>
+        </fieldset>
+        <div class="div3">
+        </div>
+    </template>
+    <div id="with-renderer"></div>
+    <div id="without-renderer" style="display:none;"></div>
+</body>
+<script>
+description('Test style update for :invalid applied on a fieldset.');
+
+var withRenderer = document.getElementById("with-renderer");
+var withoutRenderer = document.getElementById("without-renderer");
+var source = document.getElementById("test-source").content;
+
+withRenderer.appendChild(source.cloneNode(true));
+withoutRenderer.appendChild(source.cloneNode(true));
+
+function testStyleAtId(rootId, matchedClass) {
+    var allElements = document.getElementById(rootId).querySelectorAll('*');
+    for (var i = 0; i < allElements.length; ++i) {
+        var expectedStyle = matchedClass.indexOf(allElements[i].className) >= 0 ? 'rgb(4, 5, 6)' : 'rgb(1, 2, 3)';
+        shouldBeEqualToString('getComputedStyle(document.getElementById("' + rootId + '").querySelector(".' + allElements[i].className + '")).backgroundColor', expectedStyle);
+    }
+}
+
+function testStyle(matchedClass) {
+    testStyleAtId('with-renderer', matchedClass);
+    testStyleAtId('without-renderer', matchedClass);
+}
+
+function modifyTree(updateFunction) {
+    updateFunction(withRenderer);
+    updateFunction(withoutRenderer);
+}
+
+debug('');
+debug("Move fieldset2 inside div3");
+modifyTree(function(root) {
+    var fieldset2 = root.querySelector('.fieldset2');
+    var div3 = root.querySelector('.div3');
+    div3.appendChild(fieldset2);
+});
+testStyle(['fieldset2', 'input1']);
+
+
+// Remove the content otherwise it will appear in the results.
+withRenderer.style.display = 'none';
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</html>
diff --git a/LayoutTests/fast/selectors/valid-fieldset-style-update-1-expected.txt b/LayoutTests/fast/selectors/valid-fieldset-style-update-1-expected.txt
new file mode 100644 (file)
index 0000000..5ddeafc
--- /dev/null
@@ -0,0 +1,259 @@
+Test style update for :valid applied on a fieldset.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+
+Initial state
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+
+Make the text area valid.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+
+Back to invalid. We should be in the initial state.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+
+Move the invalid text area into fieldset3.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+
+Make the text area valid.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+
+Make the input invalid.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+
+Move text area as a child of fieldset1.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+
+Move text area as a child of div1.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+
+Make the text area invalid.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+
+Make the input valid.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+
+Make the text area valid, everything should be valid.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+
+Make the input invalid.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+
+Move fieldset2 inside div3
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+
+Destroy the content of div2
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/selectors/valid-fieldset-style-update-1.html b/LayoutTests/fast/selectors/valid-fieldset-style-update-1.html
new file mode 100644 (file)
index 0000000..b9a671c
--- /dev/null
@@ -0,0 +1,171 @@
+<!doctype html>
+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+<style>
+:matches(#with-renderer, #without-renderer) * {
+    background-color: rgb(1, 2, 3);
+}
+:matches(#with-renderer, #without-renderer) :valid {
+    background-color: rgb(4, 5, 6);
+}
+</style>
+</head>
+<body>
+    <template id="test-source">
+        <fieldset class="fieldset1">
+            <div class="div1">
+                <fieldset class="fieldset2">
+                    <div class="div2">
+                        <input class="input1" required value="valid">
+                    </div>
+                </fieldset>
+                <textarea class="textarea1" required></textarea>
+            </div>
+        </fieldset>
+        <fieldset class="fieldset3">
+            <div class="div3">
+            </div>
+        </fieldset>
+    </template>
+    <div id="with-renderer"></div>
+    <div id="without-renderer" style="display:none;"></div>
+</body>
+<script>
+description('Test style update for :valid applied on a fieldset.');
+
+var withRenderer = document.getElementById("with-renderer");
+var withoutRenderer = document.getElementById("without-renderer");
+var source = document.getElementById("test-source").content;
+
+withRenderer.appendChild(source.cloneNode(true));
+withoutRenderer.appendChild(source.cloneNode(true));
+
+function testStyleAtId(rootId, matchedClass) {
+    var allElements = document.getElementById(rootId).querySelectorAll('*');
+    for (var i = 0; i < allElements.length; ++i) {
+        var expectedStyle = matchedClass.indexOf(allElements[i].className) >= 0 ? 'rgb(4, 5, 6)' : 'rgb(1, 2, 3)';
+        shouldBeEqualToString('getComputedStyle(document.getElementById("' + rootId + '").querySelector(".' + allElements[i].className + '")).backgroundColor', expectedStyle);
+    }
+}
+
+function testStyle(matchedClass) {
+    testStyleAtId('with-renderer', matchedClass);
+    testStyleAtId('without-renderer', matchedClass);
+}
+
+function modifyTree(updateFunction) {
+    updateFunction(withRenderer);
+    updateFunction(withoutRenderer);
+}
+
+debug('');
+debug('Initial state');
+testStyle(['fieldset2', 'input1', 'fieldset3']);
+
+debug('');
+debug("Make the text area valid.");
+modifyTree(function(root) {
+    root.querySelector('.textarea1').value = "Valid";
+});
+testStyle(['fieldset1', 'fieldset2', 'input1', 'fieldset3', 'textarea1']);
+
+debug('');
+debug("Back to invalid. We should be in the initial state.");
+modifyTree(function(root) {
+    root.querySelector('.textarea1').value = "";
+});
+testStyle(['fieldset2', 'input1', 'fieldset3']);
+
+
+debug('');
+debug("Move the invalid text area into fieldset3.");
+modifyTree(function(root) {
+    var textArea = root.querySelector('.textarea1');
+    var fieldset3 = root.querySelector('.fieldset3');
+    fieldset3.appendChild(textArea);
+});
+testStyle(['fieldset1', 'fieldset2', 'input1']);
+
+debug('');
+debug("Make the text area valid.");
+modifyTree(function(root) {
+    root.querySelector('.textarea1').value = "Valid";
+});
+testStyle(['fieldset1', 'fieldset2', 'input1', 'fieldset3', 'textarea1']);
+
+debug('');
+debug("Make the input invalid.");
+modifyTree(function(root) {
+    root.querySelector('.input1').value = "";
+});
+testStyle(['fieldset3', 'textarea1']);
+
+debug('');
+debug("Move text area as a child of fieldset1.");
+modifyTree(function(root) {
+    var textArea = root.querySelector('.textarea1');
+    var fieldset1 = root.querySelector('.fieldset1');
+    fieldset1.appendChild(textArea);
+});
+testStyle(['textarea1', 'fieldset3']);
+
+debug('');
+debug("Move text area as a child of div1.");
+modifyTree(function(root) {
+    var textArea = root.querySelector('.textarea1');
+    var div1 = root.querySelector('.div1');
+    div1.appendChild(textArea);
+});
+testStyle(['textarea1', 'fieldset3']);
+
+debug('');
+debug("Make the text area invalid.");
+modifyTree(function(root) {
+    root.querySelector('.textarea1').value = "";
+});
+testStyle(['fieldset3']);
+
+debug('');
+debug("Make the input valid.");
+modifyTree(function(root) {
+    root.querySelector('.input1').value = "Valid";
+});
+testStyle(['fieldset2', 'input1', 'fieldset3']);
+
+debug('');
+debug("Make the text area valid, everything should be valid.");
+modifyTree(function(root) {
+    root.querySelector('.textarea1').value = "Valid";
+});
+testStyle(['fieldset1', 'fieldset2', 'input1', 'textarea1', 'fieldset3']);
+
+debug('');
+debug("Make the input invalid.");
+modifyTree(function(root) {
+    root.querySelector('.input1').value = "";
+});
+testStyle(['fieldset3', 'textarea1']);
+
+
+debug('');
+debug("Move fieldset2 inside div3");
+modifyTree(function(root) {
+    var fieldset2 = root.querySelector('.fieldset2');
+    var div3 = root.querySelector('.div3');
+    div3.appendChild(fieldset2);
+});
+testStyle(['fieldset1', 'textarea1']);
+
+debug('');
+debug("Destroy the content of div2");
+modifyTree(function(root) {
+    root.querySelector('.div2').textContent = '';
+});
+testStyle(['fieldset1', 'textarea1', 'fieldset3', 'fieldset2']);
+
+// Remove the content otherwise it will appear in the results.
+withRenderer.style.display = 'none';
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</html>
diff --git a/LayoutTests/fast/selectors/valid-fieldset-style-update-2-expected.txt b/LayoutTests/fast/selectors/valid-fieldset-style-update-2-expected.txt
new file mode 100644 (file)
index 0000000..e9b5179
--- /dev/null
@@ -0,0 +1,369 @@
+Test style update for :valid applied on a fieldset.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+
+Initial state
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input4")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input5")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input7")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input8")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input9")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input10")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button4")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input4")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input5")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input7")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input8")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input9")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input10")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button4")).backgroundColor is "rgb(4, 5, 6)"
+
+Change the type of input3 to something that validates.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input4")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input5")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input7")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input8")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input9")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input10")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button4")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input4")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input5")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input7")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input8")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input9")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input10")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button4")).backgroundColor is "rgb(4, 5, 6)"
+
+Change the type of input7 to something that validates.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input4")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input5")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input7")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input8")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input9")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input10")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button4")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input4")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input5")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input7")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input8")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input9")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input10")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button4")).backgroundColor is "rgb(4, 5, 6)"
+
+Change the type of input9 to something that does not validate.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input4")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input5")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input7")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input8")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input9")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input10")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button4")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input4")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input5")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input7")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input8")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input9")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input10")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button4")).backgroundColor is "rgb(4, 5, 6)"
+
+Change the type of input5 to something that does not validate.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input4")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input7")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input8")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input9")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input10")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button4")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input4")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input7")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input8")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input9")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input10")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button4")).backgroundColor is "rgb(4, 5, 6)"
+
+Change the type of input6 to something that does not validate.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input4")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input7")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input8")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input9")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input10")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button4")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input4")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input7")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input8")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input9")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input10")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button4")).backgroundColor is "rgb(4, 5, 6)"
+
+Change the type of input7 to something that does not validate.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input4")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input7")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input8")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input9")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input10")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button4")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input4")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input7")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input8")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input9")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input10")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button4")).backgroundColor is "rgb(4, 5, 6)"
+
+Change the type of input10 to something that does not validate.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input4")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input7")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input8")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input9")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input10")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button4")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input4")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input7")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input8")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input9")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input10")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button4")).backgroundColor is "rgb(4, 5, 6)"
+
+Disable the text area.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input4")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input7")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input8")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input9")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input10")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".button4")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input4")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".textarea1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input7")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input8")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input9")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input10")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".button4")).backgroundColor is "rgb(4, 5, 6)"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/selectors/valid-fieldset-style-update-2.html b/LayoutTests/fast/selectors/valid-fieldset-style-update-2.html
new file mode 100644 (file)
index 0000000..a10275f
--- /dev/null
@@ -0,0 +1,136 @@
+<!doctype html>
+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+<style>
+:matches(#with-renderer, #without-renderer) * {
+    background-color: rgb(1, 2, 3);
+}
+:matches(#with-renderer, #without-renderer) :valid {
+    background-color: rgb(4, 5, 6);
+}
+</style>
+</head>
+<body>
+    <template id="test-source">
+        <fieldset class="fieldset1">
+            <div class="div1">
+                <fieldset class="fieldset2">
+                    <div class="div2">
+                        <input class="input1" required value="valid">
+                        <input class="input2" type="button" required value="valid">
+                        <input class="input3" type="hidden" required value="valid">
+                        <input class="input4" type="email" required value="awesome@webkit.org">
+                        <input class="input5" type="password" required value="valid">
+                        <button class="button1">Base button</button>
+                        <button class="button2" type="submit">Submit button</button>
+                    </div>
+                </fieldset>
+                <textarea class="textarea1" required></textarea>
+                <input class="input6" required>
+                <input class="input7" type="button" required>
+                <input class="input8" type="hidden" required>
+                <input class="input9" type="email" required>
+                <input class="input10" type="password" required>
+                <button class="button3">Base button</button>
+                <button class="button4" type="submit">Submit button</button>
+            </div>
+        </fieldset>
+    </template>
+    <div id="with-renderer"></div>
+    <div id="without-renderer" style="display:none;"></div>
+</body>
+<script>
+description('Test style update for :valid applied on a fieldset.');
+
+var withRenderer = document.getElementById("with-renderer");
+var withoutRenderer = document.getElementById("without-renderer");
+var source = document.getElementById("test-source").content;
+
+withRenderer.appendChild(source.cloneNode(true));
+withoutRenderer.appendChild(source.cloneNode(true));
+
+function testStyleAtId(rootId, matchedClass) {
+    var allElements = document.getElementById(rootId).querySelectorAll('*');
+    for (var i = 0; i < allElements.length; ++i) {
+        var expectedStyle = matchedClass.indexOf(allElements[i].className) >= 0 ? 'rgb(4, 5, 6)' : 'rgb(1, 2, 3)';
+        shouldBeEqualToString('getComputedStyle(document.getElementById("' + rootId + '").querySelector(".' + allElements[i].className + '")).backgroundColor', expectedStyle);
+    }
+}
+
+function testStyle(matchedClass) {
+    testStyleAtId('with-renderer', matchedClass);
+    testStyleAtId('without-renderer', matchedClass);
+}
+
+function modifyTree(updateFunction) {
+    updateFunction(withRenderer);
+    updateFunction(withoutRenderer);
+}
+
+debug('');
+debug('Initial state');
+testStyle(['fieldset2', 'input1', 'input4', 'input5', 'button1', 'button2', 'button3', 'button4']);
+
+debug('');
+debug("Change the type of input3 to something that validates.");
+modifyTree(function(root) {
+    root.querySelector('.input3').type = "search";
+});
+testStyle(['fieldset2', 'input1', 'input3', 'input4', 'input5', 'button1', 'button2', 'button3', 'button4']);
+
+debug('');
+debug("Change the type of input7 to something that validates.");
+modifyTree(function(root) {
+    root.querySelector('.input7').type = "search";
+});
+testStyle(['fieldset2', 'input1', 'input3', 'input4', 'input5', 'button1', 'button2', 'button3', 'button4']);
+
+debug('');
+debug("Change the type of input9 to something that does not validate.");
+modifyTree(function(root) {
+    root.querySelector('.input9').type = "hidden";
+});
+testStyle(['fieldset2', 'input1', 'input3', 'input4', 'input5', 'button1', 'button2', 'button3', 'button4']);
+
+debug('');
+debug("Change the type of input5 to something that does not validate.");
+modifyTree(function(root) {
+    root.querySelector('.input5').type = "button";
+});
+testStyle(['fieldset2', 'input1', 'input3', 'input4', 'button1', 'button2', 'button3', 'button4']);
+
+// Change everything in the second half of controls without validation, eventually, fieldset1 should validate.
+debug('');
+debug("Change the type of input6 to something that does not validate.");
+modifyTree(function(root) {
+    root.querySelector('.input6').type = "button";
+});
+testStyle(['fieldset2', 'input1', 'input3', 'input4', 'button1', 'button2', 'button3', 'button4']);
+
+debug('');
+debug("Change the type of input7 to something that does not validate.");
+modifyTree(function(root) {
+    root.querySelector('.input7').type = "reset";
+});
+testStyle(['fieldset2', 'input1', 'input3', 'input4', 'button1', 'button2', 'button3', 'button4']);
+
+debug('');
+debug("Change the type of input10 to something that does not validate.");
+modifyTree(function(root) {
+    root.querySelector('.input10').type = "reset";
+});
+testStyle(['fieldset2', 'input1', 'input3', 'input4', 'button1', 'button2', 'button3', 'button4']);
+
+debug('');
+debug("Disable the text area.");
+modifyTree(function(root) {
+    root.querySelector('.textarea1').setAttribute('disabled', '');
+});
+testStyle(['fieldset1', 'fieldset2', 'input1', 'input3', 'input4', 'button1', 'button2', 'button3', 'button4']);
+
+// Remove the content otherwise it will appear in the results.
+withRenderer.style.display = 'none';
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</html>
diff --git a/LayoutTests/fast/selectors/valid-fieldset-style-update-3-expected.txt b/LayoutTests/fast/selectors/valid-fieldset-style-update-3-expected.txt
new file mode 100644 (file)
index 0000000..10a042f
--- /dev/null
@@ -0,0 +1,195 @@
+Test style update for :valid applied on a fieldset.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+
+Initial state
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+
+Add input1 to fieldset1.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+
+Add input2 to fieldset1.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+
+Add input3 to fieldset1.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+
+Add input4 to fieldset2.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+
+Add input5 to fieldset2.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+
+Add input6 to fieldset2.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input6")).backgroundColor is "rgb(1, 2, 3)"
+
+Enable fieldset2.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input4")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input6")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input4")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input6")).backgroundColor is "rgb(4, 5, 6)"
+
+Disable fieldset1.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input4")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input6")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input4")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input6")).backgroundColor is "rgb(4, 5, 6)"
+
+Remove input1
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input4")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input6")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input4")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input6")).backgroundColor is "rgb(4, 5, 6)"
+
+Remove input2
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input4")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input6")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input4")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input6")).backgroundColor is "rgb(4, 5, 6)"
+
+Remove input3
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input4")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input6")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input4")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input6")).backgroundColor is "rgb(4, 5, 6)"
+
+Remove input4
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input6")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input5")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input6")).backgroundColor is "rgb(4, 5, 6)"
+
+Remove input5
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input6")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input6")).backgroundColor is "rgb(4, 5, 6)"
+
+Remove input6
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/selectors/valid-fieldset-style-update-3.html b/LayoutTests/fast/selectors/valid-fieldset-style-update-3.html
new file mode 100644 (file)
index 0000000..b5439fd
--- /dev/null
@@ -0,0 +1,183 @@
+<!doctype html>
+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+<style>
+:matches(#with-renderer, #without-renderer) * {
+    background-color: rgb(1, 2, 3);
+}
+:matches(#with-renderer, #without-renderer) :valid {
+    background-color: rgb(4, 5, 6);
+}
+</style>
+</head>
+<body>
+    <template id="test-source">
+        <fieldset class="fieldset1">
+        </fieldset>
+        <fieldset class="fieldset2" disabled>
+        </fieldset>
+    </template>
+    <div id="with-renderer"></div>
+    <div id="without-renderer" style="display:none;"></div>
+</body>
+<script>
+description('Test style update for :valid applied on a fieldset.');
+
+var withRenderer = document.getElementById("with-renderer");
+var withoutRenderer = document.getElementById("without-renderer");
+var source = document.getElementById("test-source").content;
+
+withRenderer.appendChild(source.cloneNode(true));
+withoutRenderer.appendChild(source.cloneNode(true));
+
+function testStyleAtId(rootId, matchedClass) {
+    var allElements = document.getElementById(rootId).querySelectorAll('*');
+    for (var i = 0; i < allElements.length; ++i) {
+        var expectedStyle = matchedClass.indexOf(allElements[i].className) >= 0 ? 'rgb(4, 5, 6)' : 'rgb(1, 2, 3)';
+        shouldBeEqualToString('getComputedStyle(document.getElementById("' + rootId + '").querySelector(".' + allElements[i].className + '")).backgroundColor', expectedStyle);
+    }
+}
+
+function testStyle(matchedClass) {
+    testStyleAtId('with-renderer', matchedClass);
+    testStyleAtId('without-renderer', matchedClass);
+}
+
+function modifyTree(updateFunction) {
+    updateFunction(withRenderer);
+    updateFunction(withoutRenderer);
+}
+
+debug('');
+debug('Initial state');
+testStyle(['fieldset1', 'fieldset2']);
+
+debug('');
+debug("Add input1 to fieldset1.");
+modifyTree(function(root) {
+    var input1 = document.createElement('input');
+    input1.className = 'input1';
+    root.querySelector('.fieldset1').appendChild(input1);
+});
+testStyle(['fieldset1', 'input1', 'fieldset2']);
+
+debug('');
+debug("Add input2 to fieldset1.");
+modifyTree(function(root) {
+    var input2 = document.createElement('input');
+    input2.className = 'input2';
+    input2.setAttribute('required', '');
+    root.querySelector('.fieldset1').appendChild(input2);
+});
+testStyle(['input1', 'fieldset2']);
+
+debug('');
+debug("Add input3 to fieldset1.");
+modifyTree(function(root) {
+    var input3 = document.createElement('input');
+    input3.className = 'input3';
+    input3.setAttribute('required', '');
+    input3.value = "valid";
+    root.querySelector('.fieldset1').appendChild(input3);
+});
+testStyle(['input1', 'input3', 'fieldset2']);
+
+debug('');
+debug("Add input4 to fieldset2.");
+modifyTree(function(root) {
+    var input4 = document.createElement('input');
+    input4.className = 'input4';
+    root.querySelector('.fieldset2').appendChild(input4);
+});
+testStyle(['input1', 'input3', 'fieldset2']);
+
+debug('');
+debug("Add input5 to fieldset2.");
+modifyTree(function(root) {
+    var input5 = document.createElement('input');
+    input5.className = 'input5';
+    input5.setAttribute('required', '');
+    root.querySelector('.fieldset2').appendChild(input5);
+});
+testStyle(['input1', 'input3', 'fieldset2']);
+
+debug('');
+debug("Add input6 to fieldset2.");
+modifyTree(function(root) {
+    var input6 = document.createElement('input');
+    input6.className = 'input6';
+    input6.setAttribute('required', '');
+    input6.value = "valid"
+    root.querySelector('.fieldset2').appendChild(input6);
+});
+testStyle(['input1', 'input3', 'fieldset2']);
+
+debug('');
+debug("Enable fieldset2.");
+modifyTree(function(root) {
+    root.querySelector('.fieldset2').removeAttribute('disabled');
+});
+testStyle(['input1', 'input3', 'input4', 'input6']);
+
+debug('');
+debug("Disable fieldset1.");
+modifyTree(function(root) {
+    root.querySelector('.fieldset1').setAttribute('disabled', '');
+});
+testStyle(['fieldset1', 'input4', 'input6']);
+
+debug('');
+debug("Remove input1");
+modifyTree(function(root) {
+    var input = root.querySelector('.input1');
+    input.parentNode.removeChild(input);
+});
+testStyle(['fieldset1', 'input4', 'input6']);
+
+debug('');
+debug("Remove input2");
+modifyTree(function(root) {
+    var input = root.querySelector('.input2');
+    input.parentNode.removeChild(input);
+});
+testStyle(['fieldset1', 'input4', 'input6']);
+
+debug('');
+debug("Remove input3");
+modifyTree(function(root) {
+    var input = root.querySelector('.input3');
+    input.parentNode.removeChild(input);
+});
+testStyle(['fieldset1', 'input4', 'input6']);
+
+debug('');
+debug("Remove input4");
+modifyTree(function(root) {
+    var input = root.querySelector('.input4');
+    input.parentNode.removeChild(input);
+});
+testStyle(['fieldset1', 'input6']);
+
+debug('');
+debug("Remove input5");
+modifyTree(function(root) {
+    var input = root.querySelector('.input5');
+    input.parentNode.removeChild(input);
+});
+testStyle(['fieldset1', 'fieldset2', 'input6']);
+
+debug('');
+debug("Remove input6");
+modifyTree(function(root) {
+    var input = root.querySelector('.input6');
+    input.parentNode.removeChild(input);
+});
+testStyle(['fieldset1', 'fieldset2']);
+
+
+// Remove the content otherwise it will appear in the results.
+withRenderer.style.display = 'none';
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</html>
diff --git a/LayoutTests/fast/selectors/valid-fieldset-style-update-4-expected.txt b/LayoutTests/fast/selectors/valid-fieldset-style-update-4-expected.txt
new file mode 100644 (file)
index 0000000..9fa9291
--- /dev/null
@@ -0,0 +1,191 @@
+Test style update for :valid applied on a fieldset.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+
+Initial state
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+
+Add input1 to fieldset1.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+
+Disable input1.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+
+Re-enable input1.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+
+Make input1 readonly.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+
+Add input2 to fieldset2.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+
+Disable input2.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+
+Re-enable input2.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+
+Make input2 readonly.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+
+Add input3 to fieldset1.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+
+Disable input3.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+
+Re-enable input3.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+
+Make input3 readonly.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+
+Add input4 to fieldset2.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+
+Disable input4.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+
+Re-enable input4.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+
+Make input4 readonly.
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input4")).backgroundColor is "rgb(1, 2, 3)"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/selectors/valid-fieldset-style-update-4.html b/LayoutTests/fast/selectors/valid-fieldset-style-update-4.html
new file mode 100644 (file)
index 0000000..def30cb
--- /dev/null
@@ -0,0 +1,182 @@
+<!doctype html>
+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+<style>
+:matches(#with-renderer, #without-renderer) * {
+    background-color: rgb(1, 2, 3);
+}
+:matches(#with-renderer, #without-renderer) :valid {
+    background-color: rgb(4, 5, 6);
+}
+</style>
+</head>
+<body>
+    <template id="test-source">
+        <fieldset class="fieldset1">
+        </fieldset>
+        <fieldset class="fieldset2" disabled>
+        </fieldset>
+    </template>
+    <div id="with-renderer"></div>
+    <div id="without-renderer" style="display:none;"></div>
+</body>
+<script>
+description('Test style update for :valid applied on a fieldset.');
+
+var withRenderer = document.getElementById("with-renderer");
+var withoutRenderer = document.getElementById("without-renderer");
+var source = document.getElementById("test-source").content;
+
+withRenderer.appendChild(source.cloneNode(true));
+withoutRenderer.appendChild(source.cloneNode(true));
+
+function testStyleAtId(rootId, matchedClass) {
+    var allElements = document.getElementById(rootId).querySelectorAll('*');
+    for (var i = 0; i < allElements.length; ++i) {
+        var expectedStyle = matchedClass.indexOf(allElements[i].className) >= 0 ? 'rgb(4, 5, 6)' : 'rgb(1, 2, 3)';
+        shouldBeEqualToString('getComputedStyle(document.getElementById("' + rootId + '").querySelector(".' + allElements[i].className + '")).backgroundColor', expectedStyle);
+    }
+}
+
+function testStyle(matchedClass) {
+    testStyleAtId('with-renderer', matchedClass);
+    testStyleAtId('without-renderer', matchedClass);
+}
+
+function modifyTree(updateFunction) {
+    updateFunction(withRenderer);
+    updateFunction(withoutRenderer);
+}
+
+debug('');
+debug('Initial state');
+testStyle(['fieldset1', 'fieldset2']);
+
+debug('');
+debug("Add input1 to fieldset1.");
+modifyTree(function(root) {
+    var input1 = document.createElement('input');
+    input1.className = 'input1';
+    root.querySelector('.fieldset1').appendChild(input1);
+});
+testStyle(['fieldset1', 'input1', 'fieldset2']);
+
+debug('');
+debug("Disable input1.");
+modifyTree(function(root) {
+    root.querySelector('.input1').setAttribute('disabled', '');
+});
+testStyle(['fieldset1', 'fieldset2']);
+
+debug('');
+debug("Re-enable input1.");
+modifyTree(function(root) {
+    root.querySelector('.input1').removeAttribute('disabled');
+});
+testStyle(['fieldset1', 'input1', 'fieldset2']);
+
+debug('');
+debug("Make input1 readonly.");
+modifyTree(function(root) {
+    root.querySelector('.input1').setAttribute('readonly', '');
+});
+testStyle(['fieldset1', 'fieldset2']);
+
+debug('');
+debug("Add input2 to fieldset2.");
+modifyTree(function(root) {
+    var input2 = document.createElement('input');
+    input2.className = 'input2';
+    root.querySelector('.fieldset2').appendChild(input2);
+});
+testStyle(['fieldset1', 'fieldset2']);
+
+debug('');
+debug("Disable input2.");
+modifyTree(function(root) {
+    root.querySelector('.input2').setAttribute('disabled', '');
+});
+testStyle(['fieldset1', 'fieldset2']);
+
+debug('');
+debug("Re-enable input2.");
+modifyTree(function(root) {
+    root.querySelector('.input2').removeAttribute('disabled');
+});
+testStyle(['fieldset1', 'fieldset2']);
+
+debug('');
+debug("Make input2 readonly.");
+modifyTree(function(root) {
+    root.querySelector('.input2').setAttribute('readonly', '');
+});
+testStyle(['fieldset1', 'fieldset2']);
+
+debug('');
+debug("Add input3 to fieldset1.");
+modifyTree(function(root) {
+    var input3 = document.createElement('input');
+    input3.className = 'input3';
+    input3.setAttribute('required', '');
+    root.querySelector('.fieldset1').appendChild(input3);
+});
+testStyle(['fieldset2']);
+
+debug('');
+debug("Disable input3.");
+modifyTree(function(root) {
+    root.querySelector('.input3').setAttribute('disabled', '');
+});
+testStyle(['fieldset1', 'fieldset2']);
+
+debug('');
+debug("Re-enable input3.");
+modifyTree(function(root) {
+    root.querySelector('.input3').removeAttribute('disabled');
+});
+testStyle(['fieldset2']);
+
+debug('');
+debug("Make input3 readonly.");
+modifyTree(function(root) {
+    root.querySelector('.input3').setAttribute('readonly', '');
+});
+testStyle(['fieldset1', 'fieldset2']);
+
+debug('');
+debug("Add input4 to fieldset2.");
+modifyTree(function(root) {
+    var input4 = document.createElement('input');
+    input4.className = 'input4';
+    input4.setAttribute('required', '');
+    root.querySelector('.fieldset2').appendChild(input4);
+});
+testStyle(['fieldset1', 'fieldset2']);
+
+debug('');
+debug("Disable input4.");
+modifyTree(function(root) {
+    root.querySelector('.input4').setAttribute('disabled', '');
+});
+testStyle(['fieldset1', 'fieldset2']);
+
+debug('');
+debug("Re-enable input4.");
+modifyTree(function(root) {
+    root.querySelector('.input4').removeAttribute('disabled');
+});
+testStyle(['fieldset1', 'fieldset2']);
+
+debug('');
+debug("Make input4 readonly.");
+modifyTree(function(root) {
+    root.querySelector('.input4').setAttribute('readonly', '');
+});
+testStyle(['fieldset1', 'fieldset2']);
+
+// Remove the content otherwise it will appear in the results.
+withRenderer.style.display = 'none';
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</html>
diff --git a/LayoutTests/fast/selectors/valid-fieldset-style-update-5-expected.txt b/LayoutTests/fast/selectors/valid-fieldset-style-update-5-expected.txt
new file mode 100644 (file)
index 0000000..ab19830
--- /dev/null
@@ -0,0 +1,23 @@
+Test style update for :valid applied on a fieldset.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+
+Move fieldset2 inside div3
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("with-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset1")).backgroundColor is "rgb(4, 5, 6)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div1")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div3")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".fieldset2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".div2")).backgroundColor is "rgb(1, 2, 3)"
+PASS getComputedStyle(document.getElementById("without-renderer").querySelector(".input1")).backgroundColor is "rgb(1, 2, 3)"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/selectors/valid-fieldset-style-update-5.html b/LayoutTests/fast/selectors/valid-fieldset-style-update-5.html
new file mode 100644 (file)
index 0000000..d6f18d3
--- /dev/null
@@ -0,0 +1,73 @@
+<!doctype html>
+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+<style>
+:matches(#with-renderer, #without-renderer) * {
+    background-color: rgb(1, 2, 3);
+}
+:matches(#with-renderer, #without-renderer) :valid {
+    background-color: rgb(4, 5, 6);
+}
+</style>
+</head>
+<body>
+    <template id="test-source">
+        <fieldset class="fieldset1">
+            <div class="div1">
+                <fieldset class="fieldset2">
+                    <div class="div2">
+                        <input class="input1" required value="">
+                    </div>
+                </fieldset>
+            </div>
+        </fieldset>
+        <div class="div3">
+        </div>
+    </template>
+    <div id="with-renderer"></div>
+    <div id="without-renderer" style="display:none;"></div>
+</body>
+<script>
+description('Test style update for :valid applied on a fieldset.');
+
+var withRenderer = document.getElementById("with-renderer");
+var withoutRenderer = document.getElementById("without-renderer");
+var source = document.getElementById("test-source").content;
+
+withRenderer.appendChild(source.cloneNode(true));
+withoutRenderer.appendChild(source.cloneNode(true));
+
+function testStyleAtId(rootId, matchedClass) {
+    var allElements = document.getElementById(rootId).querySelectorAll('*');
+    for (var i = 0; i < allElements.length; ++i) {
+        var expectedStyle = matchedClass.indexOf(allElements[i].className) >= 0 ? 'rgb(4, 5, 6)' : 'rgb(1, 2, 3)';
+        shouldBeEqualToString('getComputedStyle(document.getElementById("' + rootId + '").querySelector(".' + allElements[i].className + '")).backgroundColor', expectedStyle);
+    }
+}
+
+function testStyle(matchedClass) {
+    testStyleAtId('with-renderer', matchedClass);
+    testStyleAtId('without-renderer', matchedClass);
+}
+
+function modifyTree(updateFunction) {
+    updateFunction(withRenderer);
+    updateFunction(withoutRenderer);
+}
+
+debug('');
+debug("Move fieldset2 inside div3");
+modifyTree(function(root) {
+    var fieldset2 = root.querySelector('.fieldset2');
+    var div3 = root.querySelector('.div3');
+    div3.appendChild(fieldset2);
+});
+testStyle(['fieldset1']);
+
+
+// Remove the content otherwise it will appear in the results.
+withRenderer.style.display = 'none';
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</html>
index 010615b..e530dd4 100644 (file)
@@ -1,3 +1,133 @@
+2014-11-16  Benjamin Poulain  <benjamin@webkit.org>
+
+        Implement :valid and :invalid matching for the fieldset element
+        https://bugs.webkit.org/show_bug.cgi?id=138769
+
+        Reviewed by Darin Adler.
+
+        In the latest HTML spec, the pseudo classes :valid and :invalid match
+        a fieldset element based on its descendants:
+            https://html.spec.whatwg.org/#selector-valid
+            https://html.spec.whatwg.org/#selector-invalid
+
+        This patch adds that behavior.
+
+        There are two key problems to solve with these pseudo classes on fieldset:
+        -Efficient matching.
+        -Style invalidation when any of the descendant changes.
+
+        To implement the style invalidation, I have modified HTMLFormControlElement
+        to notify its ancestor when its state changes.
+
+        The first change is making the state fully internal to HTMLFormControlElement,
+        we do not want subclass to be able to change the behavior and forget to update
+        the ancestors.
+
+        To achieve that encapsulation, the interface was changed a bit:
+        -Neither willValidate() nor isValidFormControlElement() inherit from Element.
+         Instead, willValidate() is the implementation of FormAssociatedElement's interface
+         and it is final. The method isValidFormControlElement() becomes completely internal
+         to HTMLFormControlElement.
+        -Since willValidate() should no longer be re-implemented by subclass, the elements
+         that were depending on it have been migrated to recalcWillValidate() to set
+         the initial state as needed.
+
+        With the validity state fully encapsulated in HTMLFormControlElement, all I need
+        is a way to communicate that information to HTMLFieldSetElement ancestors.
+        This is done in two cases:
+        -The validity state changes.
+        -The tree changes in a way that would make the input element not a descendant
+         of a HTMLFieldSetElement.
+
+        The invalidation is simply done by walking up the ancestors and adding the current
+        element to a "validity dependency list" on each HTMLFieldSetElement.
+
+        Tests: fast/css/pseudo-invalid-fieldset-invalidation-optimization.html
+               fast/css/pseudo-invalid-fieldset-style-sharing.html
+               fast/css/pseudo-invalid-fieldset.html
+               fast/css/pseudo-valid-fieldset-invalidation-optimization.html
+               fast/css/pseudo-valid-fieldset-style-sharing.html
+               fast/css/pseudo-valid-fieldset.html
+               fast/selectors/invalid-fieldset-style-update-1.html
+               fast/selectors/invalid-fieldset-style-update-2.html
+               fast/selectors/invalid-fieldset-style-update-3.html
+               fast/selectors/invalid-fieldset-style-update-4.html
+               fast/selectors/invalid-fieldset-style-update-5.html
+               fast/selectors/valid-fieldset-style-update-1.html
+               fast/selectors/valid-fieldset-style-update-2.html
+               fast/selectors/valid-fieldset-style-update-3.html
+               fast/selectors/valid-fieldset-style-update-4.html
+               fast/selectors/valid-fieldset-style-update-5.html
+
+        * css/SelectorCheckerTestFunctions.h:
+        (WebCore::isInRange):
+        (WebCore::isOutOfRange):
+        (WebCore::isInvalid):
+        (WebCore::isValid):
+        The hack "ContainsValidityStyleRules" is in the way of correct styling
+        of FieldSet and Form.
+        It is not the right way to get stylesheet properties anyway.
+
+        * css/StyleResolver.cpp:
+        (WebCore::StyleResolver::canShareStyleWithControl):
+        Make sure style sharing does not incorrectly share style for fieldset elements.
+
+        * dom/Document.cpp:
+        (WebCore::Document::Document):
+        * dom/Document.h:
+        (WebCore::Document::containsValidityStyleRules): Deleted.
+        (WebCore::Document::setContainsValidityStyleRules): Deleted.
+        * dom/Element.h:
+        (WebCore::Element::matchesValidPseudoClass):
+        (WebCore::Element::matchesInvalidPseudoClass):
+        (WebCore::Element::willValidate): Deleted.
+        (WebCore::Element::isValidFormControlElement): Deleted.
+        * html/FormAssociatedElement.cpp:
+        (WebCore::FormAssociatedElement::customError):
+        * html/FormAssociatedElement.h:
+
+        * html/HTMLFieldSetElement.cpp:
+        (WebCore::HTMLFieldSetElement::matchesValidPseudoClass):
+        (WebCore::HTMLFieldSetElement::matchesInvalidPseudoClass):
+        (WebCore::HTMLFieldSetElement::addInvalidDescendant):
+        (WebCore::HTMLFieldSetElement::removeInvalidDescendant):
+        Each HTMLFormControlElement that has constraint validation adds or removes
+        itself from its HTMLFieldSetElement ancestors.
+
+        It should be possible to just keep track of a count instead of a HashSet.
+        I decided to got with the HashSet to make the code more robust and easier
+        to debug. A few assertions ensure that the HashSet is actually used as a counter.
+
+        * html/HTMLFieldSetElement.h:
+        * html/HTMLFormControlElement.cpp:
+        (WebCore::addInvalidElementToAncestorFromInsertionPoint):
+        (WebCore::removeInvalidElementToAncestorFromInsertionPoint):
+
+        (WebCore::HTMLFormControlElement::insertedInto):
+        (WebCore::HTMLFormControlElement::removedFrom):
+        One tricky part of those two functions is that we cannot use
+        matchesValidPseudoClass() or matchesInvalidPseudoClass().
+
+        The reason is that HTMLFieldSetElement is a subclass of HTMLFormControlElement
+        and it has its own definition of what Valid and Invalid mean when matching selectors.
+
+        In HTMLFormControlElement, we must use the internal state,
+        willValidate() and isValidFormControlElement() must be used directly.
+
+        (WebCore::HTMLFormControlElement::matchesValidPseudoClass):
+        (WebCore::HTMLFormControlElement::matchesInvalidPseudoClass):
+        (WebCore::HTMLFormControlElement::willValidate):
+        (WebCore::addInvalidElementToAncestors):
+        (WebCore::removeInvalidElementFromAncestors):
+        (WebCore::HTMLFormControlElement::setNeedsWillValidateCheck):
+        (WebCore::HTMLFormControlElement::setNeedsValidityCheck):
+        (WebCore::HTMLFormControlElement::isValidFormControlElement): Deleted.
+        * html/HTMLFormControlElement.h:
+        (WebCore::HTMLFormControlElement::isValidFormControlElement):
+        * html/HTMLKeygenElement.h:
+        * html/HTMLObjectElement.h:
+        * html/HTMLOutputElement.h:
+
 2014-11-16  Zan Dobersek  <zdobersek@igalia.com>
 
         [TexMap] Add typecasting support for GraphicsLayerTextureMapper
index afdad99..7f9d808 100644 (file)
@@ -86,20 +86,17 @@ ALWAYS_INLINE bool isChecked(Element* element)
 
 ALWAYS_INLINE bool isInRange(Element* element)
 {
-    element->document().setContainsValidityStyleRules();
     return element->isInRange();
 }
 
 ALWAYS_INLINE bool isOutOfRange(Element* element)
 {
-    element->document().setContainsValidityStyleRules();
     return element->isOutOfRange();
 }
 
 ALWAYS_INLINE bool isInvalid(const Element* element)
 {
-    element->document().setContainsValidityStyleRules();
-    return element->willValidate() && !element->isValidFormControlElement();
+    return element->matchesInvalidPseudoClass();
 }
 
 ALWAYS_INLINE bool isOptionalFormControl(const Element* element)
@@ -114,8 +111,7 @@ ALWAYS_INLINE bool isRequiredFormControl(const Element* element)
 
 ALWAYS_INLINE bool isValid(const Element* element)
 {
-    element->document().setContainsValidityStyleRules();
-    return element->willValidate() && element->isValidFormControlElement();
+    return element->matchesValidPseudoClass();
 }
 
 ALWAYS_INLINE bool isWindowInactive(const Element* element)
index 0604e35..caa6fd1 100644 (file)
@@ -525,21 +525,17 @@ bool StyleResolver::canShareStyleWithControl(StyledElement* element) const
     if (element->isDefaultButtonForForm() != state.element()->isDefaultButtonForForm())
         return false;
 
-    if (state.document().containsValidityStyleRules()) {
-        bool willValidate = element->willValidate();
-
-        if (willValidate != state.element()->willValidate())
-            return false;
+    if (element->matchesValidPseudoClass() != state.element()->matchesValidPseudoClass())
+        return false;
 
-        if (willValidate && (element->isValidFormControlElement() != state.element()->isValidFormControlElement()))
-            return false;
+    if (element->matchesInvalidPseudoClass() != state.element()->matchesValidPseudoClass())
+        return false;
 
-        if (element->isInRange() != state.element()->isInRange())
-            return false;
+    if (element->isInRange() != state.element()->isInRange())
+        return false;
 
-        if (element->isOutOfRange() != state.element()->isOutOfRange())
-            return false;
-    }
+    if (element->isOutOfRange() != state.element()->isOutOfRange())
+        return false;
 
     return true;
 }
index f2194b7..d2cb1a0 100644 (file)
@@ -440,7 +440,6 @@ Document::Document(Frame* frame, const URL& url, unsigned documentClasses, unsig
     , m_closeAfterStyleRecalc(false)
     , m_gotoAnchorNeededAfterStylesheetsLoad(false)
     , m_frameElementsShouldIgnoreScrolling(false)
-    , m_containsValidityStyleRules(false)
     , m_updateFocusAppearanceRestoresSelection(false)
     , m_ignoreDestructiveWriteCount(0)
     , m_titleSetExplicitly(false)
index bc36139..8b413e6 100644 (file)
@@ -1108,9 +1108,6 @@ public:
     virtual bool isContextThread() const override final;
     virtual bool isJSExecutionForbidden() const override final { return false; }
 
-    bool containsValidityStyleRules() const { return m_containsValidityStyleRules; }
-    void setContainsValidityStyleRules() { m_containsValidityStyleRules = true; }
-
     void enqueueWindowEvent(PassRefPtr<Event>);
     void enqueueDocumentEvent(PassRefPtr<Event>);
     void enqueueOverflowEvent(PassRefPtr<Event>);
@@ -1478,7 +1475,6 @@ private:
     bool m_isDNSPrefetchEnabled;
     bool m_haveExplicitlyDisabledDNSPrefetch;
     bool m_frameElementsShouldIgnoreScrolling;
-    bool m_containsValidityStyleRules;
     bool m_updateFocusAppearanceRestoresSelection;
 
     // http://www.whatwg.org/specs/web-apps/current-work/#ignore-destructive-writes-counter
index c50ccfb..8ef3566 100644 (file)
@@ -453,14 +453,14 @@ public:
     virtual bool isMediaElement() const { return false; }
 #endif
 
+    virtual bool matchesValidPseudoClass() const { return false; }
+    virtual bool matchesInvalidPseudoClass() const { return false; }
     virtual bool isFormControlElement() const { return false; }
     virtual bool isSpinButtonElement() const { return false; }
     virtual bool isTextFormControl() const { return false; }
     virtual bool isOptionalFormControl() const { return false; }
     virtual bool isRequiredFormControl() const { return false; }
     virtual bool isDefaultButtonForForm() const { return false; }
-    virtual bool willValidate() const { return false; }
-    virtual bool isValidFormControlElement() const { return false; }
     virtual bool isInRange() const { return false; }
     virtual bool isOutOfRange() const { return false; }
     virtual bool isFrameElementBase() const { return false; }
index 92d3816..f927c6e 100644 (file)
@@ -175,7 +175,7 @@ void FormAssociatedElement::formAttributeChanged()
 
 bool FormAssociatedElement::customError() const
 {
-    return asHTMLElement().willValidate() && !m_customValidationMessage.isEmpty();
+    return willValidate() && !m_customValidationMessage.isEmpty();
 }
 
 bool FormAssociatedElement::hasBadInput() const
index a8512a0..7df6c39 100644 (file)
@@ -106,6 +106,7 @@ protected:
     String customValidationMessage() const;
 
 private:
+    virtual bool willValidate() const = 0;
     virtual void refFormAssociatedElement() = 0;
     virtual void derefFormAssociatedElement() = 0;
 
index fa31e5d..2fe4a62 100644 (file)
@@ -128,6 +128,16 @@ void HTMLFieldSetElement::didMoveToNewDocument(Document* oldDocument)
     }
 }
 
+bool HTMLFieldSetElement::matchesValidPseudoClass() const
+{
+    return m_invalidDescendants.isEmpty();
+}
+
+bool HTMLFieldSetElement::matchesInvalidPseudoClass() const
+{
+    return !m_invalidDescendants.isEmpty();
+}
+
 bool HTMLFieldSetElement::supportsFocus() const
 {
     return HTMLElement::supportsFocus();
@@ -189,4 +199,25 @@ unsigned HTMLFieldSetElement::length() const
     return length;
 }
 
+void HTMLFieldSetElement::addInvalidDescendant(const HTMLFormControlElement& invalidFormControlElement)
+{
+    ASSERT_WITH_MESSAGE(!is<HTMLFieldSetElement>(invalidFormControlElement), "FieldSet are never candidates for constraint validation.");
+    ASSERT(static_cast<const Element&>(invalidFormControlElement).matchesInvalidPseudoClass());
+    ASSERT_WITH_MESSAGE(!m_invalidDescendants.contains(&invalidFormControlElement), "Updating the fieldset on validity change is not an efficient operation, it should only be done when necessary.");
+
+    if (m_invalidDescendants.isEmpty())
+        setNeedsStyleRecalc();
+    m_invalidDescendants.add(&invalidFormControlElement);
+}
+
+void HTMLFieldSetElement::removeInvalidDescendant(const HTMLFormControlElement& formControlElement)
+{
+    ASSERT_WITH_MESSAGE(!is<HTMLFieldSetElement>(formControlElement), "FieldSet are never candidates for constraint validation.");
+    ASSERT_WITH_MESSAGE(m_invalidDescendants.contains(&formControlElement), "Updating the fieldset on validity change is not an efficient operation, it should only be done when necessary.");
+
+    m_invalidDescendants.remove(&formControlElement);
+    if (m_invalidDescendants.isEmpty())
+        setNeedsStyleRecalc();
+}
+
 } // namespace
index 3a02230..fcb3463 100644 (file)
@@ -25,6 +25,7 @@
 #define HTMLFieldSetElement_h
 
 #include "HTMLFormControlElement.h"
+#include <wtf/HashSet.h>
 
 namespace WebCore {
 
@@ -41,7 +42,8 @@ public:
     const Vector<FormAssociatedElement*>& associatedElements() const;
     unsigned length() const;
 
-protected:
+    void addInvalidDescendant(const HTMLFormControlElement&);
+    void removeInvalidDescendant(const HTMLFormControlElement&);
 
 private:
     HTMLFieldSetElement(const QualifiedName&, Document&, HTMLFormElement*);
@@ -57,11 +59,15 @@ private:
     virtual void childrenChanged(const ChildChange&) override;
     virtual void didMoveToNewDocument(Document* oldDocument) override;
 
+    virtual bool matchesValidPseudoClass() const override;
+    virtual bool matchesInvalidPseudoClass() const override;
+
     void refreshElementsIfNeeded() const;
 
     mutable Vector<FormAssociatedElement*> m_associatedElements;
     // When dom tree is modified, we have to refresh the m_associatedElements array.
     mutable uint64_t m_documentVersion;
+    HashSet<const HTMLFormControlElement*> m_invalidDescendants;
 };
 
 } // namespace
index aa8d071..cbcd206 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "Attribute.h"
 #include "ControlStates.h"
+#include "ElementAncestorIterator.h"
 #include "Event.h"
 #include "EventHandler.h"
 #include "EventNames.h"
@@ -230,25 +231,52 @@ void HTMLFormControlElement::didMoveToNewDocument(Document* oldDocument)
     HTMLElement::didMoveToNewDocument(oldDocument);
 }
 
+static void addInvalidElementToAncestorFromInsertionPoint(const HTMLFormControlElement& element, ContainerNode* insertionPoint)
+{
+    if (!is<Element>(insertionPoint))
+        return;
+
+    for (auto& ancestor : lineageOfType<HTMLFieldSetElement>(downcast<Element>(*insertionPoint)))
+        ancestor.addInvalidDescendant(element);
+}
+
+static void removeInvalidElementToAncestorFromInsertionPoint(const HTMLFormControlElement& element, ContainerNode* insertionPoint)
+{
+    if (!is<Element>(insertionPoint))
+        return;
+
+    for (auto& ancestor : lineageOfType<HTMLFieldSetElement>(downcast<Element>(*insertionPoint)))
+        ancestor.removeInvalidDescendant(element);
+}
+
 Node::InsertionNotificationRequest HTMLFormControlElement::insertedInto(ContainerNode& insertionPoint)
 {
+    if (willValidate() && !isValidFormControlElement())
+        addInvalidElementToAncestorFromInsertionPoint(*this, &insertionPoint);
+
     if (document().hasDisabledFieldsetElement())
         setAncestorDisabled(computeIsDisabledByFieldsetAncestor());
     m_dataListAncestorState = Unknown;
     setNeedsWillValidateCheck();
     HTMLElement::insertedInto(insertionPoint);
     FormAssociatedElement::insertedInto(insertionPoint);
+
     return InsertionDone;
 }
 
 void HTMLFormControlElement::removedFrom(ContainerNode& insertionPoint)
 {
+    bool wasMatchingInvalidPseudoClass = willValidate() && !isValidFormControlElement();
+
     m_validationMessage = nullptr;
     if (m_disabledByAncestorFieldset)
         setAncestorDisabled(computeIsDisabledByFieldsetAncestor());
     m_dataListAncestorState = Unknown;
     HTMLElement::removedFrom(insertionPoint);
     FormAssociatedElement::removedFrom(insertionPoint);
+
+    if (wasMatchingInvalidPseudoClass)
+        removeInvalidElementToAncestorFromInsertionPoint(*this, &insertionPoint);
 }
 
 void HTMLFormControlElement::setChangedSinceLastFormControlChangeEvent(bool changed)
@@ -329,6 +357,16 @@ bool HTMLFormControlElement::isMouseFocusable() const
 #endif
 }
 
+bool HTMLFormControlElement::matchesValidPseudoClass() const
+{
+    return willValidate() && isValidFormControlElement();
+}
+
+bool HTMLFormControlElement::matchesInvalidPseudoClass() const
+{
+    return willValidate() && !isValidFormControlElement();
+}
+
 short HTMLFormControlElement::tabIndex() const
 {
     // Skip the supportsFocus check in HTMLElement.
@@ -355,10 +393,8 @@ bool HTMLFormControlElement::willValidate() const
     if (!m_willValidateInitialized || m_dataListAncestorState == Unknown) {
         m_willValidateInitialized = true;
         bool newWillValidate = recalcWillValidate();
-        if (m_willValidate != newWillValidate) {
+        if (m_willValidate != newWillValidate)
             m_willValidate = newWillValidate;
-            const_cast<HTMLFormControlElement*>(this)->setNeedsValidityCheck();
-        }
     } else {
         // If the following assertion fails, setNeedsWillValidateCheck() is not
         // called correctly when something which changes recalcWillValidate() result
@@ -374,10 +410,18 @@ void HTMLFormControlElement::setNeedsWillValidateCheck()
     bool newWillValidate = recalcWillValidate();
     if (m_willValidateInitialized && m_willValidate == newWillValidate)
         return;
+
+    bool wasValid = m_isValid;
+
     m_willValidateInitialized = true;
     m_willValidate = newWillValidate;
+
     setNeedsValidityCheck();
     setNeedsStyleRecalc();
+
+    if (!m_willValidate && !wasValid)
+        removeInvalidElementToAncestorFromInsertionPoint(*this, parentNode());
+
     if (!m_willValidate)
         hideVisibleValidationMessage();
 }
@@ -414,7 +458,7 @@ bool HTMLFormControlElement::checkValidity(Vector<RefPtr<FormAssociatedElement>>
     return false;
 }
 
-bool HTMLFormControlElement::isValidFormControlElement() const
+inline bool HTMLFormControlElement::isValidFormControlElement() const
 {
     // If the following assertion fails, setNeedsValidityCheck() is not called
     // correctly when something which changes validity is updated.
@@ -424,12 +468,20 @@ bool HTMLFormControlElement::isValidFormControlElement() const
 
 void HTMLFormControlElement::setNeedsValidityCheck()
 {
-    bool newIsValid = valid();
-    if (willValidate() && newIsValid != m_isValid) {
+    bool willValidate = this->willValidate();
+    bool wasValid = m_isValid;
+
+    m_isValid = valid();
+
+    if (willValidate && m_isValid != wasValid) {
         // Update style for pseudo classes such as :valid :invalid.
         setNeedsStyleRecalc();
+
+        if (!m_isValid)
+            addInvalidElementToAncestorFromInsertionPoint(*this, parentNode());
+        else
+            removeInvalidElementToAncestorFromInsertionPoint(*this, parentNode());
     }
-    m_isValid = newIsValid;
 
     // Updates only if this control already has a validtion message.
     if (m_validationMessage && m_validationMessage->isVisible()) {
index f470ee2..2bd5f23 100644 (file)
@@ -98,7 +98,7 @@ public:
     void setAutocapitalize(const AtomicString&);
 #endif
 
-    virtual bool willValidate() const override;
+    virtual bool willValidate() const override final;
     void updateVisibleValidationMessage();
     void hideVisibleValidationMessage();
     bool checkValidity(Vector<RefPtr<FormAssociatedElement>>* unhandledInvalidControls = 0);
@@ -150,6 +150,9 @@ private:
     virtual void refFormAssociatedElement() override { ref(); }
     virtual void derefFormAssociatedElement() override { deref(); }
 
+    virtual bool matchesValidPseudoClass() const override;
+    virtual bool matchesInvalidPseudoClass() const override;
+
     virtual bool isFormControlElement() const override final { return true; }
     virtual bool alwaysCreateUserAgentShadowRoot() const override { return true; }
 
@@ -157,7 +160,7 @@ private:
 
     virtual HTMLFormElement* virtualForm() const override;
     virtual bool isDefaultButtonForForm() const override;
-    virtual bool isValidFormControlElement() const override;
+    bool isValidFormControlElement() const;
 
     bool computeIsDisabledByFieldsetAncestor() const;
 
index 6a15eca..df74ea2 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
  *           (C) 2000 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2010, 2014 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
@@ -34,11 +34,10 @@ class HTMLKeygenElement final : public HTMLFormControlElementWithState {
 public:
     static PassRefPtr<HTMLKeygenElement> create(const QualifiedName&, Document&, HTMLFormElement*);
 
-    virtual bool willValidate() const override { return false; }
-
 private:
     HTMLKeygenElement(const QualifiedName&, Document&, HTMLFormElement*);
 
+    virtual bool recalcWillValidate() const override { return false; }
     virtual bool canStartSelection() const override { return false; }
 
     virtual void parseAttribute(const QualifiedName&, const AtomicString&) override;
index 03a6bbe..017e580 100644 (file)
@@ -42,6 +42,8 @@ public:
     virtual bool useFallbackContent() const override { return m_useFallbackContent; }
     void renderFallbackContent();
 
+    virtual bool willValidate() const override { return false; }
+
     // Implementation of constraint validation API.
     // Note that the object elements are always barred from constraint validation.
     static bool checkValidity() { return true; }
index 9c41661..e84d008 100644 (file)
@@ -40,8 +40,6 @@ class HTMLOutputElement final : public HTMLFormControlElement {
 public:
     static PassRefPtr<HTMLOutputElement> create(const QualifiedName&, Document&, HTMLFormElement*);
 
-    virtual bool willValidate() const override { return false; }
-
     String value() const;
     void setValue(const String&);
     String defaultValue() const;
@@ -54,6 +52,7 @@ public:
 private:
     HTMLOutputElement(const QualifiedName&, Document&, HTMLFormElement*);
 
+    virtual bool recalcWillValidate() const override { return false; }
     virtual void parseAttribute(const QualifiedName&, const AtomicString&) override;
     virtual const AtomicString& formControlType() const override;
     virtual bool isEnumeratable() const override { return true; }