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 "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
37namespace blink {
38
39struct SameSizeAsStyleRuleBase : public RefCountedWillBeGarbageCollectedFinalized<SameSizeAsStyleRuleBase> {
40    unsigned bitfields;
41};
42
43COMPILE_ASSERT(sizeof(StyleRuleBase) <= sizeof(SameSizeAsStyleRuleBase), StyleRuleBase_should_stay_small);
44
45PassRefPtrWillBeRawPtr<CSSRule> StyleRuleBase::createCSSOMWrapper(CSSStyleSheet* parentSheet) const
46{
47    return createCSSOMWrapper(parentSheet, 0);
48}
49
50PassRefPtrWillBeRawPtr<CSSRule> StyleRuleBase::createCSSOMWrapper(CSSRule* parentRule) const
51{
52    return createCSSOMWrapper(0, parentRule);
53}
54
55void 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
94void 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
133void 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
172PassRefPtrWillBeRawPtr<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
205PassRefPtrWillBeRawPtr<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
248unsigned StyleRule::averageSizeInBytes()
249{
250    return sizeof(StyleRule) + sizeof(CSSSelector) + StylePropertySet::averageSizeInBytes();
251}
252
253StyleRule::StyleRule()
254    : StyleRuleBase(Style)
255{
256}
257
258StyleRule::StyleRule(const StyleRule& o)
259    : StyleRuleBase(o)
260    , m_properties(o.m_properties->mutableCopy())
261    , m_selectorList(o.m_selectorList)
262{
263}
264
265StyleRule::~StyleRule()
266{
267}
268
269MutableStylePropertySet& StyleRule::mutableProperties()
270{
271    if (!m_properties->isMutable())
272        m_properties = m_properties->mutableCopy();
273    return *toMutableStylePropertySet(m_properties.get());
274}
275
276void StyleRule::setProperties(PassRefPtrWillBeRawPtr<StylePropertySet> properties)
277{
278    m_properties = properties;
279}
280
281void StyleRule::traceAfterDispatch(Visitor* visitor)
282{
283    visitor->trace(m_properties);
284    StyleRuleBase::traceAfterDispatch(visitor);
285}
286
287StyleRulePage::StyleRulePage()
288    : StyleRuleBase(Page)
289{
290}
291
292StyleRulePage::StyleRulePage(const StyleRulePage& o)
293    : StyleRuleBase(o)
294    , m_properties(o.m_properties->mutableCopy())
295    , m_selectorList(o.m_selectorList)
296{
297}
298
299StyleRulePage::~StyleRulePage()
300{
301}
302
303MutableStylePropertySet& StyleRulePage::mutableProperties()
304{
305    if (!m_properties->isMutable())
306        m_properties = m_properties->mutableCopy();
307    return *toMutableStylePropertySet(m_properties.get());
308}
309
310void StyleRulePage::setProperties(PassRefPtrWillBeRawPtr<StylePropertySet> properties)
311{
312    m_properties = properties;
313}
314
315void StyleRulePage::traceAfterDispatch(Visitor* visitor)
316{
317    visitor->trace(m_properties);
318    StyleRuleBase::traceAfterDispatch(visitor);
319}
320
321StyleRuleFontFace::StyleRuleFontFace()
322    : StyleRuleBase(FontFace)
323{
324}
325
326StyleRuleFontFace::StyleRuleFontFace(const StyleRuleFontFace& o)
327    : StyleRuleBase(o)
328    , m_properties(o.m_properties->mutableCopy())
329{
330}
331
332StyleRuleFontFace::~StyleRuleFontFace()
333{
334}
335
336MutableStylePropertySet& StyleRuleFontFace::mutableProperties()
337{
338    if (!m_properties->isMutable())
339        m_properties = m_properties->mutableCopy();
340    return *toMutableStylePropertySet(m_properties);
341}
342
343void StyleRuleFontFace::setProperties(PassRefPtrWillBeRawPtr<StylePropertySet> properties)
344{
345    m_properties = properties;
346}
347
348void StyleRuleFontFace::traceAfterDispatch(Visitor* visitor)
349{
350    visitor->trace(m_properties);
351    StyleRuleBase::traceAfterDispatch(visitor);
352}
353
354StyleRuleGroup::StyleRuleGroup(Type type, WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >& adoptRule)
355    : StyleRuleBase(type)
356{
357    m_childRules.swap(adoptRule);
358}
359
360StyleRuleGroup::StyleRuleGroup(const StyleRuleGroup& o)
361    : StyleRuleBase(o)
362    , m_childRules(o.m_childRules.size())
363{
364    for (unsigned i = 0; i < m_childRules.size(); ++i)
365        m_childRules[i] = o.m_childRules[i]->copy();
366}
367
368void StyleRuleGroup::wrapperInsertRule(unsigned index, PassRefPtrWillBeRawPtr<StyleRuleBase> rule)
369{
370    m_childRules.insert(index, rule);
371}
372
373void StyleRuleGroup::wrapperRemoveRule(unsigned index)
374{
375    m_childRules.remove(index);
376}
377
378void StyleRuleGroup::traceAfterDispatch(Visitor* visitor)
379{
380    visitor->trace(m_childRules);
381    StyleRuleBase::traceAfterDispatch(visitor);
382}
383
384StyleRuleMedia::StyleRuleMedia(PassRefPtrWillBeRawPtr<MediaQuerySet> media, WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >& adoptRules)
385    : StyleRuleGroup(Media, adoptRules)
386    , m_mediaQueries(media)
387{
388}
389
390StyleRuleMedia::StyleRuleMedia(const StyleRuleMedia& o)
391    : StyleRuleGroup(o)
392{
393    if (o.m_mediaQueries)
394        m_mediaQueries = o.m_mediaQueries->copy();
395}
396
397void StyleRuleMedia::traceAfterDispatch(Visitor* visitor)
398{
399    visitor->trace(m_mediaQueries);
400    StyleRuleGroup::traceAfterDispatch(visitor);
401}
402
403StyleRuleSupports::StyleRuleSupports(const String& conditionText, bool conditionIsSupported, WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >& adoptRules)
404    : StyleRuleGroup(Supports, adoptRules)
405    , m_conditionText(conditionText)
406    , m_conditionIsSupported(conditionIsSupported)
407{
408}
409
410StyleRuleSupports::StyleRuleSupports(const StyleRuleSupports& o)
411    : StyleRuleGroup(o)
412    , m_conditionText(o.m_conditionText)
413    , m_conditionIsSupported(o.m_conditionIsSupported)
414{
415}
416
417StyleRuleViewport::StyleRuleViewport()
418    : StyleRuleBase(Viewport)
419{
420}
421
422StyleRuleViewport::StyleRuleViewport(const StyleRuleViewport& o)
423    : StyleRuleBase(o)
424    , m_properties(o.m_properties->mutableCopy())
425{
426}
427
428StyleRuleViewport::~StyleRuleViewport()
429{
430}
431
432MutableStylePropertySet& StyleRuleViewport::mutableProperties()
433{
434    if (!m_properties->isMutable())
435        m_properties = m_properties->mutableCopy();
436    return *toMutableStylePropertySet(m_properties);
437}
438
439void StyleRuleViewport::setProperties(PassRefPtrWillBeRawPtr<StylePropertySet> properties)
440{
441    m_properties = properties;
442}
443
444void StyleRuleViewport::traceAfterDispatch(Visitor* visitor)
445{
446    visitor->trace(m_properties);
447    StyleRuleBase::traceAfterDispatch(visitor);
448}
449
450StyleRuleFilter::StyleRuleFilter(const String& filterName)
451    : StyleRuleBase(Filter)
452    , m_filterName(filterName)
453{
454}
455
456StyleRuleFilter::StyleRuleFilter(const StyleRuleFilter& o)
457    : StyleRuleBase(o)
458    , m_filterName(o.m_filterName)
459    , m_properties(o.m_properties->mutableCopy())
460{
461}
462
463StyleRuleFilter::~StyleRuleFilter()
464{
465}
466
467MutableStylePropertySet& StyleRuleFilter::mutableProperties()
468{
469    if (!m_properties->isMutable())
470        m_properties = m_properties->mutableCopy();
471    return *toMutableStylePropertySet(m_properties);
472}
473
474void StyleRuleFilter::setProperties(PassRefPtrWillBeRawPtr<StylePropertySet> properties)
475{
476    m_properties = properties;
477}
478
479void StyleRuleFilter::traceAfterDispatch(Visitor* visitor)
480{
481    visitor->trace(m_properties);
482    StyleRuleBase::traceAfterDispatch(visitor);
483}
484
485} // namespace blink
486