1/* 2 * Copyright (C) 1999 Lars Knoll (knoll@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 StyleScopeResolver_h 28#define StyleScopeResolver_h 29 30#include <wtf/Assertions.h> 31#include <wtf/Forward.h> 32#include <wtf/HashMap.h> 33#include <wtf/OwnPtr.h> 34#include <wtf/Vector.h> 35 36namespace WebCore { 37 38class ContainerNode; 39class CSSStyleSheet; 40class Element; 41class RuleSet; 42class ShadowRoot; 43class StyleRuleHost; 44struct RuleFeatureSet; 45 46#if ENABLE(STYLE_SCOPED) || ENABLE(SHADOW_DOM) 47 48class StyleScopeResolver { 49public: 50 typedef HashMap<const ContainerNode*, OwnPtr<RuleSet> > ScopedRuleSetMap; 51 52 struct StackFrame { 53 StackFrame() : m_scope(0), m_authorStyleBoundsIndex(0), m_ruleSet(0) { } 54 StackFrame(const ContainerNode* scope, int authorStyleBoundsIndex, RuleSet* ruleSet) 55 : m_scope(scope), m_authorStyleBoundsIndex(authorStyleBoundsIndex), m_ruleSet(ruleSet) 56 { } 57 58 const ContainerNode* m_scope; 59 int m_authorStyleBoundsIndex; 60 RuleSet* m_ruleSet; 61 }; 62 63 StyleScopeResolver(); 64 ~StyleScopeResolver(); 65 66 static const ContainerNode* scopeFor(const CSSStyleSheet*); 67 68 void push(const ContainerNode* scope, const ContainerNode* scopeParent); 69 void pop(const ContainerNode* scope); 70 bool hasScopedStyles() const { return !m_authorStyles.isEmpty(); } 71 RuleSet* ensureRuleSetFor(const ContainerNode* scope); 72 bool ensureStackConsistency(ContainerNode*); 73 unsigned stackSize() const { return m_stack.size(); } 74 const StackFrame& stackFrameAt(unsigned index) const { return m_stack.at(index); } 75 bool matchesStyleBounds(const StackFrame& frame) const { return frame.m_authorStyleBoundsIndex == m_stackParentBoundsIndex; } 76 void collectFeaturesTo(RuleFeatureSet&); 77 78 void addHostRule(StyleRuleHost*, bool hasDocumentSecurityOrigin, const ContainerNode* scope); 79 bool styleSharingCandidateMatchesHostRules(const Element*); 80 void matchHostRules(const Element*, Vector<RuleSet*>& matchedRules); 81 82private: 83 RuleSet* ruleSetFor(const ContainerNode* scope) const; 84 void setupStack(const ContainerNode*); 85 bool stackIsConsistent(const ContainerNode* parent) const { return parent && parent == m_stackParent; } 86 RuleSet* ensureAtHostRuleSetFor(const ShadowRoot*); 87 RuleSet* atHostRuleSetFor(const ShadowRoot*) const; 88 89 ScopedRuleSetMap m_authorStyles; 90 91 // Vector (used as stack) that keeps track of scoping elements (i.e., elements with a <style scoped> child) 92 // encountered during tree iteration for style resolution. 93 Vector<StackFrame> m_stack; 94 // Element last seen as parent element when updating m_scopingElementStack. 95 // This is used to decide whether m_scopingElementStack is consistent, separately from SelectorChecker::m_parentStack. 96 const ContainerNode* m_stackParent; 97 int m_stackParentBoundsIndex; 98 99 ScopedRuleSetMap m_atHostRules; 100}; 101 102inline bool StyleScopeResolver::ensureStackConsistency(ContainerNode* parent) 103{ 104 // Match scoped author rules by traversing the scoped element stack (rebuild it if it got inconsistent). 105 if (!stackIsConsistent(parent)) 106 setupStack(parent); 107 return !m_stack.isEmpty(); 108} 109 110#else 111 112class StyleScopeResolver { 113public: 114 static const ContainerNode* scopeFor(const CSSStyleSheet*) { return 0; } 115 void push(const ContainerNode*, const ContainerNode*) { } 116 void pop(const ContainerNode*) { } 117 void collectFeaturesTo(RuleFeatureSet&) { } 118 RuleSet* ensureRuleSetFor(const ContainerNode*) { return 0; } 119}; 120 121#endif // ENABLE(STYLE_SCOPED) 122 123} // namespace WebCore 124 125#endif // StyleScopeResolver_h 126