| 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 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 void SelectorDataList::findTraverseRootsAndExecute(ContainerNode& rootNode, type
name SelectorQueryTrait::OutputType& output) const | 202 void SelectorDataList::findTraverseRootsAndExecute(ContainerNode& rootNode, type
name SelectorQueryTrait::OutputType& output) const |
| 203 { | 203 { |
| 204 // We need to return the matches in document order. To use id lookup while t
here is possiblity of multiple matches | 204 // We need to return the matches in document order. To use id lookup while t
here is possiblity of multiple matches |
| 205 // we would need to sort the results. For now, just traverse the document in
that case. | 205 // we would need to sort the results. For now, just traverse the document in
that case. |
| 206 ASSERT(m_selectors.size() == 1); | 206 ASSERT(m_selectors.size() == 1); |
| 207 | 207 |
| 208 bool isRightmostSelector = true; | 208 bool isRightmostSelector = true; |
| 209 bool startFromParent = false; | 209 bool startFromParent = false; |
| 210 | 210 |
| 211 for (const CSSSelector* selector = m_selectors[0]; selector; selector = sele
ctor->tagHistory()) { | 211 for (const CSSSelector* selector = m_selectors[0]; selector; selector = sele
ctor->tagHistory()) { |
| 212 if (selector->m_match == CSSSelector::Id && !rootNode.document().contain
sMultipleElementsWithId(selector->value())) { | 212 if (selector->match() == CSSSelector::Id && !rootNode.document().contain
sMultipleElementsWithId(selector->value())) { |
| 213 Element* element = rootNode.treeScope().getElementById(selector->val
ue()); | 213 Element* element = rootNode.treeScope().getElementById(selector->val
ue()); |
| 214 ContainerNode* adjustedNode = &rootNode; | 214 ContainerNode* adjustedNode = &rootNode; |
| 215 if (element && (isTreeScopeRoot(rootNode) || element->isDescendantOf
(&rootNode))) | 215 if (element && (isTreeScopeRoot(rootNode) || element->isDescendantOf
(&rootNode))) |
| 216 adjustedNode = element; | 216 adjustedNode = element; |
| 217 else if (!element || isRightmostSelector) | 217 else if (!element || isRightmostSelector) |
| 218 adjustedNode = 0; | 218 adjustedNode = 0; |
| 219 if (isRightmostSelector) { | 219 if (isRightmostSelector) { |
| 220 executeForTraverseRoot<SelectorQueryTrait>(*m_selectors[0], adju
stedNode, MatchesTraverseRoots, rootNode, output); | 220 executeForTraverseRoot<SelectorQueryTrait>(*m_selectors[0], adju
stedNode, MatchesTraverseRoots, rootNode, output); |
| 221 return; | 221 return; |
| 222 } | 222 } |
| 223 | 223 |
| 224 if (startFromParent && adjustedNode) | 224 if (startFromParent && adjustedNode) |
| 225 adjustedNode = adjustedNode->parentNode(); | 225 adjustedNode = adjustedNode->parentNode(); |
| 226 | 226 |
| 227 executeForTraverseRoot<SelectorQueryTrait>(*m_selectors[0], adjusted
Node, DoesNotMatchTraverseRoots, rootNode, output); | 227 executeForTraverseRoot<SelectorQueryTrait>(*m_selectors[0], adjusted
Node, DoesNotMatchTraverseRoots, rootNode, output); |
| 228 return; | 228 return; |
| 229 } | 229 } |
| 230 | 230 |
| 231 // If we have both CSSSelector::Id and CSSSelector::Class at the same ti
me, we should use Id | 231 // If we have both CSSSelector::Id and CSSSelector::Class at the same ti
me, we should use Id |
| 232 // to find traverse root. | 232 // to find traverse root. |
| 233 if (!SelectorQueryTrait::shouldOnlyMatchFirstElement && !startFromParent
&& selector->m_match == CSSSelector::Class) { | 233 if (!SelectorQueryTrait::shouldOnlyMatchFirstElement && !startFromParent
&& selector->match() == CSSSelector::Class) { |
| 234 if (isRightmostSelector) { | 234 if (isRightmostSelector) { |
| 235 ClassElementList<AllElements> traverseRoots(rootNode, selector->
value()); | 235 ClassElementList<AllElements> traverseRoots(rootNode, selector->
value()); |
| 236 executeForTraverseRoots<SelectorQueryTrait>(*m_selectors[0], tra
verseRoots, MatchesTraverseRoots, rootNode, output); | 236 executeForTraverseRoots<SelectorQueryTrait>(*m_selectors[0], tra
verseRoots, MatchesTraverseRoots, rootNode, output); |
| 237 return; | 237 return; |
| 238 } | 238 } |
| 239 // Since there exists some ancestor element which has the class name
, we need to see all children of rootNode. | 239 // Since there exists some ancestor element which has the class name
, we need to see all children of rootNode. |
| 240 if (ancestorHasClassName(rootNode, selector->value())) { | 240 if (ancestorHasClassName(rootNode, selector->value())) { |
| 241 executeForTraverseRoot<SelectorQueryTrait>(*m_selectors[0], &roo
tNode, DoesNotMatchTraverseRoots, rootNode, output); | 241 executeForTraverseRoot<SelectorQueryTrait>(*m_selectors[0], &roo
tNode, DoesNotMatchTraverseRoots, rootNode, output); |
| 242 return; | 242 return; |
| 243 } | 243 } |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 389 continue; | 389 continue; |
| 390 Element* element = toElement(node); | 390 Element* element = toElement(node); |
| 391 if (selectorListMatches<SelectorQueryTrait>(rootNode, *element, output)
&& SelectorQueryTrait::shouldOnlyMatchFirstElement) | 391 if (selectorListMatches<SelectorQueryTrait>(rootNode, *element, output)
&& SelectorQueryTrait::shouldOnlyMatchFirstElement) |
| 392 return; | 392 return; |
| 393 } | 393 } |
| 394 } | 394 } |
| 395 | 395 |
| 396 const CSSSelector* SelectorDataList::selectorForIdLookup(const CSSSelector& firs
tSelector) const | 396 const CSSSelector* SelectorDataList::selectorForIdLookup(const CSSSelector& firs
tSelector) const |
| 397 { | 397 { |
| 398 for (const CSSSelector* selector = &firstSelector; selector; selector = sele
ctor->tagHistory()) { | 398 for (const CSSSelector* selector = &firstSelector; selector; selector = sele
ctor->tagHistory()) { |
| 399 if (selector->m_match == CSSSelector::Id) | 399 if (selector->match() == CSSSelector::Id) |
| 400 return selector; | 400 return selector; |
| 401 if (selector->relation() != CSSSelector::SubSelector) | 401 if (selector->relation() != CSSSelector::SubSelector) |
| 402 break; | 402 break; |
| 403 } | 403 } |
| 404 return 0; | 404 return 0; |
| 405 } | 405 } |
| 406 | 406 |
| 407 template <typename SelectorQueryTrait> | 407 template <typename SelectorQueryTrait> |
| 408 void SelectorDataList::execute(ContainerNode& rootNode, typename SelectorQueryTr
ait::OutputType& output) const | 408 void SelectorDataList::execute(ContainerNode& rootNode, typename SelectorQueryTr
ait::OutputType& output) const |
| 409 { | 409 { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 443 Element* element = rootNode.treeScope().getElementById(idToMatch); | 443 Element* element = rootNode.treeScope().getElementById(idToMatch); |
| 444 if (!element || !(isTreeScopeRoot(rootNode) || element->isDescendantOf(&
rootNode))) | 444 if (!element || !(isTreeScopeRoot(rootNode) || element->isDescendantOf(&
rootNode))) |
| 445 return; | 445 return; |
| 446 if (selectorMatches(selector, *element, rootNode)) | 446 if (selectorMatches(selector, *element, rootNode)) |
| 447 SelectorQueryTrait::appendElement(output, *element); | 447 SelectorQueryTrait::appendElement(output, *element); |
| 448 return; | 448 return; |
| 449 } | 449 } |
| 450 | 450 |
| 451 if (!firstSelector.tagHistory()) { | 451 if (!firstSelector.tagHistory()) { |
| 452 // Fast path for querySelector*('.foo'), and querySelector*('div'). | 452 // Fast path for querySelector*('.foo'), and querySelector*('div'). |
| 453 switch (firstSelector.m_match) { | 453 switch (firstSelector.match()) { |
| 454 case CSSSelector::Class: | 454 case CSSSelector::Class: |
| 455 collectElementsByClassName<SelectorQueryTrait>(rootNode, firstSelect
or.value(), output); | 455 collectElementsByClassName<SelectorQueryTrait>(rootNode, firstSelect
or.value(), output); |
| 456 return; | 456 return; |
| 457 case CSSSelector::Tag: | 457 case CSSSelector::Tag: |
| 458 collectElementsByTagName<SelectorQueryTrait>(rootNode, firstSelector
.tagQName(), output); | 458 collectElementsByTagName<SelectorQueryTrait>(rootNode, firstSelector
.tagQName(), output); |
| 459 return; | 459 return; |
| 460 default: | 460 default: |
| 461 break; // If we need another fast path, add here. | 461 break; // If we need another fast path, add here. |
| 462 } | 462 } |
| 463 } | 463 } |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 516 m_entries.add(selectors, selectorQuery.release()); | 516 m_entries.add(selectors, selectorQuery.release()); |
| 517 return rawSelectorQuery; | 517 return rawSelectorQuery; |
| 518 } | 518 } |
| 519 | 519 |
| 520 void SelectorQueryCache::invalidate() | 520 void SelectorQueryCache::invalidate() |
| 521 { | 521 { |
| 522 m_entries.clear(); | 522 m_entries.clear(); |
| 523 } | 523 } |
| 524 | 524 |
| 525 } | 525 } |
| OLD | NEW |