OLD | NEW |
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 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 SelectorChecker::SelectorCheckingContext context( | 114 SelectorChecker::SelectorCheckingContext context( |
115 &element, SelectorChecker::VisitedMatchDisabled); | 115 &element, SelectorChecker::VisitedMatchDisabled); |
116 context.selector = &selector; | 116 context.selector = &selector; |
117 context.scope = &rootNode; | 117 context.scope = &rootNode; |
118 return checker.match(context); | 118 return checker.match(context); |
119 } | 119 } |
120 | 120 |
121 bool SelectorQuery::matches(Element& targetElement) const { | 121 bool SelectorQuery::matches(Element& targetElement) const { |
122 if (m_needsUpdatedDistribution) | 122 if (m_needsUpdatedDistribution) |
123 targetElement.updateDistribution(); | 123 targetElement.updateDistribution(); |
124 | 124 return selectorListMatches(targetElement, targetElement); |
125 for (const auto& selector : m_selectors) { | |
126 if (selectorMatches(*selector, targetElement, targetElement)) | |
127 return true; | |
128 } | |
129 | |
130 return false; | |
131 } | 125 } |
132 | 126 |
133 Element* SelectorQuery::closest(Element& targetElement) const { | 127 Element* SelectorQuery::closest(Element& targetElement) const { |
134 if (m_selectors.isEmpty()) | 128 if (m_selectors.isEmpty()) |
135 return nullptr; | 129 return nullptr; |
136 if (m_needsUpdatedDistribution) | 130 if (m_needsUpdatedDistribution) |
137 targetElement.updateDistribution(); | 131 targetElement.updateDistribution(); |
138 | 132 |
139 for (Element* currentElement = &targetElement; currentElement; | 133 for (Element* currentElement = &targetElement; currentElement; |
140 currentElement = currentElement->parentElement()) { | 134 currentElement = currentElement->parentElement()) { |
141 for (const auto& selector : m_selectors) { | 135 if (selectorListMatches(targetElement, *currentElement)) |
142 if (selectorMatches(*selector, *currentElement, targetElement)) | 136 return currentElement; |
143 return currentElement; | |
144 } | |
145 } | 137 } |
146 return nullptr; | 138 return nullptr; |
147 } | 139 } |
148 | 140 |
149 StaticElementList* SelectorQuery::queryAll(ContainerNode& rootNode) const { | 141 StaticElementList* SelectorQuery::queryAll(ContainerNode& rootNode) const { |
150 NthIndexCache nthIndexCache(rootNode.document()); | 142 NthIndexCache nthIndexCache(rootNode.document()); |
151 HeapVector<Member<Element>> result; | 143 HeapVector<Member<Element>> result; |
152 execute<AllElementsSelectorQueryTrait>(rootNode, result); | 144 execute<AllElementsSelectorQueryTrait>(rootNode, result); |
153 return StaticElementList::adopt(result); | 145 return StaticElementList::adopt(result); |
154 } | 146 } |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
319 | 311 |
320 for (Element& element : ElementTraversal::descendantsOf(*traverseRoot)) { | 312 for (Element& element : ElementTraversal::descendantsOf(*traverseRoot)) { |
321 if (selectorMatches(selector, element, rootNode)) { | 313 if (selectorMatches(selector, element, rootNode)) { |
322 SelectorQueryTrait::appendElement(output, element); | 314 SelectorQueryTrait::appendElement(output, element); |
323 if (SelectorQueryTrait::shouldOnlyMatchFirstElement) | 315 if (SelectorQueryTrait::shouldOnlyMatchFirstElement) |
324 return; | 316 return; |
325 } | 317 } |
326 } | 318 } |
327 } | 319 } |
328 | 320 |
329 template <typename SelectorQueryTrait> | 321 bool SelectorQuery::selectorListMatches(ContainerNode& rootNode, |
330 bool SelectorQuery::selectorListMatches( | 322 Element& element) const { |
331 ContainerNode& rootNode, | |
332 Element& element, | |
333 typename SelectorQueryTrait::OutputType& output) const { | |
334 for (const auto& selector : m_selectors) { | 323 for (const auto& selector : m_selectors) { |
335 if (selectorMatches(*selector, element, rootNode)) { | 324 if (selectorMatches(*selector, element, rootNode)) |
336 SelectorQueryTrait::appendElement(output, element); | |
337 return true; | 325 return true; |
338 } | |
339 } | 326 } |
340 return false; | 327 return false; |
341 } | 328 } |
342 | 329 |
343 template <typename SelectorQueryTrait> | 330 template <typename SelectorQueryTrait> |
344 void SelectorQuery::executeSlow( | 331 void SelectorQuery::executeSlow( |
345 ContainerNode& rootNode, | 332 ContainerNode& rootNode, |
346 typename SelectorQueryTrait::OutputType& output) const { | 333 typename SelectorQueryTrait::OutputType& output) const { |
347 for (Element& element : ElementTraversal::descendantsOf(rootNode)) { | 334 for (Element& element : ElementTraversal::descendantsOf(rootNode)) { |
348 if (selectorListMatches<SelectorQueryTrait>(rootNode, element, output) && | 335 if (!selectorListMatches(rootNode, element)) |
349 SelectorQueryTrait::shouldOnlyMatchFirstElement) | 336 continue; |
| 337 SelectorQueryTrait::appendElement(output, element); |
| 338 if (SelectorQueryTrait::shouldOnlyMatchFirstElement) |
350 return; | 339 return; |
351 } | 340 } |
352 } | 341 } |
353 | 342 |
354 // FIXME: Move the following helper functions, authorShadowRootOf, | 343 // FIXME: Move the following helper functions, authorShadowRootOf, |
355 // firstWithinTraversingShadowTree, nextTraversingShadowTree to the best place, | 344 // firstWithinTraversingShadowTree, nextTraversingShadowTree to the best place, |
356 // e.g. NodeTraversal. | 345 // e.g. NodeTraversal. |
357 static ShadowRoot* authorShadowRootOf(const ContainerNode& node) { | 346 static ShadowRoot* authorShadowRootOf(const ContainerNode& node) { |
358 if (!node.isElementNode()) | 347 if (!node.isElementNode()) |
359 return nullptr; | 348 return nullptr; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
397 | 386 |
398 template <typename SelectorQueryTrait> | 387 template <typename SelectorQueryTrait> |
399 void SelectorQuery::executeSlowTraversingShadowTree( | 388 void SelectorQuery::executeSlowTraversingShadowTree( |
400 ContainerNode& rootNode, | 389 ContainerNode& rootNode, |
401 typename SelectorQueryTrait::OutputType& output) const { | 390 typename SelectorQueryTrait::OutputType& output) const { |
402 for (ContainerNode* node = nextTraversingShadowTree(rootNode, &rootNode); | 391 for (ContainerNode* node = nextTraversingShadowTree(rootNode, &rootNode); |
403 node; node = nextTraversingShadowTree(*node, &rootNode)) { | 392 node; node = nextTraversingShadowTree(*node, &rootNode)) { |
404 if (!node->isElementNode()) | 393 if (!node->isElementNode()) |
405 continue; | 394 continue; |
406 Element* element = toElement(node); | 395 Element* element = toElement(node); |
407 if (selectorListMatches<SelectorQueryTrait>(rootNode, *element, output) && | 396 if (!selectorListMatches(rootNode, *element)) |
408 SelectorQueryTrait::shouldOnlyMatchFirstElement) | 397 continue; |
| 398 SelectorQueryTrait::appendElement(output, *element); |
| 399 if (SelectorQueryTrait::shouldOnlyMatchFirstElement) |
409 return; | 400 return; |
410 } | 401 } |
411 } | 402 } |
412 | 403 |
413 static const CSSSelector* selectorForIdLookup( | 404 static const CSSSelector* selectorForIdLookup( |
414 const CSSSelector& firstSelector) { | 405 const CSSSelector& firstSelector) { |
415 for (const CSSSelector* selector = &firstSelector; selector; | 406 for (const CSSSelector* selector = &firstSelector; selector; |
416 selector = selector->tagHistory()) { | 407 selector = selector->tagHistory()) { |
417 if (selector->match() == CSSSelector::Id) | 408 if (selector->match() == CSSSelector::Id) |
418 return selector; | 409 return selector; |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
560 return m_entries | 551 return m_entries |
561 .insert(selectors, SelectorQuery::adopt(std::move(selectorList))) | 552 .insert(selectors, SelectorQuery::adopt(std::move(selectorList))) |
562 .storedValue->value.get(); | 553 .storedValue->value.get(); |
563 } | 554 } |
564 | 555 |
565 void SelectorQueryCache::invalidate() { | 556 void SelectorQueryCache::invalidate() { |
566 m_entries.clear(); | 557 m_entries.clear(); |
567 } | 558 } |
568 | 559 |
569 } // namespace blink | 560 } // namespace blink |
OLD | NEW |