Replace WTF::move with WTFMove
[WebKit-https.git] / Source / WebCore / css / StyleRule.cpp
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 "CSSImportRule.h"
28 #include "CSSKeyframeRule.h"
29 #include "CSSKeyframesRule.h"
30 #include "CSSMediaRule.h"
31 #include "CSSPageRule.h"
32 #include "CSSStyleRule.h"
33 #include "CSSSupportsRule.h"
34 #include "CSSUnknownRule.h"
35 #include "StyleProperties.h"
36 #include "StyleRuleImport.h"
37 #include "WebKitCSSRegionRule.h"
38 #include "WebKitCSSViewportRule.h"
39
40 namespace WebCore {
41
42 struct SameSizeAsStyleRuleBase : public WTF::RefCountedBase {
43     unsigned bitfields;
44 };
45
46 COMPILE_ASSERT(sizeof(StyleRuleBase) == sizeof(SameSizeAsStyleRuleBase), StyleRuleBase_should_stay_small);
47
48 PassRefPtr<CSSRule> StyleRuleBase::createCSSOMWrapper(CSSStyleSheet* parentSheet) const
49 {
50     return createCSSOMWrapper(parentSheet, 0);
51 }
52
53 PassRefPtr<CSSRule> StyleRuleBase::createCSSOMWrapper(CSSRule* parentRule) const
54
55     return createCSSOMWrapper(0, parentRule);
56 }
57
58 void StyleRuleBase::destroy()
59 {
60     switch (type()) {
61     case Style:
62         delete downcast<StyleRule>(this);
63         return;
64     case Page:
65         delete downcast<StyleRulePage>(this);
66         return;
67     case FontFace:
68         delete downcast<StyleRuleFontFace>(this);
69         return;
70     case Media:
71         delete downcast<StyleRuleMedia>(this);
72         return;
73     case Supports:
74         delete downcast<StyleRuleSupports>(this);
75         return;
76 #if ENABLE(CSS_REGIONS)
77     case Region:
78         delete downcast<StyleRuleRegion>(this);
79         return;
80 #endif
81     case Import:
82         delete downcast<StyleRuleImport>(this);
83         return;
84     case Keyframes:
85         delete downcast<StyleRuleKeyframes>(this);
86         return;
87 #if ENABLE(CSS_DEVICE_ADAPTATION)
88     case Viewport:
89         delete downcast<StyleRuleViewport>(this);
90         return;
91 #endif
92     case Unknown:
93     case Charset:
94     case Keyframe:
95 #if !ENABLE(CSS_REGIONS)
96     case Region:
97 #endif
98         ASSERT_NOT_REACHED();
99         return;
100     }
101     ASSERT_NOT_REACHED();
102 }
103
104 Ref<StyleRuleBase> StyleRuleBase::copy() const
105 {
106     switch (type()) {
107     case Style:
108         return downcast<StyleRule>(*this).copy();
109     case Page:
110         return downcast<StyleRulePage>(*this).copy();
111     case FontFace:
112         return downcast<StyleRuleFontFace>(*this).copy();
113     case Media:
114         return downcast<StyleRuleMedia>(*this).copy();
115     case Supports:
116         return downcast<StyleRuleSupports>(*this).copy();
117 #if ENABLE(CSS_REGIONS)
118     case Region:
119         return downcast<StyleRuleRegion>(*this).copy();
120 #endif
121     case Keyframes:
122         return downcast<StyleRuleKeyframes>(*this).copy();
123 #if ENABLE(CSS_DEVICE_ADAPTATION)
124     case Viewport:
125         return downcast<StyleRuleViewport>(*this).copy();
126 #endif
127     case Import:
128         // FIXME: Copy import rules.
129         break;
130     case Unknown:
131     case Charset:
132     case Keyframe:
133 #if !ENABLE(CSS_REGIONS)
134     case Region:
135 #endif
136         break;
137     }
138     CRASH();
139     // HACK: EFL won't build without this (old GCC with crappy -Werror=return-type)
140     return Ref<StyleRuleBase>(*static_cast<StyleRuleBase*>(nullptr));
141 }
142
143 PassRefPtr<CSSRule> StyleRuleBase::createCSSOMWrapper(CSSStyleSheet* parentSheet, CSSRule* parentRule) const
144 {
145     RefPtr<CSSRule> rule;
146     StyleRuleBase& self = const_cast<StyleRuleBase&>(*this);
147     switch (type()) {
148     case Style:
149         rule = CSSStyleRule::create(downcast<StyleRule>(self), parentSheet);
150         break;
151     case Page:
152         rule = CSSPageRule::create(downcast<StyleRulePage>(self), parentSheet);
153         break;
154     case FontFace:
155         rule = CSSFontFaceRule::create(downcast<StyleRuleFontFace>(self), parentSheet);
156         break;
157     case Media:
158         rule = CSSMediaRule::create(downcast<StyleRuleMedia>(self), parentSheet);
159         break;
160     case Supports:
161         rule = CSSSupportsRule::create(downcast<StyleRuleSupports>(self), parentSheet);
162         break;
163 #if ENABLE(CSS_REGIONS)
164     case Region:
165         rule = WebKitCSSRegionRule::create(downcast<StyleRuleRegion>(self), parentSheet);
166         break;
167 #endif
168     case Import:
169         rule = CSSImportRule::create(downcast<StyleRuleImport>(self), parentSheet);
170         break;
171     case Keyframes:
172         rule = CSSKeyframesRule::create(downcast<StyleRuleKeyframes>(self), parentSheet);
173         break;
174 #if ENABLE(CSS_DEVICE_ADAPTATION)
175     case Viewport:
176         rule = WebKitCSSViewportRule::create(downcast<StyleRuleViewport>(self), parentSheet);
177         break;
178 #endif
179     case Unknown:
180     case Charset:
181     case Keyframe:
182 #if !ENABLE(CSS_REGIONS)
183     case Region:
184 #endif
185         ASSERT_NOT_REACHED();
186         return nullptr;
187     }
188     if (parentRule)
189         rule->setParentRule(parentRule);
190     return rule.release();
191 }
192
193 unsigned StyleRule::averageSizeInBytes()
194 {
195     return sizeof(StyleRule) + sizeof(CSSSelector) + StyleProperties::averageSizeInBytes();
196 }
197
198 StyleRule::StyleRule(int sourceLine, Ref<StyleProperties>&& properties)
199     : StyleRuleBase(Style, sourceLine)
200     , m_properties(WTFMove(properties))
201 {
202 }
203
204 StyleRule::StyleRule(const StyleRule& o)
205     : StyleRuleBase(o)
206     , m_properties(o.m_properties->mutableCopy())
207     , m_selectorList(o.m_selectorList)
208 {
209 }
210
211 StyleRule::~StyleRule()
212 {
213 }
214
215 MutableStyleProperties& StyleRule::mutableProperties()
216 {
217     if (!is<MutableStyleProperties>(m_properties.get()))
218         m_properties = m_properties->mutableCopy();
219     return downcast<MutableStyleProperties>(m_properties.get());
220 }
221
222 Ref<StyleRule> StyleRule::create(int sourceLine, const Vector<const CSSSelector*>& selectors, Ref<StyleProperties>&& properties)
223 {
224     ASSERT_WITH_SECURITY_IMPLICATION(!selectors.isEmpty());
225     CSSSelector* selectorListArray = reinterpret_cast<CSSSelector*>(fastMalloc(sizeof(CSSSelector) * selectors.size()));
226     for (unsigned i = 0; i < selectors.size(); ++i)
227         new (NotNull, &selectorListArray[i]) CSSSelector(*selectors.at(i));
228     selectorListArray[selectors.size() - 1].setLastInSelectorList();
229     auto rule = StyleRule::create(sourceLine, WTFMove(properties));
230     rule.get().parserAdoptSelectorArray(selectorListArray);
231     return rule;
232 }
233
234 Vector<RefPtr<StyleRule>> StyleRule::splitIntoMultipleRulesWithMaximumSelectorComponentCount(unsigned maxCount) const
235 {
236     ASSERT(selectorList().componentCount() > maxCount);
237
238     Vector<RefPtr<StyleRule>> rules;
239     Vector<const CSSSelector*> componentsSinceLastSplit;
240
241     for (const CSSSelector* selector = selectorList().first(); selector; selector = CSSSelectorList::next(selector)) {
242         Vector<const CSSSelector*, 8> componentsInThisSelector;
243         for (const CSSSelector* component = selector; component; component = component->tagHistory())
244             componentsInThisSelector.append(component);
245
246         if (componentsInThisSelector.size() + componentsSinceLastSplit.size() > maxCount && !componentsSinceLastSplit.isEmpty()) {
247             rules.append(create(sourceLine(), componentsSinceLastSplit, const_cast<StyleProperties&>(m_properties.get())));
248             componentsSinceLastSplit.clear();
249         }
250
251         componentsSinceLastSplit.appendVector(componentsInThisSelector);
252     }
253
254     if (!componentsSinceLastSplit.isEmpty())
255         rules.append(create(sourceLine(), componentsSinceLastSplit, const_cast<StyleProperties&>(m_properties.get())));
256
257     return rules;
258 }
259
260 StyleRulePage::StyleRulePage(Ref<StyleProperties>&& properties)
261     : StyleRuleBase(Page)
262     , m_properties(WTFMove(properties))
263 {
264 }
265
266 StyleRulePage::StyleRulePage(const StyleRulePage& o)
267     : StyleRuleBase(o)
268     , m_properties(o.m_properties->mutableCopy())
269     , m_selectorList(o.m_selectorList)
270 {
271 }
272
273 StyleRulePage::~StyleRulePage()
274 {
275 }
276
277 MutableStyleProperties& StyleRulePage::mutableProperties()
278 {
279     if (!is<MutableStyleProperties>(m_properties.get()))
280         m_properties = m_properties->mutableCopy();
281     return downcast<MutableStyleProperties>(m_properties.get());
282 }
283
284 StyleRuleFontFace::StyleRuleFontFace(Ref<StyleProperties>&& properties)
285     : StyleRuleBase(FontFace, 0)
286     , m_properties(WTFMove(properties))
287 {
288 }
289
290 StyleRuleFontFace::StyleRuleFontFace(const StyleRuleFontFace& o)
291     : StyleRuleBase(o)
292     , m_properties(o.m_properties->mutableCopy())
293 {
294 }
295
296 StyleRuleFontFace::~StyleRuleFontFace()
297 {
298 }
299
300 MutableStyleProperties& StyleRuleFontFace::mutableProperties()
301 {
302     if (!is<MutableStyleProperties>(m_properties.get()))
303         m_properties = m_properties->mutableCopy();
304     return downcast<MutableStyleProperties>(m_properties.get());
305 }
306
307 StyleRuleGroup::StyleRuleGroup(Type type, Vector<RefPtr<StyleRuleBase>>& adoptRule)
308     : StyleRuleBase(type, 0)
309 {
310     m_childRules.swap(adoptRule);
311 }
312
313 StyleRuleGroup::StyleRuleGroup(const StyleRuleGroup& o)
314     : StyleRuleBase(o)
315 {
316     m_childRules.reserveInitialCapacity(o.m_childRules.size());
317     for (unsigned i = 0, size = o.m_childRules.size(); i < size; ++i)
318         m_childRules.uncheckedAppend(o.m_childRules[i]->copy());
319 }
320
321 void StyleRuleGroup::wrapperInsertRule(unsigned index, Ref<StyleRuleBase>&& rule)
322 {
323     m_childRules.insert(index, WTFMove(rule));
324 }
325     
326 void StyleRuleGroup::wrapperRemoveRule(unsigned index)
327 {
328     m_childRules.remove(index);
329 }
330
331
332 StyleRuleMedia::StyleRuleMedia(PassRefPtr<MediaQuerySet> media, Vector<RefPtr<StyleRuleBase>>& adoptRules)
333     : StyleRuleGroup(Media, adoptRules)
334     , m_mediaQueries(media)
335 {
336 }
337
338 StyleRuleMedia::StyleRuleMedia(const StyleRuleMedia& o)
339     : StyleRuleGroup(o)
340 {
341     if (o.m_mediaQueries)
342         m_mediaQueries = o.m_mediaQueries->copy();
343 }
344
345
346 StyleRuleSupports::StyleRuleSupports(const String& conditionText, bool conditionIsSupported, Vector<RefPtr<StyleRuleBase>>& adoptRules)
347     : StyleRuleGroup(Supports, adoptRules)
348     , m_conditionText(conditionText)
349     , m_conditionIsSupported(conditionIsSupported)
350 {
351 }
352
353 StyleRuleSupports::StyleRuleSupports(const StyleRuleSupports& o)
354     : StyleRuleGroup(o)
355     , m_conditionText(o.m_conditionText)
356     , m_conditionIsSupported(o.m_conditionIsSupported)
357 {
358 }
359
360 StyleRuleRegion::StyleRuleRegion(Vector<std::unique_ptr<CSSParserSelector>>* selectors, Vector<RefPtr<StyleRuleBase>>& adoptRules)
361     : StyleRuleGroup(Region, adoptRules)
362 {
363     m_selectorList.adoptSelectorVector(*selectors);
364 }
365
366 StyleRuleRegion::StyleRuleRegion(const StyleRuleRegion& o)
367     : StyleRuleGroup(o)
368     , m_selectorList(o.m_selectorList)
369 {
370 }
371
372
373 #if ENABLE(CSS_DEVICE_ADAPTATION)
374 StyleRuleViewport::StyleRuleViewport(Ref<StyleProperties>&& properties)
375     : StyleRuleBase(Viewport, 0)
376     , m_properties(WTFMove(properties))
377 {
378 }
379
380 StyleRuleViewport::StyleRuleViewport(const StyleRuleViewport& o)
381     : StyleRuleBase(o)
382     , m_properties(o.m_properties->mutableCopy())
383 {
384 }
385
386 StyleRuleViewport::~StyleRuleViewport()
387 {
388 }
389
390 MutableStyleProperties& StyleRuleViewport::mutableProperties()
391 {
392     if (!m_properties->isMutable())
393         m_properties = m_properties->mutableCopy();
394     return static_cast<MutableStyleProperties&>(m_properties.get());
395 }
396 #endif // ENABLE(CSS_DEVICE_ADAPTATION)
397
398 } // namespace WebCore