<!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>[172220] 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/172220">172220</a></dd>
<dt>Author</dt> <dd>achristensen@apple.com</dd>
<dt>Date</dt> <dd>2014-08-07 11:55:50 -0700 (Thu, 07 Aug 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Compile scrollbar pseudoclass css selectors.
https://bugs.webkit.org/show_bug.cgi?id=135242

Reviewed by Benjamin Poulain.

Source/WebCore:

Tests: scrollbars/corner-resizer-window-inactive.html
       scrollbars/scrollbar-selectors.html

* css/ElementRuleCollector.cpp:
(WebCore::ElementRuleCollector::ruleMatches):
Changed assertion because there are pseudo-elements selectors that return CannotCompileAnything now, which
make SimpleSelectorCheckers.
Add scrollbar, scrollbarPart, and document to the CheckingContext and compile scrollbar pseudo-element selectors.
* css/SelectorChecker.cpp:
(WebCore::hasScrollbarPseudoElement):
Added.  Logic moved from matchRecursively to be easier to read and to add assertions.
context.scrollbar is always non-null when dynamicPseudo is SCROLLBAR_CORNER.
(WebCore::SelectorChecker::matchRecursively):
Moved logic to hasScrollbarPseudoElement.
(WebCore::SelectorChecker::checkOne):
checkScrollbarPseudoClass accesses the document through the element now.
(WebCore::SelectorChecker::checkScrollbarPseudoClass):
* css/SelectorChecker.h:
(WebCore::SelectorChecker::SelectorCheckingContext::SelectorCheckingContext):
* css/SelectorCheckerTestFunctions.h:
(WebCore::scrollbarMatchesEnabledPseudoClass):
(WebCore::scrollbarMatchesDisabledPseudoClass):
(WebCore::scrollbarMatchesHoverPseudoClass):
(WebCore::scrollbarMatchesActivePseudoClass):
(WebCore::scrollbarMatchesHorizontalPseudoClass):
(WebCore::scrollbarMatchesVerticalPseudoClass):
(WebCore::scrollbarMatchesDecrementPseudoClass):
(WebCore::scrollbarMatchesIncrementPseudoClass):
(WebCore::scrollbarMatchesStartPseudoClass):
(WebCore::scrollbarMatchesEndPseudoClass):
(WebCore::scrollbarMatchesDoubleButtonPseudoClass):
(WebCore::scrollbarMatchesSingleButtonPseudoClass):
(WebCore::scrollbarMatchesNoButtonPseudoClass):
(WebCore::scrollbarMatchesCornerPresentPseudoClass):
Move scrollbar selector logic from SelectorChecker.cpp to SelectorCheckerTestFunctions.h
For window-inactive pseudo classes, we now access the document through the element instead of as a separate parameter.
* cssjit/SelectorCompiler.cpp:
(WebCore::SelectorCompiler::SelectorFragment::appendUnoptimizedPseudoClassWithContext):
(WebCore::SelectorCompiler::addScrollbarPseudoClassType):
(WebCore::SelectorCompiler::addPseudoClassType):
(WebCore::SelectorCompiler::isScrollbarPseudoElement):
(WebCore::SelectorCompiler::constructFragments):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementMatching):
Call functions for unoptimized pseudo classes that require a context.
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateContextFunctionCallTest):
Added.  Similar to generateElementFunctionCallTest, but the CheckingContext pointer is stored on the stack instead of a dedicated register.
* cssjit/SelectorCompiler.h:
Added scrollbar, scrollbarPart, and document to the CheckingContext.
(WebCore::SelectorCompiler::CheckingContext::document):
Added method to access the document in a way that is syntactically equal to SelectorCheckingContext.
This way, the template functions in SelectorCheckerTestFunctions.h can be compiled with both context types,
but the context types store the document differently.

LayoutTests:

* platform/wk2/TestExpectations:
Don't run corner-resizer-window-inactive-expected in WK2 because testRunner.setWindowIsKey doesn't work with WK2.
* scrollbars/corner-resizer-window-inactive-expected.html: Added.
* scrollbars/corner-resizer-window-inactive.html: Added.
* scrollbars/scrollbar-selectors-expected.txt: Added.
* scrollbars/scrollbar-selectors.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsplatformwk2TestExpectations">trunk/LayoutTests/platform/wk2/TestExpectations</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorecssElementRuleCollectorcpp">trunk/Source/WebCore/css/ElementRuleCollector.cpp</a></li>
<li><a href="#trunkSourceWebCorecssSelectorCheckercpp">trunk/Source/WebCore/css/SelectorChecker.cpp</a></li>
<li><a href="#trunkSourceWebCorecssSelectorCheckerh">trunk/Source/WebCore/css/SelectorChecker.h</a></li>
<li><a href="#trunkSourceWebCorecssSelectorCheckerTestFunctionsh">trunk/Source/WebCore/css/SelectorCheckerTestFunctions.h</a></li>
<li><a href="#trunkSourceWebCorecssjitSelectorCompilercpp">trunk/Source/WebCore/cssjit/SelectorCompiler.cpp</a></li>
<li><a href="#trunkSourceWebCorecssjitSelectorCompilerh">trunk/Source/WebCore/cssjit/SelectorCompiler.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsscrollbarscornerresizerwindowinactiveexpectedhtml">trunk/LayoutTests/scrollbars/corner-resizer-window-inactive-expected.html</a></li>
<li><a href="#trunkLayoutTestsscrollbarscornerresizerwindowinactivehtml">trunk/LayoutTests/scrollbars/corner-resizer-window-inactive.html</a></li>
<li><a href="#trunkLayoutTestsscrollbarsscrollbarselectorsexpectedtxt">trunk/LayoutTests/scrollbars/scrollbar-selectors-expected.txt</a></li>
<li><a href="#trunkLayoutTestsscrollbarsscrollbarselectorshtml">trunk/LayoutTests/scrollbars/scrollbar-selectors.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (172219 => 172220)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2014-08-07 18:46:43 UTC (rev 172219)
+++ trunk/LayoutTests/ChangeLog        2014-08-07 18:55:50 UTC (rev 172220)
</span><span class="lines">@@ -1,3 +1,17 @@
</span><ins>+2014-08-07  Alex Christensen  &lt;achristensen@webkit.org&gt;
+
+        Compile scrollbar pseudoclass css selectors.
+        https://bugs.webkit.org/show_bug.cgi?id=135242
+
+        Reviewed by Benjamin Poulain.
+
+        * platform/wk2/TestExpectations:
+        Don't run corner-resizer-window-inactive-expected in WK2 because testRunner.setWindowIsKey doesn't work with WK2.
+        * scrollbars/corner-resizer-window-inactive-expected.html: Added.
+        * scrollbars/corner-resizer-window-inactive.html: Added.
+        * scrollbars/scrollbar-selectors-expected.txt: Added.
+        * scrollbars/scrollbar-selectors.html: Added.
+
</ins><span class="cx"> 2014-08-07  Zalan Bujtas  &lt;zalan@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         border-radius on html does not render properly.
</span></span></pre></div>
<a id="trunkLayoutTestsplatformwk2TestExpectations"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/wk2/TestExpectations (172219 => 172220)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/wk2/TestExpectations        2014-08-07 18:46:43 UTC (rev 172219)
+++ trunk/LayoutTests/platform/wk2/TestExpectations        2014-08-07 18:55:50 UTC (rev 172220)
</span><span class="lines">@@ -213,6 +213,7 @@
</span><span class="cx"> fast/selectors/querySelector-window-inactive.html
</span><span class="cx"> fast/selectors/selection-window-inactive.html
</span><span class="cx"> fast/dom/Window/window-focus-self.html
</span><ins>+scrollbars/corner-resizer-window-inactive.html
</ins><span class="cx"> 
</span><span class="cx"> # css3-conditionals support is not yet enabled.
</span><span class="cx"> webkit.org/b/86146 css3/supports.html
</span></span></pre></div>
<a id="trunkLayoutTestsscrollbarscornerresizerwindowinactiveexpectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/scrollbars/corner-resizer-window-inactive-expected.html (0 => 172220)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/scrollbars/corner-resizer-window-inactive-expected.html                                (rev 0)
+++ trunk/LayoutTests/scrollbars/corner-resizer-window-inactive-expected.html        2014-08-07 18:55:50 UTC (rev 172220)
</span><span class="lines">@@ -0,0 +1,48 @@
</span><ins>+&lt;head&gt;
+&lt;style&gt;
+body &gt; div {
+    padding: 10px;
+    margin: 20px;
+    border: 1px solid lightgray;
+    width: 125px;
+    height: 100px;
+}
+
+::-webkit-scrollbar {
+    width: 13px;
+    height: 13px;
+    background-color: blue;
+}
+
+::-webkit-resizer {
+    background-color: green;
+}
+
+::-webkit-scrollbar-corner {
+    background-color: green;
+}
+
+&lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+The scrollbar corner (bottom right) should be green when the window is inactive.
+&lt;div style=&quot;overflow: auto; padding: 0&quot;&gt;
+&lt;div style=&quot;width: 400px; padding: 10px&quot;&gt;
+Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi et nisi ut est venenatis viverra. Aenean pede orci, blandit quis, faucibus quis, egestas ut, mi. Pellentesque enim purus, venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam ut sem adipiscing orci vehicula interdum. Proin a enim. Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus nunc iaculis arcu, in molestie sem velit tempus est. In eleifend velit at sem adipiscing sodales. Nunc sapien felis, aliquam et, volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis condimentum.
+&lt;br&gt;&lt;br&gt;
+Cras commodo rutrum augue. Vivamus iaculis. Nullam est. Maecenas consequat. Sed id dui. Vivamus a nisl. Donec pretium sapien. Proin et ligula et ligula placerat pulvinar. Aliquam erat volutpat. Proin id est. Suspendisse cursus, magna at hendrerit consequat, mauris est imperdiet neque, a ultrices arcu urna non nunc. Quisque tellus. Nulla nulla justo, vehicula nec, pellentesque eu, iaculis et, ligula. Praesent mattis ante vel sem. Suspendisse porta rhoncus urna. Phasellus felis. Praesent viverra convallis libero. Maecenas non augue. Donec hendrerit lectus id enim.
+&lt;br&gt;&lt;br&gt;
+Nulla ligula dui, euismod et, sodales quis, sollicitudin quis, elit. In adipiscing est sed enim. Fusce at massa vitae metus semper hendrerit. Integer vitae urna. Nulla eget ligula. Etiam libero. Maecenas nisi nibh, convallis a, feugiat vitae, pulvinar et, mi. Curabitur arcu pede, adipiscing sed, egestas nec, commodo in, elit. Nulla facilisi. Proin varius pede et dui lacinia dapibus. Morbi nec augue. Proin imperdiet lacus eu tellus.
+&lt;/div&gt;
+&lt;/div&gt;
+
+The resizer (bottom right) should be green when the window is inactive.
+&lt;div style=&quot;overflow: auto; resize: both; padding: 0&quot;&gt;
+&lt;div style=&quot;width: 400px; padding: 10px&quot;&gt;
+Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi et nisi ut est venenatis viverra. Aenean pede orci, blandit quis, faucibus quis, egestas ut, mi. Pellentesque enim purus, venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam ut sem adipiscing orci vehicula interdum. Proin a enim. Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus nunc iaculis arcu, in molestie sem velit tempus est. In eleifend velit at sem adipiscing sodales. Nunc sapien felis, aliquam et, volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis condimentum.
+&lt;br&gt;&lt;br&gt;
+Cras commodo rutrum augue. Vivamus iaculis. Nullam est. Maecenas consequat. Sed id dui. Vivamus a nisl. Donec pretium sapien. Proin et ligula et ligula placerat pulvinar. Aliquam erat volutpat. Proin id est. Suspendisse cursus, magna at hendrerit consequat, mauris est imperdiet neque, a ultrices arcu urna non nunc. Quisque tellus. Nulla nulla justo, vehicula nec, pellentesque eu, iaculis et, ligula. Praesent mattis ante vel sem. Suspendisse porta rhoncus urna. Phasellus felis. Praesent viverra convallis libero. Maecenas non augue. Donec hendrerit lectus id enim.
+&lt;br&gt;&lt;br&gt;
+Nulla ligula dui, euismod et, sodales quis, sollicitudin quis, elit. In adipiscing est sed enim. Fusce at massa vitae metus semper hendrerit. Integer vitae urna. Nulla eget ligula. Etiam libero. Maecenas nisi nibh, convallis a, feugiat vitae, pulvinar et, mi. Curabitur arcu pede, adipiscing sed, egestas nec, commodo in, elit. Nulla facilisi. Proin varius pede et dui lacinia dapibus. Morbi nec augue. Proin imperdiet lacus eu tellus.
+&lt;/div&gt;
+&lt;/div&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsscrollbarscornerresizerwindowinactivehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/scrollbars/corner-resizer-window-inactive.html (0 => 172220)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/scrollbars/corner-resizer-window-inactive.html                                (rev 0)
+++ trunk/LayoutTests/scrollbars/corner-resizer-window-inactive.html        2014-08-07 18:55:50 UTC (rev 172220)
</span><span class="lines">@@ -0,0 +1,61 @@
</span><ins>+&lt;head&gt;
+&lt;style&gt;
+body &gt; div {
+    padding: 10px;
+    margin: 20px;
+    border: 1px solid lightgray;
+    width: 125px;
+    height: 100px;
+}
+
+::-webkit-scrollbar {
+    width: 13px;
+    height: 13px;
+    background-color: blue;
+}
+
+::-webkit-resizer {
+    background-color: white;
+}
+
+::-webkit-resizer:window-inactive {
+    background-color: green;
+}
+
+::-webkit-scrollbar-corner {
+    background-color: white;
+}
+
+::-webkit-scrollbar-corner:window-inactive {
+    background-color: green;
+}
+
+&lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+The scrollbar corner (bottom right) should be green when the window is inactive.
+&lt;div style=&quot;overflow: auto; padding: 0&quot;&gt;
+&lt;div style=&quot;width: 400px; padding: 10px&quot;&gt;
+Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi et nisi ut est venenatis viverra. Aenean pede orci, blandit quis, faucibus quis, egestas ut, mi. Pellentesque enim purus, venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam ut sem adipiscing orci vehicula interdum. Proin a enim. Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus nunc iaculis arcu, in molestie sem velit tempus est. In eleifend velit at sem adipiscing sodales. Nunc sapien felis, aliquam et, volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis condimentum.
+&lt;br&gt;&lt;br&gt;
+Cras commodo rutrum augue. Vivamus iaculis. Nullam est. Maecenas consequat. Sed id dui. Vivamus a nisl. Donec pretium sapien. Proin et ligula et ligula placerat pulvinar. Aliquam erat volutpat. Proin id est. Suspendisse cursus, magna at hendrerit consequat, mauris est imperdiet neque, a ultrices arcu urna non nunc. Quisque tellus. Nulla nulla justo, vehicula nec, pellentesque eu, iaculis et, ligula. Praesent mattis ante vel sem. Suspendisse porta rhoncus urna. Phasellus felis. Praesent viverra convallis libero. Maecenas non augue. Donec hendrerit lectus id enim.
+&lt;br&gt;&lt;br&gt;
+Nulla ligula dui, euismod et, sodales quis, sollicitudin quis, elit. In adipiscing est sed enim. Fusce at massa vitae metus semper hendrerit. Integer vitae urna. Nulla eget ligula. Etiam libero. Maecenas nisi nibh, convallis a, feugiat vitae, pulvinar et, mi. Curabitur arcu pede, adipiscing sed, egestas nec, commodo in, elit. Nulla facilisi. Proin varius pede et dui lacinia dapibus. Morbi nec augue. Proin imperdiet lacus eu tellus.
+&lt;/div&gt;
+&lt;/div&gt;
+
+The resizer (bottom right) should be green when the window is inactive.
+&lt;div style=&quot;overflow: auto; resize: both; padding: 0&quot;&gt;
+&lt;div style=&quot;width: 400px; padding: 10px&quot;&gt;
+Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi et nisi ut est venenatis viverra. Aenean pede orci, blandit quis, faucibus quis, egestas ut, mi. Pellentesque enim purus, venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam ut sem adipiscing orci vehicula interdum. Proin a enim. Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus nunc iaculis arcu, in molestie sem velit tempus est. In eleifend velit at sem adipiscing sodales. Nunc sapien felis, aliquam et, volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis condimentum.
+&lt;br&gt;&lt;br&gt;
+Cras commodo rutrum augue. Vivamus iaculis. Nullam est. Maecenas consequat. Sed id dui. Vivamus a nisl. Donec pretium sapien. Proin et ligula et ligula placerat pulvinar. Aliquam erat volutpat. Proin id est. Suspendisse cursus, magna at hendrerit consequat, mauris est imperdiet neque, a ultrices arcu urna non nunc. Quisque tellus. Nulla nulla justo, vehicula nec, pellentesque eu, iaculis et, ligula. Praesent mattis ante vel sem. Suspendisse porta rhoncus urna. Phasellus felis. Praesent viverra convallis libero. Maecenas non augue. Donec hendrerit lectus id enim.
+&lt;br&gt;&lt;br&gt;
+Nulla ligula dui, euismod et, sodales quis, sollicitudin quis, elit. In adipiscing est sed enim. Fusce at massa vitae metus semper hendrerit. Integer vitae urna. Nulla eget ligula. Etiam libero. Maecenas nisi nibh, convallis a, feugiat vitae, pulvinar et, mi. Curabitur arcu pede, adipiscing sed, egestas nec, commodo in, elit. Nulla facilisi. Proin varius pede et dui lacinia dapibus. Morbi nec augue. Proin imperdiet lacus eu tellus.
+&lt;/div&gt;
+&lt;/div&gt;
+
+&lt;script&gt;
+if (window.testRunner)
+    window.testRunner.setWindowIsKey(false);
+&lt;/script&gt;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkLayoutTestsscrollbarsscrollbarselectorsexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/scrollbars/scrollbar-selectors-expected.txt (0 => 172220)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/scrollbars/scrollbar-selectors-expected.txt                                (rev 0)
+++ trunk/LayoutTests/scrollbars/scrollbar-selectors-expected.txt        2014-08-07 18:55:50 UTC (rev 172220)
</span><span class="lines">@@ -0,0 +1,9 @@
</span><ins>+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x584
+      RenderText {#text} at (0,0) size 448x18
+        text run at (0,0) width 272: &quot;This test runs many scrollbar selector tests. &quot;
+        text run at (272,0) width 176: &quot;It passes if it does not crash.&quot;
+      RenderText {#text} at (0,0) size 0x0
</ins></span></pre></div>
<a id="trunkLayoutTestsscrollbarsscrollbarselectorshtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/scrollbars/scrollbar-selectors.html (0 => 172220)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/scrollbars/scrollbar-selectors.html                                (rev 0)
+++ trunk/LayoutTests/scrollbars/scrollbar-selectors.html        2014-08-07 18:55:50 UTC (rev 172220)
</span><span class="lines">@@ -0,0 +1,254 @@
</span><ins>+&lt;head&gt;
+&lt;style&gt;
+body &gt; div {
+    padding: 10px;
+    margin: 20px;
+    display: inline-block;
+    border: 1px solid lightgray;
+    -webkit-box-sizing: border-box;
+    vertical-align: top;
+    font-family: Verdana, sans-serif;
+    font-size: 12px;
+    -webkit-user-select: text;
+    width: 125px;
+    height: 100px;
+}
+&lt;/style&gt;
+&lt;/head&gt;
+
+&lt;body&gt;
+This test runs many scrollbar selector tests.  It passes if it does not crash.
+&lt;div style=&quot;overflow: scroll&quot;&gt;
+Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi et nisi ut est venenatis viverra. Aenean pede orci, blandit quis, faucibus quis, egestas ut, mi. Pellentesque enim purus, venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam ut sem adipiscing orci vehicula interdum. Proin a enim. Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus nunc iaculis arcu, in molestie sem velit tempus est. In eleifend velit at sem adipiscing sodales. Nunc sapien felis, aliquam et, volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis condimentum.
+&lt;br&gt;&lt;br&gt;
+Cras commodo rutrum augue. Vivamus iaculis. Nullam est. Maecenas consequat. Sed id dui. Vivamus a nisl. Donec pretium sapien. Proin et ligula et ligula placerat pulvinar. Aliquam erat volutpat. Proin id est. Suspendisse cursus, magna at hendrerit consequat, mauris est imperdiet neque, a ultrices arcu urna non nunc. Quisque tellus. Nulla nulla justo, vehicula nec, pellentesque eu, iaculis et, ligula. Praesent mattis ante vel sem. Suspendisse porta rhoncus urna. Phasellus felis. Praesent viverra convallis libero. Maecenas non augue. Donec hendrerit lectus id enim.
+&lt;br&gt;&lt;br&gt;
+Nulla ligula dui, euismod et, sodales quis, sollicitudin quis, elit. In adipiscing est sed enim. Fusce at massa vitae metus semper hendrerit. Integer vitae urna. Nulla eget ligula. Etiam libero. Maecenas nisi nibh, convallis a, feugiat vitae, pulvinar et, mi. Curabitur arcu pede, adipiscing sed, egestas nec, commodo in, elit. Nulla facilisi. Proin varius pede et dui lacinia dapibus. Morbi nec augue. Proin imperdiet lacus eu tellus.
+&lt;/div&gt;
+
+&lt;div style=&quot;overflow: auto&quot;&gt;
+Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi et nisi ut est venenatis viverra. Aenean pede orci, blandit quis, faucibus quis, egestas ut, mi. Pellentesque enim purus, venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam ut sem adipiscing orci vehicula interdum. Proin a enim. Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus nunc iaculis arcu, in molestie sem velit tempus est. In eleifend velit at sem adipiscing sodales. Nunc sapien felis, aliquam et, volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis condimentum.
+&lt;br&gt;&lt;br&gt;
+Cras commodo rutrum augue. Vivamus iaculis. Nullam est. Maecenas consequat. Sed id dui. Vivamus a nisl. Donec pretium sapien. Proin et ligula et ligula placerat pulvinar. Aliquam erat volutpat. Proin id est. Suspendisse cursus, magna at hendrerit consequat, mauris est imperdiet neque, a ultrices arcu urna non nunc. Quisque tellus. Nulla nulla justo, vehicula nec, pellentesque eu, iaculis et, ligula. Praesent mattis ante vel sem. Suspendisse porta rhoncus urna. Phasellus felis. Praesent viverra convallis libero. Maecenas non augue. Donec hendrerit lectus id enim.
+&lt;br&gt;&lt;br&gt;
+Nulla ligula dui, euismod et, sodales quis, sollicitudin quis, elit. In adipiscing est sed enim. Fusce at massa vitae metus semper hendrerit. Integer vitae urna. Nulla eget ligula. Etiam libero. Maecenas nisi nibh, convallis a, feugiat vitae, pulvinar et, mi. Curabitur arcu pede, adipiscing sed, egestas nec, commodo in, elit. Nulla facilisi. Proin varius pede et dui lacinia dapibus. Morbi nec augue. Proin imperdiet lacus eu tellus.
+&lt;/div&gt;
+
+&lt;div style=&quot;overflow: auto; padding: 0&quot;&gt;
+&lt;div style=&quot;width: 400px; padding: 10px&quot;&gt;
+Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi et nisi ut est venenatis viverra. Aenean pede orci, blandit quis, faucibus quis, egestas ut, mi. Pellentesque enim purus, venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam ut sem adipiscing orci vehicula interdum. Proin a enim. Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus nunc iaculis arcu, in molestie sem velit tempus est. In eleifend velit at sem adipiscing sodales. Nunc sapien felis, aliquam et, volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis condimentum.
+&lt;br&gt;&lt;br&gt;
+Cras commodo rutrum augue. Vivamus iaculis. Nullam est. Maecenas consequat. Sed id dui. Vivamus a nisl. Donec pretium sapien. Proin et ligula et ligula placerat pulvinar. Aliquam erat volutpat. Proin id est. Suspendisse cursus, magna at hendrerit consequat, mauris est imperdiet neque, a ultrices arcu urna non nunc. Quisque tellus. Nulla nulla justo, vehicula nec, pellentesque eu, iaculis et, ligula. Praesent mattis ante vel sem. Suspendisse porta rhoncus urna. Phasellus felis. Praesent viverra convallis libero. Maecenas non augue. Donec hendrerit lectus id enim.
+&lt;br&gt;&lt;br&gt;
+Nulla ligula dui, euismod et, sodales quis, sollicitudin quis, elit. In adipiscing est sed enim. Fusce at massa vitae metus semper hendrerit. Integer vitae urna. Nulla eget ligula. Etiam libero. Maecenas nisi nibh, convallis a, feugiat vitae, pulvinar et, mi. Curabitur arcu pede, adipiscing sed, egestas nec, commodo in, elit. Nulla facilisi. Proin varius pede et dui lacinia dapibus. Morbi nec augue. Proin imperdiet lacus eu tellus.
+&lt;/div&gt;
+&lt;/div&gt;
+
+&lt;div style=&quot;overflow: scroll; resize: both&quot;&gt;
+Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi et nisi ut est venenatis viverra. Aenean pede orci, blandit quis, faucibus quis, egestas ut, mi. Pellentesque enim purus, venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam ut sem adipiscing orci vehicula interdum. Proin a enim. Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus nunc iaculis arcu, in molestie sem velit tempus est. In eleifend velit at sem adipiscing sodales. Nunc sapien felis, aliquam et, volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis condimentum.
+&lt;br&gt;&lt;br&gt;
+Cras commodo rutrum augue. Vivamus iaculis. Nullam est. Maecenas consequat. Sed id dui. Vivamus a nisl. Donec pretium sapien. Proin et ligula et ligula placerat pulvinar. Aliquam erat volutpat. Proin id est. Suspendisse cursus, magna at hendrerit consequat, mauris est imperdiet neque, a ultrices arcu urna non nunc. Quisque tellus. Nulla nulla justo, vehicula nec, pellentesque eu, iaculis et, ligula. Praesent mattis ante vel sem. Suspendisse porta rhoncus urna. Phasellus felis. Praesent viverra convallis libero. Maecenas non augue. Donec hendrerit lectus id enim.
+&lt;br&gt;&lt;br&gt;
+Nulla ligula dui, euismod et, sodales quis, sollicitudin quis, elit. In adipiscing est sed enim. Fusce at massa vitae metus semper hendrerit. Integer vitae urna. Nulla eget ligula. Etiam libero. Maecenas nisi nibh, convallis a, feugiat vitae, pulvinar et, mi. Curabitur arcu pede, adipiscing sed, egestas nec, commodo in, elit. Nulla facilisi. Proin varius pede et dui lacinia dapibus. Morbi nec augue. Proin imperdiet lacus eu tellus.
+&lt;/div&gt;
+
+&lt;div style=&quot;overflow: auto; resize: both&quot;&gt;
+Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi et nisi ut est venenatis viverra. Aenean pede orci, blandit quis, faucibus quis, egestas ut, mi. Pellentesque enim purus, venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam ut sem adipiscing orci vehicula interdum. Proin a enim. Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus nunc iaculis arcu, in molestie sem velit tempus est. In eleifend velit at sem adipiscing sodales. Nunc sapien felis, aliquam et, volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis condimentum.
+&lt;br&gt;&lt;br&gt;
+Cras commodo rutrum augue. Vivamus iaculis. Nullam est. Maecenas consequat. Sed id dui. Vivamus a nisl. Donec pretium sapien. Proin et ligula et ligula placerat pulvinar. Aliquam erat volutpat. Proin id est. Suspendisse cursus, magna at hendrerit consequat, mauris est imperdiet neque, a ultrices arcu urna non nunc. Quisque tellus. Nulla nulla justo, vehicula nec, pellentesque eu, iaculis et, ligula. Praesent mattis ante vel sem. Suspendisse porta rhoncus urna. Phasellus felis. Praesent viverra convallis libero. Maecenas non augue. Donec hendrerit lectus id enim.
+&lt;br&gt;&lt;br&gt;
+Nulla ligula dui, euismod et, sodales quis, sollicitudin quis, elit. In adipiscing est sed enim. Fusce at massa vitae metus semper hendrerit. Integer vitae urna. Nulla eget ligula. Etiam libero. Maecenas nisi nibh, convallis a, feugiat vitae, pulvinar et, mi. Curabitur arcu pede, adipiscing sed, egestas nec, commodo in, elit. Nulla facilisi. Proin varius pede et dui lacinia dapibus. Morbi nec augue. Proin imperdiet lacus eu tellus.
+&lt;/div&gt;
+
+&lt;div style=&quot;overflow: auto; resize: both; padding: 0&quot;&gt;
+&lt;div style=&quot;width: 400px; padding: 10px&quot;&gt;
+Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi et nisi ut est venenatis viverra. Aenean pede orci, blandit quis, faucibus quis, egestas ut, mi. Pellentesque enim purus, venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam ut sem adipiscing orci vehicula interdum. Proin a enim. Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus nunc iaculis arcu, in molestie sem velit tempus est. In eleifend velit at sem adipiscing sodales. Nunc sapien felis, aliquam et, volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis condimentum.
+&lt;br&gt;&lt;br&gt;
+Cras commodo rutrum augue. Vivamus iaculis. Nullam est. Maecenas consequat. Sed id dui. Vivamus a nisl. Donec pretium sapien. Proin et ligula et ligula placerat pulvinar. Aliquam erat volutpat. Proin id est. Suspendisse cursus, magna at hendrerit consequat, mauris est imperdiet neque, a ultrices arcu urna non nunc. Quisque tellus. Nulla nulla justo, vehicula nec, pellentesque eu, iaculis et, ligula. Praesent mattis ante vel sem. Suspendisse porta rhoncus urna. Phasellus felis. Praesent viverra convallis libero. Maecenas non augue. Donec hendrerit lectus id enim.
+&lt;br&gt;&lt;br&gt;
+Nulla ligula dui, euismod et, sodales quis, sollicitudin quis, elit. In adipiscing est sed enim. Fusce at massa vitae metus semper hendrerit. Integer vitae urna. Nulla eget ligula. Etiam libero. Maecenas nisi nibh, convallis a, feugiat vitae, pulvinar et, mi. Curabitur arcu pede, adipiscing sed, egestas nec, commodo in, elit. Nulla facilisi. Proin varius pede et dui lacinia dapibus. Morbi nec augue. Proin imperdiet lacus eu tellus.
+&lt;/div&gt;
+&lt;/div&gt;
+
+&lt;div style=&quot;overflow-x: hidden; overflow-y: scroll&quot;&gt;
+Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi et nisi ut est venenatis viverra. Aenean pede orci, blandit quis, faucibus quis, egestas ut, mi. Pellentesque enim purus, venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam ut sem adipiscing orci vehicula interdum. Proin a enim. Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus nunc iaculis arcu, in molestie sem velit tempus est. In eleifend velit at sem adipiscing sodales. Nunc sapien felis, aliquam et, volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis condimentum.
+&lt;br&gt;&lt;br&gt;
+Cras commodo rutrum augue. Vivamus iaculis. Nullam est. Maecenas consequat. Sed id dui. Vivamus a nisl. Donec pretium sapien. Proin et ligula et ligula placerat pulvinar. Aliquam erat volutpat. Proin id est. Suspendisse cursus, magna at hendrerit consequat, mauris est imperdiet neque, a ultrices arcu urna non nunc. Quisque tellus. Nulla nulla justo, vehicula nec, pellentesque eu, iaculis et, ligula. Praesent mattis ante vel sem. Suspendisse porta rhoncus urna. Phasellus felis. Praesent viverra convallis libero. Maecenas non augue. Donec hendrerit lectus id enim.
+&lt;br&gt;&lt;br&gt;
+Nulla ligula dui, euismod et, sodales quis, sollicitudin quis, elit. In adipiscing est sed enim. Fusce at massa vitae metus semper hendrerit. Integer vitae urna. Nulla eget ligula. Etiam libero. Maecenas nisi nibh, convallis a, feugiat vitae, pulvinar et, mi. Curabitur arcu pede, adipiscing sed, egestas nec, commodo in, elit. Nulla facilisi. Proin varius pede et dui lacinia dapibus. Morbi nec augue. Proin imperdiet lacus eu tellus.
+&lt;/div&gt;
+
+&lt;div style=&quot;overflow-x: scroll; overflow-y: hidden; padding: 0&quot;&gt;
+&lt;div style=&quot;width: 400px; padding: 10px&quot;&gt;
+Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi et nisi ut est venenatis viverra. Aenean pede orci, blandit quis, faucibus quis, egestas ut, mi. Pellentesque enim purus, venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam ut sem adipiscing orci vehicula interdum. Proin a enim. Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus nunc iaculis arcu, in molestie sem velit tempus est. In eleifend velit at sem adipiscing sodales. Nunc sapien felis, aliquam et, volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis condimentum.
+&lt;/div&gt;
+&lt;/div&gt;
+
+&lt;div style=&quot;overflow-x: hidden; overflow-y: scroll; resize: both&quot;&gt;
+Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi et nisi ut est venenatis viverra. Aenean pede orci, blandit quis, faucibus quis, egestas ut, mi. Pellentesque enim purus, venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam ut sem adipiscing orci vehicula interdum. Proin a enim. Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus nunc iaculis arcu, in molestie sem velit tempus est. In eleifend velit at sem adipiscing sodales. Nunc sapien felis, aliquam et, volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis condimentum.
+&lt;br&gt;&lt;br&gt;
+Cras commodo rutrum augue. Vivamus iaculis. Nullam est. Maecenas consequat. Sed id dui. Vivamus a nisl. Donec pretium sapien. Proin et ligula et ligula placerat pulvinar. Aliquam erat volutpat. Proin id est. Suspendisse cursus, magna at hendrerit consequat, mauris est imperdiet neque, a ultrices arcu urna non nunc. Quisque tellus. Nulla nulla justo, vehicula nec, pellentesque eu, iaculis et, ligula. Praesent mattis ante vel sem. Suspendisse porta rhoncus urna. Phasellus felis. Praesent viverra convallis libero. Maecenas non augue. Donec hendrerit lectus id enim.
+&lt;br&gt;&lt;br&gt;
+Nulla ligula dui, euismod et, sodales quis, sollicitudin quis, elit. In adipiscing est sed enim. Fusce at massa vitae metus semper hendrerit. Integer vitae urna. Nulla eget ligula. Etiam libero. Maecenas nisi nibh, convallis a, feugiat vitae, pulvinar et, mi. Curabitur arcu pede, adipiscing sed, egestas nec, commodo in, elit. Nulla facilisi. Proin varius pede et dui lacinia dapibus. Morbi nec augue. Proin imperdiet lacus eu tellus.
+&lt;/div&gt;
+
+&lt;div style=&quot;overflow-x: scroll; overflow-y: hidden; resize: both; padding: 0&quot;&gt;
+&lt;div style=&quot;width: 400px; padding: 10px&quot;&gt;
+Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi et nisi ut est venenatis viverra. Aenean pede orci, blandit quis, faucibus quis, egestas ut, mi. Pellentesque enim purus, venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam ut sem adipiscing orci vehicula interdum. Proin a enim. Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus nunc iaculis arcu, in molestie sem velit tempus est. In eleifend velit at sem adipiscing sodales. Nunc sapien felis, aliquam et, volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis condimentum.
+&lt;/div&gt;
+&lt;/div&gt;
+
+&lt;div style=&quot;overflow: scroll; padding: 0&quot; class=&quot;single&quot;&gt;
+&lt;div style=&quot;width: 400px; padding: 10px&quot;&gt;
+Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi et nisi ut est venenatis viverra. Aenean pede orci, blandit quis, faucibus quis, egestas ut, mi. Pellentesque enim purus, venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam ut sem adipiscing orci vehicula interdum. Proin a enim. Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus nunc iaculis arcu, in molestie sem velit tempus est. In eleifend velit at sem adipiscing sodales. Nunc sapien felis, aliquam et, volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis condimentum.
+&lt;br&gt;&lt;br&gt;
+Cras commodo rutrum augue. Vivamus iaculis. Nullam est. Maecenas consequat. Sed id dui. Vivamus a nisl. Donec pretium sapien. Proin et ligula et ligula placerat pulvinar. Aliquam erat volutpat. Proin id est. Suspendisse cursus, magna at hendrerit consequat, mauris est imperdiet neque, a ultrices arcu urna non nunc. Quisque tellus. Nulla nulla justo, vehicula nec, pellentesque eu, iaculis et, ligula. Praesent mattis ante vel sem. Suspendisse porta rhoncus urna. Phasellus felis. Praesent viverra convallis libero. Maecenas non augue. Donec hendrerit lectus id enim.
+&lt;br&gt;&lt;br&gt;
+Nulla ligula dui, euismod et, sodales quis, sollicitudin quis, elit. In adipiscing est sed enim. Fusce at massa vitae metus semper hendrerit. Integer vitae urna. Nulla eget ligula. Etiam libero. Maecenas nisi nibh, convallis a, feugiat vitae, pulvinar et, mi. Curabitur arcu pede, adipiscing sed, egestas nec, commodo in, elit. Nulla facilisi. Proin varius pede et dui lacinia dapibus. Morbi nec augue. Proin imperdiet lacus eu tellus.
+&lt;/div&gt;
+&lt;/div&gt;
+
+&lt;div style=&quot;overflow: scroll; padding: 0&quot; class=&quot;double-end&quot;&gt;
+&lt;div style=&quot;width: 400px; padding: 10px&quot;&gt;
+Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi et nisi ut est venenatis viverra. Aenean pede orci, blandit quis, faucibus quis, egestas ut, mi. Pellentesque enim purus, venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam ut sem adipiscing orci vehicula interdum. Proin a enim. Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus nunc iaculis arcu, in molestie sem velit tempus est. In eleifend velit at sem adipiscing sodales. Nunc sapien felis, aliquam et, volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis condimentum.
+&lt;br&gt;&lt;br&gt;
+Cras commodo rutrum augue. Vivamus iaculis. Nullam est. Maecenas consequat. Sed id dui. Vivamus a nisl. Donec pretium sapien. Proin et ligula et ligula placerat pulvinar. Aliquam erat volutpat. Proin id est. Suspendisse cursus, magna at hendrerit consequat, mauris est imperdiet neque, a ultrices arcu urna non nunc. Quisque tellus. Nulla nulla justo, vehicula nec, pellentesque eu, iaculis et, ligula. Praesent mattis ante vel sem. Suspendisse porta rhoncus urna. Phasellus felis. Praesent viverra convallis libero. Maecenas non augue. Donec hendrerit lectus id enim.
+&lt;br&gt;&lt;br&gt;
+Nulla ligula dui, euismod et, sodales quis, sollicitudin quis, elit. In adipiscing est sed enim. Fusce at massa vitae metus semper hendrerit. Integer vitae urna. Nulla eget ligula. Etiam libero. Maecenas nisi nibh, convallis a, feugiat vitae, pulvinar et, mi. Curabitur arcu pede, adipiscing sed, egestas nec, commodo in, elit. Nulla facilisi. Proin varius pede et dui lacinia dapibus. Morbi nec augue. Proin imperdiet lacus eu tellus.
+&lt;/div&gt;
+&lt;/div&gt;
+
+&lt;div style=&quot;overflow: scroll; padding: 0&quot; class=&quot;double-start&quot;&gt;
+&lt;div style=&quot;width: 400px; padding: 10px&quot;&gt;
+Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi et nisi ut est venenatis viverra. Aenean pede orci, blandit quis, faucibus quis, egestas ut, mi. Pellentesque enim purus, venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam ut sem adipiscing orci vehicula interdum. Proin a enim. Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus nunc iaculis arcu, in molestie sem velit tempus est. In eleifend velit at sem adipiscing sodales. Nunc sapien felis, aliquam et, volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis condimentum.
+&lt;br&gt;&lt;br&gt;
+Cras commodo rutrum augue. Vivamus iaculis. Nullam est. Maecenas consequat. Sed id dui. Vivamus a nisl. Donec pretium sapien. Proin et ligula et ligula placerat pulvinar. Aliquam erat volutpat. Proin id est. Suspendisse cursus, magna at hendrerit consequat, mauris est imperdiet neque, a ultrices arcu urna non nunc. Quisque tellus. Nulla nulla justo, vehicula nec, pellentesque eu, iaculis et, ligula. Praesent mattis ante vel sem. Suspendisse porta rhoncus urna. Phasellus felis. Praesent viverra convallis libero. Maecenas non augue. Donec hendrerit lectus id enim.
+&lt;br&gt;&lt;br&gt;
+Nulla ligula dui, euismod et, sodales quis, sollicitudin quis, elit. In adipiscing est sed enim. Fusce at massa vitae metus semper hendrerit. Integer vitae urna. Nulla eget ligula. Etiam libero. Maecenas nisi nibh, convallis a, feugiat vitae, pulvinar et, mi. Curabitur arcu pede, adipiscing sed, egestas nec, commodo in, elit. Nulla facilisi. Proin varius pede et dui lacinia dapibus. Morbi nec augue. Proin imperdiet lacus eu tellus.
+&lt;/div&gt;
+&lt;/div&gt;
+
+&lt;div style=&quot;overflow: scroll; padding: 0&quot; class=&quot;double-both&quot;&gt;
+&lt;div style=&quot;width: 400px; padding: 10px&quot;&gt;
+Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi et nisi ut est venenatis viverra. Aenean pede orci, blandit quis, faucibus quis, egestas ut, mi. Pellentesque enim purus, venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam ut sem adipiscing orci vehicula interdum. Proin a enim. Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus nunc iaculis arcu, in molestie sem velit tempus est. In eleifend velit at sem adipiscing sodales. Nunc sapien felis, aliquam et, volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis condimentum.
+&lt;br&gt;&lt;br&gt;
+Cras commodo rutrum augue. Vivamus iaculis. Nullam est. Maecenas consequat. Sed id dui. Vivamus a nisl. Donec pretium sapien. Proin et ligula et ligula placerat pulvinar. Aliquam erat volutpat. Proin id est. Suspendisse cursus, magna at hendrerit consequat, mauris est imperdiet neque, a ultrices arcu urna non nunc. Quisque tellus. Nulla nulla justo, vehicula nec, pellentesque eu, iaculis et, ligula. Praesent mattis ante vel sem. Suspendisse porta rhoncus urna. Phasellus felis. Praesent viverra convallis libero. Maecenas non augue. Donec hendrerit lectus id enim.
+&lt;br&gt;&lt;br&gt;
+Nulla ligula dui, euismod et, sodales quis, sollicitudin quis, elit. In adipiscing est sed enim. Fusce at massa vitae metus semper hendrerit. Integer vitae urna. Nulla eget ligula. Etiam libero. Maecenas nisi nibh, convallis a, feugiat vitae, pulvinar et, mi. Curabitur arcu pede, adipiscing sed, egestas nec, commodo in, elit. Nulla facilisi. Proin varius pede et dui lacinia dapibus. Morbi nec augue. Proin imperdiet lacus eu tellus.
+&lt;/div&gt;
+&lt;/div&gt;
+
+&lt;div style=&quot;overflow: scroll; padding: 0&quot; class=&quot;none&quot;&gt;
+&lt;div style=&quot;width: 400px; padding: 10px&quot;&gt;
+Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi et nisi ut est venenatis viverra. Aenean pede orci, blandit quis, faucibus quis, egestas ut, mi. Pellentesque enim purus, venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam ut sem adipiscing orci vehicula interdum. Proin a enim. Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus nunc iaculis arcu, in molestie sem velit tempus est. In eleifend velit at sem adipiscing sodales. Nunc sapien felis, aliquam et, volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis condimentum.
+&lt;br&gt;&lt;br&gt;
+Cras commodo rutrum augue. Vivamus iaculis. Nullam est. Maecenas consequat. Sed id dui. Vivamus a nisl. Donec pretium sapien. Proin et ligula et ligula placerat pulvinar. Aliquam erat volutpat. Proin id est. Suspendisse cursus, magna at hendrerit consequat, mauris est imperdiet neque, a ultrices arcu urna non nunc. Quisque tellus. Nulla nulla justo, vehicula nec, pellentesque eu, iaculis et, ligula. Praesent mattis ante vel sem. Suspendisse porta rhoncus urna. Phasellus felis. Praesent viverra convallis libero. Maecenas non augue. Donec hendrerit lectus id enim.
+&lt;br&gt;&lt;br&gt;
+Nulla ligula dui, euismod et, sodales quis, sollicitudin quis, elit. In adipiscing est sed enim. Fusce at massa vitae metus semper hendrerit. Integer vitae urna. Nulla eget ligula. Etiam libero. Maecenas nisi nibh, convallis a, feugiat vitae, pulvinar et, mi. Curabitur arcu pede, adipiscing sed, egestas nec, commodo in, elit. Nulla facilisi. Proin varius pede et dui lacinia dapibus. Morbi nec augue. Proin imperdiet lacus eu tellus.
+&lt;/div&gt;
+&lt;/div&gt;
+
+&lt;script&gt;
+var pseudoElements = 
+[
+    &quot;-webkit-scrollbar&quot;, 
+    &quot;-webkit-scrollbar-button&quot;, 
+    &quot;-webkit-scrollbar-track&quot;, 
+    &quot;-webkit-scrollbar-track-piece&quot;, 
+    &quot;-webkit-scrollbar-thumb&quot;, 
+    &quot;-webkit-scrollbar-corner&quot;, 
+    &quot;-webkit-resizer&quot;,
+    &quot;invalidPseudoElement&quot;
+];
+
+function toColor(n) {
+    var hex = &quot;0123456789ABCDEF&quot;;
+    // Multiplying by 7 just makes the colors more diverse.
+    return &quot;#&quot;
+        + hex.substr(n * 7 &gt;&gt; 00 &amp; 0x0F, 1)
+        + hex.substr(n * 7 &gt;&gt; 04 &amp; 0x0F, 1)
+        + hex.substr(n * 7 &gt;&gt; 08 &amp; 0x0F, 1)
+        + hex.substr(n * 7 &gt;&gt; 12 &amp; 0x0F, 1)
+        + hex.substr(n * 7 &gt;&gt; 16 &amp; 0x0F, 1)
+        + hex.substr(n * 7 &gt;&gt; 20 &amp; 0x0F, 1);
+}
+
+function getPseudoClasses(n, pseudoClasses) {
+    var pseudoClassString = &quot;&quot;;
+    for (var i = 0; i &lt; pseudoClasses.length; i++)
+        if (n &amp; (1 &lt;&lt; i))
+            pseudoClassString += &quot;:&quot; + pseudoClasses[i];
+    return pseudoClassString;
+}
+
+function appendStyle(css) {
+    var style = document.createElement('style');
+    style.type = 'text/css';
+    style.appendChild(document.createTextNode(css));
+    document.head.appendChild(style);
+    
+    var divs = document.querySelectorAll(&quot;div&quot;);
+    for (var i = 0; i &lt; divs.length; i++) {
+        // Redraw each div
+        divs[i].style.display = &quot;none&quot;;
+        divs[i].style.display = &quot;inline-block&quot;;
+        // Switch whether window-inactive works.
+        if (window.testRunner) {
+            window.testRunner.setWindowIsKey(false);
+            window.testRunner.setWindowIsKey(true);
+        }
+    }
+}
+
+function testPseudoClasses(pseudoClasses) {
+    // Generate css with every pseudo element having every possible combination of pseudo class.
+    var css = &quot;&quot;;
+    var color = 0;
+    for (pseudoElement of pseudoElements)
+        for (var i = 0; i &lt; 1 &lt;&lt; pseudoClasses.length; i++)
+            css += &quot;::&quot; + pseudoElement + getPseudoClasses(i, pseudoClasses) + &quot; { background-color: &quot; + toColor(color++) + &quot;; }&quot;;
+    appendStyle(css);
+}
+
+var pseudoClasses1 = 
+[
+    &quot;disabled&quot;,
+    &quot;enabled&quot;,
+    &quot;horizontal&quot;,
+    &quot;active&quot;,
+    &quot;hover&quot;,
+    &quot;vertical&quot;,
+    &quot;decrement&quot;,
+    &quot;increment&quot;,
+    &quot;visited&quot;, // This is not a valid scrollbar pseudo class, but it is a valid pseudo class.
+    &quot;invalidPseudoClass&quot;
+];
+var pseudoClasses2 = 
+[
+    &quot;start&quot;,
+    &quot;end&quot;,
+    &quot;double-button&quot;,
+    &quot;single-button&quot;,
+    &quot;no-button&quot;,
+    &quot;corner-present&quot;,
+    &quot;window-inactive&quot;,
+    &quot;visited&quot;, // This is not a valid scrollbar pseudo class, but it is a valid pseudo class.
+    &quot;invalidPseudoClass&quot;
+];
+
+// Testing all combinations of pseudo classes would generate 2^17 combinations, which times out.
+// This is not quite comprehensive, but tests 2^10 + 2^9 combinations in a fraction of the time.
+testPseudoClasses(pseudoClasses1);
+testPseudoClasses(pseudoClasses2);
+
+// This tests various other unexpected things.
+appendStyle(&quot;::-webkit-scrollbar:start:start:start:start:start:start:start:start:start { color: red; }&quot;);
+appendStyle(&quot;::-webkit-scrollbar:invalid:invalid:invalid:invalid:invalid:invalid:invalid:invalid:invalid { color: red; }&quot;);
+appendStyle(&quot;::-webkit-scrollbar:visited:visited:visited:visited:visited:visited:visited:visited:visited { color: red; }&quot;);
+appendStyle(&quot;::-not-a-valid-pseudo-element::start:start:start:start:start:start:start:start:start { color: red; }&quot;);
+appendStyle(&quot;div:start { color: red; }&quot;);
+
+var divs = document.querySelectorAll(&quot;div&quot;);
+for (var i = 0; i &lt; divs.length; i++)
+    divs[i].outerHTML = &quot;&quot;;
+&lt;/script&gt;
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (172219 => 172220)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-08-07 18:46:43 UTC (rev 172219)
+++ trunk/Source/WebCore/ChangeLog        2014-08-07 18:55:50 UTC (rev 172220)
</span><span class="lines">@@ -1,3 +1,63 @@
</span><ins>+2014-08-07  Alex Christensen  &lt;achristensen@webkit.org&gt;
+
+        Compile scrollbar pseudoclass css selectors.
+        https://bugs.webkit.org/show_bug.cgi?id=135242
+
+        Reviewed by Benjamin Poulain.
+
+        Tests: scrollbars/corner-resizer-window-inactive.html
+               scrollbars/scrollbar-selectors.html
+
+        * css/ElementRuleCollector.cpp:
+        (WebCore::ElementRuleCollector::ruleMatches):
+        Changed assertion because there are pseudo-elements selectors that return CannotCompileAnything now, which
+        make SimpleSelectorCheckers.
+        Add scrollbar, scrollbarPart, and document to the CheckingContext and compile scrollbar pseudo-element selectors.
+        * css/SelectorChecker.cpp:
+        (WebCore::hasScrollbarPseudoElement):
+        Added.  Logic moved from matchRecursively to be easier to read and to add assertions.
+        context.scrollbar is always non-null when dynamicPseudo is SCROLLBAR_CORNER.
+        (WebCore::SelectorChecker::matchRecursively):
+        Moved logic to hasScrollbarPseudoElement.
+        (WebCore::SelectorChecker::checkOne):
+        checkScrollbarPseudoClass accesses the document through the element now.
+        (WebCore::SelectorChecker::checkScrollbarPseudoClass):
+        * css/SelectorChecker.h:
+        (WebCore::SelectorChecker::SelectorCheckingContext::SelectorCheckingContext):
+        * css/SelectorCheckerTestFunctions.h:
+        (WebCore::scrollbarMatchesEnabledPseudoClass):
+        (WebCore::scrollbarMatchesDisabledPseudoClass):
+        (WebCore::scrollbarMatchesHoverPseudoClass):
+        (WebCore::scrollbarMatchesActivePseudoClass):
+        (WebCore::scrollbarMatchesHorizontalPseudoClass):
+        (WebCore::scrollbarMatchesVerticalPseudoClass):
+        (WebCore::scrollbarMatchesDecrementPseudoClass):
+        (WebCore::scrollbarMatchesIncrementPseudoClass):
+        (WebCore::scrollbarMatchesStartPseudoClass):
+        (WebCore::scrollbarMatchesEndPseudoClass):
+        (WebCore::scrollbarMatchesDoubleButtonPseudoClass):
+        (WebCore::scrollbarMatchesSingleButtonPseudoClass):
+        (WebCore::scrollbarMatchesNoButtonPseudoClass):
+        (WebCore::scrollbarMatchesCornerPresentPseudoClass):
+        Move scrollbar selector logic from SelectorChecker.cpp to SelectorCheckerTestFunctions.h
+        For window-inactive pseudo classes, we now access the document through the element instead of as a separate parameter.
+        * cssjit/SelectorCompiler.cpp:
+        (WebCore::SelectorCompiler::SelectorFragment::appendUnoptimizedPseudoClassWithContext):
+        (WebCore::SelectorCompiler::addScrollbarPseudoClassType):
+        (WebCore::SelectorCompiler::addPseudoClassType):
+        (WebCore::SelectorCompiler::isScrollbarPseudoElement):
+        (WebCore::SelectorCompiler::constructFragments):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementMatching):
+        Call functions for unoptimized pseudo classes that require a context.
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateContextFunctionCallTest):
+        Added.  Similar to generateElementFunctionCallTest, but the CheckingContext pointer is stored on the stack instead of a dedicated register.
+        * cssjit/SelectorCompiler.h:
+        Added scrollbar, scrollbarPart, and document to the CheckingContext.
+        (WebCore::SelectorCompiler::CheckingContext::document):
+        Added method to access the document in a way that is syntactically equal to SelectorCheckingContext.
+        This way, the template functions in SelectorCheckerTestFunctions.h can be compiled with both context types,
+        but the context types store the document differently.
+
</ins><span class="cx"> 2014-08-07  Daniel Bates  &lt;dabates@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Sometimes Gmail cannot load messages, particularly on refresh (&quot;...the application ran into an unexpected error...&quot;)
</span></span></pre></div>
<a id="trunkSourceWebCorecssElementRuleCollectorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/ElementRuleCollector.cpp (172219 => 172220)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/ElementRuleCollector.cpp        2014-08-07 18:46:43 UTC (rev 172219)
+++ trunk/Source/WebCore/css/ElementRuleCollector.cpp        2014-08-07 18:55:50 UTC (rev 172220)
</span><span class="lines">@@ -297,8 +297,8 @@
</span><span class="cx"> 
</span><span class="cx">     if (compiledSelectorChecker) {
</span><span class="cx">         if (ruleData.compilationStatus() == SelectorCompilationStatus::SimpleSelectorChecker) {
</span><del>-            ASSERT_WITH_MESSAGE(m_pseudoStyleRequest.pseudoId == NOPSEUDO, &quot;When matching pseudo elements, we should never compile a selector checker without context. ElementRuleCollector::collectMatchingRulesForList() should filter out useless rules for pseudo elements.&quot;);
</del><span class="cx">             SelectorCompiler::SimpleSelectorChecker selectorChecker = SelectorCompiler::simpleSelectorCheckerFunction(compiledSelectorChecker, ruleData.compilationStatus());
</span><ins>+            ASSERT_WITH_MESSAGE(!selectorChecker(&amp;m_element) || m_pseudoStyleRequest.pseudoId == NOPSEUDO, &quot;When matching pseudo elements, we should never compile a selector checker without context unless it cannot match anything.&quot;);
</ins><span class="cx"> #if CSS_SELECTOR_JIT_PROFILING
</span><span class="cx">             ruleData.compiledSelectorUsed();
</span><span class="cx"> #endif
</span><span class="lines">@@ -306,18 +306,17 @@
</span><span class="cx">         }
</span><span class="cx">         ASSERT(ruleData.compilationStatus() == SelectorCompilationStatus::SelectorCheckerWithCheckingContext);
</span><span class="cx"> 
</span><del>-        // FIXME: Currently a compiled selector doesn't support scrollbar / selection's exceptional case.
-        if (!m_pseudoStyleRequest.scrollbar) {
-            SelectorCompiler::SelectorCheckerWithCheckingContext selectorChecker = SelectorCompiler::selectorCheckerFunctionWithCheckingContext(compiledSelectorChecker, ruleData.compilationStatus());
-            SelectorCompiler::CheckingContext context;
-            context.elementStyle = m_style;
-            context.resolvingMode = m_mode;
-            context.pseudoId = m_pseudoStyleRequest.pseudoId;
</del><ins>+        SelectorCompiler::SelectorCheckerWithCheckingContext selectorChecker = SelectorCompiler::selectorCheckerFunctionWithCheckingContext(compiledSelectorChecker, ruleData.compilationStatus());
+        SelectorCompiler::CheckingContext context;
+        context.elementStyle = m_style;
+        context.resolvingMode = m_mode;
+        context.pseudoId = m_pseudoStyleRequest.pseudoId;
+        context.scrollbar = m_pseudoStyleRequest.scrollbar;
+        context.scrollbarPart = m_pseudoStyleRequest.scrollbarPart;
</ins><span class="cx"> #if CSS_SELECTOR_JIT_PROFILING
</span><del>-            ruleData.compiledSelectorUsed();
</del><ins>+        ruleData.compiledSelectorUsed();
</ins><span class="cx"> #endif
</span><del>-            return selectorChecker(&amp;m_element, &amp;context);
-        }
</del><ins>+        return selectorChecker(&amp;m_element, &amp;context);
</ins><span class="cx">     }
</span><span class="cx"> #endif // ENABLE(CSS_SELECTOR_JIT)
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorecssSelectorCheckercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/SelectorChecker.cpp (172219 => 172220)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/SelectorChecker.cpp        2014-08-07 18:46:43 UTC (rev 172219)
+++ trunk/Source/WebCore/css/SelectorChecker.cpp        2014-08-07 18:55:50 UTC (rev 172220)
</span><span class="lines">@@ -48,10 +48,7 @@
</span><span class="cx"> #include &quot;NodeRenderStyle.h&quot;
</span><span class="cx"> #include &quot;Page.h&quot;
</span><span class="cx"> #include &quot;RenderElement.h&quot;
</span><del>-#include &quot;RenderScrollbar.h&quot;
</del><span class="cx"> #include &quot;RenderStyle.h&quot;
</span><del>-#include &quot;ScrollableArea.h&quot;
-#include &quot;ScrollbarTheme.h&quot;
</del><span class="cx"> #include &quot;SelectorCheckerTestFunctions.h&quot;
</span><span class="cx"> #include &quot;ShadowRoot.h&quot;
</span><span class="cx"> #include &quot;StyledElement.h&quot;
</span><span class="lines">@@ -155,6 +152,23 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline static bool hasScrollbarPseudoElement(const SelectorChecker::SelectorCheckingContext&amp; context, PseudoId&amp; dynamicPseudo)
+{
+    if (dynamicPseudo == SCROLLBAR
+        || dynamicPseudo == SCROLLBAR_THUMB
+        || dynamicPseudo == SCROLLBAR_BUTTON
+        || dynamicPseudo == SCROLLBAR_TRACK
+        || dynamicPseudo == SCROLLBAR_TRACK_PIECE
+        || dynamicPseudo == SCROLLBAR_CORNER) {
+        ASSERT(context.scrollbar);
+        return true;
+    }
+    
+    // RESIZER does not always have a scrollbar but it is a scrollbar-like pseudo element
+    // because it can have more than one pseudo element.
+    return dynamicPseudo == RESIZER;
+}
+    
</ins><span class="cx"> // Recursive check of selectors and combinators
</span><span class="cx"> // It can return 4 different values:
</span><span class="cx"> // * SelectorMatches          - the selector matches the element e
</span><span class="lines">@@ -272,7 +286,7 @@
</span><span class="cx">         // a selector is invalid if something follows a pseudo-element
</span><span class="cx">         // We make an exception for scrollbar pseudo elements and allow a set of pseudo classes (but nothing else)
</span><span class="cx">         // to follow the pseudo elements.
</span><del>-        nextContext.hasScrollbarPseudo = dynamicPseudo != NOPSEUDO &amp;&amp; (context.scrollbar || dynamicPseudo == SCROLLBAR_CORNER || dynamicPseudo == RESIZER);
</del><ins>+        nextContext.hasScrollbarPseudo = hasScrollbarPseudoElement(context, dynamicPseudo);
</ins><span class="cx">         nextContext.hasSelectionPseudo = dynamicPseudo == SELECTION;
</span><span class="cx">         if ((context.elementStyle || m_mode == Mode::CollectingRules) &amp;&amp; dynamicPseudo != NOPSEUDO
</span><span class="cx">             &amp;&amp; !nextContext.hasSelectionPseudo
</span><span class="lines">@@ -482,8 +496,8 @@
</span><span class="cx">             }
</span><span class="cx">         } else if (context.hasScrollbarPseudo) {
</span><span class="cx">             // CSS scrollbars match a specific subset of pseudo classes, and they have specialized rules for each
</span><del>-            // (since there are no elements involved).
-            return checkScrollbarPseudoClass(context, &amp;element-&gt;document(), selector);
</del><ins>+            // (since there are no elements involved except with window-inactive).
+            return checkScrollbarPseudoClass(context, selector);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         // Normal element pseudo class checking.
</span><span class="lines">@@ -810,83 +824,41 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool SelectorChecker::checkScrollbarPseudoClass(const SelectorCheckingContext&amp; context, Document* document, const CSSSelector* selector) const
</del><ins>+bool SelectorChecker::checkScrollbarPseudoClass(const SelectorCheckingContext&amp; context, const CSSSelector* selector) const
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(selector-&gt;m_match == CSSSelector::PseudoClass);
</span><span class="cx"> 
</span><del>-    RenderScrollbar* scrollbar = context.scrollbar;
-    ScrollbarPart part = context.scrollbarPart;
-
-    // FIXME: This is a temporary hack for resizers and scrollbar corners. Eventually :window-inactive should become a real
-    // pseudo class and just apply to everything.
-    if (selector-&gt;pseudoClassType() == CSSSelector::PseudoClassWindowInactive)
-        return !document-&gt;page()-&gt;focusController().isActive();
-
-    if (!scrollbar)
-        return false;
-
</del><span class="cx">     switch (selector-&gt;pseudoClassType()) {
</span><ins>+    case CSSSelector::PseudoClassWindowInactive:
+        return isWindowInactive(context.element);
</ins><span class="cx">     case CSSSelector::PseudoClassEnabled:
</span><del>-        return scrollbar-&gt;enabled();
</del><ins>+        return scrollbarMatchesEnabledPseudoClass(context);
</ins><span class="cx">     case CSSSelector::PseudoClassDisabled:
</span><del>-        return !scrollbar-&gt;enabled();
</del><ins>+        return scrollbarMatchesDisabledPseudoClass(context);
</ins><span class="cx">     case CSSSelector::PseudoClassHover:
</span><del>-        {
-            ScrollbarPart hoveredPart = scrollbar-&gt;hoveredPart();
-            if (part == ScrollbarBGPart)
-                return hoveredPart != NoPart;
-            if (part == TrackBGPart)
-                return hoveredPart == BackTrackPart || hoveredPart == ForwardTrackPart || hoveredPart == ThumbPart;
-            return part == hoveredPart;
-        }
</del><ins>+        return scrollbarMatchesHoverPseudoClass(context);
</ins><span class="cx">     case CSSSelector::PseudoClassActive:
</span><del>-        {
-            ScrollbarPart pressedPart = scrollbar-&gt;pressedPart();
-            if (part == ScrollbarBGPart)
-                return pressedPart != NoPart;
-            if (part == TrackBGPart)
-                return pressedPart == BackTrackPart || pressedPart == ForwardTrackPart || pressedPart == ThumbPart;
-            return part == pressedPart;
-        }
</del><ins>+        return scrollbarMatchesActivePseudoClass(context);
</ins><span class="cx">     case CSSSelector::PseudoClassHorizontal:
</span><del>-        return scrollbar-&gt;orientation() == HorizontalScrollbar;
</del><ins>+        return scrollbarMatchesHorizontalPseudoClass(context);
</ins><span class="cx">     case CSSSelector::PseudoClassVertical:
</span><del>-        return scrollbar-&gt;orientation() == VerticalScrollbar;
</del><ins>+        return scrollbarMatchesVerticalPseudoClass(context);
</ins><span class="cx">     case CSSSelector::PseudoClassDecrement:
</span><del>-        return part == BackButtonStartPart || part == BackButtonEndPart || part == BackTrackPart;
</del><ins>+        return scrollbarMatchesDecrementPseudoClass(context);
</ins><span class="cx">     case CSSSelector::PseudoClassIncrement:
</span><del>-        return part == ForwardButtonStartPart || part == ForwardButtonEndPart || part == ForwardTrackPart;
</del><ins>+        return scrollbarMatchesIncrementPseudoClass(context);
</ins><span class="cx">     case CSSSelector::PseudoClassStart:
</span><del>-        return part == BackButtonStartPart || part == ForwardButtonStartPart || part == BackTrackPart;
</del><ins>+        return scrollbarMatchesStartPseudoClass(context);
</ins><span class="cx">     case CSSSelector::PseudoClassEnd:
</span><del>-        return part == BackButtonEndPart || part == ForwardButtonEndPart || part == ForwardTrackPart;
</del><ins>+        return scrollbarMatchesEndPseudoClass(context);
</ins><span class="cx">     case CSSSelector::PseudoClassDoubleButton:
</span><del>-        {
-            ScrollbarButtonsPlacement buttonsPlacement = scrollbar-&gt;theme()-&gt;buttonsPlacement();
-            if (part == BackButtonStartPart || part == ForwardButtonStartPart || part == BackTrackPart)
-                return buttonsPlacement == ScrollbarButtonsDoubleStart || buttonsPlacement == ScrollbarButtonsDoubleBoth;
-            if (part == BackButtonEndPart || part == ForwardButtonEndPart || part == ForwardTrackPart)
-                return buttonsPlacement == ScrollbarButtonsDoubleEnd || buttonsPlacement == ScrollbarButtonsDoubleBoth;
-            return false;
-        }
</del><ins>+        return scrollbarMatchesDoubleButtonPseudoClass(context);
</ins><span class="cx">     case CSSSelector::PseudoClassSingleButton:
</span><del>-        {
-            ScrollbarButtonsPlacement buttonsPlacement = scrollbar-&gt;theme()-&gt;buttonsPlacement();
-            if (part == BackButtonStartPart || part == ForwardButtonEndPart || part == BackTrackPart || part == ForwardTrackPart)
-                return buttonsPlacement == ScrollbarButtonsSingle;
-            return false;
-        }
</del><ins>+        return scrollbarMatchesSingleButtonPseudoClass(context);
</ins><span class="cx">     case CSSSelector::PseudoClassNoButton:
</span><del>-        {
-            ScrollbarButtonsPlacement buttonsPlacement = scrollbar-&gt;theme()-&gt;buttonsPlacement();
-            if (part == BackTrackPart)
-                return buttonsPlacement == ScrollbarButtonsNone || buttonsPlacement == ScrollbarButtonsDoubleEnd;
-            if (part == ForwardTrackPart)
-                return buttonsPlacement == ScrollbarButtonsNone || buttonsPlacement == ScrollbarButtonsDoubleStart;
-            return false;
-        }
</del><ins>+        return scrollbarMatchesNoButtonPseudoClass(context);
</ins><span class="cx">     case CSSSelector::PseudoClassCornerPresent:
</span><del>-        return scrollbar-&gt;scrollableArea()-&gt;isScrollCornerVisible();
</del><ins>+        return scrollbarMatchesCornerPresentPseudoClass(context);
</ins><span class="cx">     default:
</span><span class="cx">         return false;
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceWebCorecssSelectorCheckerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/SelectorChecker.h (172219 => 172220)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/SelectorChecker.h        2014-08-07 18:46:43 UTC (rev 172219)
+++ trunk/Source/WebCore/css/SelectorChecker.h        2014-08-07 18:55:50 UTC (rev 172220)
</span><span class="lines">@@ -58,11 +58,11 @@
</span><span class="cx">         SelectorCheckingContext(const CSSSelector* selector, Element* element, VisitedMatchType visitedMatchType)
</span><span class="cx">             : selector(selector)
</span><span class="cx">             , element(element)
</span><del>-            , scope(0)
</del><ins>+            , scope(nullptr)
</ins><span class="cx">             , visitedMatchType(visitedMatchType)
</span><span class="cx">             , pseudoId(NOPSEUDO)
</span><del>-            , elementStyle(0)
-            , scrollbar(0)
</del><ins>+            , elementStyle(nullptr)
+            , scrollbar(nullptr)
</ins><span class="cx">             , firstSelectorOfTheFragment(selector)
</span><span class="cx">             , scrollbarPart(NoPart)
</span><span class="cx">             , inFunctionalPseudoClass(false)
</span><span class="lines">@@ -98,7 +98,7 @@
</span><span class="cx">     Match matchRecursively(const SelectorCheckingContext&amp;, PseudoId&amp;) const;
</span><span class="cx">     bool checkOne(const SelectorCheckingContext&amp;) const;
</span><span class="cx"> 
</span><del>-    bool checkScrollbarPseudoClass(const SelectorCheckingContext&amp;, Document*, const CSSSelector*) const;
</del><ins>+    bool checkScrollbarPseudoClass(const SelectorCheckingContext&amp;, const CSSSelector*) const;
</ins><span class="cx"> 
</span><span class="cx">     bool m_strictParsing;
</span><span class="cx">     bool m_documentIsHTML;
</span></span></pre></div>
<a id="trunkSourceWebCorecssSelectorCheckerTestFunctionsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/SelectorCheckerTestFunctions.h (172219 => 172220)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/SelectorCheckerTestFunctions.h        2014-08-07 18:46:43 UTC (rev 172219)
+++ trunk/Source/WebCore/css/SelectorCheckerTestFunctions.h        2014-08-07 18:55:50 UTC (rev 172220)
</span><span class="lines">@@ -31,6 +31,9 @@
</span><span class="cx"> #include &quot;HTMLAreaElement.h&quot;
</span><span class="cx"> #include &quot;HTMLInputElement.h&quot;
</span><span class="cx"> #include &quot;HTMLOptionElement.h&quot;
</span><ins>+#include &quot;RenderScrollbar.h&quot;
+#include &quot;ScrollableArea.h&quot;
+#include &quot;ScrollbarTheme.h&quot;
</ins><span class="cx"> #include &lt;wtf/Compiler.h&gt;
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(VIDEO_TRACK)
</span><span class="lines">@@ -160,7 +163,124 @@
</span><span class="cx"> {
</span><span class="cx">     return element-&gt;shouldAppearIndeterminate();
</span><span class="cx"> }
</span><ins>+    
+template &lt;typename ContextType&gt;
+ALWAYS_INLINE bool scrollbarMatchesEnabledPseudoClass(const ContextType&amp; context)
+{
+    return context.scrollbar &amp;&amp; context.scrollbar-&gt;enabled();
+}
</ins><span class="cx"> 
</span><ins>+template &lt;typename ContextType&gt;
+ALWAYS_INLINE bool scrollbarMatchesDisabledPseudoClass(const ContextType&amp; context)
+{
+    return context.scrollbar &amp;&amp; !context.scrollbar-&gt;enabled();
+}
+
+template &lt;typename ContextType&gt;
+ALWAYS_INLINE bool scrollbarMatchesHoverPseudoClass(const ContextType&amp; context)
+{
+    if (!context.scrollbar)
+        return false;
+    ScrollbarPart hoveredPart = context.scrollbar-&gt;hoveredPart();
+    if (context.scrollbarPart == ScrollbarBGPart)
+        return hoveredPart != NoPart;
+    if (context.scrollbarPart == TrackBGPart)
+        return hoveredPart == BackTrackPart || hoveredPart == ForwardTrackPart || hoveredPart == ThumbPart;
+    return context.scrollbarPart == hoveredPart;
+}
+
+template &lt;typename ContextType&gt;
+ALWAYS_INLINE bool scrollbarMatchesActivePseudoClass(const ContextType&amp; context)
+{
+    if (!context.scrollbar)
+        return false;
+    ScrollbarPart pressedPart = context.scrollbar-&gt;pressedPart();
+    if (context.scrollbarPart == ScrollbarBGPart)
+        return pressedPart != NoPart;
+    if (context.scrollbarPart == TrackBGPart)
+        return pressedPart == BackTrackPart || pressedPart == ForwardTrackPart || pressedPart == ThumbPart;
+    return context.scrollbarPart == pressedPart;
+}
+    
+template &lt;typename ContextType&gt;
+ALWAYS_INLINE bool scrollbarMatchesHorizontalPseudoClass(const ContextType&amp; context)
+{
+    return context.scrollbar &amp;&amp; context.scrollbar-&gt;orientation() == HorizontalScrollbar;
+}
+
+template &lt;typename ContextType&gt;
+ALWAYS_INLINE bool scrollbarMatchesVerticalPseudoClass(const ContextType&amp; context)
+{
+    return context.scrollbar &amp;&amp; context.scrollbar-&gt;orientation() == VerticalScrollbar;
+}
+    
+template &lt;typename ContextType&gt;
+ALWAYS_INLINE bool scrollbarMatchesDecrementPseudoClass(const ContextType&amp; context)
+{
+    return context.scrollbarPart == BackButtonStartPart || context.scrollbarPart == BackButtonEndPart || context.scrollbarPart == BackTrackPart;
+}
+    
+template &lt;typename ContextType&gt;
+ALWAYS_INLINE bool scrollbarMatchesIncrementPseudoClass(const ContextType&amp; context)
+{
+    return context.scrollbarPart == ForwardButtonStartPart || context.scrollbarPart == ForwardButtonEndPart || context.scrollbarPart == ForwardTrackPart;
+}
+    
+template &lt;typename ContextType&gt;
+ALWAYS_INLINE bool scrollbarMatchesStartPseudoClass(const ContextType&amp; context)
+{
+    return context.scrollbarPart == BackButtonStartPart || context.scrollbarPart == ForwardButtonStartPart || context.scrollbarPart == BackTrackPart;
+}
+    
+template &lt;typename ContextType&gt;
+ALWAYS_INLINE bool scrollbarMatchesEndPseudoClass(const ContextType&amp; context)
+{
+    return context.scrollbarPart == BackButtonEndPart || context.scrollbarPart == ForwardButtonEndPart || context.scrollbarPart == ForwardTrackPart;
+}
+    
+template &lt;typename ContextType&gt;
+ALWAYS_INLINE bool scrollbarMatchesDoubleButtonPseudoClass(const ContextType&amp; context)
+{
+    if (!context.scrollbar)
+        return false;
+    ScrollbarButtonsPlacement buttonsPlacement = context.scrollbar-&gt;theme()-&gt;buttonsPlacement();
+    if (context.scrollbarPart == BackButtonStartPart || context.scrollbarPart == ForwardButtonStartPart || context.scrollbarPart == BackTrackPart)
+        return buttonsPlacement == ScrollbarButtonsDoubleStart || buttonsPlacement == ScrollbarButtonsDoubleBoth;
+    if (context.scrollbarPart == BackButtonEndPart || context.scrollbarPart == ForwardButtonEndPart || context.scrollbarPart == ForwardTrackPart)
+        return buttonsPlacement == ScrollbarButtonsDoubleEnd || buttonsPlacement == ScrollbarButtonsDoubleBoth;
+    return false;
+}
+    
+template &lt;typename ContextType&gt;
+ALWAYS_INLINE bool scrollbarMatchesSingleButtonPseudoClass(const ContextType&amp; context)
+{
+    if (!context.scrollbar)
+        return false;
+    ScrollbarButtonsPlacement buttonsPlacement = context.scrollbar-&gt;theme()-&gt;buttonsPlacement();
+    if (context.scrollbarPart == BackButtonStartPart || context.scrollbarPart == ForwardButtonEndPart || context.scrollbarPart == BackTrackPart || context.scrollbarPart == ForwardTrackPart)
+        return buttonsPlacement == ScrollbarButtonsSingle;
+    return false;
+}
+    
+template &lt;typename ContextType&gt;
+ALWAYS_INLINE bool scrollbarMatchesNoButtonPseudoClass(const ContextType&amp; context)
+{
+    if (!context.scrollbar)
+        return false;
+    ScrollbarButtonsPlacement buttonsPlacement = context.scrollbar-&gt;theme()-&gt;buttonsPlacement();
+    if (context.scrollbarPart == BackTrackPart)
+        return buttonsPlacement == ScrollbarButtonsNone || buttonsPlacement == ScrollbarButtonsDoubleEnd;
+    if (context.scrollbarPart == ForwardTrackPart)
+        return buttonsPlacement == ScrollbarButtonsNone || buttonsPlacement == ScrollbarButtonsDoubleStart;
+    return false;
+}
+    
+template &lt;typename ContextType&gt;
+ALWAYS_INLINE bool scrollbarMatchesCornerPresentPseudoClass(const ContextType&amp; context)
+{
+    return context.scrollbar &amp;&amp; context.scrollbar-&gt;scrollableArea()-&gt;isScrollCornerVisible();
+}
+
</ins><span class="cx"> #if ENABLE(FULLSCREEN_API)
</span><span class="cx"> ALWAYS_INLINE bool matchesFullScreenPseudoClass(const Element* element)
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceWebCorecssjitSelectorCompilercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/cssjit/SelectorCompiler.cpp (172219 => 172220)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/cssjit/SelectorCompiler.cpp        2014-08-07 18:46:43 UTC (rev 172219)
+++ trunk/Source/WebCore/cssjit/SelectorCompiler.cpp        2014-08-07 18:55:50 UTC (rev 172220)
</span><span class="lines">@@ -157,12 +157,15 @@
</span><span class="cx">     unsigned tagNameNotMatchedBacktrackingStartWidthFromIndirectAdjacent;
</span><span class="cx">     unsigned widthFromIndirectAdjacent;
</span><span class="cx"> 
</span><ins>+    FunctionType appendUnoptimizedPseudoClassWithContext(bool (*matcher)(const CheckingContext&amp;));
+    
</ins><span class="cx">     const QualifiedName* tagName;
</span><span class="cx">     const AtomicString* id;
</span><span class="cx">     const AtomicString* langFilter;
</span><span class="cx">     Vector&lt;const AtomicStringImpl*, 32&gt; classNames;
</span><span class="cx">     HashSet&lt;unsigned&gt; pseudoClasses;
</span><span class="cx">     Vector&lt;JSC::FunctionPtr, 32&gt; unoptimizedPseudoClasses;
</span><ins>+    Vector&lt;JSC::FunctionPtr, 32&gt; unoptimizedPseudoClassesWithContext;
</ins><span class="cx">     Vector&lt;AttributeMatchingInfo, 32&gt; attributes;
</span><span class="cx">     Vector&lt;std::pair&lt;int, int&gt;, 32&gt; nthChildFilters;
</span><span class="cx">     Vector&lt;SelectorFragment&gt; notFilters;
</span><span class="lines">@@ -233,6 +236,7 @@
</span><span class="cx">     void generateElementMatching(Assembler::JumpList&amp; matchingTagNameFailureCases, Assembler::JumpList&amp; matchingPostTagNameFailureCases, const SelectorFragment&amp;);
</span><span class="cx">     void generateElementDataMatching(Assembler::JumpList&amp; failureCases, const SelectorFragment&amp;);
</span><span class="cx">     void generateElementFunctionCallTest(Assembler::JumpList&amp; failureCases, JSC::FunctionPtr);
</span><ins>+    void generateContextFunctionCallTest(Assembler::JumpList&amp; failureCases, JSC::FunctionPtr);
</ins><span class="cx">     void generateElementIsActive(Assembler::JumpList&amp; failureCases, const SelectorFragment&amp;);
</span><span class="cx">     void generateElementIsFirstChild(Assembler::JumpList&amp; failureCases, const SelectorFragment&amp;);
</span><span class="cx">     void generateElementIsHovered(Assembler::JumpList&amp; failureCases, const SelectorFragment&amp;);
</span><span class="lines">@@ -354,6 +358,52 @@
</span><span class="cx">     return fragment.relationToRightFragment == FragmentRelation::Rightmost &amp;&amp; fragment.positionInRootFragments == FragmentPositionInRootFragments::Rightmost;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+FunctionType SelectorFragment::appendUnoptimizedPseudoClassWithContext(bool (*matcher)(const CheckingContext&amp;))
+{
+    unoptimizedPseudoClassesWithContext.append(JSC::FunctionPtr(matcher));
+    return FunctionType::SelectorCheckerWithCheckingContext;
+}
+
+static inline FunctionType addScrollbarPseudoClassType(const CSSSelector&amp; selector, SelectorFragment&amp; fragment)
+{
+    switch (selector.pseudoClassType()) {
+    case CSSSelector::PseudoClassWindowInactive:
+        fragment.unoptimizedPseudoClasses.append(JSC::FunctionPtr(isWindowInactive));
+        return FunctionType::SimpleSelectorChecker;
+    case CSSSelector::PseudoClassDisabled:
+        return fragment.appendUnoptimizedPseudoClassWithContext(scrollbarMatchesDisabledPseudoClass&lt;CheckingContext&gt;);
+    case CSSSelector::PseudoClassEnabled:
+        return fragment.appendUnoptimizedPseudoClassWithContext(scrollbarMatchesEnabledPseudoClass&lt;CheckingContext&gt;);
+    case CSSSelector::PseudoClassHorizontal:
+        return fragment.appendUnoptimizedPseudoClassWithContext(scrollbarMatchesHorizontalPseudoClass&lt;CheckingContext&gt;);
+    case CSSSelector::PseudoClassVertical:
+        return fragment.appendUnoptimizedPseudoClassWithContext(scrollbarMatchesVerticalPseudoClass&lt;CheckingContext&gt;);
+    case CSSSelector::PseudoClassDecrement:
+        return fragment.appendUnoptimizedPseudoClassWithContext(scrollbarMatchesDecrementPseudoClass&lt;CheckingContext&gt;);
+    case CSSSelector::PseudoClassIncrement:
+        return fragment.appendUnoptimizedPseudoClassWithContext(scrollbarMatchesIncrementPseudoClass&lt;CheckingContext&gt;);
+    case CSSSelector::PseudoClassStart:
+        return fragment.appendUnoptimizedPseudoClassWithContext(scrollbarMatchesStartPseudoClass&lt;CheckingContext&gt;);
+    case CSSSelector::PseudoClassEnd:
+        return fragment.appendUnoptimizedPseudoClassWithContext(scrollbarMatchesEndPseudoClass&lt;CheckingContext&gt;);
+    case CSSSelector::PseudoClassDoubleButton:
+        return fragment.appendUnoptimizedPseudoClassWithContext(scrollbarMatchesDoubleButtonPseudoClass&lt;CheckingContext&gt;);
+    case CSSSelector::PseudoClassSingleButton:
+        return fragment.appendUnoptimizedPseudoClassWithContext(scrollbarMatchesSingleButtonPseudoClass&lt;CheckingContext&gt;);
+    case CSSSelector::PseudoClassNoButton:
+        return fragment.appendUnoptimizedPseudoClassWithContext(scrollbarMatchesNoButtonPseudoClass&lt;CheckingContext&gt;);
+    case CSSSelector::PseudoClassCornerPresent:
+        return fragment.appendUnoptimizedPseudoClassWithContext(scrollbarMatchesCornerPresentPseudoClass&lt;CheckingContext&gt;);
+    case CSSSelector::PseudoClassActive:
+        return fragment.appendUnoptimizedPseudoClassWithContext(scrollbarMatchesActivePseudoClass&lt;CheckingContext&gt;);
+    case CSSSelector::PseudoClassHover:
+        return fragment.appendUnoptimizedPseudoClassWithContext(scrollbarMatchesHoverPseudoClass&lt;CheckingContext&gt;);
+    default:
+        return FunctionType::CannotMatchAnything;
+    }
+    return FunctionType::CannotMatchAnything;
+}
+
</ins><span class="cx"> static inline FunctionType addPseudoClassType(const CSSSelector&amp; selector, SelectorFragment&amp; fragment, SelectorContext selectorContext, FragmentPositionInRootFragments positionInRootFragments)
</span><span class="cx"> {
</span><span class="cx">     CSSSelector::PseudoClassType type = selector.pseudoClassType();
</span><span class="lines">@@ -431,6 +481,19 @@
</span><span class="cx">         return FunctionType::SimpleSelectorChecker;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+    // These pseudo-classes only have meaning with scrollbars.
+    case CSSSelector::PseudoClassHorizontal:
+    case CSSSelector::PseudoClassVertical:
+    case CSSSelector::PseudoClassDecrement:
+    case CSSSelector::PseudoClassIncrement:
+    case CSSSelector::PseudoClassStart:
+    case CSSSelector::PseudoClassEnd:
+    case CSSSelector::PseudoClassDoubleButton:
+    case CSSSelector::PseudoClassSingleButton:
+    case CSSSelector::PseudoClassNoButton:
+    case CSSSelector::PseudoClassCornerPresent:
+        return FunctionType::CannotMatchAnything;
+
</ins><span class="cx">     // FIXME: Compile these pseudoclasses, too!
</span><span class="cx">     case CSSSelector::PseudoClassEmpty:
</span><span class="cx">     case CSSSelector::PseudoClassFirstOfType:
</span><span class="lines">@@ -443,16 +506,6 @@
</span><span class="cx">     case CSSSelector::PseudoClassDrag:
</span><span class="cx">     case CSSSelector::PseudoClassFullPageMedia:
</span><span class="cx">     case CSSSelector::PseudoClassScope:
</span><del>-    case CSSSelector::PseudoClassCornerPresent:
-    case CSSSelector::PseudoClassDecrement:
-    case CSSSelector::PseudoClassIncrement:
-    case CSSSelector::PseudoClassHorizontal:
-    case CSSSelector::PseudoClassVertical:
-    case CSSSelector::PseudoClassStart:
-    case CSSSelector::PseudoClassEnd:
-    case CSSSelector::PseudoClassDoubleButton:
-    case CSSSelector::PseudoClassSingleButton:
-    case CSSSelector::PseudoClassNoButton:
</del><span class="cx">         return FunctionType::CannotCompile;
</span><span class="cx"> 
</span><span class="cx">     // Optimized pseudo selectors.
</span><span class="lines">@@ -612,6 +665,11 @@
</span><span class="cx">     return pseudoClassType == CSSSelector::PseudoClassHover || pseudoClassType == CSSSelector::PseudoClassActive;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static bool isScrollbarPseudoElement(CSSSelector::PseudoElementType type)
+{
+    return type &gt;= CSSSelector::PseudoElementScrollbar &amp;&amp; type &lt;= CSSSelector::PseudoElementScrollbarTrackPiece;
+}
+
</ins><span class="cx"> static FunctionType constructFragments(const CSSSelector* rootSelector, SelectorContext selectorContext, SelectorFragmentList&amp; selectorFragments, FragmentsLevel fragmentLevel, FragmentPositionInRootFragments positionInRootFragments)
</span><span class="cx"> {
</span><span class="cx">     SelectorFragment fragment;
</span><span class="lines">@@ -623,10 +681,11 @@
</span><span class="cx">         // A selector is invalid if something follows a pseudo-element.
</span><span class="cx">         // We make an exception for scrollbar pseudo elements and allow a set of pseudo classes (but nothing else)
</span><span class="cx">         // to follow the pseudo elements.
</span><del>-        // FIXME: Currently, CSS JIT doesn't support scrollbar and selection's exceptional cases.
-        // So all selectors following a pseudo-element is treated as invalid.
-        if (relation == CSSSelector::SubSelector &amp;&amp; fragment.pseudoElementSelector)
-            return FunctionType::CannotCompile;
</del><ins>+        if (relation == CSSSelector::SubSelector
+            &amp;&amp; fragment.pseudoElementSelector
+            &amp;&amp; !isScrollbarPseudoElement(fragment.pseudoElementSelector-&gt;pseudoElementType())) {
+            return FunctionType::CannotMatchAnything;
+        }
</ins><span class="cx"> 
</span><span class="cx">         switch (selector-&gt;m_match) {
</span><span class="cx">         case CSSSelector::Tag:
</span><span class="lines">@@ -653,8 +712,10 @@
</span><span class="cx">             FragmentPositionInRootFragments subPosition = positionInRootFragments;
</span><span class="cx">             if (relationToPreviousFragment != FragmentRelation::Rightmost)
</span><span class="cx">                 subPosition = FragmentPositionInRootFragments::NotRightmost;
</span><del>-
-            functionType = mostRestrictiveFunctionType(functionType, addPseudoClassType(*selector, fragment, selectorContext, subPosition));
</del><ins>+            if (fragment.pseudoElementSelector &amp;&amp; isScrollbarPseudoElement(fragment.pseudoElementSelector-&gt;pseudoElementType()))
+                functionType = mostRestrictiveFunctionType(functionType, addScrollbarPseudoClassType(*selector, fragment));
+            else
+                functionType = mostRestrictiveFunctionType(functionType, addPseudoClassType(*selector, fragment, selectorContext, subPosition));
</ins><span class="cx">             if (!pseudoClassOnlyMatchesLinksInQuirksMode(*selector))
</span><span class="cx">                 fragment.onlyMatchesLinksInQuirksMode = false;
</span><span class="cx">             if (functionType == FunctionType::CannotCompile || functionType == FunctionType::CannotMatchAnything)
</span><span class="lines">@@ -678,9 +739,18 @@
</span><span class="cx">             case CSSSelector::PseudoElementBefore:
</span><span class="cx">             case CSSSelector::PseudoElementFirstLetter:
</span><span class="cx">             case CSSSelector::PseudoElementFirstLine:
</span><ins>+            case CSSSelector::PseudoElementScrollbar:
+            case CSSSelector::PseudoElementScrollbarButton:
+            case CSSSelector::PseudoElementScrollbarCorner:
+            case CSSSelector::PseudoElementScrollbarThumb:
+            case CSSSelector::PseudoElementScrollbarTrack:
+            case CSSSelector::PseudoElementScrollbarTrackPiece:
</ins><span class="cx">                 fragment.pseudoElementSelector = selector;
</span><span class="cx">                 break;
</span><del>-            // FIXME: Support SCROLLBAR, RESIZER, SELECTION etc.
</del><ins>+            case CSSSelector::PseudoElementUnknown:
+                ASSERT_NOT_REACHED();
+                return FunctionType::CannotMatchAnything;
+            // FIXME: Support RESIZER, SELECTION etc.
</ins><span class="cx">             default:
</span><span class="cx">                 return FunctionType::CannotCompile;
</span><span class="cx">             }
</span><span class="lines">@@ -1872,6 +1942,9 @@
</span><span class="cx">     for (unsigned i = 0; i &lt; fragment.unoptimizedPseudoClasses.size(); ++i)
</span><span class="cx">         generateElementFunctionCallTest(matchingPostTagNameFailureCases, fragment.unoptimizedPseudoClasses[i]);
</span><span class="cx"> 
</span><ins>+    for (unsigned i = 0; i &lt; fragment.unoptimizedPseudoClassesWithContext.size(); ++i)
+        generateContextFunctionCallTest(matchingPostTagNameFailureCases, fragment.unoptimizedPseudoClassesWithContext[i]);
+
</ins><span class="cx">     generateElementDataMatching(matchingPostTagNameFailureCases, fragment);
</span><span class="cx"> 
</span><span class="cx">     if (fragment.pseudoClasses.contains(CSSSelector::PseudoClassActive))
</span><span class="lines">@@ -2308,7 +2381,19 @@
</span><span class="cx">     functionCall.setOneArgument(elementAddress);
</span><span class="cx">     failureCases.append(functionCall.callAndBranchOnBooleanReturnValue(Assembler::Zero));
</span><span class="cx"> }
</span><ins>+    
+void SelectorCodeGenerator::generateContextFunctionCallTest(Assembler::JumpList&amp; failureCases, JSC::FunctionPtr testFunction)
+{
+    Assembler::RegisterID checkingContext = m_registerAllocator.allocateRegister();
+    loadCheckingContext(checkingContext);
+    m_registerAllocator.deallocateRegister(checkingContext);
</ins><span class="cx"> 
</span><ins>+    FunctionCall functionCall(m_assembler, m_registerAllocator, m_stackAllocator, m_functionCalls);
+    functionCall.setFunctionAddress(testFunction);
+    functionCall.setOneArgument(checkingContext);
+    failureCases.append(functionCall.callAndBranchOnBooleanReturnValue(Assembler::Zero));
+}
+
</ins><span class="cx"> static void setFirstChildState(Element* element)
</span><span class="cx"> {
</span><span class="cx">     if (RenderStyle* style = element-&gt;renderStyle())
</span></span></pre></div>
<a id="trunkSourceWebCorecssjitSelectorCompilerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/cssjit/SelectorCompiler.h (172219 => 172220)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/cssjit/SelectorCompiler.h        2014-08-07 18:46:43 UTC (rev 172219)
+++ trunk/Source/WebCore/cssjit/SelectorCompiler.h        2014-08-07 18:55:50 UTC (rev 172220)
</span><span class="lines">@@ -73,6 +73,8 @@
</span><span class="cx">     SelectorChecker::Mode resolvingMode;
</span><span class="cx">     RenderStyle* elementStyle;
</span><span class="cx">     PseudoId pseudoId;
</span><ins>+    RenderScrollbar* scrollbar;
+    ScrollbarPart scrollbarPart;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> enum class SelectorContext {
</span></span></pre>
</div>
</div>

</body>
</html>