Chromium Code Reviews| Index: Source/core/dom/NthIndexCache.h |
| diff --git a/Source/core/dom/NthIndexCache.h b/Source/core/dom/NthIndexCache.h |
| index 94f715957f73fd388bf8c6d8ac40ea0760523251..651548a7acc8ff204b77055ecb19b8f53da3e0ea 100644 |
| --- a/Source/core/dom/NthIndexCache.h |
| +++ b/Source/core/dom/NthIndexCache.h |
| @@ -24,7 +24,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> { |
| @@ -34,9 +36,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; |
| @@ -44,12 +49,30 @@ private: |
| DECLARE_TRACE(); |
| }; |
| - NthIndexData& ensureNthIndexDataFor(Node&); |
| + class HasTagName { |
|
esprehn
2015/04/30 04:55:05
This already exists elsewhere in the code. Just us
|
| + 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; |
| + }; |
| + |
| inline unsigned nthIndex(Element&); |
| using ParentMap = WillBeHeapHashMap<RefPtrWillBeMember<Node>, OwnPtrWillBeMember<NthIndexData>>; |
| - |
| OwnPtrWillBeMember<ParentMap> m_parentMap; |
| + |
| + using ElementTagNameAndNthIndexMap = WillBeHeapHashMap<String, OwnPtrWillBeMember<NthIndexData>>; |
| + OwnPtrWillBeMember<ElementTagNameAndNthIndexMap> m_elementTagNameAndNthIndexMap; |
| + |
| + using ParentMapForType = WillBeHeapHashMap<RefPtrWillBeMember<Node>, OwnPtrWillBeMember<ElementTagNameAndNthIndexMap>>; |
| + OwnPtrWillBeMember<ParentMapForType> m_parentMapForType; |
| + |
| + |
| + NthIndexData& ensureNthIndexDataFor(Node&); |
| + NthIndexCache::ElementTagNameAndNthIndexMap& ensureElementTagNameAndNthIndexMapForType(Node&); |
| + |
| + NthIndexCache::NthIndexData& nthIndexDataWithTagName(ElementTagNameAndNthIndexMap&, Element&); |
| RawPtrWillBeMember<Document> m_document; |
| uint64_t m_domTreeVersion; |
| }; |
| @@ -68,24 +91,56 @@ inline unsigned NthIndexCache::NthIndexData::nthIndex(Element& element) |
| return index; |
| } |
| +inline unsigned NthIndexCache::NthIndexData::nthIndexOfType(Element& element, const QualifiedName& type) |
| +{ |
| + if (!m_count) |
|
esprehn
2015/04/30 04:55:05
This will need the same pseudo element fix from ru
|
| + 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) |
| { |
| unsigned index = nthIndex(element); |
| return m_count - index + 1; |
| } |
| +inline unsigned NthIndexCache::NthIndexData::nthLastIndexOfType(Element& element, const QualifiedName& type) |
| +{ |
| + 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(ensureElementTagNameAndNthIndexMapForType(*element.parentNode()), element).nthIndexOfType(element, type); |
|
esprehn
2015/04/30 04:55:05
nthIndexDataWithTagName should call ensureElementT
|
| +} |
| + |
| 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(ensureElementTagNameAndNthIndexMapForType(*element.parentNode()), element).nthLastIndexOfType(element, type); |
|
esprehn
2015/04/30 04:55:05
ditto
|
| +} |
| + |
| + |
| } // namespace blink |
| #endif // NthIndexCache_h |