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 |