1/* 2 * (C) 1999-2003 Lars Knoll (knoll@kde.org) 3 * (C) 2002-2003 Dirk Mueller (mueller@kde.org) 4 * Copyright (C) 2002, 2006, 2008, 2012, 2013 Apple Inc. All rights reserved. 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Library General Public 8 * License as published by the Free Software Foundation; either 9 * version 2 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Library General Public License for more details. 15 * 16 * You should have received a copy of the GNU Library General Public License 17 * along with this library; see the file COPYING.LIB. If not, write to 18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 * Boston, MA 02110-1301, USA. 20 */ 21 22#ifndef StyleRule_h 23#define StyleRule_h 24 25#include "CSSSelectorList.h" 26#include "MediaList.h" 27#include "StyleProperties.h" 28#include <wtf/RefPtr.h> 29 30namespace WebCore { 31 32class CSSRule; 33class CSSStyleRule; 34class CSSStyleSheet; 35class MutableStyleProperties; 36class StyleProperties; 37 38class StyleRuleBase : public WTF::RefCountedBase { 39 WTF_MAKE_FAST_ALLOCATED; 40public: 41 enum Type { 42 Unknown, // Not used. 43 Style, 44 Charset, // Not used. These are internally strings owned by the style sheet. 45 Import, 46 Media, 47 FontFace, 48 Page, 49 Keyframes, 50 Keyframe, // Not used. These are internally non-rule StyleKeyframe objects. 51#if ENABLE(CSS3_CONDITIONAL_RULES) 52 Supports = 12, 53#endif 54#if ENABLE(CSS_DEVICE_ADAPTATION) 55 Viewport = 15, 56#endif 57 Region = 16, 58 }; 59 60 Type type() const { return static_cast<Type>(m_type); } 61 62 bool isCharsetRule() const { return type() == Charset; } 63 bool isFontFaceRule() const { return type() == FontFace; } 64 bool isKeyframesRule() const { return type() == Keyframes; } 65 bool isMediaRule() const { return type() == Media; } 66 bool isPageRule() const { return type() == Page; } 67 bool isStyleRule() const { return type() == Style; } 68 bool isRegionRule() const { return type() == Region; } 69#if ENABLE(CSS3_CONDITIONAL_RULES) 70 bool isSupportsRule() const { return type() == Supports; } 71#endif 72#if ENABLE(CSS_DEVICE_ADAPTATION) 73 bool isViewportRule() const { return type() == Viewport; } 74#endif 75 bool isImportRule() const { return type() == Import; } 76 77 PassRef<StyleRuleBase> copy() const; 78 79 int sourceLine() const { return m_sourceLine; } 80 81 void deref() 82 { 83 if (derefBase()) 84 destroy(); 85 } 86 87 // FIXME: There shouldn't be any need for the null parent version. 88 PassRefPtr<CSSRule> createCSSOMWrapper(CSSStyleSheet* parentSheet = 0) const; 89 PassRefPtr<CSSRule> createCSSOMWrapper(CSSRule* parentRule) const; 90 91protected: 92 StyleRuleBase(Type type, signed sourceLine = 0) : m_type(type), m_sourceLine(sourceLine) { } 93 StyleRuleBase(const StyleRuleBase& o) : WTF::RefCountedBase(), m_type(o.m_type), m_sourceLine(o.m_sourceLine) { } 94 95 ~StyleRuleBase() { } 96 97private: 98 void destroy(); 99 100 PassRefPtr<CSSRule> createCSSOMWrapper(CSSStyleSheet* parentSheet, CSSRule* parentRule) const; 101 102 unsigned m_type : 5; 103 signed m_sourceLine : 27; 104}; 105 106class StyleRule : public StyleRuleBase { 107 WTF_MAKE_FAST_ALLOCATED; 108public: 109 static PassRef<StyleRule> create(int sourceLine, PassRef<StyleProperties> properties) 110 { 111 return adoptRef(*new StyleRule(sourceLine, WTF::move(properties))); 112 } 113 114 ~StyleRule(); 115 116 const CSSSelectorList& selectorList() const { return m_selectorList; } 117 const StyleProperties& properties() const { return m_properties.get(); } 118 MutableStyleProperties& mutableProperties(); 119 120 void parserAdoptSelectorVector(Vector<std::unique_ptr<CSSParserSelector>>& selectors) { m_selectorList.adoptSelectorVector(selectors); } 121 void wrapperAdoptSelectorList(CSSSelectorList& selectors) { m_selectorList = WTF::move(selectors); } 122 void parserAdoptSelectorArray(CSSSelector* selectors) { m_selectorList.adoptSelectorArray(selectors); } 123 124 PassRef<StyleRule> copy() const { return adoptRef(*new StyleRule(*this)); } 125 126 Vector<RefPtr<StyleRule>> splitIntoMultipleRulesWithMaximumSelectorComponentCount(unsigned) const; 127 128 static unsigned averageSizeInBytes(); 129 130private: 131 StyleRule(int sourceLine, PassRef<StyleProperties>); 132 StyleRule(const StyleRule&); 133 134 static PassRef<StyleRule> create(int sourceLine, const Vector<const CSSSelector*>&, PassRef<StyleProperties>); 135 136 Ref<StyleProperties> m_properties; 137 CSSSelectorList m_selectorList; 138}; 139 140inline const StyleRule* toStyleRule(const StyleRuleBase* rule) 141{ 142 ASSERT_WITH_SECURITY_IMPLICATION(!rule || rule->isStyleRule()); 143 return static_cast<const StyleRule*>(rule); 144} 145 146class StyleRuleFontFace : public StyleRuleBase { 147public: 148 static PassRef<StyleRuleFontFace> create(PassRef<StyleProperties> properties) { return adoptRef(*new StyleRuleFontFace(WTF::move(properties))); } 149 150 ~StyleRuleFontFace(); 151 152 const StyleProperties& properties() const { return m_properties.get(); } 153 MutableStyleProperties& mutableProperties(); 154 155 PassRef<StyleRuleFontFace> copy() const { return adoptRef(*new StyleRuleFontFace(*this)); } 156 157 158private: 159 StyleRuleFontFace(PassRef<StyleProperties>); 160 StyleRuleFontFace(const StyleRuleFontFace&); 161 162 Ref<StyleProperties> m_properties; 163}; 164 165class StyleRulePage : public StyleRuleBase { 166public: 167 static PassRef<StyleRulePage> create(PassRef<StyleProperties> properties) { return adoptRef(*new StyleRulePage(WTF::move(properties))); } 168 169 ~StyleRulePage(); 170 171 const CSSSelector* selector() const { return m_selectorList.first(); } 172 const StyleProperties& properties() const { return m_properties.get(); } 173 MutableStyleProperties& mutableProperties(); 174 175 void parserAdoptSelectorVector(Vector<std::unique_ptr<CSSParserSelector>>& selectors) { m_selectorList.adoptSelectorVector(selectors); } 176 void wrapperAdoptSelectorList(CSSSelectorList& selectors) { m_selectorList = WTF::move(selectors); } 177 178 PassRef<StyleRulePage> copy() const { return adoptRef(*new StyleRulePage(*this)); } 179 180private: 181 StyleRulePage(PassRef<StyleProperties>); 182 StyleRulePage(const StyleRulePage&); 183 184 Ref<StyleProperties> m_properties; 185 CSSSelectorList m_selectorList; 186}; 187 188class StyleRuleGroup : public StyleRuleBase { 189public: 190 const Vector<RefPtr<StyleRuleBase>>& childRules() const { return m_childRules; } 191 192 void wrapperInsertRule(unsigned, PassRef<StyleRuleBase>); 193 void wrapperRemoveRule(unsigned); 194 195protected: 196 StyleRuleGroup(Type, Vector<RefPtr<StyleRuleBase>>& adoptRule); 197 StyleRuleGroup(const StyleRuleGroup&); 198 199private: 200 Vector<RefPtr<StyleRuleBase>> m_childRules; 201}; 202 203class StyleRuleMedia : public StyleRuleGroup { 204public: 205 static PassRef<StyleRuleMedia> create(PassRefPtr<MediaQuerySet> media, Vector<RefPtr<StyleRuleBase>>& adoptRules) 206 { 207 return adoptRef(*new StyleRuleMedia(media, adoptRules)); 208 } 209 210 MediaQuerySet* mediaQueries() const { return m_mediaQueries.get(); } 211 212 PassRef<StyleRuleMedia> copy() const { return adoptRef(*new StyleRuleMedia(*this)); } 213 214private: 215 StyleRuleMedia(PassRefPtr<MediaQuerySet>, Vector<RefPtr<StyleRuleBase>>& adoptRules); 216 StyleRuleMedia(const StyleRuleMedia&); 217 218 RefPtr<MediaQuerySet> m_mediaQueries; 219}; 220 221#if ENABLE(CSS3_CONDITIONAL_RULES) 222class StyleRuleSupports : public StyleRuleGroup { 223public: 224 static PassRef<StyleRuleSupports> create(const String& conditionText, bool conditionIsSupported, Vector<RefPtr<StyleRuleBase>>& adoptRules) 225 { 226 return adoptRef(*new StyleRuleSupports(conditionText, conditionIsSupported, adoptRules)); 227 } 228 229 String conditionText() const { return m_conditionText; } 230 bool conditionIsSupported() const { return m_conditionIsSupported; } 231 PassRef<StyleRuleSupports> copy() const { return adoptRef(*new StyleRuleSupports(*this)); } 232 233private: 234 StyleRuleSupports(const String& conditionText, bool conditionIsSupported, Vector<RefPtr<StyleRuleBase>>& adoptRules); 235 StyleRuleSupports(const StyleRuleSupports&); 236 237 String m_conditionText; 238 bool m_conditionIsSupported; 239}; 240#endif 241 242class StyleRuleRegion : public StyleRuleGroup { 243public: 244 static PassRef<StyleRuleRegion> create(Vector<std::unique_ptr<CSSParserSelector>>* selectors, Vector<RefPtr<StyleRuleBase>>& adoptRules) 245 { 246 return adoptRef(*new StyleRuleRegion(selectors, adoptRules)); 247 } 248 249 const CSSSelectorList& selectorList() const { return m_selectorList; } 250 251 PassRef<StyleRuleRegion> copy() const { return adoptRef(*new StyleRuleRegion(*this)); } 252 253private: 254 StyleRuleRegion(Vector<std::unique_ptr<CSSParserSelector>>*, Vector<RefPtr<StyleRuleBase>>& adoptRules); 255 StyleRuleRegion(const StyleRuleRegion&); 256 257 CSSSelectorList m_selectorList; 258}; 259 260#if ENABLE(CSS_DEVICE_ADAPTATION) 261class StyleRuleViewport : public StyleRuleBase { 262public: 263 static PassRef<StyleRuleViewport> create(PassRef<StyleProperties> properties) { return adoptRef(*new StyleRuleViewport(WTF::move(properties))); } 264 265 ~StyleRuleViewport(); 266 267 const StyleProperties& properties() const { return m_properties.get(); } 268 MutableStyleProperties& mutableProperties(); 269 270 PassRef<StyleRuleViewport> copy() const { return adoptRef(*new StyleRuleViewport(*this)); } 271 272private: 273 StyleRuleViewport(PassRef<StyleProperties>); 274 StyleRuleViewport(const StyleRuleViewport&); 275 276 Ref<StyleProperties> m_properties; 277}; 278#endif // ENABLE(CSS_DEVICE_ADAPTATION) 279 280inline const StyleRuleMedia* toStyleRuleMedia(const StyleRuleGroup* rule) 281{ 282 ASSERT_WITH_SECURITY_IMPLICATION(!rule || rule->isMediaRule()); 283 return static_cast<const StyleRuleMedia*>(rule); 284} 285 286#if ENABLE(CSS3_CONDITIONAL_RULES) 287inline const StyleRuleSupports* toStyleRuleSupports(const StyleRuleGroup* rule) 288{ 289 ASSERT_WITH_SECURITY_IMPLICATION(!rule || rule->isSupportsRule()); 290 return static_cast<const StyleRuleSupports*>(rule); 291} 292#endif 293 294inline const StyleRuleRegion* toStyleRuleRegion(const StyleRuleGroup* rule) 295{ 296 ASSERT_WITH_SECURITY_IMPLICATION(!rule || rule->isRegionRule()); 297 return static_cast<const StyleRuleRegion*>(rule); 298} 299 300} // namespace WebCore 301 302#endif // StyleRule_h 303