Title: [158587] trunk/Source/WebCore
Revision
158587
Author
[email protected]
Date
2013-11-04 13:31:27 -0800 (Mon, 04 Nov 2013)

Log Message

Make LiveNodeListBase use Elements instead of Nodes
https://bugs.webkit.org/show_bug.cgi?id=123745

Reviewed by Anders Carlsson.

* WebCore.exp.in:
* dom/Element.cpp:
(WebCore::Element::firstElementChild):
(WebCore::Element::lastElementChild):
        
    Switch to correct calls. ElementTraversal::previous and previousChild are no longer equivalent.

* dom/ElementTraversal.h:
(WebCore::::lastWithinTemplate):
(WebCore::::previousTemplate):
        
    Fix ElementTraversal::lastWithin and previous. They had no real clients and didn't work correctly.
    With LiveNodeListBase starting to use these they get excellent test coverage.

* dom/LiveNodeList.cpp:
(WebCore::LiveNodeListBase::invalidateCache):
* dom/LiveNodeList.h:
(WebCore::LiveNodeListBase::LiveNodeListBase):
(WebCore::LiveNodeListBase::isElementCacheValid):
(WebCore::LiveNodeListBase::cachedElement):
(WebCore::LiveNodeListBase::cachedElementOffset):
(WebCore::LiveNodeListBase::setCachedElement):
        
    Make the cache Element based.
    Switch to Elements in all helpers.
    Rename item -> element for clarity.

* dom/NodeIterator.cpp:
(WebCore::NodeIterator::NodePointer::moveToPrevious):
(WebCore::NodeIterator::updateForNodeRemoval):
        
    This code expected the old inconsistent NodeTraversal::previous behavior where the traversal includes
    the root as the last item. Drop the stayWithin parameter and handle the one case where it is needed here.

* dom/NodeTraversal.cpp:
(WebCore::NodeTraversal::last):
(WebCore::NodeTraversal::deepLastChild):
* dom/NodeTraversal.h:
        
    Support ElementTraversal::previous/lastWithin.

(WebCore::NodeTraversal::previous):
        
    This was slightly wrong too.

* html/HTMLCollection.cpp:
(WebCore::previousElement):
(WebCore::lastElement):
(WebCore::LiveNodeListBase::iterateForPreviousElement):
(WebCore::LiveNodeListBase::itemBefore):
(WebCore::LiveNodeListBase::isLastItemCloserThanLastOrCachedItem):
(WebCore::LiveNodeListBase::isFirstItemCloserThanCachedItem):
(WebCore::LiveNodeListBase::setCachedElement):
(WebCore::LiveNodeListBase::item):
(WebCore::LiveNodeListBase::elementBeforeOrAfterCachedElement):
* html/HTMLCollection.h:
(WebCore::HTMLCollection::isEmpty):
(WebCore::HTMLCollection::hasExactlyOneItem):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (158586 => 158587)


--- trunk/Source/WebCore/ChangeLog	2013-11-04 21:28:38 UTC (rev 158586)
+++ trunk/Source/WebCore/ChangeLog	2013-11-04 21:31:27 UTC (rev 158587)
@@ -1,3 +1,69 @@
+2013-11-04  Antti Koivisto  <[email protected]>
+
+        Make LiveNodeListBase use Elements instead of Nodes
+        https://bugs.webkit.org/show_bug.cgi?id=123745
+
+        Reviewed by Anders Carlsson.
+
+        * WebCore.exp.in:
+        * dom/Element.cpp:
+        (WebCore::Element::firstElementChild):
+        (WebCore::Element::lastElementChild):
+        
+            Switch to correct calls. ElementTraversal::previous and previousChild are no longer equivalent.
+
+        * dom/ElementTraversal.h:
+        (WebCore::::lastWithinTemplate):
+        (WebCore::::previousTemplate):
+        
+            Fix ElementTraversal::lastWithin and previous. They had no real clients and didn't work correctly.
+            With LiveNodeListBase starting to use these they get excellent test coverage.
+
+        * dom/LiveNodeList.cpp:
+        (WebCore::LiveNodeListBase::invalidateCache):
+        * dom/LiveNodeList.h:
+        (WebCore::LiveNodeListBase::LiveNodeListBase):
+        (WebCore::LiveNodeListBase::isElementCacheValid):
+        (WebCore::LiveNodeListBase::cachedElement):
+        (WebCore::LiveNodeListBase::cachedElementOffset):
+        (WebCore::LiveNodeListBase::setCachedElement):
+        
+            Make the cache Element based.
+            Switch to Elements in all helpers.
+            Rename item -> element for clarity.
+
+        * dom/NodeIterator.cpp:
+        (WebCore::NodeIterator::NodePointer::moveToPrevious):
+        (WebCore::NodeIterator::updateForNodeRemoval):
+        
+            This code expected the old inconsistent NodeTraversal::previous behavior where the traversal includes
+            the root as the last item. Drop the stayWithin parameter and handle the one case where it is needed here.
+
+        * dom/NodeTraversal.cpp:
+        (WebCore::NodeTraversal::last):
+        (WebCore::NodeTraversal::deepLastChild):
+        * dom/NodeTraversal.h:
+        
+            Support ElementTraversal::previous/lastWithin.
+
+        (WebCore::NodeTraversal::previous):
+        
+            This was slightly wrong too.
+
+        * html/HTMLCollection.cpp:
+        (WebCore::previousElement):
+        (WebCore::lastElement):
+        (WebCore::LiveNodeListBase::iterateForPreviousElement):
+        (WebCore::LiveNodeListBase::itemBefore):
+        (WebCore::LiveNodeListBase::isLastItemCloserThanLastOrCachedItem):
+        (WebCore::LiveNodeListBase::isFirstItemCloserThanCachedItem):
+        (WebCore::LiveNodeListBase::setCachedElement):
+        (WebCore::LiveNodeListBase::item):
+        (WebCore::LiveNodeListBase::elementBeforeOrAfterCachedElement):
+        * html/HTMLCollection.h:
+        (WebCore::HTMLCollection::isEmpty):
+        (WebCore::HTMLCollection::hasExactlyOneItem):
+
 2013-11-04  Michael Saboff  <[email protected]>
 
         Eliminate HostCall bit from JSC Stack CallerFrame

Modified: trunk/Source/WebCore/WebCore.exp.in (158586 => 158587)


--- trunk/Source/WebCore/WebCore.exp.in	2013-11-04 21:28:38 UTC (rev 158586)
+++ trunk/Source/WebCore/WebCore.exp.in	2013-11-04 21:31:27 UTC (rev 158587)
@@ -284,8 +284,8 @@
 __ZN7WebCore13IdentifierRep3getEi
 __ZN7WebCore13JSHTMLElement6s_infoE
 __ZN7WebCore13KeyboardEventC1ERKNS_21PlatformKeyboardEventEPNS_9DOMWindowE
+__ZN7WebCore13NodeTraversal13deepLastChildEPNS_4NodeE
 __ZN7WebCore13NodeTraversal19nextAncestorSiblingEPKNS_4NodeE
-__ZN7WebCore13NodeTraversal8previousEPKNS_4NodeES3_
 __ZN7WebCore13PageThrottler22reportInterestingEventEv
 __ZN7WebCore13PageThrottlerD1Ev
 __ZN7WebCore13QualifiedNameD1Ev

Modified: trunk/Source/WebCore/dom/Element.cpp (158586 => 158587)


--- trunk/Source/WebCore/dom/Element.cpp	2013-11-04 21:28:38 UTC (rev 158586)
+++ trunk/Source/WebCore/dom/Element.cpp	2013-11-04 21:31:27 UTC (rev 158587)
@@ -2475,12 +2475,12 @@
 // ElementTraversal API
 Element* Element::firstElementChild() const
 {
-    return ElementTraversal::firstWithin(this);
+    return ElementTraversal::firstChild(this);
 }
 
 Element* Element::lastElementChild() const
 {
-    return ElementTraversal::lastWithin(this);
+    return ElementTraversal::lastChild(this);
 }
 
 Element* Element::previousElementSibling() const

Modified: trunk/Source/WebCore/dom/ElementTraversal.h (158586 => 158587)


--- trunk/Source/WebCore/dom/ElementTraversal.h	2013-11-04 21:28:38 UTC (rev 158586)
+++ trunk/Source/WebCore/dom/ElementTraversal.h	2013-11-04 21:31:27 UTC (rev 158587)
@@ -39,7 +39,7 @@
     static ElementType* lastChild(const Node*);
     static ElementType* lastChild(const ContainerNode*);
 
-    // First or last ElementType descendant of the node. For Elements this is always the same as first/last child.
+    // First or last ElementType descendant of the node. For Elements firstWithin is always the same as first child.
     static ElementType* firstWithin(const Node*);
     static ElementType* firstWithin(const ContainerNode*);
     static ElementType* lastWithin(const Node*);
@@ -106,7 +106,10 @@
 template <typename CurrentType>
 inline Element* Traversal<Element>::lastWithinTemplate(CurrentType* current)
 {
-    return lastChildTemplate(current);
+    Node* node = NodeTraversal::last(current);
+    while (node && !node->isElementNode())
+        node = NodeTraversal::previous(node, current);
+    return static_cast<Element*>(node);
 }
 
 template <>
@@ -135,7 +138,7 @@
 {
     Node* node = NodeTraversal::previous(current);
     while (node && !node->isElementNode())
-        node = NodeTraversal::previousSkippingChildren(node);
+        node = NodeTraversal::previous(node);
     return static_cast<Element*>(node);
 }
 
@@ -145,7 +148,7 @@
 {
     Node* node = NodeTraversal::previous(current, stayWithin);
     while (node && !node->isElementNode())
-        node = NodeTraversal::previousSkippingChildren(node, stayWithin);
+        node = NodeTraversal::previous(node, stayWithin);
     return static_cast<Element*>(node);
 }
 

Modified: trunk/Source/WebCore/dom/LiveNodeList.cpp (158586 => 158587)


--- trunk/Source/WebCore/dom/LiveNodeList.cpp	2013-11-04 21:28:38 UTC (rev 158586)
+++ trunk/Source/WebCore/dom/LiveNodeList.cpp	2013-11-04 21:31:27 UTC (rev 158587)
@@ -38,9 +38,9 @@
 
 void LiveNodeListBase::invalidateCache() const
 {
-    m_cachedItem = 0;
+    m_cachedElement = nullptr;
     m_isLengthCacheValid = false;
-    m_isItemCacheValid = false;
+    m_isElementCacheValid = false;
     m_isNameCacheValid = false;
     m_isItemRefElementsCacheValid = false;
     if (isNodeList(type()))

Modified: trunk/Source/WebCore/dom/LiveNodeList.h (158586 => 158587)


--- trunk/Source/WebCore/dom/LiveNodeList.h	2013-11-04 21:28:38 UTC (rev 158586)
+++ trunk/Source/WebCore/dom/LiveNodeList.h	2013-11-04 21:31:27 UTC (rev 158587)
@@ -51,9 +51,9 @@
     LiveNodeListBase(ContainerNode& ownerNode, NodeListRootType rootType, NodeListInvalidationType invalidationType,
         bool shouldOnlyIncludeDirectChildren, CollectionType collectionType, ItemAfterOverrideType itemAfterOverrideType)
         : m_ownerNode(ownerNode)
-        , m_cachedItem(0)
+        , m_cachedElement(nullptr)
         , m_isLengthCacheValid(false)
-        , m_isItemCacheValid(false)
+        , m_isElementCacheValid(false)
         , m_rootType(rootType)
         , m_invalidationType(invalidationType)
         , m_shouldOnlyIncludeDirectChildren(shouldOnlyIncludeDirectChildren)
@@ -101,9 +101,9 @@
     ContainerNode& rootNode() const;
     bool overridesItemAfter() const { return m_overridesItemAfter; }
 
-    ALWAYS_INLINE bool isItemCacheValid() const { return m_isItemCacheValid; }
-    ALWAYS_INLINE Node* cachedItem() const { return m_cachedItem; }
-    ALWAYS_INLINE unsigned cachedItemOffset() const { return m_cachedItemOffset; }
+    ALWAYS_INLINE bool isElementCacheValid() const { return m_isElementCacheValid; }
+    ALWAYS_INLINE Element* cachedElement() const { return m_cachedElement; }
+    ALWAYS_INLINE unsigned cachedElementOffset() const { return m_cachedElementOffset; }
 
     ALWAYS_INLINE bool isLengthCacheValid() const { return m_isLengthCacheValid; }
     ALWAYS_INLINE unsigned cachedLength() const { return m_cachedLength; }
@@ -112,14 +112,13 @@
         m_cachedLength = length;
         m_isLengthCacheValid = true;
     }
-    ALWAYS_INLINE void setItemCache(Node* item, unsigned offset) const
+    ALWAYS_INLINE void setCachedElement(Element& element, unsigned offset) const
     {
-        ASSERT(item);
-        m_cachedItem = item;
-        m_cachedItemOffset = offset;
-        m_isItemCacheValid = true;
+        m_cachedElement = &element;
+        m_cachedElementOffset = offset;
+        m_isElementCacheValid = true;
     }
-    void setItemCache(Node* item, unsigned offset, unsigned elementsArrayOffset) const;
+    void setCachedElement(Element&, unsigned offset, unsigned elementsArrayOffset) const;
 
     ALWAYS_INLINE bool isItemRefElementsCacheValid() const { return m_isItemRefElementsCacheValid; }
     ALWAYS_INLINE void setItemRefElementsCacheValid() const { m_isItemRefElementsCacheValid = true; }
@@ -132,20 +131,20 @@
     bool shouldOnlyIncludeDirectChildren() const { return m_shouldOnlyIncludeDirectChildren; }
 
 private:
-    Node* itemBeforeOrAfterCachedItem(unsigned offset, ContainerNode* root) const;
+    Element* elementBeforeOrAfterCachedElement(unsigned offset, ContainerNode* root) const;
     Element* traverseLiveNodeListFirstElement(ContainerNode* root) const;
     Element* traverseLiveNodeListForwardToOffset(unsigned offset, Element* currentElement, unsigned& currentOffset, ContainerNode* root) const;
     bool isLastItemCloserThanLastOrCachedItem(unsigned offset) const;
     bool isFirstItemCloserThanCachedItem(unsigned offset) const;
-    Node* iterateForPreviousNode(Node* current) const;
-    Node* itemBefore(Node* previousItem) const;
+    Element* iterateForPreviousElement(Element* current) const;
+    Element* itemBefore(Element* previousItem) const;
 
     Ref<ContainerNode> m_ownerNode;
-    mutable Node* m_cachedItem;
+    mutable Element* m_cachedElement;
     mutable unsigned m_cachedLength;
-    mutable unsigned m_cachedItemOffset;
+    mutable unsigned m_cachedElementOffset;
     mutable unsigned m_isLengthCacheValid : 1;
-    mutable unsigned m_isItemCacheValid : 1;
+    mutable unsigned m_isElementCacheValid : 1;
     const unsigned m_rootType : 2;
     const unsigned m_invalidationType : 4;
     const unsigned m_shouldOnlyIncludeDirectChildren : 1;

Modified: trunk/Source/WebCore/dom/NodeIterator.cpp (158586 => 158587)


--- trunk/Source/WebCore/dom/NodeIterator.cpp	2013-11-04 21:28:38 UTC (rev 158586)
+++ trunk/Source/WebCore/dom/NodeIterator.cpp	2013-11-04 21:31:27 UTC (rev 158587)
@@ -66,7 +66,11 @@
         isPointerBeforeNode = true;
         return true;
     }
-    node = NodeTraversal::previous(node.get(), root);
+    if (node == root) {
+        node = nullptr;
+        return false;
+    }
+    node = NodeTraversal::previous(node.get());
     return node;
 }
 
@@ -179,13 +183,13 @@
             if (node)
                 referenceNode.node = node;
         } else {
-            node = NodeTraversal::previous(removedNode, root());
+            node = NodeTraversal::previous(removedNode);
             if (node) {
                 // Move out from under the node being removed if the reference node is
                 // a descendant of the node being removed.
                 if (willRemoveReferenceNodeAncestor) {
                     while (node && node->isDescendantOf(removedNode))
-                        node = NodeTraversal::previous(node, root());
+                        node = NodeTraversal::previous(node);
                 }
                 if (node) {
                     // Removing last node.
@@ -197,13 +201,13 @@
             }
         }
     } else {
-        Node* node = NodeTraversal::previous(removedNode, root());
+        Node* node = NodeTraversal::previous(removedNode);
         if (node) {
             // Move out from under the node being removed if the reference node is
             // a descendant of the node being removed.
             if (willRemoveReferenceNodeAncestor) {
                 while (node && node->isDescendantOf(removedNode))
-                    node = NodeTraversal::previous(node, root());
+                    node = NodeTraversal::previous(node);
             }
             if (node)
                 referenceNode.node = node;
@@ -214,7 +218,7 @@
             // a descendant of the node being removed.
             if (willRemoveReferenceNodeAncestor) {
                 while (node && node->isDescendantOf(removedNode))
-                    node = NodeTraversal::previous(node, root());
+                    node = NodeTraversal::previous(node);
             }
             if (node)
                 referenceNode.node = node;

Modified: trunk/Source/WebCore/dom/NodeTraversal.cpp (158586 => 158587)


--- trunk/Source/WebCore/dom/NodeTraversal.cpp	2013-11-04 21:28:38 UTC (rev 158586)
+++ trunk/Source/WebCore/dom/NodeTraversal.cpp	2013-11-04 21:31:27 UTC (rev 158587)
@@ -103,19 +103,23 @@
     return 0;
 }
 
-Node* previous(const Node* current, const Node* stayWithin)
+Node* last(const ContainerNode* current)
 {
-    if (current == stayWithin)
-        return 0;
-    if (current->previousSibling()) {
-        Node* previous = current->previousSibling();
-        while (previous->lastChild())
-            previous = previous->lastChild();
-        return previous;
-    }
-    return current->parentNode();
+    Node* node = current->lastChild();
+    if (!node)
+        return nullptr;
+    while (node->lastChild())
+        node = node->lastChild();
+    return node;
 }
 
+Node* deepLastChild(Node* node)
+{
+    while (node->lastChild())
+        node = node->lastChild();
+    return node;
+}
+
 Node* previousSkippingChildren(const Node* current, const Node* stayWithin)
 {
     if (current == stayWithin)

Modified: trunk/Source/WebCore/dom/NodeTraversal.h (158586 => 158587)


--- trunk/Source/WebCore/dom/NodeTraversal.h	2013-11-04 21:28:38 UTC (rev 158586)
+++ trunk/Source/WebCore/dom/NodeTraversal.h	2013-11-04 21:31:27 UTC (rev 158587)
@@ -25,7 +25,7 @@
 #ifndef NodeTraversal_h
 #define NodeTraversal_h
 
-#include "Node.h"
+#include "ContainerNode.h"
 #include "Text.h"
 
 namespace WebCore {
@@ -49,6 +49,7 @@
 Node* nextSkippingChildren(const ContainerNode*, const Node* stayWithin);
 
 // Does a reverse pre-order traversal to find the node that comes before the current one in document order
+Node* last(const ContainerNode*);
 Node* previous(const Node*, const Node* stayWithin = 0);
 
 // Like previous, but skips children and starts with the next sibling.
@@ -72,6 +73,7 @@
 
 Node* nextAncestorSibling(const Node*);
 Node* nextAncestorSibling(const Node*, const Node* stayWithin);
+Node* deepLastChild(Node*);
 
 template <class NodeType>
 inline Node* traverseNextTemplate(NodeType* current)
@@ -124,7 +126,16 @@
 inline Node* next(const Text* current) { return traverseNextSkippingChildrenTemplate(current); }
 inline Node* next(const Text* current, const Node* stayWithin) { return traverseNextSkippingChildrenTemplate(current, stayWithin); }
 
+inline Node* previous(const Node* current, const Node* stayWithin)
+{
+    if (Node* previous = current->previousSibling())
+        return deepLastChild(previous);
+    if (current->parentNode() == stayWithin)
+        return nullptr;
+    return current->parentNode();
 }
+
 }
+}
 
 #endif

Modified: trunk/Source/WebCore/html/HTMLCollection.cpp (158586 => 158587)


--- trunk/Source/WebCore/html/HTMLCollection.cpp	2013-11-04 21:28:38 UTC (rev 158586)
+++ trunk/Source/WebCore/html/HTMLCollection.cpp	2013-11-04 21:31:27 UTC (rev 158587)
@@ -251,42 +251,42 @@
     return nodeList->nodeMatchesInlined(element);
 }
 
-static Node* previousNode(Node& base, Node* previous, bool onlyIncludeDirectChildren)
+static Element* previousElement(ContainerNode& base, Element* previous, bool onlyIncludeDirectChildren)
 {
-    return onlyIncludeDirectChildren ? previous->previousSibling() : NodeTraversal::previous(previous, &base);
+    return onlyIncludeDirectChildren ? ElementTraversal::previousSibling(previous) : ElementTraversal::previous(previous, &base);
 }
 
-static Node* lastNode(Node& rootNode, bool onlyIncludeDirectChildren)
+static Element* lastElement(ContainerNode& rootNode, bool onlyIncludeDirectChildren)
 {
-    return onlyIncludeDirectChildren ? rootNode.lastChild() : rootNode.lastDescendant();
+    return onlyIncludeDirectChildren ? ElementTraversal::lastChild(&rootNode) : ElementTraversal::lastWithin(&rootNode);
 }
 
-ALWAYS_INLINE Node* LiveNodeListBase::iterateForPreviousNode(Node* current) const
+ALWAYS_INLINE Element* LiveNodeListBase::iterateForPreviousElement(Element* current) const
 {
     bool _onlyIncludeDirectChildren_ = shouldOnlyIncludeDirectChildren();
     CollectionType collectionType = type();
-    Node& rootNode = this->rootNode();
-    for (; current; current = previousNode(rootNode, current, onlyIncludeDirectChildren)) {
+    ContainerNode& rootNode = this->rootNode();
+    for (; current; current = previousElement(rootNode, current, onlyIncludeDirectChildren)) {
         if (isNodeList(collectionType)) {
-            if (current->isElementNode() && isMatchingElement(static_cast<const LiveNodeList*>(this), toElement(current)))
-                return toElement(current);
+            if (isMatchingElement(static_cast<const LiveNodeList*>(this), current))
+                return current;
         } else {
-            if (current->isElementNode() && isMatchingElement(static_cast<const HTMLCollection*>(this), toElement(current)))
-                return toElement(current);
+            if (isMatchingElement(static_cast<const HTMLCollection*>(this), current))
+                return current;
         }
     }
     return 0;
 }
 
-ALWAYS_INLINE Node* LiveNodeListBase::itemBefore(Node* previous) const
+ALWAYS_INLINE Element* LiveNodeListBase::itemBefore(Element* previous) const
 {
-    Node* current;
+    Element* current;
     if (LIKELY(!!previous)) // Without this LIKELY, length() and item() can be 10% slower.
-        current = previousNode(rootNode(), previous, shouldOnlyIncludeDirectChildren());
+        current = previousElement(rootNode(), previous, shouldOnlyIncludeDirectChildren());
     else
-        current = lastNode(rootNode(), shouldOnlyIncludeDirectChildren());
+        current = lastElement(rootNode(), shouldOnlyIncludeDirectChildren());
 
-    return iterateForPreviousNode(current);
+    return iterateForPreviousElement(current);
 }
 
 template <class NodeListType>
@@ -344,30 +344,29 @@
 {
     ASSERT(isLengthCacheValid());
     unsigned distanceFromLastItem = cachedLength() - offset;
-    if (!isItemCacheValid())
+    if (!isElementCacheValid())
         return distanceFromLastItem < offset;
 
-    return cachedItemOffset() < offset && distanceFromLastItem < offset - cachedItemOffset();
+    return cachedElementOffset() < offset && distanceFromLastItem < offset - cachedElementOffset();
 }
     
 bool ALWAYS_INLINE LiveNodeListBase::isFirstItemCloserThanCachedItem(unsigned offset) const
 {
-    ASSERT(isItemCacheValid());
-    if (cachedItemOffset() < offset)
+    ASSERT(isElementCacheValid());
+    if (cachedElementOffset() < offset)
         return false;
 
-    unsigned distanceFromCachedItem = cachedItemOffset() - offset;
+    unsigned distanceFromCachedItem = cachedElementOffset() - offset;
     return offset < distanceFromCachedItem;
 }
 
-ALWAYS_INLINE void LiveNodeListBase::setItemCache(Node* item, unsigned offset, unsigned elementsArrayOffset) const
+ALWAYS_INLINE void LiveNodeListBase::setCachedElement(Element& element, unsigned offset, unsigned elementsArrayOffset) const
 {
-    setItemCache(item, offset);
-    if (overridesItemAfter()) {
-        ASSERT_WITH_SECURITY_IMPLICATION(item->isElementNode());
+    setCachedElement(element, offset);
+    if (overridesItemAfter())
         static_cast<const HTMLCollection*>(this)->m_cachedElementsArrayOffset = elementsArrayOffset;
-    } else
-        ASSERT(!elementsArrayOffset);
+
+    ASSERT(overridesItemAfter() || !elementsArrayOffset);
 }
 
 unsigned LiveNodeListBase::length() const
@@ -384,8 +383,8 @@
 // FIXME: It is silly that these functions are in HTMLCollection.cpp.
 Node* LiveNodeListBase::item(unsigned offset) const
 {
-    if (isItemCacheValid() && cachedItemOffset() == offset)
-        return cachedItem();
+    if (isElementCacheValid() && cachedElementOffset() == offset)
+        return cachedElement();
 
     if (isLengthCacheValid() && cachedLength() <= offset)
         return 0;
@@ -393,12 +392,12 @@
     ContainerNode& root = rootNode();
 
     if (isLengthCacheValid() && !overridesItemAfter() && isLastItemCloserThanLastOrCachedItem(offset)) {
-        Node* lastItem = itemBefore(0);
+        Element* lastItem = itemBefore(0);
         ASSERT(lastItem);
-        setItemCache(lastItem, cachedLength() - 1, 0);
-    } else if (!isItemCacheValid() || isFirstItemCloserThanCachedItem(offset) || (overridesItemAfter() && offset < cachedItemOffset())) {
+        setCachedElement(*lastItem, cachedLength() - 1, 0);
+    } else if (!isElementCacheValid() || isFirstItemCloserThanCachedItem(offset) || (overridesItemAfter() && offset < cachedElementOffset())) {
         unsigned offsetInArray = 0;
-        Node* firstItem;
+        Element* firstItem;
         if (isNodeList(type()))
             firstItem = traverseLiveNodeListFirstElement(&root);
         else
@@ -408,30 +407,30 @@
             setLengthCache(0);
             return 0;
         }
-        setItemCache(firstItem, 0, offsetInArray);
-        ASSERT(!cachedItemOffset());
+        setCachedElement(*firstItem, 0, offsetInArray);
+        ASSERT(!cachedElementOffset());
     }
 
-    if (cachedItemOffset() == offset)
-        return cachedItem();
+    if (cachedElementOffset() == offset)
+        return cachedElement();
 
-    return itemBeforeOrAfterCachedItem(offset, &root);
+    return elementBeforeOrAfterCachedElement(offset, &root);
 }
 
-inline Node* LiveNodeListBase::itemBeforeOrAfterCachedItem(unsigned offset, ContainerNode* root) const
+inline Element* LiveNodeListBase::elementBeforeOrAfterCachedElement(unsigned offset, ContainerNode* root) const
 {
-    unsigned currentOffset = cachedItemOffset();
-    Node* currentItem = cachedItem();
+    unsigned currentOffset = cachedElementOffset();
+    Element* currentItem = cachedElement();
     ASSERT(currentItem);
     ASSERT(currentOffset != offset);
 
-    if (offset < cachedItemOffset()) {
+    if (offset < cachedElementOffset()) {
         ASSERT(!overridesItemAfter());
         while ((currentItem = itemBefore(currentItem))) {
             ASSERT(currentOffset);
             currentOffset--;
             if (currentOffset == offset) {
-                setItemCache(currentItem, currentOffset, 0);
+                setCachedElement(*currentItem, currentOffset, 0);
                 return currentItem;
             }
         }
@@ -441,16 +440,16 @@
 
     unsigned offsetInArray = 0;
     if (isNodeList(type()))
-        currentItem = traverseLiveNodeListForwardToOffset(offset, toElement(currentItem), currentOffset, root);
+        currentItem = traverseLiveNodeListForwardToOffset(offset, currentItem, currentOffset, root);
     else
-        currentItem = static_cast<const HTMLCollection*>(this)->traverseForwardToOffset(offset, toElement(currentItem), currentOffset, offsetInArray, root);
+        currentItem = static_cast<const HTMLCollection*>(this)->traverseForwardToOffset(offset, currentItem, currentOffset, offsetInArray, root);
 
     if (!currentItem) {
         // Did not find the item. On plus side, we now know the length.
         setLengthCache(currentOffset + 1);
         return 0;
     }
-    setItemCache(currentItem, currentOffset, offsetInArray);
+    setCachedElement(*currentItem, currentOffset, offsetInArray);
     return currentItem;
 }
 

Modified: trunk/Source/WebCore/html/HTMLCollection.h (158586 => 158587)


--- trunk/Source/WebCore/html/HTMLCollection.h	2013-11-04 21:28:38 UTC (rev 158586)
+++ trunk/Source/WebCore/html/HTMLCollection.h	2013-11-04 21:31:27 UTC (rev 158587)
@@ -48,16 +48,16 @@
     {
         if (isLengthCacheValid())
             return !cachedLength();
-        if (isItemCacheValid())
-            return !cachedItem();
+        if (isElementCacheValid())
+            return !cachedElement();
         return !item(0);
     }
     bool hasExactlyOneItem() const
     {
         if (isLengthCacheValid())
             return cachedLength() == 1;
-        if (isItemCacheValid())
-            return cachedItem() && !cachedItemOffset() && !item(1);
+        if (isElementCacheValid())
+            return cachedElement() && !cachedElementOffset() && !item(1);
         return item(0) && !item(1);
     }
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to