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 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
239 // we would need to sort the results. For now, just traverse the document in
that case. | 239 // we would need to sort the results. For now, just traverse the document in
that case. |
240 ASSERT(rootNode); | 240 ASSERT(rootNode); |
241 ASSERT(m_selectors.size() == 1); | 241 ASSERT(m_selectors.size() == 1); |
242 ASSERT(m_selectors[0].selector); | 242 ASSERT(m_selectors[0].selector); |
243 | 243 |
244 bool isRightmostSelector = true; | 244 bool isRightmostSelector = true; |
245 bool startFromParent = false; | 245 bool startFromParent = false; |
246 | 246 |
247 for (const CSSSelector* selector = m_selectors[0].selector; selector; select
or = selector->tagHistory()) { | 247 for (const CSSSelector* selector = m_selectors[0].selector; selector; select
or = selector->tagHistory()) { |
248 if (selector->m_match == CSSSelector::Id && !rootNode->document().contai
nsMultipleElementsWithId(selector->value())) { | 248 if (selector->m_match == CSSSelector::Id && !rootNode->document().contai
nsMultipleElementsWithId(selector->value())) { |
249 Element* element = rootNode->treeScope().getElementById(selector->va
lue()); | 249 Element* element = rootNode->treeScope()->getElementById(selector->v
alue()); |
250 if (element && (isTreeScopeRoot(rootNode) || element->isDescendantOf
(rootNode))) | 250 if (element && (isTreeScopeRoot(rootNode) || element->isDescendantOf
(rootNode))) |
251 rootNode = element; | 251 rootNode = element; |
252 else if (!element || isRightmostSelector) | 252 else if (!element || isRightmostSelector) |
253 rootNode = 0; | 253 rootNode = 0; |
254 if (isRightmostSelector) { | 254 if (isRightmostSelector) { |
255 matchTraverseRoots = true; | 255 matchTraverseRoots = true; |
256 return adoptPtr(new SingleNodeList(rootNode)); | 256 return adoptPtr(new SingleNodeList(rootNode)); |
257 } | 257 } |
258 if (startFromParent && rootNode) | 258 if (startFromParent && rootNode) |
259 rootNode = rootNode->parentNode(); | 259 rootNode = rootNode->parentNode(); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
310 | 310 |
311 if (!firstSelector->tagHistory()) { | 311 if (!firstSelector->tagHistory()) { |
312 // Fast path for querySelectorAll('#id'), querySelectorAl('.foo'), and q
uerySelectorAll('div'). | 312 // Fast path for querySelectorAll('#id'), querySelectorAl('.foo'), and q
uerySelectorAll('div'). |
313 switch (firstSelector->m_match) { | 313 switch (firstSelector->m_match) { |
314 case CSSSelector::Id: | 314 case CSSSelector::Id: |
315 { | 315 { |
316 if (rootNode->document().containsMultipleElementsWithId(firstSel
ector->value())) | 316 if (rootNode->document().containsMultipleElementsWithId(firstSel
ector->value())) |
317 break; | 317 break; |
318 | 318 |
319 // Just the same as getElementById. | 319 // Just the same as getElementById. |
320 Element* element = rootNode->treeScope().getElementById(firstSel
ector->value()); | 320 Element* element = rootNode->treeScope()->getElementById(firstSe
lector->value()); |
321 if (element && (isTreeScopeRoot(rootNode) || element->isDescenda
ntOf(rootNode))) | 321 if (element && (isTreeScopeRoot(rootNode) || element->isDescenda
ntOf(rootNode))) |
322 matchedElements.append(element); | 322 matchedElements.append(element); |
323 return; | 323 return; |
324 } | 324 } |
325 case CSSSelector::Class: | 325 case CSSSelector::Class: |
326 return collectElementsByClassName(rootNode, firstSelector->value(),
matchedElements); | 326 return collectElementsByClassName(rootNode, firstSelector->value(),
matchedElements); |
327 case CSSSelector::Tag: | 327 case CSSSelector::Tag: |
328 return collectElementsByTagName(rootNode, firstSelector->tagQName(),
matchedElements); | 328 return collectElementsByTagName(rootNode, firstSelector->tagQName(),
matchedElements); |
329 default: | 329 default: |
330 break; // If we need another fast path, add here. | 330 break; // If we need another fast path, add here. |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
368 // We need to return the matches in document order. To use id lookup while t
here is possiblity of multiple matches | 368 // We need to return the matches in document order. To use id lookup while t
here is possiblity of multiple matches |
369 // we would need to sort the results. For now, just traverse the document in
that case. | 369 // we would need to sort the results. For now, just traverse the document in
that case. |
370 ASSERT(rootNode); | 370 ASSERT(rootNode); |
371 ASSERT(m_selectors.size() == 1); | 371 ASSERT(m_selectors.size() == 1); |
372 ASSERT(m_selectors[0].selector); | 372 ASSERT(m_selectors[0].selector); |
373 | 373 |
374 bool matchSingleNode = true; | 374 bool matchSingleNode = true; |
375 bool startFromParent = false; | 375 bool startFromParent = false; |
376 for (const CSSSelector* selector = m_selectors[0].selector; selector; select
or = selector->tagHistory()) { | 376 for (const CSSSelector* selector = m_selectors[0].selector; selector; select
or = selector->tagHistory()) { |
377 if (selector->m_match == CSSSelector::Id && !rootNode->document().contai
nsMultipleElementsWithId(selector->value())) { | 377 if (selector->m_match == CSSSelector::Id && !rootNode->document().contai
nsMultipleElementsWithId(selector->value())) { |
378 Element* element = rootNode->treeScope().getElementById(selector->va
lue()); | 378 Element* element = rootNode->treeScope()->getElementById(selector->v
alue()); |
379 if (element && (isTreeScopeRoot(rootNode) || element->isDescendantOf
(rootNode))) | 379 if (element && (isTreeScopeRoot(rootNode) || element->isDescendantOf
(rootNode))) |
380 rootNode = element; | 380 rootNode = element; |
381 else if (!element || matchSingleNode) | 381 else if (!element || matchSingleNode) |
382 rootNode = 0; | 382 rootNode = 0; |
383 if (matchSingleNode) { | 383 if (matchSingleNode) { |
384 matchTraverseRoot = true; | 384 matchTraverseRoot = true; |
385 return rootNode; | 385 return rootNode; |
386 } | 386 } |
387 if (startFromParent && rootNode) | 387 if (startFromParent && rootNode) |
388 rootNode = rootNode->parentNode(); | 388 rootNode = rootNode->parentNode(); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
422 ASSERT(selector); | 422 ASSERT(selector); |
423 | 423 |
424 if (!selector->tagHistory()) { | 424 if (!selector->tagHistory()) { |
425 // Fast path for querySelector('#id'), querySelector('.foo'), and queryS
elector('div'). | 425 // Fast path for querySelector('#id'), querySelector('.foo'), and queryS
elector('div'). |
426 // Many web developers uses querySelector with these simple selectors. | 426 // Many web developers uses querySelector with these simple selectors. |
427 switch (selector->m_match) { | 427 switch (selector->m_match) { |
428 case CSSSelector::Id: | 428 case CSSSelector::Id: |
429 { | 429 { |
430 if (rootNode->document().containsMultipleElementsWithId(selector
->value())) | 430 if (rootNode->document().containsMultipleElementsWithId(selector
->value())) |
431 break; | 431 break; |
432 Element* element = rootNode->treeScope().getElementById(selector
->value()); | 432 Element* element = rootNode->treeScope()->getElementById(selecto
r->value()); |
433 return element && (isTreeScopeRoot(rootNode) || element->isDesce
ndantOf(rootNode)) ? element : 0; | 433 return element && (isTreeScopeRoot(rootNode) || element->isDesce
ndantOf(rootNode)) ? element : 0; |
434 } | 434 } |
435 case CSSSelector::Class: | 435 case CSSSelector::Class: |
436 return findElementByClassName(rootNode, selector->value()); | 436 return findElementByClassName(rootNode, selector->value()); |
437 case CSSSelector::Tag: | 437 case CSSSelector::Tag: |
438 return findElementByTagName(rootNode, selector->tagQName()); | 438 return findElementByTagName(rootNode, selector->tagQName()); |
439 default: | 439 default: |
440 break; // If we need another fast path, add here. | 440 break; // If we need another fast path, add here. |
441 } | 441 } |
442 } | 442 } |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
510 m_entries.add(selectors, selectorQuery.release()); | 510 m_entries.add(selectors, selectorQuery.release()); |
511 return rawSelectorQuery; | 511 return rawSelectorQuery; |
512 } | 512 } |
513 | 513 |
514 void SelectorQueryCache::invalidate() | 514 void SelectorQueryCache::invalidate() |
515 { | 515 { |
516 m_entries.clear(); | 516 m_entries.clear(); |
517 } | 517 } |
518 | 518 |
519 } | 519 } |
OLD | NEW |