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 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
138 &element, SelectorChecker::VisitedMatchDisabled); | 138 &element, SelectorChecker::VisitedMatchDisabled); |
139 context.selector = &selector; | 139 context.selector = &selector; |
140 context.scope = &rootNode; | 140 context.scope = &rootNode; |
141 return checker.match(context); | 141 return checker.match(context); |
142 } | 142 } |
143 | 143 |
144 bool SelectorDataList::matches(Element& targetElement) const { | 144 bool SelectorDataList::matches(Element& targetElement) const { |
145 if (m_needsUpdatedDistribution) | 145 if (m_needsUpdatedDistribution) |
146 targetElement.updateDistribution(); | 146 targetElement.updateDistribution(); |
147 | 147 |
148 unsigned selectorCount = m_selectors.size(); | 148 for (const auto& selector : m_selectors) { |
149 for (unsigned i = 0; i < selectorCount; ++i) { | 149 if (selectorMatches(*selector, targetElement, targetElement)) |
150 if (selectorMatches(*m_selectors[i], targetElement, targetElement)) | |
151 return true; | 150 return true; |
152 } | 151 } |
153 | 152 |
154 return false; | 153 return false; |
155 } | 154 } |
156 | 155 |
157 Element* SelectorDataList::closest(Element& targetElement) const { | 156 Element* SelectorDataList::closest(Element& targetElement) const { |
158 unsigned selectorCount = m_selectors.size(); | 157 if (m_selectors.size() == 0) |
159 if (!selectorCount) | |
160 return nullptr; | 158 return nullptr; |
161 if (m_needsUpdatedDistribution) | 159 if (m_needsUpdatedDistribution) |
162 targetElement.updateDistribution(); | 160 targetElement.updateDistribution(); |
163 | 161 |
164 for (Element* currentElement = &targetElement; currentElement; | 162 for (Element* currentElement = &targetElement; currentElement; |
165 currentElement = currentElement->parentElement()) { | 163 currentElement = currentElement->parentElement()) { |
166 for (unsigned i = 0; i < selectorCount; ++i) { | 164 for (const auto& selector : m_selectors) { |
167 if (selectorMatches(*m_selectors[i], *currentElement, targetElement)) | 165 if (selectorMatches(*selector, *currentElement, targetElement)) |
168 return currentElement; | 166 return currentElement; |
169 } | 167 } |
170 } | 168 } |
171 return nullptr; | 169 return nullptr; |
172 } | 170 } |
173 | 171 |
174 StaticElementList* SelectorDataList::queryAll(ContainerNode& rootNode) const { | 172 StaticElementList* SelectorDataList::queryAll(ContainerNode& rootNode) const { |
175 HeapVector<Member<Element>> result; | 173 HeapVector<Member<Element>> result; |
176 execute<AllElementsSelectorQueryTrait>(rootNode, result); | 174 execute<AllElementsSelectorQueryTrait>(rootNode, result); |
177 return StaticElementList::adopt(result); | 175 return StaticElementList::adopt(result); |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
402 } | 400 } |
403 } | 401 } |
404 } | 402 } |
405 } | 403 } |
406 | 404 |
407 template <typename SelectorQueryTrait> | 405 template <typename SelectorQueryTrait> |
408 bool SelectorDataList::selectorListMatches( | 406 bool SelectorDataList::selectorListMatches( |
409 ContainerNode& rootNode, | 407 ContainerNode& rootNode, |
410 Element& element, | 408 Element& element, |
411 typename SelectorQueryTrait::OutputType& output) const { | 409 typename SelectorQueryTrait::OutputType& output) const { |
412 for (unsigned i = 0; i < m_selectors.size(); ++i) { | 410 for (const auto& selector : m_selectors) { |
413 if (selectorMatches(*m_selectors[i], element, rootNode)) { | 411 if (selectorMatches(*selector, element, rootNode)) { |
414 SelectorQueryTrait::appendElement(output, element); | 412 SelectorQueryTrait::appendElement(output, element); |
415 return true; | 413 return true; |
416 } | 414 } |
417 } | 415 } |
418 return false; | 416 return false; |
419 } | 417 } |
420 | 418 |
421 template <typename SelectorQueryTrait> | 419 template <typename SelectorQueryTrait> |
422 void SelectorDataList::executeSlow( | 420 void SelectorDataList::executeSlow( |
423 ContainerNode& rootNode, | 421 ContainerNode& rootNode, |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
539 const CSSSelector& selector = *m_selectors[0]; | 537 const CSSSelector& selector = *m_selectors[0]; |
540 const CSSSelector& firstSelector = selector; | 538 const CSSSelector& firstSelector = selector; |
541 | 539 |
542 // Fast path for querySelector*('#id'), querySelector*('tag#id'), | 540 // Fast path for querySelector*('#id'), querySelector*('tag#id'), |
543 // querySelector*('tag[id=example]'). | 541 // querySelector*('tag[id=example]'). |
544 if (const CSSSelector* idSelector = selectorForIdLookup(firstSelector)) { | 542 if (const CSSSelector* idSelector = selectorForIdLookup(firstSelector)) { |
545 const AtomicString& idToMatch = idSelector->value(); | 543 const AtomicString& idToMatch = idSelector->value(); |
546 if (rootNode.treeScope().containsMultipleElementsWithId(idToMatch)) { | 544 if (rootNode.treeScope().containsMultipleElementsWithId(idToMatch)) { |
547 const HeapVector<Member<Element>>& elements = | 545 const HeapVector<Member<Element>>& elements = |
548 rootNode.treeScope().getAllElementsById(idToMatch); | 546 rootNode.treeScope().getAllElementsById(idToMatch); |
549 size_t count = elements.size(); | 547 for (const auto& element : elements) { |
550 for (size_t i = 0; i < count; ++i) { | 548 if (!(isTreeScopeRoot(rootNode) || element->isDescendantOf(&rootNode))) |
551 Element& element = *elements[i]; | |
552 if (!(isTreeScopeRoot(rootNode) || element.isDescendantOf(&rootNode))) | |
553 continue; | 549 continue; |
554 if (selectorMatches(selector, element, rootNode)) { | 550 if (selectorMatches(selector, *element, rootNode)) { |
555 SelectorQueryTrait::appendElement(output, element); | 551 SelectorQueryTrait::appendElement(output, *element); |
556 if (SelectorQueryTrait::shouldOnlyMatchFirstElement) | 552 if (SelectorQueryTrait::shouldOnlyMatchFirstElement) |
557 return; | 553 return; |
558 } | 554 } |
559 } | 555 } |
560 return; | 556 return; |
561 } | 557 } |
562 Element* element = rootNode.treeScope().getElementById(idToMatch); | 558 Element* element = rootNode.treeScope().getElementById(idToMatch); |
563 if (!element || | 559 if (!element || |
564 !(isTreeScopeRoot(rootNode) || element->isDescendantOf(&rootNode))) | 560 !(isTreeScopeRoot(rootNode) || element->isDescendantOf(&rootNode))) |
565 return; | 561 return; |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
645 | 641 |
646 return m_entries.add(selectors, SelectorQuery::adopt(std::move(selectorList))) | 642 return m_entries.add(selectors, SelectorQuery::adopt(std::move(selectorList))) |
647 .storedValue->value.get(); | 643 .storedValue->value.get(); |
648 } | 644 } |
649 | 645 |
650 void SelectorQueryCache::invalidate() { | 646 void SelectorQueryCache::invalidate() { |
651 m_entries.clear(); | 647 m_entries.clear(); |
652 } | 648 } |
653 | 649 |
654 } // namespace blink | 650 } // namespace blink |
OLD | NEW |