layout/style/nsCSSValue.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     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/. */
     6 /* representation of simple property values within CSS declarations */
     8 #ifndef nsCSSValue_h___
     9 #define nsCSSValue_h___
    11 #include "mozilla/Attributes.h"
    12 #include "mozilla/FloatingPoint.h"
    13 #include "mozilla/MemoryReporting.h"
    15 #include "nsIPrincipal.h"
    16 #include "nsIURI.h"
    17 #include "nsCOMPtr.h"
    18 #include "nsCRTGlue.h"
    19 #include "nsCSSKeywords.h"
    20 #include "nsCSSProperty.h"
    21 #include "nsColor.h"
    22 #include "nsCoord.h"
    23 #include "nsRefPtrHashtable.h"
    24 #include "nsString.h"
    25 #include "nsStringBuffer.h"
    26 #include "nsTArray.h"
    27 #include "nsStyleConsts.h"
    29 class imgRequestProxy;
    30 class nsCSSStyleSheet;
    31 class nsIDocument;
    32 class nsIPrincipal;
    33 class nsIURI;
    34 class nsPresContext;
    35 template <class T>
    36 class nsPtrHashKey;
    38 // Deletes a linked list iteratively to avoid blowing up the stack (bug 456196).
    39 #define NS_CSS_DELETE_LIST_MEMBER(type_, ptr_, member_)                        \
    40   {                                                                            \
    41     type_ *cur = (ptr_)->member_;                                              \
    42     (ptr_)->member_ = nullptr;                                                 \
    43     while (cur) {                                                              \
    44       type_ *dlm_next = cur->member_;                                          \
    45       cur->member_ = nullptr;                                                  \
    46       delete cur;                                                              \
    47       cur = dlm_next;                                                          \
    48     }                                                                          \
    49   }
    51 // Clones a linked list iteratively to avoid blowing up the stack.
    52 // If it fails to clone the entire list then 'to_' is deleted and
    53 // we return null.
    54 #define NS_CSS_CLONE_LIST_MEMBER(type_, from_, member_, to_, args_)            \
    55   {                                                                            \
    56     type_ *dest = (to_);                                                       \
    57     (to_)->member_ = nullptr;                                                  \
    58     for (const type_ *src = (from_)->member_; src; src = src->member_) {       \
    59       type_ *clm_clone = src->Clone args_;                                     \
    60       if (!clm_clone) {                                                        \
    61         delete (to_);                                                          \
    62         return nullptr;                                                        \
    63       }                                                                        \
    64       dest->member_ = clm_clone;                                               \
    65       dest = clm_clone;                                                        \
    66     }                                                                          \
    67   }
    69 namespace mozilla {
    70 namespace css {
    72 struct URLValue {
    73   // Methods are not inline because using an nsIPrincipal means requiring
    74   // caps, which leads to REQUIRES hell, since this header is included all
    75   // over.
    77   // For both constructors aString must not be null.
    78   // For both constructors aOriginPrincipal must not be null.
    79   // Construct with a base URI; this will create the actual URI lazily from
    80   // aString and aBaseURI.
    81   URLValue(nsStringBuffer* aString, nsIURI* aBaseURI, nsIURI* aReferrer,
    82            nsIPrincipal* aOriginPrincipal);
    83   // Construct with the actual URI.
    84   URLValue(nsIURI* aURI, nsStringBuffer* aString, nsIURI* aReferrer,
    85            nsIPrincipal* aOriginPrincipal);
    87   ~URLValue();
    89   bool operator==(const URLValue& aOther) const;
    91   // URIEquals only compares URIs and principals (unlike operator==, which
    92   // also compares the original strings).  URIEquals also assumes that the
    93   // mURI member of both URL objects is non-null.  Do NOT call this method
    94   // unless you're sure this is the case.
    95   bool URIEquals(const URLValue& aOther) const;
    97   nsIURI* GetURI() const;
    99   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
   101 private:
   102   // If mURIResolved is false, mURI stores the base URI.
   103   // If mURIResolved is true, mURI stores the URI we resolve to; this may be
   104   // null if the URI is invalid.
   105   mutable nsCOMPtr<nsIURI> mURI;
   106 public:
   107   nsStringBuffer* mString; // Could use nsRefPtr, but it'd add useless
   108                            // null-checks; this is never null.
   109   nsCOMPtr<nsIURI> mReferrer;
   110   nsCOMPtr<nsIPrincipal> mOriginPrincipal;
   112   NS_INLINE_DECL_REFCOUNTING(URLValue)
   114 private:
   115   mutable bool mURIResolved;
   117   URLValue(const URLValue& aOther) MOZ_DELETE;
   118   URLValue& operator=(const URLValue& aOther) MOZ_DELETE;
   119 };
   121 struct ImageValue : public URLValue {
   122   // Not making the constructor and destructor inline because that would
   123   // force us to include imgIRequest.h, which leads to REQUIRES hell, since
   124   // this header is included all over.
   125   // aString must not be null.
   126   ImageValue(nsIURI* aURI, nsStringBuffer* aString, nsIURI* aReferrer,
   127              nsIPrincipal* aOriginPrincipal, nsIDocument* aDocument);
   128   ~ImageValue();
   130   // Inherit operator== from URLValue
   132   nsRefPtrHashtable<nsPtrHashKey<nsISupports>, imgRequestProxy> mRequests; 
   134   // Override AddRef and Release to not only log ourselves correctly, but
   135   // also so that we delete correctly without a virtual destructor
   136   NS_INLINE_DECL_REFCOUNTING(ImageValue)
   137 };
   139 struct GridNamedArea {
   140   nsString mName;
   141   uint32_t mColumnStart;
   142   uint32_t mColumnEnd;
   143   uint32_t mRowStart;
   144   uint32_t mRowEnd;
   145 };
   147 struct GridTemplateAreasValue MOZ_FINAL {
   148   // Parsed value
   149   nsTArray<GridNamedArea> mNamedAreas;
   151   // Original <string> values. Length gives the number of rows,
   152   // content makes serialization easier.
   153   nsTArray<nsString> mTemplates;
   155   // How many columns grid-template-areas contributes to the explicit grid.
   156   // http://dev.w3.org/csswg/css-grid/#explicit-grid
   157   uint32_t mNColumns;
   159   // How many rows grid-template-areas contributes to the explicit grid.
   160   // http://dev.w3.org/csswg/css-grid/#explicit-grid
   161   uint32_t NRows() const {
   162     return mTemplates.Length();
   163   }
   165   GridTemplateAreasValue()
   166     : mNColumns(0)
   167     // Default constructors for mNamedAreas and mTemplates: empty arrays.
   168   {
   169   }
   171   bool operator==(const GridTemplateAreasValue& aOther) const
   172   {
   173     return mTemplates == aOther.mTemplates;
   174   }
   176   bool operator!=(const GridTemplateAreasValue& aOther) const
   177   {
   178     return !(*this == aOther);
   179   }
   181   NS_INLINE_DECL_REFCOUNTING(GridTemplateAreasValue)
   183   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
   185 private:
   186   // Private destructor to make sure this isn't used as a stack variable
   187   // or member variable.
   188   ~GridTemplateAreasValue()
   189   {
   190   }
   192   GridTemplateAreasValue(const GridTemplateAreasValue& aOther) MOZ_DELETE;
   193   GridTemplateAreasValue&
   194   operator=(const GridTemplateAreasValue& aOther) MOZ_DELETE;
   195 };
   197 }
   198 }
   200 enum nsCSSUnit {
   201   eCSSUnit_Null         = 0,      // (n/a) null unit, value is not specified
   202   eCSSUnit_Auto         = 1,      // (n/a) value is algorithmic
   203   eCSSUnit_Inherit      = 2,      // (n/a) value is inherited
   204   eCSSUnit_Initial      = 3,      // (n/a) value is default UA value
   205   eCSSUnit_Unset        = 4,      // (n/a) value equivalent to 'initial' if on a reset property, 'inherit' otherwise
   206   eCSSUnit_None         = 5,      // (n/a) value is none
   207   eCSSUnit_Normal       = 6,      // (n/a) value is normal (algorithmic, different than auto)
   208   eCSSUnit_System_Font  = 7,      // (n/a) value is -moz-use-system-font
   209   eCSSUnit_All          = 8,      // (n/a) value is all
   210   eCSSUnit_Dummy        = 9,      // (n/a) a fake but specified value, used
   211                                   //       only in temporary values
   212   eCSSUnit_DummyInherit = 10,     // (n/a) a fake but specified value, used
   213                                   //       only in temporary values
   215   eCSSUnit_String       = 11,     // (char16_t*) a string value
   216   eCSSUnit_Ident        = 12,     // (char16_t*) a string value
   217   eCSSUnit_Families     = 13,     // (char16_t*) a string value
   218   eCSSUnit_Attr         = 14,     // (char16_t*) a attr(string) value
   219   eCSSUnit_Local_Font   = 15,     // (char16_t*) a local font name
   220   eCSSUnit_Font_Format  = 16,     // (char16_t*) a font format name
   221   eCSSUnit_Element      = 17,     // (char16_t*) an element id
   223   eCSSUnit_Array        = 20,     // (nsCSSValue::Array*) a list of values
   224   eCSSUnit_Counter      = 21,     // (nsCSSValue::Array*) a counter(string,[string]) value
   225   eCSSUnit_Counters     = 22,     // (nsCSSValue::Array*) a counters(string,string[,string]) value
   226   eCSSUnit_Cubic_Bezier = 23,     // (nsCSSValue::Array*) a list of float values
   227   eCSSUnit_Steps        = 24,     // (nsCSSValue::Array*) a list of (integer, enumerated)
   228   eCSSUnit_Function     = 25,     // (nsCSSValue::Array*) a function with
   229                                   //  parameters.  First elem of array is name,
   230                                   //  an nsCSSKeyword as eCSSUnit_Enumerated,
   231                                   //  the rest of the values are arguments.
   233   // The top level of a calc() expression is eCSSUnit_Calc.  All
   234   // remaining eCSSUnit_Calc_* units only occur inside these toplevel
   235   // calc values.
   237   // eCSSUnit_Calc has an array with exactly 1 element.  eCSSUnit_Calc
   238   // exists so we can distinguish calc(2em) from 2em as specified values
   239   // (but we drop this distinction for nsStyleCoord when we store
   240   // computed values).
   241   eCSSUnit_Calc         = 30,     // (nsCSSValue::Array*) calc() value
   242   // Plus, Minus, Times_* and Divided have arrays with exactly 2
   243   // elements.  a + b + c + d is grouped as ((a + b) + c) + d
   244   eCSSUnit_Calc_Plus    = 31,     // (nsCSSValue::Array*) + node within calc()
   245   eCSSUnit_Calc_Minus   = 32,     // (nsCSSValue::Array*) - within calc
   246   eCSSUnit_Calc_Times_L = 33,     // (nsCSSValue::Array*) num * val within calc
   247   eCSSUnit_Calc_Times_R = 34,     // (nsCSSValue::Array*) val * num within calc
   248   eCSSUnit_Calc_Divided = 35,     // (nsCSSValue::Array*) / within calc
   250   eCSSUnit_URL          = 40,     // (nsCSSValue::URL*) value
   251   eCSSUnit_Image        = 41,     // (nsCSSValue::Image*) value
   252   eCSSUnit_Gradient     = 42,     // (nsCSSValueGradient*) value
   253   eCSSUnit_TokenStream  = 43,     // (nsCSSValueTokenStream*) value
   254   eCSSUnit_GridTemplateAreas   = 44,   // (GridTemplateAreasValue*)
   255                                        // for grid-template-areas
   257   eCSSUnit_Pair         = 50,     // (nsCSSValuePair*) pair of values
   258   eCSSUnit_Triplet      = 51,     // (nsCSSValueTriplet*) triplet of values
   259   eCSSUnit_Rect         = 52,     // (nsCSSRect*) rectangle (four values)
   260   eCSSUnit_List         = 53,     // (nsCSSValueList*) list of values
   261   eCSSUnit_ListDep      = 54,     // (nsCSSValueList*) same as List
   262                                   //   but does not own the list
   263   eCSSUnit_SharedList   = 55,     // (nsCSSValueSharedList*) same as list
   264                                   //   but reference counted and shared
   265   eCSSUnit_PairList     = 56,     // (nsCSSValuePairList*) list of value pairs
   266   eCSSUnit_PairListDep  = 57,     // (nsCSSValuePairList*) same as PairList
   267                                   //   but does not own the list
   269   eCSSUnit_Integer      = 70,     // (int) simple value
   270   eCSSUnit_Enumerated   = 71,     // (int) value has enumerated meaning
   272   eCSSUnit_EnumColor           = 80,   // (int) enumerated color (kColorKTable)
   273   eCSSUnit_RGBColor            = 81,   // (nscolor) an opaque RGBA value specified as rgb()
   274   eCSSUnit_RGBAColor           = 82,   // (nscolor) an RGBA value specified as rgba()
   275   eCSSUnit_HexColor            = 83,   // (nscolor) an opaque RGBA value specified as #rrggbb
   276   eCSSUnit_ShortHexColor       = 84,   // (nscolor) an opaque RGBA value specified as #rgb
   277   eCSSUnit_PercentageRGBColor  = 85,   // (nsCSSValueFloatColor*)
   278   eCSSUnit_PercentageRGBAColor = 86,   // (nsCSSValueFloatColor*)
   279   eCSSUnit_HSLColor            = 87,   // (nsCSSValueFloatColor*)
   280   eCSSUnit_HSLAColor           = 88,   // (nsCSSValueFloatColor*)
   282   eCSSUnit_Percent      = 90,     // (float) 1.0 == 100%) value is percentage of something
   283   eCSSUnit_Number       = 91,     // (float) value is numeric (usually multiplier, different behavior that percent)
   285   // Physical length units
   286   eCSSUnit_PhysicalMillimeter = 200,   // (float) 1/25.4 inch
   288   // Length units - relative
   289   // Viewport relative measure
   290   eCSSUnit_ViewportWidth  = 700,    // (float) 1% of the width of the initial containing block
   291   eCSSUnit_ViewportHeight = 701,    // (float) 1% of the height of the initial containing block
   292   eCSSUnit_ViewportMin    = 702,    // (float) smaller of ViewportWidth and ViewportHeight
   293   eCSSUnit_ViewportMax    = 703,    // (float) larger of ViewportWidth and ViewportHeight
   295   // Font relative measure
   296   eCSSUnit_EM           = 800,    // (float) == current font size
   297   eCSSUnit_XHeight      = 801,    // (float) distance from top of lower case x to baseline
   298   eCSSUnit_Char         = 802,    // (float) number of characters, used for width with monospace font
   299   eCSSUnit_RootEM       = 803,    // (float) == root element font size
   301   // Screen relative measure
   302   eCSSUnit_Point        = 900,    // (float) 4/3 of a CSS pixel
   303   eCSSUnit_Inch         = 901,    // (float) 96 CSS pixels
   304   eCSSUnit_Millimeter   = 902,    // (float) 96/25.4 CSS pixels
   305   eCSSUnit_Centimeter   = 903,    // (float) 96/2.54 CSS pixels
   306   eCSSUnit_Pica         = 904,    // (float) 12 points == 16 CSS pixls
   307   eCSSUnit_Pixel        = 905,    // (float) CSS pixel unit
   309   // Angular units
   310   eCSSUnit_Degree       = 1000,    // (float) 360 per circle
   311   eCSSUnit_Grad         = 1001,    // (float) 400 per circle
   312   eCSSUnit_Radian       = 1002,    // (float) 2*pi per circle
   313   eCSSUnit_Turn         = 1003,    // (float) 1 per circle
   315   // Frequency units
   316   eCSSUnit_Hertz        = 2000,    // (float) 1/seconds
   317   eCSSUnit_Kilohertz    = 2001,    // (float) 1000 Hertz
   319   // Time units
   320   eCSSUnit_Seconds      = 3000,    // (float) Standard time
   321   eCSSUnit_Milliseconds = 3001,    // (float) 1/1000 second
   323   // Flexible fraction (CSS Grid)
   324   eCSSUnit_FlexFraction = 4000     // (float) Fraction of free space
   325 };
   327 struct nsCSSValueGradient;
   328 struct nsCSSValuePair;
   329 struct nsCSSValuePair_heap;
   330 struct nsCSSValueTokenStream;
   331 struct nsCSSRect;
   332 struct nsCSSRect_heap;
   333 struct nsCSSValueList;
   334 struct nsCSSValueList_heap;
   335 struct nsCSSValueSharedList;
   336 struct nsCSSValuePairList;
   337 struct nsCSSValuePairList_heap;
   338 struct nsCSSValueTriplet;
   339 struct nsCSSValueTriplet_heap;
   340 class nsCSSValueFloatColor;
   342 class nsCSSValue {
   343 public:
   344   struct Array;
   345   friend struct Array;
   347   friend struct mozilla::css::URLValue;
   349   friend struct mozilla::css::ImageValue;
   351   // for valueless units only (null, auto, inherit, none, all, normal)
   352   explicit nsCSSValue(nsCSSUnit aUnit = eCSSUnit_Null)
   353     : mUnit(aUnit)
   354   {
   355     NS_ABORT_IF_FALSE(aUnit <= eCSSUnit_DummyInherit, "not a valueless unit");
   356   }
   358   nsCSSValue(int32_t aValue, nsCSSUnit aUnit);
   359   nsCSSValue(float aValue, nsCSSUnit aUnit);
   360   nsCSSValue(const nsString& aValue, nsCSSUnit aUnit);
   361   nsCSSValue(Array* aArray, nsCSSUnit aUnit);
   362   explicit nsCSSValue(mozilla::css::URLValue* aValue);
   363   explicit nsCSSValue(mozilla::css::ImageValue* aValue);
   364   explicit nsCSSValue(nsCSSValueGradient* aValue);
   365   explicit nsCSSValue(nsCSSValueTokenStream* aValue);
   366   explicit nsCSSValue(mozilla::css::GridTemplateAreasValue* aValue);
   367   nsCSSValue(const nsCSSValue& aCopy);
   368   ~nsCSSValue() { Reset(); }
   370   nsCSSValue&  operator=(const nsCSSValue& aCopy);
   371   bool        operator==(const nsCSSValue& aOther) const;
   373   bool operator!=(const nsCSSValue& aOther) const
   374   {
   375     return !(*this == aOther);
   376   }
   378   // Enum for AppendToString's aValueSerialization argument.
   379   enum Serialization { eNormalized, eAuthorSpecified };
   381   /**
   382    * Serialize |this| as a specified value for |aProperty| and append
   383    * it to |aResult|.
   384    */
   385   void AppendToString(nsCSSProperty aProperty, nsAString& aResult,
   386                       Serialization aValueSerialization) const;
   388   nsCSSUnit GetUnit() const { return mUnit; }
   389   bool      IsLengthUnit() const
   390     { return eCSSUnit_PhysicalMillimeter <= mUnit && mUnit <= eCSSUnit_Pixel; }
   391   /**
   392    * A "fixed" length unit is one that means a specific physical length
   393    * which we try to match based on the physical characteristics of an
   394    * output device.
   395    */
   396   bool      IsFixedLengthUnit() const  
   397     { return mUnit == eCSSUnit_PhysicalMillimeter; }
   398   /**
   399    * What the spec calls relative length units is, for us, split
   400    * between relative length units and pixel length units.
   401    * 
   402    * A "relative" length unit is a multiple of some derived metric,
   403    * such as a font em-size, which itself was controlled by an input CSS
   404    * length. Relative length units should not be scaled by zooming, since
   405    * the underlying CSS length would already have been scaled.
   406    */
   407   bool      IsRelativeLengthUnit() const  
   408     { return eCSSUnit_EM <= mUnit && mUnit <= eCSSUnit_RootEM; }
   409   /**
   410    * A "pixel" length unit is a some multiple of CSS pixels.
   411    */
   412   bool      IsPixelLengthUnit() const
   413     { return eCSSUnit_Point <= mUnit && mUnit <= eCSSUnit_Pixel; }
   414   bool      IsAngularUnit() const  
   415     { return eCSSUnit_Degree <= mUnit && mUnit <= eCSSUnit_Turn; }
   416   bool      IsFrequencyUnit() const  
   417     { return eCSSUnit_Hertz <= mUnit && mUnit <= eCSSUnit_Kilohertz; }
   418   bool      IsTimeUnit() const  
   419     { return eCSSUnit_Seconds <= mUnit && mUnit <= eCSSUnit_Milliseconds; }
   420   bool      IsCalcUnit() const
   421     { return eCSSUnit_Calc <= mUnit && mUnit <= eCSSUnit_Calc_Divided; }
   423   bool      UnitHasStringValue() const
   424     { return eCSSUnit_String <= mUnit && mUnit <= eCSSUnit_Element; }
   425   bool      UnitHasArrayValue() const
   426     { return eCSSUnit_Array <= mUnit && mUnit <= eCSSUnit_Calc_Divided; }
   428   // Checks for the nsCSSValue being of a particular type of color unit:
   429   //
   430   //   - IsIntegerColorUnit returns true for:
   431   //       eCSSUnit_RGBColor             -- rgb(int,int,int)
   432   //       eCSSUnit_RGBAColor            -- rgba(int,int,int,float)
   433   //       eCSSUnit_HexColor             -- #rrggbb
   434   //       eCSSUnit_ShortHexColor        -- #rgb
   435   //
   436   //   - IsFLoatColorUnit returns true for:
   437   //       eCSSUnit_PercentageRGBColor   -- rgb(%,%,%)
   438   //       eCSSUnit_PercentageRGBAColor  -- rgba(%,%,%,float)
   439   //       eCSSUnit_HSLColor             -- hsl(float,%,%)
   440   //       eCSSUnit_HSLAColor            -- hsla(float,%,%,float)
   441   //
   442   //   - IsNumericColorUnit returns true for any of the above units.
   443   //
   444   // Note that color keywords and system colors are represented by
   445   // eCSSUnit_EnumColor and eCSSUnit_Ident.
   446   bool IsIntegerColorUnit() const { return IsIntegerColorUnit(mUnit); }
   447   bool IsFloatColorUnit() const { return IsFloatColorUnit(mUnit); }
   448   bool IsNumericColorUnit() const { return IsNumericColorUnit(mUnit); }
   449   static bool IsIntegerColorUnit(nsCSSUnit aUnit)
   450   { return eCSSUnit_RGBColor <= aUnit && aUnit <= eCSSUnit_ShortHexColor; }
   451   static bool IsFloatColorUnit(nsCSSUnit aUnit)
   452   { return eCSSUnit_PercentageRGBColor <= aUnit &&
   453            aUnit <= eCSSUnit_HSLAColor; }
   454   static bool IsNumericColorUnit(nsCSSUnit aUnit)
   455   { return IsIntegerColorUnit(aUnit) || IsFloatColorUnit(aUnit); }
   457   int32_t GetIntValue() const
   458   {
   459     NS_ABORT_IF_FALSE(mUnit == eCSSUnit_Integer ||
   460                       mUnit == eCSSUnit_Enumerated ||
   461                       mUnit == eCSSUnit_EnumColor,
   462                       "not an int value");
   463     return mValue.mInt;
   464   }
   466   nsCSSKeyword GetKeywordValue() const
   467   {
   468     NS_ABORT_IF_FALSE(mUnit == eCSSUnit_Enumerated, "not a keyword value");
   469     return static_cast<nsCSSKeyword>(mValue.mInt);
   470   }
   472   float GetPercentValue() const
   473   {
   474     NS_ABORT_IF_FALSE(mUnit == eCSSUnit_Percent, "not a percent value");
   475     return mValue.mFloat;
   476   }
   478   float GetFloatValue() const
   479   {
   480     NS_ABORT_IF_FALSE(eCSSUnit_Number <= mUnit, "not a float value");
   481     MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat));
   482     return mValue.mFloat;
   483   }
   485   float GetAngleValue() const
   486   {
   487     NS_ABORT_IF_FALSE(eCSSUnit_Degree <= mUnit &&
   488                  mUnit <= eCSSUnit_Turn, "not an angle value");
   489     return mValue.mFloat;
   490   }
   492   // Converts any angle to radians.
   493   double GetAngleValueInRadians() const;
   495   nsAString& GetStringValue(nsAString& aBuffer) const
   496   {
   497     NS_ABORT_IF_FALSE(UnitHasStringValue(), "not a string value");
   498     aBuffer.Truncate();
   499     uint32_t len = NS_strlen(GetBufferValue(mValue.mString));
   500     mValue.mString->ToString(len, aBuffer);
   501     return aBuffer;
   502   }
   504   const char16_t* GetStringBufferValue() const
   505   {
   506     NS_ABORT_IF_FALSE(UnitHasStringValue(), "not a string value");
   507     return GetBufferValue(mValue.mString);
   508   }
   510   nscolor GetColorValue() const;
   511   bool IsNonTransparentColor() const;
   513   Array* GetArrayValue() const
   514   {
   515     NS_ABORT_IF_FALSE(UnitHasArrayValue(), "not an array value");
   516     return mValue.mArray;
   517   }
   519   nsIURI* GetURLValue() const
   520   {
   521     NS_ABORT_IF_FALSE(mUnit == eCSSUnit_URL || mUnit == eCSSUnit_Image,
   522                  "not a URL value");
   523     return mUnit == eCSSUnit_URL ?
   524       mValue.mURL->GetURI() : mValue.mImage->GetURI();
   525   }
   527   nsCSSValueGradient* GetGradientValue() const
   528   {
   529     NS_ABORT_IF_FALSE(mUnit == eCSSUnit_Gradient, "not a gradient value");
   530     return mValue.mGradient;
   531   }
   533   nsCSSValueTokenStream* GetTokenStreamValue() const
   534   {
   535     NS_ABORT_IF_FALSE(mUnit == eCSSUnit_TokenStream, "not a token stream value");
   536     return mValue.mTokenStream;
   537   }
   539   nsCSSValueSharedList* GetSharedListValue() const
   540   {
   541     NS_ABORT_IF_FALSE(mUnit == eCSSUnit_SharedList, "not a shared list value");
   542     return mValue.mSharedList;
   543   }
   545   // bodies of these are below
   546   inline nsCSSValuePair& GetPairValue();
   547   inline const nsCSSValuePair& GetPairValue() const;
   549   inline nsCSSRect& GetRectValue();
   550   inline const nsCSSRect& GetRectValue() const;
   552   inline nsCSSValueList* GetListValue();
   553   inline const nsCSSValueList* GetListValue() const;
   555   inline nsCSSValuePairList* GetPairListValue();
   556   inline const nsCSSValuePairList* GetPairListValue() const;
   558   inline nsCSSValueTriplet& GetTripletValue();
   559   inline const nsCSSValueTriplet& GetTripletValue() const;
   562   mozilla::css::URLValue* GetURLStructValue() const
   563   {
   564     // Not allowing this for Image values, because if the caller takes
   565     // a ref to them they won't be able to delete them properly.
   566     NS_ABORT_IF_FALSE(mUnit == eCSSUnit_URL, "not a URL value");
   567     return mValue.mURL;
   568   }
   570   mozilla::css::ImageValue* GetImageStructValue() const
   571   {
   572     NS_ABORT_IF_FALSE(mUnit == eCSSUnit_Image, "not an Image value");
   573     return mValue.mImage;
   574   }
   576   mozilla::css::GridTemplateAreasValue* GetGridTemplateAreas() const
   577   {
   578     NS_ABORT_IF_FALSE(mUnit == eCSSUnit_GridTemplateAreas,
   579                       "not a grid-template-areas value");
   580     return mValue.mGridTemplateAreas;
   581   }
   583   const char16_t* GetOriginalURLValue() const
   584   {
   585     NS_ABORT_IF_FALSE(mUnit == eCSSUnit_URL || mUnit == eCSSUnit_Image,
   586                       "not a URL value");
   587     return GetBufferValue(mUnit == eCSSUnit_URL ?
   588                             mValue.mURL->mString :
   589                             mValue.mImage->mString);
   590   }
   592   // Not making this inline because that would force us to include
   593   // imgIRequest.h, which leads to REQUIRES hell, since this header is included
   594   // all over.
   595   imgRequestProxy* GetImageValue(nsIDocument* aDocument) const;
   597   nscoord GetFixedLength(nsPresContext* aPresContext) const;
   598   nscoord GetPixelLength() const;
   600   void Reset()  // sets to null
   601   {
   602     if (mUnit != eCSSUnit_Null)
   603       DoReset();
   604   }
   605 private:
   606   void DoReset();
   608 public:
   609   void SetIntValue(int32_t aValue, nsCSSUnit aUnit);
   610   void SetPercentValue(float aValue);
   611   void SetFloatValue(float aValue, nsCSSUnit aUnit);
   612   void SetStringValue(const nsString& aValue, nsCSSUnit aUnit);
   613   void SetColorValue(nscolor aValue);
   614   void SetIntegerColorValue(nscolor aValue, nsCSSUnit aUnit);
   615   void SetFloatColorValue(float aComponent1,
   616                           float aComponent2,
   617                           float aComponent3,
   618                           float aAlpha, nsCSSUnit aUnit);
   619   void SetArrayValue(nsCSSValue::Array* aArray, nsCSSUnit aUnit);
   620   void SetURLValue(mozilla::css::URLValue* aURI);
   621   void SetImageValue(mozilla::css::ImageValue* aImage);
   622   void SetGradientValue(nsCSSValueGradient* aGradient);
   623   void SetTokenStreamValue(nsCSSValueTokenStream* aTokenStream);
   624   void SetGridTemplateAreas(mozilla::css::GridTemplateAreasValue* aValue);
   625   void SetPairValue(const nsCSSValuePair* aPair);
   626   void SetPairValue(const nsCSSValue& xValue, const nsCSSValue& yValue);
   627   void SetSharedListValue(nsCSSValueSharedList* aList);
   628   void SetDependentListValue(nsCSSValueList* aList);
   629   void SetDependentPairListValue(nsCSSValuePairList* aList);
   630   void SetTripletValue(const nsCSSValueTriplet* aTriplet);
   631   void SetTripletValue(const nsCSSValue& xValue, const nsCSSValue& yValue, const nsCSSValue& zValue);
   632   void SetAutoValue();
   633   void SetInheritValue();
   634   void SetInitialValue();
   635   void SetUnsetValue();
   636   void SetNoneValue();
   637   void SetAllValue();
   638   void SetNormalValue();
   639   void SetSystemFontValue();
   640   void SetDummyValue();
   641   void SetDummyInheritValue();
   643   // These are a little different - they allocate storage for you and
   644   // return a handle.
   645   nsCSSRect& SetRectValue();
   646   nsCSSValueList* SetListValue();
   647   nsCSSValuePairList* SetPairListValue();
   649   void StartImageLoad(nsIDocument* aDocument) const;  // Only pretend const
   651   // Initializes as a function value with the specified function id.
   652   Array* InitFunction(nsCSSKeyword aFunctionId, uint32_t aNumArgs);
   653   // Checks if this is a function value with the specified function id.
   654   bool EqualsFunction(nsCSSKeyword aFunctionId) const;
   656   // Returns an already addrefed buffer.  Guaranteed to return non-null.
   657   // (Will abort on allocation failure.)
   658   static already_AddRefed<nsStringBuffer>
   659     BufferFromString(const nsString& aValue);
   661   size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
   663 private:
   664   static const char16_t* GetBufferValue(nsStringBuffer* aBuffer) {
   665     return static_cast<char16_t*>(aBuffer->Data());
   666   }
   668 protected:
   669   nsCSSUnit mUnit;
   670   union {
   671     int32_t    mInt;
   672     float      mFloat;
   673     // Note: the capacity of the buffer may exceed the length of the string.
   674     // If we're of a string type, mString is not null.
   675     nsStringBuffer* mString;
   676     nscolor    mColor;
   677     Array*     mArray;
   678     mozilla::css::URLValue* mURL;
   679     mozilla::css::ImageValue* mImage;
   680     mozilla::css::GridTemplateAreasValue* mGridTemplateAreas;
   681     nsCSSValueGradient* mGradient;
   682     nsCSSValueTokenStream* mTokenStream;
   683     nsCSSValuePair_heap* mPair;
   684     nsCSSRect_heap* mRect;
   685     nsCSSValueTriplet_heap* mTriplet;
   686     nsCSSValueList_heap* mList;
   687     nsCSSValueList* mListDependent;
   688     nsCSSValueSharedList* mSharedList;
   689     nsCSSValuePairList_heap* mPairList;
   690     nsCSSValuePairList* mPairListDependent;
   691     nsCSSValueFloatColor* mFloatColor;
   692   } mValue;
   693 };
   695 struct nsCSSValue::Array MOZ_FINAL {
   697   // return |Array| with reference count of zero
   698   static Array* Create(size_t aItemCount) {
   699     return new (aItemCount) Array(aItemCount);
   700   }
   702   nsCSSValue& operator[](size_t aIndex) {
   703     NS_ABORT_IF_FALSE(aIndex < mCount, "out of range");
   704     return mArray[aIndex];
   705   }
   707   const nsCSSValue& operator[](size_t aIndex) const {
   708     NS_ABORT_IF_FALSE(aIndex < mCount, "out of range");
   709     return mArray[aIndex];
   710   }
   712   nsCSSValue& Item(size_t aIndex) { return (*this)[aIndex]; }
   713   const nsCSSValue& Item(size_t aIndex) const { return (*this)[aIndex]; }
   715   size_t Count() const { return mCount; }
   717   bool operator==(const Array& aOther) const
   718   {
   719     if (mCount != aOther.mCount)
   720       return false;
   721     for (size_t i = 0; i < mCount; ++i)
   722       if ((*this)[i] != aOther[i])
   723         return false;
   724     return true;
   725   }
   727   // XXXdholbert This uses a size_t ref count. Should we use a variant
   728   // of NS_INLINE_DECL_REFCOUNTING that takes a type as an argument?
   729   void AddRef() {
   730     if (mRefCnt == size_t(-1)) { // really want SIZE_MAX
   731       NS_WARNING("refcount overflow, leaking nsCSSValue::Array");
   732       return;
   733     }
   734     ++mRefCnt;
   735     NS_LOG_ADDREF(this, mRefCnt, "nsCSSValue::Array", sizeof(*this));
   736   }
   737   void Release() {
   738     if (mRefCnt == size_t(-1)) { // really want SIZE_MAX
   739       NS_WARNING("refcount overflow, leaking nsCSSValue::Array");
   740       return;
   741     }
   742     --mRefCnt;
   743     NS_LOG_RELEASE(this, mRefCnt, "nsCSSValue::Array");
   744     if (mRefCnt == 0)
   745       delete this;
   746   }
   748 private:
   750   size_t mRefCnt;
   751   const size_t mCount;
   752   // This must be the last sub-object, since we extend this array to
   753   // be of size mCount; it needs to be a sub-object so it gets proper
   754   // alignment.
   755   nsCSSValue mArray[1];
   757   void* operator new(size_t aSelfSize, size_t aItemCount) CPP_THROW_NEW {
   758     NS_ABORT_IF_FALSE(aItemCount > 0, "cannot have a 0 item count");
   759     return ::operator new(aSelfSize + sizeof(nsCSSValue) * (aItemCount - 1));
   760   }
   762   void operator delete(void* aPtr) { ::operator delete(aPtr); }
   764   nsCSSValue* First() { return mArray; }
   766   const nsCSSValue* First() const { return mArray; }
   768 #define CSSVALUE_LIST_FOR_EXTRA_VALUES(var)                                   \
   769   for (nsCSSValue *var = First() + 1, *var##_end = First() + mCount;          \
   770        var != var##_end; ++var)
   772   Array(size_t aItemCount)
   773     : mRefCnt(0)
   774     , mCount(aItemCount)
   775   {
   776     MOZ_COUNT_CTOR(nsCSSValue::Array);
   777     CSSVALUE_LIST_FOR_EXTRA_VALUES(val) {
   778       new (val) nsCSSValue();
   779     }
   780   }
   782   ~Array()
   783   {
   784     MOZ_COUNT_DTOR(nsCSSValue::Array);
   785     CSSVALUE_LIST_FOR_EXTRA_VALUES(val) {
   786       val->~nsCSSValue();
   787     }
   788   }
   790   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
   792 #undef CSSVALUE_LIST_FOR_EXTRA_VALUES
   794 private:
   795   Array(const Array& aOther) MOZ_DELETE;
   796   Array& operator=(const Array& aOther) MOZ_DELETE;
   797 };
   799 // Prefer nsCSSValue::Array for lists of fixed size.
   800 struct nsCSSValueList {
   801   nsCSSValueList() : mNext(nullptr) { MOZ_COUNT_CTOR(nsCSSValueList); }
   802   ~nsCSSValueList();
   804   nsCSSValueList* Clone() const;  // makes a deep copy
   805   void CloneInto(nsCSSValueList* aList) const; // makes a deep copy into aList
   806   void AppendToString(nsCSSProperty aProperty, nsAString& aResult,
   807                       nsCSSValue::Serialization aValueSerialization) const;
   809   bool operator==(nsCSSValueList const& aOther) const;
   810   bool operator!=(const nsCSSValueList& aOther) const
   811   { return !(*this == aOther); }
   813   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
   815   nsCSSValue      mValue;
   816   nsCSSValueList* mNext;
   818 private:
   819   nsCSSValueList(const nsCSSValueList& aCopy) // makes a shallow copy
   820     : mValue(aCopy.mValue), mNext(nullptr)
   821   {
   822     MOZ_COUNT_CTOR(nsCSSValueList);
   823   }
   824 };
   826 // nsCSSValueList_heap differs from nsCSSValueList only in being
   827 // refcounted.  It should not be necessary to use this class directly;
   828 // it's an implementation detail of nsCSSValue.
   829 struct nsCSSValueList_heap MOZ_FINAL : public nsCSSValueList {
   830   NS_INLINE_DECL_REFCOUNTING(nsCSSValueList_heap)
   832   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
   834 private:
   835   // Private destructor, to discourage deletion outside of Release():
   836   ~nsCSSValueList_heap()
   837   {
   838   }
   839 };
   841 // This is a reference counted list value.  Note that the object is
   842 // a wrapper for the reference count and a pointer to the head of the
   843 // list, whereas the other list types (such as nsCSSValueList) do
   844 // not have such a wrapper.
   845 struct nsCSSValueSharedList MOZ_FINAL {
   846   nsCSSValueSharedList()
   847     : mHead(nullptr)
   848   {
   849     MOZ_COUNT_CTOR(nsCSSValueSharedList);
   850   }
   852   // Takes ownership of aList.
   853   nsCSSValueSharedList(nsCSSValueList* aList)
   854     : mHead(aList)
   855   {
   856     MOZ_COUNT_CTOR(nsCSSValueSharedList);
   857   }
   859 private:
   860   // Private destructor, to discourage deletion outside of Release():
   861   ~nsCSSValueSharedList();
   863 public:
   864   NS_INLINE_DECL_REFCOUNTING(nsCSSValueSharedList)
   866   void AppendToString(nsCSSProperty aProperty, nsAString& aResult,
   867                       nsCSSValue::Serialization aValueSerialization) const;
   869   bool operator==(nsCSSValueSharedList const& aOther) const;
   870   bool operator!=(const nsCSSValueSharedList& aOther) const
   871   { return !(*this == aOther); }
   873   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
   875   nsCSSValueList* mHead;
   876 };
   878 // This has to be here so that the relationship between nsCSSValueList
   879 // and nsCSSValueList_heap is visible.
   880 inline nsCSSValueList*
   881 nsCSSValue::GetListValue()
   882 {
   883   if (mUnit == eCSSUnit_List)
   884     return mValue.mList;
   885   else {
   886     NS_ABORT_IF_FALSE(mUnit == eCSSUnit_ListDep, "not a pairlist value");
   887     return mValue.mListDependent;
   888   }
   889 }
   891 inline const nsCSSValueList*
   892 nsCSSValue::GetListValue() const
   893 {
   894   if (mUnit == eCSSUnit_List)
   895     return mValue.mList;
   896   else {
   897     NS_ABORT_IF_FALSE(mUnit == eCSSUnit_ListDep, "not a pairlist value");
   898     return mValue.mListDependent;
   899   }
   900 }
   902 struct nsCSSRect {
   903   nsCSSRect(void);
   904   nsCSSRect(const nsCSSRect& aCopy);
   905   ~nsCSSRect();
   907   void AppendToString(nsCSSProperty aProperty, nsAString& aResult,
   908                       nsCSSValue::Serialization aValueSerialization) const;
   910   bool operator==(const nsCSSRect& aOther) const {
   911     return mTop == aOther.mTop &&
   912            mRight == aOther.mRight &&
   913            mBottom == aOther.mBottom &&
   914            mLeft == aOther.mLeft;
   915   }
   917   bool operator!=(const nsCSSRect& aOther) const {
   918     return mTop != aOther.mTop ||
   919            mRight != aOther.mRight ||
   920            mBottom != aOther.mBottom ||
   921            mLeft != aOther.mLeft;
   922   }
   924   void SetAllSidesTo(const nsCSSValue& aValue);
   926   bool AllSidesEqualTo(const nsCSSValue& aValue) const {
   927     return mTop == aValue &&
   928            mRight == aValue &&
   929            mBottom == aValue &&
   930            mLeft == aValue;
   931   }
   933   void Reset() {
   934     mTop.Reset();
   935     mRight.Reset();
   936     mBottom.Reset();
   937     mLeft.Reset();
   938   }
   940   bool HasValue() const {
   941     return
   942       mTop.GetUnit() != eCSSUnit_Null ||
   943       mRight.GetUnit() != eCSSUnit_Null ||
   944       mBottom.GetUnit() != eCSSUnit_Null ||
   945       mLeft.GetUnit() != eCSSUnit_Null;
   946   }
   948   nsCSSValue mTop;
   949   nsCSSValue mRight;
   950   nsCSSValue mBottom;
   951   nsCSSValue mLeft;
   953   typedef nsCSSValue nsCSSRect::*side_type;
   954   static const side_type sides[4];
   955 };
   957 // nsCSSRect_heap differs from nsCSSRect only in being
   958 // refcounted.  It should not be necessary to use this class directly;
   959 // it's an implementation detail of nsCSSValue.
   960 struct nsCSSRect_heap MOZ_FINAL : public nsCSSRect {
   961   NS_INLINE_DECL_REFCOUNTING(nsCSSRect_heap)
   963   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
   965 private:
   966   // Private destructor, to discourage deletion outside of Release():
   967   ~nsCSSRect_heap()
   968   {
   969   }
   970 };
   972 // This has to be here so that the relationship between nsCSSRect
   973 // and nsCSSRect_heap is visible.
   974 inline nsCSSRect&
   975 nsCSSValue::GetRectValue()
   976 {
   977   NS_ABORT_IF_FALSE(mUnit == eCSSUnit_Rect, "not a rect value");
   978   return *mValue.mRect;
   979 }
   981 inline const nsCSSRect&
   982 nsCSSValue::GetRectValue() const
   983 {
   984   NS_ABORT_IF_FALSE(mUnit == eCSSUnit_Rect, "not a rect value");
   985   return *mValue.mRect;
   986 }
   988 struct nsCSSValuePair {
   989   nsCSSValuePair()
   990   {
   991     MOZ_COUNT_CTOR(nsCSSValuePair);
   992   }
   993   nsCSSValuePair(nsCSSUnit aUnit)
   994     : mXValue(aUnit), mYValue(aUnit)
   995   {
   996     MOZ_COUNT_CTOR(nsCSSValuePair);
   997   }
   998   nsCSSValuePair(const nsCSSValue& aXValue, const nsCSSValue& aYValue)
   999     : mXValue(aXValue), mYValue(aYValue)
  1001     MOZ_COUNT_CTOR(nsCSSValuePair);
  1003   nsCSSValuePair(const nsCSSValuePair& aCopy)
  1004     : mXValue(aCopy.mXValue), mYValue(aCopy.mYValue)
  1006     MOZ_COUNT_CTOR(nsCSSValuePair);
  1008   ~nsCSSValuePair()
  1010     MOZ_COUNT_DTOR(nsCSSValuePair);
  1013   bool operator==(const nsCSSValuePair& aOther) const {
  1014     return mXValue == aOther.mXValue &&
  1015            mYValue == aOther.mYValue;
  1018   bool operator!=(const nsCSSValuePair& aOther) const {
  1019     return mXValue != aOther.mXValue ||
  1020            mYValue != aOther.mYValue;
  1023   bool BothValuesEqualTo(const nsCSSValue& aValue) const {
  1024     return mXValue == aValue &&
  1025            mYValue == aValue;
  1028   void SetBothValuesTo(const nsCSSValue& aValue) {
  1029     mXValue = aValue;
  1030     mYValue = aValue;
  1033   void Reset() {
  1034     mXValue.Reset();
  1035     mYValue.Reset();
  1038   bool HasValue() const {
  1039     return mXValue.GetUnit() != eCSSUnit_Null ||
  1040            mYValue.GetUnit() != eCSSUnit_Null;
  1043   void AppendToString(nsCSSProperty aProperty, nsAString& aResult,
  1044                       nsCSSValue::Serialization aValueSerialization) const;
  1046   size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
  1048   nsCSSValue mXValue;
  1049   nsCSSValue mYValue;
  1050 };
  1052 // nsCSSValuePair_heap differs from nsCSSValuePair only in being
  1053 // refcounted.  It should not be necessary to use this class directly;
  1054 // it's an implementation detail of nsCSSValue.
  1055 struct nsCSSValuePair_heap MOZ_FINAL : public nsCSSValuePair {
  1056   // forward constructor
  1057   nsCSSValuePair_heap(const nsCSSValue& aXValue, const nsCSSValue& aYValue)
  1058       : nsCSSValuePair(aXValue, aYValue)
  1059   {}
  1061   NS_INLINE_DECL_REFCOUNTING(nsCSSValuePair_heap)
  1063   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
  1065 private:
  1066   // Private destructor, to discourage deletion outside of Release():
  1067   ~nsCSSValuePair_heap()
  1070 };
  1072 struct nsCSSValueTriplet {
  1073     nsCSSValueTriplet()
  1075         MOZ_COUNT_CTOR(nsCSSValueTriplet);
  1077     nsCSSValueTriplet(nsCSSUnit aUnit)
  1078         : mXValue(aUnit), mYValue(aUnit), mZValue(aUnit)
  1080         MOZ_COUNT_CTOR(nsCSSValueTriplet);
  1082     nsCSSValueTriplet(const nsCSSValue& aXValue, 
  1083                       const nsCSSValue& aYValue, 
  1084                       const nsCSSValue& aZValue)
  1085         : mXValue(aXValue), mYValue(aYValue), mZValue(aZValue)
  1087         MOZ_COUNT_CTOR(nsCSSValueTriplet);
  1089     nsCSSValueTriplet(const nsCSSValueTriplet& aCopy)
  1090         : mXValue(aCopy.mXValue), mYValue(aCopy.mYValue), mZValue(aCopy.mZValue)
  1092         MOZ_COUNT_CTOR(nsCSSValueTriplet);
  1094     ~nsCSSValueTriplet()
  1096         MOZ_COUNT_DTOR(nsCSSValueTriplet);
  1099     bool operator==(const nsCSSValueTriplet& aOther) const {
  1100         return mXValue == aOther.mXValue &&
  1101                mYValue == aOther.mYValue &&
  1102                mZValue == aOther.mZValue;
  1105     bool operator!=(const nsCSSValueTriplet& aOther) const {
  1106         return mXValue != aOther.mXValue ||
  1107                mYValue != aOther.mYValue ||
  1108                mZValue != aOther.mZValue;
  1111     bool AllValuesEqualTo(const nsCSSValue& aValue) const {
  1112         return mXValue == aValue &&
  1113                mYValue == aValue &&
  1114                mZValue == aValue;
  1117     void SetAllValuesTo(const nsCSSValue& aValue) {
  1118         mXValue = aValue;
  1119         mYValue = aValue;
  1120         mZValue = aValue;
  1123     void Reset() {
  1124         mXValue.Reset();
  1125         mYValue.Reset();
  1126         mZValue.Reset();
  1129     bool HasValue() const {
  1130         return mXValue.GetUnit() != eCSSUnit_Null ||
  1131                mYValue.GetUnit() != eCSSUnit_Null ||
  1132                mZValue.GetUnit() != eCSSUnit_Null;
  1135     void AppendToString(nsCSSProperty aProperty, nsAString& aResult,
  1136                         nsCSSValue::Serialization aValueSerialization) const;
  1138     nsCSSValue mXValue;
  1139     nsCSSValue mYValue;
  1140     nsCSSValue mZValue;
  1141 };
  1143 // nsCSSValueTriplet_heap differs from nsCSSValueTriplet only in being
  1144 // refcounted.  It should not be necessary to use this class directly;
  1145 // it's an implementation detail of nsCSSValue.
  1146 struct nsCSSValueTriplet_heap MOZ_FINAL : public nsCSSValueTriplet {
  1147   // forward constructor
  1148   nsCSSValueTriplet_heap(const nsCSSValue& aXValue, const nsCSSValue& aYValue, const nsCSSValue& aZValue)
  1149     : nsCSSValueTriplet(aXValue, aYValue, aZValue)
  1150   {}
  1152   NS_INLINE_DECL_REFCOUNTING(nsCSSValueTriplet_heap)
  1154   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
  1156 private:
  1157   // Private destructor, to discourage deletion outside of Release():
  1158   ~nsCSSValueTriplet_heap()
  1161 };
  1163 // This has to be here so that the relationship between nsCSSValuePair
  1164 // and nsCSSValuePair_heap is visible.
  1165 inline nsCSSValuePair&
  1166 nsCSSValue::GetPairValue()
  1168   NS_ABORT_IF_FALSE(mUnit == eCSSUnit_Pair, "not a pair value");
  1169   return *mValue.mPair;
  1172 inline const nsCSSValuePair&
  1173 nsCSSValue::GetPairValue() const
  1175   NS_ABORT_IF_FALSE(mUnit == eCSSUnit_Pair, "not a pair value");
  1176   return *mValue.mPair;
  1179 inline nsCSSValueTriplet&
  1180 nsCSSValue::GetTripletValue()
  1182     NS_ABORT_IF_FALSE(mUnit == eCSSUnit_Triplet, "not a triplet value");
  1183     return *mValue.mTriplet;
  1186 inline const nsCSSValueTriplet&
  1187 nsCSSValue::GetTripletValue() const
  1189     NS_ABORT_IF_FALSE(mUnit == eCSSUnit_Triplet, "not a triplet value");
  1190     return *mValue.mTriplet;
  1193 // Maybe should be replaced with nsCSSValueList and nsCSSValue::Array?
  1194 struct nsCSSValuePairList {
  1195   nsCSSValuePairList() : mNext(nullptr) { MOZ_COUNT_CTOR(nsCSSValuePairList); }
  1196   ~nsCSSValuePairList();
  1198   nsCSSValuePairList* Clone() const; // makes a deep copy
  1199   void AppendToString(nsCSSProperty aProperty, nsAString& aResult,
  1200                       nsCSSValue::Serialization aValueSerialization) const;
  1202   bool operator==(const nsCSSValuePairList& aOther) const;
  1203   bool operator!=(const nsCSSValuePairList& aOther) const
  1204   { return !(*this == aOther); }
  1206   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
  1208   nsCSSValue          mXValue;
  1209   nsCSSValue          mYValue;
  1210   nsCSSValuePairList* mNext;
  1212 private:
  1213   nsCSSValuePairList(const nsCSSValuePairList& aCopy) // makes a shallow copy
  1214     : mXValue(aCopy.mXValue), mYValue(aCopy.mYValue), mNext(nullptr)
  1216     MOZ_COUNT_CTOR(nsCSSValuePairList);
  1218 };
  1220 // nsCSSValuePairList_heap differs from nsCSSValuePairList only in being
  1221 // refcounted.  It should not be necessary to use this class directly;
  1222 // it's an implementation detail of nsCSSValue.
  1223 struct nsCSSValuePairList_heap MOZ_FINAL : public nsCSSValuePairList {
  1224   NS_INLINE_DECL_REFCOUNTING(nsCSSValuePairList_heap)
  1226   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
  1228 private:
  1229   // Private destructor, to discourage deletion outside of Release():
  1230   ~nsCSSValuePairList_heap()
  1233 };
  1235 // This has to be here so that the relationship between nsCSSValuePairList
  1236 // and nsCSSValuePairList_heap is visible.
  1237 inline nsCSSValuePairList*
  1238 nsCSSValue::GetPairListValue()
  1240   if (mUnit == eCSSUnit_PairList)
  1241     return mValue.mPairList;
  1242   else {
  1243     NS_ABORT_IF_FALSE (mUnit == eCSSUnit_PairListDep, "not a pairlist value");
  1244     return mValue.mPairListDependent;
  1248 inline const nsCSSValuePairList*
  1249 nsCSSValue::GetPairListValue() const
  1251   if (mUnit == eCSSUnit_PairList)
  1252     return mValue.mPairList;
  1253   else {
  1254     NS_ABORT_IF_FALSE (mUnit == eCSSUnit_PairListDep, "not a pairlist value");
  1255     return mValue.mPairListDependent;
  1259 struct nsCSSValueGradientStop {
  1260 public:
  1261   nsCSSValueGradientStop();
  1262   // needed to keep bloat logs happy when we use the TArray
  1263   // in nsCSSValueGradient
  1264   nsCSSValueGradientStop(const nsCSSValueGradientStop& aOther);
  1265   ~nsCSSValueGradientStop();
  1267   nsCSSValue mLocation;
  1268   nsCSSValue mColor;
  1270   bool operator==(const nsCSSValueGradientStop& aOther) const
  1272     return (mLocation == aOther.mLocation &&
  1273             mColor == aOther.mColor);
  1276   bool operator!=(const nsCSSValueGradientStop& aOther) const
  1278     return !(*this == aOther);
  1281   size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
  1282 };
  1284 struct nsCSSValueGradient MOZ_FINAL {
  1285   nsCSSValueGradient(bool aIsRadial, bool aIsRepeating);
  1287   // true if gradient is radial, false if it is linear
  1288   bool mIsRadial;
  1289   bool mIsRepeating;
  1290   bool mIsLegacySyntax;
  1291   bool mIsExplicitSize;
  1292   // line position and angle
  1293   nsCSSValuePair mBgPos;
  1294   nsCSSValue mAngle;
  1296   // Only meaningful if mIsRadial is true
  1297 private:
  1298   nsCSSValue mRadialValues[2];
  1299 public:
  1300   nsCSSValue& GetRadialShape()
  1302     MOZ_ASSERT(!mIsExplicitSize);
  1303     return mRadialValues[0];
  1305   const nsCSSValue& GetRadialShape() const
  1307     MOZ_ASSERT(!mIsExplicitSize);
  1308     return mRadialValues[0];
  1310   nsCSSValue& GetRadialSize()
  1312     MOZ_ASSERT(!mIsExplicitSize);
  1313     return mRadialValues[1];
  1315   const nsCSSValue& GetRadialSize() const
  1317     MOZ_ASSERT(!mIsExplicitSize);
  1318     return mRadialValues[1];
  1320   nsCSSValue& GetRadiusX()
  1322     MOZ_ASSERT(mIsExplicitSize);
  1323     return mRadialValues[0];
  1325   const nsCSSValue& GetRadiusX() const
  1327     MOZ_ASSERT(mIsExplicitSize);
  1328     return mRadialValues[0];
  1330   nsCSSValue& GetRadiusY()
  1332     MOZ_ASSERT(mIsExplicitSize);
  1333     return mRadialValues[1];
  1335   const nsCSSValue& GetRadiusY() const
  1337     MOZ_ASSERT(mIsExplicitSize);
  1338     return mRadialValues[1];
  1341   InfallibleTArray<nsCSSValueGradientStop> mStops;
  1343   bool operator==(const nsCSSValueGradient& aOther) const
  1345     if (mIsRadial != aOther.mIsRadial ||
  1346         mIsRepeating != aOther.mIsRepeating ||
  1347         mIsLegacySyntax != aOther.mIsLegacySyntax ||
  1348         mIsExplicitSize != aOther.mIsExplicitSize ||
  1349         mBgPos != aOther.mBgPos ||
  1350         mAngle != aOther.mAngle ||
  1351         mRadialValues[0] != aOther.mRadialValues[0] ||
  1352         mRadialValues[1] != aOther.mRadialValues[1])
  1353       return false;
  1355     if (mStops.Length() != aOther.mStops.Length())
  1356       return false;
  1358     for (uint32_t i = 0; i < mStops.Length(); i++) {
  1359       if (mStops[i] != aOther.mStops[i])
  1360         return false;
  1363     return true;
  1366   bool operator!=(const nsCSSValueGradient& aOther) const
  1368     return !(*this == aOther);
  1371   NS_INLINE_DECL_REFCOUNTING(nsCSSValueGradient)
  1373   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
  1375 private:
  1376   // Private destructor, to discourage deletion outside of Release():
  1377   ~nsCSSValueGradient()
  1381   nsCSSValueGradient(const nsCSSValueGradient& aOther) MOZ_DELETE;
  1382   nsCSSValueGradient& operator=(const nsCSSValueGradient& aOther) MOZ_DELETE;
  1383 };
  1385 struct nsCSSValueTokenStream MOZ_FINAL {
  1386   nsCSSValueTokenStream();
  1388 private:
  1389   // Private destructor, to discourage deletion outside of Release():
  1390   ~nsCSSValueTokenStream();
  1392 public:
  1393   bool operator==(const nsCSSValueTokenStream& aOther) const
  1395     bool eq;
  1396     return mPropertyID == aOther.mPropertyID &&
  1397            mShorthandPropertyID == aOther.mShorthandPropertyID &&
  1398            mTokenStream.Equals(aOther.mTokenStream) &&
  1399            (mBaseURI == aOther.mBaseURI ||
  1400             (mBaseURI && aOther.mBaseURI &&
  1401              NS_SUCCEEDED(mBaseURI->Equals(aOther.mBaseURI, &eq)) &&
  1402              eq)) &&
  1403            (mSheetURI == aOther.mSheetURI ||
  1404             (mSheetURI && aOther.mSheetURI &&
  1405              NS_SUCCEEDED(mSheetURI->Equals(aOther.mSheetURI, &eq)) &&
  1406              eq)) &&
  1407            (mSheetPrincipal == aOther.mSheetPrincipal ||
  1408             (mSheetPrincipal && aOther.mSheetPrincipal &&
  1409              NS_SUCCEEDED(mSheetPrincipal->Equals(aOther.mSheetPrincipal,
  1410                                                   &eq)) &&
  1411              eq));
  1414   bool operator!=(const nsCSSValueTokenStream& aOther) const
  1416     return !(*this == aOther);
  1419   NS_INLINE_DECL_REFCOUNTING(nsCSSValueTokenStream)
  1421   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
  1423   // The property that has mTokenStream as its unparsed specified value.
  1424   // When a variable reference is used in a shorthand property, a
  1425   // TokenStream value is stored as the specified value for each of its
  1426   // component longhand properties.
  1427   nsCSSProperty mPropertyID;
  1429   // The shorthand property that had a value with a variable reference,
  1430   // which caused the longhand property identified by mPropertyID to have
  1431   // a TokenStream value.
  1432   nsCSSProperty mShorthandPropertyID;
  1434   // The unparsed CSS corresponding to the specified value of the property.
  1435   // When the value of a shorthand property has a variable reference, the
  1436   // same mTokenStream value is used on each of the nsCSSValueTokenStream
  1437   // objects that will be set by parsing the shorthand.
  1438   nsString mTokenStream;
  1440   nsCOMPtr<nsIURI> mBaseURI;
  1441   nsCOMPtr<nsIURI> mSheetURI;
  1442   nsCOMPtr<nsIPrincipal> mSheetPrincipal;
  1443   nsCSSStyleSheet* mSheet;
  1444   uint32_t mLineNumber;
  1445   uint32_t mLineOffset;
  1447   // This table is used to hold a reference on to any ImageValue that results
  1448   // from re-parsing this token stream at computed value time.  When properties
  1449   // like background-image contain a normal url(), the Declaration's data block
  1450   // will hold a reference to the ImageValue.  When a token stream is used,
  1451   // the Declaration only holds on to this nsCSSValueTokenStream object, and
  1452   // the ImageValue would only exist for the duration of
  1453   // nsRuleNode::WalkRuleTree, in the AutoCSSValueArray.  So instead when
  1454   // we re-parse a token stream and get an ImageValue, we record it in this
  1455   // table so that the Declaration can be the object that keeps holding
  1456   // a reference to it.
  1457   nsTHashtable<nsRefPtrHashKey<mozilla::css::ImageValue> > mImageValues;
  1459 private:
  1460   nsCSSValueTokenStream(const nsCSSValueTokenStream& aOther) MOZ_DELETE;
  1461   nsCSSValueTokenStream& operator=(const nsCSSValueTokenStream& aOther) MOZ_DELETE;
  1462 };
  1464 class nsCSSValueFloatColor MOZ_FINAL {
  1465 public:
  1466   nsCSSValueFloatColor(float aComponent1, float aComponent2, float aComponent3,
  1467                        float aAlpha)
  1468     : mComponent1(aComponent1)
  1469     , mComponent2(aComponent2)
  1470     , mComponent3(aComponent3)
  1471     , mAlpha(aAlpha)
  1473     MOZ_COUNT_CTOR(nsCSSValueFloatColor);
  1476 private:
  1477   // Private destructor, to discourage deletion outside of Release():
  1478   ~nsCSSValueFloatColor()
  1480     MOZ_COUNT_DTOR(nsCSSValueFloatColor);
  1483 public:
  1484   bool operator==(nsCSSValueFloatColor& aOther) const;
  1486   nscolor GetColorValue(nsCSSUnit aUnit) const;
  1487   bool IsNonTransparentColor() const;
  1489   void AppendToString(nsCSSUnit aUnit, nsAString& aResult) const;
  1491   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
  1493   NS_INLINE_DECL_REFCOUNTING(nsCSSValueFloatColor)
  1495 private:
  1496   // FIXME: We should not be clamping specified RGB color components.
  1497   float mComponent1;  // 0..1 for RGB, 0..360 for HSL
  1498   float mComponent2;  // 0..1
  1499   float mComponent3;  // 0..1
  1500   float mAlpha;       // 0..1
  1502   nsCSSValueFloatColor(const nsCSSValueFloatColor& aOther) MOZ_DELETE;
  1503   nsCSSValueFloatColor& operator=(const nsCSSValueFloatColor& aOther)
  1504                                                                    MOZ_DELETE;
  1505 };
  1507 struct nsCSSCornerSizes {
  1508   nsCSSCornerSizes(void);
  1509   nsCSSCornerSizes(const nsCSSCornerSizes& aCopy);
  1510   ~nsCSSCornerSizes();
  1512   // argument is a "full corner" constant from nsStyleConsts.h
  1513   nsCSSValue const & GetCorner(uint32_t aCorner) const {
  1514     return this->*corners[aCorner];
  1516   nsCSSValue & GetCorner(uint32_t aCorner) {
  1517     return this->*corners[aCorner];
  1520   bool operator==(const nsCSSCornerSizes& aOther) const {
  1521     NS_FOR_CSS_FULL_CORNERS(corner) {
  1522       if (this->GetCorner(corner) != aOther.GetCorner(corner))
  1523         return false;
  1525     return true;
  1528   bool operator!=(const nsCSSCornerSizes& aOther) const {
  1529     NS_FOR_CSS_FULL_CORNERS(corner) {
  1530       if (this->GetCorner(corner) != aOther.GetCorner(corner))
  1531         return true;
  1533     return false;
  1536   bool HasValue() const {
  1537     NS_FOR_CSS_FULL_CORNERS(corner) {
  1538       if (this->GetCorner(corner).GetUnit() != eCSSUnit_Null)
  1539         return true;
  1541     return false;
  1544   void Reset();
  1546   nsCSSValue mTopLeft;
  1547   nsCSSValue mTopRight;
  1548   nsCSSValue mBottomRight;
  1549   nsCSSValue mBottomLeft;
  1551 protected:
  1552   typedef nsCSSValue nsCSSCornerSizes::*corner_type;
  1553   static const corner_type corners[4];
  1554 };
  1556 #endif /* nsCSSValue_h___ */

mercurial