| 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;
|
| +
|
| + 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
|
|
|