Home | History | Annotate | Download | only in resolver
      1 /*
      2  * Copyright (C) 1999 Lars Knoll (knoll (at) kde.org)
      3  * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
      4  * Copyright (C) 2012 Google Inc. All rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1.  Redistributions of source code must retain the above copyright
     10  *     notice, this list of conditions and the following disclaimer.
     11  * 2.  Redistributions in binary form must reproduce the above copyright
     12  *     notice, this list of conditions and the following disclaimer in the
     13  *     documentation and/or other materials provided with the distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
     16  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     18  * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     19  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     20  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     21  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
     22  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     24  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     25  */
     26 
     27 #ifndef ScopedStyleResolver_h
     28 #define ScopedStyleResolver_h
     29 
     30 #include "core/css/CSSKeyframesRule.h"
     31 #include "core/css/ElementRuleCollector.h"
     32 #include "core/css/RuleSet.h"
     33 #include "core/dom/ContainerNode.h"
     34 #include "core/dom/Element.h"
     35 #include "wtf/Forward.h"
     36 #include "wtf/HashMap.h"
     37 #include "wtf/OwnPtr.h"
     38 #include "wtf/PassOwnPtr.h"
     39 #include "wtf/Vector.h"
     40 
     41 namespace WebCore {
     42 
     43 class ElementRuleCollector;
     44 class MediaQueryEvaluator;
     45 class PageRuleCollector;
     46 class ShadowRoot;
     47 class StyleSheetContents;
     48 
     49 // This class selects a RenderStyle for a given element based on a collection of stylesheets.
     50 class ScopedStyleResolver {
     51     WTF_MAKE_NONCOPYABLE(ScopedStyleResolver); WTF_MAKE_FAST_ALLOCATED;
     52 public:
     53     static PassOwnPtr<ScopedStyleResolver> create(const ContainerNode* scopingNode) { return adoptPtr(new ScopedStyleResolver(scopingNode)); }
     54 
     55     static const ContainerNode* scopingNodeFor(const CSSStyleSheet*);
     56 
     57     const ContainerNode* scopingNode() const { return m_scopingNode; }
     58     const TreeScope* treeScope() const { return m_scopingNode->treeScope(); }
     59     void prepareEmptyRuleSet() { m_authorStyle = RuleSet::create(); }
     60     void setParent(ScopedStyleResolver* newParent) { m_parent = newParent; }
     61     ScopedStyleResolver* parent() { return m_parent; }
     62 
     63     bool hasOnlyEmptyRuleSets() const { return !m_authorStyle->ruleCount() && m_atHostRules.isEmpty(); }
     64 
     65 public:
     66     bool checkRegionStyle(Element*);
     67     const StyleRuleKeyframes* keyframeStylesForAnimation(const StringImpl* animationName);
     68     void addKeyframeStyle(PassRefPtr<StyleRuleKeyframes>);
     69 
     70     void matchHostRules(ElementRuleCollector&, bool includeEmptyRules);
     71     void matchAuthorRules(ElementRuleCollector&, bool includeEmptyRules, bool applyAuthorStyles);
     72     void collectMatchingAuthorRules(ElementRuleCollector&, bool includeEmptyRules, bool applyAuthorStyles, CascadeScope, CascadeOrder = ignoreCascadeOrder);
     73     void matchPageRules(PageRuleCollector&);
     74     void addRulesFromSheet(StyleSheetContents*, const MediaQueryEvaluator&, StyleResolver*);
     75     void addHostRule(StyleRuleHost*, bool hasDocumentSecurityOrigin, const ContainerNode* scopingNode);
     76     void collectFeaturesTo(RuleFeatureSet&);
     77     void resetAuthorStyle();
     78     void resetAtHostRules(const ShadowRoot*);
     79     void collectViewportRulesTo(StyleResolver*) const;
     80 
     81 private:
     82     ScopedStyleResolver() : m_scopingNode(0), m_parent(0) { }
     83     ScopedStyleResolver(const ContainerNode* scopingNode) : m_scopingNode(scopingNode), m_parent(0) { }
     84 
     85     RuleSet* ensureAtHostRuleSetFor(const ShadowRoot*);
     86     RuleSet* atHostRuleSetFor(const ShadowRoot*) const;
     87 
     88     const ContainerNode* m_scopingNode;
     89     ScopedStyleResolver* m_parent;
     90 
     91     OwnPtr<RuleSet> m_authorStyle;
     92     HashMap<const ShadowRoot*, OwnPtr<RuleSet> > m_atHostRules;
     93 
     94     typedef HashMap<const StringImpl*, RefPtr<StyleRuleKeyframes> > KeyframesRuleMap;
     95     KeyframesRuleMap m_keyframesRuleMap;
     96 };
     97 
     98 class ScopedStyleTree {
     99     WTF_MAKE_NONCOPYABLE(ScopedStyleTree); WTF_MAKE_FAST_ALLOCATED;
    100 public:
    101     ScopedStyleTree() : m_scopedResolverForDocument(0), m_buildInDocumentOrder(true) { }
    102 
    103     ScopedStyleResolver* ensureScopedStyleResolver(const ContainerNode* scopingNode);
    104     ScopedStyleResolver* scopedStyleResolverFor(const ContainerNode* scopingNode);
    105     ScopedStyleResolver* addScopedStyleResolver(const ContainerNode* scopingNode, bool& isNewEntry);
    106     void clear();
    107 
    108     // for fast-path.
    109     bool hasOnlyScopedResolverForDocument() const { return m_scopedResolverForDocument && m_authorStyles.size() == 1; }
    110     ScopedStyleResolver* scopedStyleResolverForDocument() { return m_scopedResolverForDocument; }
    111 
    112     void resolveScopedStyles(const Element*, Vector<ScopedStyleResolver*, 8>&);
    113     void collectScopedResolversForHostedShadowTrees(const Element*, Vector<ScopedStyleResolver*, 8>&);
    114     void resolveScopedKeyframesRules(const Element*, Vector<ScopedStyleResolver*, 8>&);
    115     ScopedStyleResolver* scopedResolverFor(const Element*);
    116 
    117     void remove(const ContainerNode* scopingNode);
    118 
    119     void pushStyleCache(const ContainerNode* scopingNode, const ContainerNode* parent);
    120     void popStyleCache(const ContainerNode* scopingNode);
    121 
    122     void collectFeaturesTo(RuleFeatureSet& features);
    123     void setBuildInDocumentOrder(bool enabled) { m_buildInDocumentOrder = enabled; }
    124     bool buildInDocumentOrder() const { return m_buildInDocumentOrder; }
    125 
    126 private:
    127     void setupScopedStylesTree(ScopedStyleResolver* target);
    128 
    129     bool cacheIsValid(const ContainerNode* parent) const { return parent && parent == m_cache.nodeForScopedStyles; }
    130     void resolveStyleCache(const ContainerNode* scopingNode);
    131     ScopedStyleResolver* enclosingScopedStyleResolverFor(const ContainerNode* scopingNode);
    132 
    133     void reparentNodes(const ScopedStyleResolver* oldParent, ScopedStyleResolver* newParent);
    134 
    135 private:
    136     HashMap<const ContainerNode*, OwnPtr<ScopedStyleResolver> > m_authorStyles;
    137     ScopedStyleResolver* m_scopedResolverForDocument;
    138     bool m_buildInDocumentOrder;
    139 
    140     struct ScopedStyleCache {
    141         ScopedStyleResolver* scopedResolver;
    142         const ContainerNode* nodeForScopedStyles;
    143 
    144         void clear()
    145         {
    146             scopedResolver = 0;
    147             nodeForScopedStyles = 0;
    148         }
    149     };
    150     ScopedStyleCache m_cache;
    151 };
    152 
    153 inline ScopedStyleResolver* ScopedStyleTree::scopedResolverFor(const Element* element)
    154 {
    155     if (!cacheIsValid(element))
    156         resolveStyleCache(element);
    157 
    158     return m_cache.scopedResolver;
    159 }
    160 
    161 } // namespace WebCore
    162 
    163 #endif // ScopedStyleResolver_h
    164