| 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 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 153 case HTMLTagNodeListType: | 153 case HTMLTagNodeListType: |
| 154 case RadioNodeListType: | 154 case RadioNodeListType: |
| 155 case RadioImgNodeListType: | 155 case RadioImgNodeListType: |
| 156 case LabelsNodeListType: | 156 case LabelsNodeListType: |
| 157 break; | 157 break; |
| 158 } | 158 } |
| 159 ASSERT_NOT_REACHED(); | 159 ASSERT_NOT_REACHED(); |
| 160 return DoNotInvalidateOnAttributeChanges; | 160 return DoNotInvalidateOnAttributeChanges; |
| 161 } | 161 } |
| 162 | 162 |
| 163 HTMLCollection::HTMLCollection(Node* ownerNode, CollectionType type, ItemAfterOv
errideType itemAfterOverrideType) | 163 HTMLCollection::HTMLCollection(ContainerNode* ownerNode, CollectionType type, It
emAfterOverrideType itemAfterOverrideType) |
| 164 : LiveNodeListBase(ownerNode, rootTypeFromCollectionType(type), invalidation
TypeExcludingIdAndNameAttributes(type), | 164 : LiveNodeListBase(ownerNode, rootTypeFromCollectionType(type), invalidation
TypeExcludingIdAndNameAttributes(type), |
| 165 WebCore::shouldOnlyIncludeDirectChildren(type), type, itemAfterOverrideT
ype) | 165 WebCore::shouldOnlyIncludeDirectChildren(type), type, itemAfterOverrideT
ype) |
| 166 , m_isNameCacheValid(false) | 166 , m_isNameCacheValid(false) |
| 167 { | 167 { |
| 168 ScriptWrappable::init(this); | 168 ScriptWrappable::init(this); |
| 169 } | 169 } |
| 170 | 170 |
| 171 PassRefPtr<HTMLCollection> HTMLCollection::create(Node* base, CollectionType typ
e) | 171 PassRefPtr<HTMLCollection> HTMLCollection::create(ContainerNode* base, Collectio
nType type) |
| 172 { | 172 { |
| 173 return adoptRef(new HTMLCollection(base, type, DoesNotOverrideItemAfter)); | 173 return adoptRef(new HTMLCollection(base, type, DoesNotOverrideItemAfter)); |
| 174 } | 174 } |
| 175 | 175 |
| 176 HTMLCollection::~HTMLCollection() | 176 HTMLCollection::~HTMLCollection() |
| 177 { | 177 { |
| 178 // HTMLNameCollection removes cache by itself. | 178 // HTMLNameCollection removes cache by itself. |
| 179 if (type() != WindowNamedItems && type() != DocumentNamedItems) | 179 if (type() != WindowNamedItems && type() != DocumentNamedItems) |
| 180 ownerNode()->nodeLists()->removeCacheWithAtomicName(this, type()); | 180 ownerNode()->nodeLists()->removeCacheWithAtomicName(this, type()); |
| 181 } | 181 } |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 419 | 419 |
| 420 // FIXME: It is silly that these functions are in HTMLCollection.cpp. | 420 // FIXME: It is silly that these functions are in HTMLCollection.cpp. |
| 421 Node* LiveNodeListBase::item(unsigned offset) const | 421 Node* LiveNodeListBase::item(unsigned offset) const |
| 422 { | 422 { |
| 423 if (cachedItem() && cachedItemOffset() == offset) | 423 if (cachedItem() && cachedItemOffset() == offset) |
| 424 return cachedItem(); | 424 return cachedItem(); |
| 425 | 425 |
| 426 if (isLengthCacheValid() && cachedLength() <= offset) | 426 if (isLengthCacheValid() && cachedLength() <= offset) |
| 427 return 0; | 427 return 0; |
| 428 | 428 |
| 429 ContainerNode* root = rootContainerNode(); | 429 ContainerNode& root = rootNode(); |
| 430 if (!root) { | |
| 431 // FIMXE: In someTextNode.childNodes case the root is Text. We shouldn't
even make a LiveNodeList for that. | |
| 432 setLengthCache(0); | |
| 433 return 0; | |
| 434 } | |
| 435 | |
| 436 if (isLengthCacheValid() && !overridesItemAfter() && isLastItemCloserThanLas
tOrCachedItem(offset)) { | 430 if (isLengthCacheValid() && !overridesItemAfter() && isLastItemCloserThanLas
tOrCachedItem(offset)) { |
| 437 Node* lastItem = itemBefore(0); | 431 Node* lastItem = itemBefore(0); |
| 438 ASSERT(lastItem); | 432 ASSERT(lastItem); |
| 439 setItemCache(lastItem, cachedLength() - 1); | 433 setItemCache(lastItem, cachedLength() - 1); |
| 440 } else if (!cachedItem() || isFirstItemCloserThanCachedItem(offset) || (over
ridesItemAfter() && offset < cachedItemOffset())) { | 434 } else if (!cachedItem() || isFirstItemCloserThanCachedItem(offset) || (over
ridesItemAfter() && offset < cachedItemOffset())) { |
| 441 Node* firstItem; | 435 Node* firstItem; |
| 442 if (isLiveNodeListType(type())) | 436 if (isLiveNodeListType(type())) |
| 443 firstItem = static_cast<const LiveNodeList*>(this)->traverseToFirstE
lement(*root); | 437 firstItem = static_cast<const LiveNodeList*>(this)->traverseToFirstE
lement(root); |
| 444 else | 438 else |
| 445 firstItem = static_cast<const HTMLCollection*>(this)->traverseToFirs
tElement(*root); | 439 firstItem = static_cast<const HTMLCollection*>(this)->traverseToFirs
tElement(root); |
| 446 | 440 |
| 447 if (!firstItem) { | 441 if (!firstItem) { |
| 448 setLengthCache(0); | 442 setLengthCache(0); |
| 449 return 0; | 443 return 0; |
| 450 } | 444 } |
| 451 setItemCache(firstItem, 0); | 445 setItemCache(firstItem, 0); |
| 452 ASSERT(!cachedItemOffset()); | 446 ASSERT(!cachedItemOffset()); |
| 453 } | 447 } |
| 454 | 448 |
| 455 if (cachedItemOffset() == offset) | 449 if (cachedItemOffset() == offset) |
| 456 return cachedItem(); | 450 return cachedItem(); |
| 457 | 451 |
| 458 return itemBeforeOrAfterCachedItem(offset, *root); | 452 return itemBeforeOrAfterCachedItem(offset, root); |
| 459 } | 453 } |
| 460 | 454 |
| 461 inline Node* LiveNodeListBase::itemBeforeOrAfterCachedItem(unsigned offset, cons
t ContainerNode& root) const | 455 inline Node* LiveNodeListBase::itemBeforeOrAfterCachedItem(unsigned offset, cons
t ContainerNode& root) const |
| 462 { | 456 { |
| 463 unsigned currentOffset = cachedItemOffset(); | 457 unsigned currentOffset = cachedItemOffset(); |
| 464 Node* currentItem = cachedItem(); | 458 Node* currentItem = cachedItem(); |
| 465 ASSERT(currentItem); | 459 ASSERT(currentItem); |
| 466 ASSERT(currentOffset != offset); | 460 ASSERT(currentOffset != offset); |
| 467 | 461 |
| 468 if (offset < cachedItemOffset()) { | 462 if (offset < cachedItemOffset()) { |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 585 } | 579 } |
| 586 | 580 |
| 587 Node* HTMLCollection::namedItem(const AtomicString& name) const | 581 Node* HTMLCollection::namedItem(const AtomicString& name) const |
| 588 { | 582 { |
| 589 // http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/namedit
em.asp | 583 // http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/namedit
em.asp |
| 590 // This method first searches for an object with a matching id | 584 // This method first searches for an object with a matching id |
| 591 // attribute. If a match is not found, the method then searches for an | 585 // 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 | 586 // object with a matching name attribute, but only on those elements |
| 593 // that are allowed a name attribute. | 587 // that are allowed a name attribute. |
| 594 | 588 |
| 595 ContainerNode* root = rootContainerNode(); | 589 ContainerNode& root = rootNode(); |
| 596 if (!root) | |
| 597 return 0; | |
| 598 | |
| 599 unsigned i = 0; | 590 unsigned i = 0; |
| 600 for (Element* element = traverseToFirstElement(*root); element; element = tr
averseNextElement(*element, *root)) { | 591 for (Element* element = traverseToFirstElement(root); element; element = tra
verseNextElement(*element, root)) { |
| 601 if (checkForNameMatch(*element, /* checkName */ false, name)) { | 592 if (checkForNameMatch(*element, /* checkName */ false, name)) { |
| 602 setItemCache(element, i); | 593 setItemCache(element, i); |
| 603 return element; | 594 return element; |
| 604 } | 595 } |
| 605 i++; | 596 i++; |
| 606 } | 597 } |
| 607 | 598 |
| 608 i = 0; | 599 i = 0; |
| 609 for (Element* element = traverseToFirstElement(*root); element; element = tr
averseNextElement(*element, *root)) { | 600 for (Element* element = traverseToFirstElement(root); element; element = tra
verseNextElement(*element, root)) { |
| 610 if (checkForNameMatch(*element, /* checkName */ true, name)) { | 601 if (checkForNameMatch(*element, /* checkName */ true, name)) { |
| 611 setItemCache(element, i); | 602 setItemCache(element, i); |
| 612 return element; | 603 return element; |
| 613 } | 604 } |
| 614 i++; | 605 i++; |
| 615 } | 606 } |
| 616 | 607 |
| 617 return 0; | 608 return 0; |
| 618 } | 609 } |
| 619 | 610 |
| 620 void HTMLCollection::updateNameCache() const | 611 void HTMLCollection::updateNameCache() const |
| 621 { | 612 { |
| 622 if (hasNameCache()) | 613 if (hasNameCache()) |
| 623 return; | 614 return; |
| 624 | 615 |
| 625 ContainerNode* root = rootContainerNode(); | 616 ContainerNode& root = rootNode(); |
| 626 if (!root) | 617 for (Element* element = traverseToFirstElement(root); element; element = tra
verseNextElement(*element, root)) { |
| 627 return; | |
| 628 | |
| 629 for (Element* element = traverseToFirstElement(*root); element; element = tr
averseNextElement(*element, *root)) { | |
| 630 const AtomicString& idAttrVal = element->getIdAttribute(); | 618 const AtomicString& idAttrVal = element->getIdAttribute(); |
| 631 if (!idAttrVal.isEmpty()) | 619 if (!idAttrVal.isEmpty()) |
| 632 appendIdCache(idAttrVal, element); | 620 appendIdCache(idAttrVal, element); |
| 633 if (!element->isHTMLElement()) | 621 if (!element->isHTMLElement()) |
| 634 continue; | 622 continue; |
| 635 const AtomicString& nameAttrVal = element->getNameAttribute(); | 623 const AtomicString& nameAttrVal = element->getNameAttribute(); |
| 636 if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal && (type() != Doc
All || nameShouldBeVisibleInDocumentAll(toHTMLElement(*element)))) | 624 if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal && (type() != Doc
All || nameShouldBeVisibleInDocumentAll(toHTMLElement(*element)))) |
| 637 appendNameCache(nameAttrVal, element); | 625 appendNameCache(nameAttrVal, element); |
| 638 } | 626 } |
| 639 | 627 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 660 | 648 |
| 661 void HTMLCollection::append(NodeCacheMap& map, const AtomicString& key, Element*
element) | 649 void HTMLCollection::append(NodeCacheMap& map, const AtomicString& key, Element*
element) |
| 662 { | 650 { |
| 663 OwnPtr<Vector<Element*> >& vector = map.add(key.impl(), nullptr).iterator->v
alue; | 651 OwnPtr<Vector<Element*> >& vector = map.add(key.impl(), nullptr).iterator->v
alue; |
| 664 if (!vector) | 652 if (!vector) |
| 665 vector = adoptPtr(new Vector<Element*>); | 653 vector = adoptPtr(new Vector<Element*>); |
| 666 vector->append(element); | 654 vector->append(element); |
| 667 } | 655 } |
| 668 | 656 |
| 669 } // namespace WebCore | 657 } // namespace WebCore |
| OLD | NEW |