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 | |
74 | namespace WebCore { |
75 | |
76 | struct SameSizeAsCSSValue : public RefCounted<SameSizeAsCSSValue> { |
77 | uint32_t bitfields; |
78 | }; |
79 | |
80 | COMPILE_ASSERT(sizeof(CSSValue) == sizeof(SameSizeAsCSSValue), CSS_value_should_stay_small); |
81 | |
82 | bool CSSValue::isImplicitInitialValue() const |
83 | { |
84 | return m_classType == InitialClass && downcast<CSSInitialValue>(*this).isImplicit(); |
85 | } |
86 | |
87 | CSSValue::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 | |
104 | bool 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 | |
121 | void CSSValue::collectDirectComputationalDependencies(HashSet<CSSPropertyID>& values) const |
122 | { |
123 | if (is<CSSPrimitiveValue>(*this)) |
124 | downcast<CSSPrimitiveValue>(*this).collectDirectComputationalDependencies(values); |
125 | } |
126 | |
127 | void CSSValue::collectDirectRootComputationalDependencies(HashSet<CSSPropertyID>& values) const |
128 | { |
129 | if (is<CSSPrimitiveValue>(*this)) |
130 | downcast<CSSPrimitiveValue>(*this).collectDirectRootComputationalDependencies(values); |
131 | } |
132 | |
133 | template<class ChildClassType> |
134 | inline 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 | |
139 | bool 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 | |
240 | String 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 | |
337 | void 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 | |
474 | Ref<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 | |
485 | bool CSSValue::treatAsInheritedValue(CSSPropertyID propertyID) const |
486 | { |
487 | return classType() == InheritedClass || (classType() == UnsetClass && CSSProperty::isInheritedProperty(propertyID)); |
488 | } |
489 | |
490 | bool CSSValue::treatAsInitialValue(CSSPropertyID propertyID) const |
491 | { |
492 | return classType() == InitialClass || (classType() == UnsetClass && !CSSProperty::isInheritedProperty(propertyID)); |
493 | } |
494 | |
495 | } |
496 | |