Home | History | Annotate | Download | only in resolver
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef StyleResolverParentScope_h
      6 #define StyleResolverParentScope_h
      7 
      8 #include "core/css/resolver/StyleResolver.h"
      9 #include "core/dom/Document.h"
     10 #include "core/dom/Element.h"
     11 #include "core/dom/shadow/ShadowRoot.h"
     12 
     13 namespace blink {
     14 
     15 // Maintains the parent element stack (and bloom filter) inside recalcStyle.
     16 class StyleResolverParentScope FINAL {
     17     STACK_ALLOCATED();
     18 public:
     19     explicit StyleResolverParentScope(Node& parent);
     20     ~StyleResolverParentScope();
     21 
     22     static void ensureParentStackIsPushed();
     23 
     24 private:
     25     void pushParentIfNeeded();
     26     Node& parent() const { return *m_parent; }
     27 
     28     RawPtrWillBeMember<Node> m_parent;
     29     bool m_pushed;
     30     StyleResolverParentScope* m_previous;
     31     StyleResolver& m_resolver;
     32 
     33     static StyleResolverParentScope* s_currentScope;
     34 };
     35 
     36 inline StyleResolverParentScope::StyleResolverParentScope(Node& parent)
     37     : m_parent(parent)
     38     , m_pushed(false)
     39     , m_previous(s_currentScope)
     40     , m_resolver(*parent.document().styleResolver())
     41 {
     42     ASSERT(parent.document().inStyleRecalc());
     43     ASSERT(parent.isElementNode() || parent.isShadowRoot());
     44     s_currentScope = this;
     45     m_resolver.increaseStyleSharingDepth();
     46 }
     47 
     48 inline StyleResolverParentScope::~StyleResolverParentScope()
     49 {
     50     s_currentScope = m_previous;
     51     m_resolver.decreaseStyleSharingDepth();
     52     if (!m_pushed)
     53         return;
     54     if (parent().isElementNode())
     55         m_resolver.popParentElement(toElement(parent()));
     56 }
     57 
     58 inline void StyleResolverParentScope::ensureParentStackIsPushed()
     59 {
     60     if (s_currentScope)
     61         s_currentScope->pushParentIfNeeded();
     62 }
     63 
     64 inline void StyleResolverParentScope::pushParentIfNeeded()
     65 {
     66     if (m_pushed)
     67         return;
     68     if (m_previous)
     69         m_previous->pushParentIfNeeded();
     70     if (parent().isElementNode())
     71         m_resolver.pushParentElement(toElement(parent()));
     72     m_pushed = true;
     73 }
     74 
     75 } // namespace blink
     76 
     77 #endif // StyleResolverParentScope_h
     78