Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * (C) 1999-2003 Lars Knoll (knoll@kde.org) | 2 * (C) 1999-2003 Lars Knoll (knoll@kde.org) |
| 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. | 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. |
| 4 * | 4 * |
| 5 * This library is free software; you can redistribute it and/or | 5 * This library is free software; you can redistribute it and/or |
| 6 * modify it under the terms of the GNU Library General Public | 6 * modify it under the terms of the GNU Library General Public |
| 7 * License as published by the Free Software Foundation; either | 7 * License as published by the Free Software Foundation; either |
| 8 * version 2 of the License, or (at your option) any later version. | 8 * version 2 of the License, or (at your option) any later version. |
| 9 * | 9 * |
| 10 * This library is distributed in the hope that it will be useful, | 10 * This library is distributed in the hope that it will be useful, |
| 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 13 * Library General Public License for more details. | 13 * Library General Public License for more details. |
| 14 * | 14 * |
| 15 * You should have received a copy of the GNU Library General Public License | 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 | 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, | 17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| 18 * Boston, MA 02110-1301, USA. | 18 * Boston, MA 02110-1301, USA. |
| 19 */ | 19 */ |
| 20 | 20 |
| 21 #ifndef CSSValue_h | 21 #ifndef CSSValue_h |
| 22 #define CSSValue_h | 22 #define CSSValue_h |
| 23 | 23 |
| 24 #include "core/CoreExport.h" | 24 #include "core/CoreExport.h" |
| 25 #include "core/css/CSSValueObject.h" | |
| 25 #include "platform/heap/Handle.h" | 26 #include "platform/heap/Handle.h" |
| 26 #include "platform/weborigin/KURL.h" | |
| 27 #include "wtf/HashMap.h" | |
| 28 #include "wtf/ListHashSet.h" | |
| 29 #include "wtf/RefCounted.h" | 27 #include "wtf/RefCounted.h" |
| 30 #include "wtf/RefPtr.h" | 28 #include "wtf/RefPtr.h" |
| 31 | 29 |
| 32 namespace blink { | 30 namespace blink { |
| 33 | 31 |
| 34 class CORE_EXPORT CSSValue : public RefCountedWillBeGarbageCollectedFinalized<CS SValue> { | 32 // A non-nullable container for CSSValueObject. Takes ownership of the passed |
| 33 // CSSValueObject. | |
| 34 class CORE_EXPORT CSSValue { | |
| 35 ALLOW_ONLY_INLINE_ALLOCATION(); | |
| 36 friend class NullableCSSValue; | |
| 35 public: | 37 public: |
| 36 #if ENABLE(OILPAN) | 38 // Not explicit to allow for casting. |
| 37 // Override operator new to allocate CSSValue subtype objects onto | 39 CSSValue(const CSSValueObject& cssValueObject) |
| 38 // a dedicated heap. | 40 : m_data(const_cast<CSSValueObject*>(&cssValueObject)) |
| 39 GC_PLUGIN_IGNORE("crbug.com/443854") | 41 { |
| 40 void* operator new(size_t size) | 42 ASSERT(m_data); |
| 41 { | 43 ref(); |
| 42 return allocateObject(size); | 44 } |
| 43 } | 45 |
| 44 static void* allocateObject(size_t size) | 46 // TODO(sashab): Remove these; construction should only be available with |
| 45 { | 47 // CSSValueObject&. |
| 46 ThreadState* state = ThreadStateFor<ThreadingTrait<CSSValue>::Affinity>: :state(); | 48 template<class T> CSSValue(PassRefPtrWillBeRawPtr<T> cssValueObject) |
| 47 return Heap::allocateOnHeapIndex(state, size, CSSValueHeapIndex, GCInfoT rait<CSSValue>::index()); | 49 : m_data(cssValueObject.leakRef()) |
| 48 } | 50 { |
| 49 #else | 51 static_assert(WTF::IsSubclass<T, CSSValueObject>::value, "Parameter must be a container for CSSValueObject"); |
| 50 // Override RefCounted's deref() to ensure operator delete is called on | 52 ASSERT(m_data); |
| 51 // the appropriate subclass type. | 53 } |
| 52 void deref() | 54 |
| 53 { | 55 #if !ENABLE(OILPAN) |
| 54 if (derefBase()) | 56 template<class T> CSSValue(RefPtrWillBeRawPtr<T> cssValueObject) |
| 55 destroy(); | 57 : m_data(cssValueObject.release().leakRef()) |
| 56 } | 58 { |
| 57 #endif // !ENABLE(OILPAN) | 59 static_assert(WTF::IsSubclass<T, CSSValueObject>::value, "Parameter must be a container for CSSValueObject"); |
| 58 | 60 ASSERT(m_data); |
| 59 String cssText() const; | 61 } |
| 60 | 62 #endif |
| 61 bool isPrimitiveValue() const { return m_classType == PrimitiveClass; } | 63 |
| 62 bool isValueList() const { return m_classType >= ValueListClass; } | 64 CSSValue(const CSSValue& cssValue) |
| 63 | 65 : m_data(cssValue.m_data) |
| 64 bool isBaseValueList() const { return m_classType == ValueListClass; } | 66 { |
| 65 | 67 ref(); |
| 66 bool isBorderImageSliceValue() const { return m_classType == BorderImageSlic eClass; } | 68 } |
| 67 bool isCanvasValue() const { return m_classType == CanvasClass; } | 69 |
| 68 bool isCursorImageValue() const { return m_classType == CursorImageClass; } | 70 ~CSSValue() |
| 69 bool isCrossfadeValue() const { return m_classType == CrossfadeClass; } | 71 { |
| 70 bool isFontFeatureValue() const { return m_classType == FontFeatureClass; } | 72 deref(); |
| 71 bool isFontFaceSrcValue() const { return m_classType == FontFaceSrcClass; } | 73 } |
| 72 bool isFunctionValue() const { return m_classType == FunctionClass; } | 74 |
| 73 bool isImageGeneratorValue() const { return m_classType >= CanvasClass && m_ classType <= RadialGradientClass; } | 75 CSSValue& operator=(const CSSValue& rhs) |
| 74 bool isGradientValue() const { return m_classType >= LinearGradientClass && m_classType <= RadialGradientClass; } | 76 { |
| 75 bool isImageSetValue() const { return m_classType == ImageSetClass; } | 77 rhs.ref(); |
| 76 bool isImageValue() const { return m_classType == ImageClass; } | 78 deref(); |
| 77 bool isImplicitInitialValue() const; | 79 m_data = rhs.m_data; |
| 78 bool isInheritedValue() const { return m_classType == InheritedClass; } | 80 return *this; |
| 79 bool isInitialValue() const { return m_classType == InitialClass; } | 81 } |
| 80 bool isUnsetValue() const { return m_classType == UnsetClass; } | 82 |
| 81 bool isCSSWideKeyword() const { return m_classType >= InheritedClass && m_cl assType <= UnsetClass; } | 83 bool operator==(const CSSValue& other) const |
| 82 bool isLinearGradientValue() const { return m_classType == LinearGradientCla ss; } | 84 { |
| 83 bool isPathValue() const { return m_classType == PathClass; } | 85 return m_data->equals(*other.m_data); |
| 84 bool isRadialGradientValue() const { return m_classType == RadialGradientCla ss; } | 86 } |
| 85 bool isReflectValue() const { return m_classType == ReflectClass; } | 87 |
| 86 bool isShadowValue() const { return m_classType == ShadowClass; } | 88 // TODO: Remove this and update callsites to use operator== instead. |
| 87 bool isCubicBezierTimingFunctionValue() const { return m_classType == CubicB ezierTimingFunctionClass; } | 89 bool equals(const CSSValue& other) const |
| 88 bool isStepsTimingFunctionValue() const { return m_classType == StepsTimingF unctionClass; } | 90 { |
| 89 bool isLineBoxContainValue() const { return m_classType == LineBoxContainCla ss; } | 91 return m_data->equals(*other.m_data); |
| 90 bool isCalcValue() const {return m_classType == CalculationClass; } | 92 } |
| 91 bool isGridTemplateAreasValue() const { return m_classType == GridTemplateAr easClass; } | 93 |
| 92 bool isSVGDocumentValue() const { return m_classType == CSSSVGDocumentClass; } | 94 bool ptrEquals(const CSSValue& other) const |
| 93 bool isContentDistributionValue() const { return m_classType == CSSContentDi stributionClass; } | 95 { |
| 94 bool isUnicodeRangeValue() const { return m_classType == UnicodeRangeClass; } | 96 return m_data == other.m_data; |
| 95 bool isGridLineNamesValue() const { return m_classType == GridLineNamesClass ; } | 97 } |
| 96 | 98 |
| 97 bool hasFailedOrCanceledSubresources() const; | 99 // Methods that proxy to CSSValueObject. |
| 98 | 100 String cssText() const { return m_data->cssText(); } |
| 99 bool equals(const CSSValue&) const; | 101 bool hasFailedOrCanceledSubresources() const { return m_data->hasFailedOrCan celedSubresources(); }; |
| 100 | 102 bool isPrimitiveValue() const { return m_data->isPrimitiveValue(); } |
| 101 void finalizeGarbageCollectedObject(); | 103 bool isValueList() const { return m_data->isValueList(); } |
| 102 DEFINE_INLINE_TRACE_AFTER_DISPATCH() { } | 104 bool isBaseValueList() const { return m_data->isBaseValueList(); } |
| 105 bool isBorderImageSliceValue() const { return m_data->isBorderImageSliceValu e(); } | |
| 106 bool isCanvasValue() const { return m_data->isCanvasValue(); } | |
| 107 bool isCursorImageValue() const { return m_data->isCursorImageValue(); } | |
| 108 bool isCrossfadeValue() const { return m_data->isCrossfadeValue(); } | |
| 109 bool isFontFeatureValue() const { return m_data->isFontFeatureValue(); } | |
| 110 bool isFontFaceSrcValue() const { return m_data->isFontFaceSrcValue(); } | |
| 111 bool isFunctionValue() const { return m_data->isFunctionValue(); } | |
| 112 bool isImageGeneratorValue() const { return m_data->isImageGeneratorValue(); } | |
| 113 bool isGradientValue() const { return m_data->isGradientValue(); } | |
| 114 bool isImageSetValue() const { return m_data->isImageSetValue(); } | |
| 115 bool isImageValue() const { return m_data->isImageValue(); } | |
| 116 bool isImplicitInitialValue() const { return m_data->isImplicitInitialValue( ); }; | |
| 117 bool isInheritedValue() const { return m_data->isInheritedValue(); }; | |
| 118 bool isInitialValue() const { return m_data->isInitialValue(); }; | |
| 119 bool isUnsetValue() const { return m_data->isUnsetValue(); }; | |
| 120 bool isCSSWideKeyword() const { return m_data->isCSSWideKeyword(); }; | |
| 121 bool isLinearGradientValue() const { return m_data->isLinearGradientValue(); }; | |
| 122 bool isPathValue() const { return m_data->isPathValue(); }; | |
| 123 bool isRadialGradientValue() const { return m_data->isRadialGradientValue(); }; | |
| 124 bool isReflectValue() const { return m_data->isReflectValue(); }; | |
| 125 bool isShadowValue() const { return m_data->isShadowValue(); }; | |
| 126 bool isCubicBezierTimingFunctionValue() const { return m_data->isCubicBezier TimingFunctionValue(); }; | |
| 127 bool isStepsTimingFunctionValue() const { return m_data->isStepsTimingFuncti onValue(); }; | |
| 128 bool isLineBoxContainValue() const { return m_data->isLineBoxContainValue(); }; | |
| 129 bool isCalcValue() const { return m_data->isCalcValue(); }; | |
| 130 bool isGridTemplateAreasValue() const { return m_data->isGridTemplateAreasVa lue(); }; | |
| 131 bool isSVGDocumentValue() const { return m_data->isSVGDocumentValue(); }; | |
| 132 bool isContentDistributionValue() const { return m_data->isContentDistributi onValue(); }; | |
| 133 bool isUnicodeRangeValue() const { return m_data->isUnicodeRangeValue(); }; | |
| 134 bool isGridLineNamesValue() const { return m_data->isGridLineNamesValue(); } ; | |
| 135 | |
| 103 DECLARE_TRACE(); | 136 DECLARE_TRACE(); |
| 104 | 137 |
| 105 // ~CSSValue should be public, because non-public ~CSSValue causes C2248 | 138 private: |
| 106 // error: 'blink::CSSValue::~CSSValue' : cannot access protected member | 139 // To ensure these are never called. Without this, the compiler may accident ally call |
| 107 // declared in class 'blink::CSSValue' when compiling | 140 // CSSValue(nullptr) with the CSSValueObject* constructor to store an interm ediate value. |
| 108 // 'source\wtf\refcounted.h' by using msvc. | 141 // e.g. NullableCSSValue n = x ? CSSValue(foo) : nullptr; |
| 109 ~CSSValue() { } | 142 CSSValue() = delete; |
| 110 | 143 CSSValue(std::nullptr_t) = delete; |
| 111 protected: | 144 |
| 112 | 145 void ref() const |
| 113 static const size_t ClassTypeBits = 6; | 146 { |
| 114 enum ClassType { | 147 #if !ENABLE(OILPAN) |
| 115 PrimitiveClass, | 148 if (m_data) |
| 116 | 149 m_data->ref(); |
| 117 // Image classes. | 150 #endif |
| 118 ImageClass, | 151 } |
| 119 CursorImageClass, | 152 |
| 120 | 153 void deref() const |
| 121 // Image generator classes. | 154 { |
| 122 CanvasClass, | 155 #if !ENABLE(OILPAN) |
| 123 CrossfadeClass, | 156 if (m_data) |
| 124 LinearGradientClass, | 157 m_data->deref(); |
| 125 RadialGradientClass, | 158 #endif |
| 126 | 159 } |
| 127 // Timing function classes. | 160 |
| 128 CubicBezierTimingFunctionClass, | 161 CSSValueObject* m_data; |
|
haraken
2015/06/11 02:48:53
You need to use RawPtrWillBeMember<CSSValueObject>
sashab
2015/06/11 23:05:35
I wasn't compiling with blink_gc_plugin=1, so mayb
| |
| 129 StepsTimingFunctionClass, | 162 }; |
| 130 | 163 |
| 131 // Other class types. | 164 // A nullable container for CSSValueObject. Contents are the same as CSSValue. |
| 132 BorderImageSliceClass, | 165 // Behavior is similar to a CSSValue*. |
| 133 FontFeatureClass, | 166 class CORE_EXPORT NullableCSSValue { |
| 134 FontFaceSrcClass, | 167 ALLOW_ONLY_INLINE_ALLOCATION(); |
| 135 | 168 public: |
| 136 InheritedClass, | 169 // Not explicit to allow for casting. |
| 137 InitialClass, | 170 NullableCSSValue() |
| 138 UnsetClass, | 171 : m_data(nullptr) |
| 139 | 172 { |
| 140 ReflectClass, | 173 } |
| 141 ShadowClass, | 174 |
| 142 UnicodeRangeClass, | 175 NullableCSSValue(const CSSValueObject* cssValueObject) |
| 143 LineBoxContainClass, | 176 : m_data(const_cast<CSSValueObject*>(cssValueObject)) |
| 144 CalculationClass, | 177 { |
| 145 GridTemplateAreasClass, | 178 ref(); |
| 146 PathClass, | 179 } |
| 147 | 180 |
| 148 // SVG classes. | 181 NullableCSSValue(const CSSValueObject& cssValueObject) |
| 149 CSSSVGDocumentClass, | 182 : m_data(const_cast<CSSValueObject*>(&cssValueObject)) |
| 150 | 183 { |
| 151 CSSContentDistributionClass, | 184 ref(); |
| 152 | 185 } |
| 153 // List class types must appear after ValueListClass. | 186 |
| 154 ValueListClass, | 187 // TODO(sashab): Remove these; construction should only be available with |
| 155 FunctionClass, | 188 // CSSValueObject& or CSSValueObject*. |
| 156 ImageSetClass, | 189 template <class T> NullableCSSValue(PassRefPtrWillBeRawPtr<T> cssValueObject ) |
| 157 GridLineNamesClass, | 190 : m_data(cssValueObject.leakRef()) |
| 158 // Do not append non-list class types here. | 191 { |
| 192 static_assert(WTF::IsSubclass<T, CSSValueObject>::value, "Parameter must be a container for CSSValueObject"); | |
| 193 } | |
| 194 | |
| 195 #if !ENABLE(OILPAN) | |
| 196 template <class T> NullableCSSValue(RefPtrWillBeRawPtr<T> cssValueObject) | |
| 197 : m_data(cssValueObject.release().leakRef()) | |
| 198 { | |
| 199 static_assert(WTF::IsSubclass<T, CSSValueObject>::value, "Parameter must be a container for CSSValueObject"); | |
| 200 } | |
| 201 #endif | |
| 202 | |
| 203 NullableCSSValue(const NullableCSSValue& cssValue) | |
| 204 : m_data(cssValue.m_data) | |
| 205 { | |
| 206 ref(); | |
| 207 } | |
| 208 | |
| 209 NullableCSSValue(const CSSValue& cssValue) | |
| 210 : m_data(cssValue.m_data) | |
| 211 { | |
| 212 ref(); | |
| 213 } | |
| 214 | |
| 215 ~NullableCSSValue() | |
| 216 { | |
| 217 deref(); | |
| 159 }; | 218 }; |
| 160 | 219 |
| 161 static const size_t ValueListSeparatorBits = 2; | 220 operator bool() const |
| 162 enum ValueListSeparator { | 221 { |
| 163 SpaceSeparator, | 222 return m_data; |
| 164 CommaSeparator, | 223 } |
| 165 SlashSeparator | 224 |
| 166 }; | 225 NullableCSSValue& operator=(const NullableCSSValue& rhs) |
| 167 | 226 { |
| 168 ClassType classType() const { return static_cast<ClassType>(m_classType); } | 227 rhs.ref(); |
| 169 | 228 deref(); |
| 170 explicit CSSValue(ClassType classType) | 229 m_data = rhs.m_data; |
| 171 : m_primitiveUnitType(0) | 230 return *this; |
| 172 , m_hasCachedCSSText(false) | 231 } |
| 173 , m_isQuirkValue(false) | 232 |
| 174 , m_valueListSeparator(SpaceSeparator) | 233 bool operator==(const NullableCSSValue& rhs) |
| 175 , m_classType(classType) | 234 { |
| 176 { | 235 return m_data ? rhs.m_data && m_data->equals(*rhs.m_data) : bool(rhs.m_d ata); |
| 177 } | 236 } |
| 178 | 237 |
| 179 // NOTE: This class is non-virtual for memory and performance reasons. | 238 bool operator!=(const NullableCSSValue& rhs) |
| 180 // Don't go making it virtual again unless you know exactly what you're doin g! | 239 { |
| 240 return !(*this == rhs); | |
| 241 } | |
| 242 | |
| 243 CSSValue& operator*() | |
| 244 { | |
| 245 ASSERT(m_data); | |
| 246 // reinterpret_casts used to avoid ref-churn. | |
| 247 return *reinterpret_cast<CSSValue*>(this); | |
| 248 } | |
| 249 | |
| 250 const CSSValue& operator*() const | |
| 251 { | |
| 252 ASSERT(m_data); | |
| 253 return *reinterpret_cast<const CSSValue*>(this); | |
| 254 } | |
| 255 | |
| 256 CSSValue* operator->() | |
| 257 { | |
| 258 ASSERT(m_data); | |
| 259 return reinterpret_cast<CSSValue*>(this); | |
| 260 } | |
| 261 | |
| 262 const CSSValue* operator->() const | |
| 263 { | |
| 264 ASSERT(m_data); | |
| 265 return reinterpret_cast<const CSSValue*>(this); | |
| 266 } | |
| 267 | |
| 268 void swap(NullableCSSValue& rhs) | |
| 269 { | |
| 270 std::swap(this->m_data, rhs.m_data); | |
| 271 } | |
| 272 | |
| 273 DECLARE_TRACE(); | |
| 181 | 274 |
| 182 private: | 275 private: |
| 183 void destroy(); | 276 void ref() const |
| 184 | 277 { |
| 185 protected: | 278 #if !ENABLE(OILPAN) |
| 186 // The bits in this section are only used by specific subclasses but kept he re | 279 if (m_data) |
| 187 // to maximize struct packing. | 280 m_data->ref(); |
| 188 | 281 #endif |
| 189 // CSSPrimitiveValue bits: | 282 } |
| 190 unsigned m_primitiveUnitType : 7; // CSSPrimitiveValue::UnitType | 283 |
| 191 mutable unsigned m_hasCachedCSSText : 1; | 284 void deref() const |
| 192 unsigned m_isQuirkValue : 1; | 285 { |
| 193 | 286 #if !ENABLE(OILPAN) |
| 194 unsigned m_valueListSeparator : ValueListSeparatorBits; | 287 if (m_data) |
| 195 | 288 m_data->deref(); |
| 196 private: | 289 #endif |
| 197 unsigned m_classType : ClassTypeBits; // ClassType | 290 } |
| 291 | |
| 292 CSSValueObject* m_data; | |
|
haraken
2015/06/11 02:48:53
Ditto. You need to use RawPtrWillBeMember<CSSValue
sashab
2015/06/11 23:05:35
Done.
| |
| 198 }; | 293 }; |
| 199 | 294 |
| 200 template<typename CSSValueType, size_t inlineCapacity> | 295 static_assert(sizeof(CSSValue) == sizeof(void*), "CSSValue should be pointer-siz ed"); |
| 201 inline bool compareCSSValueVector(const WillBeHeapVector<RefPtrWillBeMember<CSSV alueType>, inlineCapacity>& firstVector, const WillBeHeapVector<RefPtrWillBeMemb er<CSSValueType>, inlineCapacity>& secondVector) | 296 static_assert(sizeof(NullableCSSValue) == sizeof(void*), "CSSValue should be poi nter-sized"); |
| 297 static_assert(sizeof(CSSValue) == sizeof(NullableCSSValue), "Both CSSValue conta iners must contain the same data"); | |
| 298 | |
| 299 template<size_t inlineCapacity> | |
| 300 inline bool compareCSSValueVector(const WillBeHeapVector<CSSValue, inlineCapacit y>& firstVector, const WillBeHeapVector<CSSValue, inlineCapacity>& secondVector) | |
| 202 { | 301 { |
| 203 size_t size = firstVector.size(); | 302 size_t size = firstVector.size(); |
| 204 if (size != secondVector.size()) | 303 if (size != secondVector.size()) |
| 205 return false; | 304 return false; |
| 206 | 305 |
| 207 for (size_t i = 0; i < size; i++) { | 306 for (size_t i = 0; i < size; i++) { |
| 208 const RefPtrWillBeMember<CSSValueType>& firstPtr = firstVector[i]; | 307 const CSSValue& firstPtr = firstVector[i]; |
| 209 const RefPtrWillBeMember<CSSValueType>& secondPtr = secondVector[i]; | 308 const CSSValue& secondPtr = secondVector[i]; |
| 210 if (firstPtr == secondPtr || (firstPtr && secondPtr && firstPtr->equals( *secondPtr))) | 309 if (firstPtr.ptrEquals(secondPtr) || firstPtr.equals(secondPtr)) |
| 211 continue; | 310 continue; |
| 212 return false; | 311 return false; |
| 213 } | 312 } |
| 214 return true; | 313 return true; |
| 215 } | 314 } |
| 216 | 315 |
| 217 template<typename CSSValueType> | |
| 218 inline bool compareCSSValuePtr(const RefPtr<CSSValueType>& first, const RefPtr<C SSValueType>& second) | |
| 219 { | |
| 220 return first ? second && first->equals(*second) : !second; | |
| 221 } | |
| 222 | |
| 223 template<typename CSSValueType> | |
| 224 inline bool compareCSSValuePtr(const RawPtr<CSSValueType>& first, const RawPtr<C SSValueType>& second) | |
| 225 { | |
| 226 return first ? second && first->equals(*second) : !second; | |
| 227 } | |
| 228 | |
| 229 template<typename CSSValueType> | |
| 230 inline bool compareCSSValuePtr(const Member<CSSValueType>& first, const Member<C SSValueType>& second) | |
| 231 { | |
| 232 return first ? second && first->equals(*second) : !second; | |
| 233 } | |
| 234 | |
| 235 #define DEFINE_CSS_VALUE_TYPE_CASTS(thisType, predicate) \ | 316 #define DEFINE_CSS_VALUE_TYPE_CASTS(thisType, predicate) \ |
| 236 DEFINE_TYPE_CASTS(thisType, CSSValue, value, value->predicate, value.predica te) | 317 DEFINE_TYPE_CASTS(thisType, CSSValueObject, value, value->predicate, value.p redicate); \ |
| 318 inline thisType& to##thisType(CSSValue value) \ | |
| 319 { \ | |
| 320 ASSERT_WITH_SECURITY_IMPLICATION(value.predicate); \ | |
| 321 return **reinterpret_cast<thisType**>(&value); \ | |
| 322 } \ | |
| 323 inline thisType* to##thisType(NullableCSSValue value) \ | |
| 324 { \ | |
| 325 if (!value) \ | |
| 326 return nullptr; \ | |
| 327 ASSERT_WITH_SECURITY_IMPLICATION(value->predicate); \ | |
| 328 return *reinterpret_cast<thisType**>(&value); \ | |
| 329 } | |
| 237 | 330 |
| 238 } // namespace blink | 331 } // namespace blink |
| 239 | 332 |
| 240 #endif // CSSValue_h | 333 #endif // CSSValue_h |
| OLD | NEW |