1 /*
2 * (C) 1999-2003 Lars Knoll (knoll@kde.org)
3 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20
21 #ifndef CSSValue_h
22 #define CSSValue_h
23
24 #include "bindings/core/v8/ScriptWrappable.h"
25 #include "core/dom/ExceptionCode.h"
26 #include "platform/heap/Handle.h"
27 #include "platform/weborigin/KURL.h"
28 #include "wtf/HashMap.h"
29 #include "wtf/ListHashSet.h"
30 #include "wtf/RefCounted.h"
31 #include "wtf/RefPtr.h"
32
33 namespace blink {
34
35 class ExceptionState;
36
37 enum CSSTextFormattingFlags { QuoteCSSStringIfNeeded, AlwaysQuoteCSSString };
38
39 // FIXME: The current CSSValue and subclasses should be turned into internal types (StyleValue).
40 // The few subtypes that are actually exposed in CSSOM can be seen in the cloneForCSSOM() function.
41 // They should be handled by separate wrapper classes.
42
43 // Please don't expose more CSSValue types to the web.
44 class CSSValue : public RefCountedWillBeGarbageCollectedFinalized<CSSValue>, public ScriptWrappableBase {
45 public:
46 enum Type {
47 CSS_INHERIT = 0,
48 CSS_PRIMITIVE_VALUE = 1,
49 CSS_VALUE_LIST = 2,
50 CSS_CUSTOM = 3,
51 CSS_INITIAL = 4
52
53 };
54
55 // Override RefCounted's deref() to ensure operator delete is called on
56 // the appropriate subclass type.
57 // When oilpan is enabled the finalize method is called by the garbage
58 // collector and not immediately when deref reached zero.
59 #if !ENABLE(OILPAN)
deref()60 void deref()
61 {
62 if (derefBase())
63 destroy();
64 }
65 #endif // !ENABLE(OILPAN)
66
67 Type cssValueType() const;
68
69 String cssText() const;
setCSSText(const String &,ExceptionState &)70 void setCSSText(const String&, ExceptionState&) { } // FIXME: Not implemented.
71
isPrimitiveValue()72 bool isPrimitiveValue() const { return m_classType == PrimitiveClass; }
isValueList()73 bool isValueList() const { return m_classType >= ValueListClass; }
74
isBaseValueList()75 bool isBaseValueList() const { return m_classType == ValueListClass; }
76
isAspectRatioValue()77 bool isAspectRatioValue() const { return m_classType == AspectRatioClass; }
isBorderImageSliceValue()78 bool isBorderImageSliceValue() const { return m_classType == BorderImageSliceClass; }
isCanvasValue()79 bool isCanvasValue() const { return m_classType == CanvasClass; }
isCursorImageValue()80 bool isCursorImageValue() const { return m_classType == CursorImageClass; }
isCrossfadeValue()81 bool isCrossfadeValue() const { return m_classType == CrossfadeClass; }
isFontFeatureValue()82 bool isFontFeatureValue() const { return m_classType == FontFeatureClass; }
isFontValue()83 bool isFontValue() const { return m_classType == FontClass; }
isFontFaceSrcValue()84 bool isFontFaceSrcValue() const { return m_classType == FontFaceSrcClass; }
isFunctionValue()85 bool isFunctionValue() const { return m_classType == FunctionClass; }
isImageGeneratorValue()86 bool isImageGeneratorValue() const { return m_classType >= CanvasClass && m_classType <= RadialGradientClass; }
isGradientValue()87 bool isGradientValue() const { return m_classType >= LinearGradientClass && m_classType <= RadialGradientClass; }
isImageSetValue()88 bool isImageSetValue() const { return m_classType == ImageSetClass; }
isImageValue()89 bool isImageValue() const { return m_classType == ImageClass; }
90 bool isImplicitInitialValue() const;
isInheritedValue()91 bool isInheritedValue() const { return m_classType == InheritedClass; }
isInitialValue()92 bool isInitialValue() const { return m_classType == InitialClass; }
isLinearGradientValue()93 bool isLinearGradientValue() const { return m_classType == LinearGradientClass; }
isRadialGradientValue()94 bool isRadialGradientValue() const { return m_classType == RadialGradientClass; }
isReflectValue()95 bool isReflectValue() const { return m_classType == ReflectClass; }
isShadowValue()96 bool isShadowValue() const { return m_classType == ShadowClass; }
isTextCloneCSSValue()97 bool isTextCloneCSSValue() const { return m_isTextClone; }
isCubicBezierTimingFunctionValue()98 bool isCubicBezierTimingFunctionValue() const { return m_classType == CubicBezierTimingFunctionClass; }
isStepsTimingFunctionValue()99 bool isStepsTimingFunctionValue() const { return m_classType == StepsTimingFunctionClass; }
isTransformValue()100 bool isTransformValue() const { return m_classType == CSSTransformClass; }
isLineBoxContainValue()101 bool isLineBoxContainValue() const { return m_classType == LineBoxContainClass; }
isCalcValue()102 bool isCalcValue() const {return m_classType == CalculationClass; }
isFilterValue()103 bool isFilterValue() const { return m_classType == CSSFilterClass; }
isGridTemplateAreasValue()104 bool isGridTemplateAreasValue() const { return m_classType == GridTemplateAreasClass; }
isSVGDocumentValue()105 bool isSVGDocumentValue() const { return m_classType == CSSSVGDocumentClass; }
isUnicodeRangeValue()106 bool isUnicodeRangeValue() const { return m_classType == UnicodeRangeClass; }
isGridLineNamesValue()107 bool isGridLineNamesValue() const { return m_classType == GridLineNamesClass; }
108
isCSSOMSafe()109 bool isCSSOMSafe() const { return m_isCSSOMSafe; }
isSubtypeExposedToCSSOM()110 bool isSubtypeExposedToCSSOM() const
111 {
112 return isPrimitiveValue() || isValueList();
113 }
114
115 PassRefPtrWillBeRawPtr<CSSValue> cloneForCSSOM() const;
116
117 bool hasFailedOrCanceledSubresources() const;
118
119 bool equals(const CSSValue&) const;
120
121 void finalizeGarbageCollectedObject();
traceAfterDispatch(Visitor *)122 void traceAfterDispatch(Visitor*) { }
123 void trace(Visitor*);
124
125 protected:
126
127 static const size_t ClassTypeBits = 6;
128 enum ClassType {
129 PrimitiveClass,
130
131 // Image classes.
132 ImageClass,
133 CursorImageClass,
134
135 // Image generator classes.
136 CanvasClass,
137 CrossfadeClass,
138 LinearGradientClass,
139 RadialGradientClass,
140
141 // Timing function classes.
142 CubicBezierTimingFunctionClass,
143 StepsTimingFunctionClass,
144
145 // Other class types.
146 AspectRatioClass,
147 BorderImageSliceClass,
148 FontFeatureClass,
149 FontClass,
150 FontFaceSrcClass,
151 FunctionClass,
152
153 InheritedClass,
154 InitialClass,
155
156 ReflectClass,
157 ShadowClass,
158 UnicodeRangeClass,
159 LineBoxContainClass,
160 CalculationClass,
161 GridTemplateAreasClass,
162
163 // SVG classes.
164 CSSSVGDocumentClass,
165
166 // List class types must appear after ValueListClass.
167 ValueListClass,
168 ImageSetClass,
169 CSSFilterClass,
170 CSSTransformClass,
171 GridLineNamesClass,
172 // Do not append non-list class types here.
173 };
174
175 static const size_t ValueListSeparatorBits = 2;
176 enum ValueListSeparator {
177 SpaceSeparator,
178 CommaSeparator,
179 SlashSeparator
180 };
181
classType()182 ClassType classType() const { return static_cast<ClassType>(m_classType); }
183
184 explicit CSSValue(ClassType classType, bool isCSSOMSafe = false)
m_isCSSOMSafe(isCSSOMSafe)185 : m_isCSSOMSafe(isCSSOMSafe)
186 , m_isTextClone(false)
187 , m_primitiveUnitType(0)
188 , m_hasCachedCSSText(false)
189 , m_isQuirkValue(false)
190 , m_valueListSeparator(SpaceSeparator)
191 , m_classType(classType)
192 {
193 }
194
195 // NOTE: This class is non-virtual for memory and performance reasons.
196 // Don't go making it virtual again unless you know exactly what you're doing!
197
~CSSValue()198 ~CSSValue() { }
199
200 private:
201 void destroy();
202
203 protected:
204 unsigned m_isCSSOMSafe : 1;
205 unsigned m_isTextClone : 1;
206 // The bits in this section are only used by specific subclasses but kept here
207 // to maximize struct packing.
208
209 // CSSPrimitiveValue bits:
210 unsigned m_primitiveUnitType : 7; // CSSPrimitiveValue::UnitType
211 mutable unsigned m_hasCachedCSSText : 1;
212 unsigned m_isQuirkValue : 1;
213
214 unsigned m_valueListSeparator : ValueListSeparatorBits;
215
216 private:
217 unsigned m_classType : ClassTypeBits; // ClassType
218 };
219
220 template<typename CSSValueType, size_t inlineCapacity>
compareCSSValueVector(const WillBeHeapVector<RefPtrWillBeMember<CSSValueType>,inlineCapacity> & firstVector,const WillBeHeapVector<RefPtrWillBeMember<CSSValueType>,inlineCapacity> & secondVector)221 inline bool compareCSSValueVector(const WillBeHeapVector<RefPtrWillBeMember<CSSValueType>, inlineCapacity>& firstVector, const WillBeHeapVector<RefPtrWillBeMember<CSSValueType>, inlineCapacity>& secondVector)
222 {
223 size_t size = firstVector.size();
224 if (size != secondVector.size())
225 return false;
226
227 for (size_t i = 0; i < size; i++) {
228 const RefPtrWillBeMember<CSSValueType>& firstPtr = firstVector[i];
229 const RefPtrWillBeMember<CSSValueType>& secondPtr = secondVector[i];
230 if (firstPtr == secondPtr || (firstPtr && secondPtr && firstPtr->equals(*secondPtr)))
231 continue;
232 return false;
233 }
234 return true;
235 }
236
237 template<typename CSSValueType>
compareCSSValuePtr(const RefPtr<CSSValueType> & first,const RefPtr<CSSValueType> & second)238 inline bool compareCSSValuePtr(const RefPtr<CSSValueType>& first, const RefPtr<CSSValueType>& second)
239 {
240 return first ? second && first->equals(*second) : !second;
241 }
242
243 template<typename CSSValueType>
compareCSSValuePtr(const RawPtr<CSSValueType> & first,const RawPtr<CSSValueType> & second)244 inline bool compareCSSValuePtr(const RawPtr<CSSValueType>& first, const RawPtr<CSSValueType>& second)
245 {
246 return first ? second && first->equals(*second) : !second;
247 }
248
249 template<typename CSSValueType>
compareCSSValuePtr(const Member<CSSValueType> & first,const Member<CSSValueType> & second)250 inline bool compareCSSValuePtr(const Member<CSSValueType>& first, const Member<CSSValueType>& second)
251 {
252 return first ? second && first->equals(*second) : !second;
253 }
254
255 #define DEFINE_CSS_VALUE_TYPE_CASTS(thisType, predicate) \
256 DEFINE_TYPE_CASTS(thisType, CSSValue, value, value->predicate, value.predicate)
257
258 } // namespace blink
259
260 #endif // CSSValue_h
261