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 |