1/*
2 * Copyright (C) 2011 Andreas Kling (kling@webkit.org)
3 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
26 */
27
28#include "config.h"
29#include "CSSValue.h"
30
31#include "CSSAspectRatioValue.h"
32#include "CSSBorderImageSliceValue.h"
33#include "CSSCalculationValue.h"
34#include "CSSCanvasValue.h"
35#include "CSSContentDistributionValue.h"
36#include "CSSCrossfadeValue.h"
37#include "CSSCursorImageValue.h"
38#include "CSSCustomIdentValue.h"
39#include "CSSCustomPropertyValue.h"
40#include "CSSFilterImageValue.h"
41#include "CSSFontFaceSrcValue.h"
42#include "CSSFontFeatureValue.h"
43#include "CSSFontStyleRangeValue.h"
44#include "CSSFontStyleValue.h"
45#include "CSSFontValue.h"
46#include "CSSFontVariationValue.h"
47#include "CSSFunctionValue.h"
48#include "CSSGradientValue.h"
49#include "CSSImageSetValue.h"
50#include "CSSImageValue.h"
51#include "CSSInheritedValue.h"
52#include "CSSInitialValue.h"
53#include "CSSLineBoxContainValue.h"
54#include "CSSNamedImageValue.h"
55#include "CSSPaintImageValue.h"
56#include "CSSPendingSubstitutionValue.h"
57#include "CSSPrimitiveValue.h"
58#include "CSSProperty.h"
59#include "CSSReflectValue.h"
60#include "CSSShadowValue.h"
61#include "CSSTimingFunctionValue.h"
62#include "CSSUnicodeRangeValue.h"
63#include "CSSUnsetValue.h"
64#include "CSSValueList.h"
65#include "CSSVariableReferenceValue.h"
66
67#include "CSSGridAutoRepeatValue.h"
68#include "CSSGridLineNamesValue.h"
69#include "CSSGridTemplateAreasValue.h"
70
71#include "DeprecatedCSSOMPrimitiveValue.h"
72#include "DeprecatedCSSOMValueList.h"
73
74namespace WebCore {
75
76struct SameSizeAsCSSValue : public RefCounted<SameSizeAsCSSValue> {
77 uint32_t bitfields;
78};
79
80COMPILE_ASSERT(sizeof(CSSValue) == sizeof(SameSizeAsCSSValue), CSS_value_should_stay_small);
81
82bool CSSValue::isImplicitInitialValue() const
83{
84 return m_classType == InitialClass && downcast<CSSInitialValue>(*this).isImplicit();
85}
86
87CSSValue::Type CSSValue::cssValueType() const
88{
89 if (isInheritedValue())
90 return CSS_INHERIT;
91 if (isPrimitiveValue())
92 return CSS_PRIMITIVE_VALUE;
93 if (isValueList())
94 return CSS_VALUE_LIST;
95 if (isInitialValue())
96 return CSS_INITIAL;
97 if (isUnsetValue())
98 return CSS_UNSET;
99 if (isRevertValue())
100 return CSS_REVERT;
101 return CSS_CUSTOM;
102}
103
104bool CSSValue::traverseSubresources(const WTF::Function<bool (const CachedResource&)>& handler) const
105{
106 if (is<CSSValueList>(*this))
107 return downcast<CSSValueList>(*this).traverseSubresources(handler);
108 if (is<CSSFontFaceSrcValue>(*this))
109 return downcast<CSSFontFaceSrcValue>(*this).traverseSubresources(handler);
110 if (is<CSSImageValue>(*this))
111 return downcast<CSSImageValue>(*this).traverseSubresources(handler);
112 if (is<CSSCrossfadeValue>(*this))
113 return downcast<CSSCrossfadeValue>(*this).traverseSubresources(handler);
114 if (is<CSSFilterImageValue>(*this))
115 return downcast<CSSFilterImageValue>(*this).traverseSubresources(handler);
116 if (is<CSSImageSetValue>(*this))
117 return downcast<CSSImageSetValue>(*this).traverseSubresources(handler);
118 return false;
119}
120
121void CSSValue::collectDirectComputationalDependencies(HashSet<CSSPropertyID>& values) const
122{
123 if (is<CSSPrimitiveValue>(*this))
124 downcast<CSSPrimitiveValue>(*this).collectDirectComputationalDependencies(values);
125}
126
127void CSSValue::collectDirectRootComputationalDependencies(HashSet<CSSPropertyID>& values) const
128{
129 if (is<CSSPrimitiveValue>(*this))
130 downcast<CSSPrimitiveValue>(*this).collectDirectRootComputationalDependencies(values);
131}
132
133template<class ChildClassType>
134inline static bool compareCSSValues(const CSSValue& first, const CSSValue& second)
135{
136 return static_cast<const ChildClassType&>(first).equals(static_cast<const ChildClassType&>(second));
137}
138
139bool CSSValue::equals(const CSSValue& other) const
140{
141 if (m_classType == other.m_classType) {
142 switch (m_classType) {
143 case AspectRatioClass:
144 return compareCSSValues<CSSAspectRatioValue>(*this, other);
145 case BorderImageSliceClass:
146 return compareCSSValues<CSSBorderImageSliceValue>(*this, other);
147 case CanvasClass:
148 return compareCSSValues<CSSCanvasValue>(*this, other);
149 case NamedImageClass:
150 return compareCSSValues<CSSNamedImageValue>(*this, other);
151 case CursorImageClass:
152 return compareCSSValues<CSSCursorImageValue>(*this, other);
153 case FilterImageClass:
154 return compareCSSValues<CSSFilterImageValue>(*this, other);
155#if ENABLE(CSS_PAINTING_API)
156 case PaintImageClass:
157 return compareCSSValues<CSSPaintImageValue>(*this, other);
158#endif
159 case FontClass:
160 return compareCSSValues<CSSFontValue>(*this, other);
161 case FontFaceSrcClass:
162 return compareCSSValues<CSSFontFaceSrcValue>(*this, other);
163 case FontFeatureClass:
164 return compareCSSValues<CSSFontFeatureValue>(*this, other);
165#if ENABLE(VARIATION_FONTS)
166 case FontVariationClass:
167 return compareCSSValues<CSSFontVariationValue>(*this, other);
168#endif
169 case FunctionClass:
170 return compareCSSValues<CSSFunctionValue>(*this, other);
171 case LinearGradientClass:
172 return compareCSSValues<CSSLinearGradientValue>(*this, other);
173 case RadialGradientClass:
174 return compareCSSValues<CSSRadialGradientValue>(*this, other);
175 case ConicGradientClass:
176 return compareCSSValues<CSSConicGradientValue>(*this, other);
177 case CrossfadeClass:
178 return compareCSSValues<CSSCrossfadeValue>(*this, other);
179 case ImageClass:
180 return compareCSSValues<CSSImageValue>(*this, other);
181 case InheritedClass:
182 return compareCSSValues<CSSInheritedValue>(*this, other);
183 case InitialClass:
184 return compareCSSValues<CSSInitialValue>(*this, other);
185 case UnsetClass:
186 return compareCSSValues<CSSUnsetValue>(*this, other);
187 case RevertClass:
188 return compareCSSValues<CSSRevertValue>(*this, other);
189 case GridAutoRepeatClass:
190 return compareCSSValues<CSSGridAutoRepeatValue>(*this, other);
191 case GridLineNamesClass:
192 return compareCSSValues<CSSGridLineNamesValue>(*this, other);
193 case GridTemplateAreasClass:
194 return compareCSSValues<CSSGridTemplateAreasValue>(*this, other);
195 case PrimitiveClass:
196 return compareCSSValues<CSSPrimitiveValue>(*this, other);
197 case ReflectClass:
198 return compareCSSValues<CSSReflectValue>(*this, other);
199 case ShadowClass:
200 return compareCSSValues<CSSShadowValue>(*this, other);
201 case CubicBezierTimingFunctionClass:
202 return compareCSSValues<CSSCubicBezierTimingFunctionValue>(*this, other);
203 case StepsTimingFunctionClass:
204 return compareCSSValues<CSSStepsTimingFunctionValue>(*this, other);
205 case SpringTimingFunctionClass:
206 return compareCSSValues<CSSSpringTimingFunctionValue>(*this, other);
207 case UnicodeRangeClass:
208 return compareCSSValues<CSSUnicodeRangeValue>(*this, other);
209 case ValueListClass:
210 return compareCSSValues<CSSValueList>(*this, other);
211 case LineBoxContainClass:
212 return compareCSSValues<CSSLineBoxContainValue>(*this, other);
213 case CalculationClass:
214 return compareCSSValues<CSSCalcValue>(*this, other);
215 case ImageSetClass:
216 return compareCSSValues<CSSImageSetValue>(*this, other);
217 case CSSContentDistributionClass:
218 return compareCSSValues<CSSContentDistributionValue>(*this, other);
219 case CustomPropertyClass:
220 return compareCSSValues<CSSCustomPropertyValue>(*this, other);
221 case VariableReferenceClass:
222 return compareCSSValues<CSSVariableReferenceValue>(*this, other);
223 case PendingSubstitutionValueClass:
224 return compareCSSValues<CSSPendingSubstitutionValue>(*this, other);
225 case FontStyleClass:
226 return compareCSSValues<CSSFontStyleValue>(*this, other);
227 case FontStyleRangeClass:
228 return compareCSSValues<CSSFontStyleRangeValue>(*this, other);
229 default:
230 ASSERT_NOT_REACHED();
231 return false;
232 }
233 } else if (is<CSSValueList>(*this) && !is<CSSValueList>(other))
234 return downcast<CSSValueList>(*this).equals(other);
235 else if (!is<CSSValueList>(*this) && is<CSSValueList>(other))
236 return static_cast<const CSSValueList&>(other).equals(*this);
237 return false;
238}
239
240String CSSValue::cssText() const
241{
242 switch (classType()) {
243 case AspectRatioClass:
244 return downcast<CSSAspectRatioValue>(*this).customCSSText();
245 case BorderImageSliceClass:
246 return downcast<CSSBorderImageSliceValue>(*this).customCSSText();
247 case CanvasClass:
248 return downcast<CSSCanvasValue>(*this).customCSSText();
249 case NamedImageClass:
250 return downcast<CSSNamedImageValue>(*this).customCSSText();
251 case CursorImageClass:
252 return downcast<CSSCursorImageValue>(*this).customCSSText();
253 case FilterImageClass:
254 return downcast<CSSFilterImageValue>(*this).customCSSText();
255#if ENABLE(CSS_PAINTING_API)
256 case PaintImageClass:
257 return downcast<CSSPaintImageValue>(*this).customCSSText();
258#endif
259 case FontClass:
260 return downcast<CSSFontValue>(*this).customCSSText();
261 case FontFaceSrcClass:
262 return downcast<CSSFontFaceSrcValue>(*this).customCSSText();
263 case FontFeatureClass:
264 return downcast<CSSFontFeatureValue>(*this).customCSSText();
265#if ENABLE(VARIATION_FONTS)
266 case FontVariationClass:
267 return downcast<CSSFontVariationValue>(*this).customCSSText();
268#endif
269 case FunctionClass:
270 return downcast<CSSFunctionValue>(*this).customCSSText();
271 case LinearGradientClass:
272 return downcast<CSSLinearGradientValue>(*this).customCSSText();
273 case RadialGradientClass:
274 return downcast<CSSRadialGradientValue>(*this).customCSSText();
275 case ConicGradientClass:
276 return downcast<CSSConicGradientValue>(*this).customCSSText();
277 case CrossfadeClass:
278 return downcast<CSSCrossfadeValue>(*this).customCSSText();
279 case ImageClass:
280 return downcast<CSSImageValue>(*this).customCSSText();
281 case InheritedClass:
282 return downcast<CSSInheritedValue>(*this).customCSSText();
283 case InitialClass:
284 return downcast<CSSInitialValue>(*this).customCSSText();
285 case UnsetClass:
286 return downcast<CSSUnsetValue>(*this).customCSSText();
287 case RevertClass:
288 return downcast<CSSRevertValue>(*this).customCSSText();
289 case GridAutoRepeatClass:
290 return downcast<CSSGridAutoRepeatValue>(*this).customCSSText();
291 case GridLineNamesClass:
292 return downcast<CSSGridLineNamesValue>(*this).customCSSText();
293 case GridTemplateAreasClass:
294 return downcast<CSSGridTemplateAreasValue>(*this).customCSSText();
295 case PrimitiveClass:
296 return downcast<CSSPrimitiveValue>(*this).customCSSText();
297 case ReflectClass:
298 return downcast<CSSReflectValue>(*this).customCSSText();
299 case ShadowClass:
300 return downcast<CSSShadowValue>(*this).customCSSText();
301 case CubicBezierTimingFunctionClass:
302 return downcast<CSSCubicBezierTimingFunctionValue>(*this).customCSSText();
303 case StepsTimingFunctionClass:
304 return downcast<CSSStepsTimingFunctionValue>(*this).customCSSText();
305 case SpringTimingFunctionClass:
306 return downcast<CSSSpringTimingFunctionValue>(*this).customCSSText();
307 case UnicodeRangeClass:
308 return downcast<CSSUnicodeRangeValue>(*this).customCSSText();
309 case ValueListClass:
310 return downcast<CSSValueList>(*this).customCSSText();
311 case LineBoxContainClass:
312 return downcast<CSSLineBoxContainValue>(*this).customCSSText();
313 case CalculationClass:
314 return downcast<CSSCalcValue>(*this).customCSSText();
315 case ImageSetClass:
316 return downcast<CSSImageSetValue>(*this).customCSSText();
317 case CSSContentDistributionClass:
318 return downcast<CSSContentDistributionValue>(*this).customCSSText();
319 case CustomPropertyClass:
320 return downcast<CSSCustomPropertyValue>(*this).customCSSText();
321 case CustomIdentClass:
322 return downcast<CSSCustomIdentValue>(*this).customCSSText();
323 case VariableReferenceClass:
324 return downcast<CSSVariableReferenceValue>(*this).customCSSText();
325 case PendingSubstitutionValueClass:
326 return downcast<CSSPendingSubstitutionValue>(*this).customCSSText();
327 case FontStyleClass:
328 return downcast<CSSFontStyleValue>(*this).customCSSText();
329 case FontStyleRangeClass:
330 return downcast<CSSFontStyleRangeValue>(*this).customCSSText();
331 }
332
333 ASSERT_NOT_REACHED();
334 return String();
335}
336
337void CSSValue::destroy()
338{
339 switch (classType()) {
340 case AspectRatioClass:
341 delete downcast<CSSAspectRatioValue>(this);
342 return;
343 case BorderImageSliceClass:
344 delete downcast<CSSBorderImageSliceValue>(this);
345 return;
346 case CanvasClass:
347 delete downcast<CSSCanvasValue>(this);
348 return;
349 case NamedImageClass:
350 delete downcast<CSSNamedImageValue>(this);
351 return;
352 case CursorImageClass:
353 delete downcast<CSSCursorImageValue>(this);
354 return;
355 case FontClass:
356 delete downcast<CSSFontValue>(this);
357 return;
358 case FontFaceSrcClass:
359 delete downcast<CSSFontFaceSrcValue>(this);
360 return;
361 case FontFeatureClass:
362 delete downcast<CSSFontFeatureValue>(this);
363 return;
364#if ENABLE(VARIATION_FONTS)
365 case FontVariationClass:
366 delete downcast<CSSFontVariationValue>(this);
367 return;
368#endif
369 case FunctionClass:
370 delete downcast<CSSFunctionValue>(this);
371 return;
372 case LinearGradientClass:
373 delete downcast<CSSLinearGradientValue>(this);
374 return;
375 case RadialGradientClass:
376 delete downcast<CSSRadialGradientValue>(this);
377 return;
378 case ConicGradientClass:
379 delete downcast<CSSConicGradientValue>(this);
380 return;
381 case CrossfadeClass:
382 delete downcast<CSSCrossfadeValue>(this);
383 return;
384 case ImageClass:
385 delete downcast<CSSImageValue>(this);
386 return;
387 case InheritedClass:
388 delete downcast<CSSInheritedValue>(this);
389 return;
390 case InitialClass:
391 delete downcast<CSSInitialValue>(this);
392 return;
393 case UnsetClass:
394 delete downcast<CSSUnsetValue>(this);
395 return;
396 case RevertClass:
397 delete downcast<CSSRevertValue>(this);
398 return;
399 case GridAutoRepeatClass:
400 delete downcast<CSSGridAutoRepeatValue>(this);
401 return;
402 case GridLineNamesClass:
403 delete downcast<CSSGridLineNamesValue>(this);
404 return;
405 case GridTemplateAreasClass:
406 delete downcast<CSSGridTemplateAreasValue>(this);
407 return;
408 case PrimitiveClass:
409 delete downcast<CSSPrimitiveValue>(this);
410 return;
411 case ReflectClass:
412 delete downcast<CSSReflectValue>(this);
413 return;
414 case ShadowClass:
415 delete downcast<CSSShadowValue>(this);
416 return;
417 case CubicBezierTimingFunctionClass:
418 delete downcast<CSSCubicBezierTimingFunctionValue>(this);
419 return;
420 case StepsTimingFunctionClass:
421 delete downcast<CSSStepsTimingFunctionValue>(this);
422 return;
423 case SpringTimingFunctionClass:
424 delete downcast<CSSSpringTimingFunctionValue>(this);
425 return;
426 case UnicodeRangeClass:
427 delete downcast<CSSUnicodeRangeValue>(this);
428 return;
429 case ValueListClass:
430 delete downcast<CSSValueList>(this);
431 return;
432 case LineBoxContainClass:
433 delete downcast<CSSLineBoxContainValue>(this);
434 return;
435 case CalculationClass:
436 delete downcast<CSSCalcValue>(this);
437 return;
438 case ImageSetClass:
439 delete downcast<CSSImageSetValue>(this);
440 return;
441 case FilterImageClass:
442 delete downcast<CSSFilterImageValue>(this);
443 return;
444#if ENABLE(CSS_PAINTING_API)
445 case PaintImageClass:
446 delete downcast<CSSPaintImageValue>(this);
447 return;
448#endif
449 case CSSContentDistributionClass:
450 delete downcast<CSSContentDistributionValue>(this);
451 return;
452 case CustomPropertyClass:
453 delete downcast<CSSCustomPropertyValue>(this);
454 return;
455 case CustomIdentClass:
456 delete downcast<CSSCustomIdentValue>(this);
457 return;
458 case VariableReferenceClass:
459 delete downcast<CSSVariableReferenceValue>(this);
460 return;
461 case PendingSubstitutionValueClass:
462 delete downcast<CSSPendingSubstitutionValue>(this);
463 return;
464 case FontStyleClass:
465 delete downcast<CSSFontStyleValue>(this);
466 return;
467 case FontStyleRangeClass:
468 delete downcast<CSSFontStyleRangeValue>(this);
469 return;
470 }
471 ASSERT_NOT_REACHED();
472}
473
474Ref<DeprecatedCSSOMValue> CSSValue::createDeprecatedCSSOMWrapper(CSSStyleDeclaration& styleDeclaration) const
475{
476 if (isImageValue() || isCursorImageValue())
477 return downcast<CSSImageValue>(this)->createDeprecatedCSSOMWrapper(styleDeclaration);
478 if (isPrimitiveValue())
479 return DeprecatedCSSOMPrimitiveValue::create(downcast<CSSPrimitiveValue>(*this), styleDeclaration);
480 if (isValueList())
481 return DeprecatedCSSOMValueList::create(downcast<CSSValueList>(*this), styleDeclaration);
482 return DeprecatedCSSOMComplexValue::create(*this, styleDeclaration);
483}
484
485bool CSSValue::treatAsInheritedValue(CSSPropertyID propertyID) const
486{
487 return classType() == InheritedClass || (classType() == UnsetClass && CSSProperty::isInheritedProperty(propertyID));
488}
489
490bool CSSValue::treatAsInitialValue(CSSPropertyID propertyID) const
491{
492 return classType() == InitialClass || (classType() == UnsetClass && !CSSProperty::isInheritedProperty(propertyID));
493}
494
495}
496