Chromium Code Reviews| Index: Source/core/dom/LiveNodeListBase.h |
| diff --git a/Source/core/dom/LiveNodeListBase.h b/Source/core/dom/LiveNodeListBase.h |
| index 098d8ddfcce190a3990ec3465e337ff0c38c3ca4..d87d19b25e89ebb2244f219e20b1addd67b1bbb3 100644 |
| --- a/Source/core/dom/LiveNodeListBase.h |
| +++ b/Source/core/dom/LiveNodeListBase.h |
| @@ -27,6 +27,8 @@ |
| #include "HTMLNames.h" |
| #include "core/dom/Document.h" |
| +#include "core/dom/Element.h" |
| +#include "core/dom/NodeTraversal.h" |
| #include "core/html/CollectionType.h" |
| namespace WebCore { |
| @@ -84,12 +86,15 @@ protected: |
| ALWAYS_INLINE NodeListRootType rootType() const { return static_cast<NodeListRootType>(m_rootType); } |
| template <typename Collection> |
| - static Element* iterateForPreviousNode(const Collection&, Node* current); |
| - template <typename Collection> |
| static Element* itemBefore(const Collection&, const Element* previousItem); |
| private: |
| void invalidateIdNameCacheMaps() const; |
| + template <typename Collection> |
| + static Element* iterateForPreviousNode(const Collection&, Node* current); |
| + static Node* previousNode(const ContainerNode&, const Node& previous, bool onlyIncludeDirectChildren); |
| + static Node* lastDescendant(const ContainerNode&); |
| + static Node* lastNode(const ContainerNode&, bool onlyIncludeDirectChildren); |
| RefPtr<ContainerNode> m_ownerNode; // Cannot be null. |
| const unsigned m_rootType : 2; |
| @@ -121,6 +126,48 @@ ALWAYS_INLINE bool LiveNodeListBase::shouldInvalidateTypeOnAttributeChange(NodeL |
| return false; |
| } |
| +inline Node* LiveNodeListBase::previousNode(const ContainerNode& base, const Node& previous, bool onlyIncludeDirectChildren) |
| +{ |
| + return onlyIncludeDirectChildren ? previous.previousSibling() : NodeTraversal::previous(previous, &base); |
| +} |
| + |
| +inline Node* LiveNodeListBase::lastDescendant(const ContainerNode& node) |
| +{ |
| + Node* descendant = node.lastChild(); |
| + for (Node* current = descendant; current; current = current->lastChild()) |
| + descendant = current; |
| + return descendant; |
| +} |
| + |
| +inline Node* LiveNodeListBase::lastNode(const ContainerNode& rootNode, bool onlyIncludeDirectChildren) |
| +{ |
| + return onlyIncludeDirectChildren ? rootNode.lastChild() : lastDescendant(rootNode); |
| +} |
| + |
| +template <typename Collection> |
| +inline Element* LiveNodeListBase::iterateForPreviousNode(const Collection& collection, Node* current) |
|
adamk
2014/02/25 22:05:40
I take it you're hoping the ALWAYS_INLINE wasn't n
Inactive
2014/02/25 22:32:45
I dropped the inline as it shouldn't be needed for
|
| +{ |
| + bool onlyIncludeDirectChildren = collection.shouldOnlyIncludeDirectChildren(); |
| + ContainerNode& rootNode = collection.rootNode(); |
| + for (; current; current = previousNode(rootNode, *current, onlyIncludeDirectChildren)) { |
| + if (current->isElementNode() && isMatchingElement(collection, toElement(*current))) |
| + return toElement(current); |
| + } |
| + return 0; |
| +} |
| + |
| +template <typename Collection> |
| +Element* LiveNodeListBase::itemBefore(const Collection& collection, const Element* previous) |
| +{ |
| + Node* current; |
| + if (LIKELY(!!previous)) // Without this LIKELY, length() and item() can be 10% slower. |
| + current = previousNode(collection.rootNode(), *previous, collection.shouldOnlyIncludeDirectChildren()); |
| + else |
| + current = lastNode(collection.rootNode(), collection.shouldOnlyIncludeDirectChildren()); |
| + |
| + return iterateForPreviousNode(collection, current); |
| +} |
| + |
| } // namespace WebCore |
| #endif // LiveNodeListBase_h |