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 "URLHash.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 63 bool isPrimitiveValue() const { return m_classType == PrimitiveClass; } 64 bool isValueList() const { return m_classType >= ValueListClass; } 65 66 bool isBaseValueList() const { return m_classType == ValueListClass; } 67 68 69 bool isAspectRatioValue() const { return m_classType == AspectRatioClass; } 70 bool isBorderImageSliceValue() const { return m_classType == BorderImageSliceClass; } 71 bool isCanvasValue() const { return m_classType == CanvasClass; } 72 bool isCrossfadeValue() const { return m_classType == CrossfadeClass; } 73 bool isCursorImageValue() const { return m_classType == CursorImageClass; } 74 bool isFunctionValue() const { return m_classType == FunctionClass; } 75 bool isFontFeatureValue() const { return m_classType == FontFeatureClass; } 76 bool isFontFaceSrcValue() const { return m_classType == FontFaceSrcClass; } 77 bool isFontValue() const { return m_classType == FontClass; } 78 bool isImageGeneratorValue() const { return m_classType >= CanvasClass && m_classType <= RadialGradientClass; } 79 bool isGradientValue() const { return m_classType >= LinearGradientClass && m_classType <= RadialGradientClass; } 80#if ENABLE(CSS_IMAGE_SET) 81 bool isImageSetValue() const { return m_classType == ImageSetClass; } 82#endif 83 bool isImageValue() const { return m_classType == ImageClass; } 84 bool isImplicitInitialValue() const; 85 bool isInheritedValue() const { return m_classType == InheritedClass; } 86 bool isInitialValue() const { return m_classType == InitialClass; } 87 bool isLinearGradientValue() const { return m_classType == LinearGradientClass; } 88 bool isRadialGradientValue() const { return m_classType == RadialGradientClass; } 89 bool isReflectValue() const { return m_classType == ReflectClass; } 90 bool isShadowValue() const { return m_classType == ShadowClass; } 91 bool isCubicBezierTimingFunctionValue() const { return m_classType == CubicBezierTimingFunctionClass; } 92 bool isStepsTimingFunctionValue() const { return m_classType == StepsTimingFunctionClass; } 93 bool isWebKitCSSTransformValue() const { return m_classType == WebKitCSSTransformClass; } 94 bool isLineBoxContainValue() const { return m_classType == LineBoxContainClass; } 95 bool isCalcValue() const {return m_classType == CalculationClass; } 96#if ENABLE(CSS_FILTERS) 97 bool isFilterImageValue() const { return m_classType == FilterImageClass; } 98 bool isWebKitCSSFilterValue() const { return m_classType == WebKitCSSFilterClass; } 99#endif // ENABLE(CSS_FILTERS) 100#if ENABLE(CSS_GRID_LAYOUT) 101 bool isGridTemplateAreasValue() const { return m_classType == GridTemplateAreasClass; } 102 bool isGridLineNamesValue() const { return m_classType == GridLineNamesClass; } 103#endif 104 bool isSVGColor() const { return m_classType == SVGColorClass || m_classType == SVGPaintClass; } 105 bool isSVGPaint() const { return m_classType == SVGPaintClass; } 106 bool isUnicodeRangeValue() const { return m_classType == UnicodeRangeClass; } 107 108 bool isCSSOMSafe() const { return m_isCSSOMSafe; } 109 bool isSubtypeExposedToCSSOM() const 110 { 111 return isPrimitiveValue() 112 || isSVGColor() 113 || isValueList(); 114 } 115 116 PassRefPtr<CSSValue> cloneForCSSOM() const; 117 118 void addSubresourceStyleURLs(ListHashSet<URL>&, const StyleSheetContents*) const; 119 120 bool hasFailedOrCanceledSubresources() const; 121 122 bool equals(const CSSValue&) const; 123 124protected: 125 126 static const size_t ClassTypeBits = 6; 127 enum ClassType { 128 PrimitiveClass, 129 130 // Image classes. 131 ImageClass, 132 CursorImageClass, 133 134 // Image generator classes. 135 CanvasClass, 136 CrossfadeClass, 137#if ENABLE(CSS_FILTERS) 138 FilterImageClass, 139#endif 140 LinearGradientClass, 141 RadialGradientClass, 142 143 // Timing function classes. 144 CubicBezierTimingFunctionClass, 145 StepsTimingFunctionClass, 146 147 // Other class types. 148 AspectRatioClass, 149 BorderImageSliceClass, 150 FontFeatureClass, 151 FontClass, 152 FontFaceSrcClass, 153 FunctionClass, 154 155 InheritedClass, 156 InitialClass, 157 158 ReflectClass, 159 ShadowClass, 160 UnicodeRangeClass, 161 LineBoxContainClass, 162 CalculationClass, 163#if ENABLE(CSS_GRID_LAYOUT) 164 GridTemplateAreasClass, 165#endif 166 SVGColorClass, 167 SVGPaintClass, 168 169 // List class types must appear after ValueListClass. 170 ValueListClass, 171#if ENABLE(CSS_IMAGE_SET) 172 ImageSetClass, 173#endif 174#if ENABLE(CSS_FILTERS) 175 WebKitCSSFilterClass, 176#endif 177 WebKitCSSTransformClass, 178#if ENABLE(CSS_GRID_LAYOUT) 179 GridLineNamesClass, 180#endif 181 // Do not append non-list class types here. 182 }; 183 184 static const size_t ValueListSeparatorBits = 2; 185 enum ValueListSeparator { 186 SpaceSeparator, 187 CommaSeparator, 188 SlashSeparator 189 }; 190 191 ClassType classType() const { return static_cast<ClassType>(m_classType); } 192 193 explicit CSSValue(ClassType classType, bool isCSSOMSafe = false) 194 : m_isCSSOMSafe(isCSSOMSafe) 195 , m_isTextClone(false) 196 , m_primitiveUnitType(0) 197 , m_hasCachedCSSText(false) 198 , m_isQuirkValue(false) 199 , m_valueListSeparator(SpaceSeparator) 200 , m_classType(classType) 201 { 202 } 203 204 // NOTE: This class is non-virtual for memory and performance reasons. 205 // Don't go making it virtual again unless you know exactly what you're doing! 206 207 ~CSSValue() { } 208 209private: 210 void destroy(); 211 212protected: 213 unsigned m_isCSSOMSafe : 1; 214 unsigned m_isTextClone : 1; 215 // The bits in this section are only used by specific subclasses but kept here 216 // to maximize struct packing. 217 218 // CSSPrimitiveValue bits: 219 unsigned m_primitiveUnitType : 7; // CSSPrimitiveValue::UnitTypes 220 mutable unsigned m_hasCachedCSSText : 1; 221 unsigned m_isQuirkValue : 1; 222 223 unsigned m_valueListSeparator : ValueListSeparatorBits; 224 225private: 226 unsigned m_classType : ClassTypeBits; // ClassType 227}; 228 229template<typename CSSValueType> 230inline bool compareCSSValueVector(const Vector<RefPtr<CSSValueType>>& firstVector, const Vector<RefPtr<CSSValueType>>& secondVector) 231{ 232 size_t size = firstVector.size(); 233 if (size != secondVector.size()) 234 return false; 235 236 for (size_t i = 0; i < size; i++) { 237 const RefPtr<CSSValueType>& firstPtr = firstVector[i]; 238 const RefPtr<CSSValueType>& secondPtr = secondVector[i]; 239 if (firstPtr == secondPtr || (firstPtr && secondPtr && firstPtr->equals(*secondPtr))) 240 continue; 241 return false; 242 } 243 return true; 244} 245 246template<typename CSSValueType> 247inline bool compareCSSValuePtr(const RefPtr<CSSValueType>& first, const RefPtr<CSSValueType>& second) 248{ 249 return first ? second && first->equals(*second) : !second; 250} 251 252template<typename CSSValueType> 253inline bool compareCSSValue(const Ref<CSSValueType>& first, const Ref<CSSValueType>& second) 254{ 255 return first.get().equals(second.get()); 256} 257 258#define CSS_VALUE_TYPE_CASTS(ToValueTypeName, predicate) \ 259 TYPE_CASTS_BASE(ToValueTypeName, CSSValue, value, value->predicate, value.predicate) 260 261} // namespace WebCore 262 263#endif // CSSValue_h 264