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

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

Issue 2767113003: Simplify some arguments inside SelectorQuery. (Closed)
Patch Set: Created 3 years, 9 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 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 return false; 220 return false;
221 221
222 for (Element* element = &toElement(rootNode); element; 222 for (Element* element = &toElement(rootNode); element;
223 element = element->parentElement()) { 223 element = element->parentElement()) {
224 if (element->hasClass() && element->classNames().contains(className)) 224 if (element->hasClass() && element->classNames().contains(className))
225 return true; 225 return true;
226 } 226 }
227 return false; 227 return false;
228 } 228 }
229 229
230 // If returns true, traversalRoots has the elements that may match the selector
231 // query.
232 //
233 // If returns false, traversalRoots has the rootNode parameter or descendants of
234 // rootNode representing the subtree for which we can limit the querySelector
235 // traversal.
236 //
237 // The travseralRoots may be empty, regardless of the returned bool value, if
238 // this method finds that the selectors won't match any element.
esprehn 2017/03/23 01:09:33 This comment was ancient, from when we used to ret
sashab 2017/03/23 05:40:21 Wanna add an updated comment to explain how it wor
esprehn 2017/03/23 05:48:51 I'd prefer to do that in a separate patch.
239 template <typename SelectorQueryTrait> 230 template <typename SelectorQueryTrait>
240 void SelectorQuery::findTraverseRootsAndExecute( 231 void SelectorQuery::findTraverseRootsAndExecute(
241 ContainerNode& rootNode, 232 ContainerNode& rootNode,
242 typename SelectorQueryTrait::OutputType& output) const { 233 typename SelectorQueryTrait::OutputType& output) const {
243 // We need to return the matches in document order. To use id lookup while 234 // We need to return the matches in document order. To use id lookup while
244 // there is possiblity of multiple matches we would need to sort the 235 // there is possiblity of multiple matches we would need to sort the
245 // results. For now, just traverse the document in that case. 236 // results. For now, just traverse the document in that case.
246 DCHECK_EQ(m_selectors.size(), 1u); 237 DCHECK_EQ(m_selectors.size(), 1u);
247 238
248 bool isRightmostSelector = true; 239 bool isRightmostSelector = true;
249 bool startFromParent = false; 240 bool startFromParent = false;
250 241
251 for (const CSSSelector* selector = m_selectors[0]; selector; 242 for (const CSSSelector* selector = m_selectors[0]; selector;
252 selector = selector->tagHistory()) { 243 selector = selector->tagHistory()) {
253 if (selector->match() == CSSSelector::Id && rootNode.isInTreeScope() && 244 if (selector->match() == CSSSelector::Id && rootNode.isInTreeScope() &&
254 !rootNode.containingTreeScope().containsMultipleElementsWithId( 245 !rootNode.containingTreeScope().containsMultipleElementsWithId(
255 selector->value())) { 246 selector->value())) {
256 Element* element = 247 Element* element =
257 rootNode.containingTreeScope().getElementById(selector->value()); 248 rootNode.containingTreeScope().getElementById(selector->value());
258 ContainerNode* adjustedNode = &rootNode; 249 ContainerNode* adjustedNode = &rootNode;
259 if (element && 250 if (element &&
260 (isTreeScopeRoot(rootNode) || element->isDescendantOf(&rootNode))) 251 (isTreeScopeRoot(rootNode) || element->isDescendantOf(&rootNode)))
261 adjustedNode = element; 252 adjustedNode = element;
262 else if (!element || isRightmostSelector) 253 else if (!element || isRightmostSelector)
263 adjustedNode = nullptr; 254 adjustedNode = nullptr;
264 if (isRightmostSelector) { 255 if (isRightmostSelector) {
265 executeForTraverseRoot<SelectorQueryTrait>( 256 if (!adjustedNode)
266 *m_selectors[0], adjustedNode, MatchesTraverseRoots, rootNode, 257 return;
267 output); 258 element = toElement(adjustedNode);
259 if (selectorMatches(*m_selectors[0], *element, rootNode))
260 SelectorQueryTrait::appendElement(output, *element);
sashab 2017/03/23 06:26:32 I don't really understand this part of the change,
esprehn 2017/03/23 06:31:58 The code used to pass MatchedTraverseRoot as the e
sashab 2017/03/23 23:19:05 Can you remove it from the function then? Do other
esprehn 2017/03/24 00:02:31 I did remove it from that function. There's a anot
268 return; 261 return;
269 } 262 }
270 263
271 if (startFromParent && adjustedNode) 264 if (startFromParent && adjustedNode)
272 adjustedNode = adjustedNode->parentNode(); 265 adjustedNode = adjustedNode->parentNode();
273 266
274 executeForTraverseRoot<SelectorQueryTrait>(*m_selectors[0], adjustedNode, 267 executeForTraverseRoot<SelectorQueryTrait>(adjustedNode, rootNode,
275 DoesNotMatchTraverseRoots, 268 output);
276 rootNode, output);
277 return; 269 return;
278 } 270 }
279 271
280 // If we have both CSSSelector::Id and CSSSelector::Class at the same time, 272 // If we have both CSSSelector::Id and CSSSelector::Class at the same time,
281 // we should use Id to find traverse root. 273 // we should use Id to find traverse root.
282 if (!SelectorQueryTrait::shouldOnlyMatchFirstElement && !startFromParent && 274 if (!SelectorQueryTrait::shouldOnlyMatchFirstElement && !startFromParent &&
283 selector->match() == CSSSelector::Class) { 275 selector->match() == CSSSelector::Class) {
284 if (isRightmostSelector) { 276 if (isRightmostSelector) {
285 ClassElementList<AllElements> traverseRoots(rootNode, 277 ClassElementList<AllElements> traverseRoots(rootNode,
286 selector->value()); 278 selector->value());
287 executeForTraverseRoots<SelectorQueryTrait>( 279 executeForTraverseRoots<SelectorQueryTrait>(
288 *m_selectors[0], traverseRoots, MatchesTraverseRoots, rootNode, 280 traverseRoots, MatchesTraverseRoots, rootNode, output);
289 output);
290 return; 281 return;
291 } 282 }
292 // Since there exists some ancestor element which has the class name, we 283 // Since there exists some ancestor element which has the class name, we
293 // need to see all children of rootNode. 284 // need to see all children of rootNode.
294 if (ancestorHasClassName(rootNode, selector->value())) { 285 if (ancestorHasClassName(rootNode, selector->value())) {
295 executeForTraverseRoot<SelectorQueryTrait>(*m_selectors[0], &rootNode, 286 executeForTraverseRoot<SelectorQueryTrait>(&rootNode, rootNode, output);
296 DoesNotMatchTraverseRoots,
297 rootNode, output);
298 return; 287 return;
299 } 288 }
300 289
301 ClassElementList<OnlyRoots> traverseRoots(rootNode, selector->value()); 290 ClassElementList<OnlyRoots> traverseRoots(rootNode, selector->value());
302 executeForTraverseRoots<SelectorQueryTrait>( 291 executeForTraverseRoots<SelectorQueryTrait>(
303 *m_selectors[0], traverseRoots, DoesNotMatchTraverseRoots, rootNode, 292 traverseRoots, DoesNotMatchTraverseRoots, rootNode, output);
304 output);
305 return; 293 return;
306 } 294 }
307 295
308 if (selector->relation() == CSSSelector::SubSelector) 296 if (selector->relation() == CSSSelector::SubSelector)
309 continue; 297 continue;
310 isRightmostSelector = false; 298 isRightmostSelector = false;
311 if (selector->relation() == CSSSelector::DirectAdjacent || 299 if (selector->relation() == CSSSelector::DirectAdjacent ||
312 selector->relation() == CSSSelector::IndirectAdjacent) 300 selector->relation() == CSSSelector::IndirectAdjacent)
313 startFromParent = true; 301 startFromParent = true;
314 else 302 else
315 startFromParent = false; 303 startFromParent = false;
316 } 304 }
317 305
318 executeForTraverseRoot<SelectorQueryTrait>( 306 executeForTraverseRoot<SelectorQueryTrait>(&rootNode, rootNode, output);
319 *m_selectors[0], &rootNode, DoesNotMatchTraverseRoots, rootNode, output);
320 } 307 }
321 308
322 template <typename SelectorQueryTrait> 309 template <typename SelectorQueryTrait>
323 void SelectorQuery::executeForTraverseRoot( 310 void SelectorQuery::executeForTraverseRoot(
324 const CSSSelector& selector,
325 ContainerNode* traverseRoot, 311 ContainerNode* traverseRoot,
326 MatchTraverseRootState matchTraverseRoot,
327 ContainerNode& rootNode, 312 ContainerNode& rootNode,
328 typename SelectorQueryTrait::OutputType& output) const { 313 typename SelectorQueryTrait::OutputType& output) const {
314 DCHECK_EQ(m_selectors.size(), 1u);
315
329 if (!traverseRoot) 316 if (!traverseRoot)
330 return; 317 return;
331 318 const CSSSelector& selector = *m_selectors[0];
332 if (matchTraverseRoot) {
333 if (selectorMatches(selector, toElement(*traverseRoot), rootNode))
334 SelectorQueryTrait::appendElement(output, toElement(*traverseRoot));
335 return;
336 }
337 319
338 for (Element& element : ElementTraversal::descendantsOf(*traverseRoot)) { 320 for (Element& element : ElementTraversal::descendantsOf(*traverseRoot)) {
339 if (selectorMatches(selector, element, rootNode)) { 321 if (selectorMatches(selector, element, rootNode)) {
340 SelectorQueryTrait::appendElement(output, element); 322 SelectorQueryTrait::appendElement(output, element);
341 if (SelectorQueryTrait::shouldOnlyMatchFirstElement) 323 if (SelectorQueryTrait::shouldOnlyMatchFirstElement)
342 return; 324 return;
343 } 325 }
344 } 326 }
345 } 327 }
346 328
347 template <typename SelectorQueryTrait, typename SimpleElementListType> 329 template <typename SelectorQueryTrait, typename SimpleElementListType>
348 void SelectorQuery::executeForTraverseRoots( 330 void SelectorQuery::executeForTraverseRoots(
349 const CSSSelector& selector,
350 SimpleElementListType& traverseRoots, 331 SimpleElementListType& traverseRoots,
351 MatchTraverseRootState matchTraverseRoots, 332 MatchTraverseRootState matchTraverseRoots,
352 ContainerNode& rootNode, 333 ContainerNode& rootNode,
353 typename SelectorQueryTrait::OutputType& output) const { 334 typename SelectorQueryTrait::OutputType& output) const {
335 DCHECK_EQ(m_selectors.size(), 1u);
336
354 if (traverseRoots.isEmpty()) 337 if (traverseRoots.isEmpty())
355 return; 338 return;
356 339
340 const CSSSelector& selector = *m_selectors[0];
341
357 if (matchTraverseRoots) { 342 if (matchTraverseRoots) {
358 while (!traverseRoots.isEmpty()) { 343 while (!traverseRoots.isEmpty()) {
359 Element& element = *traverseRoots.next(); 344 Element& element = *traverseRoots.next();
360 if (selectorMatches(selector, element, rootNode)) { 345 if (selectorMatches(selector, element, rootNode)) {
361 SelectorQueryTrait::appendElement(output, element); 346 SelectorQueryTrait::appendElement(output, element);
362 if (SelectorQueryTrait::shouldOnlyMatchFirstElement) 347 if (SelectorQueryTrait::shouldOnlyMatchFirstElement)
363 return; 348 return;
364 } 349 }
365 } 350 }
366 return; 351 return;
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
620 return m_entries 605 return m_entries
621 .insert(selectors, SelectorQuery::adopt(std::move(selectorList))) 606 .insert(selectors, SelectorQuery::adopt(std::move(selectorList)))
622 .storedValue->value.get(); 607 .storedValue->value.get();
623 } 608 }
624 609
625 void SelectorQueryCache::invalidate() { 610 void SelectorQueryCache::invalidate() {
626 m_entries.clear(); 611 m_entries.clear();
627 } 612 }
628 613
629 } // namespace blink 614 } // 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