<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[172880] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/172880">172880</a></dd>
<dt>Author</dt> <dd>benjamin@webkit.org</dd>
<dt>Date</dt> <dd>2014-08-22 21:30:33 -0700 (Fri, 22 Aug 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Style invalidation does not work for adjacent node updates
https://bugs.webkit.org/show_bug.cgi?id=136145

Reviewed by Antti Koivisto.

Source/WebCore:

There were a bunch of cases in which the style would be in an inconsistent
state until the style resolver kicks in for the entire document.

For example, let's take the selector &quot;foo.bar + target&quot;. When the class &quot;bar&quot;
changes, the element foo is invalidated. The element target is untouched.

Now, if the style of &quot;target&quot; is accessed, nodeOrItsAncestorNeedsStyleRecalc()
returns false and the old style is accessed.

At some point, when the style of the entire document is resolved, the node
&quot;foo&quot; is styled, and &quot;target&quot; is invalidated.


To fix the issue, this patch adds an extra flag keeping track of subtrees that
have any node needing style recalc: DirectChildNeedsStyleRecalcFlag.

When invalidating the node &quot;foo&quot;, its parent is marked with
DirectChildNeedsStyleRecalcFlag to note that one of the child nodes has an invalid style.

When verifying the style state in nodeOrItsAncestorNeedsStyleRecalc(), we check that flag
in addition to the siblings dependencies to find if the node is part of a subtree that may
be invalid due to sibling selectors.

Similarly, in the style resolver, we use the flag to clear the style on all elements
that could potentially be invalid.


This patch removes the changes introduced by <a href="http://trac.webkit.org/projects/webkit/changeset/172721">r172721</a>
(The style is not updated correctly when the pseudo class :empty is applied on anything but the rightmost element).
That bug was just a special case of what is solved here.


Tests: fast/selectors/attribute-direct-adjacent-style-update.html
       fast/selectors/attribute-sibling-style-update.html
       fast/selectors/class-direct-adjacent-style-update.html
       fast/selectors/class-sibling-style-update.html
       fast/selectors/first-child-direct-adjacent-style-update.html
       fast/selectors/first-child-sibling-style-update.html

* css/SelectorChecker.cpp:
(WebCore::SelectorChecker::checkOne):
* cssjit/SelectorCompiler.cpp:
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsEmpty):
(WebCore::SelectorCompiler::setStyleOfSiblingsAffectedByEmpty): Deleted.
* dom/ContainerNode.h:
(WebCore::ContainerNode::directChildNeedsStyleRecalc):
(WebCore::ContainerNode::setDirectChildNeedsStyleRecalc):
Remove the special case for :empty.

* dom/Document.cpp:
(WebCore::nodeOrItsAncestorNeedsStyleRecalc):
* dom/Element.cpp:
(WebCore::checkForEmptyStyleChange):
(WebCore::checkForSiblingStyleChanges):
(WebCore::Element::setStyleOfSiblingsAffectedByEmpty): Deleted.
(WebCore::Element::rareDataStyleOfSiblingsAffectedByEmpty): Deleted.
* dom/Element.h:
(WebCore::Element::styleOfSiblingsAffectedByEmpty): Deleted.
* dom/ElementRareData.h:
(WebCore::ElementRareData::ElementRareData):
(WebCore::ElementRareData::styleOfSiblingsAffectedByEmpty): Deleted.
(WebCore::ElementRareData::setStyleOfSiblingsAffectedByEmpty): Deleted.
* dom/Node.cpp:
(WebCore::markAncestorsWithChildNeedsStyleRecalc):
(WebCore::Node::setNeedsStyleRecalc):
(WebCore::Node::markAncestorsWithChildNeedsStyleRecalc): Deleted.
* dom/Node.h:
(WebCore::Node::clearChildNeedsStyleRecalc):
* style/StyleResolveTree.cpp:
(WebCore::Style::resetStyleForNonRenderedDescendants):

LayoutTests:

Add tests covering the basic cases: classes and attributes.

First-child covers the basic positional updates.

The tests have a version without any indirect adjacent (&quot;~&quot;) because the marking
used for those is much more generic and having them hide some bugs.

Some tests are still failing. That is due to the style resolver not handling
direct siblings (&quot;+&quot;) correctly when there are multiple of them. I will address
that separately.

* fast/selectors/attribute-direct-adjacent-style-update-expected.txt: Added.
* fast/selectors/attribute-direct-adjacent-style-update.html: Added.
* fast/selectors/attribute-sibling-style-update-expected.txt: Added.
* fast/selectors/attribute-sibling-style-update.html: Added.
* fast/selectors/class-direct-adjacent-style-update-expected.txt: Added.
* fast/selectors/class-direct-adjacent-style-update.html: Added.
* fast/selectors/class-sibling-style-update-expected.txt: Added.
* fast/selectors/class-sibling-style-update.html: Added.
* fast/selectors/first-child-direct-adjacent-style-update.html: Added.
* fast/selectors/first-child-sibling-style-update-expected.txt: Added.
* fast/selectors/first-child-sibling-style-update.html: Added.
* fast/selectors/placeholder-shown-sibling-style-update-expected.txt:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsfastselectorsplaceholdershownsiblingstyleupdateexpectedtxt">trunk/LayoutTests/fast/selectors/placeholder-shown-sibling-style-update-expected.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorecssSelectorCheckercpp">trunk/Source/WebCore/css/SelectorChecker.cpp</a></li>
<li><a href="#trunkSourceWebCorecssjitSelectorCompilercpp">trunk/Source/WebCore/cssjit/SelectorCompiler.cpp</a></li>
<li><a href="#trunkSourceWebCoredomContainerNodeh">trunk/Source/WebCore/dom/ContainerNode.h</a></li>
<li><a href="#trunkSourceWebCoredomDocumentcpp">trunk/Source/WebCore/dom/Document.cpp</a></li>
<li><a href="#trunkSourceWebCoredomElementcpp">trunk/Source/WebCore/dom/Element.cpp</a></li>
<li><a href="#trunkSourceWebCoredomElementh">trunk/Source/WebCore/dom/Element.h</a></li>
<li><a href="#trunkSourceWebCoredomElementRareDatah">trunk/Source/WebCore/dom/ElementRareData.h</a></li>
<li><a href="#trunkSourceWebCoredomNodecpp">trunk/Source/WebCore/dom/Node.cpp</a></li>
<li><a href="#trunkSourceWebCoredomNodeh">trunk/Source/WebCore/dom/Node.h</a></li>
<li><a href="#trunkSourceWebCorestyleStyleResolveTreecpp">trunk/Source/WebCore/style/StyleResolveTree.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsfastselectorsattributedirectadjacentstyleupdateexpectedtxt">trunk/LayoutTests/fast/selectors/attribute-direct-adjacent-style-update-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastselectorsattributedirectadjacentstyleupdatehtml">trunk/LayoutTests/fast/selectors/attribute-direct-adjacent-style-update.html</a></li>
<li><a href="#trunkLayoutTestsfastselectorsattributesiblingstyleupdateexpectedtxt">trunk/LayoutTests/fast/selectors/attribute-sibling-style-update-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastselectorsattributesiblingstyleupdatehtml">trunk/LayoutTests/fast/selectors/attribute-sibling-style-update.html</a></li>
<li><a href="#trunkLayoutTestsfastselectorsclassdirectadjacentstyleupdateexpectedtxt">trunk/LayoutTests/fast/selectors/class-direct-adjacent-style-update-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastselectorsclassdirectadjacentstyleupdatehtml">trunk/LayoutTests/fast/selectors/class-direct-adjacent-style-update.html</a></li>
<li><a href="#trunkLayoutTestsfastselectorsclasssiblingstyleupdateexpectedtxt">trunk/LayoutTests/fast/selectors/class-sibling-style-update-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastselectorsclasssiblingstyleupdatehtml">trunk/LayoutTests/fast/selectors/class-sibling-style-update.html</a></li>
<li><a href="#trunkLayoutTestsfastselectorsfirstchilddirectadjacentstyleupdateexpectedtxt">trunk/LayoutTests/fast/selectors/first-child-direct-adjacent-style-update-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastselectorsfirstchilddirectadjacentstyleupdatehtml">trunk/LayoutTests/fast/selectors/first-child-direct-adjacent-style-update.html</a></li>
<li><a href="#trunkLayoutTestsfastselectorsfirstchildsiblingstyleupdateexpectedtxt">trunk/LayoutTests/fast/selectors/first-child-sibling-style-update-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastselectorsfirstchildsiblingstyleupdatehtml">trunk/LayoutTests/fast/selectors/first-child-sibling-style-update.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (172879 => 172880)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2014-08-23 01:58:06 UTC (rev 172879)
+++ trunk/LayoutTests/ChangeLog        2014-08-23 04:30:33 UTC (rev 172880)
</span><span class="lines">@@ -1,3 +1,34 @@
</span><ins>+2014-08-22  Benjamin Poulain  &lt;benjamin@webkit.org&gt;
+
+        Style invalidation does not work for adjacent node updates
+        https://bugs.webkit.org/show_bug.cgi?id=136145
+
+        Reviewed by Antti Koivisto.
+
+        Add tests covering the basic cases: classes and attributes.
+
+        First-child covers the basic positional updates.
+
+        The tests have a version without any indirect adjacent (&quot;~&quot;) because the marking
+        used for those is much more generic and having them hide some bugs.
+
+        Some tests are still failing. That is due to the style resolver not handling
+        direct siblings (&quot;+&quot;) correctly when there are multiple of them. I will address
+        that separately.
+
+        * fast/selectors/attribute-direct-adjacent-style-update-expected.txt: Added.
+        * fast/selectors/attribute-direct-adjacent-style-update.html: Added.
+        * fast/selectors/attribute-sibling-style-update-expected.txt: Added.
+        * fast/selectors/attribute-sibling-style-update.html: Added.
+        * fast/selectors/class-direct-adjacent-style-update-expected.txt: Added.
+        * fast/selectors/class-direct-adjacent-style-update.html: Added.
+        * fast/selectors/class-sibling-style-update-expected.txt: Added.
+        * fast/selectors/class-sibling-style-update.html: Added.
+        * fast/selectors/first-child-direct-adjacent-style-update.html: Added.
+        * fast/selectors/first-child-sibling-style-update-expected.txt: Added.
+        * fast/selectors/first-child-sibling-style-update.html: Added.
+        * fast/selectors/placeholder-shown-sibling-style-update-expected.txt:
+
</ins><span class="cx"> 2014-08-22  David Hyatt  &lt;hyatt@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Add proper support for letter-spacing to bopomofo Ruby
</span></span></pre></div>
<a id="trunkLayoutTestsfastselectorsattributedirectadjacentstyleupdateexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/attribute-direct-adjacent-style-update-expected.txt (0 => 172880)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/attribute-direct-adjacent-style-update-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/selectors/attribute-direct-adjacent-style-update-expected.txt        2014-08-23 04:30:33 UTC (rev 172880)
</span><span class="lines">@@ -0,0 +1,45 @@
</span><ins>+Test style update caused by attribute changes on a direct adjacent. This test does not use any sibling &quot;~&quot; combinator to avoid its more generic marking.
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+Initial state does not match, the attribute is not there.
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+Adding the attribute, the extra rules should match.
+FAIL getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).backgroundColor should be rgb(1, 2, 3). Was rgb(255, 255, 255).
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).backgroundColor is &quot;rgb(1, 2, 3)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+FAIL getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).color should be rgb(4, 5, 6). Was rgb(0, 0, 0).
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+Emptying the attribute, the extra rules should still match.
+FAIL getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).backgroundColor should be rgb(1, 2, 3). Was rgb(255, 255, 255).
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).backgroundColor is &quot;rgb(1, 2, 3)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+FAIL getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).color should be rgb(4, 5, 6). Was rgb(0, 0, 0).
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+Removing the attribute, we should not longer match.
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastselectorsattributedirectadjacentstyleupdatehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/attribute-direct-adjacent-style-update.html (0 => 172880)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/attribute-direct-adjacent-style-update.html                                (rev 0)
+++ trunk/LayoutTests/fast/selectors/attribute-direct-adjacent-style-update.html        2014-08-23 04:30:33 UTC (rev 172880)
</span><span class="lines">@@ -0,0 +1,82 @@
</span><ins>+&lt;!doctype html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;style&gt;
+* {
+    background-color: white;
+    color: black;
+}
+foo[data-webkit]+padding+padding+padding+bar {
+    background-color: rgb(1, 2, 3);
+}
+foo[data-webkit]+padding+padding+padding+bar baz {
+    color: rgb(4, 5, 6);
+}
+&lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+    &lt;div&gt;
+        &lt;foo&gt;&lt;/foo&gt;
+        &lt;padding&gt;&lt;/padding&gt;
+        &lt;padding&gt;&lt;/padding&gt;
+        &lt;padding&gt;&lt;/padding&gt;
+        &lt;bar id=&quot;bar-with-renderer&quot;&gt;
+            &lt;baz id=&quot;baz-with-renderer&quot;&gt;&lt;/baz&gt;
+        &lt;/bar&gt;
+    &lt;/div&gt;
+    &lt;div style=&quot;display:none;&quot;&gt;
+        &lt;foo&gt;&lt;/foo&gt;
+        &lt;padding&gt;&lt;/padding&gt;
+        &lt;padding&gt;&lt;/padding&gt;
+        &lt;padding&gt;&lt;/padding&gt;
+        &lt;bar id=&quot;bar-without-renderer&quot;&gt;
+            &lt;baz id=&quot;baz-without-renderer&quot;&gt;&lt;/baz&gt;
+        &lt;/bar&gt;
+    &lt;/div&gt;
+&lt;/body&gt;
+&lt;script&gt;
+description('Test style update caused by attribute changes on a direct adjacent. This test does not use any sibling &quot;~&quot; combinator to avoid its more generic marking.');
+
+function testColor(expectMatch) {
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).backgroundColor', expectMatch ? 'rgb(1, 2, 3)' : 'rgb(255, 255, 255)');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).backgroundColor', 'rgb(255, 255, 255)');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).backgroundColor', expectMatch ? 'rgb(1, 2, 3)' : 'rgb(255, 255, 255)');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).backgroundColor', 'rgb(255, 255, 255)');
+
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).color', 'rgb(0, 0, 0)');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).color', expectMatch ? 'rgb(4, 5, 6)' : 'rgb(0, 0, 0)');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).color', 'rgb(0, 0, 0)');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).color', expectMatch ? 'rgb(4, 5, 6)' : 'rgb(0, 0, 0)');
+}
+
+function setAttribute(attribute, value) {
+    var allFoos = document.querySelectorAll(&quot;foo&quot;);
+    for (var i = 0; i &lt; allFoos.length; ++i)
+        allFoos[i].setAttribute(attribute, value);
+}
+
+function removeAttribute(attribute) {
+    var allFoos = document.querySelectorAll(&quot;foo&quot;);
+    for (var i = 0; i &lt; allFoos.length; ++i)
+        allFoos[i].removeAttribute(attribute);
+}
+
+debug(&quot;Initial state does not match, the attribute is not there.&quot;);
+testColor(false);
+
+debug(&quot;Adding the attribute, the extra rules should match.&quot;);
+setAttribute(&quot;data-webkit&quot;, &quot;awesome&quot;);
+testColor(true);
+
+debug(&quot;Emptying the attribute, the extra rules should still match.&quot;);
+setAttribute(&quot;data-webkit&quot;, &quot;&quot;);
+testColor(true);
+
+debug(&quot;Removing the attribute, we should not longer match.&quot;);
+removeAttribute(&quot;data-webkit&quot;);
+testColor(false);
+
+&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsfastselectorsattributesiblingstyleupdateexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/attribute-sibling-style-update-expected.txt (0 => 172880)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/attribute-sibling-style-update-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/selectors/attribute-sibling-style-update-expected.txt        2014-08-23 04:30:33 UTC (rev 172880)
</span><span class="lines">@@ -0,0 +1,77 @@
</span><ins>+Test style update caused by attribute changes on a sibling.
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+Initial state does not match, the attribute is not there.
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).fillOpacity is &quot;1&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).fillOpacity is &quot;1&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).fillOpacity is &quot;1&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).fillOpacity is &quot;1&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).minWidth is &quot;0px&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).minWidth is &quot;0px&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).minWidth is &quot;0px&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).minWidth is &quot;0px&quot;
+Adding the attribute, the extra rules should match.
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).backgroundColor is &quot;rgb(1, 2, 3)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).backgroundColor is &quot;rgb(1, 2, 3)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).fillOpacity is &quot;0.5&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).fillOpacity is &quot;1&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).fillOpacity is &quot;0.5&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).fillOpacity is &quot;1&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).minWidth is &quot;0px&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).minWidth is &quot;1px&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).minWidth is &quot;0px&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).minWidth is &quot;1px&quot;
+Emptying the attribute, the extra rules should still match.
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).backgroundColor is &quot;rgb(1, 2, 3)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).backgroundColor is &quot;rgb(1, 2, 3)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).fillOpacity is &quot;0.5&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).fillOpacity is &quot;1&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).fillOpacity is &quot;0.5&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).fillOpacity is &quot;1&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).minWidth is &quot;0px&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).minWidth is &quot;1px&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).minWidth is &quot;0px&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).minWidth is &quot;1px&quot;
+Removing the attribute, we should not longer match.
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).fillOpacity is &quot;1&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).fillOpacity is &quot;1&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).fillOpacity is &quot;1&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).fillOpacity is &quot;1&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).minWidth is &quot;0px&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).minWidth is &quot;0px&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).minWidth is &quot;0px&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).minWidth is &quot;0px&quot;
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastselectorsattributesiblingstyleupdatehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/attribute-sibling-style-update.html (0 => 172880)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/attribute-sibling-style-update.html                                (rev 0)
+++ trunk/LayoutTests/fast/selectors/attribute-sibling-style-update.html        2014-08-23 04:30:33 UTC (rev 172880)
</span><span class="lines">@@ -0,0 +1,100 @@
</span><ins>+&lt;!doctype html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;style&gt;
+* {
+    background-color: white;
+    color: black;
+    fill-opacity: 1;
+    min-width: 0px;
+}
+foo[data-webkit]+padding+padding+padding+bar {
+    background-color: rgb(1, 2, 3);
+}
+foo[data-webkit]~bar {
+    fill-opacity: 0.5;
+}
+foo[data-webkit]+padding+padding+padding+bar baz {
+    color: rgb(4, 5, 6);
+}
+foo[data-webkit]~bar baz {
+    min-width: 1px;
+}
+&lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+    &lt;div&gt;
+        &lt;foo&gt;&lt;/foo&gt;
+        &lt;padding&gt;&lt;/padding&gt;
+        &lt;padding&gt;&lt;/padding&gt;
+        &lt;padding&gt;&lt;/padding&gt;
+        &lt;bar id=&quot;bar-with-renderer&quot;&gt;
+            &lt;baz id=&quot;baz-with-renderer&quot;&gt;&lt;/baz&gt;
+        &lt;/bar&gt;
+    &lt;/div&gt;
+    &lt;div style=&quot;display:none;&quot;&gt;
+        &lt;foo&gt;&lt;/foo&gt;
+        &lt;padding&gt;&lt;/padding&gt;
+        &lt;padding&gt;&lt;/padding&gt;
+        &lt;padding&gt;&lt;/padding&gt;
+        &lt;bar id=&quot;bar-without-renderer&quot;&gt;
+            &lt;baz id=&quot;baz-without-renderer&quot;&gt;&lt;/baz&gt;
+        &lt;/bar&gt;
+    &lt;/div&gt;
+&lt;/body&gt;
+&lt;script&gt;
+description('Test style update caused by attribute changes on a sibling.');
+
+function testColor(expectMatch) {
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).backgroundColor', expectMatch ? 'rgb(1, 2, 3)' : 'rgb(255, 255, 255)');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).backgroundColor', 'rgb(255, 255, 255)');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).backgroundColor', expectMatch ? 'rgb(1, 2, 3)' : 'rgb(255, 255, 255)');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).backgroundColor', 'rgb(255, 255, 255)');
+
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).fillOpacity', expectMatch ? '0.5' : '1');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).fillOpacity', '1');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).fillOpacity', expectMatch ? '0.5' : '1');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).fillOpacity', '1');
+
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).color', 'rgb(0, 0, 0)');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).color', expectMatch ? 'rgb(4, 5, 6)' : 'rgb(0, 0, 0)');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).color', 'rgb(0, 0, 0)');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).color', expectMatch ? 'rgb(4, 5, 6)' : 'rgb(0, 0, 0)');
+
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).minWidth', '0px');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).minWidth', expectMatch ? '1px': '0px');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).minWidth', '0px');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).minWidth', expectMatch ? '1px': '0px');
+}
+
+function setAttribute(attribute, value) {
+    var allFoos = document.querySelectorAll(&quot;foo&quot;);
+    for (var i = 0; i &lt; allFoos.length; ++i)
+        allFoos[i].setAttribute(attribute, value);
+}
+
+function removeAttribute(attribute) {
+    var allFoos = document.querySelectorAll(&quot;foo&quot;);
+    for (var i = 0; i &lt; allFoos.length; ++i)
+        allFoos[i].removeAttribute(attribute);
+}
+
+debug(&quot;Initial state does not match, the attribute is not there.&quot;);
+testColor(false);
+
+debug(&quot;Adding the attribute, the extra rules should match.&quot;);
+setAttribute(&quot;data-webkit&quot;, &quot;awesome&quot;);
+testColor(true);
+
+debug(&quot;Emptying the attribute, the extra rules should still match.&quot;);
+setAttribute(&quot;data-webkit&quot;, &quot;&quot;);
+testColor(true);
+
+debug(&quot;Removing the attribute, we should not longer match.&quot;);
+removeAttribute(&quot;data-webkit&quot;);
+testColor(false);
+
+&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsfastselectorsclassdirectadjacentstyleupdateexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/class-direct-adjacent-style-update-expected.txt (0 => 172880)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/class-direct-adjacent-style-update-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/selectors/class-direct-adjacent-style-update-expected.txt        2014-08-23 04:30:33 UTC (rev 172880)
</span><span class="lines">@@ -0,0 +1,36 @@
</span><ins>+Test style update caused by class changes on a sibling. This test does not use any sibling &quot;~&quot; combinator to avoid its more generic marking.
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+Initial state does not match, the class is not there.
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+Adding the class, the extra rules should match.
+FAIL getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).backgroundColor should be rgb(1, 2, 3). Was rgb(255, 255, 255).
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).backgroundColor is &quot;rgb(1, 2, 3)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+FAIL getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).color should be rgb(4, 5, 6). Was rgb(0, 0, 0).
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+Removing the class, we should be back to the original state.
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastselectorsclassdirectadjacentstyleupdatehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/class-direct-adjacent-style-update.html (0 => 172880)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/class-direct-adjacent-style-update.html                                (rev 0)
+++ trunk/LayoutTests/fast/selectors/class-direct-adjacent-style-update.html        2014-08-23 04:30:33 UTC (rev 172880)
</span><span class="lines">@@ -0,0 +1,72 @@
</span><ins>+&lt;!doctype html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;style&gt;
+* {
+    background-color: white;
+    color: black;
+}
+.webkit+padding+padding+padding+bar {
+    background-color: rgb(1, 2, 3);
+}
+.webkit+padding+padding+padding+bar baz {
+    color: rgb(4, 5, 6);
+}
+&lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+    &lt;div&gt;
+        &lt;foo&gt;&lt;/foo&gt;
+        &lt;padding&gt;&lt;/padding&gt;
+        &lt;padding&gt;&lt;/padding&gt;
+        &lt;padding&gt;&lt;/padding&gt;
+        &lt;bar id=&quot;bar-with-renderer&quot;&gt;
+            &lt;baz id=&quot;baz-with-renderer&quot;&gt;&lt;/baz&gt;
+        &lt;/bar&gt;
+    &lt;/div&gt;
+    &lt;div style=&quot;display:none;&quot;&gt;
+        &lt;foo&gt;&lt;/foo&gt;
+        &lt;padding&gt;&lt;/padding&gt;
+        &lt;padding&gt;&lt;/padding&gt;
+        &lt;padding&gt;&lt;/padding&gt;
+        &lt;bar id=&quot;bar-without-renderer&quot;&gt;
+            &lt;baz id=&quot;baz-without-renderer&quot;&gt;&lt;/baz&gt;
+        &lt;/bar&gt;
+    &lt;/div&gt;
+&lt;/body&gt;
+&lt;script&gt;
+description('Test style update caused by class changes on a sibling. This test does not use any sibling &quot;~&quot; combinator to avoid its more generic marking.');
+
+function testColor(expectMatch) {
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).backgroundColor', expectMatch ? 'rgb(1, 2, 3)' : 'rgb(255, 255, 255)');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).backgroundColor', 'rgb(255, 255, 255)');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).backgroundColor', expectMatch ? 'rgb(1, 2, 3)' : 'rgb(255, 255, 255)');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).backgroundColor', 'rgb(255, 255, 255)');
+
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).color', 'rgb(0, 0, 0)');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).color', expectMatch ? 'rgb(4, 5, 6)' : 'rgb(0, 0, 0)');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).color', 'rgb(0, 0, 0)');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).color', expectMatch ? 'rgb(4, 5, 6)' : 'rgb(0, 0, 0)');
+}
+
+function setClass(className) {
+    var allFoos = document.querySelectorAll(&quot;foo&quot;);
+    for (var i = 0; i &lt; allFoos.length; ++i)
+        allFoos[i].className = className;
+}
+
+debug(&quot;Initial state does not match, the class is not there.&quot;);
+testColor(false);
+
+debug(&quot;Adding the class, the extra rules should match.&quot;);
+setClass(&quot;webkit&quot;)
+testColor(true);
+
+debug(&quot;Removing the class, we should be back to the original state.&quot;);
+setClass(&quot;&quot;)
+testColor(false);
+
+&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsfastselectorsclasssiblingstyleupdateexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/class-sibling-style-update-expected.txt (0 => 172880)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/class-sibling-style-update-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/selectors/class-sibling-style-update-expected.txt        2014-08-23 04:30:33 UTC (rev 172880)
</span><span class="lines">@@ -0,0 +1,60 @@
</span><ins>+Test style update caused by class changes on a sibling.
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+Initial state does not match, the class is not there.
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).fillOpacity is &quot;1&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).fillOpacity is &quot;1&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).fillOpacity is &quot;1&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).fillOpacity is &quot;1&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).minWidth is &quot;0px&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).minWidth is &quot;0px&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).minWidth is &quot;0px&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).minWidth is &quot;0px&quot;
+Adding the class, the extra rules should match.
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).backgroundColor is &quot;rgb(1, 2, 3)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).backgroundColor is &quot;rgb(1, 2, 3)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).fillOpacity is &quot;0.5&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).fillOpacity is &quot;1&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).fillOpacity is &quot;0.5&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).fillOpacity is &quot;1&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).minWidth is &quot;0px&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).minWidth is &quot;1px&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).minWidth is &quot;0px&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).minWidth is &quot;1px&quot;
+Removing the class, we should be back to the original state.
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).fillOpacity is &quot;1&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).fillOpacity is &quot;1&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).fillOpacity is &quot;1&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).fillOpacity is &quot;1&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).minWidth is &quot;0px&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).minWidth is &quot;0px&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).minWidth is &quot;0px&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).minWidth is &quot;0px&quot;
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastselectorsclasssiblingstyleupdatehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/class-sibling-style-update.html (0 => 172880)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/class-sibling-style-update.html                                (rev 0)
+++ trunk/LayoutTests/fast/selectors/class-sibling-style-update.html        2014-08-23 04:30:33 UTC (rev 172880)
</span><span class="lines">@@ -0,0 +1,90 @@
</span><ins>+&lt;!doctype html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;style&gt;
+* {
+    background-color: white;
+    color: black;
+    fill-opacity: 1;
+    min-width: 0px;
+}
+.webkit+padding+padding+padding+bar {
+    background-color: rgb(1, 2, 3);
+}
+.webkit~bar {
+    fill-opacity: 0.5;
+}
+.webkit+padding+padding+padding+bar baz {
+    color: rgb(4, 5, 6);
+}
+.webkit~bar baz {
+    min-width: 1px;
+}
+&lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+    &lt;div&gt;
+        &lt;foo&gt;&lt;/foo&gt;
+        &lt;padding&gt;&lt;/padding&gt;
+        &lt;padding&gt;&lt;/padding&gt;
+        &lt;padding&gt;&lt;/padding&gt;
+        &lt;bar id=&quot;bar-with-renderer&quot;&gt;
+            &lt;baz id=&quot;baz-with-renderer&quot;&gt;&lt;/baz&gt;
+        &lt;/bar&gt;
+    &lt;/div&gt;
+    &lt;div style=&quot;display:none;&quot;&gt;
+        &lt;foo&gt;&lt;/foo&gt;
+        &lt;padding&gt;&lt;/padding&gt;
+        &lt;padding&gt;&lt;/padding&gt;
+        &lt;padding&gt;&lt;/padding&gt;
+        &lt;bar id=&quot;bar-without-renderer&quot;&gt;
+            &lt;baz id=&quot;baz-without-renderer&quot;&gt;&lt;/baz&gt;
+        &lt;/bar&gt;
+    &lt;/div&gt;
+&lt;/body&gt;
+&lt;script&gt;
+description('Test style update caused by class changes on a sibling.');
+
+function testColor(expectMatch) {
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).backgroundColor', expectMatch ? 'rgb(1, 2, 3)' : 'rgb(255, 255, 255)');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).backgroundColor', 'rgb(255, 255, 255)');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).backgroundColor', expectMatch ? 'rgb(1, 2, 3)' : 'rgb(255, 255, 255)');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).backgroundColor', 'rgb(255, 255, 255)');
+
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).fillOpacity', expectMatch ? '0.5' : '1');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).fillOpacity', '1');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).fillOpacity', expectMatch ? '0.5' : '1');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).fillOpacity', '1');
+
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).color', 'rgb(0, 0, 0)');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).color', expectMatch ? 'rgb(4, 5, 6)' : 'rgb(0, 0, 0)');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).color', 'rgb(0, 0, 0)');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).color', expectMatch ? 'rgb(4, 5, 6)' : 'rgb(0, 0, 0)');
+
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).minWidth', '0px');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).minWidth', expectMatch ? '1px': '0px');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).minWidth', '0px');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).minWidth', expectMatch ? '1px': '0px');
+}
+
+function setClass(className) {
+    var allFoos = document.querySelectorAll(&quot;foo&quot;);
+    for (var i = 0; i &lt; allFoos.length; ++i)
+        allFoos[i].className = className;
+}
+
+debug(&quot;Initial state does not match, the class is not there.&quot;);
+testColor(false);
+
+debug(&quot;Adding the class, the extra rules should match.&quot;);
+setClass(&quot;webkit&quot;)
+testColor(true);
+
+debug(&quot;Removing the class, we should be back to the original state.&quot;);
+setClass(&quot;&quot;)
+testColor(false);
+
+&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsfastselectorsfirstchilddirectadjacentstyleupdateexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/first-child-direct-adjacent-style-update-expected.txt (0 => 172880)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/first-child-direct-adjacent-style-update-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/selectors/first-child-direct-adjacent-style-update-expected.txt        2014-08-23 04:30:33 UTC (rev 172880)
</span><span class="lines">@@ -0,0 +1,45 @@
</span><ins>+Test style update caused by changes the positional property &quot;first-child&quot; on a sibling. This test does not use any sibling &quot;~&quot; combinator to avoid its more generic marking.
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+The initial state has &lt;foo&gt; in first position, it should match.
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).backgroundColor is &quot;rgb(1, 2, 3)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).backgroundColor is &quot;rgb(1, 2, 3)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+Adding an element as first child should clear the style.
+FAIL getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).backgroundColor should be rgb(255, 255, 255). Was rgb(1, 2, 3).
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+FAIL getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).color should be rgb(0, 0, 0). Was rgb(4, 5, 6).
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+Removing that first element put back the style.
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).backgroundColor is &quot;rgb(1, 2, 3)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).backgroundColor is &quot;rgb(1, 2, 3)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+Removing &lt;foo&gt; should clear the style.
+FAIL getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).backgroundColor should be rgb(255, 255, 255). Was rgb(1, 2, 3).
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+FAIL getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).color should be rgb(0, 0, 0). Was rgb(4, 5, 6).
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastselectorsfirstchilddirectadjacentstyleupdatehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/first-child-direct-adjacent-style-update.html (0 => 172880)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/first-child-direct-adjacent-style-update.html                                (rev 0)
+++ trunk/LayoutTests/fast/selectors/first-child-direct-adjacent-style-update.html        2014-08-23 04:30:33 UTC (rev 172880)
</span><span class="lines">@@ -0,0 +1,82 @@
</span><ins>+&lt;!doctype html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;style&gt;
+* {
+    background-color: white;
+    color: black;
+}
+foo:first-child+padding+padding+padding+bar {
+    background-color: rgb(1, 2, 3);
+}
+foo:first-child+padding+padding+padding+bar baz {
+    color: rgb(4, 5, 6);
+}
+&lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+    &lt;div id=&quot;testcases-with-renderer&quot;&gt;
+        &lt;!-- Comments should be ignored by selectors. --&gt;
+        &lt;foo&gt;&lt;/foo&gt;
+        &lt;padding&gt;&lt;/padding&gt;
+        &lt;padding&gt;&lt;/padding&gt;
+        &lt;padding&gt;&lt;/padding&gt;
+        &lt;bar id=&quot;bar-with-renderer&quot;&gt;
+            &lt;baz id=&quot;baz-with-renderer&quot;&gt;&lt;/baz&gt;
+        &lt;/bar&gt;
+    &lt;/div&gt;
+    &lt;div id=&quot;testcases-without-renderer&quot; style=&quot;display:none;&quot;&gt;
+        &lt;!-- Comments should be ignored by selectors. --&gt;
+        &lt;foo&gt;&lt;/foo&gt;
+        &lt;padding&gt;&lt;/padding&gt;
+        &lt;padding&gt;&lt;/padding&gt;
+        &lt;padding&gt;&lt;/padding&gt;
+        &lt;bar id=&quot;bar-without-renderer&quot;&gt;
+            &lt;baz id=&quot;baz-without-renderer&quot;&gt;&lt;/baz&gt;
+        &lt;/bar&gt;
+    &lt;/div&gt;
+&lt;/body&gt;
+&lt;script&gt;
+description('Test style update caused by changes the positional property &quot;first-child&quot; on a sibling. This test does not use any sibling &quot;~&quot; combinator to avoid its more generic marking.');
+
+function testColor(expectMatch) {
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).backgroundColor', expectMatch ? 'rgb(1, 2, 3)' : 'rgb(255, 255, 255)');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).backgroundColor', 'rgb(255, 255, 255)');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).backgroundColor', expectMatch ? 'rgb(1, 2, 3)' : 'rgb(255, 255, 255)');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).backgroundColor', 'rgb(255, 255, 255)');
+
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).color', 'rgb(0, 0, 0)');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).color', expectMatch ? 'rgb(4, 5, 6)' : 'rgb(0, 0, 0)');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).color', 'rgb(0, 0, 0)');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).color', expectMatch ? 'rgb(4, 5, 6)' : 'rgb(0, 0, 0)');
+}
+
+debug(&quot;The initial state has &amp;lt;foo&amp;gt; in first position, it should match.&quot;);
+testColor(true);
+
+debug(&quot;Adding an element as first child should clear the style.&quot;);
+var testCasesWithRenderer = document.getElementById(&quot;testcases-with-renderer&quot;);
+var divWithRenderer = document.createElement(&quot;div&quot;);
+testCasesWithRenderer.insertBefore(divWithRenderer, testCasesWithRenderer.firstChild)
+
+var testCasesWithoutRenderer = document.getElementById(&quot;testcases-without-renderer&quot;);
+var divWithoutRenderer = document.createElement(&quot;div&quot;);
+testCasesWithoutRenderer.insertBefore(divWithoutRenderer, testCasesWithoutRenderer.firstChild)
+
+testColor(false);
+
+
+debug(&quot;Removing that first element put back the style.&quot;);
+divWithRenderer.remove();
+divWithoutRenderer.remove();
+testColor(true);
+
+debug(&quot;Removing &amp;lt;foo&amp;gt; should clear the style.&quot;);
+testCasesWithRenderer.querySelector(&quot;foo&quot;).remove();
+testCasesWithoutRenderer.querySelector(&quot;foo&quot;).remove();
+testColor(false);
+
+&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsfastselectorsfirstchildsiblingstyleupdateexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/first-child-sibling-style-update-expected.txt (0 => 172880)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/first-child-sibling-style-update-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/selectors/first-child-sibling-style-update-expected.txt        2014-08-23 04:30:33 UTC (rev 172880)
</span><span class="lines">@@ -0,0 +1,77 @@
</span><ins>+Test style update caused by changes the positional property &quot;first-child&quot; on a sibling.
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+The initial state has &lt;foo&gt; in first position, it should match.
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).backgroundColor is &quot;rgb(1, 2, 3)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).backgroundColor is &quot;rgb(1, 2, 3)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).fillOpacity is &quot;0.5&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).fillOpacity is &quot;1&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).fillOpacity is &quot;0.5&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).fillOpacity is &quot;1&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).minWidth is &quot;0px&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).minWidth is &quot;1px&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).minWidth is &quot;0px&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).minWidth is &quot;1px&quot;
+Adding an element as first child should clear the style.
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).fillOpacity is &quot;1&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).fillOpacity is &quot;1&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).fillOpacity is &quot;1&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).fillOpacity is &quot;1&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).minWidth is &quot;0px&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).minWidth is &quot;0px&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).minWidth is &quot;0px&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).minWidth is &quot;0px&quot;
+Removing that first element put back the style.
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).backgroundColor is &quot;rgb(1, 2, 3)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).backgroundColor is &quot;rgb(1, 2, 3)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).fillOpacity is &quot;0.5&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).fillOpacity is &quot;1&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).fillOpacity is &quot;0.5&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).fillOpacity is &quot;1&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).minWidth is &quot;0px&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).minWidth is &quot;1px&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).minWidth is &quot;0px&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).minWidth is &quot;1px&quot;
+Removing &lt;foo&gt; should clear the style.
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).fillOpacity is &quot;1&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).fillOpacity is &quot;1&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).fillOpacity is &quot;1&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).fillOpacity is &quot;1&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).color is &quot;rgb(0, 0, 0)&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).minWidth is &quot;0px&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).minWidth is &quot;0px&quot;
+PASS getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).minWidth is &quot;0px&quot;
+PASS getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).minWidth is &quot;0px&quot;
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastselectorsfirstchildsiblingstyleupdatehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/first-child-sibling-style-update.html (0 => 172880)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/first-child-sibling-style-update.html                                (rev 0)
+++ trunk/LayoutTests/fast/selectors/first-child-sibling-style-update.html        2014-08-23 04:30:33 UTC (rev 172880)
</span><span class="lines">@@ -0,0 +1,100 @@
</span><ins>+&lt;!doctype html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;style&gt;
+* {
+    background-color: white;
+    color: black;
+    fill-opacity: 1;
+    min-width: 0px;
+}
+foo:first-child+padding+padding+padding+bar {
+    background-color: rgb(1, 2, 3);
+}
+foo:first-child~bar {
+    fill-opacity: 0.5;
+}
+foo:first-child+padding+padding+padding+bar baz {
+    color: rgb(4, 5, 6);
+}
+foo:first-child~bar baz {
+    min-width: 1px;
+}
+&lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+    &lt;div id=&quot;testcases-with-renderer&quot;&gt;
+        &lt;!-- Comments should be ignored by selectors. --&gt;
+        &lt;foo&gt;&lt;/foo&gt;
+        &lt;padding&gt;&lt;/padding&gt;
+        &lt;padding&gt;&lt;/padding&gt;
+        &lt;padding&gt;&lt;/padding&gt;
+        &lt;bar id=&quot;bar-with-renderer&quot;&gt;
+            &lt;baz id=&quot;baz-with-renderer&quot;&gt;&lt;/baz&gt;
+        &lt;/bar&gt;
+    &lt;/div&gt;
+    &lt;div id=&quot;testcases-without-renderer&quot; style=&quot;display:none;&quot;&gt;
+        &lt;!-- Comments should be ignored by selectors. --&gt;
+        &lt;foo&gt;&lt;/foo&gt;
+        &lt;padding&gt;&lt;/padding&gt;
+        &lt;padding&gt;&lt;/padding&gt;
+        &lt;padding&gt;&lt;/padding&gt;
+        &lt;bar id=&quot;bar-without-renderer&quot;&gt;
+            &lt;baz id=&quot;baz-without-renderer&quot;&gt;&lt;/baz&gt;
+        &lt;/bar&gt;
+    &lt;/div&gt;
+&lt;/body&gt;
+&lt;script&gt;
+description('Test style update caused by changes the positional property &quot;first-child&quot; on a sibling.');
+
+function testColor(expectMatch) {
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).backgroundColor', expectMatch ? 'rgb(1, 2, 3)' : 'rgb(255, 255, 255)');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).backgroundColor', 'rgb(255, 255, 255)');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).backgroundColor', expectMatch ? 'rgb(1, 2, 3)' : 'rgb(255, 255, 255)');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).backgroundColor', 'rgb(255, 255, 255)');
+
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).fillOpacity', expectMatch ? '0.5' : '1');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).fillOpacity', '1');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).fillOpacity', expectMatch ? '0.5' : '1');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).fillOpacity', '1');
+
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).color', 'rgb(0, 0, 0)');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).color', expectMatch ? 'rgb(4, 5, 6)' : 'rgb(0, 0, 0)');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).color', 'rgb(0, 0, 0)');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).color', expectMatch ? 'rgb(4, 5, 6)' : 'rgb(0, 0, 0)');
+
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;bar-with-renderer&quot;)).minWidth', '0px');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;baz-with-renderer&quot;)).minWidth', expectMatch ? '1px': '0px');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;bar-without-renderer&quot;)).minWidth', '0px');
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;baz-without-renderer&quot;)).minWidth', expectMatch ? '1px': '0px');
+}
+
+debug(&quot;The initial state has &amp;lt;foo&amp;gt; in first position, it should match.&quot;);
+testColor(true);
+
+debug(&quot;Adding an element as first child should clear the style.&quot;);
+var testCasesWithRenderer = document.getElementById(&quot;testcases-with-renderer&quot;);
+var divWithRenderer = document.createElement(&quot;div&quot;);
+testCasesWithRenderer.insertBefore(divWithRenderer, testCasesWithRenderer.firstChild)
+
+var testCasesWithoutRenderer = document.getElementById(&quot;testcases-without-renderer&quot;);
+var divWithoutRenderer = document.createElement(&quot;div&quot;);
+testCasesWithoutRenderer.insertBefore(divWithoutRenderer, testCasesWithoutRenderer.firstChild)
+
+testColor(false);
+
+
+debug(&quot;Removing that first element put back the style.&quot;);
+divWithRenderer.remove();
+divWithoutRenderer.remove();
+testColor(true);
+
+debug(&quot;Removing &amp;lt;foo&amp;gt; should clear the style.&quot;);
+testCasesWithRenderer.querySelector(&quot;foo&quot;).remove();
+testCasesWithoutRenderer.querySelector(&quot;foo&quot;).remove();
+testColor(false);
+
+&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsfastselectorsplaceholdershownsiblingstyleupdateexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/selectors/placeholder-shown-sibling-style-update-expected.txt (172879 => 172880)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/placeholder-shown-sibling-style-update-expected.txt        2014-08-23 01:58:06 UTC (rev 172879)
+++ trunk/LayoutTests/fast/selectors/placeholder-shown-sibling-style-update-expected.txt        2014-08-23 04:30:33 UTC (rev 172880)
</span><span class="lines">@@ -9,10 +9,10 @@
</span><span class="cx"> PASS getComputedStyle(document.getElementById(&quot;target3&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
</span><span class="cx"> PASS getComputedStyle(document.getElementById(&quot;target4&quot;)).backgroundColor is &quot;rgb(255, 255, 255)&quot;
</span><span class="cx"> Adding a placeholder, the targets should match the style.
</span><del>-FAIL getComputedStyle(document.getElementById(&quot;target1&quot;)).backgroundColor should be rgb(1, 2, 3). Was rgb(255, 255, 255).
-FAIL getComputedStyle(document.getElementById(&quot;target2&quot;)).backgroundColor should be rgb(1, 2, 3). Was rgb(255, 255, 255).
-FAIL getComputedStyle(document.getElementById(&quot;target3&quot;)).backgroundColor should be rgb(1, 2, 3). Was rgb(255, 255, 255).
-FAIL getComputedStyle(document.getElementById(&quot;target4&quot;)).backgroundColor should be rgb(1, 2, 3). Was rgb(255, 255, 255).
</del><ins>+PASS getComputedStyle(document.getElementById(&quot;target1&quot;)).backgroundColor is &quot;rgb(1, 2, 3)&quot;
+PASS getComputedStyle(document.getElementById(&quot;target2&quot;)).backgroundColor is &quot;rgb(1, 2, 3)&quot;
+PASS getComputedStyle(document.getElementById(&quot;target3&quot;)).backgroundColor is &quot;rgb(1, 2, 3)&quot;
+PASS getComputedStyle(document.getElementById(&quot;target4&quot;)).backgroundColor is &quot;rgb(1, 2, 3)&quot;
</ins><span class="cx"> PASS successfullyParsed is true
</span><span class="cx"> 
</span><span class="cx"> TEST COMPLETE
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (172879 => 172880)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-08-23 01:58:06 UTC (rev 172879)
+++ trunk/Source/WebCore/ChangeLog        2014-08-23 04:30:33 UTC (rev 172880)
</span><span class="lines">@@ -1,3 +1,81 @@
</span><ins>+2014-08-22  Benjamin Poulain  &lt;benjamin@webkit.org&gt;
+
+        Style invalidation does not work for adjacent node updates
+        https://bugs.webkit.org/show_bug.cgi?id=136145
+
+        Reviewed by Antti Koivisto.
+
+        There were a bunch of cases in which the style would be in an inconsistent
+        state until the style resolver kicks in for the entire document.
+
+        For example, let's take the selector &quot;foo.bar + target&quot;. When the class &quot;bar&quot;
+        changes, the element foo is invalidated. The element target is untouched.
+
+        Now, if the style of &quot;target&quot; is accessed, nodeOrItsAncestorNeedsStyleRecalc()
+        returns false and the old style is accessed.
+
+        At some point, when the style of the entire document is resolved, the node
+        &quot;foo&quot; is styled, and &quot;target&quot; is invalidated.
+
+
+        To fix the issue, this patch adds an extra flag keeping track of subtrees that
+        have any node needing style recalc: DirectChildNeedsStyleRecalcFlag.
+
+        When invalidating the node &quot;foo&quot;, its parent is marked with
+        DirectChildNeedsStyleRecalcFlag to note that one of the child nodes has an invalid style.
+
+        When verifying the style state in nodeOrItsAncestorNeedsStyleRecalc(), we check that flag
+        in addition to the siblings dependencies to find if the node is part of a subtree that may
+        be invalid due to sibling selectors.
+
+        Similarly, in the style resolver, we use the flag to clear the style on all elements
+        that could potentially be invalid.
+
+
+        This patch removes the changes introduced by r172721
+        (The style is not updated correctly when the pseudo class :empty is applied on anything but the rightmost element).
+        That bug was just a special case of what is solved here.
+
+
+        Tests: fast/selectors/attribute-direct-adjacent-style-update.html
+               fast/selectors/attribute-sibling-style-update.html
+               fast/selectors/class-direct-adjacent-style-update.html
+               fast/selectors/class-sibling-style-update.html
+               fast/selectors/first-child-direct-adjacent-style-update.html
+               fast/selectors/first-child-sibling-style-update.html
+
+        * css/SelectorChecker.cpp:
+        (WebCore::SelectorChecker::checkOne):
+        * cssjit/SelectorCompiler.cpp:
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsEmpty):
+        (WebCore::SelectorCompiler::setStyleOfSiblingsAffectedByEmpty): Deleted.
+        * dom/ContainerNode.h:
+        (WebCore::ContainerNode::directChildNeedsStyleRecalc):
+        (WebCore::ContainerNode::setDirectChildNeedsStyleRecalc):
+        Remove the special case for :empty.
+
+        * dom/Document.cpp:
+        (WebCore::nodeOrItsAncestorNeedsStyleRecalc):
+        * dom/Element.cpp:
+        (WebCore::checkForEmptyStyleChange):
+        (WebCore::checkForSiblingStyleChanges):
+        (WebCore::Element::setStyleOfSiblingsAffectedByEmpty): Deleted.
+        (WebCore::Element::rareDataStyleOfSiblingsAffectedByEmpty): Deleted.
+        * dom/Element.h:
+        (WebCore::Element::styleOfSiblingsAffectedByEmpty): Deleted.
+        * dom/ElementRareData.h:
+        (WebCore::ElementRareData::ElementRareData):
+        (WebCore::ElementRareData::styleOfSiblingsAffectedByEmpty): Deleted.
+        (WebCore::ElementRareData::setStyleOfSiblingsAffectedByEmpty): Deleted.
+        * dom/Node.cpp:
+        (WebCore::markAncestorsWithChildNeedsStyleRecalc):
+        (WebCore::Node::setNeedsStyleRecalc):
+        (WebCore::Node::markAncestorsWithChildNeedsStyleRecalc): Deleted.
+        * dom/Node.h:
+        (WebCore::Node::clearChildNeedsStyleRecalc):
+        * style/StyleResolveTree.cpp:
+        (WebCore::Style::resetStyleForNonRenderedDescendants):
+
</ins><span class="cx"> 2014-08-22  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Remove unused legacy InspectorFrontendHost methods
</span></span></pre></div>
<a id="trunkSourceWebCorecssSelectorCheckercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/SelectorChecker.cpp (172879 => 172880)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/SelectorChecker.cpp        2014-08-23 01:58:06 UTC (rev 172879)
+++ trunk/Source/WebCore/css/SelectorChecker.cpp        2014-08-23 04:30:33 UTC (rev 172880)
</span><span class="lines">@@ -524,8 +524,6 @@
</span><span class="cx">                 }
</span><span class="cx">                 if (m_mode == Mode::ResolvingStyle) {
</span><span class="cx">                     element-&gt;setStyleAffectedByEmpty();
</span><del>-                    if (element-&gt;document().styleSheetCollection().usesSiblingRules())
-                        element-&gt;setStyleOfSiblingsAffectedByEmpty();
</del><span class="cx">                     if (context.elementStyle)
</span><span class="cx">                         context.elementStyle-&gt;setEmptyState(result);
</span><span class="cx">                 }
</span></span></pre></div>
<a id="trunkSourceWebCorecssjitSelectorCompilercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/cssjit/SelectorCompiler.cpp (172879 => 172880)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/cssjit/SelectorCompiler.cpp        2014-08-23 01:58:06 UTC (rev 172879)
+++ trunk/Source/WebCore/cssjit/SelectorCompiler.cpp        2014-08-23 04:30:33 UTC (rev 172880)
</span><span class="lines">@@ -2511,11 +2511,6 @@
</span><span class="cx">     context-&gt;elementStyle-&gt;setEmptyState(isEmpty);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void setStyleOfSiblingsAffectedByEmpty(Element* element)
-{
-    element-&gt;setStyleOfSiblingsAffectedByEmpty();
-}
-
</del><span class="cx"> void SelectorCodeGenerator::generateElementIsEmpty(Assembler::JumpList&amp; failureCases, const SelectorFragment&amp; fragment)
</span><span class="cx"> {
</span><span class="cx">     if (m_selectorContext == SelectorContext::QuerySelector) {
</span><span class="lines">@@ -2553,7 +2548,7 @@
</span><span class="cx">             skipMarking = jumpIfNotResolvingStyle(checkingContext);
</span><span class="cx">         }
</span><span class="cx">         FunctionCall functionCall(m_assembler, m_registerAllocator, m_stackAllocator, m_functionCalls);
</span><del>-        functionCall.setFunctionAddress(setStyleOfSiblingsAffectedByEmpty);
</del><ins>+        functionCall.setFunctionAddress(setElementStyleIsAffectedByEmpty);
</ins><span class="cx">         functionCall.setOneArgument(elementAddressRegister);
</span><span class="cx">         functionCall.call();
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceWebCoredomContainerNodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/ContainerNode.h (172879 => 172880)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/ContainerNode.h        2014-08-23 01:58:06 UTC (rev 172879)
+++ trunk/Source/WebCore/dom/ContainerNode.h        2014-08-23 04:30:33 UTC (rev 172880)
</span><span class="lines">@@ -88,6 +88,9 @@
</span><span class="cx">     Node* lastChild() const { return m_lastChild; }
</span><span class="cx">     bool hasChildNodes() const { return m_firstChild; }
</span><span class="cx"> 
</span><ins>+    bool directChildNeedsStyleRecalc() const { return getFlag(DirectChildNeedsStyleRecalcFlag); }
+    void setDirectChildNeedsStyleRecalc() { setFlag(DirectChildNeedsStyleRecalcFlag); }
+
</ins><span class="cx">     WEBCORE_EXPORT unsigned childNodeCount() const;
</span><span class="cx">     WEBCORE_EXPORT Node* childNode(unsigned index) const;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoredomDocumentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Document.cpp (172879 => 172880)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Document.cpp        2014-08-23 01:58:06 UTC (rev 172879)
+++ trunk/Source/WebCore/dom/Document.cpp        2014-08-23 04:30:33 UTC (rev 172880)
</span><span class="lines">@@ -6144,9 +6144,15 @@
</span><span class="cx"> 
</span><span class="cx"> static inline bool nodeOrItsAncestorNeedsStyleRecalc(const Node&amp; node)
</span><span class="cx"> {
</span><del>-    for (const Node* n = &amp;node; n; n = n-&gt;parentOrShadowHostNode()) {
-        if (n-&gt;needsStyleRecalc())
</del><ins>+    if (node.needsStyleRecalc())
+        return true;
+
+    for (const Element* ancestor = node.parentOrShadowHostElement(); ancestor; ancestor = ancestor-&gt;parentOrShadowHostElement()) {
+        if (ancestor-&gt;needsStyleRecalc())
</ins><span class="cx">             return true;
</span><ins>+
+        if (ancestor-&gt;directChildNeedsStyleRecalc() &amp;&amp; (ancestor-&gt;childrenAffectedByDirectAdjacentRules() || ancestor-&gt;childrenAffectedByForwardPositionalRules()))
+            return true;
</ins><span class="cx">     }
</span><span class="cx">     return false;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoredomElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Element.cpp (172879 => 172880)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Element.cpp        2014-08-23 01:58:06 UTC (rev 172879)
+++ trunk/Source/WebCore/dom/Element.cpp        2014-08-23 04:30:33 UTC (rev 172880)
</span><span class="lines">@@ -1532,11 +1532,6 @@
</span><span class="cx">         if (!style || (!style-&gt;emptyState() || element.hasChildNodes()))
</span><span class="cx">             element.setNeedsStyleRecalc();
</span><span class="cx">     }
</span><del>-
-    if (element.styleOfSiblingsAffectedByEmpty()) {
-        if (Element* parent = element.parentElement())
-            parent-&gt;setNeedsStyleRecalc();
-    }
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> enum SiblingCheckType { FinishedParsingChildren, SiblingElementRemoved, Other };
</span><span class="lines">@@ -2103,11 +2098,6 @@
</span><span class="cx">     ensureElementRareData().setStyleAffectedByEmpty(true);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Element::setStyleOfSiblingsAffectedByEmpty()
-{
-    ensureElementRareData().setStyleOfSiblingsAffectedByEmpty(true);
-}
-
</del><span class="cx"> void Element::setChildrenAffectedByActive()
</span><span class="cx"> {
</span><span class="cx">     ensureElementRareData().setChildrenAffectedByActive(true);
</span><span class="lines">@@ -2155,12 +2145,6 @@
</span><span class="cx">     return elementRareData()-&gt;styleAffectedByEmpty();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool Element::rareDataStyleOfSiblingsAffectedByEmpty() const
-{
-    ASSERT(hasRareData());
-    return elementRareData()-&gt;styleOfSiblingsAffectedByEmpty();
-}
-
</del><span class="cx"> bool Element::rareDataChildrenAffectedByActive() const
</span><span class="cx"> {
</span><span class="cx">     ASSERT(hasRareData());
</span></span></pre></div>
<a id="trunkSourceWebCoredomElementh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Element.h (172879 => 172880)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Element.h        2014-08-23 01:58:06 UTC (rev 172879)
+++ trunk/Source/WebCore/dom/Element.h        2014-08-23 04:30:33 UTC (rev 172880)
</span><span class="lines">@@ -357,7 +357,6 @@
</span><span class="cx"> 
</span><span class="cx">     // Methods for indicating the style is affected by dynamic updates (e.g., children changing, our position changing in our sibling list, etc.)
</span><span class="cx">     bool styleAffectedByEmpty() const { return hasRareData() &amp;&amp; rareDataStyleAffectedByEmpty(); }
</span><del>-    bool styleOfSiblingsAffectedByEmpty() const { return hasRareData() &amp;&amp; rareDataStyleOfSiblingsAffectedByEmpty(); }
</del><span class="cx">     bool childrenAffectedByHover() const { return getFlag(ChildrenAffectedByHoverRulesFlag); }
</span><span class="cx">     bool childrenAffectedByActive() const { return hasRareData() &amp;&amp; rareDataChildrenAffectedByActive(); }
</span><span class="cx">     bool childrenAffectedByDrag() const { return hasRareData() &amp;&amp; rareDataChildrenAffectedByDrag(); }
</span><span class="lines">@@ -372,7 +371,6 @@
</span><span class="cx">     bool hasFlagsSetDuringStylingOfChildren() const;
</span><span class="cx"> 
</span><span class="cx">     void setStyleAffectedByEmpty();
</span><del>-    void setStyleOfSiblingsAffectedByEmpty();
</del><span class="cx">     void setChildrenAffectedByHover() { setFlag(ChildrenAffectedByHoverRulesFlag); }
</span><span class="cx">     void setChildrenAffectedByActive();
</span><span class="cx">     void setChildrenAffectedByDrag();
</span><span class="lines">@@ -648,7 +646,6 @@
</span><span class="cx">     void removeShadowRoot();
</span><span class="cx"> 
</span><span class="cx">     bool rareDataStyleAffectedByEmpty() const;
</span><del>-    bool rareDataStyleOfSiblingsAffectedByEmpty() const;
</del><span class="cx">     bool rareDataChildrenAffectedByHover() const;
</span><span class="cx">     bool rareDataChildrenAffectedByActive() const;
</span><span class="cx">     bool rareDataChildrenAffectedByDrag() const;
</span></span></pre></div>
<a id="trunkSourceWebCoredomElementRareDatah"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/ElementRareData.h (172879 => 172880)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/ElementRareData.h        2014-08-23 01:58:06 UTC (rev 172879)
+++ trunk/Source/WebCore/dom/ElementRareData.h        2014-08-23 04:30:33 UTC (rev 172880)
</span><span class="lines">@@ -60,9 +60,6 @@
</span><span class="cx">     bool styleAffectedByEmpty() const { return m_styleAffectedByEmpty; }
</span><span class="cx">     void setStyleAffectedByEmpty(bool value) { m_styleAffectedByEmpty = value; }
</span><span class="cx"> 
</span><del>-    bool styleOfSiblingsAffectedByEmpty() const { return m_styleOfSiblingsAffectedByEmpty; }
-    void setStyleOfSiblingsAffectedByEmpty(bool value) { m_styleOfSiblingsAffectedByEmpty = value; }
-
</del><span class="cx">     RegionOversetState regionOversetState() const { return m_regionOversetState; }
</span><span class="cx">     void setRegionOversetState(RegionOversetState state) { m_regionOversetState = state; }
</span><span class="cx"> 
</span><span class="lines">@@ -124,7 +121,6 @@
</span><span class="cx">     unsigned m_tabIndexWasSetExplicitly : 1;
</span><span class="cx">     unsigned m_needsFocusAppearanceUpdateSoonAfterAttach : 1;
</span><span class="cx">     unsigned m_styleAffectedByEmpty : 1;
</span><del>-    unsigned m_styleOfSiblingsAffectedByEmpty : 1;
</del><span class="cx"> #if ENABLE(FULLSCREEN_API)
</span><span class="cx">     unsigned m_containsFullScreenElement : 1;
</span><span class="cx"> #endif
</span><span class="lines">@@ -169,7 +165,6 @@
</span><span class="cx">     , m_tabIndexWasSetExplicitly(false)
</span><span class="cx">     , m_needsFocusAppearanceUpdateSoonAfterAttach(false)
</span><span class="cx">     , m_styleAffectedByEmpty(false)
</span><del>-    , m_styleOfSiblingsAffectedByEmpty(false)
</del><span class="cx"> #if ENABLE(FULLSCREEN_API)
</span><span class="cx">     , m_containsFullScreenElement(false)
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebCoredomNodecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Node.cpp (172879 => 172880)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Node.cpp        2014-08-23 01:58:06 UTC (rev 172879)
+++ trunk/Source/WebCore/dom/Node.cpp        2014-08-23 04:30:33 UTC (rev 172880)
</span><span class="lines">@@ -639,16 +639,6 @@
</span><span class="cx">     return LayoutRect();    
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Node::markAncestorsWithChildNeedsStyleRecalc()
-{
-    ContainerNode* ancestor = isPseudoElement() ? toPseudoElement(this)-&gt;hostElement() : parentOrShadowHostNode();
-    for (; ancestor &amp;&amp; !ancestor-&gt;childNeedsStyleRecalc(); ancestor = ancestor-&gt;parentOrShadowHostNode())
-        ancestor-&gt;setChildNeedsStyleRecalc();
-
-    if (document().childNeedsStyleRecalc())
-        document().scheduleStyleRecalc();
-}
-
</del><span class="cx"> void Node::refEventTarget()
</span><span class="cx"> {
</span><span class="cx">     ref();
</span><span class="lines">@@ -659,6 +649,20 @@
</span><span class="cx">     deref();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static inline void markAncestorsWithChildNeedsStyleRecalc(Node&amp; node)
+{
+    if (ContainerNode* ancestor = node.isPseudoElement() ? toPseudoElement(node).hostElement() : node.parentOrShadowHostNode()) {
+        ancestor-&gt;setDirectChildNeedsStyleRecalc();
+
+        for (; ancestor &amp;&amp; !ancestor-&gt;childNeedsStyleRecalc(); ancestor = ancestor-&gt;parentOrShadowHostNode())
+            ancestor-&gt;setChildNeedsStyleRecalc();
+    }
+
+    Document&amp; document = node.document();
+    if (document.childNeedsStyleRecalc())
+        document.scheduleStyleRecalc();
+}
+
</ins><span class="cx"> void Node::setNeedsStyleRecalc(StyleChangeType changeType)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(changeType != NoStyleChange);
</span><span class="lines">@@ -670,7 +674,7 @@
</span><span class="cx">         setStyleChange(changeType);
</span><span class="cx"> 
</span><span class="cx">     if (existingChangeType == NoStyleChange || changeType == ReconstructRenderTree)
</span><del>-        markAncestorsWithChildNeedsStyleRecalc();
</del><ins>+        markAncestorsWithChildNeedsStyleRecalc(*this);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> unsigned Node::nodeIndex() const
</span></span></pre></div>
<a id="trunkSourceWebCoredomNodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Node.h (172879 => 172880)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Node.h        2014-08-23 01:58:06 UTC (rev 172879)
+++ trunk/Source/WebCore/dom/Node.h        2014-08-23 04:30:33 UTC (rev 172880)
</span><span class="lines">@@ -329,7 +329,7 @@
</span><span class="cx">     bool isEditingText() const { return getFlag(IsEditingTextFlag); }
</span><span class="cx"> 
</span><span class="cx">     void setChildNeedsStyleRecalc() { setFlag(ChildNeedsStyleRecalcFlag); }
</span><del>-    void clearChildNeedsStyleRecalc() { clearFlag(ChildNeedsStyleRecalcFlag); }
</del><ins>+    void clearChildNeedsStyleRecalc() { m_nodeFlags &amp;= ~(ChildNeedsStyleRecalcFlag | DirectChildNeedsStyleRecalcFlag); }
</ins><span class="cx"> 
</span><span class="cx">     WEBCORE_EXPORT void setNeedsStyleRecalc(StyleChangeType = FullStyleChange);
</span><span class="cx">     void clearNeedsStyleRecalc() { m_nodeFlags &amp;= ~StyleChangeMask; }
</span><span class="lines">@@ -567,8 +567,6 @@
</span><span class="cx">     void updateAncestorConnectedSubframeCountForRemoval() const;
</span><span class="cx">     void updateAncestorConnectedSubframeCountForInsertion() const;
</span><span class="cx"> 
</span><del>-    void markAncestorsWithChildNeedsStyleRecalc();
-
</del><span class="cx"> #if ENABLE(CSS_SELECTOR_JIT)
</span><span class="cx">     static ptrdiff_t nodeFlagsMemoryOffset() { return OBJECT_OFFSETOF(Node, m_nodeFlags); }
</span><span class="cx">     static ptrdiff_t rareDataMemoryOffset() { return OBJECT_OFFSETOF(Node, m_data.m_rareData); }
</span><span class="lines">@@ -616,10 +614,11 @@
</span><span class="cx">         ChildrenAffectedByLastChildRulesFlag = 1 &lt;&lt; 26,
</span><span class="cx">         ChildrenAffectedByDirectAdjacentRulesFlag = 1 &lt;&lt; 27,
</span><span class="cx">         ChildrenAffectedByHoverRulesFlag = 1 &lt;&lt; 28,
</span><ins>+        DirectChildNeedsStyleRecalcFlag = 1 &lt;&lt; 29,
</ins><span class="cx"> 
</span><del>-        SelfOrAncestorHasDirAutoFlag = 1 &lt;&lt; 29,
</del><ins>+        SelfOrAncestorHasDirAutoFlag = 1 &lt;&lt; 30,
</ins><span class="cx"> 
</span><del>-        IsHTMLUnknownElementFlag = 1 &lt;&lt; 30,
</del><ins>+        IsHTMLUnknownElementFlag = 1 &lt;&lt; 31,
</ins><span class="cx"> 
</span><span class="cx">         DefaultNodeFlags = IsParsingChildrenFinishedFlag
</span><span class="cx">     };
</span></span></pre></div>
<a id="trunkSourceWebCorestyleStyleResolveTreecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/style/StyleResolveTree.cpp (172879 => 172880)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/style/StyleResolveTree.cpp        2014-08-23 01:58:06 UTC (rev 172879)
+++ trunk/Source/WebCore/style/StyleResolveTree.cpp        2014-08-23 04:30:33 UTC (rev 172880)
</span><span class="lines">@@ -552,9 +552,10 @@
</span><span class="cx"> static void resetStyleForNonRenderedDescendants(Element&amp; current)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!current.renderer());
</span><ins>+    bool shouldInvalidateDirectChildren = current.directChildNeedsStyleRecalc() &amp;&amp; (current.childrenAffectedByDirectAdjacentRules() || current.childrenAffectedByForwardPositionalRules());
</ins><span class="cx">     for (auto&amp; child : childrenOfType&lt;Element&gt;(current)) {
</span><span class="cx">         ASSERT(!child.renderer());
</span><del>-        if (child.needsStyleRecalc()) {
</del><ins>+        if (shouldInvalidateDirectChildren || child.needsStyleRecalc()) {
</ins><span class="cx">             child.resetComputedStyle();
</span><span class="cx">             child.clearNeedsStyleRecalc();
</span><span class="cx">         }
</span></span></pre>
</div>
</div>

</body>
</html>