<!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>[169547] 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/169547">169547</a></dd>
<dt>Author</dt> <dd>benjamin@webkit.org</dd>
<dt>Date</dt> <dd>2014-06-02 15:07:24 -0700 (Mon, 02 Jun 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Make pseudo element matching for style resolution more JIT friendly
https://bugs.webkit.org/show_bug.cgi?id=133441

Reviewed by Antti Koivisto.


Source/WebCore: 
Sharing pseudo elements is a complicated mess shared between the SelectorChecker
and the RuleCollector.

For compiling pseudo element matching, it would be best if all the complexity could
be moved to compile time instead of runtime. It is also preferable to keep the compiler
independant of the RuleCollector implementation's detail.

This patch is a first step toward that goal. The main objective here is to make
&quot;dynamicPseudo&quot; completely internal to the SelectorChecker.
This is mostly a mechanical change, it is likely PseudoElement matching could be simplified
further but that is not attempted here.

Test: fast/css/style-sharing-empty-rule-modification.html

* css/ElementRuleCollector.cpp:
(WebCore::ElementRuleCollector::ruleMatches):
The condition regarding pseudo element matching has been moved into SelectorChecker::match().

This creates an extra cost for querySelector(), but that should be fine since the vast majority
of selectors are JIT compiled and never use SelectorChecker in the first place.

(WebCore::ElementRuleCollector::collectMatchingRulesForList):
The loop is changed such that the tree marking (Style::setHasPseudoStyle) could be moved
to SelectorChecker.

The conditions about the security origin for getMatchedCSSRules() and the empty style rules
are moved prior to the call to ElementRuleCollector::ruleMatches(). This ensure we keep the same
behavior of not adding the pseudo style for empty rules (this could also help with tree marking
in general but empty rules are probably uncommon).

There is one behavior change from making this loop simpler: the SharingRules and StyleInvalidation
modes now update their ruleRange. It is useless but it is simpler.

* css/ElementRuleCollector.h:
* css/SelectorChecker.cpp:
(WebCore::SelectorChecker::matchRecursively):
The tree marking has been moved here.

* css/SelectorChecker.h:
(WebCore::SelectorChecker::match):
The pseudo element matching has been moved here.

* css/StyleResolver.h:
(WebCore::checkRegionSelector):
* dom/SelectorQuery.cpp:
(WebCore::SelectorDataList::selectorMatches):

LayoutTests: 
Add more coverage for style sharing with empty rules, just in case.

* fast/css/style-sharing-empty-rule-modification-expected.txt: Added.
* fast/css/style-sharing-empty-rule-modification.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorecssElementRuleCollectorcpp">trunk/Source/WebCore/css/ElementRuleCollector.cpp</a></li>
<li><a href="#trunkSourceWebCorecssElementRuleCollectorh">trunk/Source/WebCore/css/ElementRuleCollector.h</a></li>
<li><a href="#trunkSourceWebCorecssSelectorCheckercpp">trunk/Source/WebCore/css/SelectorChecker.cpp</a></li>
<li><a href="#trunkSourceWebCorecssSelectorCheckerh">trunk/Source/WebCore/css/SelectorChecker.h</a></li>
<li><a href="#trunkSourceWebCorecssStyleResolverh">trunk/Source/WebCore/css/StyleResolver.h</a></li>
<li><a href="#trunkSourceWebCoredomSelectorQuerycpp">trunk/Source/WebCore/dom/SelectorQuery.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsfastcssstylesharingemptyrulemodificationexpectedtxt">trunk/LayoutTests/fast/css/style-sharing-empty-rule-modification-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastcssstylesharingemptyrulemodificationhtml">trunk/LayoutTests/fast/css/style-sharing-empty-rule-modification.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (169546 => 169547)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2014-06-02 21:54:15 UTC (rev 169546)
+++ trunk/LayoutTests/ChangeLog        2014-06-02 22:07:24 UTC (rev 169547)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2014-06-02  Benjamin Poulain  &lt;benjamin@webkit.org&gt;
+
+        Make pseudo element matching for style resolution more JIT friendly
+        https://bugs.webkit.org/show_bug.cgi?id=133441
+
+        Reviewed by Antti Koivisto.
+
+        Add more coverage for style sharing with empty rules, just in case.
+
+        * fast/css/style-sharing-empty-rule-modification-expected.txt: Added.
+        * fast/css/style-sharing-empty-rule-modification.html: Added.
+
</ins><span class="cx"> 2014-06-02  Martin Hock  &lt;mhock@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed TestExpectations gardening after r169532.
</span></span></pre></div>
<a id="trunkLayoutTestsfastcssstylesharingemptyrulemodificationexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/css/style-sharing-empty-rule-modification-expected.txt (0 => 169547)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/css/style-sharing-empty-rule-modification-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/css/style-sharing-empty-rule-modification-expected.txt        2014-06-02 22:07:24 UTC (rev 169547)
</span><span class="lines">@@ -0,0 +1,34 @@
</span><ins>+Test that changing an empty rule with CSSOM updates the elements correctly.
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+Before changing the rules
+PASS window.getComputedStyle(document.getElementById(&quot;target1&quot;)).backgroundColor is &quot;rgb(1, 2, 3)&quot;
+PASS window.getComputedStyle(document.getElementById(&quot;target2&quot;)).backgroundColor is &quot;rgb(1, 2, 3)&quot;
+PASS window.getComputedStyle(document.getElementById(&quot;target3&quot;)).backgroundColor is &quot;rgb(1, 2, 3)&quot;
+PASS window.getComputedStyle(document.getElementById(&quot;target4&quot;)).backgroundColor is &quot;rgb(1, 2, 3)&quot;
+Changing the first-child rule
+PASS window.getComputedStyle(document.getElementById(&quot;target1&quot;)).backgroundColor is &quot;rgb(4, 5, 6)&quot;
+PASS window.getComputedStyle(document.getElementById(&quot;target2&quot;)).backgroundColor is &quot;rgb(1, 2, 3)&quot;
+PASS window.getComputedStyle(document.getElementById(&quot;target3&quot;)).backgroundColor is &quot;rgb(1, 2, 3)&quot;
+PASS window.getComputedStyle(document.getElementById(&quot;target4&quot;)).backgroundColor is &quot;rgb(1, 2, 3)&quot;
+Changing the last-child rule
+PASS window.getComputedStyle(document.getElementById(&quot;target1&quot;)).backgroundColor is &quot;rgb(4, 5, 6)&quot;
+PASS window.getComputedStyle(document.getElementById(&quot;target2&quot;)).backgroundColor is &quot;rgb(1, 2, 3)&quot;
+PASS window.getComputedStyle(document.getElementById(&quot;target3&quot;)).backgroundColor is &quot;rgb(1, 2, 3)&quot;
+PASS window.getComputedStyle(document.getElementById(&quot;target4&quot;)).backgroundColor is &quot;rgb(7, 8, 9)&quot;
+Emptying the first-child rule
+PASS window.getComputedStyle(document.getElementById(&quot;target1&quot;)).backgroundColor is &quot;rgb(1, 2, 3)&quot;
+PASS window.getComputedStyle(document.getElementById(&quot;target2&quot;)).backgroundColor is &quot;rgb(1, 2, 3)&quot;
+PASS window.getComputedStyle(document.getElementById(&quot;target3&quot;)).backgroundColor is &quot;rgb(1, 2, 3)&quot;
+PASS window.getComputedStyle(document.getElementById(&quot;target4&quot;)).backgroundColor is &quot;rgb(7, 8, 9)&quot;
+Emptying the last-child rule
+PASS window.getComputedStyle(document.getElementById(&quot;target1&quot;)).backgroundColor is &quot;rgb(1, 2, 3)&quot;
+PASS window.getComputedStyle(document.getElementById(&quot;target2&quot;)).backgroundColor is &quot;rgb(1, 2, 3)&quot;
+PASS window.getComputedStyle(document.getElementById(&quot;target3&quot;)).backgroundColor is &quot;rgb(1, 2, 3)&quot;
+PASS window.getComputedStyle(document.getElementById(&quot;target4&quot;)).backgroundColor is &quot;rgb(1, 2, 3)&quot;
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastcssstylesharingemptyrulemodificationhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/css/style-sharing-empty-rule-modification.html (0 => 169547)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/css/style-sharing-empty-rule-modification.html                                (rev 0)
+++ trunk/LayoutTests/fast/css/style-sharing-empty-rule-modification.html        2014-06-02 22:07:24 UTC (rev 169547)
</span><span class="lines">@@ -0,0 +1,71 @@
</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;
+target { display:block; background-color: rgb(1, 2, 3); }
+target:first-child { }
+target:last-child { }
+&lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;div style=&quot;display:none&quot;&gt;
+    &lt;target id=target1&gt;&lt;/target&gt;
+    &lt;target id=target2&gt;&lt;/target&gt;
+    &lt;target id=target3&gt;&lt;/target&gt;
+    &lt;target id=target4&gt;&lt;/target&gt;
+&lt;/div&gt;
+
+&lt;script&gt;
+function findRuleWithSelector(selector)
+{
+    var styleSheets = document.styleSheets;
+    for (var styleSheetIndex = 0, styleSheetCount = styleSheets.length; styleSheetIndex &lt; styleSheetCount; ++styleSheetIndex) {
+        var styleSheet = styleSheets[styleSheetIndex];
+        var rules = styleSheet.cssRules;
+        for (var ruleIndex = 0, ruleCount = rules.length; ruleIndex &lt; ruleCount; ++ruleIndex) {
+            var rule = rules[ruleIndex];
+            if (rule.selectorText === selector)
+                return rule;
+        }
+    }
+}
+
+description(&quot;Test that changing an empty rule with CSSOM updates the elements correctly.&quot;);
+debug('Before changing the rules');
+shouldBe('window.getComputedStyle(document.getElementById(&quot;target1&quot;)).backgroundColor','&quot;rgb(1, 2, 3)&quot;');
+shouldBe('window.getComputedStyle(document.getElementById(&quot;target2&quot;)).backgroundColor','&quot;rgb(1, 2, 3)&quot;');
+shouldBe('window.getComputedStyle(document.getElementById(&quot;target3&quot;)).backgroundColor','&quot;rgb(1, 2, 3)&quot;');
+shouldBe('window.getComputedStyle(document.getElementById(&quot;target4&quot;)).backgroundColor','&quot;rgb(1, 2, 3)&quot;');
+
+debug('Changing the first-child rule');
+findRuleWithSelector('target:first-child').style.backgroundColor = 'rgb(4, 5, 6)';
+shouldBe('window.getComputedStyle(document.getElementById(&quot;target1&quot;)).backgroundColor','&quot;rgb(4, 5, 6)&quot;');
+shouldBe('window.getComputedStyle(document.getElementById(&quot;target2&quot;)).backgroundColor','&quot;rgb(1, 2, 3)&quot;');
+shouldBe('window.getComputedStyle(document.getElementById(&quot;target3&quot;)).backgroundColor','&quot;rgb(1, 2, 3)&quot;');
+shouldBe('window.getComputedStyle(document.getElementById(&quot;target4&quot;)).backgroundColor','&quot;rgb(1, 2, 3)&quot;');
+
+debug('Changing the last-child rule');
+findRuleWithSelector('target:last-child').style.backgroundColor = 'rgb(7, 8, 9)';
+shouldBe('window.getComputedStyle(document.getElementById(&quot;target1&quot;)).backgroundColor','&quot;rgb(4, 5, 6)&quot;');
+shouldBe('window.getComputedStyle(document.getElementById(&quot;target2&quot;)).backgroundColor','&quot;rgb(1, 2, 3)&quot;');
+shouldBe('window.getComputedStyle(document.getElementById(&quot;target3&quot;)).backgroundColor','&quot;rgb(1, 2, 3)&quot;');
+shouldBe('window.getComputedStyle(document.getElementById(&quot;target4&quot;)).backgroundColor','&quot;rgb(7, 8, 9)&quot;');
+
+debug('Emptying the first-child rule');
+findRuleWithSelector('target:first-child').style.backgroundColor = '';
+shouldBe('window.getComputedStyle(document.getElementById(&quot;target1&quot;)).backgroundColor','&quot;rgb(1, 2, 3)&quot;');
+shouldBe('window.getComputedStyle(document.getElementById(&quot;target2&quot;)).backgroundColor','&quot;rgb(1, 2, 3)&quot;');
+shouldBe('window.getComputedStyle(document.getElementById(&quot;target3&quot;)).backgroundColor','&quot;rgb(1, 2, 3)&quot;');
+shouldBe('window.getComputedStyle(document.getElementById(&quot;target4&quot;)).backgroundColor','&quot;rgb(7, 8, 9)&quot;');
+
+debug('Emptying the last-child rule');
+findRuleWithSelector('target:last-child').style.backgroundColor = '';
+shouldBe('window.getComputedStyle(document.getElementById(&quot;target1&quot;)).backgroundColor','&quot;rgb(1, 2, 3)&quot;');
+shouldBe('window.getComputedStyle(document.getElementById(&quot;target2&quot;)).backgroundColor','&quot;rgb(1, 2, 3)&quot;');
+shouldBe('window.getComputedStyle(document.getElementById(&quot;target3&quot;)).backgroundColor','&quot;rgb(1, 2, 3)&quot;');
+shouldBe('window.getComputedStyle(document.getElementById(&quot;target4&quot;)).backgroundColor','&quot;rgb(1, 2, 3)&quot;');
+
+&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (169546 => 169547)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-06-02 21:54:15 UTC (rev 169546)
+++ trunk/Source/WebCore/ChangeLog        2014-06-02 22:07:24 UTC (rev 169547)
</span><span class="lines">@@ -1,3 +1,57 @@
</span><ins>+2014-06-02  Benjamin Poulain  &lt;benjamin@webkit.org&gt;
+
+        Make pseudo element matching for style resolution more JIT friendly
+        https://bugs.webkit.org/show_bug.cgi?id=133441
+
+        Reviewed by Antti Koivisto.
+
+        Sharing pseudo elements is a complicated mess shared between the SelectorChecker
+        and the RuleCollector.
+
+        For compiling pseudo element matching, it would be best if all the complexity could
+        be moved to compile time instead of runtime. It is also preferable to keep the compiler
+        independant of the RuleCollector implementation's detail.
+
+        This patch is a first step toward that goal. The main objective here is to make
+        &quot;dynamicPseudo&quot; completely internal to the SelectorChecker.
+        This is mostly a mechanical change, it is likely PseudoElement matching could be simplified
+        further but that is not attempted here.
+
+        Test: fast/css/style-sharing-empty-rule-modification.html
+
+        * css/ElementRuleCollector.cpp:
+        (WebCore::ElementRuleCollector::ruleMatches):
+        The condition regarding pseudo element matching has been moved into SelectorChecker::match().
+
+        This creates an extra cost for querySelector(), but that should be fine since the vast majority
+        of selectors are JIT compiled and never use SelectorChecker in the first place.
+
+        (WebCore::ElementRuleCollector::collectMatchingRulesForList):
+        The loop is changed such that the tree marking (Style::setHasPseudoStyle) could be moved
+        to SelectorChecker.
+
+        The conditions about the security origin for getMatchedCSSRules() and the empty style rules
+        are moved prior to the call to ElementRuleCollector::ruleMatches(). This ensure we keep the same
+        behavior of not adding the pseudo style for empty rules (this could also help with tree marking
+        in general but empty rules are probably uncommon).
+
+        There is one behavior change from making this loop simpler: the SharingRules and StyleInvalidation
+        modes now update their ruleRange. It is useless but it is simpler.
+
+        * css/ElementRuleCollector.h:
+        * css/SelectorChecker.cpp:
+        (WebCore::SelectorChecker::matchRecursively):
+        The tree marking has been moved here.
+
+        * css/SelectorChecker.h:
+        (WebCore::SelectorChecker::match):
+        The pseudo element matching has been moved here.
+
+        * css/StyleResolver.h:
+        (WebCore::checkRegionSelector):
+        * dom/SelectorQuery.cpp:
+        (WebCore::SelectorDataList::selectorMatches):
+
</ins><span class="cx"> 2014-06-02  Jeremy Jones  &lt;jeremyj@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Send external playback properties to fullscreen.
</span></span></pre></div>
<a id="trunkSourceWebCorecssElementRuleCollectorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/ElementRuleCollector.cpp (169546 => 169547)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/ElementRuleCollector.cpp        2014-06-02 21:54:15 UTC (rev 169546)
+++ trunk/Source/WebCore/css/ElementRuleCollector.cpp        2014-06-02 22:07:24 UTC (rev 169547)
</span><span class="lines">@@ -271,7 +271,7 @@
</span><span class="cx">     sortAndTransferMatchedRules();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline bool ElementRuleCollector::ruleMatches(const RuleData&amp; ruleData, PseudoId&amp; dynamicPseudo)
</del><ins>+inline bool ElementRuleCollector::ruleMatches(const RuleData&amp; ruleData)
</ins><span class="cx"> {
</span><span class="cx">     bool fastCheckableSelector = ruleData.hasFastCheckableSelector();
</span><span class="cx">     if (fastCheckableSelector) {
</span><span class="lines">@@ -332,11 +332,7 @@
</span><span class="cx">     context.pseudoId = m_pseudoStyleRequest.pseudoId;
</span><span class="cx">     context.scrollbar = m_pseudoStyleRequest.scrollbar;
</span><span class="cx">     context.scrollbarPart = m_pseudoStyleRequest.scrollbarPart;
</span><del>-    if (!selectorChecker.match(context, dynamicPseudo))
-        return false;
-    if (m_pseudoStyleRequest.pseudoId != NOPSEUDO &amp;&amp; m_pseudoStyleRequest.pseudoId != dynamicPseudo)
-        return false;
-    return true;
</del><ins>+    return selectorChecker.match(context);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ElementRuleCollector::collectMatchingRulesForList(const Vector&lt;RuleData&gt;* rules, const MatchRequest&amp; matchRequest, StyleResolver::RuleRange&amp; ruleRange)
</span><span class="lines">@@ -350,38 +346,24 @@
</span><span class="cx">             continue;
</span><span class="cx"> 
</span><span class="cx">         StyleRule* rule = ruleData.rule();
</span><del>-        PseudoId dynamicPseudo = NOPSEUDO;
-        if (ruleMatches(ruleData, dynamicPseudo)) {
-            // For SharingRules testing, any match is good enough, we don't care what is matched.
-            if (m_mode == SelectorChecker::SharingRules || m_mode == SelectorChecker::StyleInvalidation) {
-                addMatchedRule(&amp;ruleData);
-                break;
-            }
</del><span class="cx"> 
</span><del>-            // If the rule has no properties to apply, then ignore it in the non-debug mode.
-            const StyleProperties&amp; properties = rule-&gt;properties();
-            if (properties.isEmpty() &amp;&amp; !matchRequest.includeEmptyRules)
-                continue;
-            // FIXME: Exposing the non-standard getMatchedCSSRules API to web is the only reason this is needed.
-            if (m_sameOriginOnly &amp;&amp; !ruleData.hasDocumentSecurityOrigin())
-                continue;
-            // If we're matching normal rules, set a pseudo bit if
-            // we really just matched a pseudo-element.
-            if (dynamicPseudo != NOPSEUDO &amp;&amp; m_pseudoStyleRequest.pseudoId == NOPSEUDO) {
-                if (m_mode == SelectorChecker::CollectingRules)
-                    continue;
-                if (dynamicPseudo &lt; FIRST_INTERNAL_PSEUDOID &amp;&amp; m_style)
-                    m_style-&gt;setHasPseudoStyle(dynamicPseudo);
-            } else {
-                // Update our first/last rule indices in the matched rules array.
-                ++ruleRange.lastRuleIndex;
-                if (ruleRange.firstRuleIndex == -1)
-                    ruleRange.firstRuleIndex = ruleRange.lastRuleIndex;
</del><ins>+        // If the rule has no properties to apply, then ignore it in the non-debug mode.
+        const StyleProperties&amp; properties = rule-&gt;properties();
+        if (properties.isEmpty() &amp;&amp; !matchRequest.includeEmptyRules)
+            continue;
</ins><span class="cx"> 
</span><del>-                // Add this rule to our list of matched rules.
-                addMatchedRule(&amp;ruleData);
-                continue;
-            }
</del><ins>+        // FIXME: Exposing the non-standard getMatchedCSSRules API to web is the only reason this is needed.
+        if (m_sameOriginOnly &amp;&amp; !ruleData.hasDocumentSecurityOrigin())
+            continue;
+
+        if (ruleMatches(ruleData)) {
+            // Update our first/last rule indices in the matched rules array.
+            ++ruleRange.lastRuleIndex;
+            if (ruleRange.firstRuleIndex == -1)
+                ruleRange.firstRuleIndex = ruleRange.lastRuleIndex;
+
+            // Add this rule to our list of matched rules.
+            addMatchedRule(&amp;ruleData);
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCorecssElementRuleCollectorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/ElementRuleCollector.h (169546 => 169547)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/ElementRuleCollector.h        2014-06-02 21:54:15 UTC (rev 169546)
+++ trunk/Source/WebCore/css/ElementRuleCollector.h        2014-06-02 22:07:24 UTC (rev 169547)
</span><span class="lines">@@ -81,7 +81,7 @@
</span><span class="cx">     void collectMatchingRules(const MatchRequest&amp;, StyleResolver::RuleRange&amp;);
</span><span class="cx">     void collectMatchingRulesForRegion(const MatchRequest&amp;, StyleResolver::RuleRange&amp;);
</span><span class="cx">     void collectMatchingRulesForList(const Vector&lt;RuleData&gt;*, const MatchRequest&amp;, StyleResolver::RuleRange&amp;);
</span><del>-    bool ruleMatches(const RuleData&amp;, PseudoId&amp;);
</del><ins>+    bool ruleMatches(const RuleData&amp;);
</ins><span class="cx"> 
</span><span class="cx">     void sortMatchedRules();
</span><span class="cx">     void sortAndTransferMatchedRules();
</span></span></pre></div>
<a id="trunkSourceWebCorecssSelectorCheckercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/SelectorChecker.cpp (169546 => 169547)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/SelectorChecker.cpp        2014-06-02 21:54:15 UTC (rev 169546)
+++ trunk/Source/WebCore/css/SelectorChecker.cpp        2014-06-02 22:07:24 UTC (rev 169547)
</span><span class="lines">@@ -167,10 +167,17 @@
</span><span class="cx"> 
</span><span class="cx">             // When invalidating style all pseudo elements need to match.
</span><span class="cx">             PseudoId pseudoId = m_mode == StyleInvalidation ? NOPSEUDO : CSSSelector::pseudoId(context.selector-&gt;pseudoElementType());
</span><del>-            if (pseudoId == FIRST_LETTER)
-                context.element-&gt;document().styleSheetCollection().setUsesFirstLetterRules(true);
-            if (pseudoId != NOPSEUDO)
</del><ins>+            if (pseudoId != NOPSEUDO) {
</ins><span class="cx">                 dynamicPseudo = pseudoId;
</span><ins>+
+                if (pseudoId == FIRST_LETTER)
+                    context.element-&gt;document().styleSheetCollection().setUsesFirstLetterRules(true);
+
+                if (context.pseudoId == NOPSEUDO) {
+                    if (m_mode == ResolvingStyle &amp;&amp; pseudoId &lt; FIRST_INTERNAL_PSEUDOID)
+                        context.elementStyle-&gt;setHasPseudoStyle(pseudoId);
+                }
+            }
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorecssSelectorCheckerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/SelectorChecker.h (169546 => 169547)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/SelectorChecker.h        2014-06-02 21:54:15 UTC (rev 169546)
+++ trunk/Source/WebCore/css/SelectorChecker.h        2014-06-02 22:07:24 UTC (rev 169547)
</span><span class="lines">@@ -82,9 +82,18 @@
</span><span class="cx">         bool hasSelectionPseudo;
</span><span class="cx">     };
</span><span class="cx"> 
</span><del>-    bool match(const SelectorCheckingContext&amp; context, PseudoId&amp; pseudoId) const
</del><ins>+    bool match(const SelectorCheckingContext&amp; context) const
</ins><span class="cx">     {
</span><del>-        return matchRecursively(context, pseudoId) == SelectorMatches;
</del><ins>+        PseudoId pseudoId = NOPSEUDO;
+        if (matchRecursively(context, pseudoId) != SelectorMatches)
+            return false;
+        if (context.pseudoId != NOPSEUDO &amp;&amp; context.pseudoId != pseudoId)
+            return false;
+        if (context.pseudoId == NOPSEUDO &amp;&amp; pseudoId != NOPSEUDO) {
+            // For SharingRules testing, any match is good enough, we don't care what is matched.
+            return m_mode == SharingRules || m_mode == StyleInvalidation;
+        }
+        return true;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     static bool tagMatches(const Element*, const QualifiedName&amp;);
</span></span></pre></div>
<a id="trunkSourceWebCorecssStyleResolverh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/StyleResolver.h (169546 => 169547)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/StyleResolver.h        2014-06-02 21:54:15 UTC (rev 169546)
+++ trunk/Source/WebCore/css/StyleResolver.h        2014-06-02 22:07:24 UTC (rev 169547)
</span><span class="lines">@@ -567,8 +567,7 @@
</span><span class="cx">     SelectorChecker selectorChecker(regionElement-&gt;document(), SelectorChecker::QueryingRules);
</span><span class="cx">     for (const CSSSelector* s = regionSelector; s; s = CSSSelectorList::next(s)) {
</span><span class="cx">         SelectorChecker::SelectorCheckingContext selectorCheckingContext(s, regionElement, SelectorChecker::VisitedMatchDisabled);
</span><del>-        PseudoId ignoreDynamicPseudo = NOPSEUDO;
-        if (selectorChecker.match(selectorCheckingContext, ignoreDynamicPseudo))
</del><ins>+        if (selectorChecker.match(selectorCheckingContext))
</ins><span class="cx">             return true;
</span><span class="cx">     }
</span><span class="cx">     return false;
</span></span></pre></div>
<a id="trunkSourceWebCoredomSelectorQuerycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/SelectorQuery.cpp (169546 => 169547)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/SelectorQuery.cpp        2014-06-02 21:54:15 UTC (rev 169546)
+++ trunk/Source/WebCore/dom/SelectorQuery.cpp        2014-06-02 22:07:24 UTC (rev 169547)
</span><span class="lines">@@ -124,8 +124,7 @@
</span><span class="cx">     SelectorChecker selectorChecker(element.document(), SelectorChecker::QueryingRules);
</span><span class="cx">     SelectorChecker::SelectorCheckingContext selectorCheckingContext(selectorData.selector, &amp;element, SelectorChecker::VisitedMatchDisabled);
</span><span class="cx">     selectorCheckingContext.scope = rootNode.isDocumentNode() ? nullptr : &amp;rootNode;
</span><del>-    PseudoId ignoreDynamicPseudo = NOPSEUDO;
-    return selectorChecker.match(selectorCheckingContext, ignoreDynamicPseudo);
</del><ins>+    return selectorChecker.match(selectorCheckingContext);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool SelectorDataList::matches(Element&amp; targetElement) const
</span></span></pre>
</div>
</div>

</body>
</html>