Index: Source/core/html/HTMLCollection.h |
diff --git a/Source/core/html/HTMLCollection.h b/Source/core/html/HTMLCollection.h |
index 0c916440a01bbd03660fa337b1c9ff428a488b63..86f7dd1ac272ae9b828d4a6e45438443d249d5ed 100644 |
--- a/Source/core/html/HTMLCollection.h |
+++ b/Source/core/html/HTMLCollection.h |
@@ -65,33 +65,54 @@ public: |
protected: |
HTMLCollection(ContainerNode& base, CollectionType, ItemAfterOverrideType); |
+ class NamedItemCache { |
+ public: |
+ Vector<Element*>* getElementsById(const AtomicString& id) const { return m_idCache.get(id.impl()); } |
+ Vector<Element*>* getElementsByName(const AtomicString& name) const { return m_nameCache.get(name.impl()); } |
+ void addElementWithId(const AtomicString& id, Element* element) { addElementToMap(m_idCache, id, element); } |
+ void addElementWithName(const AtomicString& name, Element* element) { addElementToMap(m_nameCache, name, element); } |
+ |
+ private: |
+ typedef HashMap<StringImpl*, OwnPtr<Vector<Element*> > > StringToElementsMap; |
+ static void addElementToMap(StringToElementsMap& map, const AtomicString& key, Element* element) |
+ { |
+ OwnPtr<Vector<Element*> >& vector = map.add(key.impl(), nullptr).storedValue->value; |
+ if (!vector) |
+ vector = adoptPtr(new Vector<Element*>); |
+ vector->append(element); |
+ } |
+ |
+ StringToElementsMap m_idCache; |
+ StringToElementsMap m_nameCache; |
+ }; |
+ |
bool overridesItemAfter() const { return m_overridesItemAfter; } |
virtual Element* virtualItemAfter(Element*) const; |
bool shouldOnlyIncludeDirectChildren() const { return m_shouldOnlyIncludeDirectChildren; } |
virtual void supportedPropertyNames(Vector<String>& names); |
virtual void updateIdNameCache() const; |
- bool hasValidIdNameCache() const { return m_hasValidIdNameCache; } |
- void setHasValidIdNameCache() const |
+ bool hasValidIdNameCache() const { return m_namedItemCache; } |
+ |
+ NamedItemCache& createNamedItemCache() const |
{ |
- ASSERT(!m_hasValidIdNameCache); |
- m_hasValidIdNameCache = true; |
+ ASSERT(!m_namedItemCache); |
document().incrementNodeListWithIdNameCacheCount(); |
+ m_namedItemCache = adoptPtr(new NamedItemCache); |
+ return *m_namedItemCache; |
+ } |
+ NamedItemCache& namedItemCache() const |
+ { |
+ ASSERT(m_namedItemCache); |
+ return *m_namedItemCache; |
} |
- |
- typedef HashMap<StringImpl*, OwnPtr<Vector<Element*> > > NodeCacheMap; |
- Vector<Element*>* idCache(const AtomicString& name) const { return m_idCache.get(name.impl()); } |
- Vector<Element*>* nameCache(const AtomicString& name) const { return m_nameCache.get(name.impl()); } |
- void appendIdCache(const AtomicString& name, Element* element) const { append(m_idCache, name, element); } |
- void appendNameCache(const AtomicString& name, Element* element) const { append(m_nameCache, name, element); } |
private: |
Element* traverseNextElement(Element& previous, const ContainerNode& root) const; |
- static void append(NodeCacheMap&, const AtomicString&, Element*); |
void invalidateIdNameCacheMaps(Document* oldDocument = 0) const |
{ |
- if (!m_hasValidIdNameCache) |
+ if (!hasValidIdNameCache()) |
return; |
// Make sure we decrement the NodeListWithIdNameCache count from |
@@ -99,22 +120,18 @@ private: |
// is moved to a new document. |
unregisterIdNameCacheFromDocument(oldDocument ? *oldDocument : document()); |
- m_idCache.clear(); |
- m_nameCache.clear(); |
- m_hasValidIdNameCache = false; |
+ m_namedItemCache.clear(); |
} |
void unregisterIdNameCacheFromDocument(Document& document) const |
{ |
- ASSERT(m_hasValidIdNameCache); |
+ ASSERT(hasValidIdNameCache()); |
document.decrementNodeListWithIdNameCacheCount(); |
} |
const unsigned m_overridesItemAfter : 1; |
const unsigned m_shouldOnlyIncludeDirectChildren : 1; |
- mutable unsigned m_hasValidIdNameCache : 1; |
- mutable NodeCacheMap m_idCache; |
- mutable NodeCacheMap m_nameCache; |
+ mutable OwnPtr<NamedItemCache> m_namedItemCache; |
mutable CollectionIndexCache<HTMLCollection, Element> m_collectionIndexCache; |
friend class LiveNodeListBase; |