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 |