Chromium Code Reviews| Index: Source/core/dom/TreeScope.h |
| diff --git a/Source/core/dom/TreeScope.h b/Source/core/dom/TreeScope.h |
| index 1bfcdf91861bd05cc0b548b98cc7eebc3ba2422e..c2dba8d1483e0d2b80fbba249a393f33e2a69a86 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(*this); } |
|
kochi
2015/05/26 01:52:34
Why begin() and end() are same?
kojii
2015/05/26 05:21:58
end() is not really used, as operator!=() can dete
|
| + |
| + 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 isInActiveStyleSheetsTraversal() const { return m_inActiveStyleSheetsTraversal; } |
| + OrderedTreeScopeSet& childTreeScopesWithActiveStyleSheets() { return m_childTreeScopesWithActiveStyleSheets; } |
| + bool hasChildTreeScopesWithActiveStyleSheets() const { return !m_childTreeScopesWithActiveStyleSheets.isEmpty(); } |
| + void insertToActiveStyleSheetsTraversal(); |
| + void removeFromActiveStyleSheetsTraversal(); |
| + |
| 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_inActiveStyleSheetsTraversal : 1; |
|
kochi
2015/05/26 01:52:34
Not necessary to be a bitfield for one boolean.
kojii
2015/05/26 05:21:58
Done.
|
| }; |
| inline bool TreeScope::hasElementWithId(const AtomicString& id) const |