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 "ExceptionCode.h"
25#include "KURLHash.h"
26#include <wtf/ListHashSet.h>
27#include <wtf/RefCounted.h>
28#include <wtf/RefPtr.h>
29
30namespace WebCore {
31
32class StyleSheetContents;
33
34// FIXME: The current CSSValue and subclasses should be turned into internal types (StyleValue).
35// The few subtypes that are actually exposed in CSSOM can be seen in the cloneForCSSOM() function.
36// They should be handled by separate wrapper classes.
37
38// Please don't expose more CSSValue types to the web.
39class CSSValue : public RefCounted<CSSValue> {
40public:
41    enum Type {
42        CSS_INHERIT = 0,
43        CSS_PRIMITIVE_VALUE = 1,
44        CSS_VALUE_LIST = 2,
45        CSS_CUSTOM = 3,
46        CSS_INITIAL = 4
47
48    };
49
50    // Override RefCounted's deref() to ensure operator delete is called on
51    // the appropriate subclass type.
52    void deref()
53    {
54        if (derefBase())
55            destroy();
56    }
57
58    Type cssValueType() const;
59
60    String cssText() const;
61    void setCssText(const String&, ExceptionCode&) { } // FIXME: Not implemented.
62#if ENABLE(CSS_VARIABLES)
63    String serializeResolvingVariables(const HashMap<AtomicString, String>&) const;
64#endif
65
66    bool isPrimitiveValue() const { return m_classType == PrimitiveClass; }
67    bool isValueList() const { return m_classType >= ValueListClass; }
68
69    bool isBaseValueList() const { return m_classType == ValueListClass; }
70
71
72    bool isAspectRatioValue() const { return m_classType == AspectRatioClass; }
73    bool isBorderImageSliceValue() const { return m_classType == BorderImageSliceClass; }
74    bool isCursorImageValue() const { return m_classType == CursorImageClass; }
75    bool isFontFeatureValue() const { return m_classType == FontFeatureClass; }
76    bool isFontValue() const { return m_classType == FontClass; }
77    bool isImageGeneratorValue() const { return m_classType >= CanvasClass && m_classType <= RadialGradientClass; }
78    bool isGradientValue() const { return m_classType >= LinearGradientClass && m_classType <= RadialGradientClass; }
79#if ENABLE(CSS_IMAGE_SET)
80    bool isImageSetValue() const { return m_classType == ImageSetClass; }
81#endif
82    bool isImageValue() const { return m_classType == ImageClass; }
83    bool isImplicitInitialValue() const;
84    bool isInheritedValue() const { return m_classType == InheritedClass; }
85    bool isInitialValue() const { return m_classType == InitialClass; }
86    bool isReflectValue() const { return m_classType == ReflectClass; }
87    bool isShadowValue() const { return m_classType == ShadowClass; }
88    bool isCubicBezierTimingFunctionValue() const { return m_classType == CubicBezierTimingFunctionClass; }
89    bool isLinearTimingFunctionValue() const { return m_classType == LinearTimingFunctionClass; }
90    bool isStepsTimingFunctionValue() const { return m_classType == StepsTimingFunctionClass; }
91    bool isWebKitCSSTransformValue() const { return m_classType == WebKitCSSTransformClass; }
92    bool isCSSLineBoxContainValue() const { return m_classType == LineBoxContainClass; }
93    bool isCalculationValue() const {return m_classType == CalculationClass; }
94#if ENABLE(CSS_FILTERS)
95    bool isWebKitCSSFilterValue() const { return m_classType == WebKitCSSFilterClass; }
96#if ENABLE(CSS_SHADERS)
97    bool isWebKitCSSArrayFunctionValue() const { return m_classType == WebKitCSSArrayFunctionValueClass; }
98    bool isWebKitCSSMatFunctionValue() const { return m_classType == WebKitCSSMatFunctionValueClass; }
99    bool isWebKitCSSMixFunctionValue() const { return m_classType == WebKitCSSMixFunctionValueClass; }
100    bool isWebKitCSSShaderValue() const { return m_classType == WebKitCSSShaderClass; }
101#endif
102#endif // ENABLE(CSS_FILTERS)
103#if ENABLE(CSS_VARIABLES)
104    bool isVariableValue() const { return m_classType == VariableClass; }
105#endif
106#if ENABLE(SVG)
107    bool isSVGColor() const { return m_classType == SVGColorClass || m_classType == SVGPaintClass; }
108    bool isSVGPaint() const { return m_classType == SVGPaintClass; }
109    bool isWebKitCSSSVGDocumentValue() const { return m_classType == WebKitCSSSVGDocumentClass; }
110#endif
111
112    bool isCSSOMSafe() const { return m_isCSSOMSafe; }
113    bool isSubtypeExposedToCSSOM() const
114    {
115        return isPrimitiveValue()
116#if ENABLE(SVG)
117            || isSVGColor()
118#endif
119            || isValueList();
120    }
121
122    PassRefPtr<CSSValue> cloneForCSSOM() const;
123
124    void addSubresourceStyleURLs(ListHashSet<KURL>&, const StyleSheetContents*) const;
125
126    bool hasFailedOrCanceledSubresources() const;
127
128    bool equals(const CSSValue&) const;
129
130protected:
131
132    static const size_t ClassTypeBits = 6;
133    enum ClassType {
134        PrimitiveClass,
135
136        // Image classes.
137        ImageClass,
138        CursorImageClass,
139
140        // Image generator classes.
141        CanvasClass,
142        CrossfadeClass,
143        LinearGradientClass,
144        RadialGradientClass,
145
146        // Timing function classes.
147        CubicBezierTimingFunctionClass,
148        LinearTimingFunctionClass,
149        StepsTimingFunctionClass,
150
151        // Other class types.
152        AspectRatioClass,
153        BorderImageSliceClass,
154        FontFeatureClass,
155        FontClass,
156        FontFaceSrcClass,
157        FunctionClass,
158
159        InheritedClass,
160        InitialClass,
161
162        ReflectClass,
163        ShadowClass,
164        UnicodeRangeClass,
165        LineBoxContainClass,
166        CalculationClass,
167#if ENABLE(CSS_FILTERS) && ENABLE(CSS_SHADERS)
168        WebKitCSSShaderClass,
169#endif
170#if ENABLE(CSS_VARIABLES)
171        VariableClass,
172#endif
173#if ENABLE(SVG)
174        SVGColorClass,
175        SVGPaintClass,
176        WebKitCSSSVGDocumentClass,
177#endif
178
179        // List class types must appear after ValueListClass.
180        ValueListClass,
181#if ENABLE(CSS_IMAGE_SET)
182        ImageSetClass,
183#endif
184#if ENABLE(CSS_FILTERS)
185        WebKitCSSFilterClass,
186#if ENABLE(CSS_SHADERS)
187        WebKitCSSArrayFunctionValueClass,
188        WebKitCSSMatFunctionValueClass,
189        WebKitCSSMixFunctionValueClass,
190#endif
191#endif
192        WebKitCSSTransformClass,
193        // Do not append non-list class types here.
194    };
195
196    static const size_t ValueListSeparatorBits = 2;
197    enum ValueListSeparator {
198        SpaceSeparator,
199        CommaSeparator,
200        SlashSeparator
201    };
202
203    ClassType classType() const { return static_cast<ClassType>(m_classType); }
204
205    explicit CSSValue(ClassType classType, bool isCSSOMSafe = false)
206        : m_isCSSOMSafe(isCSSOMSafe)
207        , m_isTextClone(false)
208        , m_primitiveUnitType(0)
209        , m_hasCachedCSSText(false)
210        , m_isQuirkValue(false)
211        , m_valueListSeparator(SpaceSeparator)
212        , m_classType(classType)
213    {
214    }
215
216    // NOTE: This class is non-virtual for memory and performance reasons.
217    // Don't go making it virtual again unless you know exactly what you're doing!
218
219    ~CSSValue() { }
220
221private:
222    void destroy();
223
224protected:
225    unsigned m_isCSSOMSafe : 1;
226    unsigned m_isTextClone : 1;
227    // The bits in this section are only used by specific subclasses but kept here
228    // to maximize struct packing.
229
230    // CSSPrimitiveValue bits:
231    unsigned m_primitiveUnitType : 7; // CSSPrimitiveValue::UnitTypes
232    mutable unsigned m_hasCachedCSSText : 1;
233    unsigned m_isQuirkValue : 1;
234
235    unsigned m_valueListSeparator : ValueListSeparatorBits;
236
237private:
238    unsigned m_classType : ClassTypeBits; // ClassType
239};
240
241template<typename CSSValueType>
242inline bool compareCSSValueVector(const Vector<RefPtr<CSSValueType> >& firstVector, const Vector<RefPtr<CSSValueType> >& secondVector)
243{
244    size_t size = firstVector.size();
245    if (size != secondVector.size())
246        return false;
247
248    for (size_t i = 0; i < size; i++) {
249        const RefPtr<CSSValueType>& firstPtr = firstVector[i];
250        const RefPtr<CSSValueType>& secondPtr = secondVector[i];
251        if (firstPtr == secondPtr || (firstPtr && secondPtr && firstPtr->equals(*secondPtr)))
252            continue;
253        return false;
254    }
255    return true;
256}
257
258template<typename CSSValueType>
259inline bool compareCSSValuePtr(const RefPtr<CSSValueType>& first, const RefPtr<CSSValueType>& second)
260{
261    return first ? second && first->equals(*second) : !second;
262}
263
264} // namespace WebCore
265
266#endif // CSSValue_h
267