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

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

Issue 1854423002: ASSERT -> {DCHECK|DCHECK_XX}, ENABLE(ASSERT) -> DCHECK_IS_ON() in dom (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: mark svg/as-image/svg-nested.html crash on win Created 4 years, 8 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
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 26 matching lines...) Expand all
37 #include "core/dom/shadow/ElementShadow.h" 37 #include "core/dom/shadow/ElementShadow.h"
38 #include "core/dom/shadow/ShadowRoot.h" 38 #include "core/dom/shadow/ShadowRoot.h"
39 39
40 namespace blink { 40 namespace blink {
41 41
42 struct SingleElementSelectorQueryTrait { 42 struct SingleElementSelectorQueryTrait {
43 typedef Element* OutputType; 43 typedef Element* OutputType;
44 static const bool shouldOnlyMatchFirstElement = true; 44 static const bool shouldOnlyMatchFirstElement = true;
45 ALWAYS_INLINE static void appendElement(OutputType& output, Element& element ) 45 ALWAYS_INLINE static void appendElement(OutputType& output, Element& element )
46 { 46 {
47 ASSERT(!output); 47 DCHECK(!output);
48 output = &element; 48 output = &element;
49 } 49 }
50 }; 50 };
51 51
52 struct AllElementsSelectorQueryTrait { 52 struct AllElementsSelectorQueryTrait {
53 typedef HeapVector<Member<Element>> OutputType; 53 typedef HeapVector<Member<Element>> OutputType;
54 static const bool shouldOnlyMatchFirstElement = false; 54 static const bool shouldOnlyMatchFirstElement = false;
55 ALWAYS_INLINE static void appendElement(OutputType& output, Element& element ) 55 ALWAYS_INLINE static void appendElement(OutputType& output, Element& element )
56 { 56 {
57 output.append(&element); 57 output.append(&element);
58 } 58 }
59 }; 59 };
60 60
61 enum ClassElementListBehavior { AllElements, OnlyRoots }; 61 enum ClassElementListBehavior { AllElements, OnlyRoots };
62 62
63 template <ClassElementListBehavior onlyRoots> 63 template <ClassElementListBehavior onlyRoots>
64 class ClassElementList { 64 class ClassElementList {
65 STACK_ALLOCATED(); 65 STACK_ALLOCATED();
66 public: 66 public:
67 ClassElementList(ContainerNode& rootNode, const AtomicString& className) 67 ClassElementList(ContainerNode& rootNode, const AtomicString& className)
68 : m_className(className) 68 : m_className(className)
69 , m_rootNode(&rootNode) 69 , m_rootNode(&rootNode)
70 , m_currentElement(nextInternal(ElementTraversal::firstWithin(rootNode)) ) { } 70 , m_currentElement(nextInternal(ElementTraversal::firstWithin(rootNode)) ) { }
71 71
72 bool isEmpty() const { return !m_currentElement; } 72 bool isEmpty() const { return !m_currentElement; }
73 73
74 Element* next() 74 Element* next()
75 { 75 {
76 Element* current = m_currentElement; 76 Element* current = m_currentElement;
77 ASSERT(current); 77 DCHECK(current);
78 if (onlyRoots) 78 if (onlyRoots)
79 m_currentElement = nextInternal(ElementTraversal::nextSkippingChildr en(*m_currentElement, m_rootNode)); 79 m_currentElement = nextInternal(ElementTraversal::nextSkippingChildr en(*m_currentElement, m_rootNode));
80 else 80 else
81 m_currentElement = nextInternal(ElementTraversal::next(*m_currentEle ment, m_rootNode)); 81 m_currentElement = nextInternal(ElementTraversal::next(*m_currentEle ment, m_rootNode));
82 return current; 82 return current;
83 } 83 }
84 84
85 private: 85 private:
86 Element* nextInternal(Element* element) 86 Element* nextInternal(Element* element)
87 { 87 {
88 for (; element; element = ElementTraversal::next(*element, m_rootNode)) { 88 for (; element; element = ElementTraversal::next(*element, m_rootNode)) {
89 if (element->hasClass() && element->classNames().contains(m_classNam e)) 89 if (element->hasClass() && element->classNames().contains(m_classNam e))
90 return element; 90 return element;
91 } 91 }
92 return nullptr; 92 return nullptr;
93 } 93 }
94 94
95 const AtomicString& m_className; 95 const AtomicString& m_className;
96 Member<ContainerNode> m_rootNode; 96 Member<ContainerNode> m_rootNode;
97 Member<Element> m_currentElement; 97 Member<Element> m_currentElement;
98 }; 98 };
99 99
100 void SelectorDataList::initialize(const CSSSelectorList& selectorList) 100 void SelectorDataList::initialize(const CSSSelectorList& selectorList)
101 { 101 {
102 ASSERT(m_selectors.isEmpty()); 102 DCHECK(m_selectors.isEmpty());
103 103
104 unsigned selectorCount = 0; 104 unsigned selectorCount = 0;
105 for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(*selector)) 105 for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(*selector))
106 selectorCount++; 106 selectorCount++;
107 107
108 m_usesDeepCombinatorOrShadowPseudo = false; 108 m_usesDeepCombinatorOrShadowPseudo = false;
109 m_needsUpdatedDistribution = false; 109 m_needsUpdatedDistribution = false;
110 m_selectors.reserveInitialCapacity(selectorCount); 110 m_selectors.reserveInitialCapacity(selectorCount);
111 unsigned index = 0; 111 unsigned index = 0;
112 for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(*selector), ++index) { 112 for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(*selector), ++index) {
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 return element.tagQName().localNameUpper() == tagName.localNameUpper(); 201 return element.tagQName().localNameUpper() == tagName.localNameUpper();
202 return false; 202 return false;
203 } 203 }
204 204
205 template <typename SelectorQueryTrait> 205 template <typename SelectorQueryTrait>
206 void SelectorDataList::collectElementsByTagName(ContainerNode& rootNode, const Q ualifiedName& tagName, typename SelectorQueryTrait::OutputType& output) const 206 void SelectorDataList::collectElementsByTagName(ContainerNode& rootNode, const Q ualifiedName& tagName, typename SelectorQueryTrait::OutputType& output) const
207 { 207 {
208 for (Element& element : ElementTraversal::descendantsOf(rootNode)) { 208 for (Element& element : ElementTraversal::descendantsOf(rootNode)) {
209 // querySelector*() doesn't allow namespaces and throws before it gets 209 // querySelector*() doesn't allow namespaces and throws before it gets
210 // here so we can ignore them. 210 // here so we can ignore them.
211 ASSERT(tagName.namespaceURI() == starAtom); 211 DCHECK_EQ(tagName.namespaceURI(), starAtom);
212 if (matchesTagName(tagName, element)) { 212 if (matchesTagName(tagName, element)) {
213 SelectorQueryTrait::appendElement(output, element); 213 SelectorQueryTrait::appendElement(output, element);
214 if (SelectorQueryTrait::shouldOnlyMatchFirstElement) 214 if (SelectorQueryTrait::shouldOnlyMatchFirstElement)
215 return; 215 return;
216 } 216 }
217 } 217 }
218 } 218 }
219 219
220 inline bool SelectorDataList::canUseFastQuery(const ContainerNode& rootNode) con st 220 inline bool SelectorDataList::canUseFastQuery(const ContainerNode& rootNode) con st
221 { 221 {
(...skipping 26 matching lines...) Expand all
248 // If returns false, traversalRoots has the rootNode parameter or descendants of rootNode representing 248 // If returns false, traversalRoots has the rootNode parameter or descendants of rootNode representing
249 // the subtree for which we can limit the querySelector traversal. 249 // the subtree for which we can limit the querySelector traversal.
250 // 250 //
251 // The travseralRoots may be empty, regardless of the returned bool value, if th is method finds that the selectors won't 251 // The travseralRoots may be empty, regardless of the returned bool value, if th is method finds that the selectors won't
252 // match any element. 252 // match any element.
253 template <typename SelectorQueryTrait> 253 template <typename SelectorQueryTrait>
254 void SelectorDataList::findTraverseRootsAndExecute(ContainerNode& rootNode, type name SelectorQueryTrait::OutputType& output) const 254 void SelectorDataList::findTraverseRootsAndExecute(ContainerNode& rootNode, type name SelectorQueryTrait::OutputType& output) const
255 { 255 {
256 // We need to return the matches in document order. To use id lookup while t here is possiblity of multiple matches 256 // We need to return the matches in document order. To use id lookup while t here is possiblity of multiple matches
257 // we would need to sort the results. For now, just traverse the document in that case. 257 // we would need to sort the results. For now, just traverse the document in that case.
258 ASSERT(m_selectors.size() == 1); 258 DCHECK_EQ(m_selectors.size(), 1u);
259 259
260 bool isRightmostSelector = true; 260 bool isRightmostSelector = true;
261 bool startFromParent = false; 261 bool startFromParent = false;
262 262
263 for (const CSSSelector* selector = m_selectors[0]; selector; selector = sele ctor->tagHistory()) { 263 for (const CSSSelector* selector = m_selectors[0]; selector; selector = sele ctor->tagHistory()) {
264 if (selector->match() == CSSSelector::Id && !rootNode.document().contain sMultipleElementsWithId(selector->value())) { 264 if (selector->match() == CSSSelector::Id && !rootNode.document().contain sMultipleElementsWithId(selector->value())) {
265 Element* element = rootNode.treeScope().getElementById(selector->val ue()); 265 Element* element = rootNode.treeScope().getElementById(selector->val ue());
266 ContainerNode* adjustedNode = &rootNode; 266 ContainerNode* adjustedNode = &rootNode;
267 if (element && (isTreeScopeRoot(rootNode) || element->isDescendantOf (&rootNode))) 267 if (element && (isTreeScopeRoot(rootNode) || element->isDescendantOf (&rootNode)))
268 adjustedNode = element; 268 adjustedNode = element;
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 } 383 }
384 384
385 // FIXME: Move the following helper functions, authorShadowRootOf, firstWithinTr aversingShadowTree, 385 // FIXME: Move the following helper functions, authorShadowRootOf, firstWithinTr aversingShadowTree,
386 // nextTraversingShadowTree to the best place, e.g. NodeTraversal. 386 // nextTraversingShadowTree to the best place, e.g. NodeTraversal.
387 static ShadowRoot* authorShadowRootOf(const ContainerNode& node) 387 static ShadowRoot* authorShadowRootOf(const ContainerNode& node)
388 { 388 {
389 if (!node.isElementNode() || !isShadowHost(&node)) 389 if (!node.isElementNode() || !isShadowHost(&node))
390 return nullptr; 390 return nullptr;
391 391
392 ElementShadow* shadow = toElement(node).shadow(); 392 ElementShadow* shadow = toElement(node).shadow();
393 ASSERT(shadow); 393 DCHECK(shadow);
394 for (ShadowRoot* shadowRoot = shadow->oldestShadowRoot(); shadowRoot; shadow Root = shadowRoot->youngerShadowRoot()) { 394 for (ShadowRoot* shadowRoot = shadow->oldestShadowRoot(); shadowRoot; shadow Root = shadowRoot->youngerShadowRoot()) {
395 if (shadowRoot->type() == ShadowRootType::V0 || shadowRoot->type() == Sh adowRootType::Open) 395 if (shadowRoot->type() == ShadowRootType::V0 || shadowRoot->type() == Sh adowRootType::Open)
396 return shadowRoot; 396 return shadowRoot;
397 } 397 }
398 return nullptr; 398 return nullptr;
399 } 399 }
400 400
401 static ContainerNode* firstWithinTraversingShadowTree(const ContainerNode& rootN ode) 401 static ContainerNode* firstWithinTraversingShadowTree(const ContainerNode& rootN ode)
402 { 402 {
403 if (ShadowRoot* shadowRoot = authorShadowRootOf(rootNode)) 403 if (ShadowRoot* shadowRoot = authorShadowRootOf(rootNode))
(...skipping 12 matching lines...) Expand all
416 return next; 416 return next;
417 417
418 if (!current->isInShadowTree()) 418 if (!current->isInShadowTree())
419 return nullptr; 419 return nullptr;
420 420
421 ShadowRoot* shadowRoot = current->containingShadowRoot(); 421 ShadowRoot* shadowRoot = current->containingShadowRoot();
422 if (shadowRoot == rootNode) 422 if (shadowRoot == rootNode)
423 return nullptr; 423 return nullptr;
424 if (ShadowRoot* youngerShadowRoot = shadowRoot->youngerShadowRoot()) { 424 if (ShadowRoot* youngerShadowRoot = shadowRoot->youngerShadowRoot()) {
425 // Should not obtain any elements in closed or user-agent shadow roo t. 425 // Should not obtain any elements in closed or user-agent shadow roo t.
426 ASSERT(youngerShadowRoot->type() == ShadowRootType::V0 || youngerSha dowRoot->type() == ShadowRootType::Open); 426 DCHECK(youngerShadowRoot->type() == ShadowRootType::V0 || youngerSha dowRoot->type() == ShadowRootType::Open);
427 return youngerShadowRoot; 427 return youngerShadowRoot;
428 } 428 }
429 429
430 current = shadowRoot->host(); 430 current = shadowRoot->host();
431 } 431 }
432 return nullptr; 432 return nullptr;
433 } 433 }
434 434
435 template <typename SelectorQueryTrait> 435 template <typename SelectorQueryTrait>
436 void SelectorDataList::executeSlowTraversingShadowTree(ContainerNode& rootNode, typename SelectorQueryTrait::OutputType& output) const 436 void SelectorDataList::executeSlowTraversingShadowTree(ContainerNode& rootNode, typename SelectorQueryTrait::OutputType& output) const
(...skipping 28 matching lines...) Expand all
465 if (m_needsUpdatedDistribution) 465 if (m_needsUpdatedDistribution)
466 rootNode.updateDistribution(); 466 rootNode.updateDistribution();
467 if (m_usesDeepCombinatorOrShadowPseudo) { 467 if (m_usesDeepCombinatorOrShadowPseudo) {
468 executeSlowTraversingShadowTree<SelectorQueryTrait>(rootNode, output ); 468 executeSlowTraversingShadowTree<SelectorQueryTrait>(rootNode, output );
469 } else { 469 } else {
470 executeSlow<SelectorQueryTrait>(rootNode, output); 470 executeSlow<SelectorQueryTrait>(rootNode, output);
471 } 471 }
472 return; 472 return;
473 } 473 }
474 474
475 ASSERT(m_selectors.size() == 1); 475 DCHECK_EQ(m_selectors.size(), 1u);
476 476
477 const CSSSelector& selector = *m_selectors[0]; 477 const CSSSelector& selector = *m_selectors[0];
478 const CSSSelector& firstSelector = selector; 478 const CSSSelector& firstSelector = selector;
479 479
480 // Fast path for querySelector*('#id'), querySelector*('tag#id'). 480 // Fast path for querySelector*('#id'), querySelector*('tag#id').
481 if (const CSSSelector* idSelector = selectorForIdLookup(firstSelector)) { 481 if (const CSSSelector* idSelector = selectorForIdLookup(firstSelector)) {
482 const AtomicString& idToMatch = idSelector->value(); 482 const AtomicString& idToMatch = idSelector->value();
483 if (rootNode.treeScope().containsMultipleElementsWithId(idToMatch)) { 483 if (rootNode.treeScope().containsMultipleElementsWithId(idToMatch)) {
484 const HeapVector<Member<Element>>& elements = rootNode.treeScope().g etAllElementsById(idToMatch); 484 const HeapVector<Member<Element>>& elements = rootNode.treeScope().g etAllElementsById(idToMatch);
485 size_t count = elements.size(); 485 size_t count = elements.size();
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
570 570
571 return m_entries.add(selectors, SelectorQuery::adopt(std::move(selectorList) )).storedValue->value.get(); 571 return m_entries.add(selectors, SelectorQuery::adopt(std::move(selectorList) )).storedValue->value.get();
572 } 572 }
573 573
574 void SelectorQueryCache::invalidate() 574 void SelectorQueryCache::invalidate()
575 { 575 {
576 m_entries.clear(); 576 m_entries.clear();
577 } 577 }
578 578
579 } // namespace blink 579 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698