Chromium Code Reviews| 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 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 271 return; | 271 return; |
| 272 } | 272 } |
| 273 | 273 |
| 274 // If we have both CSSSelector::Id and CSSSelector::Class at the same time, | 274 // If we have both CSSSelector::Id and CSSSelector::Class at the same time, |
| 275 // we should use Id to find traverse root. | 275 // we should use Id to find traverse root. |
| 276 if (!SelectorQueryTrait::shouldOnlyMatchFirstElement && !startFromParent && | 276 if (!SelectorQueryTrait::shouldOnlyMatchFirstElement && !startFromParent && |
| 277 selector->match() == CSSSelector::Class) { | 277 selector->match() == CSSSelector::Class) { |
| 278 if (isRightmostSelector) { | 278 if (isRightmostSelector) { |
| 279 ClassElementList<AllElements> traverseRoots(rootNode, | 279 ClassElementList<AllElements> traverseRoots(rootNode, |
| 280 selector->value()); | 280 selector->value()); |
| 281 executeForTraverseRoots<SelectorQueryTrait>( | 281 while (!traverseRoots.isEmpty()) { |
| 282 traverseRoots, MatchesTraverseRoots, rootNode, output); | 282 Element& element = *traverseRoots.next(); |
| 283 if (selectorMatches(*m_selectors[0], element, rootNode)) | |
| 284 SelectorQueryTrait::appendElement(output, element); | |
| 285 } | |
| 283 return; | 286 return; |
| 284 } | 287 } |
| 285 // Since there exists some ancestor element which has the class name, we | 288 // Since there exists some ancestor element which has the class name, we |
| 286 // need to see all children of rootNode. | 289 // need to see all children of rootNode. |
| 287 if (ancestorHasClassName(rootNode, selector->value())) { | 290 if (ancestorHasClassName(rootNode, selector->value())) |
| 288 executeForTraverseRoot<SelectorQueryTrait>(&rootNode, rootNode, output); | 291 break; |
|
esprehn
2017/03/29 05:00:43
This was just executing the code below if we had n
| |
| 289 return; | |
| 290 } | |
| 291 | 292 |
| 292 ClassElementList<OnlyRoots> traverseRoots(rootNode, selector->value()); | 293 ClassElementList<OnlyRoots> traverseRoots(rootNode, selector->value()); |
| 293 executeForTraverseRoots<SelectorQueryTrait>( | 294 while (!traverseRoots.isEmpty()) { |
| 294 traverseRoots, DoesNotMatchTraverseRoots, rootNode, output); | 295 for (Element& element : |
| 296 ElementTraversal::descendantsOf(*traverseRoots.next())) { | |
| 297 if (selectorMatches(*m_selectors[0], element, rootNode)) | |
| 298 SelectorQueryTrait::appendElement(output, element); | |
| 299 } | |
| 300 } | |
| 295 return; | 301 return; |
| 296 } | 302 } |
| 297 | 303 |
| 298 if (selector->relation() == CSSSelector::SubSelector) | 304 if (selector->relation() == CSSSelector::SubSelector) |
| 299 continue; | 305 continue; |
| 300 isRightmostSelector = false; | 306 isRightmostSelector = false; |
| 301 if (selector->relation() == CSSSelector::DirectAdjacent || | 307 if (selector->relation() == CSSSelector::DirectAdjacent || |
| 302 selector->relation() == CSSSelector::IndirectAdjacent) | 308 selector->relation() == CSSSelector::IndirectAdjacent) |
| 303 startFromParent = true; | 309 startFromParent = true; |
| 304 else | 310 else |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 321 | 327 |
| 322 for (Element& element : ElementTraversal::descendantsOf(*traverseRoot)) { | 328 for (Element& element : ElementTraversal::descendantsOf(*traverseRoot)) { |
| 323 if (selectorMatches(selector, element, rootNode)) { | 329 if (selectorMatches(selector, element, rootNode)) { |
| 324 SelectorQueryTrait::appendElement(output, element); | 330 SelectorQueryTrait::appendElement(output, element); |
| 325 if (SelectorQueryTrait::shouldOnlyMatchFirstElement) | 331 if (SelectorQueryTrait::shouldOnlyMatchFirstElement) |
| 326 return; | 332 return; |
| 327 } | 333 } |
| 328 } | 334 } |
| 329 } | 335 } |
| 330 | 336 |
| 331 template <typename SelectorQueryTrait, typename SimpleElementListType> | |
| 332 void SelectorQuery::executeForTraverseRoots( | |
| 333 SimpleElementListType& traverseRoots, | |
| 334 MatchTraverseRootState matchTraverseRoots, | |
| 335 ContainerNode& rootNode, | |
| 336 typename SelectorQueryTrait::OutputType& output) const { | |
| 337 DCHECK_EQ(m_selectors.size(), 1u); | |
| 338 | |
| 339 if (traverseRoots.isEmpty()) | |
| 340 return; | |
| 341 | |
| 342 const CSSSelector& selector = *m_selectors[0]; | |
| 343 | |
| 344 if (matchTraverseRoots) { | |
| 345 while (!traverseRoots.isEmpty()) { | |
| 346 Element& element = *traverseRoots.next(); | |
| 347 if (selectorMatches(selector, element, rootNode)) { | |
| 348 SelectorQueryTrait::appendElement(output, element); | |
| 349 if (SelectorQueryTrait::shouldOnlyMatchFirstElement) | |
| 350 return; | |
| 351 } | |
| 352 } | |
| 353 return; | |
| 354 } | |
| 355 | |
| 356 while (!traverseRoots.isEmpty()) { | |
| 357 for (Element& element : | |
| 358 ElementTraversal::descendantsOf(*traverseRoots.next())) { | |
| 359 if (selectorMatches(selector, element, rootNode)) { | |
| 360 SelectorQueryTrait::appendElement(output, element); | |
| 361 if (SelectorQueryTrait::shouldOnlyMatchFirstElement) | |
| 362 return; | |
| 363 } | |
| 364 } | |
| 365 } | |
| 366 } | |
| 367 | |
| 368 template <typename SelectorQueryTrait> | 337 template <typename SelectorQueryTrait> |
| 369 bool SelectorQuery::selectorListMatches( | 338 bool SelectorQuery::selectorListMatches( |
| 370 ContainerNode& rootNode, | 339 ContainerNode& rootNode, |
| 371 Element& element, | 340 Element& element, |
| 372 typename SelectorQueryTrait::OutputType& output) const { | 341 typename SelectorQueryTrait::OutputType& output) const { |
| 373 for (const auto& selector : m_selectors) { | 342 for (const auto& selector : m_selectors) { |
| 374 if (selectorMatches(*selector, element, rootNode)) { | 343 if (selectorMatches(*selector, element, rootNode)) { |
| 375 SelectorQueryTrait::appendElement(output, element); | 344 SelectorQueryTrait::appendElement(output, element); |
| 376 return true; | 345 return true; |
| 377 } | 346 } |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 608 return m_entries | 577 return m_entries |
| 609 .insert(selectors, SelectorQuery::adopt(std::move(selectorList))) | 578 .insert(selectors, SelectorQuery::adopt(std::move(selectorList))) |
| 610 .storedValue->value.get(); | 579 .storedValue->value.get(); |
| 611 } | 580 } |
| 612 | 581 |
| 613 void SelectorQueryCache::invalidate() { | 582 void SelectorQueryCache::invalidate() { |
| 614 m_entries.clear(); | 583 m_entries.clear(); |
| 615 } | 584 } |
| 616 | 585 |
| 617 } // namespace blink | 586 } // namespace blink |
| OLD | NEW |