OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
4 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2011, 2012 Apple Inc. All r
ights reserved. | 4 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2011, 2012 Apple Inc. All r
ights reserved. |
5 * | 5 * |
6 * This library is free software; you can redistribute it and/or | 6 * This library is free software; you can redistribute it and/or |
7 * modify it under the terms of the GNU Library General Public | 7 * modify it under the terms of the GNU Library General Public |
8 * License as published by the Free Software Foundation; either | 8 * License as published by the Free Software Foundation; either |
9 * version 2 of the License, or (at your option) any later version. | 9 * version 2 of the License, or (at your option) any later version. |
10 * | 10 * |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
295 current = previousNode(rootNode(), *previous, shouldOnlyIncludeDirectChi
ldren()); | 295 current = previousNode(rootNode(), *previous, shouldOnlyIncludeDirectChi
ldren()); |
296 else | 296 else |
297 current = lastNode(rootNode(), shouldOnlyIncludeDirectChildren()); | 297 current = lastNode(rootNode(), shouldOnlyIncludeDirectChildren()); |
298 | 298 |
299 if (type() == ChildNodeListType) | 299 if (type() == ChildNodeListType) |
300 return current; | 300 return current; |
301 return iterateForPreviousNode(current); | 301 return iterateForPreviousNode(current); |
302 } | 302 } |
303 | 303 |
304 template <class NodeListType> | 304 template <class NodeListType> |
305 inline Element* firstMatchingElement(const NodeListType* nodeList, ContainerNode
* root) | 305 inline Element* firstMatchingElement(const NodeListType* nodeList, ContainerNode
& root) |
306 { | 306 { |
307 Element* element = ElementTraversal::firstWithin(root); | 307 Element* element = ElementTraversal::firstWithin(root); |
308 while (element && !isMatchingElement(nodeList, element)) | 308 while (element && !isMatchingElement(nodeList, element)) |
309 element = ElementTraversal::next(*element, root); | 309 element = ElementTraversal::next(*element, &root); |
310 return element; | 310 return element; |
311 } | 311 } |
312 | 312 |
313 template <class NodeListType> | 313 template <class NodeListType> |
314 inline Element* nextMatchingElement(const NodeListType* nodeList, Element& curre
nt, ContainerNode* root) | 314 inline Element* nextMatchingElement(const NodeListType* nodeList, Element& curre
nt, ContainerNode* root) |
315 { | 315 { |
316 Element* next = ¤t; | 316 Element* next = ¤t; |
317 do { | 317 do { |
318 next = ElementTraversal::next(*next, root); | 318 next = ElementTraversal::next(*next, root); |
319 } while (next && !isMatchingElement(nodeList, next)); | 319 } while (next && !isMatchingElement(nodeList, next)); |
(...skipping 18 matching lines...) Expand all Loading... |
338 ASSERT(type() == ChildNodeListType); | 338 ASSERT(type() == ChildNodeListType); |
339 ASSERT(currentOffset < offset); | 339 ASSERT(currentOffset < offset); |
340 while ((currentNode = currentNode->nextSibling())) { | 340 while ((currentNode = currentNode->nextSibling())) { |
341 if (++currentOffset == offset) | 341 if (++currentOffset == offset) |
342 return currentNode; | 342 return currentNode; |
343 } | 343 } |
344 return 0; | 344 return 0; |
345 } | 345 } |
346 | 346 |
347 // FIXME: This should be in LiveNodeList | 347 // FIXME: This should be in LiveNodeList |
348 inline Element* LiveNodeListBase::traverseLiveNodeListFirstElement(ContainerNode
* root) const | 348 inline Element* LiveNodeListBase::traverseLiveNodeListFirstElement(ContainerNode
& root) const |
349 { | 349 { |
350 ASSERT(isNodeList(type())); | 350 ASSERT(isNodeList(type())); |
351 ASSERT(type() != ChildNodeListType); | 351 ASSERT(type() != ChildNodeListType); |
352 if (type() == HTMLTagNodeListType) | 352 if (type() == HTMLTagNodeListType) |
353 return firstMatchingElement(static_cast<const HTMLTagNodeList*>(this), r
oot); | 353 return firstMatchingElement(static_cast<const HTMLTagNodeList*>(this), r
oot); |
354 if (type() == ClassNodeListType) | 354 if (type() == ClassNodeListType) |
355 return firstMatchingElement(static_cast<const ClassNodeList*>(this), roo
t); | 355 return firstMatchingElement(static_cast<const ClassNodeList*>(this), roo
t); |
356 return firstMatchingElement(static_cast<const LiveNodeList*>(this), root); | 356 return firstMatchingElement(static_cast<const LiveNodeList*>(this), root); |
357 } | 357 } |
358 | 358 |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
428 if (isLengthCacheValid() && !overridesItemAfter() && isLastItemCloserThanLas
tOrCachedItem(offset)) { | 428 if (isLengthCacheValid() && !overridesItemAfter() && isLastItemCloserThanLas
tOrCachedItem(offset)) { |
429 Node* lastItem = itemBefore(0); | 429 Node* lastItem = itemBefore(0); |
430 ASSERT(lastItem); | 430 ASSERT(lastItem); |
431 setItemCache(lastItem, cachedLength() - 1, 0); | 431 setItemCache(lastItem, cachedLength() - 1, 0); |
432 } else if (!isItemCacheValid() || isFirstItemCloserThanCachedItem(offset) ||
(overridesItemAfter() && offset < cachedItemOffset())) { | 432 } else if (!isItemCacheValid() || isFirstItemCloserThanCachedItem(offset) ||
(overridesItemAfter() && offset < cachedItemOffset())) { |
433 unsigned offsetInArray = 0; | 433 unsigned offsetInArray = 0; |
434 Node* firstItem; | 434 Node* firstItem; |
435 if (type() == ChildNodeListType) | 435 if (type() == ChildNodeListType) |
436 firstItem = root->firstChild(); | 436 firstItem = root->firstChild(); |
437 else if (isNodeList(type())) | 437 else if (isNodeList(type())) |
438 firstItem = traverseLiveNodeListFirstElement(root); | 438 firstItem = traverseLiveNodeListFirstElement(*root); |
439 else | 439 else |
440 firstItem = static_cast<const HTMLCollection*>(this)->traverseFirstE
lement(offsetInArray, root); | 440 firstItem = static_cast<const HTMLCollection*>(this)->traverseFirstE
lement(offsetInArray, *root); |
441 | 441 |
442 if (!firstItem) { | 442 if (!firstItem) { |
443 setLengthCache(0); | 443 setLengthCache(0); |
444 return 0; | 444 return 0; |
445 } | 445 } |
446 setItemCache(firstItem, 0, offsetInArray); | 446 setItemCache(firstItem, 0, offsetInArray); |
447 ASSERT(!cachedItemOffset()); | 447 ASSERT(!cachedItemOffset()); |
448 } | 448 } |
449 | 449 |
450 if (cachedItemOffset() == offset) | 450 if (cachedItemOffset() == offset) |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
518 HTMLElement* e = toHTMLElement(element); | 518 HTMLElement* e = toHTMLElement(element); |
519 if (!checkName) | 519 if (!checkName) |
520 return e->getIdAttribute() == name; | 520 return e->getIdAttribute() == name; |
521 | 521 |
522 if (type() == DocAll && !nameShouldBeVisibleInDocumentAll(e)) | 522 if (type() == DocAll && !nameShouldBeVisibleInDocumentAll(e)) |
523 return false; | 523 return false; |
524 | 524 |
525 return e->getNameAttribute() == name && e->getIdAttribute() != name; | 525 return e->getNameAttribute() == name && e->getIdAttribute() != name; |
526 } | 526 } |
527 | 527 |
528 inline Element* firstMatchingChildElement(const HTMLCollection* nodeList, Contai
nerNode* root) | 528 inline Element* firstMatchingChildElement(const HTMLCollection* nodeList, Contai
nerNode& root) |
529 { | 529 { |
530 Element* element = ElementTraversal::firstWithin(root); | 530 Element* element = ElementTraversal::firstWithin(root); |
531 while (element && !isMatchingElement(nodeList, element)) | 531 while (element && !isMatchingElement(nodeList, element)) |
532 element = ElementTraversal::nextSkippingChildren(element, root); | 532 element = ElementTraversal::nextSkippingChildren(element, &root); |
533 return element; | 533 return element; |
534 } | 534 } |
535 | 535 |
536 inline Element* nextMatchingChildElement(const HTMLCollection* nodeList, Element
* current, ContainerNode* root) | 536 inline Element* nextMatchingChildElement(const HTMLCollection* nodeList, Element
* current, ContainerNode* root) |
537 { | 537 { |
538 do { | 538 do { |
539 current = ElementTraversal::nextSkippingChildren(current, root); | 539 current = ElementTraversal::nextSkippingChildren(current, root); |
540 } while (current && !isMatchingElement(nodeList, current)); | 540 } while (current && !isMatchingElement(nodeList, current)); |
541 return current; | 541 return current; |
542 } | 542 } |
543 | 543 |
544 inline Element* HTMLCollection::traverseFirstElement(unsigned& offsetInArray, Co
ntainerNode* root) const | 544 inline Element* HTMLCollection::traverseFirstElement(unsigned& offsetInArray, Co
ntainerNode& root) const |
545 { | 545 { |
546 if (overridesItemAfter()) | 546 if (overridesItemAfter()) |
547 return virtualItemAfter(offsetInArray, 0); | 547 return virtualItemAfter(offsetInArray, 0); |
548 ASSERT(!offsetInArray); | 548 ASSERT(!offsetInArray); |
549 if (shouldOnlyIncludeDirectChildren()) | 549 if (shouldOnlyIncludeDirectChildren()) |
550 return firstMatchingChildElement(static_cast<const HTMLCollection*>(this
), root); | 550 return firstMatchingChildElement(static_cast<const HTMLCollection*>(this
), root); |
551 return firstMatchingElement(static_cast<const HTMLCollection*>(this), root); | 551 return firstMatchingElement(static_cast<const HTMLCollection*>(this), root); |
552 } | 552 } |
553 | 553 |
554 inline Element* HTMLCollection::traverseNextElement(unsigned& offsetInArray, Ele
ment& previous, ContainerNode* root) const | 554 inline Element* HTMLCollection::traverseNextElement(unsigned& offsetInArray, Ele
ment& previous, ContainerNode* root) const |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
591 // attribute. If a match is not found, the method then searches for an | 591 // attribute. If a match is not found, the method then searches for an |
592 // object with a matching name attribute, but only on those elements | 592 // object with a matching name attribute, but only on those elements |
593 // that are allowed a name attribute. | 593 // that are allowed a name attribute. |
594 | 594 |
595 ContainerNode* root = rootContainerNode(); | 595 ContainerNode* root = rootContainerNode(); |
596 if (!root) | 596 if (!root) |
597 return 0; | 597 return 0; |
598 | 598 |
599 unsigned arrayOffset = 0; | 599 unsigned arrayOffset = 0; |
600 unsigned i = 0; | 600 unsigned i = 0; |
601 for (Element* element = traverseFirstElement(arrayOffset, root); element; el
ement = traverseNextElement(arrayOffset, *element, root)) { | 601 for (Element* element = traverseFirstElement(arrayOffset, *root); element; e
lement = traverseNextElement(arrayOffset, *element, root)) { |
602 if (checkForNameMatch(element, /* checkName */ false, name)) { | 602 if (checkForNameMatch(element, /* checkName */ false, name)) { |
603 setItemCache(element, i, arrayOffset); | 603 setItemCache(element, i, arrayOffset); |
604 return element; | 604 return element; |
605 } | 605 } |
606 i++; | 606 i++; |
607 } | 607 } |
608 | 608 |
609 i = 0; | 609 i = 0; |
610 for (Element* element = traverseFirstElement(arrayOffset, root); element; el
ement = traverseNextElement(arrayOffset, *element, root)) { | 610 for (Element* element = traverseFirstElement(arrayOffset, *root); element; e
lement = traverseNextElement(arrayOffset, *element, root)) { |
611 if (checkForNameMatch(element, /* checkName */ true, name)) { | 611 if (checkForNameMatch(element, /* checkName */ true, name)) { |
612 setItemCache(element, i, arrayOffset); | 612 setItemCache(element, i, arrayOffset); |
613 return element; | 613 return element; |
614 } | 614 } |
615 i++; | 615 i++; |
616 } | 616 } |
617 | 617 |
618 return 0; | 618 return 0; |
619 } | 619 } |
620 | 620 |
621 void HTMLCollection::updateNameCache() const | 621 void HTMLCollection::updateNameCache() const |
622 { | 622 { |
623 if (hasNameCache()) | 623 if (hasNameCache()) |
624 return; | 624 return; |
625 | 625 |
626 ContainerNode* root = rootContainerNode(); | 626 ContainerNode* root = rootContainerNode(); |
627 if (!root) | 627 if (!root) |
628 return; | 628 return; |
629 | 629 |
630 unsigned arrayOffset = 0; | 630 unsigned arrayOffset = 0; |
631 for (Element* element = traverseFirstElement(arrayOffset, root); element; el
ement = traverseNextElement(arrayOffset, *element, root)) { | 631 for (Element* element = traverseFirstElement(arrayOffset, *root); element; e
lement = traverseNextElement(arrayOffset, *element, root)) { |
632 const AtomicString& idAttrVal = element->getIdAttribute(); | 632 const AtomicString& idAttrVal = element->getIdAttribute(); |
633 if (!idAttrVal.isEmpty()) | 633 if (!idAttrVal.isEmpty()) |
634 appendIdCache(idAttrVal, element); | 634 appendIdCache(idAttrVal, element); |
635 if (!element->isHTMLElement()) | 635 if (!element->isHTMLElement()) |
636 continue; | 636 continue; |
637 const AtomicString& nameAttrVal = element->getNameAttribute(); | 637 const AtomicString& nameAttrVal = element->getNameAttribute(); |
638 if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal && (type() != Doc
All || nameShouldBeVisibleInDocumentAll(toHTMLElement(element)))) | 638 if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal && (type() != Doc
All || nameShouldBeVisibleInDocumentAll(toHTMLElement(element)))) |
639 appendNameCache(nameAttrVal, element); | 639 appendNameCache(nameAttrVal, element); |
640 } | 640 } |
641 | 641 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
682 | 682 |
683 void HTMLCollection::append(NodeCacheMap& map, const AtomicString& key, Element*
element) | 683 void HTMLCollection::append(NodeCacheMap& map, const AtomicString& key, Element*
element) |
684 { | 684 { |
685 OwnPtr<Vector<Element*> >& vector = map.add(key.impl(), nullptr).iterator->v
alue; | 685 OwnPtr<Vector<Element*> >& vector = map.add(key.impl(), nullptr).iterator->v
alue; |
686 if (!vector) | 686 if (!vector) |
687 vector = adoptPtr(new Vector<Element*>); | 687 vector = adoptPtr(new Vector<Element*>); |
688 vector->append(element); | 688 vector->append(element); |
689 } | 689 } |
690 | 690 |
691 } // namespace WebCore | 691 } // namespace WebCore |
OLD | NEW |