1 /* 2 * (C) 1999-2003 Lars Knoll (knoll (at) 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) 60 void deref() 61 { 62 if (derefBase()) 63 destroy(); 64 } 65 #endif // !ENABLE(OILPAN) 66 67 Type cssValueType() const; 68 69 String cssText() const; 70 void setCSSText(const String&, ExceptionState&) { } // FIXME: Not implemented. 71 72 bool isPrimitiveValue() const { return m_classType == PrimitiveClass; } 73 bool isValueList() const { return m_classType >= ValueListClass; } 74 75 bool isBaseValueList() const { return m_classType == ValueListClass; } 76 77 bool isAspectRatioValue() const { return m_classType == AspectRatioClass; } 78 bool isBorderImageSliceValue() const { return m_classType == BorderImageSliceClass; } 79 bool isCanvasValue() const { return m_classType == CanvasClass; } 80 bool isCursorImageValue() const { return m_classType == CursorImageClass; } 81 bool isCrossfadeValue() const { return m_classType == CrossfadeClass; } 82 bool isFontFeatureValue() const { return m_classType == FontFeatureClass; } 83 bool isFontValue() const { return m_classType == FontClass; } 84 bool isFontFaceSrcValue() const { return m_classType == FontFaceSrcClass; } 85 bool isFunctionValue() const { return m_classType == FunctionClass; } 86 bool isImageGeneratorValue() const { return m_classType >= CanvasClass && m_classType <= RadialGradientClass; } 87 bool isGradientValue() const { return m_classType >= LinearGradientClass && m_classType <= RadialGradientClass; } 88 bool isImageSetValue() const { return m_classType == ImageSetClass; } 89 bool isImageValue() const { return m_classType == ImageClass; } 90 bool isImplicitInitialValue() const; 91 bool isInheritedValue() const { return m_classType == InheritedClass; } 92 bool isInitialValue() const { return m_classType == InitialClass; } 93 bool isLinearGradientValue() const { return m_classType == LinearGradientClass; } 94 bool isRadialGradientValue() const { return m_classType == RadialGradientClass; } 95 bool isReflectValue() const { return m_classType == ReflectClass; } 96 bool isShadowValue() const { return m_classType == ShadowClass; } 97 bool isTextCloneCSSValue() const { return m_isTextClone; } 98 bool isCubicBezierTimingFunctionValue() const { return m_classType == CubicBezierTimingFunctionClass; } 99 bool isStepsTimingFunctionValue() const { return m_classType == StepsTimingFunctionClass; } 100 bool isTransformValue() const { return m_classType == CSSTransformClass; } 101 bool isLineBoxContainValue() const { return m_classType == LineBoxContainClass; } 102 bool isCalcValue() const {return m_classType == CalculationClass; } 103 bool isFilterValue() const { return m_classType == CSSFilterClass; } 104 bool isGridTemplateAreasValue() const { return m_classType == GridTemplateAreasClass; } 105 bool isSVGDocumentValue() const { return m_classType == CSSSVGDocumentClass; } 106 bool isUnicodeRangeValue() const { return m_classType == UnicodeRangeClass; } 107 bool isGridLineNamesValue() const { return m_classType == GridLineNamesClass; } 108 109 bool isCSSOMSafe() const { return m_isCSSOMSafe; } 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(); 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 182 ClassType classType() const { return static_cast<ClassType>(m_classType); } 183 184 explicit CSSValue(ClassType classType, bool isCSSOMSafe = false) 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 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> 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> 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> 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> 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