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

Side by Side Diff: Source/core/dom/SelectorQuery.cpp

Issue 1153873004: Handle ::content and :host-context correctly in SelectorQuery. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: fix test naming. Created 5 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2011, 2013 Apple Inc. All rights reserved. 2 * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
3 * Copyright (C) 2014 Samsung Electronics. All rights reserved. 3 * Copyright (C) 2014 Samsung Electronics. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 8 *
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 100
101 void SelectorDataList::initialize(const CSSSelectorList& selectorList) 101 void SelectorDataList::initialize(const CSSSelectorList& selectorList)
102 { 102 {
103 ASSERT(m_selectors.isEmpty()); 103 ASSERT(m_selectors.isEmpty());
104 104
105 unsigned selectorCount = 0; 105 unsigned selectorCount = 0;
106 for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(*selector)) 106 for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(*selector))
107 selectorCount++; 107 selectorCount++;
108 108
109 m_crossesTreeBoundary = false; 109 m_crossesTreeBoundary = false;
110 m_needsUpdatedDistribution = false;
110 m_selectors.reserveInitialCapacity(selectorCount); 111 m_selectors.reserveInitialCapacity(selectorCount);
111 unsigned index = 0; 112 unsigned index = 0;
112 for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(*selector), ++index) { 113 for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(*selector), ++index) {
113 m_selectors.uncheckedAppend(selector); 114 m_selectors.uncheckedAppend(selector);
114 m_crossesTreeBoundary |= selectorList.selectorCrossesTreeScopes(index); 115 m_crossesTreeBoundary |= selectorList.selectorCrossesTreeScopes(index);
116 m_needsUpdatedDistribution |= selectorList.selectorNeedsUpdatedDistribut ion(index);
115 } 117 }
116 } 118 }
117 119
118 inline bool SelectorDataList::selectorMatches(const CSSSelector& selector, Eleme nt& element, const ContainerNode& rootNode) const 120 inline bool SelectorDataList::selectorMatches(const CSSSelector& selector, Eleme nt& element, const ContainerNode& rootNode) const
119 { 121 {
120 SelectorChecker selectorChecker(SelectorChecker::QueryingRules); 122 SelectorChecker selectorChecker(SelectorChecker::QueryingRules);
121 SelectorChecker::SelectorCheckingContext selectorCheckingContext(&element, S electorChecker::VisitedMatchDisabled); 123 SelectorChecker::SelectorCheckingContext selectorCheckingContext(&element, S electorChecker::VisitedMatchDisabled);
122 selectorCheckingContext.selector = &selector; 124 selectorCheckingContext.selector = &selector;
123 selectorCheckingContext.scope = !rootNode.isDocumentNode() ? &rootNode : 0; 125 selectorCheckingContext.scope = !rootNode.isDocumentNode() ? &rootNode : 0;
124 if (selectorCheckingContext.scope) 126 if (selectorCheckingContext.scope)
125 selectorCheckingContext.scopeContainsLastMatchedElement = true; 127 selectorCheckingContext.scopeContainsLastMatchedElement = true;
126 return selectorChecker.match(selectorCheckingContext); 128 return selectorChecker.match(selectorCheckingContext);
127 } 129 }
128 130
129 bool SelectorDataList::matches(Element& targetElement) const 131 bool SelectorDataList::matches(Element& targetElement) const
130 { 132 {
133 if (m_needsUpdatedDistribution)
134 targetElement.updateDistribution();
135
131 unsigned selectorCount = m_selectors.size(); 136 unsigned selectorCount = m_selectors.size();
132 for (unsigned i = 0; i < selectorCount; ++i) { 137 for (unsigned i = 0; i < selectorCount; ++i) {
133 if (selectorMatches(*m_selectors[i], targetElement, targetElement)) 138 if (selectorMatches(*m_selectors[i], targetElement, targetElement))
134 return true; 139 return true;
135 } 140 }
136 141
137 return false; 142 return false;
138 } 143 }
139 144
140 Element* SelectorDataList::closest(Element& targetElement) const 145 Element* SelectorDataList::closest(Element& targetElement) const
141 { 146 {
147 if (m_needsUpdatedDistribution)
148 targetElement.updateDistribution();
149
142 unsigned selectorCount = m_selectors.size(); 150 unsigned selectorCount = m_selectors.size();
143 for (Element* currentElement = &targetElement; currentElement; currentElemen t = currentElement->parentElement()) { 151 for (Element* currentElement = &targetElement; currentElement; currentElemen t = currentElement->parentElement()) {
144 for (unsigned i = 0; i < selectorCount; ++i) { 152 for (unsigned i = 0; i < selectorCount; ++i) {
145 if (selectorMatches(*m_selectors[i], *currentElement, targetElement) ) 153 if (selectorMatches(*m_selectors[i], *currentElement, targetElement) )
146 return currentElement; 154 return currentElement;
147 } 155 }
148 } 156 }
149 return nullptr; 157 return nullptr;
150 } 158 }
151 159
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
200 if (matchesTagName(tagName, element)) { 208 if (matchesTagName(tagName, element)) {
201 SelectorQueryTrait::appendElement(output, element); 209 SelectorQueryTrait::appendElement(output, element);
202 if (SelectorQueryTrait::shouldOnlyMatchFirstElement) 210 if (SelectorQueryTrait::shouldOnlyMatchFirstElement)
203 return; 211 return;
204 } 212 }
205 } 213 }
206 } 214 }
207 215
208 inline bool SelectorDataList::canUseFastQuery(const ContainerNode& rootNode) con st 216 inline bool SelectorDataList::canUseFastQuery(const ContainerNode& rootNode) con st
209 { 217 {
210 return m_selectors.size() == 1 && !m_crossesTreeBoundary && rootNode.inDocum ent() && !rootNode.document().inQuirksMode(); 218 if (m_crossesTreeBoundary)
219 return false;
220 if (m_needsUpdatedDistribution)
221 return false;
222 if (rootNode.document().inQuirksMode())
223 return false;
224 if (!rootNode.inDocument())
225 return false;
226 return m_selectors.size() == 1;
211 } 227 }
212 228
213 inline bool ancestorHasClassName(ContainerNode& rootNode, const AtomicString& cl assName) 229 inline bool ancestorHasClassName(ContainerNode& rootNode, const AtomicString& cl assName)
214 { 230 {
215 if (!rootNode.isElementNode()) 231 if (!rootNode.isElementNode())
216 return false; 232 return false;
217 233
218 for (Element* element = &toElement(rootNode); element; element = element->pa rentElement()) { 234 for (Element* element = &toElement(rootNode); element; element = element->pa rentElement()) {
219 if (element->hasClass() && element->classNames().contains(className)) 235 if (element->hasClass() && element->classNames().contains(className))
220 return true; 236 return true;
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 if (selector->relation() != CSSSelector::SubSelector) 448 if (selector->relation() != CSSSelector::SubSelector)
433 break; 449 break;
434 } 450 }
435 return 0; 451 return 0;
436 } 452 }
437 453
438 template <typename SelectorQueryTrait> 454 template <typename SelectorQueryTrait>
439 void SelectorDataList::execute(ContainerNode& rootNode, typename SelectorQueryTr ait::OutputType& output) const 455 void SelectorDataList::execute(ContainerNode& rootNode, typename SelectorQueryTr ait::OutputType& output) const
440 { 456 {
441 if (!canUseFastQuery(rootNode)) { 457 if (!canUseFastQuery(rootNode)) {
458 if (m_needsUpdatedDistribution)
459 rootNode.updateDistribution();
442 if (m_crossesTreeBoundary) { 460 if (m_crossesTreeBoundary) {
443 rootNode.updateDistribution();
444 executeSlowTraversingShadowTree<SelectorQueryTrait>(rootNode, output ); 461 executeSlowTraversingShadowTree<SelectorQueryTrait>(rootNode, output );
445 } else { 462 } else {
446 executeSlow<SelectorQueryTrait>(rootNode, output); 463 executeSlow<SelectorQueryTrait>(rootNode, output);
447 } 464 }
448 return; 465 return;
449 } 466 }
450 467
451 ASSERT(m_selectors.size() == 1); 468 ASSERT(m_selectors.size() == 1);
452 469
453 const CSSSelector& selector = *m_selectors[0]; 470 const CSSSelector& selector = *m_selectors[0];
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
553 570
554 return m_entries.add(selectors, SelectorQuery::adopt(selectorList)).storedVa lue->value.get(); 571 return m_entries.add(selectors, SelectorQuery::adopt(selectorList)).storedVa lue->value.get();
555 } 572 }
556 573
557 void SelectorQueryCache::invalidate() 574 void SelectorQueryCache::invalidate()
558 { 575 {
559 m_entries.clear(); 576 m_entries.clear();
560 } 577 }
561 578
562 } 579 }
OLDNEW
« LayoutTests/fast/selectors/query-update-distribution.html ('K') | « Source/core/dom/SelectorQuery.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698