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

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

Issue 159503003: Do not cause unnecessary node lists invalidation on id/name attribute change (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Rebase Created 6 years, 10 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
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 * Copyright (C) 2014 Samsung Electronics. All rights reserved. 5 * Copyright (C) 2014 Samsung Electronics. All rights reserved.
6 * 6 *
7 * This library is free software; you can redistribute it and/or 7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public 8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version. 10 * version 2 of the License, or (at your option) any later version.
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
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(ContainerNode* ownerNode, CollectionType type, It emAfterOverrideType itemAfterOverrideType) 163 HTMLCollection::HTMLCollection(ContainerNode* ownerNode, CollectionType type, It emAfterOverrideType itemAfterOverrideType)
164 : LiveNodeListBase(ownerNode, rootTypeFromCollectionType(type), invalidation TypeExcludingIdAndNameAttributes(type), type) 164 : LiveNodeListBase(ownerNode, rootTypeFromCollectionType(type), invalidation TypeExcludingIdAndNameAttributes(type), type)
165 , m_overridesItemAfter(itemAfterOverrideType == OverridesItemAfter) 165 , m_overridesItemAfter(itemAfterOverrideType == OverridesItemAfter)
166 , m_shouldOnlyIncludeDirectChildren(shouldTypeOnlyIncludeDirectChildren(type )) 166 , m_shouldOnlyIncludeDirectChildren(shouldTypeOnlyIncludeDirectChildren(type ))
167 , m_isNameCacheValid(false) 167 , m_hasValidIdNameCache(false)
168 { 168 {
169 ScriptWrappable::init(this); 169 ScriptWrappable::init(this);
170 } 170 }
171 171
172 PassRefPtr<HTMLCollection> HTMLCollection::create(ContainerNode* base, Collectio nType type) 172 PassRefPtr<HTMLCollection> HTMLCollection::create(ContainerNode* base, Collectio nType type)
173 { 173 {
174 return adoptRef(new HTMLCollection(base, type, DoesNotOverrideItemAfter)); 174 return adoptRef(new HTMLCollection(base, type, DoesNotOverrideItemAfter));
175 } 175 }
176 176
177 HTMLCollection::~HTMLCollection() 177 HTMLCollection::~HTMLCollection()
178 { 178 {
179 if (hasValidIdNameCache())
180 unregisterIdNameCacheFromDocument(document());
179 // HTMLNameCollection, ClassCollection and TagCollection remove cache by the mselves. 181 // HTMLNameCollection, ClassCollection and TagCollection remove cache by the mselves.
180 if (type() != WindowNamedItems && type() != DocumentNamedItems && type() != ClassCollectionType 182 if (type() != WindowNamedItems && type() != DocumentNamedItems && type() != ClassCollectionType
181 && type() != HTMLTagCollectionType && type() != TagCollectionType) { 183 && type() != HTMLTagCollectionType && type() != TagCollectionType) {
182 ownerNode()->nodeLists()->removeCache(this, type()); 184 ownerNode()->nodeLists()->removeCache(this, type());
183 } 185 }
184 } 186 }
185 187
186 void HTMLCollection::invalidateCache() const 188 void HTMLCollection::invalidateCache(Document* oldDocument) const
187 { 189 {
188 m_collectionIndexCache.invalidate(); 190 m_collectionIndexCache.invalidate();
189 invalidateIdNameCacheMaps(); 191 invalidateIdNameCacheMaps(oldDocument);
190 } 192 }
191 193
192 template <class NodeListType> 194 template <class NodeListType>
193 inline bool isMatchingElement(const NodeListType&, const Element&); 195 inline bool isMatchingElement(const NodeListType&, const Element&);
194 196
195 template <> inline bool isMatchingElement(const HTMLCollection& htmlCollection, const Element& element) 197 template <> inline bool isMatchingElement(const HTMLCollection& htmlCollection, const Element& element)
196 { 198 {
197 CollectionType type = htmlCollection.type(); 199 CollectionType type = htmlCollection.type();
198 200
199 // These collections apply to any kind of Elements, not just HTMLElements. 201 // These collections apply to any kind of Elements, not just HTMLElements.
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 } 471 }
470 } 472 }
471 473
472 Element* HTMLCollection::namedItem(const AtomicString& name) const 474 Element* HTMLCollection::namedItem(const AtomicString& name) const
473 { 475 {
474 // http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/namedit em.asp 476 // http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/namedit em.asp
475 // This method first searches for an object with a matching id 477 // This method first searches for an object with a matching id
476 // attribute. If a match is not found, the method then searches for an 478 // attribute. If a match is not found, the method then searches for an
477 // object with a matching name attribute, but only on those elements 479 // object with a matching name attribute, but only on those elements
478 // that are allowed a name attribute. 480 // that are allowed a name attribute.
479 updateNameCache(); 481 updateIdNameCache();
480 482
481 Vector<Element*>* idResults = idCache(name); 483 Vector<Element*>* idResults = idCache(name);
482 if (idResults && !idResults->isEmpty()) 484 if (idResults && !idResults->isEmpty())
483 return idResults->first(); 485 return idResults->first();
484 486
485 Vector<Element*>* nameResults = nameCache(name); 487 Vector<Element*>* nameResults = nameCache(name);
486 if (nameResults && !nameResults->isEmpty()) 488 if (nameResults && !nameResults->isEmpty())
487 return nameResults->first(); 489 return nameResults->first();
488 490
489 return 0; 491 return 0;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 names.append(idAttribute); 524 names.append(idAttribute);
523 } 525 }
524 } 526 }
525 } 527 }
526 528
527 void HTMLCollection::namedPropertyEnumerator(Vector<String>& names, ExceptionSta te&) 529 void HTMLCollection::namedPropertyEnumerator(Vector<String>& names, ExceptionSta te&)
528 { 530 {
529 supportedPropertyNames(names); 531 supportedPropertyNames(names);
530 } 532 }
531 533
532 void HTMLCollection::updateNameCache() const 534 void HTMLCollection::updateIdNameCache() const
533 { 535 {
534 if (hasNameCache()) 536 if (hasValidIdNameCache())
535 return; 537 return;
536 538
537 ContainerNode& root = rootNode(); 539 ContainerNode& root = rootNode();
538 for (Element* element = traverseToFirstElement(root); element; element = tra verseNextElement(*element, root)) { 540 for (Element* element = traverseToFirstElement(root); element; element = tra verseNextElement(*element, root)) {
539 const AtomicString& idAttrVal = element->getIdAttribute(); 541 const AtomicString& idAttrVal = element->getIdAttribute();
540 if (!idAttrVal.isEmpty()) 542 if (!idAttrVal.isEmpty())
541 appendIdCache(idAttrVal, element); 543 appendIdCache(idAttrVal, element);
542 if (!element->isHTMLElement()) 544 if (!element->isHTMLElement())
543 continue; 545 continue;
544 const AtomicString& nameAttrVal = element->getNameAttribute(); 546 const AtomicString& nameAttrVal = element->getNameAttribute();
545 if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal && (type() != Doc All || nameShouldBeVisibleInDocumentAll(toHTMLElement(*element)))) 547 if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal && (type() != Doc All || nameShouldBeVisibleInDocumentAll(toHTMLElement(*element))))
546 appendNameCache(nameAttrVal, element); 548 appendNameCache(nameAttrVal, element);
547 } 549 }
548 550
549 setHasNameCache(); 551 setHasValidIdNameCache();
550 } 552 }
551 553
552 void HTMLCollection::namedItems(const AtomicString& name, Vector<RefPtr<Element> >& result) const 554 void HTMLCollection::namedItems(const AtomicString& name, Vector<RefPtr<Element> >& result) const
553 { 555 {
554 ASSERT(result.isEmpty()); 556 ASSERT(result.isEmpty());
555 if (name.isEmpty()) 557 if (name.isEmpty())
556 return; 558 return;
557 559
558 updateNameCache(); 560 updateIdNameCache();
559 561
560 Vector<Element*>* idResults = idCache(name); 562 Vector<Element*>* idResults = idCache(name);
561 Vector<Element*>* nameResults = nameCache(name); 563 Vector<Element*>* nameResults = nameCache(name);
562 564
563 for (unsigned i = 0; idResults && i < idResults->size(); ++i) 565 for (unsigned i = 0; idResults && i < idResults->size(); ++i)
564 result.append(idResults->at(i)); 566 result.append(idResults->at(i));
565 567
566 for (unsigned i = 0; nameResults && i < nameResults->size(); ++i) 568 for (unsigned i = 0; nameResults && i < nameResults->size(); ++i)
567 result.append(nameResults->at(i)); 569 result.append(nameResults->at(i));
568 } 570 }
569 571
570 void HTMLCollection::append(NodeCacheMap& map, const AtomicString& key, Element* element) 572 void HTMLCollection::append(NodeCacheMap& map, const AtomicString& key, Element* element)
571 { 573 {
572 OwnPtr<Vector<Element*> >& vector = map.add(key.impl(), nullptr).iterator->v alue; 574 OwnPtr<Vector<Element*> >& vector = map.add(key.impl(), nullptr).iterator->v alue;
573 if (!vector) 575 if (!vector)
574 vector = adoptPtr(new Vector<Element*>); 576 vector = adoptPtr(new Vector<Element*>);
575 vector->append(element); 577 vector->append(element);
576 } 578 }
577 579
578 } // namespace WebCore 580 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698