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 * 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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |