Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(579)

Side by Side Diff: Source/core/html/HTMLCollection.cpp

Issue 132923003: Make sure the rootNode of a LiveNodeListBase is always a ContainerNode (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Rebase Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/html/HTMLCollection.h ('k') | Source/core/html/HTMLFormControlsCollection.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « Source/core/html/HTMLCollection.h ('k') | Source/core/html/HTMLFormControlsCollection.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698