HTMLCollection on Document should be stored on NodeListsNodeData like other HTMLColle...
authorrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 27 Nov 2012 19:58:46 +0000 (19:58 +0000)
committerrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 27 Nov 2012 19:58:46 +0000 (19:58 +0000)
https://bugs.webkit.org/show_bug.cgi?id=103364

Reviewed by Anders Carlsson.

Replaced the HTMLCollection storage in Document by NodeListsNodeData used by other HTMLCollection's
and LiveNodeList's. Now NodeListsNodeData is the only storage for HTMLCollection and LiveNodeList.

* dom/Document.cpp:
(WebCore::Document::Document): Removed code for m_collection since it has been removed.
(WebCore::Document::~Document): Ditto.
(WebCore::Document::registerNodeList): Renamed.
(WebCore::Document::unregisterNodeList): Ditto.
(WebCore::Document::ensureCachedCollection): Renamed from cachedCollection to match the convetion
used elsewhere. Also use NodeListNodeData::addCacheWithAtomicName now that m_collection is gone.
(WebCore::Document::images):
(WebCore::Document::applets):
(WebCore::Document::embeds):
(WebCore::Document::plugins):
(WebCore::Document::scripts):
(WebCore::Document::links):
(WebCore::Document::forms):
(WebCore::Document::anchors):
(WebCore::Document::all):
(WebCore::Document::windowNamedItems): Use addCacheWithAtomicName.
(WebCore::Document::documentNamedItems): Ditto.
(WebCore::Document::reportMemoryUsage): Removed code for m_collection since it has been removed.
* dom/Document.h:
(WebCore::Document): Removed m_collections, m_documentNamedItemCollections, and
m_windowNamedItemCollections.
* dom/Element.cpp:
(WebCore::Element::ensureCachedHTMLCollection): Merged ElementRareData::ensureCachedHTMLCollection.
(WebCore::Element::cachedHTMLCollection): Merged ElementRareData::cachedHTMLCollection.
* Source/WebCore/dom/ElementRareData.h: Removed ensureCachedHTMLCollection, cachedHTMLCollection,
and removeCachedHTMLCollection since they're no longer used.
* dom/LiveNodeList.h:
(WebCore::LiveNodeListBase::LiveNodeListBase): Call registerNodeList now that LiveNodeList
and HTMLCollection share the same storage in all nodes.
(WebCore::LiveNodeListBase::~LiveNodeListBase): Ditto about unregisterNodeList.
(WebCore::LiveNodeList): Removed the calls to registerNodeList and unregisterNodeList since they
are now called in the base class.
* dom/NameNodeList.h:
(WebCore::NameNodeList::create):
* dom/NodeRareData.h:
(WebCore::NodeListsNodeData::addCacheWithAtomicName): Pass in CollectionType as the second argument
to T::create. This is used in HTMLNameCollection::create. Sevearl LiveNodeList constructors and
create functions have been modified to support this.
(WebCore::NodeListsNodeData::adoptTreeScope):
(WebCore::NodeListsNodeData::namedNodeListKey): CollectionType is no longer restricted in its range.
* dom/TagNodeList.h:
(WebCore::TagNodeList::create):
(WebCore::HTMLTagNodeList::create):
* html/CollectionType.h: Deleted a bunch of unused inline functions and constants, and cleanup enum.
* html/HTMLCollection.cpp:
(WebCore::HTMLCollection::HTMLCollection): Removed the call to registerNodeListCache since it's called
in LiveNodeListBase now.
(WebCore::HTMLCollection::~HTMLCollection): Ditto. Also replaced calls to removeCachedHTMLCollection
of Element and Document by a call to NodeListsNodeData::removeCacheWithAtomicName.
* html/HTMLFormControlsCollection.cpp:
(WebCore::HTMLFormControlsCollection::HTMLFormControlsCollection):
(WebCore::HTMLFormControlsCollection::create):
* html/HTMLFormControlsCollection.h:
(HTMLFormControlsCollection):
* html/HTMLNameCollection.cpp:
(WebCore::HTMLNameCollection::HTMLNameCollection):
(WebCore::HTMLNameCollection::~HTMLNameCollection):
* html/HTMLNameCollection.h:
(WebCore::HTMLNameCollection::create):
(HTMLNameCollection):
* html/HTMLOptionsCollection.cpp:
(WebCore::HTMLOptionsCollection::HTMLOptionsCollection):
(WebCore::HTMLOptionsCollection::create):
* html/HTMLOptionsCollection.h:
(HTMLOptionsCollection):
* html/HTMLTableRowsCollection.cpp:
(WebCore::HTMLTableRowsCollection::HTMLTableRowsCollection):
(WebCore::HTMLTableRowsCollection::create):
* html/HTMLTableRowsCollection.h:
(HTMLTableRowsCollection):
* html/LabelsNodeList.h:
(WebCore::LabelsNodeList::create):
* html/RadioNodeList.h:
(WebCore::RadioNodeList::create):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@135893 268f45cc-cd09-0410-ab3c-d52691b4dbfc

21 files changed:
Source/WebCore/ChangeLog
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h
Source/WebCore/dom/Element.cpp
Source/WebCore/dom/ElementRareData.h
Source/WebCore/dom/LiveNodeList.h
Source/WebCore/dom/NameNodeList.h
Source/WebCore/dom/NodeRareData.h
Source/WebCore/dom/TagNodeList.h
Source/WebCore/html/CollectionType.h
Source/WebCore/html/HTMLCollection.cpp
Source/WebCore/html/HTMLFormControlsCollection.cpp
Source/WebCore/html/HTMLFormControlsCollection.h
Source/WebCore/html/HTMLNameCollection.cpp
Source/WebCore/html/HTMLNameCollection.h
Source/WebCore/html/HTMLOptionsCollection.cpp
Source/WebCore/html/HTMLOptionsCollection.h
Source/WebCore/html/HTMLTableRowsCollection.cpp
Source/WebCore/html/HTMLTableRowsCollection.h
Source/WebCore/html/LabelsNodeList.h
Source/WebCore/html/RadioNodeList.h

index 2c27455..bed6291 100644 (file)
@@ -1,3 +1,89 @@
+2012-11-27  Ryosuke Niwa  <rniwa@webkit.org>
+
+        HTMLCollection on Document should be stored on NodeListsNodeData like other HTMLCollections and LiveNodeLists
+        https://bugs.webkit.org/show_bug.cgi?id=103364
+
+        Reviewed by Anders Carlsson.
+
+        Replaced the HTMLCollection storage in Document by NodeListsNodeData used by other HTMLCollection's
+        and LiveNodeList's. Now NodeListsNodeData is the only storage for HTMLCollection and LiveNodeList.
+
+        * dom/Document.cpp:
+        (WebCore::Document::Document): Removed code for m_collection since it has been removed.
+        (WebCore::Document::~Document): Ditto.
+        (WebCore::Document::registerNodeList): Renamed. 
+        (WebCore::Document::unregisterNodeList): Ditto.
+        (WebCore::Document::ensureCachedCollection): Renamed from cachedCollection to match the convetion
+        used elsewhere. Also use NodeListNodeData::addCacheWithAtomicName now that m_collection is gone.
+        (WebCore::Document::images):
+        (WebCore::Document::applets):
+        (WebCore::Document::embeds):
+        (WebCore::Document::plugins):
+        (WebCore::Document::scripts):
+        (WebCore::Document::links):
+        (WebCore::Document::forms):
+        (WebCore::Document::anchors):
+        (WebCore::Document::all):
+        (WebCore::Document::windowNamedItems): Use addCacheWithAtomicName.
+        (WebCore::Document::documentNamedItems): Ditto.
+        (WebCore::Document::reportMemoryUsage): Removed code for m_collection since it has been removed.
+        * dom/Document.h:
+        (WebCore::Document): Removed m_collections, m_documentNamedItemCollections, and
+        m_windowNamedItemCollections.
+        * dom/Element.cpp:
+        (WebCore::Element::ensureCachedHTMLCollection): Merged ElementRareData::ensureCachedHTMLCollection.
+        (WebCore::Element::cachedHTMLCollection): Merged ElementRareData::cachedHTMLCollection.
+        * Source/WebCore/dom/ElementRareData.h: Removed ensureCachedHTMLCollection, cachedHTMLCollection,
+        and removeCachedHTMLCollection since they're no longer used.
+        * dom/LiveNodeList.h:
+        (WebCore::LiveNodeListBase::LiveNodeListBase): Call registerNodeList now that LiveNodeList
+        and HTMLCollection share the same storage in all nodes.
+        (WebCore::LiveNodeListBase::~LiveNodeListBase): Ditto about unregisterNodeList.
+        (WebCore::LiveNodeList): Removed the calls to registerNodeList and unregisterNodeList since they
+        are now called in the base class.
+        * dom/NameNodeList.h:
+        (WebCore::NameNodeList::create):
+        * dom/NodeRareData.h:
+        (WebCore::NodeListsNodeData::addCacheWithAtomicName): Pass in CollectionType as the second argument
+        to T::create. This is used in HTMLNameCollection::create. Sevearl LiveNodeList constructors and
+        create functions have been modified to support this.
+        (WebCore::NodeListsNodeData::adoptTreeScope):
+        (WebCore::NodeListsNodeData::namedNodeListKey): CollectionType is no longer restricted in its range.
+        * dom/TagNodeList.h:
+        (WebCore::TagNodeList::create):
+        (WebCore::HTMLTagNodeList::create):
+        * html/CollectionType.h: Deleted a bunch of unused inline functions and constants, and cleanup enum.
+        * html/HTMLCollection.cpp:
+        (WebCore::HTMLCollection::HTMLCollection): Removed the call to registerNodeListCache since it's called
+        in LiveNodeListBase now.
+        (WebCore::HTMLCollection::~HTMLCollection): Ditto. Also replaced calls to removeCachedHTMLCollection
+        of Element and Document by a call to NodeListsNodeData::removeCacheWithAtomicName.
+        * html/HTMLFormControlsCollection.cpp:
+        (WebCore::HTMLFormControlsCollection::HTMLFormControlsCollection):
+        (WebCore::HTMLFormControlsCollection::create):
+        * html/HTMLFormControlsCollection.h:
+        (HTMLFormControlsCollection):
+        * html/HTMLNameCollection.cpp:
+        (WebCore::HTMLNameCollection::HTMLNameCollection):
+        (WebCore::HTMLNameCollection::~HTMLNameCollection):
+        * html/HTMLNameCollection.h:
+        (WebCore::HTMLNameCollection::create):
+        (HTMLNameCollection):
+        * html/HTMLOptionsCollection.cpp:
+        (WebCore::HTMLOptionsCollection::HTMLOptionsCollection):
+        (WebCore::HTMLOptionsCollection::create):
+        * html/HTMLOptionsCollection.h:
+        (HTMLOptionsCollection):
+        * html/HTMLTableRowsCollection.cpp:
+        (WebCore::HTMLTableRowsCollection::HTMLTableRowsCollection):
+        (WebCore::HTMLTableRowsCollection::create):
+        * html/HTMLTableRowsCollection.h:
+        (HTMLTableRowsCollection):
+        * html/LabelsNodeList.h:
+        (WebCore::LabelsNodeList::create):
+        * html/RadioNodeList.h:
+        (WebCore::RadioNodeList::create):
+
 2012-11-27  Pravin D  <pravind.2k4@gmail.com>
 
         max-height property not respected in case of tables
index 3759c44..db74d55 100644 (file)
@@ -571,9 +571,6 @@ Document::Document(Frame* frame, const KURL& url, bool isXHTML, bool isHTML)
     for (unsigned i = 0; i < WTF_ARRAY_LENGTH(m_nodeListCounts); i++)
         m_nodeListCounts[i] = 0;
 
-    for (unsigned i = 0; i < WTF_ARRAY_LENGTH(m_collections); i++)
-        m_collections[i] = 0;
-
     InspectorCounters::incrementCounter(InspectorCounters::DocumentCounter);
 }
 
@@ -666,9 +663,6 @@ Document::~Document()
     for (unsigned i = 0; i < WTF_ARRAY_LENGTH(m_nodeListCounts); i++)
         ASSERT(!m_nodeListCounts[i]);
 
-    for (unsigned i = 0; i < WTF_ARRAY_LENGTH(m_collections); i++)
-        ASSERT(!m_collections[i]);
-
     m_document = 0;
 
     InspectorCounters::decrementCounter(InspectorCounters::DocumentCounter);
@@ -3459,7 +3453,7 @@ void Document::setCSSTarget(Element* n)
     }
 }
 
-void Document::registerNodeListCache(LiveNodeListBase* list)
+void Document::registerNodeList(LiveNodeListBase* list)
 {
     if (list->hasIdNameCache())
         m_nodeListCounts[InvalidateOnIdNameAttrChange]++;
@@ -3468,7 +3462,7 @@ void Document::registerNodeListCache(LiveNodeListBase* list)
         m_listsInvalidatedAtDocument.add(list);
 }
 
-void Document::unregisterNodeListCache(LiveNodeListBase* list)
+void Document::unregisterNodeList(LiveNodeListBase* list)
 {
     if (list->hasIdNameCache())
         m_nodeListCounts[InvalidateOnIdNameAttrChange]--;
@@ -4334,108 +4328,65 @@ bool Document::hasSVGRootNode() const
 }
 #endif
 
-// FIXME: This caching mechanism should be merged that of LiveNodeList in NodeRareData.
-PassRefPtr<HTMLCollection> Document::cachedCollection(CollectionType type)
-{
-    ASSERT(static_cast<unsigned>(type) < NumUnnamedDocumentCachedTypes);
-    if (m_collections[type])
-        return m_collections[type];
-
-    RefPtr<HTMLCollection> collection;
-    if (type == DocAll)
-        collection = HTMLAllCollection::create(this);
-    else
-        collection = HTMLCollection::create(this, type);
-    m_collections[type] = collection.get();
-
-    return collection.release();
-}
-
-void Document::removeCachedHTMLCollection(HTMLCollection* collection, CollectionType type)
+PassRefPtr<HTMLCollection> Document::ensureCachedCollection(CollectionType type)
 {
-    ASSERT_UNUSED(collection, m_collections[type] == collection);
-    m_collections[type] = 0;
+    return ensureRareData()->ensureNodeLists()->addCacheWithAtomicName<HTMLCollection>(this, type);
 }
 
 PassRefPtr<HTMLCollection> Document::images()
 {
-    return cachedCollection(DocImages);
+    return ensureCachedCollection(DocImages);
 }
 
 PassRefPtr<HTMLCollection> Document::applets()
 {
-    return cachedCollection(DocApplets);
+    return ensureCachedCollection(DocApplets);
 }
 
 PassRefPtr<HTMLCollection> Document::embeds()
 {
-    return cachedCollection(DocEmbeds);
+    return ensureCachedCollection(DocEmbeds);
 }
 
 PassRefPtr<HTMLCollection> Document::plugins()
 {
     // This is an alias for embeds() required for the JS DOM bindings.
-    return cachedCollection(DocEmbeds);
+    return ensureCachedCollection(DocEmbeds);
 }
 
 PassRefPtr<HTMLCollection> Document::scripts()
 {
-    return cachedCollection(DocScripts);
+    return ensureCachedCollection(DocScripts);
 }
 
 PassRefPtr<HTMLCollection> Document::links()
 {
-    return cachedCollection(DocLinks);
+    return ensureCachedCollection(DocLinks);
 }
 
 PassRefPtr<HTMLCollection> Document::forms()
 {
-    return cachedCollection(DocForms);
+    return ensureCachedCollection(DocForms);
 }
 
 PassRefPtr<HTMLCollection> Document::anchors()
 {
-    return cachedCollection(DocAnchors);
+    return ensureCachedCollection(DocAnchors);
 }
 
 PassRefPtr<HTMLCollection> Document::all()
 {
-    return cachedCollection(DocAll);
+    return ensureCachedCollection(DocAll);
 }
 
 PassRefPtr<HTMLCollection> Document::windowNamedItems(const AtomicString& name)
 {
-    NamedCollectionMap::AddResult result = m_windowNamedItemCollections.add(name, 0);
-    if (!result.isNewEntry)
-        return result.iterator->value;
-
-    RefPtr<HTMLNameCollection> collection = HTMLNameCollection::create(this, WindowNamedItems, name);
-    result.iterator->value = collection.get();
-    return collection.release();
+    return ensureRareData()->ensureNodeLists()->addCacheWithAtomicName<HTMLNameCollection>(this, WindowNamedItems, name);
 }
 
 PassRefPtr<HTMLCollection> Document::documentNamedItems(const AtomicString& name)
 {
-    NamedCollectionMap::AddResult result = m_documentNamedItemCollections.add(name, 0);
-    if (!result.isNewEntry)
-        return result.iterator->value;
-
-    RefPtr<HTMLNameCollection> collection = HTMLNameCollection::create(this, DocumentNamedItems, name);
-    result.iterator->value = collection.get();
-    return collection.release();
-}
-
-// FIXME: This caching mechanism should be merged that of LiveNodeList in NodeRareData.
-void Document::removeWindowNamedItemCache(HTMLCollection* collection, const AtomicString& name)
-{
-    ASSERT_UNUSED(collection, m_windowNamedItemCollections.get(name) == collection);
-    m_windowNamedItemCollections.remove(name);
-}
-
-void Document::removeDocumentNamedItemCache(HTMLCollection* collection, const AtomicString& name)
-{
-    ASSERT_UNUSED(collection, m_documentNamedItemCollections.get(name) == collection);
-    m_documentNamedItemCollections.remove(name);
+    return ensureRareData()->ensureNodeLists()->addCacheWithAtomicName<HTMLNameCollection>(this, DocumentNamedItems, name);
 }
 
 void Document::finishedParsing()
@@ -5891,8 +5842,6 @@ void Document::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
     info.addMember(m_xmlEncoding);
     info.addMember(m_xmlVersion);
     info.addMember(m_contentLanguage);
-    info.addMember(m_documentNamedItemCollections);
-    info.addMember(m_windowNamedItemCollections);
 #if ENABLE(DASHBOARD_SUPPORT) || ENABLE(DRAGGABLE_REGION)
     info.addMember(m_annotatedRegions);
 #endif
index 075b00e..ba1e547 100644 (file)
@@ -441,12 +441,9 @@ public:
     PassRefPtr<HTMLCollection> anchors();
     PassRefPtr<HTMLCollection> scripts();
     PassRefPtr<HTMLCollection> all();
-    void removeCachedHTMLCollection(HTMLCollection*, CollectionType);
 
     PassRefPtr<HTMLCollection> windowNamedItems(const AtomicString& name);
     PassRefPtr<HTMLCollection> documentNamedItems(const AtomicString& name);
-    void removeWindowNamedItemCache(HTMLCollection*, const AtomicString&);
-    void removeDocumentNamedItemCache(HTMLCollection*, const AtomicString&);
 
     // Other methods (not part of DOM)
     bool isHTMLDocument() const { return m_isHTML; }
@@ -718,8 +715,8 @@ public:
     bool hasPendingForcedStyleRecalc() const;
     void styleRecalcTimerFired(Timer<Document>*);
 
-    void registerNodeListCache(LiveNodeListBase*);
-    void unregisterNodeListCache(LiveNodeListBase*);
+    void registerNodeList(LiveNodeListBase*);
+    void unregisterNodeList(LiveNodeListBase*);
     bool shouldInvalidateNodeListCaches(const QualifiedName* attrName = 0) const;
     void invalidateNodeListCaches(const QualifiedName* attrName);
 
@@ -1238,7 +1235,7 @@ private:
     PageVisibilityState visibilityState() const;
 #endif
 
-    PassRefPtr<HTMLCollection> cachedCollection(CollectionType);
+    PassRefPtr<HTMLCollection> ensureCachedCollection(CollectionType);
 
 #if ENABLE(FULLSCREEN_API)
     void clearFullscreenElementStack();
@@ -1410,11 +1407,6 @@ private:
     HashSet<LiveNodeListBase*> m_listsInvalidatedAtDocument;
     unsigned m_nodeListCounts[numNodeListInvalidationTypes];
 
-    HTMLCollection* m_collections[NumUnnamedDocumentCachedTypes];
-    typedef HashMap<AtomicString, HTMLNameCollection*> NamedCollectionMap;
-    NamedCollectionMap m_documentNamedItemCollections;
-    NamedCollectionMap m_windowNamedItemCollections;
-
     RefPtr<XPathEvaluator> m_xpathEvaluator;
 
 #if ENABLE(SVG)
index 77e2ce6..8f2fb7e 100644 (file)
@@ -2431,41 +2431,30 @@ void Element::updateExtraNamedItemRegistration(const AtomicString& oldId, const
 
 PassRefPtr<HTMLCollection> Element::ensureCachedHTMLCollection(CollectionType type)
 {
-    return ensureElementRareData()->ensureCachedHTMLCollection(this, type);
-}
-
-PassRefPtr<HTMLCollection> ElementRareData::ensureCachedHTMLCollection(Element* element, CollectionType type)
-{
     if (HTMLCollection* collection = cachedHTMLCollection(type))
         return collection;
 
     RefPtr<HTMLCollection> collection;
     if (type == TableRows) {
-        ASSERT(element->hasTagName(tableTag));
-        return ensureNodeLists()->addCacheWithAtomicName<HTMLTableRowsCollection>(element, type);
+        ASSERT(hasTagName(tableTag));
+        return ensureRareData()->ensureNodeLists()->addCacheWithAtomicName<HTMLTableRowsCollection>(this, type);
     } else if (type == SelectOptions) {
-        ASSERT(element->hasTagName(selectTag));
-        return ensureNodeLists()->addCacheWithAtomicName<HTMLOptionsCollection>(element, type);
+        ASSERT(hasTagName(selectTag));
+        return ensureRareData()->ensureNodeLists()->addCacheWithAtomicName<HTMLOptionsCollection>(this, type);
     } else if (type == FormControls) {
-        ASSERT(element->hasTagName(formTag) || element->hasTagName(fieldsetTag));
-        return ensureNodeLists()->addCacheWithAtomicName<HTMLFormControlsCollection>(element, type);
+        ASSERT(hasTagName(formTag) || hasTagName(fieldsetTag));
+        return ensureRareData()->ensureNodeLists()->addCacheWithAtomicName<HTMLFormControlsCollection>(this, type);
 #if ENABLE(MICRODATA)
     } else if (type == ItemProperties) {
-        return ensureNodeLists()->addCacheWithAtomicName<HTMLPropertiesCollection>(element, type);
+        return ensureRareData()->ensureNodeLists()->addCacheWithAtomicName<HTMLPropertiesCollection>(this, type);
 #endif
     }
-    return ensureNodeLists()->addCacheWithAtomicName<HTMLCollection>(element, type);
+    return ensureRareData()->ensureNodeLists()->addCacheWithAtomicName<HTMLCollection>(this, type);
 }
 
 HTMLCollection* Element::cachedHTMLCollection(CollectionType type)
 {
-    return hasRareData() ? elementRareData()->cachedHTMLCollection(type) : 0;
-}
-
-void Element::removeCachedHTMLCollection(HTMLCollection* collection, CollectionType type)
-{
-    ASSERT(hasRareData());
-    elementRareData()->removeCachedHTMLCollection(collection, type);
+    return hasRareData() && rareData()->nodeLists() ? rareData()->nodeLists()->cacheWithAtomicName<HTMLCollection>(type) : 0;
 }
 
 IntSize Element::savedLayerScrollOffset() const
index 4501f19..43733d5 100644 (file)
@@ -24,9 +24,7 @@
 
 #include "ClassList.h"
 #include "DatasetDOMStringMap.h"
-#include "Element.h"
 #include "ElementShadow.h"
-#include "HTMLCollection.h"
 #include "NamedNodeMap.h"
 #include "NodeRareData.h"
 #include "StyleInheritedData.h"
@@ -34,8 +32,6 @@
 
 namespace WebCore {
 
-class HTMLCollection;
-
 class ElementRareData : public NodeRareData {
 public:
     ElementRareData();
@@ -58,18 +54,6 @@ public:
     using NodeRareData::setIsInTopLayer;
 #endif
 
-    PassRefPtr<HTMLCollection> ensureCachedHTMLCollection(Element*, CollectionType);
-    HTMLCollection* cachedHTMLCollection(CollectionType type)
-    {
-        return nodeLists() ? nodeLists()->cacheWithAtomicName<HTMLCollection>(type) : 0;
-    }
-
-    void removeCachedHTMLCollection(HTMLCollection* collection, CollectionType type)
-    {
-        ASSERT(nodeLists());
-        nodeLists()->removeCacheWithAtomicName(collection, type);
-    }
-
     virtual void reportMemoryUsage(MemoryObjectInfo*) const OVERRIDE;
 
     LayoutSize m_minimumSizeForResizing;
index 20a103d..5b5368e 100644 (file)
@@ -66,6 +66,15 @@ public:
         ASSERT(m_invalidationType == static_cast<unsigned>(invalidationType));
         ASSERT(m_collectionType == static_cast<unsigned>(collectionType));
         ASSERT(!m_overridesItemAfter || !isNodeList(collectionType));
+
+        if (collectionType != ChildNodeListType)
+            document()->registerNodeList(this);
+    }
+
+    virtual ~LiveNodeListBase()
+    {
+        if (type() != ChildNodeListType)
+            document()->unregisterNodeList(this);
     }
 
     virtual void reportMemoryUsage(MemoryObjectInfo*) const;
@@ -186,16 +195,7 @@ public:
     LiveNodeList(PassRefPtr<Node> ownerNode, CollectionType collectionType, NodeListInvalidationType invalidationType, NodeListRootType rootType = NodeListIsRootedAtNode)
         : LiveNodeListBase(ownerNode.get(), rootType, invalidationType, collectionType == ChildNodeListType,
         collectionType, DoesNotOverrideItemAfter)
-    {
-        if (collectionType != ChildNodeListType)
-            document()->registerNodeListCache(this);
-    }
-
-    virtual ~LiveNodeList()
-    {
-        if (type() != ChildNodeListType)
-            document()->unregisterNodeListCache(this);
-    }
+    { }
 
     virtual Node* namedItem(const AtomicString&) const OVERRIDE;
     virtual bool nodeMatches(Element*) const = 0;
index 8d8512b..a7f7c14 100644 (file)
@@ -33,8 +33,9 @@ namespace WebCore {
 // NodeList which lists all Nodes in a Element with a given "name" attribute
 class NameNodeList : public LiveNodeList {
 public:
-    static PassRefPtr<NameNodeList> create(PassRefPtr<Node> rootNode, const AtomicString& name)
+    static PassRefPtr<NameNodeList> create(PassRefPtr<Node> rootNode, CollectionType type, const AtomicString& name)
     {
+        ASSERT_UNUSED(type, type == NameNodeListType);
         return adoptRef(new NameNodeList(rootNode, name));
     }
 
index 65959f7..9780d66 100644 (file)
@@ -70,13 +70,13 @@ public:
         if (!result.isNewEntry)
             return static_cast<T*>(result.iterator->value);
 
-        RefPtr<T> list = T::create(node, name);
+        RefPtr<T> list = T::create(node, collectionType, name);
         result.iterator->value = list.get();
         return list.release();
     }
 
     template<typename T>
-    PassRefPtr<T> addCacheWithAtomicName(Element* node, CollectionType collectionType)
+    PassRefPtr<T> addCacheWithAtomicName(Node* node, CollectionType collectionType)
     {
         NodeListAtomicNameCacheMap::AddResult result = m_atomicNameCaches.add(namedNodeListKey(collectionType, starAtom), 0);
         if (!result.isNewEntry)
@@ -155,23 +155,23 @@ public:
             NodeListAtomicNameCacheMap::const_iterator atomicNameCacheEnd = m_atomicNameCaches.end();
             for (NodeListAtomicNameCacheMap::const_iterator it = m_atomicNameCaches.begin(); it != atomicNameCacheEnd; ++it) {
                 LiveNodeListBase* list = it->value;
-                oldDocument->unregisterNodeListCache(list);
-                newDocument->registerNodeListCache(list);
+                oldDocument->unregisterNodeList(list);
+                newDocument->registerNodeList(list);
             }
 
             NodeListNameCacheMap::const_iterator nameCacheEnd = m_nameCaches.end();
             for (NodeListNameCacheMap::const_iterator it = m_nameCaches.begin(); it != nameCacheEnd; ++it) {
                 LiveNodeListBase* list = it->value;
-                oldDocument->unregisterNodeListCache(list);
-                newDocument->registerNodeListCache(list);
+                oldDocument->unregisterNodeList(list);
+                newDocument->registerNodeList(list);
             }
 
             TagNodeListCacheNS::const_iterator tagEnd = m_tagNodeListCacheNS.end();
             for (TagNodeListCacheNS::const_iterator it = m_tagNodeListCacheNS.begin(); it != tagEnd; ++it) {
                 LiveNodeListBase* list = it->value;
                 ASSERT(!list->isRootedAtDocument());
-                oldDocument->unregisterNodeListCache(list);
-                newDocument->registerNodeListCache(list);
+                oldDocument->unregisterNodeList(list);
+                newDocument->registerNodeList(list);
             }
         }
     }
@@ -183,14 +183,12 @@ private:
 
     std::pair<unsigned char, AtomicString> namedNodeListKey(CollectionType type, const AtomicString& name)
     {
-        ASSERT(type >= FirstNodeCollectionType);
-        return std::pair<unsigned char, AtomicString>(type - FirstNodeCollectionType, name);
+        return std::pair<unsigned char, AtomicString>(type, name);
     }
 
     std::pair<unsigned char, String> namedNodeListKey(CollectionType type, const String& name)
     {
-        ASSERT(type >= FirstNodeCollectionType);
-        return std::pair<unsigned char, String>(type - FirstNodeCollectionType, name);
+        return std::pair<unsigned char, String>(type, name);
     }
 
     NodeListAtomicNameCacheMap m_atomicNameCaches;
index 95c0f5d..a0c1651 100644 (file)
@@ -38,8 +38,9 @@ namespace WebCore {
             return adoptRef(new TagNodeList(rootNode, namespaceURI, localName));
         }
 
-        static PassRefPtr<TagNodeList> create(PassRefPtr<Node> rootNode, const AtomicString& localName)
+        static PassRefPtr<TagNodeList> create(PassRefPtr<Node> rootNode, CollectionType type, const AtomicString& localName)
         {
+            ASSERT_UNUSED(type, type == TagNodeListType);
             return adoptRef(new TagNodeList(rootNode, starAtom, localName));
         }
 
@@ -56,8 +57,9 @@ namespace WebCore {
 
     class HTMLTagNodeList : public TagNodeList {
     public:
-        static PassRefPtr<HTMLTagNodeList> create(PassRefPtr<Node> rootNode, const AtomicString& localName)
+        static PassRefPtr<HTMLTagNodeList> create(PassRefPtr<Node> rootNode, CollectionType type, const AtomicString& localName)
         {
+            ASSERT_UNUSED(type, type == TagNodeListType);
             return adoptRef(new HTMLTagNodeList(rootNode, localName));
         }
 
index f43d5df..9ec75c0 100644 (file)
@@ -26,8 +26,7 @@
 namespace WebCore {
 
 enum CollectionType {
-    // unnamed collection types cached in the document
-
+    // Unnamed HTMLCollection types cached in the document.
     DocImages,    // all <img> elements in the document
     DocApplets,   // all <object> and <applet> elements
     DocEmbeds,    // all <embed> elements
@@ -35,16 +34,13 @@ enum CollectionType {
     DocLinks,     // all <a> _and_ <area> elements with a value for href
     DocAnchors,   // all <a> elements with a value for name
     DocScripts,   // all <script> elements
-
     DocAll,       // "all" elements (IE)
 
-    // named collection types cached in the document
-
+    // Named collection types cached in the document.
     WindowNamedItems,
     DocumentNamedItems,
 
-    // types not cached in the document; these are types that can't be used on a document
-
+    // Unnamed HTMLCollection types cached in elements.
     NodeChildren, // first-level children (IE)
     TableTBodies, // all <tbody> elements in this table
     TSectionRows, // all row elements in this table section
@@ -54,15 +50,12 @@ enum CollectionType {
     SelectedOptions,
     DataListOptions,
     MapAreas,
-
 #if ENABLE(MICRODATA)
     ItemProperties, // Microdata item properties in the document
 #endif
-
     FormControls,
 
-    // Live node lists.
-
+    // Live NodeList.
     ChildNodeListType,
     ClassNodeListType,
     NameNodeListType,
@@ -73,22 +66,8 @@ enum CollectionType {
     PropertyNodeListType,
 };
 
-static const CollectionType FirstUnnamedDocumentCachedType = DocImages;
-static const unsigned NumUnnamedDocumentCachedTypes = WindowNamedItems - DocImages;
-
-static const CollectionType FirstNodeCollectionType = NodeChildren;
 static const CollectionType FirstNodeListType = ChildNodeListType;
 
-inline bool isUnnamedDocumentCachedType(CollectionType type)
-{
-    return static_cast<unsigned>(type) < NumUnnamedDocumentCachedTypes;
-}
-
-inline bool isNodeCollectionType(CollectionType type)
-{
-    return type >= FirstNodeCollectionType;
-}
-
 inline bool isNodeList(CollectionType type)
 {
     return type >= FirstNodeListType;
index df20954..278f793 100644 (file)
@@ -29,6 +29,7 @@
 #include "HTMLObjectElement.h"
 #include "HTMLOptionElement.h"
 #include "NodeList.h"
+#include "NodeRareData.h"
 
 #if ENABLE(MICRODATA)
 #include "HTMLPropertiesCollection.h"
@@ -179,7 +180,6 @@ HTMLCollection::HTMLCollection(Node* ownerNode, CollectionType type, ItemAfterOv
     : LiveNodeListBase(ownerNode, rootTypeFromCollectionType(type), invalidationTypeExcludingIdAndNameAttributes(type),
         WebCore::shouldOnlyIncludeDirectChildren(type), type, itemAfterOverrideType)
 {
-    document()->registerNodeListCache(this);
 }
 
 PassRefPtr<HTMLCollection> HTMLCollection::create(Node* base, CollectionType type)
@@ -189,16 +189,9 @@ PassRefPtr<HTMLCollection> HTMLCollection::create(Node* base, CollectionType typ
 
 HTMLCollection::~HTMLCollection()
 {
-    if (isUnnamedDocumentCachedType(type())) {
-        ASSERT(base()->isDocumentNode());
-        static_cast<Document*>(base())->removeCachedHTMLCollection(this, type());
-    } else if (isNodeCollectionType(type())) {
-        ASSERT(base()->isElementNode());
-        toElement(base())->removeCachedHTMLCollection(this, type());
-    } else // HTMLNameCollection removes cache by itself.
-        ASSERT(type() == WindowNamedItems || type() == DocumentNamedItems);
-
-    document()->unregisterNodeListCache(this);
+    // HTMLNameCollection removes cache by itself.
+    if (type() != WindowNamedItems && type() != DocumentNamedItems)
+        ownerNode()->nodeLists()->removeCacheWithAtomicName(this, type());
 }
 
 static inline bool isAcceptableElement(CollectionType type, Element* element)
index e735209..aac92ba 100644 (file)
@@ -36,13 +36,13 @@ using namespace HTMLNames;
 // Since the collections are to be "live", we have to do the
 // calculation every time if anything has changed.
 
-HTMLFormControlsCollection::HTMLFormControlsCollection(Element* base)
+HTMLFormControlsCollection::HTMLFormControlsCollection(Node* base)
     : HTMLCollection(base, FormControls, OverridesItemAfter)
 {
     ASSERT(base->hasTagName(formTag) || base->hasTagName(fieldsetTag));
 }
 
-PassRefPtr<HTMLFormControlsCollection> HTMLFormControlsCollection::create(Element* base, CollectionType)
+PassRefPtr<HTMLFormControlsCollection> HTMLFormControlsCollection::create(Node* base, CollectionType)
 {
     return adoptRef(new HTMLFormControlsCollection(base));
 }
index 7846a50..cef0f14 100644 (file)
@@ -37,14 +37,14 @@ class QualifiedName;
 
 class HTMLFormControlsCollection : public HTMLCollection {
 public:
-    static PassRefPtr<HTMLFormControlsCollection> create(Element*, CollectionType);
+    static PassRefPtr<HTMLFormControlsCollection> create(Node*, CollectionType);
 
     virtual ~HTMLFormControlsCollection();
 
     virtual Node* namedItem(const AtomicString& name) const;
 
 private:
-    HTMLFormControlsCollection(Element*);
+    HTMLFormControlsCollection(Node*);
 
     virtual void updateNameCache() const;
 
index 36c7350..9e48527 100644 (file)
 #include "HTMLDocument.h"
 #include "HTMLNames.h"
 #include "HTMLObjectElement.h"
+#include "NodeRareData.h"
 
 namespace WebCore {
 
 using namespace HTMLNames;
 
-HTMLNameCollection::HTMLNameCollection(Document* document, CollectionType type, const AtomicString& name)
+HTMLNameCollection::HTMLNameCollection(Node* document, CollectionType type, const AtomicString& name)
     : HTMLCollection(document, type, OverridesItemAfter)
     , m_name(name)
 {
@@ -43,10 +44,8 @@ HTMLNameCollection::~HTMLNameCollection()
     ASSERT(base());
     ASSERT(base()->isDocumentNode());
     ASSERT(type() == WindowNamedItems || type() == DocumentNamedItems);
-    if (type() == WindowNamedItems)
-        static_cast<Document*>(base())->removeWindowNamedItemCache(this, m_name);
-    else
-        static_cast<Document*>(base())->removeDocumentNamedItemCache(this, m_name);
+
+    ownerNode()->nodeLists()->removeCacheWithAtomicName(this, type(), m_name);
 }
 
 Element* HTMLNameCollection::virtualItemAfter(unsigned& offsetInArray, Element* previous) const
index 4a7afeb..1fb85b9 100644 (file)
@@ -33,7 +33,7 @@ class Document;
 
 class HTMLNameCollection : public HTMLCollection {
 public:
-    static PassRefPtr<HTMLNameCollection> create(Document* document, CollectionType type, const AtomicString& name)
+    static PassRefPtr<HTMLNameCollection> create(Node* document, CollectionType type, const AtomicString& name)
     {
         return adoptRef(new HTMLNameCollection(document, type, name));
     }
@@ -41,7 +41,7 @@ public:
     ~HTMLNameCollection();
 
 private:
-    HTMLNameCollection(Document*, CollectionType, const AtomicString& name);
+    HTMLNameCollection(Node*, CollectionType, const AtomicString& name);
 
     virtual Element* virtualItemAfter(unsigned& offsetInArray, Element*) const OVERRIDE;
 
index 06dda7a..75b707e 100644 (file)
 
 namespace WebCore {
 
-HTMLOptionsCollection::HTMLOptionsCollection(Element* select)
+HTMLOptionsCollection::HTMLOptionsCollection(Node* select)
     : HTMLCollection(select, SelectOptions, DoesNotOverrideItemAfter)
 {
     ASSERT(select->hasTagName(HTMLNames::selectTag));
 }
 
-PassRefPtr<HTMLOptionsCollection> HTMLOptionsCollection::create(Element* select, CollectionType)
+PassRefPtr<HTMLOptionsCollection> HTMLOptionsCollection::create(Node* select, CollectionType)
 {
     return adoptRef(new HTMLOptionsCollection(select));
 }
index 46e450d..d76580f 100644 (file)
@@ -35,7 +35,7 @@ typedef int ExceptionCode;
 
 class HTMLOptionsCollection : public HTMLCollection {
 public:
-    static PassRefPtr<HTMLOptionsCollection> create(Element*, CollectionType);
+    static PassRefPtr<HTMLOptionsCollection> create(Node*, CollectionType);
 
     void add(PassRefPtr<HTMLOptionElement>, ExceptionCode&);
     void add(PassRefPtr<HTMLOptionElement>, int index, ExceptionCode&);
@@ -47,7 +47,7 @@ public:
     void setLength(unsigned, ExceptionCode&);
 
 private:
-    HTMLOptionsCollection(Element*);
+    HTMLOptionsCollection(Node*);
 };
 
 } //namespace
index d94038e..9845936 100644 (file)
@@ -151,13 +151,13 @@ HTMLTableRowElement* HTMLTableRowsCollection::lastRow(HTMLTableElement* table)
 // Must call get() on the table in case that argument is compiled before dereferencing the
 // table to get at the collection cache. Order of argument evaluation is undefined and can
 // differ between compilers.
-HTMLTableRowsCollection::HTMLTableRowsCollection(Element* table)
+HTMLTableRowsCollection::HTMLTableRowsCollection(Node* table)
     : HTMLCollection(table, TableRows, OverridesItemAfter)
 {
     ASSERT(table->hasTagName(tableTag));
 }
 
-PassRefPtr<HTMLTableRowsCollection> HTMLTableRowsCollection::create(Element* table, CollectionType)
+PassRefPtr<HTMLTableRowsCollection> HTMLTableRowsCollection::create(Node* table, CollectionType)
 {
     return adoptRef(new HTMLTableRowsCollection(table));
 }
index c431289..1a54f0f 100644 (file)
@@ -38,13 +38,13 @@ class HTMLTableRowElement;
 
 class HTMLTableRowsCollection : public HTMLCollection {
 public:
-    static PassRefPtr<HTMLTableRowsCollection> create(Element*, CollectionType);
+    static PassRefPtr<HTMLTableRowsCollection> create(Node*, CollectionType);
 
     static HTMLTableRowElement* rowAfter(HTMLTableElement*, HTMLTableRowElement*);
     static HTMLTableRowElement* lastRow(HTMLTableElement*);
 
 private:
-    HTMLTableRowsCollection(Element*);
+    HTMLTableRowsCollection(Node*);
 
     virtual Element* virtualItemAfter(unsigned& offsetInArray, Element*) const OVERRIDE;
 };
index 9052eed..0da4f3c 100644 (file)
@@ -32,8 +32,9 @@ namespace WebCore {
 
 class LabelsNodeList : public LiveNodeList {
 public:
-    static PassRefPtr<LabelsNodeList> create(Node* forNode, const AtomicString&)
+    static PassRefPtr<LabelsNodeList> create(Node* forNode, CollectionType type, const AtomicString&)
     {
+        ASSERT_UNUSED(type, type == LabelsNodeListType);
         return adoptRef(new LabelsNodeList(forNode));
     }
     ~LabelsNodeList();
index 23a527d..57cad32 100644 (file)
@@ -36,8 +36,9 @@ namespace WebCore {
 
 class RadioNodeList : public LiveNodeList {
 public:
-    static PassRefPtr<RadioNodeList> create(Node* rootNode, const AtomicString& name)
+    static PassRefPtr<RadioNodeList> create(Node* rootNode, CollectionType type, const AtomicString& name)
     {
+        ASSERT_UNUSED(type, type == RadioNodeListType);
         return adoptRef(new RadioNodeList(rootNode, name));
     }