| 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 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 DCHECK(!isRightmostSelector); | 252 DCHECK(!isRightmostSelector); |
| 253 Element* element = | 253 Element* element = |
| 254 rootNode.containingTreeScope().getElementById(selector->value()); | 254 rootNode.containingTreeScope().getElementById(selector->value()); |
| 255 if (!element) | 255 if (!element) |
| 256 return; | 256 return; |
| 257 ContainerNode* start = &rootNode; | 257 ContainerNode* start = &rootNode; |
| 258 if (element->isDescendantOf(&rootNode)) | 258 if (element->isDescendantOf(&rootNode)) |
| 259 start = element; | 259 start = element; |
| 260 if (startFromParent) | 260 if (startFromParent) |
| 261 start = start->parentNode(); | 261 start = start->parentNode(); |
| 262 executeForTraverseRoot<SelectorQueryTrait>(start, rootNode, output); | 262 if (!start) |
| 263 return; |
| 264 executeForTraverseRoot<SelectorQueryTrait>(*start, rootNode, output); |
| 263 return; | 265 return; |
| 264 } | 266 } |
| 265 | 267 |
| 266 // If we have both CSSSelector::Id and CSSSelector::Class at the same time, | 268 // If we have both CSSSelector::Id and CSSSelector::Class at the same time, |
| 267 // we should use Id to find traverse root. | 269 // we should use Id to find traverse root. |
| 268 if (!SelectorQueryTrait::shouldOnlyMatchFirstElement && !startFromParent && | 270 if (!SelectorQueryTrait::shouldOnlyMatchFirstElement && !startFromParent && |
| 269 selector->match() == CSSSelector::Class) { | 271 selector->match() == CSSSelector::Class) { |
| 270 if (isRightmostSelector) { | 272 if (isRightmostSelector) { |
| 271 ClassElementList<AllElements> traverseRoots(rootNode, | 273 ClassElementList<AllElements> traverseRoots(rootNode, |
| 272 selector->value()); | 274 selector->value()); |
| 273 while (!traverseRoots.isEmpty()) { | 275 while (!traverseRoots.isEmpty()) { |
| 274 Element& element = *traverseRoots.next(); | 276 Element& element = *traverseRoots.next(); |
| 275 if (selectorMatches(*m_selectors[0], element, rootNode)) | 277 if (selectorMatches(*m_selectors[0], element, rootNode)) |
| 276 SelectorQueryTrait::appendElement(output, element); | 278 SelectorQueryTrait::appendElement(output, element); |
| 277 } | 279 } |
| 278 return; | 280 return; |
| 279 } | 281 } |
| 280 // Since there exists some ancestor element which has the class name, we | 282 // Since there exists some ancestor element which has the class name, we |
| 281 // need to see all children of rootNode. | 283 // need to see all children of rootNode. |
| 282 if (ancestorHasClassName(rootNode, selector->value())) | 284 if (ancestorHasClassName(rootNode, selector->value())) |
| 283 break; | 285 break; |
| 284 | 286 |
| 285 ClassElementList<OnlyRoots> traverseRoots(rootNode, selector->value()); | 287 ClassElementList<OnlyRoots> traverseRoots(rootNode, selector->value()); |
| 286 while (!traverseRoots.isEmpty()) { | 288 while (!traverseRoots.isEmpty()) { |
| 287 for (Element& element : | 289 executeForTraverseRoot<SelectorQueryTrait>(*traverseRoots.next(), |
| 288 ElementTraversal::descendantsOf(*traverseRoots.next())) { | 290 rootNode, output); |
| 289 if (selectorMatches(*m_selectors[0], element, rootNode)) | |
| 290 SelectorQueryTrait::appendElement(output, element); | |
| 291 } | |
| 292 } | 291 } |
| 293 return; | 292 return; |
| 294 } | 293 } |
| 295 | 294 |
| 296 if (selector->relation() == CSSSelector::SubSelector) | 295 if (selector->relation() == CSSSelector::SubSelector) |
| 297 continue; | 296 continue; |
| 298 isRightmostSelector = false; | 297 isRightmostSelector = false; |
| 299 if (selector->relation() == CSSSelector::DirectAdjacent || | 298 if (selector->relation() == CSSSelector::DirectAdjacent || |
| 300 selector->relation() == CSSSelector::IndirectAdjacent) | 299 selector->relation() == CSSSelector::IndirectAdjacent) |
| 301 startFromParent = true; | 300 startFromParent = true; |
| 302 else | 301 else |
| 303 startFromParent = false; | 302 startFromParent = false; |
| 304 } | 303 } |
| 305 | 304 |
| 306 executeForTraverseRoot<SelectorQueryTrait>(&rootNode, rootNode, output); | 305 executeForTraverseRoot<SelectorQueryTrait>(rootNode, rootNode, output); |
| 307 } | 306 } |
| 308 | 307 |
| 309 template <typename SelectorQueryTrait> | 308 template <typename SelectorQueryTrait> |
| 310 void SelectorQuery::executeForTraverseRoot( | 309 void SelectorQuery::executeForTraverseRoot( |
| 311 ContainerNode* traverseRoot, | 310 ContainerNode& traverseRoot, |
| 312 ContainerNode& rootNode, | 311 ContainerNode& rootNode, |
| 313 typename SelectorQueryTrait::OutputType& output) const { | 312 typename SelectorQueryTrait::OutputType& output) const { |
| 314 DCHECK_EQ(m_selectors.size(), 1u); | 313 DCHECK_EQ(m_selectors.size(), 1u); |
| 315 | 314 |
| 316 if (!traverseRoot) | |
| 317 return; | |
| 318 const CSSSelector& selector = *m_selectors[0]; | 315 const CSSSelector& selector = *m_selectors[0]; |
| 319 | 316 |
| 320 for (Element& element : ElementTraversal::descendantsOf(*traverseRoot)) { | 317 for (Element& element : ElementTraversal::descendantsOf(traverseRoot)) { |
| 321 if (selectorMatches(selector, element, rootNode)) { | 318 if (selectorMatches(selector, element, rootNode)) { |
| 322 SelectorQueryTrait::appendElement(output, element); | 319 SelectorQueryTrait::appendElement(output, element); |
| 323 if (SelectorQueryTrait::shouldOnlyMatchFirstElement) | 320 if (SelectorQueryTrait::shouldOnlyMatchFirstElement) |
| 324 return; | 321 return; |
| 325 } | 322 } |
| 326 } | 323 } |
| 327 } | 324 } |
| 328 | 325 |
| 329 template <typename SelectorQueryTrait> | 326 template <typename SelectorQueryTrait> |
| 330 bool SelectorQuery::selectorListMatches( | 327 bool SelectorQuery::selectorListMatches( |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 560 return m_entries | 557 return m_entries |
| 561 .insert(selectors, SelectorQuery::adopt(std::move(selectorList))) | 558 .insert(selectors, SelectorQuery::adopt(std::move(selectorList))) |
| 562 .storedValue->value.get(); | 559 .storedValue->value.get(); |
| 563 } | 560 } |
| 564 | 561 |
| 565 void SelectorQueryCache::invalidate() { | 562 void SelectorQueryCache::invalidate() { |
| 566 m_entries.clear(); | 563 m_entries.clear(); |
| 567 } | 564 } |
| 568 | 565 |
| 569 } // namespace blink | 566 } // namespace blink |
| OLD | NEW |