1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 /* Utilities for animation of computed style values */
7 
8 #ifndef mozilla_StyleAnimationValue_h_
9 #define mozilla_StyleAnimationValue_h_
10 
11 #include "mozilla/gfx/MatrixFwd.h"
12 #include "mozilla/UniquePtr.h"
13 #include "nsStringFwd.h"
14 #include "nsStringBuffer.h"
15 #include "nsCoord.h"
16 #include "nsColor.h"
17 #include "nsCSSProps.h"
18 #include "nsCSSValue.h"
19 #include "nsStyleCoord.h"
20 
21 class nsIFrame;
22 class nsStyleContext;
23 class gfx3DMatrix;
24 struct RawServoDeclarationBlock;
25 
26 namespace mozilla {
27 
28 namespace css {
29 class StyleRule;
30 } // namespace css
31 
32 namespace dom {
33 class Element;
34 } // namespace dom
35 
36 enum class CSSPseudoElementType : uint8_t;
37 struct PropertyStyleAnimationValuePair;
38 
39 /**
40  * Utility class to handle animated style values
41  */
42 class StyleAnimationValue {
43 public:
44   // Mathematical methods
45   // --------------------
46   /**
47    * Adds |aCount| copies of |aValueToAdd| to |aDest|.  The result of this
48    * addition is stored in aDest.
49    *
50    * Note that if |aCount| is 0, then |aDest| will be unchanged.  Also, if
51    * this method fails, then |aDest| will be unchanged.
52    *
53    * @param aDest       The value to add to.
54    * @param aValueToAdd The value to add.
55    * @param aCount      The number of times to add aValueToAdd.
56    * @return true on success, false on failure.
57    */
58   static MOZ_MUST_USE bool
Add(nsCSSPropertyID aProperty,StyleAnimationValue & aDest,const StyleAnimationValue & aValueToAdd,uint32_t aCount)59   Add(nsCSSPropertyID aProperty, StyleAnimationValue& aDest,
60       const StyleAnimationValue& aValueToAdd, uint32_t aCount) {
61     return AddWeighted(aProperty, 1.0, aDest, aCount, aValueToAdd, aDest);
62   }
63 
64   /**
65    * Calculates a measure of 'distance' between two colors.
66    *
67    * @param aStartColor The start of the interval for which the distance
68    *                    should be calculated.
69    * @param aEndColor   The end of the interval for which the distance
70    *                    should be calculated.
71    * @return the result of the calculation.
72    */
73   static double ComputeColorDistance(const css::RGBAColorData& aStartColor,
74                                      const css::RGBAColorData& aEndColor);
75 
76   /**
77    * Calculates a measure of 'distance' between two values.
78    *
79    * This measure of Distance is guaranteed to be proportional to
80    * portions passed to Interpolate, Add, or AddWeighted.  However, for
81    * some types of StyleAnimationValue it may not produce sensible results
82    * for paced animation.
83    *
84    * If this method succeeds, the returned distance value is guaranteed to be
85    * non-negative.
86    *
87    * @param aStartValue The start of the interval for which the distance
88    *                    should be calculated.
89    * @param aEndValue   The end of the interval for which the distance
90    *                    should be calculated.
91    * @param aStyleContext The style context to use for processing the
92    *                      translate part of transforms.
93    * @param aDistance   The result of the calculation.
94    * @return true on success, false on failure.
95    */
96   static MOZ_MUST_USE bool
97   ComputeDistance(nsCSSPropertyID aProperty,
98                   const StyleAnimationValue& aStartValue,
99                   const StyleAnimationValue& aEndValue,
100                   nsStyleContext* aStyleContext,
101                   double& aDistance);
102 
103   /**
104    * Calculates an interpolated value that is the specified |aPortion| between
105    * the two given values.
106    *
107    * This really just does the following calculation:
108    *   aResultValue = (1.0 - aPortion) * aStartValue + aPortion * aEndValue
109    *
110    * @param aStartValue The value defining the start of the interval of
111    *                    interpolation.
112    * @param aEndValue   The value defining the end of the interval of
113    *                    interpolation.
114    * @param aPortion    A number in the range [0.0, 1.0] defining the
115    *                    distance of the interpolated value in the interval.
116    * @param [out] aResultValue The resulting interpolated value.
117    * @return true on success, false on failure.
118    */
119   static MOZ_MUST_USE bool
Interpolate(nsCSSPropertyID aProperty,const StyleAnimationValue & aStartValue,const StyleAnimationValue & aEndValue,double aPortion,StyleAnimationValue & aResultValue)120   Interpolate(nsCSSPropertyID aProperty,
121               const StyleAnimationValue& aStartValue,
122               const StyleAnimationValue& aEndValue,
123               double aPortion,
124               StyleAnimationValue& aResultValue) {
125     return AddWeighted(aProperty, 1.0 - aPortion, aStartValue,
126                        aPortion, aEndValue, aResultValue);
127   }
128 
129   /**
130    * Does the calculation:
131    *   aResultValue = aCoeff1 * aValue1 + aCoeff2 * aValue2
132    *
133    * @param [out] aResultValue The resulting interpolated value.  May be
134    *                           the same as aValue1 or aValue2.
135    * @return true on success, false on failure.
136    *
137    * NOTE: Current callers always pass aCoeff1 and aCoeff2 >= 0.  They
138    * are currently permitted to be negative; however, if, as we add
139    * support more value types types, we find that this causes
140    * difficulty, we might change this to restrict them to being
141    * positive.
142    */
143   static MOZ_MUST_USE bool
144   AddWeighted(nsCSSPropertyID aProperty,
145               double aCoeff1, const StyleAnimationValue& aValue1,
146               double aCoeff2, const StyleAnimationValue& aValue2,
147               StyleAnimationValue& aResultValue);
148 
149   /**
150    * Accumulates |aValueToAccumulate| onto |aDest| |aCount| times.
151    * The result is stored in |aDest| on success.
152    *
153    * @param aDest              The base value to be accumulated.
154    * @param aValueToAccumulate The value to accumulate.
155    * @param aCount             The number of times to accumulate
156    *                           aValueToAccumulate.
157    * @return true on success, false on failure.
158    *
159    * NOTE: This function will work as a wrapper of StyleAnimationValue::Add()
160    * if |aProperty| isn't color or shadow or filter.  For these properties,
161    * this function may return a color value that at least one of its components
162    * has a value which is outside the range [0, 1] so that we can calculate
163    * plausible values as interpolation with the return value.
164    */
165   static MOZ_MUST_USE bool
166   Accumulate(nsCSSPropertyID aProperty, StyleAnimationValue& aDest,
167              const StyleAnimationValue& aValueToAccumulate,
168              uint64_t aCount);
169 
170   // Type-conversion methods
171   // -----------------------
172   /**
173    * Creates a computed value for the given specified value
174    * (property ID + string).  A style context is needed in case the
175    * specified value depends on inherited style or on the values of other
176    * properties.
177    *
178    * @param aProperty       The property whose value we're computing.
179    * @param aTargetElement  The content node to which our computed value is
180    *                        applicable. For pseudo-elements, this is the parent
181    *                        element to which the pseudo is attached, not the
182    *                        generated content node.
183    * @param aStyleContext   The style context used to compute values from the
184    *                        specified value. For pseudo-elements, this should
185    *                        be the style context corresponding to the pseudo
186    *                        element.
187    * @param aSpecifiedValue The specified value, from which we'll build our
188    *                        computed value.
189    * @param aUseSVGMode     A flag to indicate whether we should parse
190    *                        |aSpecifiedValue| in SVG mode.
191    * @param [out] aComputedValue The resulting computed value.
192    * @param [out] aIsContextSensitive
193    *                        Set to true if |aSpecifiedValue| may produce
194    *                        a different |aComputedValue| depending on other CSS
195    *                        properties on |aTargetElement| or its ancestors.
196    *                        false otherwise.
197    *                        Note that the operation of this method is
198    *                        significantly faster when |aIsContextSensitive| is
199    *                        nullptr.
200    * @return true on success, false on failure.
201    */
202   static MOZ_MUST_USE bool
203   ComputeValue(nsCSSPropertyID aProperty,
204                mozilla::dom::Element* aTargetElement,
205                nsStyleContext* aStyleContext,
206                const nsAString& aSpecifiedValue,
207                bool aUseSVGMode,
208                StyleAnimationValue& aComputedValue,
209                bool* aIsContextSensitive = nullptr);
210 
211   /**
212    * Like ComputeValue, but returns an array of StyleAnimationValues.
213    *
214    * On success, when aProperty is a longhand, aResult will have a single
215    * value in it.  When aProperty is a shorthand, aResult will be filled with
216    * values for all of aProperty's longhand components.  aEnabledState
217    * is used to filter the longhand components that will be appended
218    * to aResult.  On failure, aResult might still have partial results
219    * in it.
220    */
221   static MOZ_MUST_USE bool
222   ComputeValues(nsCSSPropertyID aProperty,
223                 mozilla::CSSEnabledState aEnabledState,
224                 mozilla::dom::Element* aTargetElement,
225                 nsStyleContext* aStyleContext,
226                 const nsAString& aSpecifiedValue,
227                 bool aUseSVGMode,
228                 nsTArray<PropertyStyleAnimationValuePair>& aResult);
229 
230   /**
231    * A variant on ComputeValues that takes an nsCSSValue as the specified
232    * value. Only longhand properties are supported.
233    */
234   static MOZ_MUST_USE bool
235   ComputeValues(nsCSSPropertyID aProperty,
236                 mozilla::CSSEnabledState aEnabledState,
237                 mozilla::dom::Element* aTargetElement,
238                 nsStyleContext* aStyleContext,
239                 const nsCSSValue& aSpecifiedValue,
240                 bool aUseSVGMode,
241                 nsTArray<PropertyStyleAnimationValuePair>& aResult);
242 
243   /**
244    * A variant of ComputeValues that takes a RawServoDeclarationBlock
245    * as the specified value.
246    */
247   static MOZ_MUST_USE bool
248   ComputeValues(nsCSSPropertyID aProperty,
249                 mozilla::CSSEnabledState aEnabledState,
250                 nsStyleContext* aStyleContext,
251                 const RawServoDeclarationBlock& aDeclarations,
252                 nsTArray<PropertyStyleAnimationValuePair>& aValues);
253 
254   /**
255    * Creates a specified value for the given computed value.
256    *
257    * The first two overloads fill in an nsCSSValue object; the third
258    * produces a string.  For the overload that takes a const
259    * StyleAnimationValue& reference, the nsCSSValue result may depend on
260    * objects owned by the |aComputedValue| object, so users of that variant
261    * must keep |aComputedValue| alive longer than |aSpecifiedValue|.
262    * The overload that takes an rvalue StyleAnimationValue reference
263    * transfers ownership for some resources such that the |aComputedValue|
264    * does not depend on the lifetime of |aSpecifiedValue|.
265    *
266    * @param aProperty      The property whose value we're uncomputing.
267    * @param aComputedValue The computed value to be converted.
268    * @param [out] aSpecifiedValue The resulting specified value.
269    * @return true on success, false on failure.
270    *
271    * These functions are not MOZ_MUST_USE because failing to check the return
272    * value is common and reasonable.
273    */
274   static MOZ_MUST_USE bool
275   UncomputeValue(nsCSSPropertyID aProperty,
276                  const StyleAnimationValue& aComputedValue,
277                  nsCSSValue& aSpecifiedValue);
278   static MOZ_MUST_USE bool
279   UncomputeValue(nsCSSPropertyID aProperty,
280                  StyleAnimationValue&& aComputedValue,
281                  nsCSSValue& aSpecifiedValue);
282   static MOZ_MUST_USE bool
283   UncomputeValue(nsCSSPropertyID aProperty,
284                  const StyleAnimationValue& aComputedValue,
285                  nsAString& aSpecifiedValue);
286 
287   /**
288    * Gets the computed value for the given property from the given style
289    * context.
290    *
291    * Obtaining the computed value allows us to animate properties when the
292    * content author has specified a value like "inherit" or "initial" or some
293    * other keyword that isn't directly interpolatable, but which *computes* to
294    * something interpolatable.
295    *
296    * @param aProperty     The property whose value we're looking up.
297    * @param aStyleContext The style context to check for the computed value.
298    * @param [out] aComputedValue The resulting computed value.
299    * @return true on success, false on failure.
300    */
301   static MOZ_MUST_USE bool ExtractComputedValue(
302     nsCSSPropertyID aProperty,
303     nsStyleContext* aStyleContext,
304     StyleAnimationValue& aComputedValue);
305 
306   /**
307    * Interpolates between 2 matrices by decomposing them.
308    *
309    * @param aMatrix1   First matrix, using CSS pixel units.
310    * @param aMatrix2   Second matrix, using CSS pixel units.
311    * @param aProgress  Interpolation value in the range [0.0, 1.0]
312    */
313   static gfx::Matrix4x4 InterpolateTransformMatrix(const gfx::Matrix4x4 &aMatrix1,
314                                                    const gfx::Matrix4x4 &aMatrix2,
315                                                    double aProgress);
316 
317   static already_AddRefed<nsCSSValue::Array>
318     AppendTransformFunction(nsCSSKeyword aTransformFunction,
319                             nsCSSValueList**& aListTail);
320 
321   /**
322    * The types and values for the values that we extract and animate.
323    */
324   enum Unit {
325     eUnit_Null, // not initialized
326     eUnit_Normal,
327     eUnit_Auto,
328     eUnit_None,
329     eUnit_Enumerated,
330     eUnit_Visibility, // special case for transitions (which converts
331                       // Enumerated to Visibility as needed)
332     eUnit_Integer,
333     eUnit_Coord,
334     eUnit_Percent,
335     eUnit_Float,
336     eUnit_Color, // nsCSSValue* (never null), always with an nscolor or
337                  // an nsCSSValueFloatColor
338     eUnit_CurrentColor,
339     eUnit_ComplexColor, // ComplexColorValue* (never null)
340     eUnit_Calc, // nsCSSValue* (never null), always with a single
341                 // calc() expression that's either length or length+percent
342     eUnit_ObjectPosition, // nsCSSValue* (never null), always with a
343                           // 4-entry nsCSSValue::Array
344     eUnit_URL, // nsCSSValue* (never null), always with a css::URLValue
345     eUnit_DiscreteCSSValue, // nsCSSValue* (never null)
346     eUnit_CSSValuePair, // nsCSSValuePair* (never null)
347     eUnit_CSSValueTriplet, // nsCSSValueTriplet* (never null)
348     eUnit_CSSRect, // nsCSSRect* (never null)
349     eUnit_Dasharray, // nsCSSValueList* (never null)
350     eUnit_Shadow, // nsCSSValueList* (may be null)
351     eUnit_Shape,  // nsCSSValue::Array* (never null)
352     eUnit_Filter, // nsCSSValueList* (may be null)
353     eUnit_Transform, // nsCSSValueList* (never null)
354     eUnit_BackgroundPositionCoord, // nsCSSValueList* (never null)
355     eUnit_CSSValuePairList, // nsCSSValuePairList* (never null)
356     eUnit_UnparsedString // nsStringBuffer* (never null)
357   };
358 
359 private:
360   Unit mUnit;
361   union {
362     int32_t mInt;
363     nscoord mCoord;
364     float mFloat;
365     nsCSSValue* mCSSValue;
366     nsCSSValuePair* mCSSValuePair;
367     nsCSSValueTriplet* mCSSValueTriplet;
368     nsCSSRect* mCSSRect;
369     nsCSSValue::Array* mCSSValueArray;
370     nsCSSValueList* mCSSValueList;
371     nsCSSValueSharedList* mCSSValueSharedList;
372     nsCSSValuePairList* mCSSValuePairList;
373     nsStringBuffer* mString;
374     css::ComplexColorValue* mComplexColor;
375   } mValue;
376 
377 public:
GetUnit()378   Unit GetUnit() const {
379     NS_ASSERTION(mUnit != eUnit_Null, "uninitialized");
380     return mUnit;
381   }
382 
383   // Accessor to let us verify assumptions about presence of null unit,
384   // without tripping the assertion in GetUnit().
IsNull()385   bool IsNull() const {
386     return mUnit == eUnit_Null;
387   }
388 
GetIntValue()389   int32_t GetIntValue() const {
390     NS_ASSERTION(IsIntUnit(mUnit), "unit mismatch");
391     return mValue.mInt;
392   }
GetCoordValue()393   nscoord GetCoordValue() const {
394     NS_ASSERTION(mUnit == eUnit_Coord, "unit mismatch");
395     return mValue.mCoord;
396   }
GetPercentValue()397   float GetPercentValue() const {
398     NS_ASSERTION(mUnit == eUnit_Percent, "unit mismatch");
399     return mValue.mFloat;
400   }
GetFloatValue()401   float GetFloatValue() const {
402     NS_ASSERTION(mUnit == eUnit_Float, "unit mismatch");
403     return mValue.mFloat;
404   }
GetCSSValueValue()405   nsCSSValue* GetCSSValueValue() const {
406     NS_ASSERTION(IsCSSValueUnit(mUnit), "unit mismatch");
407     return mValue.mCSSValue;
408   }
GetCSSValuePairValue()409   nsCSSValuePair* GetCSSValuePairValue() const {
410     NS_ASSERTION(IsCSSValuePairUnit(mUnit), "unit mismatch");
411     return mValue.mCSSValuePair;
412   }
GetCSSValueTripletValue()413   nsCSSValueTriplet* GetCSSValueTripletValue() const {
414     NS_ASSERTION(IsCSSValueTripletUnit(mUnit), "unit mismatch");
415     return mValue.mCSSValueTriplet;
416   }
GetCSSRectValue()417   nsCSSRect* GetCSSRectValue() const {
418     NS_ASSERTION(IsCSSRectUnit(mUnit), "unit mismatch");
419     return mValue.mCSSRect;
420   }
GetCSSValueArrayValue()421   nsCSSValue::Array* GetCSSValueArrayValue() const {
422     NS_ASSERTION(IsCSSValueArrayUnit(mUnit), "unit mismatch");
423     return mValue.mCSSValueArray;
424   }
GetCSSValueListValue()425   nsCSSValueList* GetCSSValueListValue() const {
426     NS_ASSERTION(IsCSSValueListUnit(mUnit), "unit mismatch");
427     return mValue.mCSSValueList;
428   }
GetCSSValueSharedListValue()429   nsCSSValueSharedList* GetCSSValueSharedListValue() const {
430     NS_ASSERTION(IsCSSValueSharedListValue(mUnit), "unit mismatch");
431     return mValue.mCSSValueSharedList;
432   }
GetCSSValuePairListValue()433   nsCSSValuePairList* GetCSSValuePairListValue() const {
434     NS_ASSERTION(IsCSSValuePairListUnit(mUnit), "unit mismatch");
435     return mValue.mCSSValuePairList;
436   }
GetStringBufferValue()437   const char16_t* GetStringBufferValue() const {
438     NS_ASSERTION(IsStringUnit(mUnit), "unit mismatch");
439     return GetBufferValue(mValue.mString);
440   }
441 
GetStringValue(nsAString & aBuffer)442   void GetStringValue(nsAString& aBuffer) const {
443     NS_ASSERTION(IsStringUnit(mUnit), "unit mismatch");
444     aBuffer.Truncate();
445     uint32_t len = NS_strlen(GetBufferValue(mValue.mString));
446     mValue.mString->ToString(len, aBuffer);
447   }
448 
449   /// @return the scale for this value, calculated with reference to @aForFrame.
450   gfxSize GetScaleValue(const nsIFrame* aForFrame) const;
451 
GetComplexColorData()452   const css::ComplexColorData& GetComplexColorData() const {
453     MOZ_ASSERT(mUnit == eUnit_ComplexColor, "unit mismatch");
454     return *mValue.mComplexColor;
455   }
GetStyleComplexColorValue()456   StyleComplexColor GetStyleComplexColorValue() const {
457     return GetComplexColorData().ToComplexColor();
458   }
459 
TakeCSSValueListValue()460   UniquePtr<nsCSSValueList> TakeCSSValueListValue() {
461     nsCSSValueList* list = GetCSSValueListValue();
462     mValue.mCSSValueList = nullptr;
463     mUnit = eUnit_Null;
464     return UniquePtr<nsCSSValueList>(list);
465   }
TakeCSSValuePairListValue()466   UniquePtr<nsCSSValuePairList> TakeCSSValuePairListValue() {
467     nsCSSValuePairList* list = GetCSSValuePairListValue();
468     mValue.mCSSValuePairList = nullptr;
469     mUnit = eUnit_Null;
470     return UniquePtr<nsCSSValuePairList>(list);
471   }
472 
mUnit(aUnit)473   explicit StyleAnimationValue(Unit aUnit = eUnit_Null) : mUnit(aUnit) {
474     NS_ASSERTION(aUnit == eUnit_Null || aUnit == eUnit_Normal ||
475                  aUnit == eUnit_Auto || aUnit == eUnit_None,
476                  "must be valueless unit");
477   }
StyleAnimationValue(const StyleAnimationValue & aOther)478   StyleAnimationValue(const StyleAnimationValue& aOther)
479     : mUnit(eUnit_Null) { *this = aOther; }
StyleAnimationValue(StyleAnimationValue && aOther)480   StyleAnimationValue(StyleAnimationValue&& aOther)
481     : mUnit(aOther.mUnit)
482     , mValue(aOther.mValue)
483   {
484     aOther.mUnit = eUnit_Null;
485   }
486   enum IntegerConstructorType { IntegerConstructor };
487   StyleAnimationValue(int32_t aInt, Unit aUnit, IntegerConstructorType);
488   enum CoordConstructorType { CoordConstructor };
489   StyleAnimationValue(nscoord aLength, CoordConstructorType);
490   enum PercentConstructorType { PercentConstructor };
491   StyleAnimationValue(float aPercent, PercentConstructorType);
492   enum FloatConstructorType { FloatConstructor };
493   StyleAnimationValue(float aFloat, FloatConstructorType);
494   enum ColorConstructorType { ColorConstructor };
495   StyleAnimationValue(nscolor aColor, ColorConstructorType);
496 
~StyleAnimationValue()497   ~StyleAnimationValue() { FreeValue(); }
498 
499   void SetNormalValue();
500   void SetAutoValue();
501   void SetNoneValue();
502   void SetIntValue(int32_t aInt, Unit aUnit);
503   template<typename T,
504            typename = typename std::enable_if<std::is_enum<T>::value>::type>
SetIntValue(T aInt,Unit aUnit)505   void SetIntValue(T aInt, Unit aUnit)
506   {
507     static_assert(mozilla::EnumTypeFitsWithin<T, int32_t>::value,
508                   "aValue must be an enum that fits within mValue.mInt");
509     SetIntValue(static_cast<int32_t>(aInt), aUnit);
510   }
511   void SetCoordValue(nscoord aCoord);
512   void SetPercentValue(float aPercent);
513   void SetFloatValue(float aFloat);
514   void SetColorValue(nscolor aColor);
515   void SetCurrentColorValue();
516   void SetComplexColorValue(const StyleComplexColor& aColor);
517   void SetComplexColorValue(already_AddRefed<css::ComplexColorValue> aValue);
518   void SetUnparsedStringValue(const nsString& aString);
519   void SetCSSValueArrayValue(nsCSSValue::Array* aValue, Unit aUnit);
520 
521   // These setters take ownership of |aValue|, and are therefore named
522   // "SetAndAdopt*".
523   void SetAndAdoptCSSValueValue(nsCSSValue *aValue, Unit aUnit);
524   void SetAndAdoptCSSValuePairValue(nsCSSValuePair *aValue, Unit aUnit);
525   void SetAndAdoptCSSValueTripletValue(nsCSSValueTriplet *aValue, Unit aUnit);
526   void SetAndAdoptCSSRectValue(nsCSSRect *aValue, Unit aUnit);
527   void SetAndAdoptCSSValueListValue(nsCSSValueList *aValue, Unit aUnit);
528   void SetAndAdoptCSSValuePairListValue(nsCSSValuePairList *aValue);
529 
530   void SetTransformValue(nsCSSValueSharedList* aList);
531 
532   StyleAnimationValue& operator=(const StyleAnimationValue& aOther);
533   StyleAnimationValue& operator=(StyleAnimationValue&& aOther)
534   {
535     MOZ_ASSERT(this != &aOther, "Do not move itself");
536     if (this != &aOther) {
537       FreeValue();
538       mUnit = aOther.mUnit;
539       mValue = aOther.mValue;
540       aOther.mUnit = eUnit_Null;
541     }
542     return *this;
543   }
544 
545   bool operator==(const StyleAnimationValue& aOther) const;
546   bool operator!=(const StyleAnimationValue& aOther) const
547     { return !(*this == aOther); }
548 
549 private:
550   void FreeValue();
551 
GetBufferValue(nsStringBuffer * aBuffer)552   static const char16_t* GetBufferValue(nsStringBuffer* aBuffer) {
553     return static_cast<char16_t*>(aBuffer->Data());
554   }
555 
IsIntUnit(Unit aUnit)556   static bool IsIntUnit(Unit aUnit) {
557     return aUnit == eUnit_Enumerated || aUnit == eUnit_Visibility ||
558            aUnit == eUnit_Integer;
559   }
IsCSSValueUnit(Unit aUnit)560   static bool IsCSSValueUnit(Unit aUnit) {
561     return aUnit == eUnit_Color ||
562            aUnit == eUnit_Calc ||
563            aUnit == eUnit_ObjectPosition ||
564            aUnit == eUnit_URL ||
565            aUnit == eUnit_DiscreteCSSValue;
566   }
IsCSSValuePairUnit(Unit aUnit)567   static bool IsCSSValuePairUnit(Unit aUnit) {
568     return aUnit == eUnit_CSSValuePair;
569   }
IsCSSValueTripletUnit(Unit aUnit)570   static bool IsCSSValueTripletUnit(Unit aUnit) {
571     return aUnit == eUnit_CSSValueTriplet;
572   }
IsCSSRectUnit(Unit aUnit)573   static bool IsCSSRectUnit(Unit aUnit) {
574     return aUnit == eUnit_CSSRect;
575   }
IsCSSValueArrayUnit(Unit aUnit)576   static bool IsCSSValueArrayUnit(Unit aUnit) {
577     return aUnit == eUnit_Shape;
578   }
IsCSSValueListUnit(Unit aUnit)579   static bool IsCSSValueListUnit(Unit aUnit) {
580     return aUnit == eUnit_Dasharray || aUnit == eUnit_Filter ||
581            aUnit == eUnit_Shadow ||
582            aUnit == eUnit_BackgroundPositionCoord;
583   }
IsCSSValueSharedListValue(Unit aUnit)584   static bool IsCSSValueSharedListValue(Unit aUnit) {
585     return aUnit == eUnit_Transform;
586   }
IsCSSValuePairListUnit(Unit aUnit)587   static bool IsCSSValuePairListUnit(Unit aUnit) {
588     return aUnit == eUnit_CSSValuePairList;
589   }
IsStringUnit(Unit aUnit)590   static bool IsStringUnit(Unit aUnit) {
591     return aUnit == eUnit_UnparsedString;
592   }
593 };
594 
595 struct PropertyStyleAnimationValuePair
596 {
597   nsCSSPropertyID mProperty;
598   StyleAnimationValue mValue;
599 };
600 } // namespace mozilla
601 
602 #endif
603