Chromium Code Reviews| Index: Source/core/dom/NthIndexCache.h |
| diff --git a/Source/core/dom/NthIndexCache.h b/Source/core/dom/NthIndexCache.h |
| index 19923a06c51693bd33ed9fa45812f0bfe8817466..bd3f99c3a14b926836b9324561e96a5bc4a1163a 100644 |
| --- a/Source/core/dom/NthIndexCache.h |
| +++ b/Source/core/dom/NthIndexCache.h |
| @@ -16,6 +16,13 @@ |
| namespace blink { |
| class Document; |
| +class HasTagName { |
| +public: |
| + explicit HasTagName(const QualifiedName& tagName) : m_tagName(tagName) { } |
| + bool operator() (const Element& element) const { return element.hasTagName(m_tagName); } |
| +private: |
| + const QualifiedName m_tagName; |
| +}; |
| class CORE_EXPORT NthIndexCache final { |
| STACK_ALLOCATED(); |
| @@ -25,7 +32,9 @@ public: |
| ~NthIndexCache(); |
| inline unsigned nthChildIndex(Element&); |
| + inline unsigned nthChildIndexOfType(Element&, const QualifiedName&); |
| inline unsigned nthLastChildIndex(Element&); |
| + inline unsigned nthLastChildIndexOfType(Element&, const QualifiedName&); |
| private: |
| class NthIndexData final : public NoBaseWillBeGarbageCollected<NthIndexData> { |
| @@ -35,9 +44,12 @@ private: |
| NthIndexData() { } |
| inline unsigned nthIndex(Element&); |
| + inline unsigned nthIndexOfType(Element&, const QualifiedName&); |
| inline unsigned nthLastIndex(Element&); |
| + inline unsigned nthLastIndexOfType(Element&, const QualifiedName&); |
| unsigned cacheNthIndices(Element&); |
| + unsigned cacheNthIndicesOfType(Element&, const QualifiedName&); |
| WillBeHeapHashMap<RawPtrWillBeMember<Element>, unsigned> m_elementIndexMap; |
| unsigned m_count = 0; |
| @@ -45,11 +57,21 @@ private: |
| DECLARE_TRACE(); |
| }; |
| + using ParentMap = WillBeHeapHashMap<RefPtrWillBeMember<Node>, OwnPtrWillBeMember<NthIndexData>>; |
| + OwnPtrWillBeMember<ParentMap> m_parentMap; |
| + |
| + using IndexByType = WillBeHeapHashMap<String, OwnPtrWillBeMember<NthIndexData>>; |
| + OwnPtrWillBeMember<IndexByType> m_IndexByType; |
|
esprehn
2015/05/07 04:16:10
m_indexByType, lower case
|
| + |
| + using ParentMapForType = WillBeHeapHashMap<RefPtrWillBeMember<Node>, OwnPtrWillBeMember<IndexByType>>; |
| + OwnPtrWillBeMember<ParentMapForType> m_parentMapForType; |
| + |
| + |
| NthIndexData& ensureNthIndexDataFor(Node&); |
| + NthIndexCache::IndexByType& ensureTypeIndexMap(Node&); |
| - using ParentMap = WillBeHeapHashMap<RefPtrWillBeMember<Node>, OwnPtrWillBeMember<NthIndexData>>; |
| + NthIndexCache::NthIndexData& nthIndexDataWithTagName(Element&); |
| - OwnPtrWillBeMember<ParentMap> m_parentMap; |
| RawPtrWillBeMember<Document> m_document; |
| uint64_t m_domTreeVersion; |
| }; |
| @@ -70,6 +92,21 @@ inline unsigned NthIndexCache::NthIndexData::nthIndex(Element& element) |
| return index; |
| } |
| +inline unsigned NthIndexCache::NthIndexData::nthIndexOfType(Element& element, const QualifiedName& type) |
| +{ |
| + if (element.isPseudoElement()) |
| + return 1; |
| + if (!m_count) |
| + return cacheNthIndicesOfType(element, type); |
| + unsigned index = 0; |
| + for (Element* sibling = &element; sibling; sibling = ElementTraversal::previousSibling(*sibling, HasTagName(type)), index++) { |
| + auto it = m_elementIndexMap.find(sibling); |
| + if (it != m_elementIndexMap.end()) |
| + return it->value + index; |
| + } |
| + return index; |
| +} |
| + |
| inline unsigned NthIndexCache::NthIndexData::nthLastIndex(Element& element) |
| { |
| if (element.isPseudoElement()) |
| @@ -78,18 +115,39 @@ inline unsigned NthIndexCache::NthIndexData::nthLastIndex(Element& element) |
| return m_count - index + 1; |
| } |
| +inline unsigned NthIndexCache::NthIndexData::nthLastIndexOfType(Element& element, const QualifiedName& type) |
| +{ |
| + if (element.isPseudoElement()) |
| + return 1; |
| + unsigned index = nthIndexOfType(element, type); |
| + return m_count - index + 1; |
| +} |
| + |
| inline unsigned NthIndexCache::nthChildIndex(Element& element) |
| { |
| ASSERT(element.parentNode()); |
| return ensureNthIndexDataFor(*element.parentNode()).nthIndex(element); |
| } |
| +inline unsigned NthIndexCache::nthChildIndexOfType(Element& element, const QualifiedName& type) |
| +{ |
| + ASSERT(element.parentNode()); |
| + return nthIndexDataWithTagName(element).nthIndexOfType(element, type); |
| +} |
| + |
| inline unsigned NthIndexCache::nthLastChildIndex(Element& element) |
| { |
| ASSERT(element.parentNode()); |
| return ensureNthIndexDataFor(*element.parentNode()).nthLastIndex(element); |
| } |
| +inline unsigned NthIndexCache::nthLastChildIndexOfType(Element& element, const QualifiedName& type) |
| +{ |
| + ASSERT(element.parentNode()); |
| + return nthIndexDataWithTagName(element).nthLastIndexOfType(element, type); |
| +} |
| + |
| + |
| } // namespace blink |
| #endif // NthIndexCache_h |