Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(323)

Unified Diff: third_party/WebKit/Source/core/dom/SelectorQuery.cpp

Issue 2875673006: Allow using SelectorQuery fast paths in quirks mode and disconnected subtrees. (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/dom/SelectorQuery.cpp
diff --git a/third_party/WebKit/Source/core/dom/SelectorQuery.cpp b/third_party/WebKit/Source/core/dom/SelectorQuery.cpp
index 7189c5e43414daa7e93edc04d7cd0ddb73c890f5..dcf0a1694318d24cadaedc8d075fe888f55952be 100644
--- a/third_party/WebKit/Source/core/dom/SelectorQuery.cpp
+++ b/third_party/WebKit/Source/core/dom/SelectorQuery.cpp
@@ -41,11 +41,14 @@
#include "core/dom/shadow/ShadowRoot.h"
#include "platform/wtf/PtrUtil.h"
+// Uncomment to run the SelectorQueryTests for stats in a release build.
+// #define RELEASE_QUERY_STATS
+
namespace blink {
using namespace HTMLNames;
-#if DCHECK_IS_ON()
+#if DCHECK_IS_ON() || defined(RELEASE_QUERY_STATS)
static SelectorQuery::QueryStats& CurrentQueryStats() {
DEFINE_STATIC_LOCAL(SelectorQuery::QueryStats, stats, ());
return stats;
@@ -197,19 +200,6 @@ static void CollectElementsByTagName(
}
}
-inline bool SelectorQuery::CanUseFastQuery(
- const ContainerNode& root_node) const {
- if (uses_deep_combinator_or_shadow_pseudo_)
- return false;
- if (needs_updated_distribution_)
- return false;
- if (root_node.GetDocument().InQuirksMode())
- return false;
- if (!root_node.isConnected())
- return false;
- return selectors_.size() == 1;
-}
-
inline bool AncestorHasClassName(ContainerNode& root_node,
const AtomicString& class_name) {
if (!root_node.IsElementNode())
@@ -387,6 +377,9 @@ template <typename SelectorQueryTrait>
void SelectorQuery::ExecuteWithId(
ContainerNode& root_node,
typename SelectorQueryTrait::OutputType& output) const {
+ DCHECK_EQ(selectors_.size(), 1u);
+ DCHECK(!root_node.GetDocument().InQuirksMode());
+
const CSSSelector& first_selector = *selectors_[0];
const TreeScope& scope = root_node.ContainingTreeScope();
@@ -440,7 +433,7 @@ void SelectorQuery::Execute(
if (selectors_.IsEmpty())
return;
- if (!CanUseFastQuery(root_node)) {
+ if (use_slow_scan_) {
if (needs_updated_distribution_)
root_node.UpdateDistribution();
if (uses_deep_combinator_or_shadow_pseudo_) {
@@ -452,9 +445,15 @@ void SelectorQuery::Execute(
}
DCHECK_EQ(selectors_.size(), 1u);
- DCHECK(!root_node.GetDocument().InQuirksMode());
-
- if (selector_id_) {
+ DCHECK(!needs_updated_distribution_);
+ DCHECK(!uses_deep_combinator_or_shadow_pseudo_);
+
+ // In quirks mode getElementById("a") is case sensitive and should only
+ // match elements with lowercase id "a", but querySelector is case-insensitive
+ // so querySelector("#a") == querySelector("#A"), which means we can only use
+ // the id fast path when we're in a standards mode document.
+ if (selector_id_ && root_node.IsInTreeScope() &&
+ !root_node.GetDocument().InQuirksMode()) {
ExecuteWithId<SelectorQueryTrait>(root_node, output);
return;
}
@@ -496,7 +495,8 @@ SelectorQuery::SelectorQuery(CSSSelectorList selector_list)
selector_id_is_rightmost_(true),
selector_id_affected_by_sibling_combinator_(false),
uses_deep_combinator_or_shadow_pseudo_(false),
- needs_updated_distribution_(false) {
+ needs_updated_distribution_(false),
+ use_slow_scan_(true) {
selectors_.ReserveInitialCapacity(selector_list_.ComputeLength());
for (const CSSSelector* selector = selector_list_.First(); selector;
selector = CSSSelectorList::Next(*selector)) {
@@ -510,6 +510,7 @@ SelectorQuery::SelectorQuery(CSSSelectorList selector_list)
if (selectors_.size() == 1 && !uses_deep_combinator_or_shadow_pseudo_ &&
!needs_updated_distribution_) {
+ use_slow_scan_ = false;
for (const CSSSelector* current = selectors_[0]; current;
current = current->TagHistory()) {
if (current->Match() == CSSSelector::kId) {
« no previous file with comments | « third_party/WebKit/Source/core/dom/SelectorQuery.h ('k') | third_party/WebKit/Source/core/dom/SelectorQueryTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698