LCOV - code coverage report
Current view: top level - layout/style - nsCSSValue.h (source / functions) Hit Total Coverage
Test: output.info Lines: 256 464 55.2 %
Date: 2017-07-14 16:53:18 Functions: 115 189 60.8 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : /* representation of simple property values within CSS declarations */
       7             : 
       8             : #ifndef nsCSSValue_h___
       9             : #define nsCSSValue_h___
      10             : 
      11             : #include "mozilla/Attributes.h"
      12             : #include "mozilla/MemoryReporting.h"
      13             : #include "mozilla/SheetType.h"
      14             : #include "mozilla/StyleComplexColor.h"
      15             : #include "mozilla/URLExtraData.h"
      16             : #include "mozilla/UniquePtr.h"
      17             : 
      18             : #include "nsCSSKeywords.h"
      19             : #include "nsCSSPropertyID.h"
      20             : #include "nsCSSProps.h"
      21             : #include "nsColor.h"
      22             : #include "nsCoord.h"
      23             : #include "nsProxyRelease.h"
      24             : #include "nsRefPtrHashtable.h"
      25             : #include "nsString.h"
      26             : #include "nsStringBuffer.h"
      27             : #include "nsTArray.h"
      28             : #include "nsStyleConsts.h"
      29             : #include "nsStyleCoord.h"
      30             : #include "gfxFontFamilyList.h"
      31             : 
      32             : #include <type_traits>
      33             : 
      34             : class imgRequestProxy;
      35             : class nsIAtom;
      36             : class nsIContent;
      37             : class nsIDocument;
      38             : class nsIPrincipal;
      39             : class nsIURI;
      40             : class nsPresContext;
      41             : template <class T>
      42             : class nsPtrHashKey;
      43             : 
      44             : namespace mozilla {
      45             : class CSSStyleSheet;
      46             : } // namespace mozilla
      47             : 
      48             : // Deletes a linked list iteratively to avoid blowing up the stack (bug 456196).
      49             : #define NS_CSS_DELETE_LIST_MEMBER(type_, ptr_, member_)                        \
      50             :   {                                                                            \
      51             :     type_ *cur = (ptr_)->member_;                                              \
      52             :     (ptr_)->member_ = nullptr;                                                 \
      53             :     while (cur) {                                                              \
      54             :       type_ *dlm_next = cur->member_;                                          \
      55             :       cur->member_ = nullptr;                                                  \
      56             :       delete cur;                                                              \
      57             :       cur = dlm_next;                                                          \
      58             :     }                                                                          \
      59             :   }
      60             : // Ditto, but use NS_RELEASE instead of 'delete' (bug 1221902).
      61             : #define NS_CSS_NS_RELEASE_LIST_MEMBER(type_, ptr_, member_)                    \
      62             :   {                                                                            \
      63             :     type_ *cur = (ptr_)->member_;                                              \
      64             :     (ptr_)->member_ = nullptr;                                                 \
      65             :     while (cur) {                                                              \
      66             :       type_ *dlm_next = cur->member_;                                          \
      67             :       cur->member_ = nullptr;                                                  \
      68             :       NS_RELEASE(cur);                                                         \
      69             :       cur = dlm_next;                                                          \
      70             :     }                                                                          \
      71             :   }
      72             : 
      73             : // Clones a linked list iteratively to avoid blowing up the stack.
      74             : // If it fails to clone the entire list then 'to_' is deleted and
      75             : // we return null.
      76             : #define NS_CSS_CLONE_LIST_MEMBER(type_, from_, member_, to_, args_)            \
      77             :   {                                                                            \
      78             :     type_ *dest = (to_);                                                       \
      79             :     (to_)->member_ = nullptr;                                                  \
      80             :     for (const type_ *src = (from_)->member_; src; src = src->member_) {       \
      81             :       type_ *clm_clone = src->Clone args_;                                     \
      82             :       if (!clm_clone) {                                                        \
      83             :         delete (to_);                                                          \
      84             :         return nullptr;                                                        \
      85             :       }                                                                        \
      86             :       dest->member_ = clm_clone;                                               \
      87             :       dest = clm_clone;                                                        \
      88             :     }                                                                          \
      89             :   }
      90             : 
      91             : namespace mozilla {
      92             : namespace css {
      93             : 
      94             : struct URLValueData
      95             : {
      96             : protected:
      97             :   // Methods are not inline because using an nsIPrincipal means requiring
      98             :   // caps, which leads to REQUIRES hell, since this header is included all
      99             :   // over.
     100             : 
     101             :   // For both constructors aString must not be null.
     102             :   // For both constructors principal of aExtraData must not be null.
     103             :   // Construct with a base URI; this will create the actual URI lazily from
     104             :   // aString and aExtraData.
     105             :   URLValueData(const nsAString& aString,
     106             :                already_AddRefed<URLExtraData> aExtraData);
     107             :   // Construct with the actual URI.
     108             :   URLValueData(already_AddRefed<PtrHolder<nsIURI>> aURI,
     109             :                const nsAString& aString,
     110             :                already_AddRefed<URLExtraData> aExtraData);
     111             : 
     112             : public:
     113             :   // Returns true iff all fields of the two URLValueData objects are equal.
     114             :   //
     115             :   // Only safe to call on the main thread, since this will call Equals on the
     116             :   // nsIURI and nsIPrincipal objects stored on the URLValueData objects.
     117             :   bool Equals(const URLValueData& aOther) const;
     118             : 
     119             :   // Returns true iff we know for sure, by comparing the mBaseURI pointer,
     120             :   // the specified url() value mString, and the mIsLocalRef, that these
     121             :   // two URLValueData objects represent the same computed url() value.
     122             :   //
     123             :   // Doesn't look at mReferrer or mOriginPrincipal.
     124             :   //
     125             :   // Safe to call from any thread.
     126             :   bool DefinitelyEqualURIs(const URLValueData& aOther) const;
     127             : 
     128             :   // Smae as DefinitelyEqualURIs but additionally compares the nsIPrincipal
     129             :   // pointers of the two URLValueData objects.
     130             :   bool DefinitelyEqualURIsAndPrincipal(const URLValueData& aOther) const;
     131             : 
     132             :   nsIURI* GetURI() const;
     133             : 
     134             :   bool IsLocalRef() const;
     135             : 
     136             :   bool HasRef() const;
     137             : 
     138             :   // This function takes a guess whether the URL has a fragment, by searching
     139             :   // for a hash character. It definitely returns false if we know it can't
     140             :   // have a fragment because it has no hash character.
     141             :   //
     142             :   // MightHaveRef can be used in any thread, whereas HasRef can only be used
     143             :   // in the main thread.
     144             :   bool MightHaveRef() const;
     145             : 
     146        3417 :   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(URLValueData)
     147             : 
     148             :   // When matching a url with mIsLocalRef set, resolve it against aURI;
     149             :   // Otherwise, ignore aURL and return mURL directly.
     150             :   already_AddRefed<nsIURI> ResolveLocalRef(nsIURI* aURI) const;
     151             :   already_AddRefed<nsIURI> ResolveLocalRef(nsIContent* aContent) const;
     152             : 
     153             :   // Serializes mURI as a computed URI value, taking into account mIsLocalRef
     154             :   // and serializing just the fragment if true.
     155             :   void GetSourceString(nsString& aRef) const;
     156             : 
     157             :   bool EqualsExceptRef(nsIURI* aURI) const;
     158             : 
     159             : private:
     160             :   // mURI stores the lazily resolved URI.  This may be null if the URI is
     161             :   // invalid, even once resolved.
     162             :   mutable PtrHandle<nsIURI> mURI;
     163             : public:
     164             :   nsString mString;
     165             :   RefPtr<URLExtraData> mExtraData;
     166             : private:
     167             :   mutable bool mURIResolved;
     168             :   // mIsLocalRef is set when url starts with a U+0023 number sign(#) character.
     169             :   mutable Maybe<bool> mIsLocalRef;
     170             :   mutable Maybe<bool> mMightHaveRef;
     171             : 
     172             : protected:
     173          42 :   virtual ~URLValueData() = default;
     174             : 
     175             :   size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
     176             : 
     177             : private:
     178             :   URLValueData(const URLValueData& aOther) = delete;
     179             :   URLValueData& operator=(const URLValueData& aOther) = delete;
     180             : };
     181             : 
     182         126 : struct URLValue final : public URLValueData
     183             : {
     184             :   // These two constructors are safe to call only on the main thread.
     185             :   URLValue(const nsAString& aString, nsIURI* aBaseURI, nsIURI* aReferrer,
     186             :            nsIPrincipal* aOriginPrincipal);
     187             :   URLValue(nsIURI* aURI, const nsAString& aString, nsIURI* aBaseURI,
     188             :            nsIURI* aReferrer, nsIPrincipal* aOriginPrincipal);
     189             : 
     190             :   // This constructor is safe to call from any thread.
     191           0 :   URLValue(const nsAString& aString,
     192             :            already_AddRefed<URLExtraData> aExtraData)
     193           0 :     : URLValueData(aString, Move(aExtraData)) {}
     194             : 
     195             :   URLValue(const URLValue&) = delete;
     196             :   URLValue& operator=(const URLValue&) = delete;
     197             : 
     198             :   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
     199             : };
     200             : 
     201             : struct ImageValue final : public URLValueData
     202             : {
     203             :   // Not making the constructor and destructor inline because that would
     204             :   // force us to include imgIRequest.h, which leads to REQUIRES hell, since
     205             :   // this header is included all over.
     206             :   //
     207             :   // This constructor is only safe to call from the main thread.
     208             :   ImageValue(nsIURI* aURI, const nsAString& aString,
     209             :              already_AddRefed<URLExtraData> aExtraData,
     210             :              nsIDocument* aDocument);
     211             : 
     212             :   // This constructor is safe to call from any thread, but Initialize
     213             :   // must be called later for the object to be useful.
     214             :   ImageValue(const nsAString& aString,
     215             :              already_AddRefed<URLExtraData> aExtraData);
     216             : 
     217             :   ImageValue(const ImageValue&) = delete;
     218             :   ImageValue& operator=(const ImageValue&) = delete;
     219             : 
     220             :   void Initialize(nsIDocument* aDocument);
     221             : 
     222             :   // XXXheycam We should have our own SizeOfIncludingThis method.
     223             : 
     224             : protected:
     225             :   ~ImageValue();
     226             : 
     227             : public:
     228             :   // Inherit Equals from URLValueData
     229             : 
     230             :   nsRefPtrHashtable<nsPtrHashKey<nsIDocument>, imgRequestProxy> mRequests;
     231             : 
     232             : private:
     233             :   bool mLoadedImage = false;
     234             : };
     235             : 
     236           0 : struct GridNamedArea {
     237             :   nsString mName;
     238             :   uint32_t mColumnStart;
     239             :   uint32_t mColumnEnd;
     240             :   uint32_t mRowStart;
     241             :   uint32_t mRowEnd;
     242             : };
     243             : 
     244             : struct GridTemplateAreasValue final {
     245             :   // Parsed value
     246             :   nsTArray<GridNamedArea> mNamedAreas;
     247             : 
     248             :   // Original <string> values. Length gives the number of rows,
     249             :   // content makes serialization easier.
     250             :   nsTArray<nsString> mTemplates;
     251             : 
     252             :   // How many columns grid-template-areas contributes to the explicit grid.
     253             :   // http://dev.w3.org/csswg/css-grid/#explicit-grid
     254             :   uint32_t mNColumns;
     255             : 
     256             :   // How many rows grid-template-areas contributes to the explicit grid.
     257             :   // http://dev.w3.org/csswg/css-grid/#explicit-grid
     258           0 :   uint32_t NRows() const {
     259           0 :     return mTemplates.Length();
     260             :   }
     261             : 
     262           0 :   GridTemplateAreasValue()
     263           0 :     : mNColumns(0)
     264             :     // Default constructors for mNamedAreas and mTemplates: empty arrays.
     265             :   {
     266           0 :   }
     267             : 
     268           0 :   bool operator==(const GridTemplateAreasValue& aOther) const
     269             :   {
     270           0 :     return mTemplates == aOther.mTemplates;
     271             :   }
     272             : 
     273             :   bool operator!=(const GridTemplateAreasValue& aOther) const
     274             :   {
     275             :     return !(*this == aOther);
     276             :   }
     277             : 
     278           0 :   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GridTemplateAreasValue)
     279             : 
     280             :   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
     281             : 
     282             : private:
     283             :   // Private destructor to make sure this isn't used as a stack variable
     284             :   // or member variable.
     285           0 :   ~GridTemplateAreasValue()
     286           0 :   {
     287           0 :   }
     288             : 
     289             :   GridTemplateAreasValue(const GridTemplateAreasValue& aOther) = delete;
     290             :   GridTemplateAreasValue&
     291             :   operator=(const GridTemplateAreasValue& aOther) = delete;
     292             : };
     293             : 
     294             : class FontFamilyListRefCnt final : public FontFamilyList {
     295             : public:
     296          16 :     FontFamilyListRefCnt()
     297          16 :         : FontFamilyList()
     298          16 :     {}
     299             : 
     300             :     explicit FontFamilyListRefCnt(FontFamilyType aGenericType)
     301             :         : FontFamilyList(aGenericType)
     302             :     {}
     303             : 
     304             :     FontFamilyListRefCnt(const nsAString& aFamilyName,
     305             :                          QuotedName aQuoted)
     306             :         : FontFamilyList(aFamilyName, aQuoted)
     307             :     {}
     308             : 
     309             :     FontFamilyListRefCnt(const FontFamilyListRefCnt& aOther)
     310             :         : FontFamilyList(aOther)
     311             :     {}
     312             : 
     313          80 :     NS_INLINE_DECL_REFCOUNTING(FontFamilyListRefCnt);
     314             : 
     315             : private:
     316           0 :     ~FontFamilyListRefCnt() {}
     317             : };
     318             : 
     319             : struct RGBAColorData
     320             : {
     321             :   // 1.0 means 100% for all components, but the value may fall outside
     322             :   // the range of [0.0, 1.0], so it is necessary to clamp them when
     323             :   // converting to nscolor.
     324             :   float mR;
     325             :   float mG;
     326             :   float mB;
     327             :   float mA;
     328             : 
     329           0 :   RGBAColorData() = default;
     330           0 :   MOZ_IMPLICIT RGBAColorData(nscolor aColor)
     331           0 :     : mR(NS_GET_R(aColor) * (1.0f / 255.0f))
     332           0 :     , mG(NS_GET_G(aColor) * (1.0f / 255.0f))
     333           0 :     , mB(NS_GET_B(aColor) * (1.0f / 255.0f))
     334           0 :     , mA(NS_GET_A(aColor) * (1.0f / 255.0f))
     335           0 :   {}
     336           0 :   RGBAColorData(float aR, float aG, float aB, float aA)
     337           0 :     : mR(aR), mG(aG), mB(aB), mA(aA) {}
     338             : 
     339           0 :   bool operator==(const RGBAColorData& aOther) const
     340             :   {
     341           0 :     return mR == aOther.mR && mG == aOther.mG &&
     342           0 :            mB == aOther.mB && mA == aOther.mA;
     343             :   }
     344             :   bool operator!=(const RGBAColorData& aOther) const
     345             :   {
     346             :     return !(*this == aOther);
     347             :   }
     348             : 
     349           0 :   nscolor ToColor() const
     350             :   {
     351           0 :     return NS_RGBA(ClampColor(mR * 255.0f),
     352             :                    ClampColor(mG * 255.0f),
     353             :                    ClampColor(mB * 255.0f),
     354             :                    ClampColor(mA * 255.0f));
     355             :   }
     356             : 
     357           0 :   RGBAColorData WithAlpha(float aAlpha) const
     358             :   {
     359           0 :     RGBAColorData result = *this;
     360           0 :     result.mA = aAlpha;
     361           0 :     return result;
     362             :   }
     363             : };
     364             : 
     365             : struct ComplexColorData
     366             : {
     367             :   RGBAColorData mColor;
     368             :   float mForegroundRatio;
     369             : 
     370           0 :   ComplexColorData() = default;
     371           0 :   ComplexColorData(const RGBAColorData& aColor, float aForegroundRatio)
     372           0 :     : mColor(aColor), mForegroundRatio(aForegroundRatio) {}
     373             :   ComplexColorData(nscolor aColor, float aForegroundRatio)
     374             :     : mColor(aColor), mForegroundRatio(aForegroundRatio) {}
     375           0 :   explicit ComplexColorData(const StyleComplexColor& aColor)
     376           0 :     : mColor(aColor.mColor)
     377           0 :     , mForegroundRatio(aColor.mForegroundRatio * (1.0f / 255.0f)) {}
     378             : 
     379           0 :   bool operator==(const ComplexColorData& aOther) const
     380             :   {
     381           0 :     return mForegroundRatio == aOther.mForegroundRatio &&
     382           0 :            (IsCurrentColor() || mColor == aOther.mColor);
     383             :   }
     384             :   bool operator!=(const ComplexColorData& aOther) const
     385             :   {
     386             :     return !(*this == aOther);
     387             :   }
     388             : 
     389           0 :   bool IsCurrentColor() const { return mForegroundRatio >= 1.0f; }
     390           0 :   bool IsNumericColor() const { return mForegroundRatio <= 0.0f; }
     391             : 
     392           0 :   StyleComplexColor ToComplexColor() const
     393             :   {
     394           0 :     return {mColor.ToColor(), ClampColor(mForegroundRatio * 255.0f)};
     395             :   }
     396             : };
     397             : 
     398             : struct ComplexColorValue final : public ComplexColorData
     399             : {
     400             :   // Just redirect any parameter to the data struct.
     401             :   template<typename... Args>
     402           0 :   explicit ComplexColorValue(Args&&... aArgs)
     403           0 :     : ComplexColorData(Forward<Args>(aArgs)...) {}
     404             :   ComplexColorValue(const ComplexColorValue&) = delete;
     405             : 
     406           0 :   NS_INLINE_DECL_REFCOUNTING(ComplexColorValue)
     407             : 
     408             :   size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const;
     409             : 
     410             : private:
     411           0 :   ~ComplexColorValue() {}
     412             : };
     413             : 
     414             : } // namespace css
     415             : } // namespace mozilla
     416             : 
     417             : enum nsCSSUnit {
     418             :   eCSSUnit_Null         = 0,      // (n/a) null unit, value is not specified
     419             :   eCSSUnit_Auto         = 1,      // (n/a) value is algorithmic
     420             :   eCSSUnit_Inherit      = 2,      // (n/a) value is inherited
     421             :   eCSSUnit_Initial      = 3,      // (n/a) value is default UA value
     422             :   eCSSUnit_Unset        = 4,      // (n/a) value equivalent to 'initial' if on a reset property, 'inherit' otherwise
     423             :   eCSSUnit_None         = 5,      // (n/a) value is none
     424             :   eCSSUnit_Normal       = 6,      // (n/a) value is normal (algorithmic, different than auto)
     425             :   eCSSUnit_System_Font  = 7,      // (n/a) value is -moz-use-system-font
     426             :   eCSSUnit_All          = 8,      // (n/a) value is all
     427             :   eCSSUnit_Dummy        = 9,      // (n/a) a fake but specified value, used
     428             :                                   //       only in temporary values
     429             :   eCSSUnit_DummyInherit = 10,     // (n/a) a fake but specified value, used
     430             :                                   //       only in temporary values
     431             : 
     432             :   eCSSUnit_String       = 11,     // (char16_t*) a string value
     433             :   eCSSUnit_Ident        = 12,     // (char16_t*) a string value
     434             :   eCSSUnit_Attr         = 14,     // (char16_t*) a attr(string) value
     435             :   eCSSUnit_Local_Font   = 15,     // (char16_t*) a local font name
     436             :   eCSSUnit_Font_Format  = 16,     // (char16_t*) a font format name
     437             :   eCSSUnit_Element      = 17,     // (char16_t*) an element id
     438             : 
     439             :   eCSSUnit_Array        = 20,     // (nsCSSValue::Array*) a list of values
     440             :   eCSSUnit_Counter      = 21,     // (nsCSSValue::Array*) a counter(string,[string]) value
     441             :   eCSSUnit_Counters     = 22,     // (nsCSSValue::Array*) a counters(string,string[,string]) value
     442             :   eCSSUnit_Cubic_Bezier = 23,     // (nsCSSValue::Array*) a list of float values
     443             :   eCSSUnit_Steps        = 24,     // (nsCSSValue::Array*) a list of (integer, enumerated)
     444             :   eCSSUnit_Symbols      = 25,     // (nsCSSValue::Array*) a symbols(enumerated, symbols) value
     445             :   eCSSUnit_Function     = 26,     // (nsCSSValue::Array*) a function with
     446             :                                   //  parameters.  First elem of array is name,
     447             :                                   //  an nsCSSKeyword as eCSSUnit_Enumerated,
     448             :                                   //  the rest of the values are arguments.
     449             : 
     450             :   // The top level of a calc() expression is eCSSUnit_Calc.  All
     451             :   // remaining eCSSUnit_Calc_* units only occur inside these toplevel
     452             :   // calc values.
     453             : 
     454             :   // eCSSUnit_Calc has an array with exactly 1 element.  eCSSUnit_Calc
     455             :   // exists so we can distinguish calc(2em) from 2em as specified values
     456             :   // (but we drop this distinction for nsStyleCoord when we store
     457             :   // computed values).
     458             :   eCSSUnit_Calc         = 30,     // (nsCSSValue::Array*) calc() value
     459             :   // Plus, Minus, Times_* and Divided have arrays with exactly 2
     460             :   // elements.  a + b + c + d is grouped as ((a + b) + c) + d
     461             :   eCSSUnit_Calc_Plus    = 31,     // (nsCSSValue::Array*) + node within calc()
     462             :   eCSSUnit_Calc_Minus   = 32,     // (nsCSSValue::Array*) - within calc
     463             :   eCSSUnit_Calc_Times_L = 33,     // (nsCSSValue::Array*) num * val within calc
     464             :   eCSSUnit_Calc_Times_R = 34,     // (nsCSSValue::Array*) val * num within calc
     465             :   eCSSUnit_Calc_Divided = 35,     // (nsCSSValue::Array*) / within calc
     466             : 
     467             :   eCSSUnit_URL          = 40,     // (nsCSSValue::URL*) value
     468             :   eCSSUnit_Image        = 41,     // (nsCSSValue::Image*) value
     469             :   eCSSUnit_Gradient     = 42,     // (nsCSSValueGradient*) value
     470             :   eCSSUnit_TokenStream  = 43,     // (nsCSSValueTokenStream*) value
     471             :   eCSSUnit_GridTemplateAreas   = 44,   // (GridTemplateAreasValue*)
     472             :                                        // for grid-template-areas
     473             : 
     474             :   eCSSUnit_Pair         = 50,     // (nsCSSValuePair*) pair of values
     475             :   eCSSUnit_Triplet      = 51,     // (nsCSSValueTriplet*) triplet of values
     476             :   eCSSUnit_Rect         = 52,     // (nsCSSRect*) rectangle (four values)
     477             :   eCSSUnit_List         = 53,     // (nsCSSValueList*) list of values
     478             :   eCSSUnit_ListDep      = 54,     // (nsCSSValueList*) same as List
     479             :                                   //   but does not own the list
     480             :   eCSSUnit_SharedList   = 55,     // (nsCSSValueSharedList*) same as list
     481             :                                   //   but reference counted and shared
     482             :   eCSSUnit_PairList     = 56,     // (nsCSSValuePairList*) list of value pairs
     483             :   eCSSUnit_PairListDep  = 57,     // (nsCSSValuePairList*) same as PairList
     484             :                                   //   but does not own the list
     485             : 
     486             :   eCSSUnit_FontFamilyList = 58,   // (FontFamilyList*) value
     487             : 
     488             :   // Atom units
     489             :   eCSSUnit_AtomIdent    = 60,     // (nsIAtom*) for its string as an identifier
     490             : 
     491             :   eCSSUnit_Integer      = 70,     // (int) simple value
     492             :   eCSSUnit_Enumerated   = 71,     // (int) value has enumerated meaning
     493             : 
     494             :   eCSSUnit_EnumColor           = 80,   // (int) enumerated color (kColorKTable)
     495             :   eCSSUnit_RGBColor            = 81,   // (nscolor) an opaque RGBA value specified as rgb()
     496             :   eCSSUnit_RGBAColor           = 82,   // (nscolor) an RGBA value specified as rgba()
     497             :   eCSSUnit_HexColor            = 83,   // (nscolor) an opaque RGBA value specified as #rrggbb
     498             :   eCSSUnit_ShortHexColor       = 84,   // (nscolor) an opaque RGBA value specified as #rgb
     499             :   eCSSUnit_HexColorAlpha       = 85,   // (nscolor) an opaque RGBA value specified as #rrggbbaa
     500             :   eCSSUnit_ShortHexColorAlpha  = 86,   // (nscolor) an opaque RGBA value specified as #rgba
     501             :   eCSSUnit_PercentageRGBColor  = 87,   // (nsCSSValueFloatColor*) an opaque
     502             :                                        // RGBA value specified as rgb() with
     503             :                                        // percentage components. Values over
     504             :                                        // 100% are allowed.
     505             :   eCSSUnit_PercentageRGBAColor = 88,   // (nsCSSValueFloatColor*) an RGBA value
     506             :                                        // specified as rgba() with percentage
     507             :                                        // components. Values over 100% are
     508             :                                        // allowed.
     509             :   eCSSUnit_HSLColor            = 89,   // (nsCSSValueFloatColor*)
     510             :   eCSSUnit_HSLAColor           = 90,   // (nsCSSValueFloatColor*)
     511             :   eCSSUnit_ComplexColor        = 91,   // (ComplexColorValue*)
     512             : 
     513             :   eCSSUnit_Percent      = 100,     // (float) 1.0 == 100%) value is percentage of something
     514             :   eCSSUnit_Number       = 101,     // (float) value is numeric (usually multiplier, different behavior than percent)
     515             : 
     516             :   // Physical length units
     517             :   eCSSUnit_PhysicalMillimeter = 200,   // (float) 1/25.4 inch
     518             : 
     519             :   // Length units - relative
     520             :   // Viewport relative measure
     521             :   eCSSUnit_ViewportWidth  = 700,    // (float) 1% of the width of the initial containing block
     522             :   eCSSUnit_ViewportHeight = 701,    // (float) 1% of the height of the initial containing block
     523             :   eCSSUnit_ViewportMin    = 702,    // (float) smaller of ViewportWidth and ViewportHeight
     524             :   eCSSUnit_ViewportMax    = 703,    // (float) larger of ViewportWidth and ViewportHeight
     525             : 
     526             :   // Font relative measure
     527             :   eCSSUnit_EM           = 800,    // (float) == current font size
     528             :   eCSSUnit_XHeight      = 801,    // (float) distance from top of lower case x to baseline
     529             :   eCSSUnit_Char         = 802,    // (float) number of characters, used for width with monospace font
     530             :   eCSSUnit_RootEM       = 803,    // (float) == root element font size
     531             : 
     532             :   // Screen relative measure
     533             :   eCSSUnit_Point        = 900,    // (float) 4/3 of a CSS pixel
     534             :   eCSSUnit_Inch         = 901,    // (float) 96 CSS pixels
     535             :   eCSSUnit_Millimeter   = 902,    // (float) 96/25.4 CSS pixels
     536             :   eCSSUnit_Centimeter   = 903,    // (float) 96/2.54 CSS pixels
     537             :   eCSSUnit_Pica         = 904,    // (float) 12 points == 16 CSS pixls
     538             :   eCSSUnit_Quarter      = 905,    // (float) 96/101.6 CSS pixels
     539             :   eCSSUnit_Pixel        = 906,    // (float) CSS pixel unit
     540             : 
     541             :   // Angular units
     542             :   eCSSUnit_Degree       = 1000,    // (float) 360 per circle
     543             :   eCSSUnit_Grad         = 1001,    // (float) 400 per circle
     544             :   eCSSUnit_Radian       = 1002,    // (float) 2*pi per circle
     545             :   eCSSUnit_Turn         = 1003,    // (float) 1 per circle
     546             : 
     547             :   // Frequency units
     548             :   eCSSUnit_Hertz        = 2000,    // (float) 1/seconds
     549             :   eCSSUnit_Kilohertz    = 2001,    // (float) 1000 Hertz
     550             : 
     551             :   // Time units
     552             :   eCSSUnit_Seconds      = 3000,    // (float) Standard time
     553             :   eCSSUnit_Milliseconds = 3001,    // (float) 1/1000 second
     554             : 
     555             :   // Flexible fraction (CSS Grid)
     556             :   eCSSUnit_FlexFraction = 4000     // (float) Fraction of free space
     557             : };
     558             : 
     559             : struct nsCSSValueGradient;
     560             : struct nsCSSValuePair;
     561             : struct nsCSSValuePair_heap;
     562             : struct nsCSSValueTokenStream;
     563             : struct nsCSSRect;
     564             : struct nsCSSRect_heap;
     565             : struct nsCSSValueList;
     566             : struct nsCSSValueList_heap;
     567             : struct nsCSSValueSharedList;
     568             : struct nsCSSValuePairList;
     569             : struct nsCSSValuePairList_heap;
     570             : struct nsCSSValueTriplet;
     571             : struct nsCSSValueTriplet_heap;
     572             : class nsCSSValueFloatColor;
     573             : 
     574             : class nsCSSValue {
     575             : public:
     576             :   struct Array;
     577             :   friend struct Array;
     578             : 
     579             :   friend struct mozilla::css::URLValueData;
     580             : 
     581             :   friend struct mozilla::css::ImageValue;
     582             : 
     583             :   // for valueless units only (null, auto, inherit, none, all, normal)
     584      230562 :   explicit nsCSSValue(nsCSSUnit aUnit = eCSSUnit_Null)
     585      230562 :     : mUnit(aUnit)
     586             :   {
     587      230562 :     MOZ_ASSERT(aUnit <= eCSSUnit_DummyInherit, "not a valueless unit");
     588      230562 :   }
     589             : 
     590             :   nsCSSValue(int32_t aValue, nsCSSUnit aUnit);
     591             :   nsCSSValue(float aValue, nsCSSUnit aUnit);
     592             :   nsCSSValue(const nsString& aValue, nsCSSUnit aUnit);
     593             :   nsCSSValue(Array* aArray, nsCSSUnit aUnit);
     594             :   explicit nsCSSValue(mozilla::css::URLValue* aValue);
     595             :   explicit nsCSSValue(mozilla::css::ImageValue* aValue);
     596             :   explicit nsCSSValue(nsCSSValueGradient* aValue);
     597             :   explicit nsCSSValue(nsCSSValueTokenStream* aValue);
     598             :   explicit nsCSSValue(mozilla::css::GridTemplateAreasValue* aValue);
     599             :   explicit nsCSSValue(mozilla::css::FontFamilyListRefCnt* aValue);
     600             :   nsCSSValue(const nsCSSValue& aCopy);
     601           8 :   nsCSSValue(nsCSSValue&& aOther)
     602           8 :     : mUnit(aOther.mUnit)
     603           8 :     , mValue(aOther.mValue)
     604             :   {
     605           8 :     aOther.mUnit = eCSSUnit_Null;
     606           8 :   }
     607      209590 :   ~nsCSSValue() { Reset(); }
     608             : 
     609             :   nsCSSValue&  operator=(const nsCSSValue& aCopy);
     610             :   nsCSSValue&  operator=(nsCSSValue&& aCopy);
     611             :   bool        operator==(const nsCSSValue& aOther) const;
     612             : 
     613       13020 :   bool operator!=(const nsCSSValue& aOther) const
     614             :   {
     615       13020 :     return !(*this == aOther);
     616             :   }
     617             : 
     618             :   // Enum for AppendToString's aValueSerialization argument.
     619             :   enum Serialization { eNormalized, eAuthorSpecified };
     620             : 
     621             :   /**
     622             :    * Serialize |this| as a specified value for |aProperty| and append
     623             :    * it to |aResult|.
     624             :    */
     625             :   void AppendToString(nsCSSPropertyID aProperty, nsAString& aResult,
     626             :                       Serialization aValueSerialization) const;
     627             : 
     628     7687071 :   nsCSSUnit GetUnit() const { return mUnit; }
     629        9265 :   bool      IsLengthUnit() const
     630        9265 :     { return eCSSUnit_PhysicalMillimeter <= mUnit && mUnit <= eCSSUnit_Pixel; }
     631           0 :   bool      IsLengthPercentCalcUnit() const
     632           0 :     { return IsLengthUnit() || mUnit == eCSSUnit_Percent || IsCalcUnit(); }
     633             :   /**
     634             :    * A "fixed" length unit is one that means a specific physical length
     635             :    * which we try to match based on the physical characteristics of an
     636             :    * output device.
     637             :    */
     638        2514 :   bool      IsFixedLengthUnit() const
     639        2514 :     { return mUnit == eCSSUnit_PhysicalMillimeter; }
     640             :   /**
     641             :    * What the spec calls relative length units is, for us, split
     642             :    * between relative length units and pixel length units.
     643             :    *
     644             :    * A "relative" length unit is a multiple of some derived metric,
     645             :    * such as a font em-size, which itself was controlled by an input CSS
     646             :    * length. Relative length units should not be scaled by zooming, since
     647             :    * the underlying CSS length would already have been scaled.
     648             :    */
     649         640 :   bool      IsRelativeLengthUnit() const
     650         640 :     { return eCSSUnit_EM <= mUnit && mUnit <= eCSSUnit_RootEM; }
     651             :   /**
     652             :    * A "pixel" length unit is a some multiple of CSS pixels.
     653             :    */
     654        5009 :   static bool IsPixelLengthUnit(nsCSSUnit aUnit)
     655        5009 :     { return eCSSUnit_Point <= aUnit && aUnit <= eCSSUnit_Pixel; }
     656        5009 :   bool      IsPixelLengthUnit() const
     657        5009 :     { return IsPixelLengthUnit(mUnit); }
     658           0 :   static bool IsPercentLengthUnit(nsCSSUnit aUnit)
     659           0 :     { return aUnit == eCSSUnit_Percent; }
     660           0 :   bool      IsPercentLengthUnit()
     661           0 :     { return IsPercentLengthUnit(mUnit); }
     662       11527 :   static bool IsFloatUnit(nsCSSUnit aUnit)
     663       11527 :     { return eCSSUnit_Number <= aUnit; }
     664         157 :   bool      IsAngularUnit() const
     665         157 :     { return eCSSUnit_Degree <= mUnit && mUnit <= eCSSUnit_Turn; }
     666             :   bool      IsFrequencyUnit() const
     667             :     { return eCSSUnit_Hertz <= mUnit && mUnit <= eCSSUnit_Kilohertz; }
     668             :   bool      IsTimeUnit() const
     669             :     { return eCSSUnit_Seconds <= mUnit && mUnit <= eCSSUnit_Milliseconds; }
     670         671 :   bool      IsCalcUnit() const
     671         671 :     { return eCSSUnit_Calc <= mUnit && mUnit <= eCSSUnit_Calc_Divided; }
     672             : 
     673       70982 :   bool      UnitHasStringValue() const
     674       70982 :     { return eCSSUnit_String <= mUnit && mUnit <= eCSSUnit_Element; }
     675       51933 :   bool      UnitHasArrayValue() const
     676       51933 :     { return eCSSUnit_Array <= mUnit && mUnit <= eCSSUnit_Calc_Divided; }
     677             : 
     678             :   // Checks for the nsCSSValue being of a particular type of color unit:
     679             :   //
     680             :   //   - IsIntegerColorUnit returns true for:
     681             :   //       eCSSUnit_RGBColor             -- rgb(int,int,int)
     682             :   //       eCSSUnit_RGBAColor            -- rgba(int,int,int,float)
     683             :   //       eCSSUnit_HexColor             -- #rrggbb
     684             :   //       eCSSUnit_ShortHexColor        -- #rgb
     685             :   //       eCSSUnit_HexColorAlpha        -- #rrggbbaa
     686             :   //       eCSSUnit_ShortHexColorAlpha   -- #rgba
     687             :   //
     688             :   //   - IsFloatColorUnit returns true for:
     689             :   //       eCSSUnit_PercentageRGBColor   -- rgb(%,%,%)
     690             :   //       eCSSUnit_PercentageRGBAColor  -- rgba(%,%,%,float)
     691             :   //       eCSSUnit_HSLColor             -- hsl(float,%,%)
     692             :   //       eCSSUnit_HSLAColor            -- hsla(float,%,%,float)
     693             :   //
     694             :   //   - IsNumericColorUnit returns true for any of the above units.
     695             :   //
     696             :   // Note that color keywords and system colors are represented by
     697             :   // eCSSUnit_EnumColor and eCSSUnit_Ident.
     698       10063 :   bool IsIntegerColorUnit() const { return IsIntegerColorUnit(mUnit); }
     699       51546 :   bool IsFloatColorUnit() const { return IsFloatColorUnit(mUnit); }
     700         885 :   bool IsNumericColorUnit() const { return IsNumericColorUnit(mUnit); }
     701       10948 :   static bool IsIntegerColorUnit(nsCSSUnit aUnit)
     702       10948 :   { return eCSSUnit_RGBColor <= aUnit && aUnit <= eCSSUnit_ShortHexColorAlpha; }
     703       52092 :   static bool IsFloatColorUnit(nsCSSUnit aUnit)
     704       72958 :   { return eCSSUnit_PercentageRGBColor <= aUnit &&
     705       72958 :            aUnit <= eCSSUnit_HSLAColor; }
     706         885 :   static bool IsNumericColorUnit(nsCSSUnit aUnit)
     707         885 :   { return IsIntegerColorUnit(aUnit) || IsFloatColorUnit(aUnit); }
     708             : 
     709        5851 :   int32_t GetIntValue() const
     710             :   {
     711        5851 :     MOZ_ASSERT(mUnit == eCSSUnit_Integer ||
     712             :                mUnit == eCSSUnit_Enumerated ||
     713             :                mUnit == eCSSUnit_EnumColor,
     714             :                "not an int value");
     715        5851 :     return mValue.mInt;
     716             :   }
     717             : 
     718          56 :   nsCSSKeyword GetKeywordValue() const
     719             :   {
     720          56 :     MOZ_ASSERT(mUnit == eCSSUnit_Enumerated, "not a keyword value");
     721          56 :     return static_cast<nsCSSKeyword>(mValue.mInt);
     722             :   }
     723             : 
     724         421 :   float GetPercentValue() const
     725             :   {
     726         421 :     MOZ_ASSERT(mUnit == eCSSUnit_Percent, "not a percent value");
     727         421 :     return mValue.mFloat;
     728             :   }
     729             : 
     730        4283 :   float GetFloatValue() const
     731             :   {
     732        4283 :     MOZ_ASSERT(eCSSUnit_Number <= mUnit, "not a float value");
     733        4283 :     MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat));
     734        4283 :     return mValue.mFloat;
     735             :   }
     736             : 
     737           0 :   float GetAngleValue() const
     738             :   {
     739           0 :     MOZ_ASSERT(eCSSUnit_Degree <= mUnit && mUnit <= eCSSUnit_Turn,
     740             :                "not an angle value");
     741           0 :     return mValue.mFloat;
     742             :   }
     743             : 
     744             :   // Converts any angle to radians.
     745             :   double GetAngleValueInRadians() const;
     746             : 
     747             :   // Converts any angle to degrees.
     748             :   double GetAngleValueInDegrees() const;
     749             : 
     750         141 :   nsAString& GetStringValue(nsAString& aBuffer) const
     751             :   {
     752         141 :     MOZ_ASSERT(UnitHasStringValue(), "not a string value");
     753         141 :     aBuffer.Truncate();
     754         141 :     uint32_t len = NS_strlen(GetBufferValue(mValue.mString));
     755         141 :     mValue.mString->ToString(len, aBuffer);
     756         141 :     return aBuffer;
     757             :   }
     758             : 
     759         247 :   const char16_t* GetStringBufferValue() const
     760             :   {
     761         247 :     MOZ_ASSERT(UnitHasStringValue(), "not a string value");
     762         247 :     return GetBufferValue(mValue.mString);
     763             :   }
     764             : 
     765             :   nscolor GetColorValue() const;
     766             :   bool IsNonTransparentColor() const;
     767           0 :   mozilla::StyleComplexColor GetStyleComplexColorValue() const
     768             :   {
     769           0 :     MOZ_ASSERT(mUnit == eCSSUnit_ComplexColor);
     770           0 :     return mValue.mComplexColor->ToComplexColor();
     771             :   }
     772             : 
     773         748 :   Array* GetArrayValue() const
     774             :   {
     775         748 :     MOZ_ASSERT(UnitHasArrayValue(), "not an array value");
     776         748 :     return mValue.mArray;
     777             :   }
     778             : 
     779           0 :   nsIURI* GetURLValue() const
     780             :   {
     781           0 :     MOZ_ASSERT(mUnit == eCSSUnit_URL || mUnit == eCSSUnit_Image,
     782             :                "not a URL value");
     783           0 :     return mUnit == eCSSUnit_URL ?
     784           0 :       mValue.mURL->GetURI() : mValue.mImage->GetURI();
     785             :   }
     786             : 
     787          15 :   nsCSSValueGradient* GetGradientValue() const
     788             :   {
     789          15 :     MOZ_ASSERT(mUnit == eCSSUnit_Gradient, "not a gradient value");
     790          15 :     return mValue.mGradient;
     791             :   }
     792             : 
     793        2649 :   nsCSSValueTokenStream* GetTokenStreamValue() const
     794             :   {
     795        2649 :     MOZ_ASSERT(mUnit == eCSSUnit_TokenStream, "not a token stream value");
     796        2649 :     return mValue.mTokenStream;
     797             :   }
     798             : 
     799          16 :   nsCSSValueSharedList* GetSharedListValue() const
     800             :   {
     801          16 :     MOZ_ASSERT(mUnit == eCSSUnit_SharedList, "not a shared list value");
     802          16 :     return mValue.mSharedList;
     803             :   }
     804             : 
     805           0 :   mozilla::FontFamilyList* GetFontFamilyListValue() const
     806             :   {
     807           0 :     MOZ_ASSERT(mUnit == eCSSUnit_FontFamilyList,
     808             :                "not a font family list value");
     809           0 :     NS_ASSERTION(mValue.mFontFamilyList != nullptr,
     810             :                  "font family list value should never be null");
     811           0 :     return mValue.mFontFamilyList;
     812             :   }
     813             : 
     814             :   // bodies of these are below
     815             :   inline nsCSSValuePair& GetPairValue();
     816             :   inline const nsCSSValuePair& GetPairValue() const;
     817             : 
     818             :   inline nsCSSRect& GetRectValue();
     819             :   inline const nsCSSRect& GetRectValue() const;
     820             : 
     821             :   inline nsCSSValueList* GetListValue();
     822             :   inline const nsCSSValueList* GetListValue() const;
     823             : 
     824             :   inline nsCSSValuePairList* GetPairListValue();
     825             :   inline const nsCSSValuePairList* GetPairListValue() const;
     826             : 
     827             :   inline nsCSSValueTriplet& GetTripletValue();
     828             :   inline const nsCSSValueTriplet& GetTripletValue() const;
     829             : 
     830             : 
     831         244 :   mozilla::css::URLValue* GetURLStructValue() const
     832             :   {
     833             :     // Not allowing this for Image values, because if the caller takes
     834             :     // a ref to them they won't be able to delete them properly.
     835         244 :     MOZ_ASSERT(mUnit == eCSSUnit_URL, "not a URL value");
     836         244 :     return mValue.mURL;
     837             :   }
     838             : 
     839         242 :   mozilla::css::ImageValue* GetImageStructValue() const
     840             :   {
     841         242 :     MOZ_ASSERT(mUnit == eCSSUnit_Image, "not an Image value");
     842         242 :     return mValue.mImage;
     843             :   }
     844             : 
     845           0 :   mozilla::css::GridTemplateAreasValue* GetGridTemplateAreas() const
     846             :   {
     847           0 :     MOZ_ASSERT(mUnit == eCSSUnit_GridTemplateAreas,
     848             :                "not a grid-template-areas value");
     849           0 :     return mValue.mGridTemplateAreas;
     850             :   }
     851             : 
     852           0 :   const char16_t* GetOriginalURLValue() const
     853             :   {
     854           0 :     MOZ_ASSERT(mUnit == eCSSUnit_URL || mUnit == eCSSUnit_Image,
     855             :                "not a URL value");
     856           0 :     return mUnit == eCSSUnit_URL ?
     857           0 :              mValue.mURL->mString.get() :
     858           0 :              mValue.mImage->mString.get();
     859             :   }
     860             : 
     861             :   // Not making this inline because that would force us to include
     862             :   // imgIRequest.h, which leads to REQUIRES hell, since this header is included
     863             :   // all over.
     864             :   imgRequestProxy* GetImageValue(nsIDocument* aDocument) const;
     865             : 
     866             :   // Like GetImageValue, but additionally will pass the imgRequestProxy
     867             :   // through nsContentUtils::GetStaticRequest if aPresContent is static.
     868             :   already_AddRefed<imgRequestProxy> GetPossiblyStaticImageValue(
     869             :       nsIDocument* aDocument, nsPresContext* aPresContext) const;
     870             : 
     871             :   nscoord GetFixedLength(nsPresContext* aPresContext) const;
     872             :   nscoord GetPixelLength() const;
     873             : 
     874           0 :   nsCSSValueFloatColor* GetFloatColorValue() const
     875             :   {
     876           0 :     MOZ_ASSERT(IsFloatColorUnit(), "not a float color value");
     877           0 :     return mValue.mFloatColor;
     878             :   }
     879             : 
     880          72 :   nsIAtom* GetAtomValue() const {
     881          72 :     MOZ_ASSERT(mUnit == eCSSUnit_AtomIdent);
     882          72 :     return mValue.mAtom;
     883             :   }
     884             : 
     885      279968 :   void Reset()  // sets to null
     886             :   {
     887      279968 :     if (mUnit != eCSSUnit_Null)
     888       44454 :       DoReset();
     889      279968 :   }
     890             : private:
     891             :   void DoReset();
     892             : 
     893             : public:
     894             :   void SetIntValue(int32_t aValue, nsCSSUnit aUnit);
     895             :   template<typename T,
     896             :            typename = typename std::enable_if<std::is_enum<T>::value>::type>
     897         132 :   void SetEnumValue(T aValue)
     898             :   {
     899             :     static_assert(mozilla::EnumTypeFitsWithin<T, int32_t>::value,
     900             :                   "aValue must be an enum that fits within mValue.mInt");
     901         132 :     SetIntValue(static_cast<int32_t>(aValue), eCSSUnit_Enumerated);
     902         132 :   }
     903             :   void SetPercentValue(float aValue);
     904             :   void SetFloatValue(float aValue, nsCSSUnit aUnit);
     905             :   void SetStringValue(const nsString& aValue, nsCSSUnit aUnit);
     906             :   void SetAtomIdentValue(already_AddRefed<nsIAtom> aValue);
     907             :   void SetColorValue(nscolor aValue);
     908             :   void SetIntegerColorValue(nscolor aValue, nsCSSUnit aUnit);
     909             :   // converts the nscoord to pixels
     910             :   void SetIntegerCoordValue(nscoord aCoord);
     911             :   void SetFloatColorValue(float aComponent1,
     912             :                           float aComponent2,
     913             :                           float aComponent3,
     914             :                           float aAlpha, nsCSSUnit aUnit);
     915             :   void SetRGBAColorValue(const mozilla::css::RGBAColorData& aValue);
     916             :   void SetComplexColorValue(
     917             :     already_AddRefed<mozilla::css::ComplexColorValue> aValue);
     918             :   void SetArrayValue(nsCSSValue::Array* aArray, nsCSSUnit aUnit);
     919             :   void SetURLValue(mozilla::css::URLValue* aURI);
     920             :   void SetImageValue(mozilla::css::ImageValue* aImage);
     921             :   void SetGradientValue(nsCSSValueGradient* aGradient);
     922             :   void SetTokenStreamValue(nsCSSValueTokenStream* aTokenStream);
     923             :   void SetGridTemplateAreas(mozilla::css::GridTemplateAreasValue* aValue);
     924             :   void SetFontFamilyListValue(mozilla::css::FontFamilyListRefCnt* aFontListValue);
     925             :   void SetPairValue(const nsCSSValuePair* aPair);
     926             :   void SetPairValue(const nsCSSValue& xValue, const nsCSSValue& yValue);
     927             :   void SetSharedListValue(nsCSSValueSharedList* aList);
     928             :   void SetDependentListValue(nsCSSValueList* aList);
     929             :   void SetDependentPairListValue(nsCSSValuePairList* aList);
     930             :   void SetTripletValue(const nsCSSValueTriplet* aTriplet);
     931             :   void SetTripletValue(const nsCSSValue& xValue, const nsCSSValue& yValue, const nsCSSValue& zValue);
     932             :   void SetAutoValue();
     933             :   void SetInheritValue();
     934             :   void SetInitialValue();
     935             :   void SetUnsetValue();
     936             :   void SetNoneValue();
     937             :   void SetAllValue();
     938             :   void SetNormalValue();
     939             :   void SetSystemFontValue();
     940             :   void SetDummyValue();
     941             :   void SetDummyInheritValue();
     942             : 
     943             :   // Converts an nsStyleCoord::CalcValue back into a CSSValue
     944             :   void SetCalcValue(const nsStyleCoord::CalcValue* aCalc);
     945             : 
     946             :   nsStyleCoord::CalcValue GetCalcValue() const;
     947             : 
     948             :   // These are a little different - they allocate storage for you and
     949             :   // return a handle.
     950             :   nsCSSRect& SetRectValue();
     951             :   nsCSSValueList* SetListValue();
     952             :   nsCSSValuePairList* SetPairListValue();
     953             : 
     954             :   // These take ownership of the passed-in resource.
     955             :   void AdoptListValue(mozilla::UniquePtr<nsCSSValueList> aValue);
     956             :   void AdoptPairListValue(mozilla::UniquePtr<nsCSSValuePairList> aValue);
     957             : 
     958             :   void StartImageLoad(nsIDocument* aDocument) const;  // Only pretend const
     959             : 
     960             :   // Initializes as a function value with the specified function id.
     961             :   Array* InitFunction(nsCSSKeyword aFunctionId, uint32_t aNumArgs);
     962             :   // Checks if this is a function value with the specified function id.
     963             :   bool EqualsFunction(nsCSSKeyword aFunctionId) const;
     964             : 
     965             :   // Returns an already addrefed buffer.  Guaranteed to return non-null.
     966             :   // (Will abort on allocation failure.)
     967             :   static already_AddRefed<nsStringBuffer>
     968             :     BufferFromString(const nsString& aValue);
     969             : 
     970             :   // Convert the given Ident value into AtomIdent.
     971             :   void AtomizeIdentValue();
     972             : 
     973             :   size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
     974             : 
     975             :   static void
     976             :   AppendSidesShorthandToString(const nsCSSPropertyID aProperties[],
     977             :                                const nsCSSValue* aValues[],
     978             :                                nsAString& aString,
     979             :                                Serialization aSerialization);
     980             :   static void
     981             :   AppendBasicShapeRadiusToString(const nsCSSPropertyID aProperties[],
     982             :                                  const nsCSSValue* aValues[],
     983             :                                  nsAString& aResult,
     984             :                                  Serialization aValueSerialization);
     985             :   static void
     986             :   AppendAlignJustifyValueToString(int32_t aValue, nsAString& aResult);
     987             : 
     988             : private:
     989         388 :   static const char16_t* GetBufferValue(nsStringBuffer* aBuffer) {
     990         388 :     return static_cast<char16_t*>(aBuffer->Data());
     991             :   }
     992             : 
     993             :   void AppendPolygonToString(nsCSSPropertyID aProperty, nsAString& aResult,
     994             :                              Serialization aValueSerialization) const;
     995             :   void AppendPositionCoordinateToString(const nsCSSValue& aValue,
     996             :                                         nsCSSPropertyID aProperty,
     997             :                                         nsAString& aResult,
     998             :                                         Serialization aSerialization) const;
     999             :   void AppendCircleOrEllipseToString(
    1000             :            nsCSSKeyword aFunctionId,
    1001             :            nsCSSPropertyID aProperty, nsAString& aResult,
    1002             :            Serialization aValueSerialization) const;
    1003             :   void AppendBasicShapePositionToString(
    1004             :            nsAString& aResult,
    1005             :            Serialization aValueSerialization) const;
    1006             :   void AppendInsetToString(nsCSSPropertyID aProperty, nsAString& aResult,
    1007             :                            Serialization aValueSerialization) const;
    1008             : protected:
    1009             :   nsCSSUnit mUnit;
    1010             :   union {
    1011             :     int32_t    mInt;
    1012             :     float      mFloat;
    1013             :     // Note: the capacity of the buffer may exceed the length of the string.
    1014             :     // If we're of a string type, mString is not null.
    1015             :     nsStringBuffer* MOZ_OWNING_REF mString;
    1016             :     nscolor    mColor;
    1017             :     nsIAtom* MOZ_OWNING_REF mAtom;
    1018             :     Array* MOZ_OWNING_REF mArray;
    1019             :     mozilla::css::URLValue* MOZ_OWNING_REF mURL;
    1020             :     mozilla::css::ImageValue* MOZ_OWNING_REF mImage;
    1021             :     mozilla::css::GridTemplateAreasValue* MOZ_OWNING_REF mGridTemplateAreas;
    1022             :     nsCSSValueGradient* MOZ_OWNING_REF mGradient;
    1023             :     nsCSSValueTokenStream* MOZ_OWNING_REF mTokenStream;
    1024             :     nsCSSValuePair_heap* MOZ_OWNING_REF mPair;
    1025             :     nsCSSRect_heap* MOZ_OWNING_REF mRect;
    1026             :     nsCSSValueTriplet_heap* MOZ_OWNING_REF mTriplet;
    1027             :     nsCSSValueList_heap* MOZ_OWNING_REF mList;
    1028             :     nsCSSValueList* mListDependent;
    1029             :     nsCSSValueSharedList* MOZ_OWNING_REF mSharedList;
    1030             :     nsCSSValuePairList_heap* MOZ_OWNING_REF mPairList;
    1031             :     nsCSSValuePairList* mPairListDependent;
    1032             :     nsCSSValueFloatColor* MOZ_OWNING_REF mFloatColor;
    1033             :     mozilla::css::FontFamilyListRefCnt* MOZ_OWNING_REF mFontFamilyList;
    1034             :     mozilla::css::ComplexColorValue* MOZ_OWNING_REF mComplexColor;
    1035             :   } mValue;
    1036             : };
    1037             : 
    1038             : struct nsCSSValue::Array final {
    1039             : 
    1040             :   // return |Array| with reference count of zero
    1041        1059 :   static Array* Create(size_t aItemCount) {
    1042        1059 :     return new (aItemCount) Array(aItemCount);
    1043             :   }
    1044             : 
    1045        3849 :   nsCSSValue& operator[](size_t aIndex) {
    1046        3849 :     MOZ_ASSERT(aIndex < mCount, "out of range");
    1047        3849 :     return mArray[aIndex];
    1048             :   }
    1049             : 
    1050         150 :   const nsCSSValue& operator[](size_t aIndex) const {
    1051         150 :     MOZ_ASSERT(aIndex < mCount, "out of range");
    1052         150 :     return mArray[aIndex];
    1053             :   }
    1054             : 
    1055        3849 :   nsCSSValue& Item(size_t aIndex) { return (*this)[aIndex]; }
    1056         150 :   const nsCSSValue& Item(size_t aIndex) const { return (*this)[aIndex]; }
    1057             : 
    1058         497 :   size_t Count() const { return mCount; }
    1059             : 
    1060             :   // callers depend on the items being contiguous
    1061           0 :   nsCSSValue* ItemStorage() {
    1062           0 :     return this->First();
    1063             :   }
    1064             : 
    1065           0 :   bool operator==(const Array& aOther) const
    1066             :   {
    1067           0 :     if (mCount != aOther.mCount)
    1068           0 :       return false;
    1069           0 :     for (size_t i = 0; i < mCount; ++i)
    1070           0 :       if ((*this)[i] != aOther[i])
    1071           0 :         return false;
    1072           0 :     return true;
    1073             :   }
    1074             : 
    1075        5503 :   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Array);
    1076             : private:
    1077             : 
    1078             :   const size_t mCount;
    1079             :   // This must be the last sub-object, since we extend this array to
    1080             :   // be of size mCount; it needs to be a sub-object so it gets proper
    1081             :   // alignment.
    1082             :   nsCSSValue mArray[1];
    1083             : 
    1084        1059 :   void* operator new(size_t aSelfSize, size_t aItemCount) CPP_THROW_NEW {
    1085        1059 :     MOZ_ASSERT(aItemCount > 0, "cannot have a 0 item count");
    1086        2118 :     return ::operator new(aSelfSize + sizeof(nsCSSValue) * (aItemCount - 1));
    1087             :   }
    1088             : 
    1089        1194 :   void operator delete(void* aPtr) { ::operator delete(aPtr); }
    1090             : 
    1091        3312 :   nsCSSValue* First() { return mArray; }
    1092             : 
    1093             :   const nsCSSValue* First() const { return mArray; }
    1094             : 
    1095             : #define CSSVALUE_LIST_FOR_EXTRA_VALUES(var)                                   \
    1096             :   for (nsCSSValue *var = First() + 1, *var##_end = First() + mCount;          \
    1097             :        var != var##_end; ++var)
    1098             : 
    1099        1059 :   explicit Array(size_t aItemCount)
    1100        1059 :     : mRefCnt(0)
    1101        1059 :     , mCount(aItemCount)
    1102             :   {
    1103        2274 :     CSSVALUE_LIST_FOR_EXTRA_VALUES(val) {
    1104        1215 :       new (val) nsCSSValue();
    1105             :     }
    1106        1059 :   }
    1107             : 
    1108         597 :   ~Array()
    1109         597 :   {
    1110        1135 :     CSSVALUE_LIST_FOR_EXTRA_VALUES(val) {
    1111         538 :       val->~nsCSSValue();
    1112             :     }
    1113         597 :   }
    1114             : 
    1115             :   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
    1116             : 
    1117             : #undef CSSVALUE_LIST_FOR_EXTRA_VALUES
    1118             : 
    1119             : private:
    1120             :   Array(const Array& aOther) = delete;
    1121             :   Array& operator=(const Array& aOther) = delete;
    1122             : };
    1123             : 
    1124             : // Prefer nsCSSValue::Array for lists of fixed size.
    1125           0 : struct nsCSSValueList {
    1126        3317 :   nsCSSValueList() : mNext(nullptr) { MOZ_COUNT_CTOR(nsCSSValueList); }
    1127             :   ~nsCSSValueList();
    1128             : 
    1129             :   nsCSSValueList* Clone() const;  // makes a deep copy. Infallible.
    1130             :   void CloneInto(nsCSSValueList* aList) const; // makes a deep copy into aList
    1131             :   void AppendToString(nsCSSPropertyID aProperty, nsAString& aResult,
    1132             :                       nsCSSValue::Serialization aValueSerialization) const;
    1133             : 
    1134             :   static bool Equal(const nsCSSValueList* aList1,
    1135             :                     const nsCSSValueList* aList2);
    1136             : 
    1137             :   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
    1138             : 
    1139             :   nsCSSValue      mValue;
    1140             :   nsCSSValueList* mNext;
    1141             : 
    1142             : private:
    1143           0 :   nsCSSValueList(const nsCSSValueList& aCopy) // makes a shallow copy
    1144           0 :     : mValue(aCopy.mValue), mNext(nullptr)
    1145             :   {
    1146           0 :     MOZ_COUNT_CTOR(nsCSSValueList);
    1147           0 :   }
    1148             : 
    1149             :   // We don't want operator== or operator!= because they wouldn't be
    1150             :   // null-safe, which is generally what we need.  Use |Equal| method
    1151             :   // above instead.
    1152             :   bool operator==(nsCSSValueList const& aOther) const = delete;
    1153             :   bool operator!=(const nsCSSValueList& aOther) const = delete;
    1154             : };
    1155             : 
    1156             : // nsCSSValueList_heap differs from nsCSSValueList only in being
    1157             : // refcounted.  It should not be necessary to use this class directly;
    1158             : // it's an implementation detail of nsCSSValue.
    1159        1870 : struct nsCSSValueList_heap final : public nsCSSValueList {
    1160        7725 :   NS_INLINE_DECL_REFCOUNTING(nsCSSValueList_heap)
    1161             : 
    1162             :   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
    1163             : 
    1164             : private:
    1165             :   // Private destructor, to discourage deletion outside of Release():
    1166         586 :   ~nsCSSValueList_heap()
    1167         586 :   {
    1168         586 :   }
    1169             : };
    1170             : 
    1171             : // This is a reference counted list value.  Note that the object is
    1172             : // a wrapper for the reference count and a pointer to the head of the
    1173             : // list, whereas the other list types (such as nsCSSValueList) do
    1174             : // not have such a wrapper.
    1175             : struct nsCSSValueSharedList final {
    1176          80 :   nsCSSValueSharedList()
    1177          80 :     : mHead(nullptr)
    1178             :   {
    1179          80 :   }
    1180             : 
    1181             :   // Takes ownership of aList.
    1182           0 :   explicit nsCSSValueSharedList(nsCSSValueList* aList)
    1183           0 :     : mHead(aList)
    1184             :   {
    1185           0 :   }
    1186             : 
    1187             : private:
    1188             :   // Private destructor, to discourage deletion outside of Release():
    1189             :   ~nsCSSValueSharedList();
    1190             : 
    1191             : public:
    1192         395 :   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsCSSValueSharedList)
    1193             : 
    1194             :   void AppendToString(nsCSSPropertyID aProperty, nsAString& aResult,
    1195             :                       nsCSSValue::Serialization aValueSerialization) const;
    1196             : 
    1197             :   bool operator==(nsCSSValueSharedList const& aOther) const;
    1198           8 :   bool operator!=(const nsCSSValueSharedList& aOther) const
    1199           8 :   { return !(*this == aOther); }
    1200             : 
    1201             :   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
    1202             : 
    1203             :   nsCSSValueList* mHead;
    1204             : };
    1205             : 
    1206             : // This has to be here so that the relationship between nsCSSValueList
    1207             : // and nsCSSValueList_heap is visible.
    1208             : inline nsCSSValueList*
    1209          98 : nsCSSValue::GetListValue()
    1210             : {
    1211          98 :   if (mUnit == eCSSUnit_List)
    1212          98 :     return mValue.mList;
    1213             :   else {
    1214           0 :     MOZ_ASSERT(mUnit == eCSSUnit_ListDep, "not a list value");
    1215           0 :     return mValue.mListDependent;
    1216             :   }
    1217             : }
    1218             : 
    1219             : inline const nsCSSValueList*
    1220        1311 : nsCSSValue::GetListValue() const
    1221             : {
    1222        1311 :   if (mUnit == eCSSUnit_List)
    1223        1311 :     return mValue.mList;
    1224             :   else {
    1225           0 :     MOZ_ASSERT(mUnit == eCSSUnit_ListDep, "not a list value");
    1226           0 :     return mValue.mListDependent;
    1227             :   }
    1228             : }
    1229             : 
    1230         535 : struct nsCSSRect {
    1231             :   nsCSSRect(void);
    1232             :   nsCSSRect(const nsCSSRect& aCopy);
    1233             :   ~nsCSSRect();
    1234             : 
    1235             :   void AppendToString(nsCSSPropertyID aProperty, nsAString& aResult,
    1236             :                       nsCSSValue::Serialization aValueSerialization) const;
    1237             : 
    1238           2 :   bool operator==(const nsCSSRect& aOther) const {
    1239           2 :     return mTop == aOther.mTop &&
    1240           0 :            mRight == aOther.mRight &&
    1241           2 :            mBottom == aOther.mBottom &&
    1242           2 :            mLeft == aOther.mLeft;
    1243             :   }
    1244             : 
    1245             :   bool operator!=(const nsCSSRect& aOther) const {
    1246             :     return mTop != aOther.mTop ||
    1247             :            mRight != aOther.mRight ||
    1248             :            mBottom != aOther.mBottom ||
    1249             :            mLeft != aOther.mLeft;
    1250             :   }
    1251             : 
    1252             :   void SetAllSidesTo(const nsCSSValue& aValue);
    1253             : 
    1254           0 :   bool AllSidesEqualTo(const nsCSSValue& aValue) const {
    1255           0 :     return mTop == aValue &&
    1256           0 :            mRight == aValue &&
    1257           0 :            mBottom == aValue &&
    1258           0 :            mLeft == aValue;
    1259             :   }
    1260             : 
    1261         300 :   void Reset() {
    1262         300 :     mTop.Reset();
    1263         300 :     mRight.Reset();
    1264         300 :     mBottom.Reset();
    1265         300 :     mLeft.Reset();
    1266         300 :   }
    1267             : 
    1268             :   bool HasValue() const {
    1269             :     return
    1270             :       mTop.GetUnit() != eCSSUnit_Null ||
    1271             :       mRight.GetUnit() != eCSSUnit_Null ||
    1272             :       mBottom.GetUnit() != eCSSUnit_Null ||
    1273             :       mLeft.GetUnit() != eCSSUnit_Null;
    1274             :   }
    1275             : 
    1276             :   nsCSSValue mTop;
    1277             :   nsCSSValue mRight;
    1278             :   nsCSSValue mBottom;
    1279             :   nsCSSValue mLeft;
    1280             : 
    1281             :   typedef nsCSSValue nsCSSRect::*side_type;
    1282             :   static const side_type sides[4];
    1283             : };
    1284             : 
    1285             : // nsCSSRect_heap differs from nsCSSRect only in being
    1286             : // refcounted.  It should not be necessary to use this class directly;
    1287             : // it's an implementation detail of nsCSSValue.
    1288         806 : struct nsCSSRect_heap final : public nsCSSRect {
    1289        3352 :   NS_INLINE_DECL_REFCOUNTING(nsCSSRect_heap)
    1290             : 
    1291             :   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
    1292             : 
    1293             : private:
    1294             :   // Private destructor, to discourage deletion outside of Release():
    1295         272 :   ~nsCSSRect_heap()
    1296         272 :   {
    1297         272 :   }
    1298             : };
    1299             : 
    1300             : // This has to be here so that the relationship between nsCSSRect
    1301             : // and nsCSSRect_heap is visible.
    1302             : inline nsCSSRect&
    1303           0 : nsCSSValue::GetRectValue()
    1304             : {
    1305           0 :   MOZ_ASSERT(mUnit == eCSSUnit_Rect, "not a rect value");
    1306           0 :   return *mValue.mRect;
    1307             : }
    1308             : 
    1309             : inline const nsCSSRect&
    1310         190 : nsCSSValue::GetRectValue() const
    1311             : {
    1312         190 :   MOZ_ASSERT(mUnit == eCSSUnit_Rect, "not a rect value");
    1313         190 :   return *mValue.mRect;
    1314             : }
    1315             : 
    1316             : struct nsCSSValuePair {
    1317         512 :   nsCSSValuePair()
    1318         512 :   {
    1319         512 :     MOZ_COUNT_CTOR(nsCSSValuePair);
    1320         512 :   }
    1321          51 :   explicit nsCSSValuePair(nsCSSUnit aUnit)
    1322          51 :     : mXValue(aUnit), mYValue(aUnit)
    1323             :   {
    1324          51 :     MOZ_COUNT_CTOR(nsCSSValuePair);
    1325          51 :   }
    1326         317 :   nsCSSValuePair(const nsCSSValue& aXValue, const nsCSSValue& aYValue)
    1327         317 :     : mXValue(aXValue), mYValue(aYValue)
    1328             :   {
    1329         317 :     MOZ_COUNT_CTOR(nsCSSValuePair);
    1330         317 :   }
    1331           0 :   nsCSSValuePair(const nsCSSValuePair& aCopy)
    1332           0 :     : mXValue(aCopy.mXValue), mYValue(aCopy.mYValue)
    1333             :   {
    1334           0 :     MOZ_COUNT_CTOR(nsCSSValuePair);
    1335           0 :   }
    1336         625 :   ~nsCSSValuePair()
    1337         625 :   {
    1338         625 :     MOZ_COUNT_DTOR(nsCSSValuePair);
    1339         625 :   }
    1340             : 
    1341          75 :   nsCSSValuePair& operator=(const nsCSSValuePair& aOther) {
    1342          75 :     mXValue = aOther.mXValue;
    1343          75 :     mYValue = aOther.mYValue;
    1344          75 :     return *this;
    1345             :   }
    1346             : 
    1347           0 :   bool operator==(const nsCSSValuePair& aOther) const {
    1348           0 :     return mXValue == aOther.mXValue &&
    1349           0 :            mYValue == aOther.mYValue;
    1350             :   }
    1351             : 
    1352           0 :   bool operator!=(const nsCSSValuePair& aOther) const {
    1353           0 :     return mXValue != aOther.mXValue ||
    1354           0 :            mYValue != aOther.mYValue;
    1355             :   }
    1356             : 
    1357           0 :   bool BothValuesEqualTo(const nsCSSValue& aValue) const {
    1358           0 :     return mXValue == aValue &&
    1359           0 :            mYValue == aValue;
    1360             :   }
    1361             : 
    1362         241 :   void SetBothValuesTo(const nsCSSValue& aValue) {
    1363         241 :     mXValue = aValue;
    1364         241 :     mYValue = aValue;
    1365         241 :   }
    1366             : 
    1367         100 :   void Reset() {
    1368         100 :     mXValue.Reset();
    1369         100 :     mYValue.Reset();
    1370         100 :   }
    1371             : 
    1372             :   bool HasValue() const {
    1373             :     return mXValue.GetUnit() != eCSSUnit_Null ||
    1374             :            mYValue.GetUnit() != eCSSUnit_Null;
    1375             :   }
    1376             : 
    1377             :   void AppendToString(nsCSSPropertyID aProperty, nsAString& aResult,
    1378             :                       nsCSSValue::Serialization aValueSerialization) const;
    1379             : 
    1380             :   size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
    1381             : 
    1382             :   nsCSSValue mXValue;
    1383             :   nsCSSValue mYValue;
    1384             : };
    1385             : 
    1386             : // nsCSSValuePair_heap differs from nsCSSValuePair only in being
    1387             : // refcounted.  It should not be necessary to use this class directly;
    1388             : // it's an implementation detail of nsCSSValue.
    1389             : struct nsCSSValuePair_heap final : public nsCSSValuePair {
    1390             :   // forward constructor
    1391         303 :   nsCSSValuePair_heap(const nsCSSValue& aXValue, const nsCSSValue& aYValue)
    1392         303 :       : nsCSSValuePair(aXValue, aYValue)
    1393         303 :   {}
    1394             : 
    1395        1216 :   NS_INLINE_DECL_REFCOUNTING(nsCSSValuePair_heap)
    1396             : 
    1397             :   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
    1398             : 
    1399             : private:
    1400             :   // Private destructor, to discourage deletion outside of Release():
    1401          90 :   ~nsCSSValuePair_heap()
    1402          90 :   {
    1403          90 :   }
    1404             : };
    1405             : 
    1406             : struct nsCSSValueTriplet {
    1407           0 :     nsCSSValueTriplet()
    1408           0 :     {
    1409           0 :         MOZ_COUNT_CTOR(nsCSSValueTriplet);
    1410           0 :     }
    1411             :     explicit nsCSSValueTriplet(nsCSSUnit aUnit)
    1412             :         : mXValue(aUnit), mYValue(aUnit), mZValue(aUnit)
    1413             :     {
    1414             :         MOZ_COUNT_CTOR(nsCSSValueTriplet);
    1415             :     }
    1416           2 :     nsCSSValueTriplet(const nsCSSValue& aXValue,
    1417             :                       const nsCSSValue& aYValue,
    1418             :                       const nsCSSValue& aZValue)
    1419           2 :         : mXValue(aXValue), mYValue(aYValue), mZValue(aZValue)
    1420             :     {
    1421           2 :         MOZ_COUNT_CTOR(nsCSSValueTriplet);
    1422           2 :     }
    1423           0 :     nsCSSValueTriplet(const nsCSSValueTriplet& aCopy)
    1424           0 :         : mXValue(aCopy.mXValue), mYValue(aCopy.mYValue), mZValue(aCopy.mZValue)
    1425             :     {
    1426           0 :         MOZ_COUNT_CTOR(nsCSSValueTriplet);
    1427           0 :     }
    1428           0 :     ~nsCSSValueTriplet()
    1429           0 :     {
    1430           0 :         MOZ_COUNT_DTOR(nsCSSValueTriplet);
    1431           0 :     }
    1432             : 
    1433           0 :     bool operator==(const nsCSSValueTriplet& aOther) const {
    1434           0 :         return mXValue == aOther.mXValue &&
    1435           0 :                mYValue == aOther.mYValue &&
    1436           0 :                mZValue == aOther.mZValue;
    1437             :     }
    1438             : 
    1439             :     bool operator!=(const nsCSSValueTriplet& aOther) const {
    1440             :         return mXValue != aOther.mXValue ||
    1441             :                mYValue != aOther.mYValue ||
    1442             :                mZValue != aOther.mZValue;
    1443             :     }
    1444             : 
    1445             :     bool AllValuesEqualTo(const nsCSSValue& aValue) const {
    1446             :         return mXValue == aValue &&
    1447             :                mYValue == aValue &&
    1448             :                mZValue == aValue;
    1449             :     }
    1450             : 
    1451             :     void SetAllValuesTo(const nsCSSValue& aValue) {
    1452             :         mXValue = aValue;
    1453             :         mYValue = aValue;
    1454             :         mZValue = aValue;
    1455             :     }
    1456             : 
    1457             :     void Reset() {
    1458             :         mXValue.Reset();
    1459             :         mYValue.Reset();
    1460             :         mZValue.Reset();
    1461             :     }
    1462             : 
    1463             :     bool HasValue() const {
    1464             :         return mXValue.GetUnit() != eCSSUnit_Null ||
    1465             :                mYValue.GetUnit() != eCSSUnit_Null ||
    1466             :                mZValue.GetUnit() != eCSSUnit_Null;
    1467             :     }
    1468             : 
    1469             :     void AppendToString(nsCSSPropertyID aProperty, nsAString& aResult,
    1470             :                         nsCSSValue::Serialization aValueSerialization) const;
    1471             : 
    1472             :     nsCSSValue mXValue;
    1473             :     nsCSSValue mYValue;
    1474             :     nsCSSValue mZValue;
    1475             : };
    1476             : 
    1477             : // nsCSSValueTriplet_heap differs from nsCSSValueTriplet only in being
    1478             : // refcounted.  It should not be necessary to use this class directly;
    1479             : // it's an implementation detail of nsCSSValue.
    1480             : struct nsCSSValueTriplet_heap final : public nsCSSValueTriplet {
    1481             :   // forward constructor
    1482           2 :   nsCSSValueTriplet_heap(const nsCSSValue& aXValue, const nsCSSValue& aYValue, const nsCSSValue& aZValue)
    1483           2 :     : nsCSSValueTriplet(aXValue, aYValue, aZValue)
    1484           2 :   {}
    1485             : 
    1486          66 :   NS_INLINE_DECL_REFCOUNTING(nsCSSValueTriplet_heap)
    1487             : 
    1488             :   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
    1489             : 
    1490             : private:
    1491             :   // Private destructor, to discourage deletion outside of Release():
    1492           0 :   ~nsCSSValueTriplet_heap()
    1493           0 :   {
    1494           0 :   }
    1495             : };
    1496             : 
    1497             : // This has to be here so that the relationship between nsCSSValuePair
    1498             : // and nsCSSValuePair_heap is visible.
    1499             : inline nsCSSValuePair&
    1500             : nsCSSValue::GetPairValue()
    1501             : {
    1502             :   MOZ_ASSERT(mUnit == eCSSUnit_Pair, "not a pair value");
    1503             :   return *mValue.mPair;
    1504             : }
    1505             : 
    1506             : inline const nsCSSValuePair&
    1507         121 : nsCSSValue::GetPairValue() const
    1508             : {
    1509         121 :   MOZ_ASSERT(mUnit == eCSSUnit_Pair, "not a pair value");
    1510         121 :   return *mValue.mPair;
    1511             : }
    1512             : 
    1513             : inline nsCSSValueTriplet&
    1514             : nsCSSValue::GetTripletValue()
    1515             : {
    1516             :     MOZ_ASSERT(mUnit == eCSSUnit_Triplet, "not a triplet value");
    1517             :     return *mValue.mTriplet;
    1518             : }
    1519             : 
    1520             : inline const nsCSSValueTriplet&
    1521          90 : nsCSSValue::GetTripletValue() const
    1522             : {
    1523          90 :     MOZ_ASSERT(mUnit == eCSSUnit_Triplet, "not a triplet value");
    1524          90 :     return *mValue.mTriplet;
    1525             : }
    1526             : 
    1527             : // Maybe should be replaced with nsCSSValueList and nsCSSValue::Array?
    1528             : struct nsCSSValuePairList {
    1529         569 :   nsCSSValuePairList() : mNext(nullptr) { MOZ_COUNT_CTOR(nsCSSValuePairList); }
    1530             :   ~nsCSSValuePairList();
    1531             : 
    1532             :   nsCSSValuePairList* Clone() const; // makes a deep copy. Infallible.
    1533             :   void AppendToString(nsCSSPropertyID aProperty, nsAString& aResult,
    1534             :                       nsCSSValue::Serialization aValueSerialization) const;
    1535             : 
    1536             :   static bool Equal(const nsCSSValuePairList* aList1,
    1537             :                     const nsCSSValuePairList* aList2);
    1538             : 
    1539             :   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
    1540             : 
    1541             :   nsCSSValue          mXValue;
    1542             :   nsCSSValue          mYValue;
    1543             :   nsCSSValuePairList* mNext;
    1544             : 
    1545             : private:
    1546           0 :   nsCSSValuePairList(const nsCSSValuePairList& aCopy) // makes a shallow copy
    1547           0 :     : mXValue(aCopy.mXValue), mYValue(aCopy.mYValue), mNext(nullptr)
    1548             :   {
    1549           0 :     MOZ_COUNT_CTOR(nsCSSValuePairList);
    1550           0 :   }
    1551             : 
    1552             :   // We don't want operator== or operator!= because they wouldn't be
    1553             :   // null-safe, which is generally what we need.  Use |Equal| method
    1554             :   // above instead.
    1555             :   bool operator==(const nsCSSValuePairList& aOther) const = delete;
    1556             :   bool operator!=(const nsCSSValuePairList& aOther) const = delete;
    1557             : };
    1558             : 
    1559             : // nsCSSValuePairList_heap differs from nsCSSValuePairList only in being
    1560             : // refcounted.  It should not be necessary to use this class directly;
    1561             : // it's an implementation detail of nsCSSValue.
    1562         228 : struct nsCSSValuePairList_heap final : public nsCSSValuePairList {
    1563         782 :   NS_INLINE_DECL_REFCOUNTING(nsCSSValuePairList_heap)
    1564             : 
    1565             :   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
    1566             : 
    1567             : private:
    1568             :   // Private destructor, to discourage deletion outside of Release():
    1569          26 :   ~nsCSSValuePairList_heap()
    1570          26 :   {
    1571          26 :   }
    1572             : };
    1573             : 
    1574             : // This has to be here so that the relationship between nsCSSValuePairList
    1575             : // and nsCSSValuePairList_heap is visible.
    1576             : inline nsCSSValuePairList*
    1577           0 : nsCSSValue::GetPairListValue()
    1578             : {
    1579           0 :   if (mUnit == eCSSUnit_PairList)
    1580           0 :     return mValue.mPairList;
    1581             :   else {
    1582           0 :     MOZ_ASSERT (mUnit == eCSSUnit_PairListDep, "not a pairlist value");
    1583           0 :     return mValue.mPairListDependent;
    1584             :   }
    1585             : }
    1586             : 
    1587             : inline const nsCSSValuePairList*
    1588          41 : nsCSSValue::GetPairListValue() const
    1589             : {
    1590          41 :   if (mUnit == eCSSUnit_PairList)
    1591          41 :     return mValue.mPairList;
    1592             :   else {
    1593           0 :     MOZ_ASSERT (mUnit == eCSSUnit_PairListDep, "not a pairlist value");
    1594           0 :     return mValue.mPairListDependent;
    1595             :   }
    1596             : }
    1597             : 
    1598           0 : struct nsCSSValueGradientStop {
    1599             : public:
    1600             :   nsCSSValueGradientStop();
    1601             :   // needed to keep bloat logs happy when we use the TArray
    1602             :   // in nsCSSValueGradient
    1603             :   nsCSSValueGradientStop(const nsCSSValueGradientStop& aOther);
    1604             :   ~nsCSSValueGradientStop();
    1605             : 
    1606             :   nsCSSValue mLocation;
    1607             :   nsCSSValue mColor;
    1608             :   // If mIsInterpolationHint is true, there is no color, just
    1609             :   // a location.
    1610             :   bool mIsInterpolationHint;
    1611             : 
    1612           0 :   bool operator==(const nsCSSValueGradientStop& aOther) const
    1613             :   {
    1614           0 :     return (mLocation == aOther.mLocation &&
    1615           0 :             mIsInterpolationHint == aOther.mIsInterpolationHint &&
    1616           0 :             (mIsInterpolationHint || mColor == aOther.mColor));
    1617             :   }
    1618             : 
    1619           0 :   bool operator!=(const nsCSSValueGradientStop& aOther) const
    1620             :   {
    1621           0 :     return !(*this == aOther);
    1622             :   }
    1623             : 
    1624             :   size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
    1625             : };
    1626             : 
    1627             : struct nsCSSValueGradient final {
    1628             :   nsCSSValueGradient(bool aIsRadial, bool aIsRepeating);
    1629             : 
    1630             :   // true if gradient is radial, false if it is linear
    1631             :   bool mIsRadial;
    1632             :   bool mIsRepeating;
    1633             :   bool mIsLegacySyntax; // If true, serialization should use a vendor prefix.
    1634             :   // XXXdholbert This will hopefully be going away soon, if bug 1337655 sticks:
    1635             :   bool mIsMozLegacySyntax; // (Only makes sense when mIsLegacySyntax is true.)
    1636             :                            // If true, serialization should use -moz prefix.
    1637             :                            // Else, serialization should use -webkit prefix.
    1638             :   bool mIsExplicitSize;
    1639             :   // line position and angle
    1640             :   nsCSSValuePair mBgPos;
    1641             :   nsCSSValue mAngle;
    1642             : 
    1643             :   // Only meaningful if mIsRadial is true
    1644             : private:
    1645             :   nsCSSValue mRadialValues[2];
    1646             : public:
    1647           4 :   nsCSSValue& GetRadialShape()
    1648             :   {
    1649           4 :     MOZ_ASSERT(!mIsExplicitSize);
    1650           4 :     return mRadialValues[0];
    1651             :   }
    1652          15 :   const nsCSSValue& GetRadialShape() const
    1653             :   {
    1654          15 :     MOZ_ASSERT(!mIsExplicitSize);
    1655          15 :     return mRadialValues[0];
    1656             :   }
    1657           2 :   nsCSSValue& GetRadialSize()
    1658             :   {
    1659           2 :     MOZ_ASSERT(!mIsExplicitSize);
    1660           2 :     return mRadialValues[1];
    1661             :   }
    1662          15 :   const nsCSSValue& GetRadialSize() const
    1663             :   {
    1664          15 :     MOZ_ASSERT(!mIsExplicitSize);
    1665          15 :     return mRadialValues[1];
    1666             :   }
    1667           2 :   nsCSSValue& GetRadiusX()
    1668             :   {
    1669           2 :     MOZ_ASSERT(mIsExplicitSize);
    1670           2 :     return mRadialValues[0];
    1671             :   }
    1672           0 :   const nsCSSValue& GetRadiusX() const
    1673             :   {
    1674           0 :     MOZ_ASSERT(mIsExplicitSize);
    1675           0 :     return mRadialValues[0];
    1676             :   }
    1677           2 :   nsCSSValue& GetRadiusY()
    1678             :   {
    1679           2 :     MOZ_ASSERT(mIsExplicitSize);
    1680           2 :     return mRadialValues[1];
    1681             :   }
    1682           0 :   const nsCSSValue& GetRadiusY() const
    1683             :   {
    1684           0 :     MOZ_ASSERT(mIsExplicitSize);
    1685           0 :     return mRadialValues[1];
    1686             :   }
    1687             : 
    1688             :   InfallibleTArray<nsCSSValueGradientStop> mStops;
    1689             : 
    1690           0 :   bool operator==(const nsCSSValueGradient& aOther) const
    1691             :   {
    1692           0 :     if (mIsRadial != aOther.mIsRadial ||
    1693           0 :         mIsRepeating != aOther.mIsRepeating ||
    1694           0 :         mIsLegacySyntax != aOther.mIsLegacySyntax ||
    1695           0 :         mIsMozLegacySyntax != aOther.mIsMozLegacySyntax ||
    1696           0 :         mIsExplicitSize != aOther.mIsExplicitSize ||
    1697           0 :         mBgPos != aOther.mBgPos ||
    1698           0 :         mAngle != aOther.mAngle ||
    1699           0 :         mRadialValues[0] != aOther.mRadialValues[0] ||
    1700           0 :         mRadialValues[1] != aOther.mRadialValues[1])
    1701           0 :       return false;
    1702             : 
    1703           0 :     if (mStops.Length() != aOther.mStops.Length())
    1704           0 :       return false;
    1705             : 
    1706           0 :     for (uint32_t i = 0; i < mStops.Length(); i++) {
    1707           0 :       if (mStops[i] != aOther.mStops[i])
    1708           0 :         return false;
    1709             :     }
    1710             : 
    1711           0 :     return true;
    1712             :   }
    1713             : 
    1714             :   bool operator!=(const nsCSSValueGradient& aOther) const
    1715             :   {
    1716             :     return !(*this == aOther);
    1717             :   }
    1718             : 
    1719         169 :   NS_INLINE_DECL_REFCOUNTING(nsCSSValueGradient)
    1720             : 
    1721             :   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
    1722             : 
    1723             : private:
    1724             :   // Private destructor, to discourage deletion outside of Release():
    1725           9 :   ~nsCSSValueGradient()
    1726           9 :   {
    1727           9 :   }
    1728             : 
    1729             :   nsCSSValueGradient(const nsCSSValueGradient& aOther) = delete;
    1730             :   nsCSSValueGradient& operator=(const nsCSSValueGradient& aOther) = delete;
    1731             : };
    1732             : 
    1733             : // A string value used primarily to represent variable references.
    1734             : //
    1735             : // Animation code, specifically the KeyframeUtils class, also uses this
    1736             : // type as a container for various string values including:
    1737             : //
    1738             : // * Shorthand property values
    1739             : // * Shorthand sentinel values used for testing failure conditions
    1740             : // * Invalid longhand property values
    1741             : //
    1742             : // For the most part, the above values are not passed to functions that
    1743             : // manipulate nsCSSValue objects in a generic fashion. Instead KeyframeUtils
    1744             : // extracts the string from the nsCSSValueTokenStream and passes that around
    1745             : // instead. The single exception is nsCSSValue::AppendToString which we use
    1746             : // to serialize the string contained in the nsCSSValueTokenStream by ensuring
    1747             : // the mShorthandPropertyID is set to eCSSProperty_UNKNOWN.
    1748             : struct nsCSSValueTokenStream final {
    1749             :   nsCSSValueTokenStream();
    1750             : 
    1751             : private:
    1752             :   // Private destructor, to discourage deletion outside of Release():
    1753             :   ~nsCSSValueTokenStream();
    1754             : 
    1755             : public:
    1756           0 :   bool operator==(const nsCSSValueTokenStream& aOther) const
    1757             :   {
    1758             :     bool eq;
    1759           0 :     return mPropertyID == aOther.mPropertyID &&
    1760           0 :            mShorthandPropertyID == aOther.mShorthandPropertyID &&
    1761           0 :            mTokenStream.Equals(aOther.mTokenStream) &&
    1762           0 :            mLevel == aOther.mLevel &&
    1763           0 :            (mBaseURI == aOther.mBaseURI ||
    1764           0 :             (mBaseURI && aOther.mBaseURI &&
    1765           0 :              NS_SUCCEEDED(mBaseURI->Equals(aOther.mBaseURI, &eq)) &&
    1766           0 :              eq)) &&
    1767           0 :            (mSheetURI == aOther.mSheetURI ||
    1768           0 :             (mSheetURI && aOther.mSheetURI &&
    1769           0 :              NS_SUCCEEDED(mSheetURI->Equals(aOther.mSheetURI, &eq)) &&
    1770           0 :              eq)) &&
    1771           0 :            (mSheetPrincipal == aOther.mSheetPrincipal ||
    1772           0 :             (mSheetPrincipal && aOther.mSheetPrincipal &&
    1773           0 :              NS_SUCCEEDED(mSheetPrincipal->Equals(aOther.mSheetPrincipal,
    1774           0 :                                                   &eq)) &&
    1775           0 :              eq));
    1776             :   }
    1777             : 
    1778             :   bool operator!=(const nsCSSValueTokenStream& aOther) const
    1779             :   {
    1780             :     return !(*this == aOther);
    1781             :   }
    1782             : 
    1783        3598 :   NS_INLINE_DECL_REFCOUNTING(nsCSSValueTokenStream)
    1784             : 
    1785             :   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
    1786             : 
    1787             :   // The property that has mTokenStream as its unparsed specified value.
    1788             :   // When a variable reference is used in a shorthand property, a
    1789             :   // TokenStream value is stored as the specified value for each of its
    1790             :   // component longhand properties.
    1791             :   nsCSSPropertyID mPropertyID;
    1792             : 
    1793             :   // The shorthand property that had a value with a variable reference,
    1794             :   // which caused the longhand property identified by mPropertyID to have
    1795             :   // a TokenStream value.
    1796             :   nsCSSPropertyID mShorthandPropertyID;
    1797             : 
    1798             :   // The unparsed CSS corresponding to the specified value of the property.
    1799             :   // When the value of a shorthand property has a variable reference, the
    1800             :   // same mTokenStream value is used on each of the nsCSSValueTokenStream
    1801             :   // objects that will be set by parsing the shorthand.
    1802             :   nsString mTokenStream;
    1803             : 
    1804             :   nsCOMPtr<nsIURI> mBaseURI;
    1805             :   nsCOMPtr<nsIURI> mSheetURI;
    1806             :   nsCOMPtr<nsIPrincipal> mSheetPrincipal;
    1807             :   // XXX Should store sheet here (see Bug 952338)
    1808             :   // mozilla::CSSStyleSheet* mSheet;
    1809             :   uint32_t mLineNumber;
    1810             :   uint32_t mLineOffset;
    1811             :   mozilla::SheetType mLevel;
    1812             : 
    1813             : private:
    1814             :   nsCSSValueTokenStream(const nsCSSValueTokenStream& aOther) = delete;
    1815             :   nsCSSValueTokenStream& operator=(const nsCSSValueTokenStream& aOther) = delete;
    1816             : };
    1817             : 
    1818             : class nsCSSValueFloatColor final {
    1819             : public:
    1820         171 :   nsCSSValueFloatColor(float aComponent1, float aComponent2, float aComponent3,
    1821             :                        float aAlpha)
    1822         171 :     : mComponent1(aComponent1)
    1823             :     , mComponent2(aComponent2)
    1824             :     , mComponent3(aComponent3)
    1825         171 :     , mAlpha(aAlpha)
    1826             :   {
    1827             :     // We may copy nsCSSValueFloatColor and do some comparisons on them.
    1828             :     // In order to get the correct result, we have to make sure each component
    1829             :     // is finite.
    1830         171 :     MOZ_ASSERT(mozilla::IsFinite(aComponent1) &&
    1831             :                mozilla::IsFinite(aComponent2) &&
    1832             :                mozilla::IsFinite(aComponent3) &&
    1833             :                mozilla::IsFinite(aAlpha),
    1834             :                "Caller must ensure color components are finite");
    1835         171 :   }
    1836             : 
    1837             : private:
    1838             :   // Private destructor, to discourage deletion outside of Release():
    1839          88 :   ~nsCSSValueFloatColor()
    1840          88 :   {}
    1841             : 
    1842             : public:
    1843             :   bool operator==(nsCSSValueFloatColor& aOther) const;
    1844             : 
    1845             :   nscolor GetColorValue(nsCSSUnit aUnit) const;
    1846           0 :   float Comp1() const { return mComponent1; }
    1847           0 :   float Comp2() const { return mComponent2; }
    1848           0 :   float Comp3() const { return mComponent3; }
    1849           0 :   float Alpha() const { return mAlpha; }
    1850             :   bool IsNonTransparentColor() const;
    1851             : 
    1852             :   void AppendToString(nsCSSUnit aUnit, nsAString& aResult) const;
    1853             : 
    1854             :   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
    1855             : 
    1856        1242 :   NS_INLINE_DECL_REFCOUNTING(nsCSSValueFloatColor)
    1857             : 
    1858             : private:
    1859             :   // The range of each component is.
    1860             :   // [0, 1] for HSLColor and HSLAColor. mComponent1 for hue, mComponent2 for
    1861             :   //                                    saturation, mComponent3 for lightness.
    1862             :   //                                    [0, 1] for saturation and lightness
    1863             :   //                                    represents [0%, 100%].
    1864             :   //                                    [0, 1] for hue represents
    1865             :   //                                    [0deg, 360deg].
    1866             :   //
    1867             :   // [-float::max(), float::max()] for PercentageRGBColor, PercentageRGBAColor.
    1868             :   //                               1.0 means 100%.
    1869             :   float mComponent1;
    1870             :   float mComponent2;
    1871             :   float mComponent3;
    1872             :   float mAlpha;
    1873             : 
    1874             :   nsCSSValueFloatColor(const nsCSSValueFloatColor& aOther) = delete;
    1875             :   nsCSSValueFloatColor& operator=(const nsCSSValueFloatColor& aOther)
    1876             :                                                                    = delete;
    1877             : };
    1878             : 
    1879             : struct nsCSSCornerSizes {
    1880             :   nsCSSCornerSizes(void);
    1881             :   nsCSSCornerSizes(const nsCSSCornerSizes& aCopy);
    1882             :   ~nsCSSCornerSizes();
    1883             : 
    1884             :   // argument is a "full corner" constant from nsStyleConsts.h
    1885             :   nsCSSValue const & GetCorner(uint32_t aCorner) const {
    1886             :     return this->*corners[aCorner];
    1887             :   }
    1888           0 :   nsCSSValue & GetCorner(uint32_t aCorner) {
    1889           0 :     return this->*corners[aCorner];
    1890             :   }
    1891             : 
    1892             :   bool operator==(const nsCSSCornerSizes& aOther) const {
    1893             :     NS_FOR_CSS_FULL_CORNERS(corner) {
    1894             :       if (this->GetCorner(corner) != aOther.GetCorner(corner))
    1895             :         return false;
    1896             :     }
    1897             :     return true;
    1898             :   }
    1899             : 
    1900             :   bool operator!=(const nsCSSCornerSizes& aOther) const {
    1901             :     NS_FOR_CSS_FULL_CORNERS(corner) {
    1902             :       if (this->GetCorner(corner) != aOther.GetCorner(corner))
    1903             :         return true;
    1904             :     }
    1905             :     return false;
    1906             :   }
    1907             : 
    1908             :   bool HasValue() const {
    1909             :     NS_FOR_CSS_FULL_CORNERS(corner) {
    1910             :       if (this->GetCorner(corner).GetUnit() != eCSSUnit_Null)
    1911             :         return true;
    1912             :     }
    1913             :     return false;
    1914             :   }
    1915             : 
    1916             :   void Reset();
    1917             : 
    1918             :   nsCSSValue mTopLeft;
    1919             :   nsCSSValue mTopRight;
    1920             :   nsCSSValue mBottomRight;
    1921             :   nsCSSValue mBottomLeft;
    1922             : 
    1923             : protected:
    1924             :   typedef nsCSSValue nsCSSCornerSizes::*corner_type;
    1925             :   static const corner_type corners[4];
    1926             : };
    1927             : 
    1928             : #endif /* nsCSSValue_h___ */
    1929             : 

Generated by: LCOV version 1.13