Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(489)

Side by Side Diff: third_party/WebKit/Source/core/dom/SelectorQuery.cpp

Issue 2785253002: Reuse executeForTraverseRoot to avoid a manual loop in SelectorQuery::findTraverseRootsAndExecute. (Closed)
Patch Set: woops Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/WebKit/Source/core/dom/SelectorQuery.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/dom/SelectorQuery.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698