OLD | NEW |
---|---|
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 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
172 Vector<RefPtr<Node> > result; | 172 Vector<RefPtr<Node> > result; |
173 executeQueryAll(rootNode, result); | 173 executeQueryAll(rootNode, result); |
174 return StaticNodeList::adopt(result); | 174 return StaticNodeList::adopt(result); |
175 } | 175 } |
176 | 176 |
177 PassRefPtr<Element> SelectorDataList::queryFirst(Node& rootNode) const | 177 PassRefPtr<Element> SelectorDataList::queryFirst(Node& rootNode) const |
178 { | 178 { |
179 return executeQueryFirst(rootNode); | 179 return executeQueryFirst(rootNode); |
180 } | 180 } |
181 | 181 |
182 // FIXME: StyleSheetScopingNodeList also has isTreeScopeRoot. | |
183 // Need to move TreeScope.h to remove duplicate functions. | |
Hajime Morrita
2013/11/18 05:02:52
Let's do this in this change.
tasak
2013/11/18 05:45:56
Done.
| |
182 static inline bool isTreeScopeRoot(Node* node) | 184 static inline bool isTreeScopeRoot(Node* node) |
183 { | 185 { |
184 ASSERT(node); | 186 ASSERT(node); |
185 return node->isDocumentNode() || node->isShadowRoot(); | 187 return node->isDocumentNode() || node->isShadowRoot(); |
186 } | 188 } |
187 | 189 |
188 void SelectorDataList::collectElementsByClassName(Node& rootNode, const AtomicSt ring& className, Vector<RefPtr<Node> >& traversalRoots) const | 190 void SelectorDataList::collectElementsByClassName(Node& rootNode, const AtomicSt ring& className, Vector<RefPtr<Node> >& traversalRoots) const |
189 { | 191 { |
190 for (Element* element = ElementTraversal::firstWithin(rootNode); element; el ement = ElementTraversal::next(*element, &rootNode)) { | 192 for (Element* element = ElementTraversal::firstWithin(rootNode); element; el ement = ElementTraversal::next(*element, &rootNode)) { |
191 if (element->hasClass() && element->classNames().contains(className)) | 193 if (element->hasClass() && element->classNames().contains(className)) |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
326 if (!firstSelector->tagHistory()) { | 328 if (!firstSelector->tagHistory()) { |
327 // Fast path for querySelectorAll('#id'), querySelectorAl('.foo'), and q uerySelectorAll('div'). | 329 // Fast path for querySelectorAll('#id'), querySelectorAl('.foo'), and q uerySelectorAll('div'). |
328 switch (firstSelector->m_match) { | 330 switch (firstSelector->m_match) { |
329 case CSSSelector::Id: | 331 case CSSSelector::Id: |
330 { | 332 { |
331 if (rootNode.document().containsMultipleElementsWithId(firstSele ctor->value())) | 333 if (rootNode.document().containsMultipleElementsWithId(firstSele ctor->value())) |
332 break; | 334 break; |
333 | 335 |
334 // Just the same as getElementById. | 336 // Just the same as getElementById. |
335 Element* element = rootNode.treeScope().getElementById(firstSele ctor->value()); | 337 Element* element = rootNode.treeScope().getElementById(firstSele ctor->value()); |
336 if (element && (isTreeScopeRoot(rootNode) || element->isDescenda ntOf(&rootNode))) | 338 if (element && (isTreeScopeRoot(&rootNode) || element->isDescend antOf(&rootNode))) |
337 matchedElements.append(element); | 339 matchedElements.append(element); |
338 return; | 340 return; |
339 } | 341 } |
340 case CSSSelector::Class: | 342 case CSSSelector::Class: |
341 return collectElementsByClassName(rootNode, firstSelector->value(), matchedElements); | 343 return collectElementsByClassName(rootNode, firstSelector->value(), matchedElements); |
342 case CSSSelector::Tag: | 344 case CSSSelector::Tag: |
343 return collectElementsByTagName(rootNode, firstSelector->tagQName(), matchedElements); | 345 return collectElementsByTagName(rootNode, firstSelector->tagQName(), matchedElements); |
344 default: | 346 default: |
345 break; // If we need another fast path, add here. | 347 break; // If we need another fast path, add here. |
346 } | 348 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
385 // we would need to sort the results. For now, just traverse the document in that case. | 387 // we would need to sort the results. For now, just traverse the document in that case. |
386 ASSERT(m_selectors.size() == 1); | 388 ASSERT(m_selectors.size() == 1); |
387 ASSERT(m_selectors[0].selector); | 389 ASSERT(m_selectors[0].selector); |
388 | 390 |
389 bool matchSingleNode = true; | 391 bool matchSingleNode = true; |
390 bool startFromParent = false; | 392 bool startFromParent = false; |
391 for (const CSSSelector* selector = m_selectors[0].selector; selector; select or = selector->tagHistory()) { | 393 for (const CSSSelector* selector = m_selectors[0].selector; selector; select or = selector->tagHistory()) { |
392 if (selector->m_match == CSSSelector::Id && !rootNode.document().contain sMultipleElementsWithId(selector->value())) { | 394 if (selector->m_match == CSSSelector::Id && !rootNode.document().contain sMultipleElementsWithId(selector->value())) { |
393 Element* element = rootNode.treeScope().getElementById(selector->val ue()); | 395 Element* element = rootNode.treeScope().getElementById(selector->val ue()); |
394 Node* adjustedRootNode = &rootNode; | 396 Node* adjustedRootNode = &rootNode; |
395 if (element && (isTreeScopeRoot(rootNode) || element->isDescendantOf (&rootNode))) | 397 if (element && (isTreeScopeRoot(&rootNode) || element->isDescendantO f(&rootNode))) |
396 adjustedRootNode = element; | 398 adjustedRootNode = element; |
397 else if (!element || matchSingleNode) | 399 else if (!element || matchSingleNode) |
398 adjustedRootNode = 0; | 400 adjustedRootNode = 0; |
399 if (matchSingleNode) { | 401 if (matchSingleNode) { |
400 matchTraverseRoot = true; | 402 matchTraverseRoot = true; |
401 return adjustedRootNode; | 403 return adjustedRootNode; |
402 } | 404 } |
403 if (startFromParent && adjustedRootNode) | 405 if (startFromParent && adjustedRootNode) |
404 adjustedRootNode = adjustedRootNode->parentNode(); | 406 adjustedRootNode = adjustedRootNode->parentNode(); |
405 matchTraverseRoot = false; | 407 matchTraverseRoot = false; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
439 | 441 |
440 if (!selector->tagHistory()) { | 442 if (!selector->tagHistory()) { |
441 // Fast path for querySelector('#id'), querySelector('.foo'), and queryS elector('div'). | 443 // Fast path for querySelector('#id'), querySelector('.foo'), and queryS elector('div'). |
442 // Many web developers uses querySelector with these simple selectors. | 444 // Many web developers uses querySelector with these simple selectors. |
443 switch (selector->m_match) { | 445 switch (selector->m_match) { |
444 case CSSSelector::Id: | 446 case CSSSelector::Id: |
445 { | 447 { |
446 if (rootNode.document().containsMultipleElementsWithId(selector- >value())) | 448 if (rootNode.document().containsMultipleElementsWithId(selector- >value())) |
447 break; | 449 break; |
448 Element* element = rootNode.treeScope().getElementById(selector- >value()); | 450 Element* element = rootNode.treeScope().getElementById(selector- >value()); |
449 return element && (isTreeScopeRoot(rootNode) || element->isDesce ndantOf(&rootNode)) ? element : 0; | 451 return element && (isTreeScopeRoot(&rootNode) || element->isDesc endantOf(&rootNode)) ? element : 0; |
450 } | 452 } |
451 case CSSSelector::Class: | 453 case CSSSelector::Class: |
452 return findElementByClassName(rootNode, selector->value()); | 454 return findElementByClassName(rootNode, selector->value()); |
453 case CSSSelector::Tag: | 455 case CSSSelector::Tag: |
454 return findElementByTagName(rootNode, selector->tagQName()); | 456 return findElementByTagName(rootNode, selector->tagQName()); |
455 default: | 457 default: |
456 break; // If we need another fast path, add here. | 458 break; // If we need another fast path, add here. |
457 } | 459 } |
458 } | 460 } |
459 | 461 |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
526 m_entries.add(selectors, selectorQuery.release()); | 528 m_entries.add(selectors, selectorQuery.release()); |
527 return rawSelectorQuery; | 529 return rawSelectorQuery; |
528 } | 530 } |
529 | 531 |
530 void SelectorQueryCache::invalidate() | 532 void SelectorQueryCache::invalidate() |
531 { | 533 { |
532 m_entries.clear(); | 534 m_entries.clear(); |
533 } | 535 } |
534 | 536 |
535 } | 537 } |
OLD | NEW |