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

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

Issue 53683007: Have SelectorQuery API take rootNode by reference (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 7 years, 1 month 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 | « Source/core/dom/SelectorQuery.h ('k') | Source/core/dom/StyleSheetScopingNodeList.h » ('j') | 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 Apple Inc. All rights reserved. 2 * Copyright (C) 2011 Apple Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 132
133 unsigned selectorCount = 0; 133 unsigned selectorCount = 0;
134 for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(selector)) 134 for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(selector))
135 selectorCount++; 135 selectorCount++;
136 136
137 m_selectors.reserveInitialCapacity(selectorCount); 137 m_selectors.reserveInitialCapacity(selectorCount);
138 for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(selector)) 138 for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(selector))
139 m_selectors.uncheckedAppend(SelectorData(selector, SelectorCheckerFastPa th::canUse(selector))); 139 m_selectors.uncheckedAppend(SelectorData(selector, SelectorCheckerFastPa th::canUse(selector)));
140 } 140 }
141 141
142 inline bool SelectorDataList::selectorMatches(const SelectorData& selectorData, Element* element, const Node* rootNode) const 142 inline bool SelectorDataList::selectorMatches(const SelectorData& selectorData, Element& element, const Node& rootNode) const
143 { 143 {
144 if (selectorData.isFastCheckable && !element->isSVGElement()) { 144 if (selectorData.isFastCheckable && !element.isSVGElement()) {
145 SelectorCheckerFastPath selectorCheckerFastPath(selectorData.selector, e lement); 145 SelectorCheckerFastPath selectorCheckerFastPath(selectorData.selector, e lement);
146 if (!selectorCheckerFastPath.matchesRightmostSelector(SelectorChecker::V isitedMatchDisabled)) 146 if (!selectorCheckerFastPath.matchesRightmostSelector(SelectorChecker::V isitedMatchDisabled))
147 return false; 147 return false;
148 return selectorCheckerFastPath.matches(); 148 return selectorCheckerFastPath.matches();
149 } 149 }
150 150
151 SelectorChecker selectorChecker(element->document(), SelectorChecker::Queryi ngRules); 151 SelectorChecker selectorChecker(element.document(), SelectorChecker::Queryin gRules);
152 SelectorChecker::SelectorCheckingContext selectorCheckingContext(selectorDat a.selector, element, SelectorChecker::VisitedMatchDisabled); 152 SelectorChecker::SelectorCheckingContext selectorCheckingContext(selectorDat a.selector, &element, SelectorChecker::VisitedMatchDisabled);
153 selectorCheckingContext.behaviorAtBoundary = SelectorChecker::StaysWithinTre eScope; 153 selectorCheckingContext.behaviorAtBoundary = SelectorChecker::StaysWithinTre eScope;
154 selectorCheckingContext.scope = !rootNode->isDocumentNode() && rootNode->isC ontainerNode() ? toContainerNode(rootNode) : 0; 154 selectorCheckingContext.scope = !rootNode.isDocumentNode() && rootNode.isCon tainerNode() ? &toContainerNode(rootNode) : 0;
155 PseudoId ignoreDynamicPseudo = NOPSEUDO; 155 PseudoId ignoreDynamicPseudo = NOPSEUDO;
156 return selectorChecker.match(selectorCheckingContext, ignoreDynamicPseudo, D OMSiblingTraversalStrategy()) == SelectorChecker::SelectorMatches; 156 return selectorChecker.match(selectorCheckingContext, ignoreDynamicPseudo, D OMSiblingTraversalStrategy()) == SelectorChecker::SelectorMatches;
157 } 157 }
158 158
159 bool SelectorDataList::matches(Element* targetElement) const 159 bool SelectorDataList::matches(Element& targetElement) const
160 { 160 {
161 ASSERT(targetElement);
162
163 unsigned selectorCount = m_selectors.size(); 161 unsigned selectorCount = m_selectors.size();
164 for (unsigned i = 0; i < selectorCount; ++i) { 162 for (unsigned i = 0; i < selectorCount; ++i) {
165 if (selectorMatches(m_selectors[i], targetElement, targetElement)) 163 if (selectorMatches(m_selectors[i], targetElement, targetElement))
166 return true; 164 return true;
167 } 165 }
168 166
169 return false; 167 return false;
170 } 168 }
171 169
172 PassRefPtr<NodeList> SelectorDataList::queryAll(Node* rootNode) const 170 PassRefPtr<NodeList> SelectorDataList::queryAll(Node& rootNode) const
173 { 171 {
174 Vector<RefPtr<Node> > result; 172 Vector<RefPtr<Node> > result;
175 executeQueryAll(rootNode, result); 173 executeQueryAll(rootNode, result);
176 return StaticNodeList::adopt(result); 174 return StaticNodeList::adopt(result);
177 } 175 }
178 176
179 PassRefPtr<Element> SelectorDataList::queryFirst(Node* rootNode) const 177 PassRefPtr<Element> SelectorDataList::queryFirst(Node& rootNode) const
180 { 178 {
181 return executeQueryFirst(rootNode); 179 return executeQueryFirst(rootNode);
182 } 180 }
183 181
184 static inline bool isTreeScopeRoot(Node* node) 182 static inline bool isTreeScopeRoot(Node* node)
185 { 183 {
186 ASSERT(node); 184 ASSERT(node);
187 return node->isDocumentNode() || node->isShadowRoot(); 185 return node->isDocumentNode() || node->isShadowRoot();
188 } 186 }
189 187
190 void SelectorDataList::collectElementsByClassName(Node* rootNode, const AtomicSt ring& className, Vector<RefPtr<Node> >& traversalRoots) const 188 void SelectorDataList::collectElementsByClassName(Node& rootNode, const AtomicSt ring& className, Vector<RefPtr<Node> >& traversalRoots) const
191 { 189 {
192 for (Element* element = ElementTraversal::firstWithin(rootNode); element; el ement = ElementTraversal::next(element, rootNode)) { 190 for (Element* element = ElementTraversal::firstWithin(&rootNode); element; e lement = ElementTraversal::next(element, &rootNode)) {
193 if (element->hasClass() && element->classNames().contains(className)) 191 if (element->hasClass() && element->classNames().contains(className))
194 traversalRoots.append(element); 192 traversalRoots.append(element);
195 } 193 }
196 } 194 }
197 195
198 void SelectorDataList::collectElementsByTagName(Node* rootNode, const QualifiedN ame& tagName, Vector<RefPtr<Node> >& traversalRoots) const 196 void SelectorDataList::collectElementsByTagName(Node& rootNode, const QualifiedN ame& tagName, Vector<RefPtr<Node> >& traversalRoots) const
199 { 197 {
200 for (Element* element = ElementTraversal::firstWithin(rootNode); element; el ement = ElementTraversal::next(element, rootNode)) { 198 for (Element* element = ElementTraversal::firstWithin(&rootNode); element; e lement = ElementTraversal::next(element, &rootNode)) {
201 if (SelectorChecker::tagMatches(element, tagName)) 199 if (SelectorChecker::tagMatches(*element, tagName))
202 traversalRoots.append(element); 200 traversalRoots.append(element);
203 } 201 }
204 } 202 }
205 203
206 Element* SelectorDataList::findElementByClassName(Node* rootNode, const AtomicSt ring& className) const 204 Element* SelectorDataList::findElementByClassName(Node& rootNode, const AtomicSt ring& className) const
207 { 205 {
208 for (Element* element = ElementTraversal::firstWithin(rootNode); element; el ement = ElementTraversal::next(element, rootNode)) { 206 for (Element* element = ElementTraversal::firstWithin(&rootNode); element; e lement = ElementTraversal::next(element, &rootNode)) {
209 if (element->hasClass() && element->classNames().contains(className)) 207 if (element->hasClass() && element->classNames().contains(className))
210 return element; 208 return element;
211 } 209 }
212 return 0; 210 return 0;
213 } 211 }
214 212
215 Element* SelectorDataList::findElementByTagName(Node* rootNode, const QualifiedN ame& tagName) const 213 Element* SelectorDataList::findElementByTagName(Node& rootNode, const QualifiedN ame& tagName) const
216 { 214 {
217 for (Element* element = ElementTraversal::firstWithin(rootNode); element; el ement = ElementTraversal::next(element, rootNode)) { 215 for (Element* element = ElementTraversal::firstWithin(&rootNode); element; e lement = ElementTraversal::next(element, &rootNode)) {
218 if (SelectorChecker::tagMatches(element, tagName)) 216 if (SelectorChecker::tagMatches(*element, tagName))
219 return element; 217 return element;
220 } 218 }
221 return 0; 219 return 0;
222 } 220 }
223 221
224 inline bool SelectorDataList::canUseFastQuery(Node* rootNode) const 222 inline bool SelectorDataList::canUseFastQuery(const Node& rootNode) const
225 { 223 {
226 return m_selectors.size() == 1 && rootNode->inDocument() && !rootNode->docum ent().inQuirksMode(); 224 return m_selectors.size() == 1 && rootNode.inDocument() && !rootNode.documen t().inQuirksMode();
227 } 225 }
228 226
229 inline bool ancestorHasClassName(Node* rootNode, const AtomicString& className) 227 inline bool ancestorHasClassName(Node* rootNode, const AtomicString& className)
230 { 228 {
231 if (!rootNode->isElementNode()) 229 if (!rootNode->isElementNode())
232 return false; 230 return false;
233 231
234 for (Element* element = toElement(rootNode); element; element = element->par entElement()) { 232 for (Element* element = toElement(rootNode); element; element = element->par entElement()) {
235 if (element->hasClass() && element->classNames().contains(className)) 233 if (element->hasClass() && element->classNames().contains(className))
236 return true; 234 return true;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 if (selector->relation() == CSSSelector::DirectAdjacent || selector->rel ation() == CSSSelector::IndirectAdjacent) 294 if (selector->relation() == CSSSelector::DirectAdjacent || selector->rel ation() == CSSSelector::IndirectAdjacent)
297 startFromParent = true; 295 startFromParent = true;
298 else 296 else
299 startFromParent = false; 297 startFromParent = false;
300 } 298 }
301 299
302 matchTraverseRoots = false; 300 matchTraverseRoots = false;
303 return adoptPtr(new SingleNodeList(rootNode)); 301 return adoptPtr(new SingleNodeList(rootNode));
304 } 302 }
305 303
306 void SelectorDataList::executeSlowQueryAll(Node* rootNode, Vector<RefPtr<Node> > & matchedElements) const 304 void SelectorDataList::executeSlowQueryAll(Node& rootNode, Vector<RefPtr<Node> > & matchedElements) const
307 { 305 {
308 for (Element* element = ElementTraversal::firstWithin(rootNode); element; el ement = ElementTraversal::next(element, rootNode)) { 306 for (Element* element = ElementTraversal::firstWithin(&rootNode); element; e lement = ElementTraversal::next(element, &rootNode)) {
309 for (unsigned i = 0; i < m_selectors.size(); ++i) { 307 for (unsigned i = 0; i < m_selectors.size(); ++i) {
310 if (selectorMatches(m_selectors[i], element, rootNode)) { 308 if (selectorMatches(m_selectors[i], *element, rootNode)) {
311 matchedElements.append(element); 309 matchedElements.append(element);
312 break; 310 break;
313 } 311 }
314 } 312 }
315 } 313 }
316 } 314 }
317 315
318 void SelectorDataList::executeQueryAll(Node* rootNode, Vector<RefPtr<Node> >& ma tchedElements) const 316 void SelectorDataList::executeQueryAll(Node& rootNode, Vector<RefPtr<Node> >& ma tchedElements) const
319 { 317 {
320 if (!canUseFastQuery(rootNode)) 318 if (!canUseFastQuery(rootNode))
321 return executeSlowQueryAll(rootNode, matchedElements); 319 return executeSlowQueryAll(rootNode, matchedElements);
322 320
323 ASSERT(m_selectors.size() == 1); 321 ASSERT(m_selectors.size() == 1);
324 ASSERT(m_selectors[0].selector); 322 ASSERT(m_selectors[0].selector);
325 323
326 const CSSSelector* firstSelector = m_selectors[0].selector; 324 const CSSSelector* firstSelector = m_selectors[0].selector;
327 325
328 if (!firstSelector->tagHistory()) { 326 if (!firstSelector->tagHistory()) {
329 // Fast path for querySelectorAll('#id'), querySelectorAl('.foo'), and q uerySelectorAll('div'). 327 // Fast path for querySelectorAll('#id'), querySelectorAl('.foo'), and q uerySelectorAll('div').
330 switch (firstSelector->m_match) { 328 switch (firstSelector->m_match) {
331 case CSSSelector::Id: 329 case CSSSelector::Id:
332 { 330 {
333 if (rootNode->document().containsMultipleElementsWithId(firstSel ector->value())) 331 if (rootNode.document().containsMultipleElementsWithId(firstSele ctor->value()))
334 break; 332 break;
335 333
336 // Just the same as getElementById. 334 // Just the same as getElementById.
337 Element* element = rootNode->treeScope().getElementById(firstSel ector->value()); 335 Element* element = rootNode.treeScope().getElementById(firstSele ctor->value());
338 if (element && (isTreeScopeRoot(rootNode) || element->isDescenda ntOf(rootNode))) 336 if (element && (isTreeScopeRoot(rootNode) || element->isDescenda ntOf(&rootNode)))
339 matchedElements.append(element); 337 matchedElements.append(element);
340 return; 338 return;
341 } 339 }
342 case CSSSelector::Class: 340 case CSSSelector::Class:
343 return collectElementsByClassName(rootNode, firstSelector->value(), matchedElements); 341 return collectElementsByClassName(rootNode, firstSelector->value(), matchedElements);
344 case CSSSelector::Tag: 342 case CSSSelector::Tag:
345 return collectElementsByTagName(rootNode, firstSelector->tagQName(), matchedElements); 343 return collectElementsByTagName(rootNode, firstSelector->tagQName(), matchedElements);
346 default: 344 default:
347 break; // If we need another fast path, add here. 345 break; // If we need another fast path, add here.
348 } 346 }
349 } 347 }
350 348
351 bool matchTraverseRoots; 349 bool matchTraverseRoots;
352 OwnPtr<SimpleNodeList> traverseRoots = findTraverseRoots(rootNode, matchTrav erseRoots); 350 OwnPtr<SimpleNodeList> traverseRoots = findTraverseRoots(&rootNode, matchTra verseRoots);
353 if (traverseRoots->isEmpty()) 351 if (traverseRoots->isEmpty())
354 return; 352 return;
355 353
356 const SelectorData& selector = m_selectors[0]; 354 const SelectorData& selector = m_selectors[0];
357 if (matchTraverseRoots) { 355 if (matchTraverseRoots) {
358 while (!traverseRoots->isEmpty()) { 356 while (!traverseRoots->isEmpty()) {
359 Node* node = traverseRoots->next(); 357 Node& node = *traverseRoots->next();
360 Element* element = toElement(node); 358 Element& element = toElement(node);
361 if (selectorMatches(selector, element, rootNode)) 359 if (selectorMatches(selector, element, rootNode))
362 matchedElements.append(element); 360 matchedElements.append(&element);
363 } 361 }
364 return; 362 return;
365 } 363 }
366 364
367 while (!traverseRoots->isEmpty()) { 365 while (!traverseRoots->isEmpty()) {
368 Node* traverseRoot = traverseRoots->next(); 366 Node* traverseRoot = traverseRoots->next();
369 for (Element* element = ElementTraversal::firstWithin(traverseRoot); ele ment; element = ElementTraversal::next(element, traverseRoot)) { 367 for (Element* element = ElementTraversal::firstWithin(traverseRoot); ele ment; element = ElementTraversal::next(element, traverseRoot)) {
370 if (selectorMatches(selector, element, rootNode)) 368 if (selectorMatches(selector, *element, rootNode))
371 matchedElements.append(element); 369 matchedElements.append(element);
372 } 370 }
373 } 371 }
374 } 372 }
375 373
376 // If matchTraverseRoot is true, the returned Node is the single Element that ma y match the selector query. 374 // If matchTraverseRoot is true, the returned Node is the single Element that ma y match the selector query.
377 // 375 //
378 // If matchTraverseRoot is false, the returned Node is the rootNode parameter or a descendant of rootNode representing 376 // If matchTraverseRoot is false, the returned Node is the rootNode parameter or a descendant of rootNode representing
379 // the subtree for which we can limit the querySelector traversal. 377 // the subtree for which we can limit the querySelector traversal.
380 // 378 //
381 // The returned Node may be 0, regardless of matchTraverseRoot, if this method f inds that the selectors won't 379 // The returned Node may be 0, regardless of matchTraverseRoot, if this method f inds that the selectors won't
382 // match any element. 380 // match any element.
383 Node* SelectorDataList::findTraverseRoot(Node* rootNode, bool& matchTraverseRoot ) const 381 Node* SelectorDataList::findTraverseRoot(Node& rootNode, bool& matchTraverseRoot ) const
384 { 382 {
385 // We need to return the matches in document order. To use id lookup while t here is possiblity of multiple matches 383 // We need to return the matches in document order. To use id lookup while t here is possiblity of multiple matches
386 // we would need to sort the results. For now, just traverse the document in that case. 384 // we would need to sort the results. For now, just traverse the document in that case.
387 ASSERT(rootNode);
388 ASSERT(m_selectors.size() == 1); 385 ASSERT(m_selectors.size() == 1);
389 ASSERT(m_selectors[0].selector); 386 ASSERT(m_selectors[0].selector);
390 387
391 bool matchSingleNode = true; 388 bool matchSingleNode = true;
392 bool startFromParent = false; 389 bool startFromParent = false;
393 for (const CSSSelector* selector = m_selectors[0].selector; selector; select or = selector->tagHistory()) { 390 for (const CSSSelector* selector = m_selectors[0].selector; selector; select or = selector->tagHistory()) {
394 if (selector->m_match == CSSSelector::Id && !rootNode->document().contai nsMultipleElementsWithId(selector->value())) { 391 if (selector->m_match == CSSSelector::Id && !rootNode.document().contain sMultipleElementsWithId(selector->value())) {
395 Element* element = rootNode->treeScope().getElementById(selector->va lue()); 392 Element* element = rootNode.treeScope().getElementById(selector->val ue());
396 if (element && (isTreeScopeRoot(rootNode) || element->isDescendantOf (rootNode))) 393 Node* adjustedRootNode = &rootNode;
397 rootNode = element; 394 if (element && (isTreeScopeRoot(rootNode) || element->isDescendantOf (&rootNode)))
395 adjustedRootNode = element;
398 else if (!element || matchSingleNode) 396 else if (!element || matchSingleNode)
399 rootNode = 0; 397 adjustedRootNode = 0;
400 if (matchSingleNode) { 398 if (matchSingleNode) {
401 matchTraverseRoot = true; 399 matchTraverseRoot = true;
402 return rootNode; 400 return adjustedRootNode;
403 } 401 }
404 if (startFromParent && rootNode) 402 if (startFromParent && adjustedRootNode)
405 rootNode = rootNode->parentNode(); 403 adjustedRootNode = adjustedRootNode->parentNode();
406 matchTraverseRoot = false; 404 matchTraverseRoot = false;
407 return rootNode; 405 return adjustedRootNode;
408 } 406 }
409 if (selector->relation() == CSSSelector::SubSelector) 407 if (selector->relation() == CSSSelector::SubSelector)
410 continue; 408 continue;
411 matchSingleNode = false; 409 matchSingleNode = false;
412 if (selector->relation() == CSSSelector::DirectAdjacent || selector->rel ation() == CSSSelector::IndirectAdjacent) 410 if (selector->relation() == CSSSelector::DirectAdjacent || selector->rel ation() == CSSSelector::IndirectAdjacent)
413 startFromParent = true; 411 startFromParent = true;
414 else 412 else
415 startFromParent = false; 413 startFromParent = false;
416 } 414 }
417 matchTraverseRoot = false; 415 matchTraverseRoot = false;
418 return rootNode; 416 return &rootNode;
419 } 417 }
420 418
421 Element* SelectorDataList::executeSlowQueryFirst(Node* rootNode) const 419 Element* SelectorDataList::executeSlowQueryFirst(Node& rootNode) const
422 { 420 {
423 for (Element* element = ElementTraversal::firstWithin(rootNode); element; el ement = ElementTraversal::next(element, rootNode)) { 421 for (Element* element = ElementTraversal::firstWithin(&rootNode); element; e lement = ElementTraversal::next(element, &rootNode)) {
424 for (unsigned i = 0; i < m_selectors.size(); ++i) { 422 for (unsigned i = 0; i < m_selectors.size(); ++i) {
425 if (selectorMatches(m_selectors[i], element, rootNode)) 423 if (selectorMatches(m_selectors[i], *element, rootNode))
426 return element; 424 return element;
427 } 425 }
428 } 426 }
429 return 0; 427 return 0;
430 } 428 }
431 429
432 Element* SelectorDataList::executeQueryFirst(Node* rootNode) const 430 Element* SelectorDataList::executeQueryFirst(Node& rootNode) const
433 { 431 {
434 if (!canUseFastQuery(rootNode)) 432 if (!canUseFastQuery(rootNode))
435 return executeSlowQueryFirst(rootNode); 433 return executeSlowQueryFirst(rootNode);
436 434
437 435
438 const CSSSelector* selector = m_selectors[0].selector; 436 const CSSSelector* selector = m_selectors[0].selector;
439 ASSERT(selector); 437 ASSERT(selector);
440 438
441 if (!selector->tagHistory()) { 439 if (!selector->tagHistory()) {
442 // Fast path for querySelector('#id'), querySelector('.foo'), and queryS elector('div'). 440 // Fast path for querySelector('#id'), querySelector('.foo'), and queryS elector('div').
443 // Many web developers uses querySelector with these simple selectors. 441 // Many web developers uses querySelector with these simple selectors.
444 switch (selector->m_match) { 442 switch (selector->m_match) {
445 case CSSSelector::Id: 443 case CSSSelector::Id:
446 { 444 {
447 if (rootNode->document().containsMultipleElementsWithId(selector ->value())) 445 if (rootNode.document().containsMultipleElementsWithId(selector- >value()))
448 break; 446 break;
449 Element* element = rootNode->treeScope().getElementById(selector ->value()); 447 Element* element = rootNode.treeScope().getElementById(selector- >value());
450 return element && (isTreeScopeRoot(rootNode) || element->isDesce ndantOf(rootNode)) ? element : 0; 448 return element && (isTreeScopeRoot(rootNode) || element->isDesce ndantOf(&rootNode)) ? element : 0;
451 } 449 }
452 case CSSSelector::Class: 450 case CSSSelector::Class:
453 return findElementByClassName(rootNode, selector->value()); 451 return findElementByClassName(rootNode, selector->value());
454 case CSSSelector::Tag: 452 case CSSSelector::Tag:
455 return findElementByTagName(rootNode, selector->tagQName()); 453 return findElementByTagName(rootNode, selector->tagQName());
456 default: 454 default:
457 break; // If we need another fast path, add here. 455 break; // If we need another fast path, add here.
458 } 456 }
459 } 457 }
460 458
461 bool matchTraverseRoot; 459 bool matchTraverseRoot;
462 Node* traverseRootNode = findTraverseRoot(rootNode, matchTraverseRoot); 460 Node* traverseRootNode = findTraverseRoot(rootNode, matchTraverseRoot);
463 if (!traverseRootNode) 461 if (!traverseRootNode)
464 return 0; 462 return 0;
465 if (matchTraverseRoot) { 463 if (matchTraverseRoot) {
466 ASSERT(m_selectors.size() == 1); 464 ASSERT(m_selectors.size() == 1);
467 ASSERT(traverseRootNode->isElementNode()); 465 ASSERT(traverseRootNode->isElementNode());
468 Element* element = toElement(traverseRootNode); 466 Element& element = toElement(*traverseRootNode);
469 return selectorMatches(m_selectors[0], element, rootNode) ? element : 0; 467 return selectorMatches(m_selectors[0], element, rootNode) ? &element : 0 ;
470 } 468 }
471 469
472 for (Element* element = ElementTraversal::firstWithin(traverseRootNode); ele ment; element = ElementTraversal::next(element, traverseRootNode)) { 470 for (Element* element = ElementTraversal::firstWithin(traverseRootNode); ele ment; element = ElementTraversal::next(element, traverseRootNode)) {
473 if (selectorMatches(m_selectors[0], element, rootNode)) 471 if (selectorMatches(m_selectors[0], *element, rootNode))
474 return element; 472 return element;
475 } 473 }
476 return 0; 474 return 0;
477 } 475 }
478 476
479 SelectorQuery::SelectorQuery(const CSSSelectorList& selectorList) 477 SelectorQuery::SelectorQuery(const CSSSelectorList& selectorList)
480 : m_selectorList(selectorList) 478 : m_selectorList(selectorList)
481 { 479 {
482 m_selectors.initialize(m_selectorList); 480 m_selectors.initialize(m_selectorList);
483 } 481 }
484 482
485 bool SelectorQuery::matches(Element* element) const 483 bool SelectorQuery::matches(Element& element) const
486 { 484 {
487 return m_selectors.matches(element); 485 return m_selectors.matches(element);
488 } 486 }
489 487
490 PassRefPtr<NodeList> SelectorQuery::queryAll(Node* rootNode) const 488 PassRefPtr<NodeList> SelectorQuery::queryAll(Node& rootNode) const
491 { 489 {
492 return m_selectors.queryAll(rootNode); 490 return m_selectors.queryAll(rootNode);
493 } 491 }
494 492
495 PassRefPtr<Element> SelectorQuery::queryFirst(Node* rootNode) const 493 PassRefPtr<Element> SelectorQuery::queryFirst(Node& rootNode) const
496 { 494 {
497 return m_selectors.queryFirst(rootNode); 495 return m_selectors.queryFirst(rootNode);
498 } 496 }
499 497
500 SelectorQuery* SelectorQueryCache::add(const AtomicString& selectors, const Docu ment& document, ExceptionState& es) 498 SelectorQuery* SelectorQueryCache::add(const AtomicString& selectors, const Docu ment& document, ExceptionState& es)
501 { 499 {
502 HashMap<AtomicString, OwnPtr<SelectorQuery> >::iterator it = m_entries.find( selectors); 500 HashMap<AtomicString, OwnPtr<SelectorQuery> >::iterator it = m_entries.find( selectors);
503 if (it != m_entries.end()) 501 if (it != m_entries.end())
504 return it->value.get(); 502 return it->value.get();
505 503
(...skipping 21 matching lines...) Expand all
527 m_entries.add(selectors, selectorQuery.release()); 525 m_entries.add(selectors, selectorQuery.release());
528 return rawSelectorQuery; 526 return rawSelectorQuery;
529 } 527 }
530 528
531 void SelectorQueryCache::invalidate() 529 void SelectorQueryCache::invalidate()
532 { 530 {
533 m_entries.clear(); 531 m_entries.clear();
534 } 532 }
535 533
536 } 534 }
OLDNEW
« no previous file with comments | « Source/core/dom/SelectorQuery.h ('k') | Source/core/dom/StyleSheetScopingNodeList.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698