Diff
Modified: trunk/LayoutTests/ChangeLog (203438 => 203439)
--- trunk/LayoutTests/ChangeLog 2016-07-20 01:27:24 UTC (rev 203438)
+++ trunk/LayoutTests/ChangeLog 2016-07-20 01:29:25 UTC (rev 203439)
@@ -1,3 +1,15 @@
+2016-07-19 Benjamin Poulain <[email protected]>
+
+ Use getElementById for attribute matching if the attribute name is html's id
+ https://bugs.webkit.org/show_bug.cgi?id=159960
+
+ Reviewed by Chris Dumez.
+
+ * fast/selectors/id-attribute-querySelector-used-as-id-selector-expected.txt: Added.
+ * fast/selectors/id-attribute-querySelector-used-as-id-selector-quirks-expected.txt: Added.
+ * fast/selectors/id-attribute-querySelector-used-as-id-selector-quirks.html: Added.
+ * fast/selectors/id-attribute-querySelector-used-as-id-selector.html: Added.
+
2016-07-19 Chris Dumez <[email protected]>
Drop SVGElement.xmlbase attribute
Added: trunk/LayoutTests/fast/selectors/id-attribute-querySelector-used-as-id-selector-expected.txt (0 => 203439)
--- trunk/LayoutTests/fast/selectors/id-attribute-querySelector-used-as-id-selector-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/selectors/id-attribute-querySelector-used-as-id-selector-expected.txt 2016-07-20 01:29:25 UTC (rev 203439)
@@ -0,0 +1,57 @@
+Verify the optimization transforming [id=value] into #value for querySelector.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Trivial Selector used as rightmost
+PASS document.querySelectorAll("[id=simple_unique]").length is 1
+PASS document.querySelectorAll("[id=simple_Duplicated]").length is 3
+PASS document.querySelectorAll("[id=simple_duplicated]").length is 0
+Non-Trivial Selector used as rightmost
+PASS document.querySelectorAll("div[id=simple_unique][data-case]").length is 1
+PASS document.querySelectorAll("div[id=simple_Duplicated][data-case]").length is 3
+PASS document.querySelectorAll("div[id=simple_duplicated][data-case]").length is 0
+Trivial Selector used as ancestor filter
+PASS document.querySelectorAll("[id=Ancestor_Unique] >> *").length is 4
+PASS document.querySelectorAll("[id=Ancestor_Unique] > * >> *").length is 2
+PASS document.querySelectorAll("[id=Ancestor_Unique] >> * > *").length is 2
+PASS document.querySelectorAll("[id=ancestor_unique] >> *").length is 0
+PASS document.querySelectorAll("[id=ancestor_unique] > * >> *").length is 0
+PASS document.querySelectorAll("[id=ancestor_unique] >> * > *").length is 0
+PASS document.querySelectorAll("[id=ANCESTOR_DUPLICATED] >> *").length is 5
+PASS document.querySelectorAll("[id=ANCESTOR_DUPLICATED] > * >> *").length is 2
+PASS document.querySelectorAll("[id=ANCESTOR_DUPLICATED] >> * > *").length is 2
+PASS document.querySelectorAll("[id=ancestor_duplicated] >> *").length is 0
+PASS document.querySelectorAll("[id=ancestor_duplicated] > * >> *").length is 0
+PASS document.querySelectorAll("[id=ancestor_duplicated] >> * > *").length is 0
+Non-Trivial Selector used as ancestor filter
+PASS document.querySelectorAll("div[id=Ancestor_Unique][data-case] >> *").length is 4
+PASS document.querySelectorAll("div[id=Ancestor_Unique][data-case] > * >> *").length is 2
+PASS document.querySelectorAll("div[id=Ancestor_Unique][data-case] >> * > *").length is 2
+PASS document.querySelectorAll("div[id=ancestor_unique][data-case] >> *").length is 0
+PASS document.querySelectorAll("div[id=ancestor_unique][data-case] > * >> *").length is 0
+PASS document.querySelectorAll("div[id=ancestor_unique][data-case] >> * > *").length is 0
+PASS document.querySelectorAll("div[id=ANCESTOR_DUPLICATED][data-case] >> *").length is 5
+PASS document.querySelectorAll("div[id=ANCESTOR_DUPLICATED][data-case] > * >> *").length is 2
+PASS document.querySelectorAll("div[id=ANCESTOR_DUPLICATED][data-case] >> * > *").length is 2
+PASS document.querySelectorAll("div[id=ancestor_duplicated][data-case] >> *").length is 0
+PASS document.querySelectorAll("div[id=ancestor_duplicated][data-case] > * >> *").length is 0
+PASS document.querySelectorAll("div[id=ancestor_duplicated][data-case] >> * > *").length is 0
+Trivial Selector used as sibling filter
+PASS document.querySelectorAll("[id=simple_unique] + *").length is 1
+PASS document.querySelectorAll("[id=simple_unique] ~ *").length is 5
+PASS document.querySelectorAll("[id=simple_Duplicated] + *").length is 3
+PASS document.querySelectorAll("[id=simple_Duplicated] ~ *").length is 4
+PASS document.querySelectorAll("[id=simple_duplicated] + *").length is 0
+PASS document.querySelectorAll("[id=simple_duplicated] ~ *").length is 0
+Trivial Selector used as sibling of ancestor filter
+PASS document.querySelectorAll("[id=simple_unique] + * > *").length is 0
+PASS document.querySelectorAll("[id=simple_unique] ~ * > *").length is 4
+PASS document.querySelectorAll("[id=simple_Duplicated] + * > *").length is 2
+PASS document.querySelectorAll("[id=simple_Duplicated] ~ * > *").length is 4
+PASS document.querySelectorAll("[id=simple_duplicated] + * > *").length is 0
+PASS document.querySelectorAll("[id=simple_duplicated] ~ * > *").length is 0
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/selectors/id-attribute-querySelector-used-as-id-selector-quirks-expected.txt (0 => 203439)
--- trunk/LayoutTests/fast/selectors/id-attribute-querySelector-used-as-id-selector-quirks-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/selectors/id-attribute-querySelector-used-as-id-selector-quirks-expected.txt 2016-07-20 01:29:25 UTC (rev 203439)
@@ -0,0 +1,57 @@
+Verify the optimization transforming [id=value] into #value for querySelector.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Trivial Selector used as rightmost
+PASS document.querySelectorAll("[id=simple_unique]").length is 1
+PASS document.querySelectorAll("[id=simple_Duplicated]").length is 3
+PASS document.querySelectorAll("[id=simple_duplicated]").length is 0
+Non-Trivial Selector used as rightmost
+PASS document.querySelectorAll("div[id=simple_unique][data-case]").length is 1
+PASS document.querySelectorAll("div[id=simple_Duplicated][data-case]").length is 3
+PASS document.querySelectorAll("div[id=simple_duplicated][data-case]").length is 0
+Trivial Selector used as ancestor filter
+PASS document.querySelectorAll("[id=Ancestor_Unique] >> *").length is 4
+PASS document.querySelectorAll("[id=Ancestor_Unique] > * >> *").length is 2
+PASS document.querySelectorAll("[id=Ancestor_Unique] >> * > *").length is 2
+PASS document.querySelectorAll("[id=ancestor_unique] >> *").length is 0
+PASS document.querySelectorAll("[id=ancestor_unique] > * >> *").length is 0
+PASS document.querySelectorAll("[id=ancestor_unique] >> * > *").length is 0
+PASS document.querySelectorAll("[id=ANCESTOR_DUPLICATED] >> *").length is 5
+PASS document.querySelectorAll("[id=ANCESTOR_DUPLICATED] > * >> *").length is 2
+PASS document.querySelectorAll("[id=ANCESTOR_DUPLICATED] >> * > *").length is 2
+PASS document.querySelectorAll("[id=ancestor_duplicated] >> *").length is 0
+PASS document.querySelectorAll("[id=ancestor_duplicated] > * >> *").length is 0
+PASS document.querySelectorAll("[id=ancestor_duplicated] >> * > *").length is 0
+Non-Trivial Selector used as ancestor filter
+PASS document.querySelectorAll("div[id=Ancestor_Unique][data-case] >> *").length is 4
+PASS document.querySelectorAll("div[id=Ancestor_Unique][data-case] > * >> *").length is 2
+PASS document.querySelectorAll("div[id=Ancestor_Unique][data-case] >> * > *").length is 2
+PASS document.querySelectorAll("div[id=ancestor_unique][data-case] >> *").length is 0
+PASS document.querySelectorAll("div[id=ancestor_unique][data-case] > * >> *").length is 0
+PASS document.querySelectorAll("div[id=ancestor_unique][data-case] >> * > *").length is 0
+PASS document.querySelectorAll("div[id=ANCESTOR_DUPLICATED][data-case] >> *").length is 5
+PASS document.querySelectorAll("div[id=ANCESTOR_DUPLICATED][data-case] > * >> *").length is 2
+PASS document.querySelectorAll("div[id=ANCESTOR_DUPLICATED][data-case] >> * > *").length is 2
+PASS document.querySelectorAll("div[id=ancestor_duplicated][data-case] >> *").length is 0
+PASS document.querySelectorAll("div[id=ancestor_duplicated][data-case] > * >> *").length is 0
+PASS document.querySelectorAll("div[id=ancestor_duplicated][data-case] >> * > *").length is 0
+Trivial Selector used as sibling filter
+PASS document.querySelectorAll("[id=simple_unique] + *").length is 1
+PASS document.querySelectorAll("[id=simple_unique] ~ *").length is 5
+PASS document.querySelectorAll("[id=simple_Duplicated] + *").length is 3
+PASS document.querySelectorAll("[id=simple_Duplicated] ~ *").length is 4
+PASS document.querySelectorAll("[id=simple_duplicated] + *").length is 0
+PASS document.querySelectorAll("[id=simple_duplicated] ~ *").length is 0
+Trivial Selector used as sibling of ancestor filter
+PASS document.querySelectorAll("[id=simple_unique] + * > *").length is 0
+PASS document.querySelectorAll("[id=simple_unique] ~ * > *").length is 4
+PASS document.querySelectorAll("[id=simple_Duplicated] + * > *").length is 2
+PASS document.querySelectorAll("[id=simple_Duplicated] ~ * > *").length is 4
+PASS document.querySelectorAll("[id=simple_duplicated] + * > *").length is 0
+PASS document.querySelectorAll("[id=simple_duplicated] ~ * > *").length is 0
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/selectors/id-attribute-querySelector-used-as-id-selector-quirks.html (0 => 203439)
--- trunk/LayoutTests/fast/selectors/id-attribute-querySelector-used-as-id-selector-quirks.html (rev 0)
+++ trunk/LayoutTests/fast/selectors/id-attribute-querySelector-used-as-id-selector-quirks.html 2016-07-20 01:29:25 UTC (rev 203439)
@@ -0,0 +1,101 @@
+<html>
+ <head>
+ <script src=""
+ </head>
+ <body>
+ <div class="display:none;">
+ <div id="simple_unique" data-case="1"></div>
+ <div id="simple_Duplicated" data-case="2"></div>
+ <div id="simple_Duplicated" data-case="3"></div>
+ <div id="simple_Duplicated" data-case="4"></div>
+
+ <div id="Ancestor_Unique" data-case="5">
+ <div data-case="6">
+ <div data-case="7">
+ </div>
+ </div>
+ <div id="ANCESTOR_DUPLICATED" data-case="8">
+ <div data-case="9">
+ </div>
+ </div>
+ </div>
+ <div id="ANCESTOR_DUPLICATED" data-case="10">
+ <div data-case="11">
+ <div data-case="12">
+ </div>
+ </div>
+ <div id="ANCESTOR_DUPLICATED" data-case="13">
+ <div data-case="14">
+ </div>
+ </div>
+ </div>
+ </div>
+ <script>
+ description("Verify the optimization transforming [id=value] into #value for querySelector.");
+
+ function test(selector, expectedCases)
+ {
+ shouldBe('document.querySelectorAll("' + selector + '").length', '' + expectedCases.length);
+ /*let queryResult = document.querySelectorAll(selector);
+ for (let i = 0; i < queryResult.length; ++i) {
+ shouldBeEqualToString('document.querySelectorAll("' + selector + '")[' + i + '].dataset.case', '' + expectedCases[i]);
+ }*/
+ }
+
+ debug("Trivial Selector used as rightmost");
+ test("[id=simple_unique]", [1]);
+ test("[id=simple_Duplicated]", [2, 3, 4]);
+ test("[id=simple_duplicated]", []);
+
+ debug("Non-Trivial Selector used as rightmost");
+ test("div[id=simple_unique][data-case]", [1]);
+ test("div[id=simple_Duplicated][data-case]", [2, 3, 4]);
+ test("div[id=simple_duplicated][data-case]", []);
+
+ debug("Trivial Selector used as ancestor filter");
+ test("[id=Ancestor_Unique] >> *", [6, 7, 8, 9]);
+ test("[id=Ancestor_Unique] > * >> *", [7, 9]);
+ test("[id=Ancestor_Unique] >> * > *", [7, 9]);
+ test("[id=ancestor_unique] >> *", []);
+ test("[id=ancestor_unique] > * >> *", []);
+ test("[id=ancestor_unique] >> * > *", []);
+ test("[id=ANCESTOR_DUPLICATED] >> *", [9, 11, 12, 13, 14]);
+ test("[id=ANCESTOR_DUPLICATED] > * >> *", [12, 14]);
+ test("[id=ANCESTOR_DUPLICATED] >> * > *", [12, 14]);
+ test("[id=ancestor_duplicated] >> *", []);
+ test("[id=ancestor_duplicated] > * >> *", []);
+ test("[id=ancestor_duplicated] >> * > *", []);
+
+ debug("Non-Trivial Selector used as ancestor filter");
+ test("div[id=Ancestor_Unique][data-case] >> *", [6, 7, 8, 9]);
+ test("div[id=Ancestor_Unique][data-case] > * >> *", [7, 9]);
+ test("div[id=Ancestor_Unique][data-case] >> * > *", [7, 9]);
+ test("div[id=ancestor_unique][data-case] >> *", []);
+ test("div[id=ancestor_unique][data-case] > * >> *", []);
+ test("div[id=ancestor_unique][data-case] >> * > *", []);
+ test("div[id=ANCESTOR_DUPLICATED][data-case] >> *", [9, 11, 12, 13, 14]);
+ test("div[id=ANCESTOR_DUPLICATED][data-case] > * >> *", [12, 14]);
+ test("div[id=ANCESTOR_DUPLICATED][data-case] >> * > *", [12, 14]);
+ test("div[id=ancestor_duplicated][data-case] >> *", []);
+ test("div[id=ancestor_duplicated][data-case] > * >> *", []);
+ test("div[id=ancestor_duplicated][data-case] >> * > *", []);
+
+ debug("Trivial Selector used as sibling filter");
+ test("[id=simple_unique] + *", [2]);
+ test("[id=simple_unique] ~ *", [2, 3, 4, 5, 10]);
+ test("[id=simple_Duplicated] + *", [3, 4, 5]);
+ test("[id=simple_Duplicated] ~ *", [3, 4, 5, 10]);
+ test("[id=simple_duplicated] + *", []);
+ test("[id=simple_duplicated] ~ *", []);
+
+ debug("Trivial Selector used as sibling of ancestor filter");
+ test("[id=simple_unique] + * > *", []);
+ test("[id=simple_unique] ~ * > *", [6, 8, 11, 13]);
+ test("[id=simple_Duplicated] + * > *", [6, 8]);
+ test("[id=simple_Duplicated] ~ * > *", [6, 8, 11, 13]);
+ test("[id=simple_duplicated] + * > *", []);
+ test("[id=simple_duplicated] ~ * > *", []);
+ </script>
+ <script src=""
+ </body>
+</html>
Added: trunk/LayoutTests/fast/selectors/id-attribute-querySelector-used-as-id-selector.html (0 => 203439)
--- trunk/LayoutTests/fast/selectors/id-attribute-querySelector-used-as-id-selector.html (rev 0)
+++ trunk/LayoutTests/fast/selectors/id-attribute-querySelector-used-as-id-selector.html 2016-07-20 01:29:25 UTC (rev 203439)
@@ -0,0 +1,102 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <script src=""
+ </head>
+ <body>
+ <div class="display:none;">
+ <div id="simple_unique" data-case="1"></div>
+ <div id="simple_Duplicated" data-case="2"></div>
+ <div id="simple_Duplicated" data-case="3"></div>
+ <div id="simple_Duplicated" data-case="4"></div>
+
+ <div id="Ancestor_Unique" data-case="5">
+ <div data-case="6">
+ <div data-case="7">
+ </div>
+ </div>
+ <div id="ANCESTOR_DUPLICATED" data-case="8">
+ <div data-case="9">
+ </div>
+ </div>
+ </div>
+ <div id="ANCESTOR_DUPLICATED" data-case="10">
+ <div data-case="11">
+ <div data-case="12">
+ </div>
+ </div>
+ <div id="ANCESTOR_DUPLICATED" data-case="13">
+ <div data-case="14">
+ </div>
+ </div>
+ </div>
+ </div>
+ <script>
+ description("Verify the optimization transforming [id=value] into #value for querySelector.");
+
+ function test(selector, expectedCases)
+ {
+ shouldBe('document.querySelectorAll("' + selector + '").length', '' + expectedCases.length);
+ /*let queryResult = document.querySelectorAll(selector);
+ for (let i = 0; i < queryResult.length; ++i) {
+ shouldBeEqualToString('document.querySelectorAll("' + selector + '")[' + i + '].dataset.case', '' + expectedCases[i]);
+ }*/
+ }
+
+ debug("Trivial Selector used as rightmost");
+ test("[id=simple_unique]", [1]);
+ test("[id=simple_Duplicated]", [2, 3, 4]);
+ test("[id=simple_duplicated]", []);
+
+ debug("Non-Trivial Selector used as rightmost");
+ test("div[id=simple_unique][data-case]", [1]);
+ test("div[id=simple_Duplicated][data-case]", [2, 3, 4]);
+ test("div[id=simple_duplicated][data-case]", []);
+
+ debug("Trivial Selector used as ancestor filter");
+ test("[id=Ancestor_Unique] >> *", [6, 7, 8, 9]);
+ test("[id=Ancestor_Unique] > * >> *", [7, 9]);
+ test("[id=Ancestor_Unique] >> * > *", [7, 9]);
+ test("[id=ancestor_unique] >> *", []);
+ test("[id=ancestor_unique] > * >> *", []);
+ test("[id=ancestor_unique] >> * > *", []);
+ test("[id=ANCESTOR_DUPLICATED] >> *", [9, 11, 12, 13, 14]);
+ test("[id=ANCESTOR_DUPLICATED] > * >> *", [12, 14]);
+ test("[id=ANCESTOR_DUPLICATED] >> * > *", [12, 14]);
+ test("[id=ancestor_duplicated] >> *", []);
+ test("[id=ancestor_duplicated] > * >> *", []);
+ test("[id=ancestor_duplicated] >> * > *", []);
+
+ debug("Non-Trivial Selector used as ancestor filter");
+ test("div[id=Ancestor_Unique][data-case] >> *", [6, 7, 8, 9]);
+ test("div[id=Ancestor_Unique][data-case] > * >> *", [7, 9]);
+ test("div[id=Ancestor_Unique][data-case] >> * > *", [7, 9]);
+ test("div[id=ancestor_unique][data-case] >> *", []);
+ test("div[id=ancestor_unique][data-case] > * >> *", []);
+ test("div[id=ancestor_unique][data-case] >> * > *", []);
+ test("div[id=ANCESTOR_DUPLICATED][data-case] >> *", [9, 11, 12, 13, 14]);
+ test("div[id=ANCESTOR_DUPLICATED][data-case] > * >> *", [12, 14]);
+ test("div[id=ANCESTOR_DUPLICATED][data-case] >> * > *", [12, 14]);
+ test("div[id=ancestor_duplicated][data-case] >> *", []);
+ test("div[id=ancestor_duplicated][data-case] > * >> *", []);
+ test("div[id=ancestor_duplicated][data-case] >> * > *", []);
+
+ debug("Trivial Selector used as sibling filter");
+ test("[id=simple_unique] + *", [2]);
+ test("[id=simple_unique] ~ *", [2, 3, 4, 5, 10]);
+ test("[id=simple_Duplicated] + *", [3, 4, 5]);
+ test("[id=simple_Duplicated] ~ *", [3, 4, 5, 10]);
+ test("[id=simple_duplicated] + *", []);
+ test("[id=simple_duplicated] ~ *", []);
+
+ debug("Trivial Selector used as sibling of ancestor filter");
+ test("[id=simple_unique] + * > *", []);
+ test("[id=simple_unique] ~ * > *", [6, 8, 11, 13]);
+ test("[id=simple_Duplicated] + * > *", [6, 8]);
+ test("[id=simple_Duplicated] ~ * > *", [6, 8, 11, 13]);
+ test("[id=simple_duplicated] + * > *", []);
+ test("[id=simple_duplicated] ~ * > *", []);
+ </script>
+ <script src=""
+ </body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (203438 => 203439)
--- trunk/Source/WebCore/ChangeLog 2016-07-20 01:27:24 UTC (rev 203438)
+++ trunk/Source/WebCore/ChangeLog 2016-07-20 01:29:25 UTC (rev 203439)
@@ -1,3 +1,26 @@
+2016-07-19 Benjamin Poulain <[email protected]>
+
+ Use getElementById for attribute matching if the attribute name is html's id
+ https://bugs.webkit.org/show_bug.cgi?id=159960
+
+ Reviewed by Chris Dumez.
+
+ Elliott Sprehn discovered YUI makes heavy uses of querySelector with [id=value]
+ (https://bugs.chromium.org/p/chromium/issues/detail?id=627242).
+
+ If we are not in quirks mode, IdForStyleResolution has the same value
+ as the Id attribute. We can use the same optimization for both cases.
+
+ Tests: fast/selectors/id-attribute-querySelector-used-as-id-selector-quirks.html
+ fast/selectors/id-attribute-querySelector-used-as-id-selector.html
+
+ * dom/SelectorQuery.cpp:
+ (WebCore::canBeUsedForIdFastPath):
+ (WebCore::findIdMatchingType):
+ (WebCore::SelectorDataList::SelectorDataList):
+ (WebCore::selectorForIdLookup):
+ (WebCore::filterRootById):
+
2016-07-19 Chris Dumez <[email protected]>
Drop SVGElement.xmlbase attribute
Modified: trunk/Source/WebCore/dom/SelectorQuery.cpp (203438 => 203439)
--- trunk/Source/WebCore/dom/SelectorQuery.cpp 2016-07-20 01:27:24 UTC (rev 203438)
+++ trunk/Source/WebCore/dom/SelectorQuery.cpp 2016-07-20 01:29:25 UTC (rev 203439)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013, 2014, 2016 Apple Inc. All rights reserved.
* Copyright (C) 2014 Yusuke Suzuki <[email protected]>
*
* Redistribution and use in source and binary forms, with or without
@@ -29,6 +29,7 @@
#include "CSSParser.h"
#include "ElementDescendantIterator.h"
+#include "HTMLNames.h"
#include "SelectorChecker.h"
#include "StaticNodeList.h"
#include "StyledElement.h"
@@ -53,11 +54,17 @@
Filter
};
+static bool canBeUsedForIdFastPath(const CSSSelector& selector)
+{
+ return selector.match() == CSSSelector::Id
+ || (selector.match() == CSSSelector::Exact && selector.attribute() == HTMLNames::idAttr && !selector.attributeValueMatchingIsCaseInsensitive());
+}
+
static IdMatchingType findIdMatchingType(const CSSSelector& firstSelector)
{
bool inRightmost = true;
for (const CSSSelector* selector = &firstSelector; selector; selector = selector->tagHistory()) {
- if (selector->match() == CSSSelector::Id) {
+ if (canBeUsedForIdFastPath(*selector)) {
if (inRightmost)
return IdMatchingType::Rightmost;
return IdMatchingType::Filter;
@@ -88,11 +95,11 @@
case CSSSelector::Class:
m_matchType = ClassNameMatch;
break;
- case CSSSelector::Id:
- m_matchType = RightMostWithIdMatch;
- break;
default:
- m_matchType = CompilableSingle;
+ if (canBeUsedForIdFastPath(selector))
+ m_matchType = RightMostWithIdMatch;
+ else
+ m_matchType = CompilableSingle;
break;
}
} else {
@@ -194,7 +201,7 @@
return nullptr;
for (const CSSSelector* selector = &firstSelector; selector; selector = selector->tagHistory()) {
- if (selector->match() == CSSSelector::Id)
+ if (canBeUsedForIdFastPath(*selector))
return selector;
if (selector->relation() != CSSSelector::SubSelector)
break;
@@ -247,7 +254,7 @@
// Thus we can skip the rightmost match.
const CSSSelector* selector = &firstSelector;
do {
- ASSERT(selector->match() != CSSSelector::Id);
+ ASSERT(!canBeUsedForIdFastPath(*selector));
if (selector->relation() != CSSSelector::SubSelector)
break;
selector = selector->tagHistory();
@@ -255,7 +262,7 @@
bool inAdjacentChain = false;
for (; selector; selector = selector->tagHistory()) {
- if (selector->match() == CSSSelector::Id) {
+ if (canBeUsedForIdFastPath(*selector)) {
const AtomicString& idToMatch = selector->value();
if (ContainerNode* searchRoot = rootNode.treeScope().getElementById(idToMatch)) {
if (LIKELY(!rootNode.treeScope().containsMultipleElementsWithId(idToMatch))) {