| Index: Source/core/dom/TreeScope.h
|
| diff --git a/Source/core/dom/TreeScope.h b/Source/core/dom/TreeScope.h
|
| index 1bfcdf91861bd05cc0b548b98cc7eebc3ba2422e..72877b63df1f15fcf59b5938dc834a14904f8ce9 100644
|
| --- a/Source/core/dom/TreeScope.h
|
| +++ b/Source/core/dom/TreeScope.h
|
| @@ -43,8 +43,9 @@ class HTMLMapElement;
|
| class HitTestResult;
|
| class HitTestRequest;
|
| class IdTargetObserverRegistry;
|
| -class ScopedStyleResolver;
|
| class Node;
|
| +class ScopedStyleResolver;
|
| +class TreeScopeStyleSheetCollection;
|
|
|
| // A class which inherits both Node and TreeScope must call clearRareData() in its destructor
|
| // so that the Node destructor no longer does problematic NodeList cache manipulation in
|
| @@ -141,6 +142,96 @@ public:
|
| ScopedStyleResolver& ensureScopedStyleResolver();
|
| void clearScopedStyleResolver();
|
|
|
| + TreeScopeStyleSheetCollection* styleSheetCollection();
|
| +
|
| + typedef WillBeHeapHashSet<RawPtrWillBeMember<TreeScope>> UnorderedTreeScopeSet;
|
| +
|
| + // A class which holds document-ordered treescopes which have stylesheets.
|
| + // ListHashSet allows only sequential access, not random access.
|
| + // So it gets slow when the size of treescopes gets larger when finding
|
| + // the best place to insert a treescope into the document-ordered
|
| + // treescopes (requires linear search).
|
| + // To solve this, use a vector for the document-ordered treescopes and
|
| + // use a hashset for quickly checking whether a given treescope is
|
| + // in the document-ordered treescopes or not.
|
| + class OrderedTreeScopeSet final {
|
| + DISALLOW_ALLOCATION();
|
| + WTF_MAKE_NONCOPYABLE(OrderedTreeScopeSet);
|
| + public:
|
| + OrderedTreeScopeSet() { }
|
| +
|
| + bool insert(TreeScope*);
|
| + bool remove(TreeScope*);
|
| +
|
| + // When we don't need to consider document-order, use this iterator.
|
| + // Otherwise, use [] operator.
|
| + UnorderedTreeScopeSet& unordered() { return m_hash; }
|
| +
|
| + bool isEmpty() const { return m_treeScopes.isEmpty(); }
|
| + void clear()
|
| + {
|
| + m_treeScopes.clear();
|
| + m_hash.clear();
|
| + }
|
| +
|
| + size_t size() const { return m_treeScopes.size(); }
|
| +
|
| + TreeScope* operator[](size_t i) { return m_treeScopes[i]; }
|
| + const TreeScope* operator[](size_t i) const { return m_treeScopes[i]; }
|
| +
|
| + typedef WillBeHeapVector<RawPtrWillBeMember<TreeScope>, 16>::iterator iterator;
|
| + iterator begin() { return m_treeScopes.begin(); }
|
| + iterator end() { return m_treeScopes.end(); }
|
| +
|
| + DECLARE_TRACE();
|
| +
|
| + private:
|
| + WillBeHeapVector<RawPtrWillBeMember<TreeScope>, 16> m_treeScopes;
|
| + UnorderedTreeScopeSet m_hash;
|
| + };
|
| +
|
| + class TreeScopesWithActiveStyleSheetsTraversal final {
|
| + DISALLOW_ALLOCATION();
|
| + WTF_MAKE_NONCOPYABLE(TreeScopesWithActiveStyleSheetsTraversal);
|
| + public:
|
| + TreeScopesWithActiveStyleSheetsTraversal(TreeScope&);
|
| + TreeScopesWithActiveStyleSheetsTraversal(OrderedTreeScopeSet&);
|
| +
|
| + class iterator {
|
| + public:
|
| + iterator(TreeScopesWithActiveStyleSheetsTraversal* traversal) : m_traversal(traversal) { }
|
| + iterator(const iterator& iterator) : m_traversal(iterator.m_traversal) { }
|
| +
|
| + TreeScope* operator*() { return m_traversal->m_current; }
|
| + void operator++() { m_traversal->nextWithStyleSheetCollection(); }
|
| + bool operator!=(const iterator& other) const { return m_traversal->m_current; }
|
| +
|
| + private:
|
| + TreeScopesWithActiveStyleSheetsTraversal* m_traversal;
|
| + };
|
| +
|
| + iterator begin() { return iterator(this); }
|
| + iterator end() { return iterator(nullptr); }
|
| +
|
| + DECLARE_TRACE();
|
| +
|
| + private:
|
| + void skipIfNoStyleSheetCollection();
|
| + void nextWithStyleSheetCollection();
|
| + void next();
|
| +
|
| + RawPtrWillBeMember<TreeScope> m_current;
|
| + OrderedTreeScopeSet::iterator m_iterator;
|
| + OrderedTreeScopeSet::iterator m_end;
|
| + WillBeHeapVector<std::pair<OrderedTreeScopeSet::iterator, OrderedTreeScopeSet::iterator>, 8> m_stack;
|
| + };
|
| +
|
| + bool selfOrDescendantsHaveActiveStyleSheets() const { return m_selfOrDescendantsHaveActiveStyleSheets; }
|
| + OrderedTreeScopeSet& childTreeScopesWithActiveStyleSheets() { return m_childTreeScopesWithActiveStyleSheets; }
|
| + bool hasChildTreeScopesWithActiveStyleSheets() const { return !m_childTreeScopesWithActiveStyleSheets.isEmpty(); }
|
| + void setSelfOrDescendantsHaveActiveStyleSheets();
|
| + void clearSelfOrDescendantsHaveActiveStyleSheets();
|
| +
|
| protected:
|
| TreeScope(ContainerNode&, Document&);
|
| TreeScope(Document&);
|
| @@ -191,8 +282,11 @@ private:
|
| OwnPtrWillBeMember<IdTargetObserverRegistry> m_idTargetObserverRegistry;
|
|
|
| OwnPtrWillBeMember<ScopedStyleResolver> m_scopedStyleResolver;
|
| + OrderedTreeScopeSet m_childTreeScopesWithActiveStyleSheets;
|
|
|
| mutable RefPtrWillBeMember<DOMSelection> m_selection;
|
| +
|
| + bool m_selfOrDescendantsHaveActiveStyleSheets;
|
| };
|
|
|
| inline bool TreeScope::hasElementWithId(const AtomicString& id) const
|
|
|