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