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 "core/dom/ExceptionCode.h"
25#include "platform/weborigin/KURL.h"
26#include "wtf/HashMap.h"
27#include "wtf/ListHashSet.h"
28#include "wtf/RefCounted.h"
29#include "wtf/RefPtr.h"
30
31namespace WebCore {
32
33class ExceptionState;
34class StyleSheetContents;
35
36enum CSSTextFormattingFlags { QuoteCSSStringIfNeeded, AlwaysQuoteCSSString };
37
38// FIXME: The current CSSValue and subclasses should be turned into internal types (StyleValue).
39// The few subtypes that are actually exposed in CSSOM can be seen in the cloneForCSSOM() function.
40// They should be handled by separate wrapper classes.
41
42// Please don't expose more CSSValue types to the web.
43class CSSValue : public RefCounted<CSSValue> {
44public:
45    enum Type {
46        CSS_INHERIT = 0,
47        CSS_PRIMITIVE_VALUE = 1,
48        CSS_VALUE_LIST = 2,
49        CSS_CUSTOM = 3,
50        CSS_INITIAL = 4
51
52    };
53
54    // Override RefCounted's deref() to ensure operator delete is called on
55    // the appropriate subclass type.
56    void deref()
57    {
58        if (derefBase())
59            destroy();
60    }
61
62    Type cssValueType() const;
63
64    String cssText() const;
65    void setCSSText(const String&, ExceptionState&) { } // FIXME: Not implemented.
66    String serializeResolvingVariables(const HashMap<AtomicString, String>&) const;
67
68    bool isPrimitiveValue() const { return m_classType == PrimitiveClass; }
69    bool isValueList() const { return m_classType >= ValueListClass; }
70
71    bool isBaseValueList() const { return m_classType == ValueListClass; }
72
73    bool isAspectRatioValue() const { return m_classType == AspectRatioClass; }
74    bool isBorderImageSliceValue() const { return m_classType == BorderImageSliceClass; }
75    bool isCanvasValue() const { return m_classType == CanvasClass; }
76    bool isCursorImageValue() const { return m_classType == CursorImageClass; }
77    bool isCrossfadeValue() const { return m_classType == CrossfadeClass; }
78    bool isFontFeatureValue() const { return m_classType == FontFeatureClass; }
79    bool isFontValue() const { return m_classType == FontClass; }
80    bool isFontFaceSrcValue() const { return m_classType == FontFaceSrcClass; }
81    bool isFunctionValue() const { return m_classType == FunctionClass; }
82    bool isImageGeneratorValue() const { return m_classType >= CanvasClass && m_classType <= RadialGradientClass; }
83    bool isGradientValue() const { return m_classType >= LinearGradientClass && m_classType <= RadialGradientClass; }
84    bool isImageSetValue() const { return m_classType == ImageSetClass; }
85    bool isImageValue() const { return m_classType == ImageClass; }
86    bool isImplicitInitialValue() const;
87    bool isInheritedValue() const { return m_classType == InheritedClass; }
88    bool isInitialValue() const { return m_classType == InitialClass; }
89    bool isLinearGradientValue() const { return m_classType == LinearGradientClass; }
90    bool isRadialGradientValue() const { return m_classType == RadialGradientClass; }
91    bool isReflectValue() const { return m_classType == ReflectClass; }
92    bool isShadowValue() const { return m_classType == ShadowClass; }
93    bool isTextCloneCSSValue() const { return m_isTextClone; }
94    bool isCubicBezierTimingFunctionValue() const { return m_classType == CubicBezierTimingFunctionClass; }
95    bool isStepsTimingFunctionValue() const { return m_classType == StepsTimingFunctionClass; }
96    bool isTransformValue() const { return m_classType == CSSTransformClass; }
97    bool isLineBoxContainValue() const { return m_classType == LineBoxContainClass; }
98    bool isCalcValue() const {return m_classType == CalculationClass; }
99    bool isFilterValue() const { return m_classType == CSSFilterClass; }
100    bool isArrayFunctionValue() const { return m_classType == CSSArrayFunctionValueClass; }
101    bool isMixFunctionValue() const { return m_classType == CSSMixFunctionValueClass; }
102    bool isShaderValue() const { return m_classType == CSSShaderClass; }
103    bool isVariableValue() const { return m_classType == VariableClass; }
104    bool isGridTemplateValue() const { return m_classType == GridTemplateClass; }
105    bool isSVGColor() const { return m_classType == SVGColorClass || m_classType == SVGPaintClass; }
106    bool isSVGPaint() const { return m_classType == SVGPaintClass; }
107    bool isSVGDocumentValue() const { return m_classType == CSSSVGDocumentClass; }
108    bool isUnicodeRangeValue() const { return m_classType == UnicodeRangeClass; }
109    bool isGridLineNamesValue() const { return m_classType == GridLineNamesClass; }
110
111    bool isCSSOMSafe() const { return m_isCSSOMSafe; }
112    bool isSubtypeExposedToCSSOM() const
113    {
114        return isPrimitiveValue() || isSVGColor() || isValueList();
115    }
116
117    PassRefPtr<CSSValue> cloneForCSSOM() const;
118
119    void addSubresourceStyleURLs(ListHashSet<KURL>&, const StyleSheetContents*) const;
120
121    bool hasFailedOrCanceledSubresources() const;
122
123    bool equals(const CSSValue&) const;
124
125protected:
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        CSSShaderClass,
162        VariableClass,
163        GridTemplateClass,
164
165        // SVG classes.
166        SVGColorClass,
167        SVGPaintClass,
168        CSSSVGDocumentClass,
169
170        // List class types must appear after ValueListClass.
171        ValueListClass,
172        ImageSetClass,
173        CSSFilterClass,
174        CSSArrayFunctionValueClass,
175        CSSMixFunctionValueClass,
176        CSSTransformClass,
177        GridLineNamesClass,
178        // Do not append non-list class types here.
179    };
180
181    static const size_t ValueListSeparatorBits = 2;
182    enum ValueListSeparator {
183        SpaceSeparator,
184        CommaSeparator,
185        SlashSeparator
186    };
187
188    ClassType classType() const { return static_cast<ClassType>(m_classType); }
189
190    explicit CSSValue(ClassType classType, bool isCSSOMSafe = false)
191        : m_isCSSOMSafe(isCSSOMSafe)
192        , m_isTextClone(false)
193        , m_primitiveUnitType(0)
194        , m_hasCachedCSSText(false)
195        , m_isQuirkValue(false)
196        , m_valueListSeparator(SpaceSeparator)
197        , m_classType(classType)
198    {
199    }
200
201    // NOTE: This class is non-virtual for memory and performance reasons.
202    // Don't go making it virtual again unless you know exactly what you're doing!
203
204    ~CSSValue() { }
205
206private:
207    void destroy();
208
209protected:
210    unsigned m_isCSSOMSafe : 1;
211    unsigned m_isTextClone : 1;
212    // The bits in this section are only used by specific subclasses but kept here
213    // to maximize struct packing.
214
215    // CSSPrimitiveValue bits:
216    unsigned m_primitiveUnitType : 7; // CSSPrimitiveValue::UnitTypes
217    mutable unsigned m_hasCachedCSSText : 1;
218    unsigned m_isQuirkValue : 1;
219
220    unsigned m_valueListSeparator : ValueListSeparatorBits;
221
222private:
223    unsigned m_classType : ClassTypeBits; // ClassType
224};
225
226template<typename CSSValueType>
227inline bool compareCSSValueVector(const Vector<RefPtr<CSSValueType> >& firstVector, const Vector<RefPtr<CSSValueType> >& secondVector)
228{
229    size_t size = firstVector.size();
230    if (size != secondVector.size())
231        return false;
232
233    for (size_t i = 0; i < size; i++) {
234        const RefPtr<CSSValueType>& firstPtr = firstVector[i];
235        const RefPtr<CSSValueType>& secondPtr = secondVector[i];
236        if (firstPtr == secondPtr || (firstPtr && secondPtr && firstPtr->equals(*secondPtr)))
237            continue;
238        return false;
239    }
240    return true;
241}
242
243template<typename CSSValueType>
244inline bool compareCSSValuePtr(const RefPtr<CSSValueType>& first, const RefPtr<CSSValueType>& second)
245{
246    return first ? second && first->equals(*second) : !second;
247}
248
249#define DEFINE_CSS_VALUE_TYPE_CASTS(thisType, predicate) \
250    DEFINE_TYPE_CASTS(thisType, CSSValue, value, value->predicate, value.predicate)
251
252} // namespace WebCore
253
254#endif // CSSValue_h
255