<!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>[169525] 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/169525">169525</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2014-06-02 00:00:53 -0700 (Mon, 02 Jun 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>CSS JIT: add support for the &quot;not&quot; pseudo class
https://bugs.webkit.org/show_bug.cgi?id=133314

Source/WebCore:
Patch by Yusuke Suzuki &lt;utatane.tea@gmail.com&gt; on 2014-06-02
Reviewed by Benjamin Poulain.

Add :not pseudo class support to CSS JIT. Current implementation
doesn't support visitedMatchType. So when link pseudo class appears in
:not sub fragment, fallback to the non-JIT implementation.

Tests: fast/selectors/not-active-hover-quirks.html
       fast/selectors/not-active-hover-strict.html
       fast/selectors/pseudo-class-not.html

* cssjit/SelectorCompiler.cpp:
(WebCore::SelectorCompiler::addPseudoClassType):
(WebCore::SelectorCompiler::SelectorCodeGenerator::SelectorCodeGenerator):
(WebCore::SelectorCompiler::constructFragments):
(WebCore::SelectorCompiler::minimumRegisterRequirements):
(WebCore::SelectorCompiler::computeBacktrackingInformation):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateSelectorChecker):
(WebCore::SelectorCompiler::fragmentOnlyMatchesLinksInQuirksMode):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementMatching):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementDataMatching):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsNthChild):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementMatchesNotPseudoClass):
(WebCore::SelectorCompiler::SelectorCodeGenerator::computeBacktrackingInformation): Deleted.

LayoutTests:
Add :not pseudo class support to CSS JIT. Current implementation
doesn't support visitedMatchType. So when link pseudo class appears in
:not sub fragment, fallback to the non-JIT implementation.

Patch by Yusuke Suzuki &lt;utatane.tea@gmail.com&gt; on 2014-06-02
Reviewed by Benjamin Poulain.

* fast/selectors/not-active-hover-quirks-expected.txt: Added.
* fast/selectors/not-active-hover-quirks.html: Added.
* fast/selectors/not-active-hover-strict-expected.txt: Added.
* fast/selectors/not-active-hover-strict.html: Added.
* fast/selectors/pseudo-class-not-expected.txt: Added.
* fast/selectors/pseudo-class-not.html: Added.
* fast/selectors/resources/not-hover-active-quirks-utility.js: Added.
(testQuerySelector):
(test):
* fast/selectors/resources/not-hover-active-strict-utility.js: Added.
(testQuerySelector):
(test):</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="#trunkSourceWebCorecssjitSelectorCompilercpp">trunk/Source/WebCore/cssjit/SelectorCompiler.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsfastselectorsnotactivehoverquirksexpectedtxt">trunk/LayoutTests/fast/selectors/not-active-hover-quirks-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastselectorsnotactivehoverquirkshtml">trunk/LayoutTests/fast/selectors/not-active-hover-quirks.html</a></li>
<li><a href="#trunkLayoutTestsfastselectorsnotactivehoverstrictexpectedtxt">trunk/LayoutTests/fast/selectors/not-active-hover-strict-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastselectorsnotactivehoverstricthtml">trunk/LayoutTests/fast/selectors/not-active-hover-strict.html</a></li>
<li><a href="#trunkLayoutTestsfastselectorspseudoclassnotexpectedtxt">trunk/LayoutTests/fast/selectors/pseudo-class-not-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastselectorspseudoclassnothtml">trunk/LayoutTests/fast/selectors/pseudo-class-not.html</a></li>
<li><a href="#trunkLayoutTestsfastselectorsresourcesnothoveractivequirksutilityjs">trunk/LayoutTests/fast/selectors/resources/not-hover-active-quirks-utility.js</a></li>
<li><a href="#trunkLayoutTestsfastselectorsresourcesnothoveractivestrictutilityjs">trunk/LayoutTests/fast/selectors/resources/not-hover-active-strict-utility.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (169524 => 169525)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2014-06-02 06:52:50 UTC (rev 169524)
+++ trunk/LayoutTests/ChangeLog        2014-06-02 07:00:53 UTC (rev 169525)
</span><span class="lines">@@ -1,3 +1,27 @@
</span><ins>+2014-06-02  Yusuke Suzuki  &lt;utatane.tea@gmail.com&gt;
+
+        CSS JIT: add support for the &quot;not&quot; pseudo class
+        https://bugs.webkit.org/show_bug.cgi?id=133314
+
+        Add :not pseudo class support to CSS JIT. Current implementation
+        doesn't support visitedMatchType. So when link pseudo class appears in
+        :not sub fragment, fallback to the non-JIT implementation.
+
+        Reviewed by Benjamin Poulain.
+
+        * fast/selectors/not-active-hover-quirks-expected.txt: Added.
+        * fast/selectors/not-active-hover-quirks.html: Added.
+        * fast/selectors/not-active-hover-strict-expected.txt: Added.
+        * fast/selectors/not-active-hover-strict.html: Added.
+        * fast/selectors/pseudo-class-not-expected.txt: Added.
+        * fast/selectors/pseudo-class-not.html: Added.
+        * fast/selectors/resources/not-hover-active-quirks-utility.js: Added.
+        (testQuerySelector):
+        (test):
+        * fast/selectors/resources/not-hover-active-strict-utility.js: Added.
+        (testQuerySelector):
+        (test):
+
</ins><span class="cx"> 2014-06-01  Jinwoo Song  &lt;jinwoo7.song@samsung.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed EFL gardening.
</span></span></pre></div>
<a id="trunkLayoutTestsfastselectorsnotactivehoverquirksexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/not-active-hover-quirks-expected.txt (0 => 169525)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/not-active-hover-quirks-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/selectors/not-active-hover-quirks-expected.txt        2014-06-02 07:00:53 UTC (rev 169525)
</span><span class="lines">@@ -0,0 +1,194 @@
</span><ins>+START
+Test the :not(:active) and :not(:hover) selector when the document is in quirks mode. To test manually, make sure not to move the cursor over the green rectangle and press the gray START div until the test is finished.
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS document.querySelectorAll(&quot;*&quot;).length - document.querySelectorAll(&quot;:not(:active)&quot;).length is 3
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;*&quot;).length - document.querySelectorAll(&quot;*:not(:active)&quot;).length is 3
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;:not(:active):hover&quot;).length is 0
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(1, 2, 3)&quot;
+PASS document.querySelectorAll(&quot;:hover:not(:active)&quot;).length is 0
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(1, 2, 3)&quot;
+PASS document.querySelectorAll(&quot;:hover:not(:active):hover&quot;).length is 0
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(1, 2, 3)&quot;
+PASS document.querySelectorAll(&quot;:not(:active):active&quot;).length is 0
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(1, 2, 3)&quot;
+PASS document.querySelectorAll(&quot;:active:not(:active)&quot;).length is 0
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(1, 2, 3)&quot;
+PASS document.querySelectorAll(&quot;:active:not(:active):active&quot;).length is 0
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(1, 2, 3)&quot;
+PASS document.querySelectorAll(&quot;testing:not(:active)&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;#target:not(:active)&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;:not(:active)#target&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;#target:not(:active)#target&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;.aClass:not(:active)&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;:not(:active).aClass&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;.aClass:not(:active).otherClass&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;.aClass[webkit]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;:not(:active)[webkit]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;[id]:not(:active)[webkit]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;.aClass[webkit=rocks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;:not(:active)[webkit=rocks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;[id=target]:not(:active)[webkit=rocks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;.aClass[webkit^=ro]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;:not(:active)[webkit^=ro]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;[id^=ta]:not(:active)[webkit^=ro]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;.aClass[webkit$=ks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;:not(:active)[webkit$=ks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;[id$=et]:not(:active)[webkit$=ks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;.aClass[webkit*=ck]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;:not(:active)[webkit*=ck]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;[id*=rg]:not(:active)[webkit*=ck]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;.aClass[webkit~=rocks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;:not(:active)[webkit~=rocks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;[id~=target]:not(:active)[webkit~=rocks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;.aClass[webkit|=rocks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;:not(:active)[webkit|=rocks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;[id|=target]:not(:active)[webkit|=rocks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;testing:nth-child(1):not(:active)&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;testing:not(:active):nth-child(1)&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;testing:nth-child(1):not(:active):nth-child(1)&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;:nth-child(n):not(:active) &gt; #target&quot;).length is 0
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(1, 2, 3)&quot;
+PASS document.querySelectorAll(&quot;:not(:active):nth-child(n) &gt; #target&quot;).length is 0
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(1, 2, 3)&quot;
+PASS document.querySelectorAll(&quot;:nth-child(n):not(:active):nth-child(n) &gt; #target&quot;).length is 0
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(1, 2, 3)&quot;
+PASS document.querySelectorAll(&quot;:nth-child(n):not(:active) #target&quot;).length is 0
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(1, 2, 3)&quot;
+PASS document.querySelectorAll(&quot;:not(:active):nth-child(n) #target&quot;).length is 0
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(1, 2, 3)&quot;
+PASS document.querySelectorAll(&quot;:nth-child(n):not(:active):nth-child(n) #target&quot;).length is 0
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(1, 2, 3)&quot;
+PASS document.querySelectorAll(&quot;:-webkit-any(:not(:active)) #target&quot;).length is 0
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(1, 2, 3)&quot;
+PASS document.querySelectorAll(&quot;*&quot;).length - document.querySelectorAll(&quot;:not(:hover)&quot;).length is 3
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;*&quot;).length - document.querySelectorAll(&quot;*:not(:hover)&quot;).length is 3
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;:not(:hover):hover&quot;).length is 0
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(1, 2, 3)&quot;
+PASS document.querySelectorAll(&quot;:hover:not(:hover)&quot;).length is 0
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(1, 2, 3)&quot;
+PASS document.querySelectorAll(&quot;:hover:not(:hover):hover&quot;).length is 0
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(1, 2, 3)&quot;
+PASS document.querySelectorAll(&quot;:not(:hover):active&quot;).length is 0
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(1, 2, 3)&quot;
+PASS document.querySelectorAll(&quot;:active:not(:hover)&quot;).length is 0
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(1, 2, 3)&quot;
+PASS document.querySelectorAll(&quot;:active:not(:hover):active&quot;).length is 0
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(1, 2, 3)&quot;
+PASS document.querySelectorAll(&quot;testing:not(:hover)&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;#target:not(:hover)&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;:not(:hover)#target&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;#target:not(:hover)#target&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;.aClass:not(:hover)&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;:not(:hover).aClass&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;.aClass:not(:hover).otherClass&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;.aClass[webkit]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;:not(:hover)[webkit]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;[id]:not(:hover)[webkit]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;.aClass[webkit=rocks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;:not(:hover)[webkit=rocks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;[id=target]:not(:hover)[webkit=rocks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;.aClass[webkit^=ro]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;:not(:hover)[webkit^=ro]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;[id^=ta]:not(:hover)[webkit^=ro]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;.aClass[webkit$=ks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;:not(:hover)[webkit$=ks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;[id$=et]:not(:hover)[webkit$=ks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;.aClass[webkit*=ck]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;:not(:hover)[webkit*=ck]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;[id*=rg]:not(:hover)[webkit*=ck]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;.aClass[webkit~=rocks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;:not(:hover)[webkit~=rocks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;[id~=target]:not(:hover)[webkit~=rocks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;.aClass[webkit|=rocks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;:not(:hover)[webkit|=rocks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;[id|=target]:not(:hover)[webkit|=rocks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;testing:nth-child(1):not(:hover)&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;testing:not(:hover):nth-child(1)&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;testing:nth-child(1):not(:hover):nth-child(1)&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;:nth-child(n):not(:hover) &gt; #target&quot;).length is 0
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(1, 2, 3)&quot;
+PASS document.querySelectorAll(&quot;:not(:hover):nth-child(n) &gt; #target&quot;).length is 0
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(1, 2, 3)&quot;
+PASS document.querySelectorAll(&quot;:nth-child(n):not(:hover):nth-child(n) &gt; #target&quot;).length is 0
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(1, 2, 3)&quot;
+PASS document.querySelectorAll(&quot;:nth-child(n):not(:hover) #target&quot;).length is 0
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(1, 2, 3)&quot;
+PASS document.querySelectorAll(&quot;:not(:hover):nth-child(n) #target&quot;).length is 0
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(1, 2, 3)&quot;
+PASS document.querySelectorAll(&quot;:nth-child(n):not(:hover):nth-child(n) #target&quot;).length is 0
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(1, 2, 3)&quot;
+PASS document.querySelectorAll(&quot;:-webkit-any(:not(:hover)) #target&quot;).length is 0
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(1, 2, 3)&quot;
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastselectorsnotactivehoverquirkshtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/not-active-hover-quirks.html (0 => 169525)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/not-active-hover-quirks.html                                (rev 0)
+++ trunk/LayoutTests/fast/selectors/not-active-hover-quirks.html        2014-06-02 07:00:53 UTC (rev 169525)
</span><span class="lines">@@ -0,0 +1,38 @@
</span><ins>+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;resources/not-hover-active-quirks-utility.js&quot;&gt;&lt;/script&gt;
+&lt;style id=&quot;testStyle&quot;&gt;
+&lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;testing id=&quot;target&quot; class=&quot;aClass otherClass&quot; webkit=&quot;rocks&quot; style=&quot;background-color:green; width:200px; height:200px;display:block;&quot;&gt;&lt;/testing&gt;
+&lt;div id=&quot;start&quot; style=&quot;background-color:gray; height:200px; width:200px; display:block; text-align:center; color:white;&quot;&gt;START&lt;/div&gt;
+&lt;div id=&quot;console&quot;&gt;&lt;/div&gt;
+&lt;/div&gt;
+&lt;/body&gt;
+&lt;script&gt;
+description('Test the :not(:active) and :not(:hover) selector when the document is in quirks mode. To test manually, make sure not to move the cursor over the green rectangle and press the gray START div until the test is finished.');
+
+if (window.eventSender) {
+    var start = document.getElementById('start');
+    var x = start.offsetLeft + start.offsetWidth / 2;
+    var y = start.offsetTop + start.offsetHeight / 2;
+    eventSender.mouseMoveTo(x, y);
+    eventSender.mouseDown();
+    test(':active');
+    test(':hover');
+    eventSender.mouseUp()
+} else {
+    // For some reasons, the test does not work well without the timeout on Firefox.
+    document.getElementById('start').addEventListener('mousedown', function(ev) {
+        setTimeout(function () {
+            test(':active');
+            test(':hover');
+        }, 250);
+    });
+}
+
+&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="trunkLayoutTestsfastselectorsnotactivehoverstrictexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/not-active-hover-strict-expected.txt (0 => 169525)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/not-active-hover-strict-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/selectors/not-active-hover-strict-expected.txt        2014-06-02 07:00:53 UTC (rev 169525)
</span><span class="lines">@@ -0,0 +1,170 @@
</span><ins>+START
+Test the :not(:active) and :not(:hover) selector when the document is in strict mode. To test manually, make sure not to move the cursor over the green rectangle and press the gray START div until the test is finished.
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS document.querySelectorAll(&quot;testing:not(:active)&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;#target:not(:active)&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;:not(:active)#target&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;#target:not(:active)#target&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;.aClass:not(:active)&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;:not(:active).aClass&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;.aClass:not(:active).otherClass&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;.aClass[webkit]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;:not(:active)[webkit]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;[id]:not(:active)[webkit]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;.aClass[webkit=rocks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;:not(:active)[webkit=rocks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;[id=target]:not(:active)[webkit=rocks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;.aClass[webkit^=ro]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;:not(:active)[webkit^=ro]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;[id^=ta]:not(:active)[webkit^=ro]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;.aClass[webkit$=ks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;:not(:active)[webkit$=ks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;[id$=et]:not(:active)[webkit$=ks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;.aClass[webkit*=ck]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;:not(:active)[webkit*=ck]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;[id*=rg]:not(:active)[webkit*=ck]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;.aClass[webkit~=rocks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;:not(:active)[webkit~=rocks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;[id~=target]:not(:active)[webkit~=rocks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;.aClass[webkit|=rocks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;:not(:active)[webkit|=rocks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;[id|=target]:not(:active)[webkit|=rocks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;testing:nth-child(1):not(:active)&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;testing:not(:active):nth-child(1)&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;testing:nth-child(1):not(:active):nth-child(1)&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;:nth-child(n):not(:active) &gt; #target&quot;).length is 0
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(1, 2, 3)&quot;
+PASS document.querySelectorAll(&quot;:not(:active):nth-child(n) &gt; #target&quot;).length is 0
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(1, 2, 3)&quot;
+PASS document.querySelectorAll(&quot;:nth-child(n):not(:active):nth-child(n) &gt; #target&quot;).length is 0
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(1, 2, 3)&quot;
+PASS document.querySelectorAll(&quot;:nth-child(n):not(:active) #target&quot;).length is 0
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(1, 2, 3)&quot;
+PASS document.querySelectorAll(&quot;:not(:active):nth-child(n) #target&quot;).length is 0
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(1, 2, 3)&quot;
+PASS document.querySelectorAll(&quot;:nth-child(n):not(:active):nth-child(n) #target&quot;).length is 0
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(1, 2, 3)&quot;
+PASS document.querySelectorAll(&quot;:-webkit-any(:not(:active)) #target&quot;).length is 0
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(1, 2, 3)&quot;
+PASS document.querySelectorAll(&quot;*&quot;).length - document.querySelectorAll(&quot;:not(:active)&quot;).length is 3
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;*&quot;).length - document.querySelectorAll(&quot;*:not(:active)&quot;).length is 3
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;testing:not(:hover)&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;#target:not(:hover)&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;:not(:hover)#target&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;#target:not(:hover)#target&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;.aClass:not(:hover)&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;:not(:hover).aClass&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;.aClass:not(:hover).otherClass&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;.aClass[webkit]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;:not(:hover)[webkit]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;[id]:not(:hover)[webkit]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;.aClass[webkit=rocks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;:not(:hover)[webkit=rocks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;[id=target]:not(:hover)[webkit=rocks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;.aClass[webkit^=ro]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;:not(:hover)[webkit^=ro]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;[id^=ta]:not(:hover)[webkit^=ro]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;.aClass[webkit$=ks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;:not(:hover)[webkit$=ks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;[id$=et]:not(:hover)[webkit$=ks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;.aClass[webkit*=ck]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;:not(:hover)[webkit*=ck]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;[id*=rg]:not(:hover)[webkit*=ck]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;.aClass[webkit~=rocks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;:not(:hover)[webkit~=rocks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;[id~=target]:not(:hover)[webkit~=rocks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;.aClass[webkit|=rocks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;:not(:hover)[webkit|=rocks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;[id|=target]:not(:hover)[webkit|=rocks]&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;testing:nth-child(1):not(:hover)&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;testing:not(:hover):nth-child(1)&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;testing:nth-child(1):not(:hover):nth-child(1)&quot;).length is 1
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;:nth-child(n):not(:hover) &gt; #target&quot;).length is 0
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(1, 2, 3)&quot;
+PASS document.querySelectorAll(&quot;:not(:hover):nth-child(n) &gt; #target&quot;).length is 0
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(1, 2, 3)&quot;
+PASS document.querySelectorAll(&quot;:nth-child(n):not(:hover):nth-child(n) &gt; #target&quot;).length is 0
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(1, 2, 3)&quot;
+PASS document.querySelectorAll(&quot;:nth-child(n):not(:hover) #target&quot;).length is 0
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(1, 2, 3)&quot;
+PASS document.querySelectorAll(&quot;:not(:hover):nth-child(n) #target&quot;).length is 0
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(1, 2, 3)&quot;
+PASS document.querySelectorAll(&quot;:nth-child(n):not(:hover):nth-child(n) #target&quot;).length is 0
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(1, 2, 3)&quot;
+PASS document.querySelectorAll(&quot;:-webkit-any(:not(:hover)) #target&quot;).length is 0
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(1, 2, 3)&quot;
+PASS document.querySelectorAll(&quot;*&quot;).length - document.querySelectorAll(&quot;:not(:hover)&quot;).length is 3
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS document.querySelectorAll(&quot;*&quot;).length - document.querySelectorAll(&quot;*:not(:hover)&quot;).length is 3
+PASS getComputedStyle(document.getElementById(&quot;target&quot;)).color is &quot;rgb(4, 5, 6)&quot;
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastselectorsnotactivehoverstricthtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/not-active-hover-strict.html (0 => 169525)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/not-active-hover-strict.html                                (rev 0)
+++ trunk/LayoutTests/fast/selectors/not-active-hover-strict.html        2014-06-02 07:00:53 UTC (rev 169525)
</span><span class="lines">@@ -0,0 +1,39 @@
</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;script src=&quot;resources/not-hover-active-strict-utility.js&quot;&gt;&lt;/script&gt;
+&lt;style id=&quot;testStyle&quot;&gt;
+&lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;testing id=&quot;target&quot; class=&quot;aClass otherClass&quot; webkit=&quot;rocks&quot; style=&quot;background-color:green; width:200px; height:200px;display:block;&quot;&gt;&lt;/testing&gt;
+&lt;div id=&quot;start&quot; style=&quot;background-color:gray; height:200px; width:200px; display:block; text-align:center; color:white;&quot;&gt;START&lt;/div&gt;
+&lt;div id=&quot;console&quot;&gt;&lt;/div&gt;
+&lt;/div&gt;
+&lt;/body&gt;
+&lt;script&gt;
+description('Test the :not(:active) and :not(:hover) selector when the document is in strict mode. To test manually, make sure not to move the cursor over the green rectangle and press the gray START div until the test is finished.');
+
+if (window.eventSender) {
+    var start = document.getElementById('start');
+    var x = start.offsetLeft + start.offsetWidth / 2;
+    var y = start.offsetTop + start.offsetHeight / 2;
+    eventSender.mouseMoveTo(x, y);
+    eventSender.mouseDown();
+    test(':active');
+    test(':hover');
+    eventSender.mouseUp()
+} else {
+    // For some reasons, the test does not work well without the timeout on Firefox.
+    document.getElementById('start').addEventListener('mousedown', function(ev) {
+        setTimeout(function () {
+            test(':active');
+            test(':hover');
+        }, 250);
+    });
+}
+
+&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="trunkLayoutTestsfastselectorspseudoclassnotexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/pseudo-class-not-expected.txt (0 => 169525)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/pseudo-class-not-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/selectors/pseudo-class-not-expected.txt        2014-06-02 07:00:53 UTC (rev 169525)
</span><span class="lines">@@ -0,0 +1,27 @@
</span><ins>+The pseudo class :not
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+:not selector matched.
+PASS getComputedStyle(document.getElementById(&quot;target1&quot;)).backgroundColor is &quot;rgb(0, 0, 0)&quot;
+:not selector unmatched.
+PASS getComputedStyle(document.getElementById(&quot;target2&quot;)).backgroundColor is &quot;rgb(1, 2, 3)&quot;
+multiple :not selector matched.
+PASS getComputedStyle(document.getElementById(&quot;target3&quot;)).backgroundColor is &quot;rgb(2, 3, 4)&quot;
+multiple :not selector matched.
+PASS getComputedStyle(document.getElementById(&quot;target4&quot;)).backgroundColor is &quot;rgb(2, 3, 4)&quot;
+multiple :not selector unmatched.
+PASS getComputedStyle(document.getElementById(&quot;target5&quot;)).backgroundColor is &quot;rgb(0, 0, 0)&quot;
+:not with backtracking matched.
+PASS getComputedStyle(document.getElementById(&quot;target6&quot;)).backgroundColor is &quot;rgb(1, 2, 3)&quot;
+:not with backtracking failed.
+PASS getComputedStyle(document.getElementById(&quot;target7&quot;)).backgroundColor is &quot;rgb(0, 0, 0)&quot;
+:not with maximum registers matched.
+PASS getComputedStyle(document.getElementById(&quot;target8&quot;)).backgroundColor is &quot;rgb(1, 2, 3)&quot;
+:not with maximum registers matched.
+PASS getComputedStyle(document.getElementById(&quot;target9&quot;)).backgroundColor is &quot;rgb(1, 2, 3)&quot;
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastselectorspseudoclassnothtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/pseudo-class-not.html (0 => 169525)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/pseudo-class-not.html                                (rev 0)
+++ trunk/LayoutTests/fast/selectors/pseudo-class-not.html        2014-06-02 07:00:53 UTC (rev 169525)
</span><span class="lines">@@ -0,0 +1,153 @@
</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;
+span.target {
+    background-color:rgb(0,0,0);
+}
+span.target.rabbit:not(.horse) {
+    background-color:rgb(1,2,3);
+}
+span.target:not(.rabbit):not(.horse) {
+    background-color:rgb(2,3,4);
+}
+
+span.target1 {
+    background-color:rgb(0,0,0);
+}
+c:not(.ng) &gt; c span.target1 {
+    background-color:rgb(1,2,3);
+}
+
+span.target2 {
+    background-color:rgb(0,0,0);
+}
+/* Maximum register case */
+d &gt; d[rel=&quot;drink&quot;][data-cocoa][data-cappuccino]:not(.ng) &gt; d &gt; d span.target2 {
+    background-color:rgb(1,2,3);
+}
+
+span.target3 {
+    background-color:rgb(0,0,0);
+}
+/* Maximum register case */
+d &gt; d:not([rel=&quot;drink&quot;]) &gt; d &gt; d span.target3 {
+    background-color:rgb(1,2,3);
+}
+&lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;div style=&quot;display:none&quot;&gt;
+    &lt;!-- span.target.rabbit:not(.horse) --&gt;
+    &lt;target1&gt;
+            &lt;span class=&quot;target rabbit horse&quot; id=&quot;target1&quot;&gt;&lt;/span&gt;
+    &lt;/target1&gt;
+
+    &lt;!-- span.target.rabbit:not(.horse) --&gt;
+    &lt;target2&gt;
+            &lt;span class=&quot;target rabbit house&quot; id=&quot;target2&quot;&gt;&lt;/span&gt;
+    &lt;/target2&gt;
+
+    &lt;!-- span.target:not(.rabbit):not(.horse) --&gt;
+    &lt;target3&gt;
+            &lt;span class=&quot;target&quot; id=&quot;target3&quot;&gt;&lt;/span&gt;
+    &lt;/target3&gt;
+
+    &lt;!-- span.target:not(.rabbit):not(.horse) --&gt;
+    &lt;target4&gt;
+            &lt;span class=&quot;target house&quot; id=&quot;target4&quot;&gt;&lt;/span&gt;
+    &lt;/target4&gt;
+
+    &lt;!-- span.target:not(.rabbit):not(.horse) --&gt;
+    &lt;target5&gt;
+            &lt;span class=&quot;target horse&quot; id=&quot;target5&quot;&gt;&lt;/span&gt;
+    &lt;/target5&gt;
+
+    &lt;!-- c:not(.ng) &gt; c span.target1 --&gt;
+    &lt;target6&gt;
+            &lt;c&gt;  &lt;!-- Matched. --&gt;
+                &lt;c class=&quot;ng&quot;&gt;  &lt;!-- Failed. Backtracking from here. --&gt;
+                    &lt;c&gt;
+                        &lt;span class=&quot;target1&quot; id=&quot;target6&quot;&gt;&lt;/span&gt;
+                    &lt;/c&gt;
+                &lt;/c&gt;
+            &lt;/c&gt;
+    &lt;/target6&gt;
+
+    &lt;!-- c:not(.ng) &gt; c span.target1 --&gt;
+    &lt;target7&gt;
+            &lt;c class=&quot;ng&quot;&gt;  &lt;!-- Failed. Backtracking from here. --&gt;
+                &lt;c class=&quot;ng&quot;&gt;  &lt;!-- Failed. Backtracking from here. --&gt;
+                    &lt;c class=&quot;ng&quot;&gt;  &lt;!-- Failed. Backtracking from here. --&gt;
+                        &lt;c&gt;
+                            &lt;span class=&quot;target1&quot; id=&quot;target7&quot;&gt;&lt;/span&gt;
+                        &lt;/c&gt;
+                    &lt;/c&gt;
+                &lt;/c&gt;
+            &lt;/c&gt;
+    &lt;/target7&gt;
+
+    &lt;!-- d &gt; d[data-cocoa][data-cappuccino]:not(.ng) &gt; d &gt; d span.target2 --&gt;
+    &lt;target8&gt;
+        &lt;d&gt;  &lt;!-- Matched. --&gt;
+            &lt;d rel=&quot;drink&quot; data-cocoa data-cappuccino&gt;
+                &lt;d data-cocoa data-cappuccino class=&quot;ng&quot;&gt;  &lt;!-- Failed. Backtracking from the tail. --&gt;
+                    &lt;d&gt;
+                        &lt;d&gt;
+                            &lt;span class=&quot;target2&quot; id=&quot;target8&quot;&gt;&lt;/span&gt;
+                        &lt;/d&gt;
+                    &lt;/d&gt;
+                &lt;/d&gt;
+            &lt;/d&gt;
+        &lt;/d&gt;
+    &lt;/target8&gt;
+
+    &lt;!-- d &gt; d:not([rel=&quot;drink&quot;]) &gt; d &gt; d span.target3 --&gt;
+    &lt;target9&gt;
+        &lt;d&gt;  &lt;!-- Matched. --&gt;
+            &lt;d&gt;
+                &lt;d rel=&quot;drink&quot;&gt;  &lt;!-- Failed. Backtracking from the tail. --&gt;
+                    &lt;d&gt;
+                        &lt;d&gt;
+                            &lt;span class=&quot;target3&quot; id=&quot;target9&quot;&gt;&lt;/span&gt;
+                        &lt;/d&gt;
+                    &lt;/d&gt;
+                &lt;/d&gt;
+            &lt;/d&gt;
+        &lt;/d&gt;
+    &lt;/target9&gt;
+&lt;/div&gt;
+&lt;/body&gt;
+&lt;script&gt;
+description('The pseudo class :not');
+
+debug(&quot;:not selector matched.&quot;);
+shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;target1&quot;)).backgroundColor', 'rgb(0, 0, 0)');
+
+debug(&quot;:not selector unmatched.&quot;);
+shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;target2&quot;)).backgroundColor', 'rgb(1, 2, 3)');
+
+debug(&quot;multiple :not selector matched.&quot;);
+shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;target3&quot;)).backgroundColor', 'rgb(2, 3, 4)');
+
+debug(&quot;multiple :not selector matched.&quot;);
+shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;target4&quot;)).backgroundColor', 'rgb(2, 3, 4)');
+
+debug(&quot;multiple :not selector unmatched.&quot;);
+shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;target5&quot;)).backgroundColor', 'rgb(0, 0, 0)');
+
+debug(&quot;:not with backtracking matched.&quot;);
+shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;target6&quot;)).backgroundColor', 'rgb(1, 2, 3)');
+
+debug(&quot;:not with backtracking failed.&quot;);
+shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;target7&quot;)).backgroundColor', 'rgb(0, 0, 0)');
+
+debug(&quot;:not with maximum registers matched.&quot;);
+shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;target8&quot;)).backgroundColor', 'rgb(1, 2, 3)');
+
+debug(&quot;:not with maximum registers matched.&quot;);
+shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;target9&quot;)).backgroundColor', 'rgb(1, 2, 3)');
+&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="trunkLayoutTestsfastselectorsresourcesnothoveractivequirksutilityjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/resources/not-hover-active-quirks-utility.js (0 => 169525)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/resources/not-hover-active-quirks-utility.js                                (rev 0)
+++ trunk/LayoutTests/fast/selectors/resources/not-hover-active-quirks-utility.js        2014-06-02 07:00:53 UTC (rev 169525)
</span><span class="lines">@@ -0,0 +1,97 @@
</span><ins>+var testCases = [
+    // Having :hover or :active does not qualify the pseudo class.
+    [&quot;PLACEHOLDER:hover&quot;, false],
+    [&quot;:hoverPLACEHOLDER&quot;, false],
+    [&quot;:hoverPLACEHOLDER:hover&quot;, false],
+    [&quot;PLACEHOLDER:active&quot;, false],
+    [&quot;:activePLACEHOLDER&quot;, false],
+    [&quot;:activePLACEHOLDER:active&quot;, false],
+
+    // Tag qualify the pseudo class.
+    [&quot;testingPLACEHOLDER&quot;, true],
+
+    // Id qualify the pseudo class.
+    [&quot;#targetPLACEHOLDER&quot;, true],
+    [&quot;PLACEHOLDER#target&quot;, true],
+    [&quot;#targetPLACEHOLDER#target&quot;, true],
+
+    // Class qualify the pseudo class.
+    [&quot;.aClassPLACEHOLDER&quot;, true],
+    [&quot;PLACEHOLDER.aClass&quot;, true],
+    [&quot;.aClassPLACEHOLDER.otherClass&quot;, true],
+
+    // Any attribute filter qualify the pseudo class.
+    [&quot;.aClass[webkit]&quot;, true],
+    [&quot;PLACEHOLDER[webkit]&quot;, true],
+    [&quot;[id]PLACEHOLDER[webkit]&quot;, true],
+
+    [&quot;.aClass[webkit=rocks]&quot;, true],
+    [&quot;PLACEHOLDER[webkit=rocks]&quot;, true],
+    [&quot;[id=target]PLACEHOLDER[webkit=rocks]&quot;, true],
+
+    [&quot;.aClass[webkit^=ro]&quot;, true],
+    [&quot;PLACEHOLDER[webkit^=ro]&quot;, true],
+    [&quot;[id^=ta]PLACEHOLDER[webkit^=ro]&quot;, true],
+
+    [&quot;.aClass[webkit$=ks]&quot;, true],
+    [&quot;PLACEHOLDER[webkit$=ks]&quot;, true],
+    [&quot;[id$=et]PLACEHOLDER[webkit$=ks]&quot;, true],
+
+    [&quot;.aClass[webkit*=ck]&quot;, true],
+    [&quot;PLACEHOLDER[webkit*=ck]&quot;, true],
+    [&quot;[id*=rg]PLACEHOLDER[webkit*=ck]&quot;, true],
+
+    [&quot;.aClass[webkit~=rocks]&quot;, true],
+    [&quot;PLACEHOLDER[webkit~=rocks]&quot;, true],
+    [&quot;[id~=target]PLACEHOLDER[webkit~=rocks]&quot;, true],
+
+    [&quot;.aClass[webkit|=rocks]&quot;, true],
+    [&quot;PLACEHOLDER[webkit|=rocks]&quot;, true],
+    [&quot;[id|=target]PLACEHOLDER[webkit|=rocks]&quot;, true],
+
+    // A pseudo-class other than :active/:hover qualify the pseudo class.
+    [&quot;testing:nth-child(1)PLACEHOLDER&quot;, true],
+    [&quot;testingPLACEHOLDER:nth-child(1)&quot;, true],
+    [&quot;testing:nth-child(1)PLACEHOLDER:nth-child(1)&quot;, true],
+    // Same with child.
+    [&quot;:nth-child(n)PLACEHOLDER &gt; #target&quot;, false],
+    [&quot;PLACEHOLDER:nth-child(n) &gt; #target&quot;, false],
+    [&quot;:nth-child(n)PLACEHOLDER:nth-child(n) &gt; #target&quot;, false],
+    // Same with descendant.
+    [&quot;:nth-child(n)PLACEHOLDER #target&quot;, false],
+    [&quot;PLACEHOLDER:nth-child(n) #target&quot;, false],
+    [&quot;:nth-child(n)PLACEHOLDER:nth-child(n) #target&quot;, false],
+
+    [&quot;:-webkit-any(PLACEHOLDER) #target&quot;, false],
+];
+
+function testQuerySelector(selector, shouldMatch) {
+    shouldBe('document.querySelectorAll(&quot;' + selector + '&quot;).length', shouldMatch? '1' : '0');
+}
+
+function testStyling(selector, shouldMatch) {
+    var testStyle = document.getElementById('testStyle');
+    var noMatchStyle = &quot;rgb(1, 2, 3)&quot;;
+    var matchStyle = &quot;rgb(4, 5, 6)&quot;
+    testStyle.textContent = &quot;#target { color:&quot; + noMatchStyle + &quot; } &quot; + selector + &quot; { color:&quot; + matchStyle + &quot; !important }&quot;;
+
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;target&quot;)).color', shouldMatch ? matchStyle : noMatchStyle);
+
+    testStyle.textContent = &quot;&quot;;
+}
+
+function test(original) {
+    var pseudoClass = ':not(' + original + ')';
+
+    // Since inFunctionalPseudo is true, :hover and :active can be matched in quirks mode.
+    shouldBe('document.querySelectorAll(&quot;*&quot;).length - document.querySelectorAll(&quot;' + pseudoClass + '&quot;).length', '3');
+    testStyling(pseudoClass, true);
+    shouldBe('document.querySelectorAll(&quot;*&quot;).length - document.querySelectorAll(&quot;*' + pseudoClass + '&quot;).length', '3');
+    testStyling('*' + pseudoClass, true);
+
+    for (var i = 0, length = testCases.length; i &lt; length; ++i) {
+        var selector = testCases[i][0].replace('PLACEHOLDER', pseudoClass)
+        testQuerySelector(selector, testCases[i][1]);
+        testStyling(selector, testCases[i][1]);
+    }
+}
</ins></span></pre></div>
<a id="trunkLayoutTestsfastselectorsresourcesnothoveractivestrictutilityjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/resources/not-hover-active-strict-utility.js (0 => 169525)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/resources/not-hover-active-strict-utility.js                                (rev 0)
+++ trunk/LayoutTests/fast/selectors/resources/not-hover-active-strict-utility.js        2014-06-02 07:00:53 UTC (rev 169525)
</span><span class="lines">@@ -0,0 +1,90 @@
</span><ins>+// In strict mode, there is no restriction on when :hover or :active can match.
+var testCases = [
+    // Tag name.
+    [&quot;testingPLACEHOLDER&quot;, true],
+
+    // Id.
+    [&quot;#targetPLACEHOLDER&quot;, true],
+    [&quot;PLACEHOLDER#target&quot;, true],
+    [&quot;#targetPLACEHOLDER#target&quot;, true],
+
+    // Class name.
+    [&quot;.aClassPLACEHOLDER&quot;, true],
+    [&quot;PLACEHOLDER.aClass&quot;, true],
+    [&quot;.aClassPLACEHOLDER.otherClass&quot;, true],
+
+    // Attribute filter.
+    [&quot;.aClass[webkit]&quot;, true],
+    [&quot;PLACEHOLDER[webkit]&quot;, true],
+    [&quot;[id]PLACEHOLDER[webkit]&quot;, true],
+
+    [&quot;.aClass[webkit=rocks]&quot;, true],
+    [&quot;PLACEHOLDER[webkit=rocks]&quot;, true],
+    [&quot;[id=target]PLACEHOLDER[webkit=rocks]&quot;, true],
+
+    [&quot;.aClass[webkit^=ro]&quot;, true],
+    [&quot;PLACEHOLDER[webkit^=ro]&quot;, true],
+    [&quot;[id^=ta]PLACEHOLDER[webkit^=ro]&quot;, true],
+
+    [&quot;.aClass[webkit$=ks]&quot;, true],
+    [&quot;PLACEHOLDER[webkit$=ks]&quot;, true],
+    [&quot;[id$=et]PLACEHOLDER[webkit$=ks]&quot;, true],
+
+    [&quot;.aClass[webkit*=ck]&quot;, true],
+    [&quot;PLACEHOLDER[webkit*=ck]&quot;, true],
+    [&quot;[id*=rg]PLACEHOLDER[webkit*=ck]&quot;, true],
+
+    [&quot;.aClass[webkit~=rocks]&quot;, true],
+    [&quot;PLACEHOLDER[webkit~=rocks]&quot;, true],
+    [&quot;[id~=target]PLACEHOLDER[webkit~=rocks]&quot;, true],
+
+    [&quot;.aClass[webkit|=rocks]&quot;, true],
+    [&quot;PLACEHOLDER[webkit|=rocks]&quot;, true],
+    [&quot;[id|=target]PLACEHOLDER[webkit|=rocks]&quot;, true],
+
+    // Pseudo-class other than :active/:hover.
+    [&quot;testing:nth-child(1)PLACEHOLDER&quot;, true],
+    [&quot;testingPLACEHOLDER:nth-child(1)&quot;, true],
+    [&quot;testing:nth-child(1)PLACEHOLDER:nth-child(1)&quot;, true],
+    // Same with child relation.
+    [&quot;:nth-child(n)PLACEHOLDER &gt; #target&quot;, false],
+    [&quot;PLACEHOLDER:nth-child(n) &gt; #target&quot;, false],
+    [&quot;:nth-child(n)PLACEHOLDER:nth-child(n) &gt; #target&quot;, false],
+    // Same with descendant relation.
+    [&quot;:nth-child(n)PLACEHOLDER #target&quot;, false],
+    [&quot;PLACEHOLDER:nth-child(n) #target&quot;, false],
+    [&quot;:nth-child(n)PLACEHOLDER:nth-child(n) #target&quot;, false],
+
+    [&quot;:-webkit-any(PLACEHOLDER) #target&quot;, false],
+];
+
+function testQuerySelector(selector, shouldMatch) {
+    shouldBe('document.querySelectorAll(&quot;' + selector + '&quot;).length', shouldMatch? '1' : '0');
+}
+
+function testStyling(selector, shouldMatch) {
+    var testStyle = document.getElementById('testStyle');
+    var noMatchStyle = &quot;rgb(1, 2, 3)&quot;;
+    var matchStyle = &quot;rgb(4, 5, 6)&quot;
+    testStyle.textContent = &quot;#target { color:&quot; + noMatchStyle + &quot; } &quot; + selector + &quot; { color:&quot; + matchStyle + &quot; !important }&quot;;
+
+    shouldBeEqualToString('getComputedStyle(document.getElementById(&quot;target&quot;)).color', shouldMatch ? matchStyle : noMatchStyle);
+
+    testStyle.textContent = &quot;&quot;;
+}
+
+function test(original) {
+    var pseudoClass = ':not(' + original + ')';
+    for (var i = 0, length = testCases.length; i &lt; length; ++i) {
+        var selector = testCases[i][0].replace('PLACEHOLDER', pseudoClass)
+        testQuerySelector(selector, testCases[i][1]);
+        testStyling(selector, testCases[i][1]);
+    }
+
+    // In strict mode, no tag name or the universal selector also work. This is tested separately because those selectors match
+    // every ancestor of the target.
+    shouldBe('document.querySelectorAll(&quot;*&quot;).length - document.querySelectorAll(&quot;' + pseudoClass + '&quot;).length', '3');
+    testStyling(pseudoClass, true);
+    shouldBe('document.querySelectorAll(&quot;*&quot;).length - document.querySelectorAll(&quot;*' + pseudoClass + '&quot;).length', '3');
+    testStyling('*' + pseudoClass, true);
+}
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (169524 => 169525)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-06-02 06:52:50 UTC (rev 169524)
+++ trunk/Source/WebCore/ChangeLog        2014-06-02 07:00:53 UTC (rev 169525)
</span><span class="lines">@@ -1,3 +1,32 @@
</span><ins>+2014-06-02  Yusuke Suzuki  &lt;utatane.tea@gmail.com&gt;
+
+        CSS JIT: add support for the &quot;not&quot; pseudo class
+        https://bugs.webkit.org/show_bug.cgi?id=133314
+
+        Reviewed by Benjamin Poulain.
+
+        Add :not pseudo class support to CSS JIT. Current implementation
+        doesn't support visitedMatchType. So when link pseudo class appears in
+        :not sub fragment, fallback to the non-JIT implementation.
+
+        Tests: fast/selectors/not-active-hover-quirks.html
+               fast/selectors/not-active-hover-strict.html
+               fast/selectors/pseudo-class-not.html
+
+        * cssjit/SelectorCompiler.cpp:
+        (WebCore::SelectorCompiler::addPseudoClassType):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::SelectorCodeGenerator):
+        (WebCore::SelectorCompiler::constructFragments):
+        (WebCore::SelectorCompiler::minimumRegisterRequirements):
+        (WebCore::SelectorCompiler::computeBacktrackingInformation):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateSelectorChecker):
+        (WebCore::SelectorCompiler::fragmentOnlyMatchesLinksInQuirksMode):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementMatching):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementDataMatching):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsNthChild):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementMatchesNotPseudoClass):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::computeBacktrackingInformation): Deleted.
+
</ins><span class="cx"> 2014-06-01  Jer Noble  &lt;jer.noble@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [MSE] Appends of overlapping sample data do not clear existing samples properly.
</span></span></pre></div>
<a id="trunkSourceWebCorecssjitSelectorCompilercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/cssjit/SelectorCompiler.cpp (169524 => 169525)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/cssjit/SelectorCompiler.cpp        2014-06-02 06:52:50 UTC (rev 169524)
+++ trunk/Source/WebCore/cssjit/SelectorCompiler.cpp        2014-06-02 07:00:53 UTC (rev 169525)
</span><span class="lines">@@ -30,6 +30,7 @@
</span><span class="cx"> #if ENABLE(CSS_SELECTOR_JIT)
</span><span class="cx"> 
</span><span class="cx"> #include &quot;CSSSelector.h&quot;
</span><ins>+#include &quot;CSSSelectorList.h&quot;
</ins><span class="cx"> #include &quot;Element.h&quot;
</span><span class="cx"> #include &quot;ElementData.h&quot;
</span><span class="cx"> #include &quot;ElementRareData.h&quot;
</span><span class="lines">@@ -154,7 +155,8 @@
</span><span class="cx">     HashSet&lt;unsigned&gt; pseudoClasses;
</span><span class="cx">     Vector&lt;JSC::FunctionPtr&gt; unoptimizedPseudoClasses;
</span><span class="cx">     Vector&lt;AttributeMatchingInfo&gt; attributes;
</span><del>-    Vector&lt;std::pair&lt;int, int&gt;&gt; nthChildfilters;
</del><ins>+    Vector&lt;std::pair&lt;int, int&gt;&gt; nthChildFilters;
+    Vector&lt;SelectorFragment&gt; notFilters;
</ins><span class="cx"> 
</span><span class="cx">     bool inFunctionalPseudoClass;
</span><span class="cx"> };
</span><span class="lines">@@ -184,7 +186,6 @@
</span><span class="cx">     static const Assembler::RegisterID checkingContextRegister;
</span><span class="cx">     static const Assembler::RegisterID callFrameRegister;
</span><span class="cx"> 
</span><del>-    void computeBacktrackingInformation();
</del><span class="cx">     void generateSelectorChecker();
</span><span class="cx"> 
</span><span class="cx">     // Element relations tree walker.
</span><span class="lines">@@ -227,6 +228,7 @@
</span><span class="cx">     void generateElementHasClasses(Assembler::JumpList&amp; failureCases, const LocalRegister&amp; elementDataAddress, const Vector&lt;const AtomicStringImpl*&gt;&amp; classNames);
</span><span class="cx">     void generateElementIsLink(Assembler::JumpList&amp; failureCases);
</span><span class="cx">     void generateElementIsNthChild(Assembler::JumpList&amp; failureCases, const SelectorFragment&amp;);
</span><ins>+    void generateElementMatchesNotPseudoClass(Assembler::JumpList&amp; failureCases, const SelectorFragment&amp;);
</ins><span class="cx">     void generateElementIsRoot(Assembler::JumpList&amp; failureCases);
</span><span class="cx">     void generateElementIsTarget(Assembler::JumpList&amp; failureCases);
</span><span class="cx"> 
</span><span class="lines">@@ -242,7 +244,7 @@
</span><span class="cx">     bool generatePrologue();
</span><span class="cx">     void generateEpilogue();
</span><span class="cx">     Vector&lt;StackAllocator::StackReference&gt; m_prologueStackReferences;
</span><del>-    
</del><ins>+
</ins><span class="cx">     Assembler m_assembler;
</span><span class="cx">     RegisterAllocator m_registerAllocator;
</span><span class="cx">     StackAllocator m_stackAllocator;
</span><span class="lines">@@ -274,6 +276,10 @@
</span><span class="cx"> const Assembler::RegisterID SelectorCodeGenerator::checkingContextRegister = JSC::GPRInfo::argumentGPR1;
</span><span class="cx"> const Assembler::RegisterID SelectorCodeGenerator::callFrameRegister = JSC::GPRInfo::callFrameRegister;
</span><span class="cx"> 
</span><ins>+static FunctionType constructFragments(const CSSSelector* rootSelector, SelectorContext, SelectorFragmentList&amp; selectorFragments);
+
+static void computeBacktrackingInformation(SelectorFragmentList&amp; selectorFragments, bool&amp; needsAdjacentBacktrackingStart);
+
</ins><span class="cx"> SelectorCompilationStatus compileSelector(const CSSSelector* lastSelector, JSC::VM* vm, SelectorContext selectorContext, JSC::MacroAssemblerCodeRef&amp; codeRef)
</span><span class="cx"> {
</span><span class="cx">     if (!vm-&gt;canUseJIT())
</span><span class="lines">@@ -397,11 +403,44 @@
</span><span class="cx">             if (a &lt;= 0 &amp;&amp; b &lt; 1)
</span><span class="cx">                 return FunctionType::CannotMatchAnything;
</span><span class="cx"> 
</span><del>-            fragment.nthChildfilters.append(std::pair&lt;int, int&gt;(a, b));
</del><ins>+            fragment.nthChildFilters.append(std::pair&lt;int, int&gt;(a, b));
</ins><span class="cx">             if (selectorContext == SelectorContext::QuerySelector)
</span><span class="cx">                 return FunctionType::SimpleSelectorChecker;
</span><span class="cx">             return FunctionType::SelectorCheckerWithCheckingContext;
</span><span class="cx">         }
</span><ins>+
+    case CSSSelector::PseudoClassNot:
+        {
+            const CSSSelectorList* selectorList = selector.selectorList();
+
+            if (!selectorList)
+                return FunctionType::CannotMatchAnything;
+
+            SelectorFragmentList notFragments;
+            FunctionType functionType = constructFragments(selectorList-&gt;first(), selectorContext, notFragments);
+
+            // Since this is not pseudo class filter, CannotMatchAnything implies this filter always passes.
+            if (functionType == FunctionType::CannotMatchAnything)
+                return FunctionType::SimpleSelectorChecker;
+
+            if (functionType == FunctionType::CannotCompile)
+                return functionType;
+
+            ASSERT(notFragments.size() == 1);
+            if (notFragments.size() != 1)
+                return FunctionType::CannotCompile;
+
+            SelectorFragment subFragment = notFragments.first();
+            subFragment.inFunctionalPseudoClass = true;
+
+            // FIXME: Currently we don't support visitedMatchType.
+            if (subFragment.pseudoClasses.contains(CSSSelector::PseudoClassLink))
+                return FunctionType::CannotCompile;
+
+            fragment.notFilters.append(subFragment);
+            return functionType;
+        }
+
</ins><span class="cx">     default:
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="lines">@@ -421,8 +460,16 @@
</span><span class="cx">     dataLogF(&quot;Compiling \&quot;%s\&quot;\n&quot;, m_originalSelector-&gt;selectorText().utf8().data());
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+    m_functionType = constructFragments(rootSelector, m_selectorContext, m_selectorFragments);
+    if (m_functionType != FunctionType::CannotCompile &amp;&amp; m_functionType != FunctionType::CannotMatchAnything)
+        computeBacktrackingInformation(m_selectorFragments, m_needsAdjacentBacktrackingStart);
+}
+
+static FunctionType constructFragments(const CSSSelector* rootSelector, SelectorContext selectorContext, SelectorFragmentList&amp; selectorFragments)
+{
</ins><span class="cx">     SelectorFragment fragment;
</span><span class="cx">     FragmentRelation relationToPreviousFragment = FragmentRelation::Rightmost;
</span><ins>+    FunctionType functionType = FunctionType::SimpleSelectorChecker;
</ins><span class="cx">     for (const CSSSelector* selector = rootSelector; selector; selector = selector-&gt;tagHistory()) {
</span><span class="cx">         switch (selector-&gt;m_match) {
</span><span class="cx">         case CSSSelector::Tag:
</span><span class="lines">@@ -433,8 +480,7 @@
</span><span class="cx">             const AtomicString&amp; id = selector-&gt;value();
</span><span class="cx">             if (fragment.id) {
</span><span class="cx">                 if (id != *fragment.id) {
</span><del>-                    m_functionType = FunctionType::CannotMatchAnything;
-                    return;
</del><ins>+                    return FunctionType::CannotMatchAnything;
</ins><span class="cx">                 }
</span><span class="cx">             } else
</span><span class="cx">                 fragment.id = &amp;(selector-&gt;value());
</span><span class="lines">@@ -444,22 +490,20 @@
</span><span class="cx">             fragment.classNames.append(selector-&gt;value().impl());
</span><span class="cx">             break;
</span><span class="cx">         case CSSSelector::PseudoClass:
</span><del>-            m_functionType = mostRestrictiveFunctionType(m_functionType, addPseudoClassType(*selector, fragment, m_selectorContext));
-            if (m_functionType == FunctionType::CannotCompile || m_functionType == FunctionType::CannotMatchAnything)
-                return;
</del><ins>+            functionType = mostRestrictiveFunctionType(functionType, addPseudoClassType(*selector, fragment, selectorContext));
+            if (functionType == FunctionType::CannotCompile || functionType == FunctionType::CannotMatchAnything)
+                return functionType;
</ins><span class="cx">             break;
</span><span class="cx">         case CSSSelector::List:
</span><span class="cx">             if (selector-&gt;value().contains(' ')) {
</span><del>-                m_functionType = FunctionType::CannotMatchAnything;
-                return;
</del><ins>+                return FunctionType::CannotMatchAnything;
</ins><span class="cx">             }
</span><span class="cx">             FALLTHROUGH;
</span><span class="cx">         case CSSSelector::Begin:
</span><span class="cx">         case CSSSelector::End:
</span><span class="cx">         case CSSSelector::Contain:
</span><span class="cx">             if (selector-&gt;value().isEmpty()) {
</span><del>-                m_functionType = FunctionType::CannotMatchAnything;
-                return;
</del><ins>+                return FunctionType::CannotMatchAnything;
</ins><span class="cx">             }
</span><span class="cx">             FALLTHROUGH;
</span><span class="cx">         case CSSSelector::Exact:
</span><span class="lines">@@ -474,10 +518,9 @@
</span><span class="cx">             break;
</span><span class="cx">         case CSSSelector::Unknown:
</span><span class="cx">             ASSERT_NOT_REACHED();
</span><del>-            m_functionType = FunctionType::CannotMatchAnything;
-            return;
</del><ins>+            return FunctionType::CannotMatchAnything;
</ins><span class="cx">         case CSSSelector::PseudoElement:
</span><del>-            goto CannotHandleSelector;
</del><ins>+            return FunctionType::CannotCompile;
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         CSSSelector::Relation relation = selector-&gt;relation();
</span><span class="lines">@@ -485,28 +528,23 @@
</span><span class="cx">             continue;
</span><span class="cx"> 
</span><span class="cx">         if (relation == CSSSelector::ShadowDescendant &amp;&amp; !selector-&gt;isLastInTagHistory())
</span><del>-            goto CannotHandleSelector;
</del><ins>+            return FunctionType::CannotCompile;
</ins><span class="cx"> 
</span><span class="cx">         if (relation == CSSSelector::DirectAdjacent || relation == CSSSelector::IndirectAdjacent) {
</span><span class="cx">             FunctionType relationFunctionType = FunctionType::SelectorCheckerWithCheckingContext;
</span><del>-            if (m_selectorContext == SelectorContext::QuerySelector)
</del><ins>+            if (selectorContext == SelectorContext::QuerySelector)
</ins><span class="cx">                 relationFunctionType = FunctionType::SimpleSelectorChecker;
</span><del>-            m_functionType = std::max(m_functionType, relationFunctionType);
</del><ins>+            functionType = mostRestrictiveFunctionType(functionType, relationFunctionType);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         fragment.relationToLeftFragment = fragmentRelationForSelectorRelation(relation);
</span><span class="cx">         fragment.relationToRightFragment = relationToPreviousFragment;
</span><span class="cx">         relationToPreviousFragment = fragment.relationToLeftFragment;
</span><span class="cx"> 
</span><del>-        m_selectorFragments.append(fragment);
</del><ins>+        selectorFragments.append(fragment);
</ins><span class="cx">         fragment = SelectorFragment();
</span><span class="cx">     }
</span><del>-
-    computeBacktrackingInformation();
-
-    return;
-CannotHandleSelector:
-    m_functionType = FunctionType::CannotCompile;
</del><ins>+    return functionType;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static inline bool attributeNameTestingRequiresNamespaceRegister(const CSSSelector&amp; attributeSelector)
</span><span class="lines">@@ -519,37 +557,55 @@
</span><span class="cx">     return !attributeInfo.canDefaultToCaseSensitiveValueMatch();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static inline unsigned minimumRegisterRequirements(const SelectorFragmentList&amp; selectorFragments)
</del><ins>+// Strict minimum to match anything interesting:
+// Element + BacktrackingRegister + ElementData + a pointer to values + an index on that pointer + the value we expect;
+static const unsigned minimumRequiredRegisterCount = 6;
+// Element + ElementData + scratchRegister + attributeArrayPointer + expectedLocalName + (qualifiedNameImpl &amp;&amp; expectedValue).
+static const unsigned minimumRequiredRegisterCountForAttributeFilter = 6;
+
+static inline unsigned minimumRegisterRequirements(const SelectorFragment&amp; selectorFragment)
</ins><span class="cx"> {
</span><del>-    // Strict minimum to match anything interesting:
-    // Element + BacktrackingRegister + ElementData + a pointer to values + an index on that pointer + the value we expect;
-    unsigned minimum = 6;
</del><ins>+    unsigned minimum = minimumRequiredRegisterCount;
+    const Vector&lt;AttributeMatchingInfo&gt;&amp; attributes = selectorFragment.attributes;
</ins><span class="cx"> 
</span><ins>+    unsigned backtrackingRegisterRequirements = 0;
+    if (selectorFragment.backtrackingFlags &amp; BacktrackingFlag::InChainWithDescendantTail)
+        backtrackingRegisterRequirements = 1; // If there is a DescendantTail, there is a backtracking register.
+
</ins><span class="cx">     // Attributes cause some register pressure.
</span><del>-    for (unsigned selectorFragmentIndex = 0; selectorFragmentIndex &lt; selectorFragments.size(); ++selectorFragmentIndex) {
-        const SelectorFragment&amp; selectorFragment = selectorFragments[selectorFragmentIndex];
-        const Vector&lt;AttributeMatchingInfo&gt;&amp; attributes = selectorFragment.attributes;
</del><ins>+    unsigned attributeCount = attributes.size();
+    for (unsigned attributeIndex = 0; attributeIndex &lt; attributeCount; ++attributeIndex) {
+        unsigned attributeMinimum = minimumRequiredRegisterCountForAttributeFilter + backtrackingRegisterRequirements;
</ins><span class="cx"> 
</span><del>-        unsigned attributeCount = attributes.size();
-        for (unsigned attributeIndex = 0; attributeIndex &lt; attributeCount; ++attributeIndex) {
-            // Element + ElementData + scratchRegister + attributeArrayPointer + expectedLocalName + (qualifiedNameImpl &amp;&amp; expectedValue).
-            unsigned attributeMinimum = 6;
-            if (selectorFragment.backtrackingFlags &amp; BacktrackingFlag::InChainWithDescendantTail)
-                attributeMinimum += 1; // If there is a DescendantTail, there is a backtracking register.
</del><ins>+        if (attributeIndex + 1 &lt; attributeCount)
+            attributeMinimum += 2; // For the local copy of the counter and attributeArrayPointer.
</ins><span class="cx"> 
</span><del>-            if (attributeIndex + 1 &lt; attributeCount)
-                attributeMinimum += 2; // For the local copy of the counter and attributeArrayPointer.
</del><ins>+        const AttributeMatchingInfo&amp; attributeInfo = attributes[attributeIndex];
+        const CSSSelector&amp; attributeSelector = attributeInfo.selector();
+        if (attributeNameTestingRequiresNamespaceRegister(attributeSelector)
+            || attributeValueTestingRequiresCaseFoldingRegister(attributeInfo))
+            attributeMinimum += 1;
</ins><span class="cx"> 
</span><del>-            const AttributeMatchingInfo&amp; attributeInfo = attributes[attributeIndex];
-            const CSSSelector&amp; attributeSelector = attributeInfo.selector();
-            if (attributeNameTestingRequiresNamespaceRegister(attributeSelector)
-                || attributeValueTestingRequiresCaseFoldingRegister(attributeInfo))
-                attributeMinimum += 1;
</del><ins>+        minimum = std::max(minimum, attributeMinimum);
+    }
</ins><span class="cx"> 
</span><del>-            minimum = std::max(minimum, attributeMinimum);
-        }
</del><ins>+    // :not pseudo class filters cause some register pressure.
+    for (const SelectorFragment&amp; subFragment : selectorFragment.notFilters) {
+        unsigned notFilterMinimum = minimumRegisterRequirements(subFragment) + backtrackingRegisterRequirements;
+        minimum = std::max(minimum, notFilterMinimum);
</ins><span class="cx">     }
</span><ins>+    return minimum;
+}
</ins><span class="cx"> 
</span><ins>+static inline unsigned minimumRegisterRequirements(const SelectorFragmentList&amp; selectorFragments)
+{
+    unsigned minimum = minimumRequiredRegisterCount;
+
+    for (unsigned selectorFragmentIndex = 0; selectorFragmentIndex &lt; selectorFragments.size(); ++selectorFragmentIndex) {
+        const SelectorFragment&amp; selectorFragment = selectorFragments[selectorFragmentIndex];
+        minimum = std::max(minimum, minimumRegisterRequirements(selectorFragment));
+    }
+
</ins><span class="cx">     return minimum;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -873,7 +929,7 @@
</span><span class="cx">     return fragment.matchingTagNameBacktrackingAction == BacktrackingAction::JumpToDescendantTail || fragment.matchingPostTagNameBacktrackingAction == BacktrackingAction::JumpToDescendantTail || fragment.traversalBacktrackingAction == BacktrackingAction::JumpToDescendantTail;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void SelectorCodeGenerator::computeBacktrackingInformation()
</del><ins>+void computeBacktrackingInformation(SelectorFragmentList&amp; selectorFragments, bool&amp; needsAdjacentBacktrackingStart)
</ins><span class="cx"> {
</span><span class="cx">     bool hasDescendantRelationOnTheRight = false;
</span><span class="cx">     unsigned ancestorPositionSinceDescendantRelation = 0;
</span><span class="lines">@@ -890,8 +946,8 @@
</span><span class="cx">     const SelectorFragment* previousChildFragmentInChildChain = nullptr;
</span><span class="cx">     const SelectorFragment* previousDirectAdjacentFragmentInDirectAdjacentChain = nullptr;
</span><span class="cx"> 
</span><del>-    for (unsigned i = 0; i &lt; m_selectorFragments.size(); ++i) {
-        SelectorFragment&amp; fragment = m_selectorFragments[i];
</del><ins>+    for (unsigned i = 0; i &lt; selectorFragments.size(); ++i) {
+        SelectorFragment&amp; fragment = selectorFragments[i];
</ins><span class="cx"> 
</span><span class="cx">         updateChainStates(fragment, hasDescendantRelationOnTheRight, ancestorPositionSinceDescendantRelation, hasIndirectAdjacentRelationOnTheRightOfDirectAdjacentChain, adjacentPositionSinceIndirectAdjacentTreeWalk);
</span><span class="cx"> 
</span><span class="lines">@@ -926,8 +982,8 @@
</span><span class="cx">                 ASSERT(fragment.relationToRightFragment == FragmentRelation::DirectAdjacent);
</span><span class="cx">                 ASSERT(saveIndirectAdjacentBacktrackingStartFragmentIndex != std::numeric_limits&lt;unsigned&gt;::max());
</span><span class="cx">                 fragment.backtrackingFlags |= BacktrackingFlag::DirectAdjacentTail;
</span><del>-                m_selectorFragments[saveIndirectAdjacentBacktrackingStartFragmentIndex].backtrackingFlags |= BacktrackingFlag::SaveAdjacentBacktrackingStart;
-                m_needsAdjacentBacktrackingStart = true;
</del><ins>+                selectorFragments[saveIndirectAdjacentBacktrackingStartFragmentIndex].backtrackingFlags |= BacktrackingFlag::SaveAdjacentBacktrackingStart;
+                needsAdjacentBacktrackingStart = true;
</ins><span class="cx">                 needsAdjacentTail = false;
</span><span class="cx">             }
</span><span class="cx">             saveIndirectAdjacentBacktrackingStartFragmentIndex = std::numeric_limits&lt;unsigned&gt;::max();
</span><span class="lines">@@ -936,10 +992,10 @@
</span><span class="cx">             if (needsDescendantTail) {
</span><span class="cx">                 ASSERT(saveDescendantBacktrackingStartFragmentIndex != std::numeric_limits&lt;unsigned&gt;::max());
</span><span class="cx">                 fragment.backtrackingFlags |= BacktrackingFlag::DescendantTail;
</span><del>-                m_selectorFragments[saveDescendantBacktrackingStartFragmentIndex].backtrackingFlags |= BacktrackingFlag::SaveDescendantBacktrackingStart;
</del><ins>+                selectorFragments[saveDescendantBacktrackingStartFragmentIndex].backtrackingFlags |= BacktrackingFlag::SaveDescendantBacktrackingStart;
</ins><span class="cx">                 needsDescendantTail = false;
</span><span class="cx">                 for (unsigned j = saveDescendantBacktrackingStartFragmentIndex; j &lt;= i; ++j)
</span><del>-                    m_selectorFragments[j].backtrackingFlags |= BacktrackingFlag::InChainWithDescendantTail;
</del><ins>+                    selectorFragments[j].backtrackingFlags |= BacktrackingFlag::InChainWithDescendantTail;
</ins><span class="cx">             }
</span><span class="cx">             saveDescendantBacktrackingStartFragmentIndex = std::numeric_limits&lt;unsigned&gt;::max();
</span><span class="cx">         }
</span><span class="lines">@@ -962,7 +1018,7 @@
</span><span class="cx"> #endif
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><del>-    
</del><ins>+
</ins><span class="cx"> inline void SelectorCodeGenerator::generateEpilogue()
</span><span class="cx"> {
</span><span class="cx"> #if CPU(ARM64)
</span><span class="lines">@@ -976,15 +1032,18 @@
</span><span class="cx">     m_stackAllocator.pop(m_prologueStackReferences, prologueRegister);
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><del>-    
</del><ins>+
</ins><span class="cx"> void SelectorCodeGenerator::generateSelectorChecker()
</span><span class="cx"> {
</span><span class="cx">     bool needsEpilogue = generatePrologue();
</span><del>-    
</del><ins>+
</ins><span class="cx">     Vector&lt;StackAllocator::StackReference&gt; calleeSavedRegisterStackReferences;
</span><span class="cx">     bool reservedCalleeSavedRegisters = false;
</span><span class="cx">     unsigned availableRegisterCount = m_registerAllocator.availableRegisterCount();
</span><span class="cx">     unsigned minimumRegisterCountForAttributes = minimumRegisterRequirements(m_selectorFragments);
</span><ins>+#if CSS_SELECTOR_JIT_DEBUGGING
+    dataLogF(&quot;Compiling with minimum required register count %u\n&quot;, minimumRegisterCountForAttributes);
+#endif
</ins><span class="cx">     ASSERT(minimumRegisterCountForAttributes &lt;= registerCount);
</span><span class="cx">     if (availableRegisterCount &lt; minimumRegisterCountForAttributes) {
</span><span class="cx">         reservedCalleeSavedRegisters = true;
</span><span class="lines">@@ -1290,7 +1349,7 @@
</span><span class="cx">     if (!fragment.classNames.isEmpty())
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><del>-    if (!fragment.unoptimizedPseudoClasses.isEmpty() || !fragment.nthChildfilters.isEmpty())
</del><ins>+    if (!fragment.unoptimizedPseudoClasses.isEmpty() || !fragment.nthChildFilters.isEmpty())
</ins><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="cx">     for (unsigned pseudoClassType : fragment.pseudoClasses) {
</span><span class="lines">@@ -1591,8 +1650,10 @@
</span><span class="cx">         generateElementIsFirstChild(matchingPostTagNameFailureCases, fragment);
</span><span class="cx">     if (fragment.pseudoClasses.contains(CSSSelector::PseudoClassLastChild))
</span><span class="cx">         generateElementIsLastChild(matchingPostTagNameFailureCases, fragment);
</span><del>-    if (!fragment.nthChildfilters.isEmpty())
</del><ins>+    if (!fragment.nthChildFilters.isEmpty())
</ins><span class="cx">         generateElementIsNthChild(matchingPostTagNameFailureCases, fragment);
</span><ins>+    if (!fragment.notFilters.isEmpty())
+        generateElementMatchesNotPseudoClass(matchingPostTagNameFailureCases, fragment);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void SelectorCodeGenerator::generateElementDataMatching(Assembler::JumpList&amp; failureCases, const SelectorFragment&amp; fragment)
</span><span class="lines">@@ -1613,7 +1674,7 @@
</span><span class="cx">     if (!fragment.classNames.isEmpty())
</span><span class="cx">         generateElementHasClasses(failureCases, elementDataAddress, fragment.classNames);
</span><span class="cx">     if (!fragment.attributes.isEmpty())
</span><del>-    generateElementAttributesMatching(failureCases, elementDataAddress, fragment);
</del><ins>+        generateElementAttributesMatching(failureCases, elementDataAddress, fragment);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static inline Assembler::Jump testIsHTMLFlagOnNode(Assembler::ResultCondition condition, Assembler&amp; assembler, Assembler::RegisterID nodeAddress)
</span><span class="lines">@@ -2385,8 +2446,8 @@
</span><span class="cx">     generateWalkToParentElement(failureCases, parentElement);
</span><span class="cx"> 
</span><span class="cx">     Vector&lt;std::pair&lt;int, int&gt;&gt; validSubsetFilters;
</span><del>-    validSubsetFilters.reserveInitialCapacity(fragment.nthChildfilters.size());
-    for (const auto&amp; slot : fragment.nthChildfilters) {
</del><ins>+    validSubsetFilters.reserveInitialCapacity(fragment.nthChildFilters.size());
+    for (const auto&amp; slot : fragment.nthChildFilters) {
</ins><span class="cx">         int a = slot.first;
</span><span class="cx">         int b = slot.second;
</span><span class="cx"> 
</span><span class="lines">@@ -2494,6 +2555,17 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void SelectorCodeGenerator::generateElementMatchesNotPseudoClass(Assembler::JumpList&amp; failureCases, const SelectorFragment&amp; fragment)
+{
+    for (const auto&amp; subFragment : fragment.notFilters) {
+        Assembler::JumpList localFailureCases;
+        generateElementMatching(localFailureCases, localFailureCases, subFragment);
+        // Since this is a not pseudo class filter, reaching here is a failure.
+        failureCases.append(m_assembler.jump());
+        localFailureCases.link(&amp;m_assembler);
+    }
+}
+
</ins><span class="cx"> void SelectorCodeGenerator::generateElementIsRoot(Assembler::JumpList&amp; failureCases)
</span><span class="cx"> {
</span><span class="cx">     LocalRegister document(m_registerAllocator);
</span></span></pre>
</div>
</div>

</body>
</html>