<!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>[164924] 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/164924">164924</a></dd>
<dt>Author</dt> <dd>benjamin@webkit.org</dd>
<dt>Date</dt> <dd>2014-03-01 14:09:48 -0800 (Sat, 01 Mar 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Optimized querySelector(All) when selector contains #id
https://bugs.webkit.org/show_bug.cgi?id=116502

Reviewed by Andreas Kling.

Source/WebCore: 

Test: fast/selectors/querySelector-id-filtering.html

The idea of this patch is to perform querySelector on a subtree
rooted at the last element with #id matching. For example, if we have the selector
&quot;#foobar div a&quot;, we start by looking for the element with ID foobar in the TreeScope
cache, and start matching the children from there.

The idea comes from Rune for
https://chromium.googlesource.com/chromium/blink/+/1cd83d3588973a02ab15d94b1b05a28620853624
but the code as diverged too much so it had to be reimplemented specifically for WebKit.

* css/CSSSelectorList.cpp:
(WebCore::CSSSelectorList::CSSSelectorList):
(WebCore::CSSSelectorList::operator=):
* css/CSSSelectorList.h:
(WebCore::CSSSelectorList::~CSSSelectorList):
* css/StyleRule.h:
(WebCore::StyleRule::wrapperAdoptSelectorList):
(WebCore::StyleRulePage::wrapperAdoptSelectorList):
* dom/SelectorQuery.cpp:
(WebCore::isSingleTagNameSelector):
(WebCore::isSingleClassNameSelector):
(WebCore::findIdMatchingType):
(WebCore::SelectorDataList::SelectorDataList):
(WebCore::filterRootById):
(WebCore::SelectorDataList::executeCompiledSimpleSelectorChecker):
(WebCore::SelectorDataList::execute):
(WebCore::SelectorQuery::SelectorQuery):
(WebCore::SelectorQueryCache::add):
* dom/SelectorQuery.h:
(WebCore::SelectorDataList::SelectorData::SelectorData):

LayoutTests: 

* fast/selectors/querySelector-id-filtering-expected.txt: Added.
* fast/selectors/querySelector-id-filtering.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorecssCSSSelectorListcpp">trunk/Source/WebCore/css/CSSSelectorList.cpp</a></li>
<li><a href="#trunkSourceWebCorecssCSSSelectorListh">trunk/Source/WebCore/css/CSSSelectorList.h</a></li>
<li><a href="#trunkSourceWebCorecssStyleRuleh">trunk/Source/WebCore/css/StyleRule.h</a></li>
<li><a href="#trunkSourceWebCoredomSelectorQuerycpp">trunk/Source/WebCore/dom/SelectorQuery.cpp</a></li>
<li><a href="#trunkSourceWebCoredomSelectorQueryh">trunk/Source/WebCore/dom/SelectorQuery.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsfastselectorsquerySelectoridfilteringexpectedtxt">trunk/LayoutTests/fast/selectors/querySelector-id-filtering-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastselectorsquerySelectoridfilteringhtml">trunk/LayoutTests/fast/selectors/querySelector-id-filtering.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (164923 => 164924)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2014-03-01 19:57:40 UTC (rev 164923)
+++ trunk/LayoutTests/ChangeLog        2014-03-01 22:09:48 UTC (rev 164924)
</span><span class="lines">@@ -1,3 +1,13 @@
</span><ins>+2014-03-01  Benjamin Poulain  &lt;benjamin@webkit.org&gt;
+
+        Optimized querySelector(All) when selector contains #id
+        https://bugs.webkit.org/show_bug.cgi?id=116502
+
+        Reviewed by Andreas Kling.
+
+        * fast/selectors/querySelector-id-filtering-expected.txt: Added.
+        * fast/selectors/querySelector-id-filtering.html: Added.
+
</ins><span class="cx"> 2014-02-28  Alexey Proskuryakov  &lt;ap@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Node::compareDocumentPosition leaks memory structure
</span></span></pre></div>
<a id="trunkLayoutTestsfastselectorsquerySelectoridfilteringexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/querySelector-id-filtering-expected.txt (0 => 164924)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/querySelector-id-filtering-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/selectors/querySelector-id-filtering-expected.txt        2014-03-01 22:09:48 UTC (rev 164924)
</span><span class="lines">@@ -0,0 +1,44 @@
</span><ins>+Test various cases when we constrain a selector matching to a subtree selected by #ID
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+Missing id.
+PASS document.body.querySelectorAll(&quot;#notThere *&quot;).length is 0
+
+Trivial filtering.
+PASS document.body.querySelectorAll(&quot;#simple li&quot;).length is 1
+PASS document.body.querySelectorAll(&quot;#simple li&quot;)[0].id is &quot;simpleTarget&quot;
+
+ID is adjacent of target.
+PASS document.body.querySelectorAll(&quot;#directAdjacentRoot+div li&quot;).length is 1
+PASS document.body.querySelectorAll(&quot;#directAdjacentRoot+div li&quot;)[0].id is &quot;directAdjacentTarget&quot;
+PASS document.body.querySelectorAll(&quot;#indirectAdjacentRoot~div li&quot;).length is 1
+PASS document.body.querySelectorAll(&quot;#indirectAdjacentRoot~div li&quot;)[0].id is &quot;indirectAdjacentTarget&quot;
+
+Duplicated IDs.
+PASS document.body.querySelectorAll(&quot;#duplicated li&quot;).length is 3
+PASS document.body.querySelectorAll(&quot;#duplicated li&quot;)[0].id is &quot;duplicatedTarget1&quot;
+PASS document.body.querySelectorAll(&quot;#duplicated li&quot;)[1].id is &quot;duplicatedTarget2&quot;
+PASS document.body.querySelectorAll(&quot;#duplicated li&quot;)[2].id is &quot;duplicatedTarget3&quot;
+PASS document.body.querySelectorAll(&quot;#duplicated+div li&quot;).length is 2
+PASS document.body.querySelectorAll(&quot;#duplicated+div li&quot;)[0].id is &quot;siblingOfDuplicated1&quot;
+PASS document.body.querySelectorAll(&quot;#duplicated+div li&quot;)[1].id is &quot;siblingOfDuplicated2&quot;
+
+Duplicated IDs with a non-duplicated ancestor.
+PASS document.body.querySelectorAll(&quot;#nonDuplicatedParentOfDuplicate #deduplicated li&quot;).length is 3
+PASS document.body.querySelectorAll(&quot;#nonDuplicatedParentOfDuplicate #deduplicated li&quot;)[0].id is &quot;deduplicatedTarget1&quot;
+PASS document.body.querySelectorAll(&quot;#nonDuplicatedParentOfDuplicate #deduplicated li&quot;)[1].id is &quot;deduplicatedTarget2&quot;
+PASS document.body.querySelectorAll(&quot;#nonDuplicatedParentOfDuplicate #deduplicated li&quot;)[2].id is &quot;deduplicatedTarget3&quot;
+PASS document.body.querySelectorAll(&quot;#nonDuplicatedParentOfDuplicate #deduplicated+div li&quot;).length is 2
+PASS document.body.querySelectorAll(&quot;#nonDuplicatedParentOfDuplicate #deduplicated+div li&quot;)[0].id is &quot;siblingOfDeduplicated1&quot;
+PASS document.body.querySelectorAll(&quot;#nonDuplicatedParentOfDuplicate #deduplicated+div li&quot;)[1].id is &quot;siblingOfDeduplicated2&quot;
+PASS document.body.querySelectorAll(&quot;#nonDuplicatedParentOfDuplicate+div li&quot;).length is 1
+PASS document.body.querySelectorAll(&quot;#nonDuplicatedParentOfDuplicate+div li&quot;)[0].id is &quot;siblingOfNonDuplicatedParentOfDuplicate&quot;
+
+Sibling of HTML document.
+PASS document.body.querySelectorAll(&quot;#htmlDocument~* *&quot;).length is 0
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastselectorsquerySelectoridfilteringhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/querySelector-id-filtering.html (0 => 164924)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/querySelector-id-filtering.html                                (rev 0)
+++ trunk/LayoutTests/fast/selectors/querySelector-id-filtering.html        2014-03-01 22:09:48 UTC (rev 164924)
</span><span class="lines">@@ -0,0 +1,138 @@
</span><ins>+&lt;!doctype html&gt;
+&lt;html id=htmlDocument&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;div style=&quot;display:none&quot;&gt;
+    &lt;!-- Simple case --&gt;
+    &lt;div id=simple&gt;
+        &lt;ul&gt;
+            &lt;li id=simpleTarget&gt;&lt;/li&gt;
+        &lt;/ul&gt;
+    &lt;/div&gt;
+
+    &lt;!-- Duplicated IDs case --&gt;
+    &lt;div id=duplicated&gt;
+        &lt;ul&gt;
+            &lt;li id=duplicatedTarget1&gt;&lt;/li&gt;
+        &lt;/ul&gt;
+        &lt;div id=duplicated&gt;
+            &lt;ul&gt;
+                &lt;li id=duplicatedTarget2&gt;&lt;/li&gt;
+            &lt;/ul&gt;
+        &lt;/div&gt;
+    &lt;/div&gt;
+    &lt;div&gt;
+        &lt;ul&gt;
+            &lt;li id=siblingOfDuplicated1&gt;&lt;/li&gt;
+        &lt;/ul&gt;
+    &lt;/div&gt;
+
+    &lt;div id=duplicated&gt;
+        &lt;ul&gt;
+            &lt;li id=duplicatedTarget3&gt;&lt;/li&gt;
+        &lt;/ul&gt;
+    &lt;/div&gt;
+    &lt;div&gt;
+        &lt;ul&gt;
+            &lt;li id=siblingOfDuplicated2&gt;&lt;/li&gt;
+        &lt;/ul&gt;
+    &lt;/div&gt;
+
+    &lt;!-- Duplicated IDs in a non-duplicated ID --&gt;
+    &lt;div id=nonDuplicatedParentOfDuplicate&gt;
+        &lt;div id=deduplicated&gt;
+            &lt;ul&gt;
+                &lt;li id=deduplicatedTarget1&gt;&lt;/li&gt;
+            &lt;/ul&gt;
+            &lt;div id=deduplicated&gt;
+                &lt;ul&gt;
+                    &lt;li id=deduplicatedTarget2&gt;&lt;/li&gt;
+                &lt;/ul&gt;
+            &lt;/div&gt;
+        &lt;/div&gt;
+        &lt;div&gt;
+            &lt;ul&gt;
+                &lt;li id=siblingOfDeduplicated1&gt;&lt;/li&gt;
+            &lt;/ul&gt;
+        &lt;/div&gt;
+
+        &lt;div id=deduplicated&gt;
+            &lt;ul&gt;
+                &lt;li id=deduplicatedTarget3&gt;&lt;/li&gt;
+            &lt;/ul&gt;
+        &lt;/div&gt;
+        &lt;div&gt;
+            &lt;ul&gt;
+                &lt;li id=siblingOfDeduplicated2&gt;&lt;/li&gt;
+            &lt;/ul&gt;
+        &lt;/div&gt;
+    &lt;/div&gt;
+    &lt;div&gt;
+        &lt;ul&gt;
+            &lt;li id=siblingOfNonDuplicatedParentOfDuplicate&gt;&lt;/li&gt;
+        &lt;/ul&gt;
+    &lt;/div&gt;
+
+    &lt;!-- ID adjacent of target --&gt;
+    &lt;div id=directAdjacentRoot&gt;&lt;/div&gt;
+    &lt;div&gt;
+        &lt;ul&gt;
+            &lt;li id=&quot;directAdjacentTarget&quot;&gt;&lt;/li&gt;
+        &lt;/ul&gt;
+    &lt;/div&gt;
+
+    &lt;!-- ID indirect adjacent of target --&gt;
+    &lt;div id=indirectAdjacentRoot&gt;&lt;/div&gt;
+    &lt;div&gt;&lt;/div&gt;
+    &lt;div&gt;&lt;/div&gt;
+    &lt;div&gt;
+        &lt;ul&gt;
+            &lt;li id=&quot;indirectAdjacentTarget&quot;&gt;&lt;/li&gt;
+        &lt;/ul&gt;
+    &lt;/div&gt;
+&lt;/div&gt;
+&lt;/body&gt;
+&lt;script&gt;
+description('Test various cases when we constrain a selector matching to a subtree selected by #ID');
+
+debug(&quot;Missing id.&quot;);
+shouldBe('document.body.querySelectorAll(&quot;#notThere *&quot;).length', '0');
+
+debug(&quot;&lt;br&gt;Trivial filtering.&quot;);
+shouldBe('document.body.querySelectorAll(&quot;#simple li&quot;).length', '1');
+shouldBeEqualToString('document.body.querySelectorAll(&quot;#simple li&quot;)[0].id', 'simpleTarget');
+
+debug(&quot;&lt;br&gt;ID is adjacent of target.&quot;);
+shouldBe('document.body.querySelectorAll(&quot;#directAdjacentRoot+div li&quot;).length', '1');
+shouldBeEqualToString('document.body.querySelectorAll(&quot;#directAdjacentRoot+div li&quot;)[0].id', 'directAdjacentTarget');
+shouldBe('document.body.querySelectorAll(&quot;#indirectAdjacentRoot~div li&quot;).length', '1');
+shouldBeEqualToString('document.body.querySelectorAll(&quot;#indirectAdjacentRoot~div li&quot;)[0].id', 'indirectAdjacentTarget');
+
+debug(&quot;&lt;br&gt;Duplicated IDs.&quot;);
+shouldBe('document.body.querySelectorAll(&quot;#duplicated li&quot;).length', '3');
+shouldBeEqualToString('document.body.querySelectorAll(&quot;#duplicated li&quot;)[0].id', 'duplicatedTarget1');
+shouldBeEqualToString('document.body.querySelectorAll(&quot;#duplicated li&quot;)[1].id', 'duplicatedTarget2');
+shouldBeEqualToString('document.body.querySelectorAll(&quot;#duplicated li&quot;)[2].id', 'duplicatedTarget3');
+shouldBe('document.body.querySelectorAll(&quot;#duplicated+div li&quot;).length', '2');
+shouldBeEqualToString('document.body.querySelectorAll(&quot;#duplicated+div li&quot;)[0].id', 'siblingOfDuplicated1');
+shouldBeEqualToString('document.body.querySelectorAll(&quot;#duplicated+div li&quot;)[1].id', 'siblingOfDuplicated2');
+
+debug(&quot;&lt;br&gt;Duplicated IDs with a non-duplicated ancestor.&quot;);
+shouldBe('document.body.querySelectorAll(&quot;#nonDuplicatedParentOfDuplicate #deduplicated li&quot;).length', '3');
+shouldBeEqualToString('document.body.querySelectorAll(&quot;#nonDuplicatedParentOfDuplicate #deduplicated li&quot;)[0].id', 'deduplicatedTarget1');
+shouldBeEqualToString('document.body.querySelectorAll(&quot;#nonDuplicatedParentOfDuplicate #deduplicated li&quot;)[1].id', 'deduplicatedTarget2');
+shouldBeEqualToString('document.body.querySelectorAll(&quot;#nonDuplicatedParentOfDuplicate #deduplicated li&quot;)[2].id', 'deduplicatedTarget3');
+shouldBe('document.body.querySelectorAll(&quot;#nonDuplicatedParentOfDuplicate #deduplicated+div li&quot;).length', '2');
+shouldBeEqualToString('document.body.querySelectorAll(&quot;#nonDuplicatedParentOfDuplicate #deduplicated+div li&quot;)[0].id', 'siblingOfDeduplicated1');
+shouldBeEqualToString('document.body.querySelectorAll(&quot;#nonDuplicatedParentOfDuplicate #deduplicated+div li&quot;)[1].id', 'siblingOfDeduplicated2');
+shouldBe('document.body.querySelectorAll(&quot;#nonDuplicatedParentOfDuplicate+div li&quot;).length', '1');
+shouldBeEqualToString('document.body.querySelectorAll(&quot;#nonDuplicatedParentOfDuplicate+div li&quot;)[0].id', 'siblingOfNonDuplicatedParentOfDuplicate');
+
+debug(&quot;&lt;br&gt;Sibling of HTML document.&quot;);
+shouldBe('document.body.querySelectorAll(&quot;#htmlDocument~* *&quot;).length', '0');
+
+&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (164923 => 164924)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-03-01 19:57:40 UTC (rev 164923)
+++ trunk/Source/WebCore/ChangeLog        2014-03-01 22:09:48 UTC (rev 164924)
</span><span class="lines">@@ -1,3 +1,42 @@
</span><ins>+2014-03-01  Benjamin Poulain  &lt;benjamin@webkit.org&gt;
+
+        Optimized querySelector(All) when selector contains #id
+        https://bugs.webkit.org/show_bug.cgi?id=116502
+
+        Reviewed by Andreas Kling.
+
+        Test: fast/selectors/querySelector-id-filtering.html
+
+        The idea of this patch is to perform querySelector on a subtree
+        rooted at the last element with #id matching. For example, if we have the selector
+        &quot;#foobar div a&quot;, we start by looking for the element with ID foobar in the TreeScope
+        cache, and start matching the children from there.
+
+        The idea comes from Rune for
+        https://chromium.googlesource.com/chromium/blink/+/1cd83d3588973a02ab15d94b1b05a28620853624
+        but the code as diverged too much so it had to be reimplemented specifically for WebKit.
+
+        * css/CSSSelectorList.cpp:
+        (WebCore::CSSSelectorList::CSSSelectorList):
+        (WebCore::CSSSelectorList::operator=):
+        * css/CSSSelectorList.h:
+        (WebCore::CSSSelectorList::~CSSSelectorList):
+        * css/StyleRule.h:
+        (WebCore::StyleRule::wrapperAdoptSelectorList):
+        (WebCore::StyleRulePage::wrapperAdoptSelectorList):
+        * dom/SelectorQuery.cpp:
+        (WebCore::isSingleTagNameSelector):
+        (WebCore::isSingleClassNameSelector):
+        (WebCore::findIdMatchingType):
+        (WebCore::SelectorDataList::SelectorDataList):
+        (WebCore::filterRootById):
+        (WebCore::SelectorDataList::executeCompiledSimpleSelectorChecker):
+        (WebCore::SelectorDataList::execute):
+        (WebCore::SelectorQuery::SelectorQuery):
+        (WebCore::SelectorQueryCache::add):
+        * dom/SelectorQuery.h:
+        (WebCore::SelectorDataList::SelectorData::SelectorData):
+
</ins><span class="cx"> 2014-02-28  Alexey Proskuryakov  &lt;ap@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Node::compareDocumentPosition leaks memory structure
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSSelectorListcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSSelectorList.cpp (164923 => 164924)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSSelectorList.cpp        2014-03-01 19:57:40 UTC (rev 164923)
+++ trunk/Source/WebCore/css/CSSSelectorList.cpp        2014-03-01 22:09:48 UTC (rev 164924)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2008, 2012, 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2008, 2012, 2013, 2014 Apple Inc. All rights reserved.
</ins><span class="cx">  * Copyright (C) 2009 Google Inc. All rights reserved.
</span><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="lines">@@ -32,11 +32,6 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-CSSSelectorList::~CSSSelectorList()
-{
-    deleteSelectors();
-}
-
</del><span class="cx"> CSSSelectorList::CSSSelectorList(const CSSSelectorList&amp; other)
</span><span class="cx"> {
</span><span class="cx">     unsigned otherComponentCount = other.componentCount();
</span><span class="lines">@@ -45,11 +40,10 @@
</span><span class="cx">         new (NotNull, &amp;m_selectorArray[i]) CSSSelector(other.m_selectorArray[i]);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void CSSSelectorList::adopt(CSSSelectorList&amp; list)
</del><ins>+CSSSelectorList::CSSSelectorList(CSSSelectorList&amp;&amp; other)
+    : m_selectorArray(other.m_selectorArray)
</ins><span class="cx"> {
</span><del>-    deleteSelectors();
-    m_selectorArray = list.m_selectorArray;
-    list.m_selectorArray = 0;
</del><ins>+    other.m_selectorArray = nullptr;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void CSSSelectorList::adoptSelectorVector(Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;&gt;&amp; selectorVector)
</span><span class="lines">@@ -97,6 +91,14 @@
</span><span class="cx">     return (current - m_selectorArray) + 1;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+CSSSelectorList&amp; CSSSelectorList::operator=(CSSSelectorList&amp;&amp; other)
+{
+    deleteSelectors();
+    m_selectorArray = other.m_selectorArray;
+    other.m_selectorArray = nullptr;
+    return *this;
+}
+
</ins><span class="cx"> void CSSSelectorList::deleteSelectors()
</span><span class="cx"> {
</span><span class="cx">     if (!m_selectorArray)
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSSelectorListh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSSelectorList.h (164923 => 164924)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSSelectorList.h        2014-03-01 19:57:40 UTC (rev 164923)
+++ trunk/Source/WebCore/css/CSSSelectorList.h        2014-03-01 22:09:48 UTC (rev 164924)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2008 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2008, 2014 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -38,10 +38,10 @@
</span><span class="cx"> public:
</span><span class="cx">     CSSSelectorList() : m_selectorArray(0) { }
</span><span class="cx">     CSSSelectorList(const CSSSelectorList&amp;);
</span><ins>+    CSSSelectorList(CSSSelectorList&amp;&amp;);
</ins><span class="cx"> 
</span><del>-    ~CSSSelectorList();
</del><ins>+    ~CSSSelectorList() { deleteSelectors(); }
</ins><span class="cx"> 
</span><del>-    void adopt(CSSSelectorList&amp; list);
</del><span class="cx">     void adoptSelectorVector(Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;&gt;&amp; selectorVector);
</span><span class="cx">     void adoptSelectorArray(CSSSelector* selectors) { ASSERT(!m_selectorArray); m_selectorArray = selectors; }
</span><span class="cx"> 
</span><span class="lines">@@ -67,6 +67,8 @@
</span><span class="cx"> 
</span><span class="cx">     unsigned componentCount() const;
</span><span class="cx"> 
</span><ins>+    CSSSelectorList&amp; operator=(CSSSelectorList&amp;&amp;);
+
</ins><span class="cx"> private:
</span><span class="cx">     void deleteSelectors();
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorecssStyleRuleh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/StyleRule.h (164923 => 164924)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/StyleRule.h        2014-03-01 19:57:40 UTC (rev 164923)
+++ trunk/Source/WebCore/css/StyleRule.h        2014-03-01 22:09:48 UTC (rev 164924)
</span><span class="lines">@@ -118,7 +118,7 @@
</span><span class="cx">     MutableStyleProperties&amp; mutableProperties();
</span><span class="cx">     
</span><span class="cx">     void parserAdoptSelectorVector(Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;&gt;&amp; selectors) { m_selectorList.adoptSelectorVector(selectors); }
</span><del>-    void wrapperAdoptSelectorList(CSSSelectorList&amp; selectors) { m_selectorList.adopt(selectors); }
</del><ins>+    void wrapperAdoptSelectorList(CSSSelectorList&amp; selectors) { m_selectorList = std::move(selectors); }
</ins><span class="cx">     void parserAdoptSelectorArray(CSSSelector* selectors) { m_selectorList.adoptSelectorArray(selectors); }
</span><span class="cx"> 
</span><span class="cx">     PassRef&lt;StyleRule&gt; copy() const { return adoptRef(*new StyleRule(*this)); }
</span><span class="lines">@@ -173,7 +173,7 @@
</span><span class="cx">     MutableStyleProperties&amp; mutableProperties();
</span><span class="cx"> 
</span><span class="cx">     void parserAdoptSelectorVector(Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;&gt;&amp; selectors) { m_selectorList.adoptSelectorVector(selectors); }
</span><del>-    void wrapperAdoptSelectorList(CSSSelectorList&amp; selectors) { m_selectorList.adopt(selectors); }
</del><ins>+    void wrapperAdoptSelectorList(CSSSelectorList&amp; selectors) { m_selectorList = std::move(selectors); }
</ins><span class="cx"> 
</span><span class="cx">     PassRef&lt;StyleRulePage&gt; copy() const { return adoptRef(*new StyleRulePage(*this)); }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoredomSelectorQuerycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/SelectorQuery.cpp (164923 => 164924)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/SelectorQuery.cpp        2014-03-01 19:57:40 UTC (rev 164923)
+++ trunk/Source/WebCore/dom/SelectorQuery.cpp        2014-03-01 22:09:48 UTC (rev 164924)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -35,10 +35,41 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-void SelectorDataList::initialize(const CSSSelectorList&amp; selectorList)
</del><ins>+#if !ASSERT_DISABLED
+static bool isSingleTagNameSelector(const CSSSelector&amp; selector)
</ins><span class="cx"> {
</span><del>-    ASSERT(m_selectors.isEmpty());
</del><ins>+    return selector.isLastInTagHistory() &amp;&amp; selector.m_match == CSSSelector::Tag;
+}
</ins><span class="cx"> 
</span><ins>+static bool isSingleClassNameSelector(const CSSSelector&amp; selector)
+{
+    return selector.isLastInTagHistory() &amp;&amp; selector.m_match == CSSSelector::Class;
+}
+#endif
+
+enum class IdMatchingType : uint8_t {
+    None,
+    Rightmost,
+    Filter
+};
+
+static IdMatchingType findIdMatchingType(const CSSSelector&amp; firstSelector)
+{
+    bool inRightmost = true;
+    for (const CSSSelector* selector = &amp;firstSelector; selector; selector = selector-&gt;tagHistory()) {
+        if (selector-&gt;m_match == CSSSelector::Id) {
+            if (inRightmost)
+                return IdMatchingType::Rightmost;
+            return IdMatchingType::Filter;
+        }
+        if (selector-&gt;relation() != CSSSelector::SubSelector)
+            inRightmost = false;
+    }
+    return IdMatchingType::None;
+}
+
+SelectorDataList::SelectorDataList(const CSSSelectorList&amp; selectorList)
+{
</ins><span class="cx">     unsigned selectorCount = 0;
</span><span class="cx">     for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(selector))
</span><span class="cx">         selectorCount++;
</span><span class="lines">@@ -46,6 +77,39 @@
</span><span class="cx">     m_selectors.reserveInitialCapacity(selectorCount);
</span><span class="cx">     for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(selector))
</span><span class="cx">         m_selectors.uncheckedAppend(SelectorData(selector, SelectorCheckerFastPath::canUse(selector)));
</span><ins>+
+    if (selectorCount == 1) {
+        const CSSSelector&amp; selector = *m_selectors.first().selector;
+        if (selector.isLastInTagHistory()) {
+            switch (selector.m_match) {
+            case CSSSelector::Tag:
+                m_matchType = TagNameMatch;
+                break;
+            case CSSSelector::Class:
+                m_matchType = ClassNameMatch;
+                break;
+            case CSSSelector::Id:
+                m_matchType = RightMostWithIdMatch;
+                break;
+            default:
+                m_matchType = CompilableSingle;
+                break;
+            }
+        } else {
+            switch (findIdMatchingType(selector)) {
+            case IdMatchingType::None:
+                m_matchType = CompilableSingle;
+                break;
+            case IdMatchingType::Rightmost:
+                m_matchType = RightMostWithIdMatch;
+                break;
+            case IdMatchingType::Filter:
+                m_matchType = CompilableSingleWithRootFilter;
+                break;
+            }
+        }
+    } else
+        m_matchType = MultipleSelectorMatch;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> inline bool SelectorDataList::selectorMatches(const SelectorData&amp; selectorData, Element&amp; element, const ContainerNode&amp; rootNode) const
</span><span class="lines">@@ -157,10 +221,45 @@
</span><span class="cx">         SelectorQueryTrait::appendOutputForElement(output, element);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static bool isSingleTagNameSelector(const CSSSelector&amp; selector)
</del><ins>+#if ENABLE(CSS_SELECTOR_JIT)
+static ContainerNode&amp; filterRootById(ContainerNode&amp; rootNode, const CSSSelector&amp; firstSelector)
</ins><span class="cx"> {
</span><del>-    return selector.isLastInTagHistory() &amp;&amp; selector.m_match == CSSSelector::Tag;
</del><ins>+    if (!rootNode.inDocument())
+        return rootNode;
+    if (rootNode.document().inQuirksMode())
+        return rootNode;
+
+    // If there was an Id match in the rightmost Simple Selector, we should be in a RightMostWithIdMatch, not in filter.
+    // Thus we can skip the rightmost match.
+    const CSSSelector* selector = &amp;firstSelector;
+    do {
+        ASSERT(selector-&gt;m_match != CSSSelector::Id);
+        if (selector-&gt;relation() != CSSSelector::SubSelector)
+            break;
+        selector = selector-&gt;tagHistory();
+    } while (selector);
+
+    bool inAdjacentChain = false;
+    for (; selector; selector = selector-&gt;tagHistory()) {
+        if (selector-&gt;m_match == CSSSelector::Id) {
+            const AtomicString&amp; idToMatch = selector-&gt;value();
+            if (ContainerNode* searchRoot = rootNode.treeScope().getElementById(idToMatch)) {
+                if (LIKELY(!rootNode.treeScope().containsMultipleElementsWithId(idToMatch))) {
+                    if (inAdjacentChain)
+                        searchRoot = searchRoot-&gt;parentNode();
+                    if (searchRoot &amp;&amp; (isTreeScopeRoot(rootNode) || searchRoot == &amp;rootNode || searchRoot-&gt;isDescendantOf(&amp;rootNode)))
+                        return *searchRoot;
+                }
+            }
+        }
+        if (selector-&gt;relation() == CSSSelector::DirectAdjacent || selector-&gt;relation() == CSSSelector::IndirectAdjacent)
+            inAdjacentChain = true;
+        else
+            inAdjacentChain = false;
+    }
+    return rootNode;
</ins><span class="cx"> }
</span><ins>+#endif
</ins><span class="cx"> 
</span><span class="cx"> template &lt;typename SelectorQueryTrait&gt;
</span><span class="cx"> static inline void elementsForLocalName(const ContainerNode&amp; rootNode, const AtomicString&amp; localName, typename SelectorQueryTrait::OutputType&amp; output)
</span><span class="lines">@@ -215,11 +314,6 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static bool isSingleClassNameSelector(const CSSSelector&amp; selector)
-{
-    return selector.isLastInTagHistory() &amp;&amp; selector.m_match == CSSSelector::Class;
-}
-
</del><span class="cx"> template &lt;typename SelectorQueryTrait&gt;
</span><span class="cx"> ALWAYS_INLINE void SelectorDataList::executeSingleClassNameSelectorData(const ContainerNode&amp; rootNode, const SelectorData&amp; selectorData, typename SelectorQueryTrait::OutputType&amp; output) const
</span><span class="cx"> {
</span><span class="lines">@@ -278,59 +372,91 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> }
</span><del>-
-template &lt;typename SelectorQueryTrait&gt;
-ALWAYS_INLINE void SelectorDataList::executeCompiledSelectorCheckerWithContext(const ContainerNode&amp; rootNode, SelectorCompiler::SelectorCheckerWithCheckingContext selectorChecker, const SelectorCompiler::CheckingContext&amp; context, typename SelectorQueryTrait::OutputType&amp; output) const
-{
-    for (auto&amp; element : descendantsOfType&lt;Element&gt;(const_cast&lt;ContainerNode&amp;&gt;(rootNode))) {
-        if (selectorChecker(&amp;element, &amp;context)) {
-            SelectorQueryTrait::appendOutputForElement(output, &amp;element);
-            if (SelectorQueryTrait::shouldOnlyMatchFirstElement)
-                return;
-        }
-    }
-}
</del><span class="cx"> #endif // ENABLE(CSS_SELECTOR_JIT)
</span><span class="cx"> 
</span><span class="cx"> template &lt;typename SelectorQueryTrait&gt;
</span><span class="cx"> ALWAYS_INLINE void SelectorDataList::execute(ContainerNode&amp; rootNode, typename SelectorQueryTrait::OutputType&amp; output) const
</span><span class="cx"> {
</span><del>-    if (m_selectors.size() == 1) {
-        const SelectorData&amp; selectorData = m_selectors[0];
-        if (const CSSSelector* idSelector = selectorForIdLookup(rootNode, *selectorData.selector))
-            executeFastPathForIdSelector&lt;SelectorQueryTrait&gt;(rootNode, selectorData, idSelector, output);
-        else if (isSingleTagNameSelector(*selectorData.selector))
-            executeSingleTagNameSelectorData&lt;SelectorQueryTrait&gt;(rootNode, selectorData, output);
-        else if (isSingleClassNameSelector(*selectorData.selector))
-            executeSingleClassNameSelectorData&lt;SelectorQueryTrait&gt;(rootNode, selectorData, output);
-        else {
</del><ins>+    ContainerNode* searchRootNode = &amp;rootNode;
+    switch (m_matchType) {
+    case RightMostWithIdMatch:
+        if (const CSSSelector* idSelector = selectorForIdLookup(*searchRootNode, *m_selectors.first().selector)) {
+            executeFastPathForIdSelector&lt;SelectorQueryTrait&gt;(*searchRootNode, m_selectors.first(), idSelector, output);
+            break;
+        }
+        FALLTHROUGH;
+    case CompilableSingleWithRootFilter:
+    case CompilableSingle:
+        {
</ins><span class="cx"> #if ENABLE(CSS_SELECTOR_JIT)
</span><del>-            void* compiledSelectorChecker = selectorData.compiledSelectorCodeRef.code().executableAddress();
-            if (!compiledSelectorChecker &amp;&amp; selectorData.compilationStatus == SelectorCompilationStatus::NotCompiled) {
-                JSC::VM* vm = rootNode.document().scriptExecutionContext()-&gt;vm();
-                selectorData.compilationStatus = SelectorCompiler::compileSelector(selectorData.selector, vm, SelectorCompiler::SelectorContext::QuerySelector, selectorData.compiledSelectorCodeRef);
-                RELEASE_ASSERT(selectorData.compilationStatus != SelectorCompilationStatus::SelectorCheckerWithCheckingContext);
-                compiledSelectorChecker = selectorData.compiledSelectorCodeRef.code().executableAddress();
-            }
</del><ins>+        const SelectorData&amp; selectorData = m_selectors.first();
+        ASSERT(m_matchType == RightMostWithIdMatch || selectorData.compilationStatus == SelectorCompilationStatus::NotCompiled);
</ins><span class="cx"> 
</span><del>-            if (compiledSelectorChecker) {
-                SelectorCompiler::SimpleSelectorChecker selectorChecker = SelectorCompiler::simpleSelectorCheckerFunction(compiledSelectorChecker, selectorData.compilationStatus);
-                executeCompiledSimpleSelectorChecker&lt;SelectorQueryTrait&gt;(rootNode, selectorChecker, output);
-                return;
</del><ins>+        JSC::VM* vm = searchRootNode-&gt;document().scriptExecutionContext()-&gt;vm();
+        selectorData.compilationStatus = SelectorCompiler::compileSelector(selectorData.selector, vm, SelectorCompiler::SelectorContext::QuerySelector, selectorData.compiledSelectorCodeRef);
+        RELEASE_ASSERT(selectorData.compilationStatus != SelectorCompilationStatus::SelectorCheckerWithCheckingContext);
+
+        if (selectorData.compilationStatus == SelectorCompilationStatus::SimpleSelectorChecker) {
+            if (m_matchType == CompilableSingle) {
+                m_matchType = CompiledSingle;
+                goto CompiledSingleCase;
</ins><span class="cx">             }
</span><ins>+            if (m_matchType == CompilableSingleWithRootFilter) {
+                m_matchType = CompiledSingleWithRootFilter;
+                goto CompiledSingleWithRootFilterCase;
+            }
+            goto CompiledSingleCase;
+        }
+        if (m_matchType != RightMostWithIdMatch)
+            m_matchType = SingleSelector;
+        goto SingleSelectorCase;
+        ASSERT_NOT_REACHED();
+        break;
+#else
+        FALLTHROUGH;
</ins><span class="cx"> #endif // ENABLE(CSS_SELECTOR_JIT)
</span><del>-
-            executeSingleSelectorData&lt;SelectorQueryTrait&gt;(rootNode, selectorData, output);
</del><span class="cx">         }
</span><del>-        return;
</del><ins>+    case CompiledSingleWithRootFilter:
+#if ENABLE(CSS_SELECTOR_JIT)
+        CompiledSingleWithRootFilterCase:
+        searchRootNode = &amp;filterRootById(*searchRootNode, *m_selectors.first().selector);
+#endif // ENABLE(CSS_SELECTOR_JIT)
+        FALLTHROUGH;
+    case CompiledSingle:
+#if ENABLE(CSS_SELECTOR_JIT)
+        {
+        CompiledSingleCase:
+        const SelectorData&amp; selectorData = m_selectors.first();
+        void* compiledSelectorChecker = selectorData.compiledSelectorCodeRef.code().executableAddress();
+        SelectorCompiler::SimpleSelectorChecker selectorChecker = SelectorCompiler::simpleSelectorCheckerFunction(compiledSelectorChecker, selectorData.compilationStatus);
+        executeCompiledSimpleSelectorChecker&lt;SelectorQueryTrait&gt;(*searchRootNode, selectorChecker, output);
+        break;
+        }
+#else
+        FALLTHROUGH;
+#endif // ENABLE(CSS_SELECTOR_JIT)
+    case SingleSelector:
+#if ENABLE(CSS_SELECTOR_JIT)
+        SingleSelectorCase:
+#endif
+        executeSingleSelectorData&lt;SelectorQueryTrait&gt;(*searchRootNode, m_selectors.first(), output);
+        break;
+    case TagNameMatch:
+        executeSingleTagNameSelectorData&lt;SelectorQueryTrait&gt;(*searchRootNode, m_selectors.first(), output);
+        break;
+    case ClassNameMatch:
+        executeSingleClassNameSelectorData&lt;SelectorQueryTrait&gt;(*searchRootNode, m_selectors.first(), output);
+        break;
+    case MultipleSelectorMatch:
+        executeSingleMultiSelectorData&lt;SelectorQueryTrait&gt;(*searchRootNode, output);
+        break;
</ins><span class="cx">     }
</span><del>-    executeSingleMultiSelectorData&lt;SelectorQueryTrait&gt;(rootNode, output);
</del><span class="cx"> }
</span><span class="cx"> 
</span><del>-SelectorQuery::SelectorQuery(const CSSSelectorList&amp; selectorList)
</del><ins>+SelectorQuery::SelectorQuery(CSSSelectorList&amp;&amp; selectorList)
</ins><span class="cx">     : m_selectorList(selectorList)
</span><ins>+    , m_selectors(m_selectorList)
</ins><span class="cx"> {
</span><del>-    m_selectors.initialize(m_selectorList);
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> SelectorQuery* SelectorQueryCache::add(const String&amp; selectors, Document&amp; document, ExceptionCode&amp; ec)
</span><span class="lines">@@ -358,7 +484,7 @@
</span><span class="cx">     if (m_entries.size() == maximumSelectorQueryCacheSize)
</span><span class="cx">         m_entries.remove(m_entries.begin());
</span><span class="cx">     
</span><del>-    return m_entries.add(selectors, std::make_unique&lt;SelectorQuery&gt;(selectorList)).iterator-&gt;value.get();
</del><ins>+    return m_entries.add(selectors, std::make_unique&lt;SelectorQuery&gt;(std::move(selectorList))).iterator-&gt;value.get();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void SelectorQueryCache::invalidate()
</span></span></pre></div>
<a id="trunkSourceWebCoredomSelectorQueryh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/SelectorQuery.h (164923 => 164924)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/SelectorQuery.h        2014-03-01 19:57:40 UTC (rev 164923)
+++ trunk/Source/WebCore/dom/SelectorQuery.h        2014-03-01 22:09:48 UTC (rev 164924)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -46,21 +46,25 @@
</span><span class="cx"> 
</span><span class="cx"> class SelectorDataList {
</span><span class="cx"> public:
</span><del>-    void initialize(const CSSSelectorList&amp;);
</del><ins>+    explicit SelectorDataList(const CSSSelectorList&amp;);
</ins><span class="cx">     bool matches(Element&amp;) const;
</span><span class="cx">     RefPtr&lt;NodeList&gt; queryAll(ContainerNode&amp; rootNode) const;
</span><span class="cx">     Element* queryFirst(ContainerNode&amp; rootNode) const;
</span><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     struct SelectorData {
</span><del>-        SelectorData(const CSSSelector* selector, bool isFastCheckable) : selector(selector), isFastCheckable(isFastCheckable) { }
</del><ins>+        SelectorData(const CSSSelector* selector, bool isFastCheckable)
+            : selector(selector)
+            , isFastCheckable(isFastCheckable)
+        {
+        }
+
</ins><span class="cx">         const CSSSelector* selector;
</span><del>-        bool isFastCheckable;
-
</del><span class="cx"> #if ENABLE(CSS_SELECTOR_JIT)
</span><ins>+        mutable JSC::MacroAssemblerCodeRef compiledSelectorCodeRef;
</ins><span class="cx">         mutable SelectorCompilationStatus compilationStatus;
</span><del>-        mutable JSC::MacroAssemblerCodeRef compiledSelectorCodeRef;
</del><span class="cx"> #endif // ENABLE(CSS_SELECTOR_JIT)
</span><ins>+        bool isFastCheckable;
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     bool selectorMatches(const SelectorData&amp;, Element&amp;, const ContainerNode&amp; rootNode) const;
</span><span class="lines">@@ -73,10 +77,20 @@
</span><span class="cx">     template &lt;typename SelectorQueryTrait&gt; void executeSingleMultiSelectorData(const ContainerNode&amp; rootNode, typename SelectorQueryTrait::OutputType&amp;) const;
</span><span class="cx"> #if ENABLE(CSS_SELECTOR_JIT)
</span><span class="cx">     template &lt;typename SelectorQueryTrait&gt; void executeCompiledSimpleSelectorChecker(const ContainerNode&amp; rootNode, SelectorCompiler::SimpleSelectorChecker, typename SelectorQueryTrait::OutputType&amp;) const;
</span><del>-    template &lt;typename SelectorQueryTrait&gt; void executeCompiledSelectorCheckerWithContext(const ContainerNode&amp; rootNode, SelectorCompiler::SelectorCheckerWithCheckingContext, const SelectorCompiler::CheckingContext&amp;, typename SelectorQueryTrait::OutputType&amp;) const;
</del><span class="cx"> #endif // ENABLE(CSS_SELECTOR_JIT)
</span><span class="cx"> 
</span><span class="cx">     Vector&lt;SelectorData&gt; m_selectors;
</span><ins>+    mutable enum MatchType {
+        CompilableSingle,
+        CompilableSingleWithRootFilter,
+        CompiledSingle,
+        CompiledSingleWithRootFilter,
+        SingleSelector,
+        RightMostWithIdMatch,
+        TagNameMatch,
+        ClassNameMatch,
+        MultipleSelectorMatch,
+    } m_matchType;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> class SelectorQuery {
</span><span class="lines">@@ -84,14 +98,14 @@
</span><span class="cx">     WTF_MAKE_FAST_ALLOCATED;
</span><span class="cx"> 
</span><span class="cx"> public:
</span><del>-    explicit SelectorQuery(const CSSSelectorList&amp;);
</del><ins>+    explicit SelectorQuery(CSSSelectorList&amp;&amp;);
</ins><span class="cx">     bool matches(Element&amp;) const;
</span><span class="cx">     RefPtr&lt;NodeList&gt; queryAll(ContainerNode&amp; rootNode) const;
</span><span class="cx">     Element* queryFirst(ContainerNode&amp; rootNode) const;
</span><span class="cx"> 
</span><span class="cx"> private:
</span><ins>+    CSSSelectorList m_selectorList;
</ins><span class="cx">     SelectorDataList m_selectors;
</span><del>-    CSSSelectorList m_selectorList;
</del><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> class SelectorQueryCache {
</span></span></pre>
</div>
</div>

</body>
</html>