1 /* 2 * (C) 1999-2003 Lars Knoll (knoll (at) kde.org) 3 * (C) 2002-2003 Dirk Mueller (mueller (at) kde.org) 4 * Copyright (C) 2002, 2005, 2006, 2008, 2012 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 #include "config.h" 23 #include "core/css/StyleRule.h" 24 25 #include "core/css/CSSFilterRule.h" 26 #include "core/css/CSSFontFaceRule.h" 27 #include "core/css/CSSImportRule.h" 28 #include "core/css/CSSKeyframesRule.h" 29 #include "core/css/CSSMediaRule.h" 30 #include "core/css/CSSPageRule.h" 31 #include "core/css/CSSStyleRule.h" 32 #include "core/css/CSSSupportsRule.h" 33 #include "core/css/CSSViewportRule.h" 34 #include "core/css/StylePropertySet.h" 35 #include "core/css/StyleRuleImport.h" 36 37 namespace WebCore { 38 39 struct SameSizeAsStyleRuleBase : public RefCountedWillBeRefCountedGarbageCollected<SameSizeAsStyleRuleBase> { 40 unsigned bitfields; 41 }; 42 43 COMPILE_ASSERT(sizeof(StyleRuleBase) <= sizeof(SameSizeAsStyleRuleBase), StyleRuleBase_should_stay_small); 44 45 PassRefPtrWillBeRawPtr<CSSRule> StyleRuleBase::createCSSOMWrapper(CSSStyleSheet* parentSheet) const 46 { 47 return createCSSOMWrapper(parentSheet, 0); 48 } 49 50 PassRefPtrWillBeRawPtr<CSSRule> StyleRuleBase::createCSSOMWrapper(CSSRule* parentRule) const 51 { 52 return createCSSOMWrapper(0, parentRule); 53 } 54 55 void StyleRuleBase::trace(Visitor* visitor) 56 { 57 switch (type()) { 58 case Style: 59 toStyleRule(this)->traceAfterDispatch(visitor); 60 return; 61 case Page: 62 toStyleRulePage(this)->traceAfterDispatch(visitor); 63 return; 64 case FontFace: 65 toStyleRuleFontFace(this)->traceAfterDispatch(visitor); 66 return; 67 case Media: 68 toStyleRuleMedia(this)->traceAfterDispatch(visitor); 69 return; 70 case Supports: 71 toStyleRuleSupports(this)->traceAfterDispatch(visitor); 72 return; 73 case Import: 74 toStyleRuleImport(this)->traceAfterDispatch(visitor); 75 return; 76 case Keyframes: 77 toStyleRuleKeyframes(this)->traceAfterDispatch(visitor); 78 return; 79 case Viewport: 80 toStyleRuleViewport(this)->traceAfterDispatch(visitor); 81 return; 82 case Filter: 83 toStyleRuleFilter(this)->traceAfterDispatch(visitor); 84 return; 85 case Unknown: 86 case Charset: 87 case Keyframe: 88 ASSERT_NOT_REACHED(); 89 return; 90 } 91 ASSERT_NOT_REACHED(); 92 } 93 94 void StyleRuleBase::finalizeGarbageCollectedObject() 95 { 96 switch (type()) { 97 case Style: 98 toStyleRule(this)->~StyleRule(); 99 return; 100 case Page: 101 toStyleRulePage(this)->~StyleRulePage(); 102 return; 103 case FontFace: 104 toStyleRuleFontFace(this)->~StyleRuleFontFace(); 105 return; 106 case Media: 107 toStyleRuleMedia(this)->~StyleRuleMedia(); 108 return; 109 case Supports: 110 toStyleRuleSupports(this)->~StyleRuleSupports(); 111 return; 112 case Import: 113 toStyleRuleImport(this)->~StyleRuleImport(); 114 return; 115 case Keyframes: 116 toStyleRuleKeyframes(this)->~StyleRuleKeyframes(); 117 return; 118 case Viewport: 119 toStyleRuleViewport(this)->~StyleRuleViewport(); 120 return; 121 case Filter: 122 toStyleRuleFilter(this)->~StyleRuleFilter(); 123 return; 124 case Unknown: 125 case Charset: 126 case Keyframe: 127 ASSERT_NOT_REACHED(); 128 return; 129 } 130 ASSERT_NOT_REACHED(); 131 } 132 133 void StyleRuleBase::destroy() 134 { 135 switch (type()) { 136 case Style: 137 delete toStyleRule(this); 138 return; 139 case Page: 140 delete toStyleRulePage(this); 141 return; 142 case FontFace: 143 delete toStyleRuleFontFace(this); 144 return; 145 case Media: 146 delete toStyleRuleMedia(this); 147 return; 148 case Supports: 149 delete toStyleRuleSupports(this); 150 return; 151 case Import: 152 delete toStyleRuleImport(this); 153 return; 154 case Keyframes: 155 delete toStyleRuleKeyframes(this); 156 return; 157 case Viewport: 158 delete toStyleRuleViewport(this); 159 return; 160 case Filter: 161 delete toStyleRuleFilter(this); 162 return; 163 case Unknown: 164 case Charset: 165 case Keyframe: 166 ASSERT_NOT_REACHED(); 167 return; 168 } 169 ASSERT_NOT_REACHED(); 170 } 171 172 PassRefPtrWillBeRawPtr<StyleRuleBase> StyleRuleBase::copy() const 173 { 174 switch (type()) { 175 case Style: 176 return toStyleRule(this)->copy(); 177 case Page: 178 return toStyleRulePage(this)->copy(); 179 case FontFace: 180 return toStyleRuleFontFace(this)->copy(); 181 case Media: 182 return toStyleRuleMedia(this)->copy(); 183 case Supports: 184 return toStyleRuleSupports(this)->copy(); 185 case Import: 186 // FIXME: Copy import rules. 187 ASSERT_NOT_REACHED(); 188 return nullptr; 189 case Keyframes: 190 return toStyleRuleKeyframes(this)->copy(); 191 case Viewport: 192 return toStyleRuleViewport(this)->copy(); 193 case Filter: 194 return toStyleRuleFilter(this)->copy(); 195 case Unknown: 196 case Charset: 197 case Keyframe: 198 ASSERT_NOT_REACHED(); 199 return nullptr; 200 } 201 ASSERT_NOT_REACHED(); 202 return nullptr; 203 } 204 205 PassRefPtrWillBeRawPtr<CSSRule> StyleRuleBase::createCSSOMWrapper(CSSStyleSheet* parentSheet, CSSRule* parentRule) const 206 { 207 RefPtrWillBeRawPtr<CSSRule> rule = nullptr; 208 StyleRuleBase* self = const_cast<StyleRuleBase*>(this); 209 switch (type()) { 210 case Style: 211 rule = CSSStyleRule::create(toStyleRule(self), parentSheet); 212 break; 213 case Page: 214 rule = CSSPageRule::create(toStyleRulePage(self), parentSheet); 215 break; 216 case FontFace: 217 rule = CSSFontFaceRule::create(toStyleRuleFontFace(self), parentSheet); 218 break; 219 case Media: 220 rule = CSSMediaRule::create(toStyleRuleMedia(self), parentSheet); 221 break; 222 case Supports: 223 rule = CSSSupportsRule::create(toStyleRuleSupports(self), parentSheet); 224 break; 225 case Import: 226 rule = CSSImportRule::create(toStyleRuleImport(self), parentSheet); 227 break; 228 case Keyframes: 229 rule = CSSKeyframesRule::create(toStyleRuleKeyframes(self), parentSheet); 230 break; 231 case Viewport: 232 rule = CSSViewportRule::create(toStyleRuleViewport(self), parentSheet); 233 break; 234 case Filter: 235 rule = CSSFilterRule::create(toStyleRuleFilter(self), parentSheet); 236 break; 237 case Unknown: 238 case Charset: 239 case Keyframe: 240 ASSERT_NOT_REACHED(); 241 return nullptr; 242 } 243 if (parentRule) 244 rule->setParentRule(parentRule); 245 return rule.release(); 246 } 247 248 unsigned StyleRule::averageSizeInBytes() 249 { 250 return sizeof(StyleRule) + sizeof(CSSSelector) + StylePropertySet::averageSizeInBytes(); 251 } 252 253 StyleRule::StyleRule() 254 : StyleRuleBase(Style) 255 { 256 } 257 258 StyleRule::StyleRule(const StyleRule& o) 259 : StyleRuleBase(o) 260 , m_properties(o.m_properties->mutableCopy()) 261 , m_selectorList(o.m_selectorList) 262 { 263 } 264 265 StyleRule::~StyleRule() 266 { 267 } 268 269 MutableStylePropertySet& StyleRule::mutableProperties() 270 { 271 if (!m_properties->isMutable()) 272 m_properties = m_properties->mutableCopy(); 273 return *toMutableStylePropertySet(m_properties); 274 } 275 276 void StyleRule::setProperties(PassRefPtr<StylePropertySet> properties) 277 { 278 m_properties = properties; 279 } 280 281 StyleRulePage::StyleRulePage() 282 : StyleRuleBase(Page) 283 { 284 } 285 286 StyleRulePage::StyleRulePage(const StyleRulePage& o) 287 : StyleRuleBase(o) 288 , m_properties(o.m_properties->mutableCopy()) 289 , m_selectorList(o.m_selectorList) 290 { 291 } 292 293 StyleRulePage::~StyleRulePage() 294 { 295 } 296 297 MutableStylePropertySet& StyleRulePage::mutableProperties() 298 { 299 if (!m_properties->isMutable()) 300 m_properties = m_properties->mutableCopy(); 301 return *toMutableStylePropertySet(m_properties); 302 } 303 304 void StyleRulePage::setProperties(PassRefPtr<StylePropertySet> properties) 305 { 306 m_properties = properties; 307 } 308 309 StyleRuleFontFace::StyleRuleFontFace() 310 : StyleRuleBase(FontFace) 311 { 312 } 313 314 StyleRuleFontFace::StyleRuleFontFace(const StyleRuleFontFace& o) 315 : StyleRuleBase(o) 316 , m_properties(o.m_properties->mutableCopy()) 317 { 318 } 319 320 StyleRuleFontFace::~StyleRuleFontFace() 321 { 322 } 323 324 MutableStylePropertySet& StyleRuleFontFace::mutableProperties() 325 { 326 if (!m_properties->isMutable()) 327 m_properties = m_properties->mutableCopy(); 328 return *toMutableStylePropertySet(m_properties); 329 } 330 331 void StyleRuleFontFace::setProperties(PassRefPtr<StylePropertySet> properties) 332 { 333 m_properties = properties; 334 } 335 336 StyleRuleGroup::StyleRuleGroup(Type type, WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >& adoptRule) 337 : StyleRuleBase(type) 338 { 339 m_childRules.swap(adoptRule); 340 } 341 342 StyleRuleGroup::StyleRuleGroup(const StyleRuleGroup& o) 343 : StyleRuleBase(o) 344 , m_childRules(o.m_childRules.size()) 345 { 346 for (unsigned i = 0; i < m_childRules.size(); ++i) 347 m_childRules[i] = o.m_childRules[i]->copy(); 348 } 349 350 void StyleRuleGroup::wrapperInsertRule(unsigned index, PassRefPtrWillBeRawPtr<StyleRuleBase> rule) 351 { 352 m_childRules.insert(index, rule); 353 } 354 355 void StyleRuleGroup::wrapperRemoveRule(unsigned index) 356 { 357 m_childRules.remove(index); 358 } 359 360 void StyleRuleGroup::traceAfterDispatch(Visitor* visitor) 361 { 362 visitor->trace(m_childRules); 363 StyleRuleBase::traceAfterDispatch(visitor); 364 } 365 366 StyleRuleMedia::StyleRuleMedia(PassRefPtrWillBeRawPtr<MediaQuerySet> media, WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >& adoptRules) 367 : StyleRuleGroup(Media, adoptRules) 368 , m_mediaQueries(media) 369 { 370 } 371 372 StyleRuleMedia::StyleRuleMedia(const StyleRuleMedia& o) 373 : StyleRuleGroup(o) 374 { 375 if (o.m_mediaQueries) 376 m_mediaQueries = o.m_mediaQueries->copy(); 377 } 378 379 void StyleRuleMedia::traceAfterDispatch(Visitor* visitor) 380 { 381 visitor->trace(m_mediaQueries); 382 StyleRuleGroup::traceAfterDispatch(visitor); 383 } 384 385 StyleRuleSupports::StyleRuleSupports(const String& conditionText, bool conditionIsSupported, WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >& adoptRules) 386 : StyleRuleGroup(Supports, adoptRules) 387 , m_conditionText(conditionText) 388 , m_conditionIsSupported(conditionIsSupported) 389 { 390 } 391 392 StyleRuleSupports::StyleRuleSupports(const StyleRuleSupports& o) 393 : StyleRuleGroup(o) 394 , m_conditionText(o.m_conditionText) 395 , m_conditionIsSupported(o.m_conditionIsSupported) 396 { 397 } 398 399 StyleRuleViewport::StyleRuleViewport() 400 : StyleRuleBase(Viewport) 401 { 402 } 403 404 StyleRuleViewport::StyleRuleViewport(const StyleRuleViewport& o) 405 : StyleRuleBase(o) 406 , m_properties(o.m_properties->mutableCopy()) 407 { 408 } 409 410 StyleRuleViewport::~StyleRuleViewport() 411 { 412 } 413 414 MutableStylePropertySet& StyleRuleViewport::mutableProperties() 415 { 416 if (!m_properties->isMutable()) 417 m_properties = m_properties->mutableCopy(); 418 return *toMutableStylePropertySet(m_properties); 419 } 420 421 void StyleRuleViewport::setProperties(PassRefPtr<StylePropertySet> properties) 422 { 423 m_properties = properties; 424 } 425 426 StyleRuleFilter::StyleRuleFilter(const String& filterName) 427 : StyleRuleBase(Filter) 428 , m_filterName(filterName) 429 { 430 } 431 432 StyleRuleFilter::StyleRuleFilter(const StyleRuleFilter& o) 433 : StyleRuleBase(o) 434 , m_filterName(o.m_filterName) 435 , m_properties(o.m_properties->mutableCopy()) 436 { 437 } 438 439 StyleRuleFilter::~StyleRuleFilter() 440 { 441 } 442 443 MutableStylePropertySet& StyleRuleFilter::mutableProperties() 444 { 445 if (!m_properties->isMutable()) 446 m_properties = m_properties->mutableCopy(); 447 return *toMutableStylePropertySet(m_properties); 448 } 449 450 void StyleRuleFilter::setProperties(PassRefPtr<StylePropertySet> properties) 451 { 452 m_properties = properties; 453 } 454 455 } // namespace WebCore 456