layout/style/nsCSSValue.cpp

Thu, 15 Jan 2015 21:03:48 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 21:03:48 +0100
branch
TOR_BUG_9701
changeset 11
deefc01c0e14
permissions
-rw-r--r--

Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* vim: set ts=2 et sw=2 tw=80: */
     3 /* This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 /* representation of simple property values within CSS declarations */
     9 #include "nsCSSValue.h"
    11 #include "mozilla/Likely.h"
    12 #include "mozilla/MemoryReporting.h"
    13 #include "mozilla/css/ImageLoader.h"
    14 #include "CSSCalc.h"
    15 #include "gfxFontConstants.h"
    16 #include "imgIRequest.h"
    17 #include "imgRequestProxy.h"
    18 #include "nsIDocument.h"
    19 #include "nsIPrincipal.h"
    20 #include "nsCSSProps.h"
    21 #include "nsCSSStyleSheet.h"
    22 #include "nsNetUtil.h"
    23 #include "nsPresContext.h"
    24 #include "nsStyleUtil.h"
    25 #include "nsDeviceContext.h"
    27 using namespace mozilla;
    29 nsCSSValue::nsCSSValue(int32_t aValue, nsCSSUnit aUnit)
    30   : mUnit(aUnit)
    31 {
    32   NS_ABORT_IF_FALSE(aUnit == eCSSUnit_Integer || aUnit == eCSSUnit_Enumerated ||
    33                     aUnit == eCSSUnit_EnumColor, "not an int value");
    34   if (aUnit == eCSSUnit_Integer || aUnit == eCSSUnit_Enumerated ||
    35       aUnit == eCSSUnit_EnumColor) {
    36     mValue.mInt = aValue;
    37   }
    38   else {
    39     mUnit = eCSSUnit_Null;
    40     mValue.mInt = 0;
    41   }
    42 }
    44 nsCSSValue::nsCSSValue(float aValue, nsCSSUnit aUnit)
    45   : mUnit(aUnit)
    46 {
    47   NS_ABORT_IF_FALSE(eCSSUnit_Percent <= aUnit, "not a float value");
    48   if (eCSSUnit_Percent <= aUnit) {
    49     mValue.mFloat = aValue;
    50     MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat));
    51   }
    52   else {
    53     mUnit = eCSSUnit_Null;
    54     mValue.mInt = 0;
    55   }
    56 }
    58 nsCSSValue::nsCSSValue(const nsString& aValue, nsCSSUnit aUnit)
    59   : mUnit(aUnit)
    60 {
    61   NS_ABORT_IF_FALSE(UnitHasStringValue(), "not a string value");
    62   if (UnitHasStringValue()) {
    63     mValue.mString = BufferFromString(aValue).take();
    64   }
    65   else {
    66     mUnit = eCSSUnit_Null;
    67     mValue.mInt = 0;
    68   }
    69 }
    71 nsCSSValue::nsCSSValue(nsCSSValue::Array* aValue, nsCSSUnit aUnit)
    72   : mUnit(aUnit)
    73 {
    74   NS_ABORT_IF_FALSE(UnitHasArrayValue(), "bad unit");
    75   mValue.mArray = aValue;
    76   mValue.mArray->AddRef();
    77 }
    79 nsCSSValue::nsCSSValue(mozilla::css::URLValue* aValue)
    80   : mUnit(eCSSUnit_URL)
    81 {
    82   mValue.mURL = aValue;
    83   mValue.mURL->AddRef();
    84 }
    86 nsCSSValue::nsCSSValue(mozilla::css::ImageValue* aValue)
    87   : mUnit(eCSSUnit_Image)
    88 {
    89   mValue.mImage = aValue;
    90   mValue.mImage->AddRef();
    91 }
    93 nsCSSValue::nsCSSValue(nsCSSValueGradient* aValue)
    94   : mUnit(eCSSUnit_Gradient)
    95 {
    96   mValue.mGradient = aValue;
    97   mValue.mGradient->AddRef();
    98 }
   100 nsCSSValue::nsCSSValue(nsCSSValueTokenStream* aValue)
   101   : mUnit(eCSSUnit_TokenStream)
   102 {
   103   mValue.mTokenStream = aValue;
   104   mValue.mTokenStream->AddRef();
   105 }
   107 nsCSSValue::nsCSSValue(mozilla::css::GridTemplateAreasValue* aValue)
   108   : mUnit(eCSSUnit_GridTemplateAreas)
   109 {
   110   mValue.mGridTemplateAreas = aValue;
   111   mValue.mGridTemplateAreas->AddRef();
   112 }
   114 nsCSSValue::nsCSSValue(const nsCSSValue& aCopy)
   115   : mUnit(aCopy.mUnit)
   116 {
   117   if (mUnit <= eCSSUnit_DummyInherit) {
   118     // nothing to do, but put this important case first
   119   }
   120   else if (eCSSUnit_Percent <= mUnit) {
   121     mValue.mFloat = aCopy.mValue.mFloat;
   122     MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat));
   123   }
   124   else if (UnitHasStringValue()) {
   125     mValue.mString = aCopy.mValue.mString;
   126     mValue.mString->AddRef();
   127   }
   128   else if (eCSSUnit_Integer <= mUnit && mUnit <= eCSSUnit_EnumColor) {
   129     mValue.mInt = aCopy.mValue.mInt;
   130   }
   131   else if (IsIntegerColorUnit()) {
   132     mValue.mColor = aCopy.mValue.mColor;
   133   }
   134   else if (IsFloatColorUnit()) {
   135     mValue.mFloatColor = aCopy.mValue.mFloatColor;
   136     mValue.mFloatColor->AddRef();
   137   }
   138   else if (UnitHasArrayValue()) {
   139     mValue.mArray = aCopy.mValue.mArray;
   140     mValue.mArray->AddRef();
   141   }
   142   else if (eCSSUnit_URL == mUnit) {
   143     mValue.mURL = aCopy.mValue.mURL;
   144     mValue.mURL->AddRef();
   145   }
   146   else if (eCSSUnit_Image == mUnit) {
   147     mValue.mImage = aCopy.mValue.mImage;
   148     mValue.mImage->AddRef();
   149   }
   150   else if (eCSSUnit_Gradient == mUnit) {
   151     mValue.mGradient = aCopy.mValue.mGradient;
   152     mValue.mGradient->AddRef();
   153   }
   154   else if (eCSSUnit_TokenStream == mUnit) {
   155     mValue.mTokenStream = aCopy.mValue.mTokenStream;
   156     mValue.mTokenStream->AddRef();
   157   }
   158   else if (eCSSUnit_Pair == mUnit) {
   159     mValue.mPair = aCopy.mValue.mPair;
   160     mValue.mPair->AddRef();
   161   }
   162   else if (eCSSUnit_Triplet == mUnit) {
   163     mValue.mTriplet = aCopy.mValue.mTriplet;
   164     mValue.mTriplet->AddRef();
   165   }
   166   else if (eCSSUnit_Rect == mUnit) {
   167     mValue.mRect = aCopy.mValue.mRect;
   168     mValue.mRect->AddRef();
   169   }
   170   else if (eCSSUnit_List == mUnit) {
   171     mValue.mList = aCopy.mValue.mList;
   172     mValue.mList->AddRef();
   173   }
   174   else if (eCSSUnit_ListDep == mUnit) {
   175     mValue.mListDependent = aCopy.mValue.mListDependent;
   176   }
   177   else if (eCSSUnit_SharedList == mUnit) {
   178     mValue.mSharedList = aCopy.mValue.mSharedList;
   179     mValue.mSharedList->AddRef();
   180   }
   181   else if (eCSSUnit_PairList == mUnit) {
   182     mValue.mPairList = aCopy.mValue.mPairList;
   183     mValue.mPairList->AddRef();
   184   }
   185   else if (eCSSUnit_PairListDep == mUnit) {
   186     mValue.mPairListDependent = aCopy.mValue.mPairListDependent;
   187   }
   188   else if (eCSSUnit_GridTemplateAreas == mUnit) {
   189     mValue.mGridTemplateAreas = aCopy.mValue.mGridTemplateAreas;
   190     mValue.mGridTemplateAreas->AddRef();
   191   }
   192   else {
   193     NS_ABORT_IF_FALSE(false, "unknown unit");
   194   }
   195 }
   197 nsCSSValue& nsCSSValue::operator=(const nsCSSValue& aCopy)
   198 {
   199   if (this != &aCopy) {
   200     Reset();
   201     new (this) nsCSSValue(aCopy);
   202   }
   203   return *this;
   204 }
   206 bool nsCSSValue::operator==(const nsCSSValue& aOther) const
   207 {
   208   NS_ABORT_IF_FALSE(mUnit != eCSSUnit_ListDep &&
   209                     aOther.mUnit != eCSSUnit_ListDep &&
   210                     mUnit != eCSSUnit_PairListDep &&
   211                     aOther.mUnit != eCSSUnit_PairListDep,
   212                     "don't use operator== with dependent lists");
   214   if (mUnit == aOther.mUnit) {
   215     if (mUnit <= eCSSUnit_DummyInherit) {
   216       return true;
   217     }
   218     else if (UnitHasStringValue()) {
   219       return (NS_strcmp(GetBufferValue(mValue.mString),
   220                         GetBufferValue(aOther.mValue.mString)) == 0);
   221     }
   222     else if ((eCSSUnit_Integer <= mUnit) && (mUnit <= eCSSUnit_EnumColor)) {
   223       return mValue.mInt == aOther.mValue.mInt;
   224     }
   225     else if (IsIntegerColorUnit()) {
   226       return mValue.mColor == aOther.mValue.mColor;
   227     }
   228     else if (IsFloatColorUnit()) {
   229       return *mValue.mFloatColor == *aOther.mValue.mFloatColor;
   230     }
   231     else if (UnitHasArrayValue()) {
   232       return *mValue.mArray == *aOther.mValue.mArray;
   233     }
   234     else if (eCSSUnit_URL == mUnit) {
   235       return *mValue.mURL == *aOther.mValue.mURL;
   236     }
   237     else if (eCSSUnit_Image == mUnit) {
   238       return *mValue.mImage == *aOther.mValue.mImage;
   239     }
   240     else if (eCSSUnit_Gradient == mUnit) {
   241       return *mValue.mGradient == *aOther.mValue.mGradient;
   242     }
   243     else if (eCSSUnit_TokenStream == mUnit) {
   244       return *mValue.mTokenStream == *aOther.mValue.mTokenStream;
   245     }
   246     else if (eCSSUnit_Pair == mUnit) {
   247       return *mValue.mPair == *aOther.mValue.mPair;
   248     }
   249     else if (eCSSUnit_Triplet == mUnit) {
   250       return *mValue.mTriplet == *aOther.mValue.mTriplet;
   251     }
   252     else if (eCSSUnit_Rect == mUnit) {
   253       return *mValue.mRect == *aOther.mValue.mRect;
   254     }
   255     else if (eCSSUnit_List == mUnit) {
   256       return *mValue.mList == *aOther.mValue.mList;
   257     }
   258     else if (eCSSUnit_SharedList == mUnit) {
   259       return *mValue.mSharedList == *aOther.mValue.mSharedList;
   260     }
   261     else if (eCSSUnit_PairList == mUnit) {
   262       return *mValue.mPairList == *aOther.mValue.mPairList;
   263     }
   264     else if (eCSSUnit_GridTemplateAreas == mUnit) {
   265       return *mValue.mGridTemplateAreas == *aOther.mValue.mGridTemplateAreas;
   266     }
   267     else {
   268       return mValue.mFloat == aOther.mValue.mFloat;
   269     }
   270   }
   271   return false;
   272 }
   274 double nsCSSValue::GetAngleValueInRadians() const
   275 {
   276   double angle = GetFloatValue();
   278   switch (GetUnit()) {
   279   case eCSSUnit_Radian: return angle;
   280   case eCSSUnit_Turn:   return angle * 2 * M_PI;
   281   case eCSSUnit_Degree: return angle * M_PI / 180.0;
   282   case eCSSUnit_Grad:   return angle * M_PI / 200.0;
   284   default:
   285     NS_ABORT_IF_FALSE(false, "unrecognized angular unit");
   286     return 0.0;
   287   }
   288 }
   290 imgRequestProxy* nsCSSValue::GetImageValue(nsIDocument* aDocument) const
   291 {
   292   NS_ABORT_IF_FALSE(mUnit == eCSSUnit_Image, "not an Image value");
   293   return mValue.mImage->mRequests.GetWeak(aDocument);
   294 }
   296 nscoord nsCSSValue::GetFixedLength(nsPresContext* aPresContext) const
   297 {
   298   NS_ABORT_IF_FALSE(mUnit == eCSSUnit_PhysicalMillimeter,
   299                     "not a fixed length unit");
   301   float inches = mValue.mFloat / MM_PER_INCH_FLOAT;
   302   return NSToCoordFloorClamped(inches *
   303     float(aPresContext->DeviceContext()->AppUnitsPerPhysicalInch()));
   304 }
   306 nscoord nsCSSValue::GetPixelLength() const
   307 {
   308   NS_ABORT_IF_FALSE(IsPixelLengthUnit(), "not a fixed length unit");
   310   double scaleFactor;
   311   switch (mUnit) {
   312   case eCSSUnit_Pixel: return nsPresContext::CSSPixelsToAppUnits(mValue.mFloat);
   313   case eCSSUnit_Pica: scaleFactor = 16.0; break;
   314   case eCSSUnit_Point: scaleFactor = 4/3.0; break;
   315   case eCSSUnit_Inch: scaleFactor = 96.0; break;
   316   case eCSSUnit_Millimeter: scaleFactor = 96/25.4; break;
   317   case eCSSUnit_Centimeter: scaleFactor = 96/2.54; break;
   318   default:
   319     NS_ERROR("should never get here");
   320     return 0;
   321   }
   322   return nsPresContext::CSSPixelsToAppUnits(float(mValue.mFloat*scaleFactor));
   323 }
   325 void nsCSSValue::DoReset()
   326 {
   327   if (UnitHasStringValue()) {
   328     mValue.mString->Release();
   329   } else if (IsFloatColorUnit()) {
   330     mValue.mFloatColor->Release();
   331   } else if (UnitHasArrayValue()) {
   332     mValue.mArray->Release();
   333   } else if (eCSSUnit_URL == mUnit) {
   334     mValue.mURL->Release();
   335   } else if (eCSSUnit_Image == mUnit) {
   336     mValue.mImage->Release();
   337   } else if (eCSSUnit_Gradient == mUnit) {
   338     mValue.mGradient->Release();
   339   } else if (eCSSUnit_TokenStream == mUnit) {
   340     mValue.mTokenStream->Release();
   341   } else if (eCSSUnit_Pair == mUnit) {
   342     mValue.mPair->Release();
   343   } else if (eCSSUnit_Triplet == mUnit) {
   344     mValue.mTriplet->Release();
   345   } else if (eCSSUnit_Rect == mUnit) {
   346     mValue.mRect->Release();
   347   } else if (eCSSUnit_List == mUnit) {
   348     mValue.mList->Release();
   349   } else if (eCSSUnit_SharedList == mUnit) {
   350     mValue.mSharedList->Release();
   351   } else if (eCSSUnit_PairList == mUnit) {
   352     mValue.mPairList->Release();
   353   } else if (eCSSUnit_GridTemplateAreas == mUnit) {
   354     mValue.mGridTemplateAreas->Release();
   355   }
   356   mUnit = eCSSUnit_Null;
   357 }
   359 void nsCSSValue::SetIntValue(int32_t aValue, nsCSSUnit aUnit)
   360 {
   361   NS_ABORT_IF_FALSE(aUnit == eCSSUnit_Integer || aUnit == eCSSUnit_Enumerated ||
   362                     aUnit == eCSSUnit_EnumColor, "not an int value");
   363   Reset();
   364   if (aUnit == eCSSUnit_Integer || aUnit == eCSSUnit_Enumerated ||
   365       aUnit == eCSSUnit_EnumColor) {
   366     mUnit = aUnit;
   367     mValue.mInt = aValue;
   368   }
   369 }
   371 void nsCSSValue::SetPercentValue(float aValue)
   372 {
   373   Reset();
   374   mUnit = eCSSUnit_Percent;
   375   mValue.mFloat = aValue;
   376   MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat));
   377 }
   379 void nsCSSValue::SetFloatValue(float aValue, nsCSSUnit aUnit)
   380 {
   381   NS_ABORT_IF_FALSE(eCSSUnit_Number <= aUnit, "not a float value");
   382   Reset();
   383   if (eCSSUnit_Number <= aUnit) {
   384     mUnit = aUnit;
   385     mValue.mFloat = aValue;
   386     MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat));
   387   }
   388 }
   390 void nsCSSValue::SetStringValue(const nsString& aValue,
   391                                 nsCSSUnit aUnit)
   392 {
   393   Reset();
   394   mUnit = aUnit;
   395   NS_ABORT_IF_FALSE(UnitHasStringValue(), "not a string unit");
   396   if (UnitHasStringValue()) {
   397     mValue.mString = BufferFromString(aValue).take();
   398   } else
   399     mUnit = eCSSUnit_Null;
   400 }
   402 void nsCSSValue::SetColorValue(nscolor aValue)
   403 {
   404   SetIntegerColorValue(aValue, eCSSUnit_RGBAColor);
   405 }
   407 void nsCSSValue::SetIntegerColorValue(nscolor aValue, nsCSSUnit aUnit)
   408 {
   409   Reset();
   410   mUnit = aUnit;
   411   NS_ABORT_IF_FALSE(IsIntegerColorUnit(), "bad unit");
   412   mValue.mColor = aValue;
   413 }
   415 void nsCSSValue::SetFloatColorValue(float aComponent1,
   416                                     float aComponent2,
   417                                     float aComponent3,
   418                                     float aAlpha,
   419                                     nsCSSUnit aUnit)
   420 {
   421   Reset();
   422   mUnit = aUnit;
   423   NS_ABORT_IF_FALSE(IsFloatColorUnit(), "bad unit");
   424   mValue.mFloatColor =
   425     new nsCSSValueFloatColor(aComponent1, aComponent2, aComponent3, aAlpha);
   426   mValue.mFloatColor->AddRef();
   427 }
   429 void nsCSSValue::SetArrayValue(nsCSSValue::Array* aValue, nsCSSUnit aUnit)
   430 {
   431   Reset();
   432   mUnit = aUnit;
   433   NS_ABORT_IF_FALSE(UnitHasArrayValue(), "bad unit");
   434   mValue.mArray = aValue;
   435   mValue.mArray->AddRef();
   436 }
   438 void nsCSSValue::SetURLValue(mozilla::css::URLValue* aValue)
   439 {
   440   Reset();
   441   mUnit = eCSSUnit_URL;
   442   mValue.mURL = aValue;
   443   mValue.mURL->AddRef();
   444 }
   446 void nsCSSValue::SetImageValue(mozilla::css::ImageValue* aValue)
   447 {
   448   Reset();
   449   mUnit = eCSSUnit_Image;
   450   mValue.mImage = aValue;
   451   mValue.mImage->AddRef();
   452 }
   454 void nsCSSValue::SetGradientValue(nsCSSValueGradient* aValue)
   455 {
   456   Reset();
   457   mUnit = eCSSUnit_Gradient;
   458   mValue.mGradient = aValue;
   459   mValue.mGradient->AddRef();
   460 }
   462 void nsCSSValue::SetTokenStreamValue(nsCSSValueTokenStream* aValue)
   463 {
   464   Reset();
   465   mUnit = eCSSUnit_TokenStream;
   466   mValue.mTokenStream = aValue;
   467   mValue.mTokenStream->AddRef();
   468 }
   470 void nsCSSValue::SetGridTemplateAreas(mozilla::css::GridTemplateAreasValue* aValue)
   471 {
   472   Reset();
   473   mUnit = eCSSUnit_GridTemplateAreas;
   474   mValue.mGridTemplateAreas = aValue;
   475   mValue.mGridTemplateAreas->AddRef();
   476 }
   478 void nsCSSValue::SetPairValue(const nsCSSValuePair* aValue)
   479 {
   480   // pairs should not be used for null/inherit/initial values
   481   NS_ABORT_IF_FALSE(aValue &&
   482                     aValue->mXValue.GetUnit() != eCSSUnit_Null &&
   483                     aValue->mYValue.GetUnit() != eCSSUnit_Null &&
   484                     aValue->mXValue.GetUnit() != eCSSUnit_Inherit &&
   485                     aValue->mYValue.GetUnit() != eCSSUnit_Inherit &&
   486                     aValue->mXValue.GetUnit() != eCSSUnit_Initial &&
   487                     aValue->mYValue.GetUnit() != eCSSUnit_Initial &&
   488                     aValue->mXValue.GetUnit() != eCSSUnit_Unset &&
   489                     aValue->mYValue.GetUnit() != eCSSUnit_Unset,
   490                     "missing or inappropriate pair value");
   491   Reset();
   492   mUnit = eCSSUnit_Pair;
   493   mValue.mPair = new nsCSSValuePair_heap(aValue->mXValue, aValue->mYValue);
   494   mValue.mPair->AddRef();
   495 }
   497 void nsCSSValue::SetPairValue(const nsCSSValue& xValue,
   498                               const nsCSSValue& yValue)
   499 {
   500   NS_ABORT_IF_FALSE(xValue.GetUnit() != eCSSUnit_Null &&
   501                     yValue.GetUnit() != eCSSUnit_Null &&
   502                     xValue.GetUnit() != eCSSUnit_Inherit &&
   503                     yValue.GetUnit() != eCSSUnit_Inherit &&
   504                     xValue.GetUnit() != eCSSUnit_Initial &&
   505                     yValue.GetUnit() != eCSSUnit_Initial &&
   506                     xValue.GetUnit() != eCSSUnit_Unset &&
   507                     yValue.GetUnit() != eCSSUnit_Unset,
   508                     "inappropriate pair value");
   509   Reset();
   510   mUnit = eCSSUnit_Pair;
   511   mValue.mPair = new nsCSSValuePair_heap(xValue, yValue);
   512   mValue.mPair->AddRef();
   513 }
   515 void nsCSSValue::SetTripletValue(const nsCSSValueTriplet* aValue)
   516 {
   517     // triplet should not be used for null/inherit/initial values
   518     NS_ABORT_IF_FALSE(aValue &&
   519                       aValue->mXValue.GetUnit() != eCSSUnit_Null &&
   520                       aValue->mYValue.GetUnit() != eCSSUnit_Null &&
   521                       aValue->mZValue.GetUnit() != eCSSUnit_Null &&
   522                       aValue->mXValue.GetUnit() != eCSSUnit_Inherit &&
   523                       aValue->mYValue.GetUnit() != eCSSUnit_Inherit &&
   524                       aValue->mZValue.GetUnit() != eCSSUnit_Inherit &&
   525                       aValue->mXValue.GetUnit() != eCSSUnit_Initial &&
   526                       aValue->mYValue.GetUnit() != eCSSUnit_Initial &&
   527                       aValue->mZValue.GetUnit() != eCSSUnit_Initial &&
   528                       aValue->mXValue.GetUnit() != eCSSUnit_Unset &&
   529                       aValue->mYValue.GetUnit() != eCSSUnit_Unset &&
   530                       aValue->mZValue.GetUnit() != eCSSUnit_Unset,
   531                       "missing or inappropriate triplet value");
   532     Reset();
   533     mUnit = eCSSUnit_Triplet;
   534     mValue.mTriplet = new nsCSSValueTriplet_heap(aValue->mXValue, aValue->mYValue, aValue->mZValue);
   535     mValue.mTriplet->AddRef();
   536 }
   538 void nsCSSValue::SetTripletValue(const nsCSSValue& xValue,
   539                                  const nsCSSValue& yValue,
   540                                  const nsCSSValue& zValue)
   541 {
   542     // Only allow Null for the z component
   543     NS_ABORT_IF_FALSE(xValue.GetUnit() != eCSSUnit_Null &&
   544                       yValue.GetUnit() != eCSSUnit_Null &&
   545                       xValue.GetUnit() != eCSSUnit_Inherit &&
   546                       yValue.GetUnit() != eCSSUnit_Inherit &&
   547                       zValue.GetUnit() != eCSSUnit_Inherit &&
   548                       xValue.GetUnit() != eCSSUnit_Initial &&
   549                       yValue.GetUnit() != eCSSUnit_Initial &&
   550                       zValue.GetUnit() != eCSSUnit_Initial &&
   551                       xValue.GetUnit() != eCSSUnit_Unset &&
   552                       yValue.GetUnit() != eCSSUnit_Unset &&
   553                       zValue.GetUnit() != eCSSUnit_Unset,
   554                       "inappropriate triplet value");
   555     Reset();
   556     mUnit = eCSSUnit_Triplet;
   557     mValue.mTriplet = new nsCSSValueTriplet_heap(xValue, yValue, zValue);
   558     mValue.mTriplet->AddRef();
   559 }
   561 nsCSSRect& nsCSSValue::SetRectValue()
   562 {
   563   Reset();
   564   mUnit = eCSSUnit_Rect;
   565   mValue.mRect = new nsCSSRect_heap;
   566   mValue.mRect->AddRef();
   567   return *mValue.mRect;
   568 }
   570 nsCSSValueList* nsCSSValue::SetListValue()
   571 {
   572   Reset();
   573   mUnit = eCSSUnit_List;
   574   mValue.mList = new nsCSSValueList_heap;
   575   mValue.mList->AddRef();
   576   return mValue.mList;
   577 }
   579 void nsCSSValue::SetSharedListValue(nsCSSValueSharedList* aList)
   580 {
   581   Reset();
   582   mUnit = eCSSUnit_SharedList;
   583   mValue.mSharedList = aList;
   584   mValue.mSharedList->AddRef();
   585 }
   587 void nsCSSValue::SetDependentListValue(nsCSSValueList* aList)
   588 {
   589   Reset();
   590   if (aList) {
   591     mUnit = eCSSUnit_ListDep;
   592     mValue.mListDependent = aList;
   593   }
   594 }
   596 nsCSSValuePairList* nsCSSValue::SetPairListValue()
   597 {
   598   Reset();
   599   mUnit = eCSSUnit_PairList;
   600   mValue.mPairList = new nsCSSValuePairList_heap;
   601   mValue.mPairList->AddRef();
   602   return mValue.mPairList;
   603 }
   605 void nsCSSValue::SetDependentPairListValue(nsCSSValuePairList* aList)
   606 {
   607   Reset();
   608   if (aList) {
   609     mUnit = eCSSUnit_PairListDep;
   610     mValue.mPairListDependent = aList;
   611   }
   612 }
   614 void nsCSSValue::SetAutoValue()
   615 {
   616   Reset();
   617   mUnit = eCSSUnit_Auto;
   618 }
   620 void nsCSSValue::SetInheritValue()
   621 {
   622   Reset();
   623   mUnit = eCSSUnit_Inherit;
   624 }
   626 void nsCSSValue::SetInitialValue()
   627 {
   628   Reset();
   629   mUnit = eCSSUnit_Initial;
   630 }
   632 void nsCSSValue::SetUnsetValue()
   633 {
   634   Reset();
   635   mUnit = eCSSUnit_Unset;
   636 }
   638 void nsCSSValue::SetNoneValue()
   639 {
   640   Reset();
   641   mUnit = eCSSUnit_None;
   642 }
   644 void nsCSSValue::SetAllValue()
   645 {
   646   Reset();
   647   mUnit = eCSSUnit_All;
   648 }
   650 void nsCSSValue::SetNormalValue()
   651 {
   652   Reset();
   653   mUnit = eCSSUnit_Normal;
   654 }
   656 void nsCSSValue::SetSystemFontValue()
   657 {
   658   Reset();
   659   mUnit = eCSSUnit_System_Font;
   660 }
   662 void nsCSSValue::SetDummyValue()
   663 {
   664   Reset();
   665   mUnit = eCSSUnit_Dummy;
   666 }
   668 void nsCSSValue::SetDummyInheritValue()
   669 {
   670   Reset();
   671   mUnit = eCSSUnit_DummyInherit;
   672 }
   674 void nsCSSValue::StartImageLoad(nsIDocument* aDocument) const
   675 {
   676   NS_ABORT_IF_FALSE(eCSSUnit_URL == mUnit, "Not a URL value!");
   677   mozilla::css::ImageValue* image =
   678     new mozilla::css::ImageValue(mValue.mURL->GetURI(),
   679                                  mValue.mURL->mString,
   680                                  mValue.mURL->mReferrer,
   681                                  mValue.mURL->mOriginPrincipal,
   682                                  aDocument);
   684   nsCSSValue* writable = const_cast<nsCSSValue*>(this);
   685   writable->SetImageValue(image);
   686 }
   688 nscolor nsCSSValue::GetColorValue() const
   689 {
   690   NS_ABORT_IF_FALSE(IsNumericColorUnit(), "not a color value");
   691   if (IsFloatColorUnit()) {
   692     return mValue.mFloatColor->GetColorValue(mUnit);
   693   }
   694   return mValue.mColor;
   695 }
   697 bool nsCSSValue::IsNonTransparentColor() const
   698 {
   699   // We have the value in the form it was specified in at this point, so we
   700   // have to look for both the keyword 'transparent' and its equivalent in
   701   // rgba notation.
   702   nsDependentString buf;
   703   return
   704     (IsIntegerColorUnit() && NS_GET_A(GetColorValue()) > 0) ||
   705     (IsFloatColorUnit() && mValue.mFloatColor->IsNonTransparentColor()) ||
   706     (mUnit == eCSSUnit_Ident &&
   707      !nsGkAtoms::transparent->Equals(GetStringValue(buf))) ||
   708     (mUnit == eCSSUnit_EnumColor);
   709 }
   711 nsCSSValue::Array*
   712 nsCSSValue::InitFunction(nsCSSKeyword aFunctionId, uint32_t aNumArgs)
   713 {
   714   nsRefPtr<nsCSSValue::Array> func = Array::Create(aNumArgs + 1);
   715   func->Item(0).SetIntValue(aFunctionId, eCSSUnit_Enumerated);
   716   SetArrayValue(func, eCSSUnit_Function);
   717   return func;
   718 }
   720 bool
   721 nsCSSValue::EqualsFunction(nsCSSKeyword aFunctionId) const
   722 {
   723   if (mUnit != eCSSUnit_Function) {
   724     return false;
   725   }
   727   nsCSSValue::Array* func = mValue.mArray;
   728   NS_ABORT_IF_FALSE(func && func->Count() >= 1 &&
   729                     func->Item(0).GetUnit() == eCSSUnit_Enumerated,
   730                     "illegally structured function value");
   732   nsCSSKeyword thisFunctionId = func->Item(0).GetKeywordValue();
   733   return thisFunctionId == aFunctionId;
   734 }
   736 // static
   737 already_AddRefed<nsStringBuffer>
   738 nsCSSValue::BufferFromString(const nsString& aValue)
   739 {
   740   nsRefPtr<nsStringBuffer> buffer = nsStringBuffer::FromString(aValue);
   741   if (buffer) {
   742     return buffer.forget();
   743   }
   745   nsString::size_type length = aValue.Length();
   747   // NOTE: Alloc prouduces a new, already-addref'd (refcnt = 1) buffer.
   748   // NOTE: String buffer allocation is currently fallible.
   749   buffer = nsStringBuffer::Alloc((length + 1) * sizeof(char16_t));
   750   if (MOZ_UNLIKELY(!buffer)) {
   751     NS_RUNTIMEABORT("out of memory");
   752   }
   754   char16_t* data = static_cast<char16_t*>(buffer->Data());
   755   nsCharTraits<char16_t>::copy(data, aValue.get(), length);
   756   // Null-terminate.
   757   data[length] = 0;
   758   return buffer.forget();
   759 }
   761 namespace {
   763 struct CSSValueSerializeCalcOps {
   764   CSSValueSerializeCalcOps(nsCSSProperty aProperty, nsAString& aResult,
   765                            nsCSSValue::Serialization aSerialization)
   766     : mProperty(aProperty),
   767       mResult(aResult),
   768       mValueSerialization(aSerialization)
   769   {
   770   }
   772   typedef nsCSSValue input_type;
   773   typedef nsCSSValue::Array input_array_type;
   775   static nsCSSUnit GetUnit(const input_type& aValue) {
   776     return aValue.GetUnit();
   777   }
   779   void Append(const char* aString)
   780   {
   781     mResult.AppendASCII(aString);
   782   }
   784   void AppendLeafValue(const input_type& aValue)
   785   {
   786     NS_ABORT_IF_FALSE(aValue.GetUnit() == eCSSUnit_Percent ||
   787                       aValue.IsLengthUnit(), "unexpected unit");
   788     aValue.AppendToString(mProperty, mResult, mValueSerialization);
   789   }
   791   void AppendNumber(const input_type& aValue)
   792   {
   793     NS_ABORT_IF_FALSE(aValue.GetUnit() == eCSSUnit_Number, "unexpected unit");
   794     aValue.AppendToString(mProperty, mResult, mValueSerialization);
   795   }
   797 private:
   798   nsCSSProperty mProperty;
   799   nsAString &mResult;
   800   nsCSSValue::Serialization mValueSerialization;
   801 };
   803 } // anonymous namespace
   805 void
   806 nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult,
   807                            Serialization aSerialization) const
   808 {
   809   // eCSSProperty_UNKNOWN gets used for some recursive calls below.
   810   NS_ABORT_IF_FALSE((0 <= aProperty &&
   811                      aProperty <= eCSSProperty_COUNT_no_shorthands) ||
   812                     aProperty == eCSSProperty_UNKNOWN,
   813                     "property ID out of range");
   815   nsCSSUnit unit = GetUnit();
   816   if (unit == eCSSUnit_Null) {
   817     return;
   818   }
   820   if (eCSSUnit_String <= unit && unit <= eCSSUnit_Attr) {
   821     if (unit == eCSSUnit_Attr) {
   822       aResult.AppendLiteral("attr(");
   823     }
   824     nsAutoString  buffer;
   825     GetStringValue(buffer);
   826     if (unit == eCSSUnit_String) {
   827       nsStyleUtil::AppendEscapedCSSString(buffer, aResult);
   828     } else if (unit == eCSSUnit_Families) {
   829       // XXX We really need to do *some* escaping.
   830       aResult.Append(buffer);
   831     } else {
   832       nsStyleUtil::AppendEscapedCSSIdent(buffer, aResult);
   833     }
   834   }
   835   else if (eCSSUnit_Array <= unit && unit <= eCSSUnit_Steps) {
   836     switch (unit) {
   837       case eCSSUnit_Counter:  aResult.AppendLiteral("counter(");  break;
   838       case eCSSUnit_Counters: aResult.AppendLiteral("counters("); break;
   839       case eCSSUnit_Cubic_Bezier: aResult.AppendLiteral("cubic-bezier("); break;
   840       case eCSSUnit_Steps: aResult.AppendLiteral("steps("); break;
   841       default: break;
   842     }
   844     nsCSSValue::Array *array = GetArrayValue();
   845     bool mark = false;
   846     for (size_t i = 0, i_end = array->Count(); i < i_end; ++i) {
   847       if (mark && array->Item(i).GetUnit() != eCSSUnit_Null) {
   848         if (unit == eCSSUnit_Array &&
   849             eCSSProperty_transition_timing_function != aProperty)
   850           aResult.AppendLiteral(" ");
   851         else
   852           aResult.AppendLiteral(", ");
   853       }
   854       if (unit == eCSSUnit_Steps && i == 1) {
   855         NS_ABORT_IF_FALSE(array->Item(i).GetUnit() == eCSSUnit_Enumerated &&
   856                           (array->Item(i).GetIntValue() ==
   857                             NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_START ||
   858                            array->Item(i).GetIntValue() ==
   859                             NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_END),
   860                           "unexpected value");
   861         if (array->Item(i).GetIntValue() ==
   862               NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_START) {
   863           aResult.AppendLiteral("start");
   864         } else {
   865           aResult.AppendLiteral("end");
   866         }
   867         continue;
   868       }
   869       nsCSSProperty prop =
   870         ((eCSSUnit_Counter <= unit && unit <= eCSSUnit_Counters) &&
   871          i == array->Count() - 1)
   872         ? eCSSProperty_list_style_type : aProperty;
   873       if (array->Item(i).GetUnit() != eCSSUnit_Null) {
   874         array->Item(i).AppendToString(prop, aResult, aSerialization);
   875         mark = true;
   876       }
   877     }
   878     if (eCSSUnit_Array == unit &&
   879         aProperty == eCSSProperty_transition_timing_function) {
   880       aResult.AppendLiteral(")");
   881     }
   882   }
   883   /* Although Function is backed by an Array, we'll handle it separately
   884    * because it's a bit quirky.
   885    */
   886   else if (eCSSUnit_Function == unit) {
   887     const nsCSSValue::Array* array = GetArrayValue();
   888     NS_ABORT_IF_FALSE(array->Count() >= 1,
   889                       "Functions must have at least one element for the name.");
   891     /* Append the function name. */
   892     const nsCSSValue& functionName = array->Item(0);
   893     if (functionName.GetUnit() == eCSSUnit_Enumerated) {
   894       // We assume that the first argument is always of nsCSSKeyword type.
   895       const nsCSSKeyword functionId = functionName.GetKeywordValue();
   896       NS_ConvertASCIItoUTF16 ident(nsCSSKeywords::GetStringValue(functionId));
   897       // Bug 721136: Normalize the identifier to lowercase, except that things
   898       // like scaleX should have the last character capitalized.  This matches
   899       // what other browsers do.
   900       switch (functionId) {
   901         case eCSSKeyword_rotatex:
   902         case eCSSKeyword_scalex:
   903         case eCSSKeyword_skewx:
   904         case eCSSKeyword_translatex:
   905           ident.Replace(ident.Length() - 1, 1, char16_t('X'));
   906           break;
   908         case eCSSKeyword_rotatey:
   909         case eCSSKeyword_scaley:
   910         case eCSSKeyword_skewy:
   911         case eCSSKeyword_translatey:
   912           ident.Replace(ident.Length() - 1, 1, char16_t('Y'));
   913           break;
   915         case eCSSKeyword_rotatez:
   916         case eCSSKeyword_scalez:
   917         case eCSSKeyword_translatez:
   918           ident.Replace(ident.Length() - 1, 1, char16_t('Z'));
   919           break;
   921         default:
   922           break;
   923       }
   924       nsStyleUtil::AppendEscapedCSSIdent(ident, aResult);
   925     } else {
   926       MOZ_ASSERT(false, "should no longer have non-enumerated functions");
   927     }
   928     aResult.AppendLiteral("(");
   930     /* Now, step through the function contents, writing each of them as we go. */
   931     for (size_t index = 1; index < array->Count(); ++index) {
   932       array->Item(index).AppendToString(aProperty, aResult,
   933                                         aSerialization);
   935       /* If we're not at the final element, append a comma. */
   936       if (index + 1 != array->Count())
   937         aResult.AppendLiteral(", ");
   938     }
   940     /* Finally, append the closing parenthesis. */
   941     aResult.AppendLiteral(")");
   942   }
   943   else if (IsCalcUnit()) {
   944     NS_ABORT_IF_FALSE(GetUnit() == eCSSUnit_Calc, "unexpected unit");
   945     CSSValueSerializeCalcOps ops(aProperty, aResult, aSerialization);
   946     css::SerializeCalc(*this, ops);
   947   }
   948   else if (eCSSUnit_Integer == unit) {
   949     aResult.AppendInt(GetIntValue(), 10);
   950   }
   951   else if (eCSSUnit_Enumerated == unit) {
   952     int32_t intValue = GetIntValue();
   953     switch(aProperty) {
   956     case eCSSProperty_text_combine_upright:
   957       if (intValue <= NS_STYLE_TEXT_COMBINE_UPRIGHT_ALL) {
   958         AppendASCIItoUTF16(nsCSSProps::LookupPropertyValue(aProperty, intValue),
   959                            aResult);
   960       } else if (intValue == NS_STYLE_TEXT_COMBINE_UPRIGHT_DIGITS_2) {
   961         aResult.AppendLiteral("digits 2");
   962       } else if (intValue == NS_STYLE_TEXT_COMBINE_UPRIGHT_DIGITS_3) {
   963         aResult.AppendLiteral("digits 3");
   964       } else {
   965         aResult.AppendLiteral("digits 4");
   966       }
   967       break;
   969     case eCSSProperty_text_decoration_line:
   970       if (NS_STYLE_TEXT_DECORATION_LINE_NONE == intValue) {
   971         AppendASCIItoUTF16(nsCSSProps::LookupPropertyValue(aProperty, intValue),
   972                            aResult);
   973       } else {
   974         // Ignore the "override all" internal value.
   975         // (It doesn't have a string representation.)
   976         intValue &= ~NS_STYLE_TEXT_DECORATION_LINE_OVERRIDE_ALL;
   977         nsStyleUtil::AppendBitmaskCSSValue(
   978           aProperty, intValue,
   979           NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE,
   980           NS_STYLE_TEXT_DECORATION_LINE_PREF_ANCHORS,
   981           aResult);
   982       }
   983       break;
   985     case eCSSProperty_marks:
   986       if (intValue == NS_STYLE_PAGE_MARKS_NONE) {
   987         AppendASCIItoUTF16(nsCSSProps::LookupPropertyValue(aProperty, intValue),
   988                            aResult);
   989       } else {
   990         nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue,
   991                                            NS_STYLE_PAGE_MARKS_CROP,
   992                                            NS_STYLE_PAGE_MARKS_REGISTER,
   993                                            aResult);
   994       }
   995       break;
   997     case eCSSProperty_paint_order:
   998       static_assert
   999         (NS_STYLE_PAINT_ORDER_BITWIDTH * NS_STYLE_PAINT_ORDER_LAST_VALUE <= 8,
  1000          "SVGStyleStruct::mPaintOrder and the following cast not big enough");
  1001       nsStyleUtil::AppendPaintOrderValue(static_cast<uint8_t>(GetIntValue()),
  1002                                          aResult);
  1003       break;
  1005     case eCSSProperty_font_synthesis:
  1006       nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue,
  1007                                          NS_FONT_SYNTHESIS_WEIGHT,
  1008                                          NS_FONT_SYNTHESIS_STYLE,
  1009                                          aResult);
  1010       break;
  1012     case eCSSProperty_font_variant_east_asian:
  1013       nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue,
  1014                                          NS_FONT_VARIANT_EAST_ASIAN_JIS78,
  1015                                          NS_FONT_VARIANT_EAST_ASIAN_RUBY,
  1016                                          aResult);
  1017       break;
  1019     case eCSSProperty_font_variant_ligatures:
  1020       nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue,
  1021                                          NS_FONT_VARIANT_LIGATURES_NONE,
  1022                                          NS_FONT_VARIANT_LIGATURES_NO_CONTEXTUAL,
  1023                                          aResult);
  1024       break;
  1026     case eCSSProperty_font_variant_numeric:
  1027       nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue,
  1028                                          NS_FONT_VARIANT_NUMERIC_LINING,
  1029                                          NS_FONT_VARIANT_NUMERIC_ORDINAL,
  1030                                          aResult);
  1031       break;
  1033     case eCSSProperty_grid_auto_flow:
  1034       nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue,
  1035                                          NS_STYLE_GRID_AUTO_FLOW_NONE,
  1036                                          NS_STYLE_GRID_AUTO_FLOW_DENSE,
  1037                                          aResult);
  1038       break;
  1040     case eCSSProperty_grid_auto_position:
  1041     case eCSSProperty_grid_column_start:
  1042     case eCSSProperty_grid_column_end:
  1043     case eCSSProperty_grid_row_start:
  1044     case eCSSProperty_grid_row_end:
  1045       // "span" is the only enumerated-unit value for these properties
  1046       aResult.AppendLiteral("span");
  1047       break;
  1049     case eCSSProperty_touch_action:
  1050       nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue,
  1051                                          NS_STYLE_TOUCH_ACTION_NONE,
  1052                                          NS_STYLE_TOUCH_ACTION_MANIPULATION,
  1053                                          aResult);
  1054       break;
  1056     default:
  1057       const nsAFlatCString& name = nsCSSProps::LookupPropertyValue(aProperty, intValue);
  1058       AppendASCIItoUTF16(name, aResult);
  1059       break;
  1062   else if (eCSSUnit_EnumColor == unit) {
  1063     // we can lookup the property in the ColorTable and then
  1064     // get a string mapping the name
  1065     nsAutoCString str;
  1066     if (nsCSSProps::GetColorName(GetIntValue(), str)){
  1067       AppendASCIItoUTF16(str, aResult);
  1068     } else {
  1069       NS_ABORT_IF_FALSE(false, "bad color value");
  1072   else if (IsNumericColorUnit(unit)) {
  1073     if (aSerialization == eNormalized ||
  1074         unit == eCSSUnit_RGBColor ||
  1075         unit == eCSSUnit_RGBAColor) {
  1076       nscolor color = GetColorValue();
  1077       if (aSerialization == eNormalized &&
  1078           color == NS_RGBA(0, 0, 0, 0)) {
  1079         // Use the strictest match for 'transparent' so we do correct
  1080         // round-tripping of all other rgba() values.
  1081         aResult.AppendLiteral("transparent");
  1082       } else {
  1083         uint8_t a = NS_GET_A(color);
  1084         bool showAlpha =
  1085           (aSerialization == eNormalized && a < 255) ||
  1086           (aSerialization == eAuthorSpecified &&
  1087            unit == eCSSUnit_RGBAColor);
  1088         if (showAlpha) {
  1089           aResult.AppendLiteral("rgba(");
  1090         } else {
  1091           aResult.AppendLiteral("rgb(");
  1094         NS_NAMED_LITERAL_STRING(comma, ", ");
  1096         aResult.AppendInt(NS_GET_R(color), 10);
  1097         aResult.Append(comma);
  1098         aResult.AppendInt(NS_GET_G(color), 10);
  1099         aResult.Append(comma);
  1100         aResult.AppendInt(NS_GET_B(color), 10);
  1101         if (showAlpha) {
  1102           aResult.Append(comma);
  1103           aResult.AppendFloat(nsStyleUtil::ColorComponentToFloat(a));
  1105         aResult.Append(char16_t(')'));
  1107     } else if (eCSSUnit_HexColor == unit) {
  1108       nscolor color = GetColorValue();
  1109       aResult.Append('#');
  1110       aResult.AppendPrintf("%02x", NS_GET_R(color));
  1111       aResult.AppendPrintf("%02x", NS_GET_G(color));
  1112       aResult.AppendPrintf("%02x", NS_GET_B(color));
  1113     } else if (eCSSUnit_ShortHexColor == unit) {
  1114       nscolor color = GetColorValue();
  1115       aResult.Append('#');
  1116       aResult.AppendInt(NS_GET_R(color) / 0x11, 16);
  1117       aResult.AppendInt(NS_GET_G(color) / 0x11, 16);
  1118       aResult.AppendInt(NS_GET_B(color) / 0x11, 16);
  1119     } else {
  1120       MOZ_ASSERT(IsFloatColorUnit());
  1121       mValue.mFloatColor->AppendToString(unit, aResult);
  1124   else if (eCSSUnit_URL == unit || eCSSUnit_Image == unit) {
  1125     aResult.Append(NS_LITERAL_STRING("url("));
  1126     nsStyleUtil::AppendEscapedCSSString(
  1127       nsDependentString(GetOriginalURLValue()), aResult);
  1128     aResult.Append(NS_LITERAL_STRING(")"));
  1130   else if (eCSSUnit_Element == unit) {
  1131     aResult.Append(NS_LITERAL_STRING("-moz-element(#"));
  1132     nsAutoString tmpStr;
  1133     GetStringValue(tmpStr);
  1134     nsStyleUtil::AppendEscapedCSSIdent(tmpStr, aResult);
  1135     aResult.Append(NS_LITERAL_STRING(")"));
  1137   else if (eCSSUnit_Percent == unit) {
  1138     aResult.AppendFloat(GetPercentValue() * 100.0f);
  1140   else if (eCSSUnit_Percent < unit) {  // length unit
  1141     aResult.AppendFloat(GetFloatValue());
  1143   else if (eCSSUnit_Gradient == unit) {
  1144     nsCSSValueGradient* gradient = GetGradientValue();
  1146     if (gradient->mIsLegacySyntax) {
  1147       aResult.AppendLiteral("-moz-");
  1149     if (gradient->mIsRepeating) {
  1150       aResult.AppendLiteral("repeating-");
  1152     if (gradient->mIsRadial) {
  1153       aResult.AppendLiteral("radial-gradient(");
  1154     } else {
  1155       aResult.AppendLiteral("linear-gradient(");
  1158     bool needSep = false;
  1159     if (gradient->mIsRadial && !gradient->mIsLegacySyntax) {
  1160       if (!gradient->mIsExplicitSize) {
  1161         if (gradient->GetRadialShape().GetUnit() != eCSSUnit_None) {
  1162           NS_ABORT_IF_FALSE(gradient->GetRadialShape().GetUnit() ==
  1163                             eCSSUnit_Enumerated,
  1164                             "bad unit for radial gradient shape");
  1165           int32_t intValue = gradient->GetRadialShape().GetIntValue();
  1166           NS_ABORT_IF_FALSE(intValue != NS_STYLE_GRADIENT_SHAPE_LINEAR,
  1167                             "radial gradient with linear shape?!");
  1168           AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(intValue,
  1169                                  nsCSSProps::kRadialGradientShapeKTable),
  1170                              aResult);
  1171           needSep = true;
  1174         if (gradient->GetRadialSize().GetUnit() != eCSSUnit_None) {
  1175           if (needSep) {
  1176             aResult.AppendLiteral(" ");
  1178           NS_ABORT_IF_FALSE(gradient->GetRadialSize().GetUnit() ==
  1179                             eCSSUnit_Enumerated,
  1180                             "bad unit for radial gradient size");
  1181           int32_t intValue = gradient->GetRadialSize().GetIntValue();
  1182           AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(intValue,
  1183                                  nsCSSProps::kRadialGradientSizeKTable),
  1184                              aResult);
  1185           needSep = true;
  1187       } else {
  1188         NS_ABORT_IF_FALSE(gradient->GetRadiusX().GetUnit() != eCSSUnit_None,
  1189                           "bad unit for radial gradient explicit size");
  1190         gradient->GetRadiusX().AppendToString(aProperty, aResult,
  1191                                               aSerialization);
  1192         if (gradient->GetRadiusY().GetUnit() != eCSSUnit_None) {
  1193           aResult.AppendLiteral(" ");
  1194           gradient->GetRadiusY().AppendToString(aProperty, aResult,
  1195                                                 aSerialization);
  1197         needSep = true;
  1200     if (!gradient->mIsRadial && !gradient->mIsLegacySyntax) {
  1201       if (gradient->mBgPos.mXValue.GetUnit() != eCSSUnit_None ||
  1202           gradient->mBgPos.mYValue.GetUnit() != eCSSUnit_None) {
  1203         MOZ_ASSERT(gradient->mAngle.GetUnit() == eCSSUnit_None);
  1204         NS_ABORT_IF_FALSE(gradient->mBgPos.mXValue.GetUnit() == eCSSUnit_Enumerated &&
  1205                           gradient->mBgPos.mYValue.GetUnit() == eCSSUnit_Enumerated,
  1206                           "unexpected unit");
  1207         aResult.AppendLiteral("to");
  1208         if (!(gradient->mBgPos.mXValue.GetIntValue() & NS_STYLE_BG_POSITION_CENTER)) {
  1209           aResult.AppendLiteral(" ");
  1210           gradient->mBgPos.mXValue.AppendToString(eCSSProperty_background_position,
  1211                                                   aResult, aSerialization);
  1213         if (!(gradient->mBgPos.mYValue.GetIntValue() & NS_STYLE_BG_POSITION_CENTER)) {
  1214           aResult.AppendLiteral(" ");
  1215           gradient->mBgPos.mYValue.AppendToString(eCSSProperty_background_position,
  1216                                                   aResult, aSerialization);
  1218         needSep = true;
  1219       } else if (gradient->mAngle.GetUnit() != eCSSUnit_None) {
  1220         gradient->mAngle.AppendToString(aProperty, aResult, aSerialization);
  1221         needSep = true;
  1223     } else if (gradient->mBgPos.mXValue.GetUnit() != eCSSUnit_None ||
  1224         gradient->mBgPos.mYValue.GetUnit() != eCSSUnit_None ||
  1225         gradient->mAngle.GetUnit() != eCSSUnit_None) {
  1226       if (needSep) {
  1227         aResult.AppendLiteral(" ");
  1229       if (gradient->mIsRadial && !gradient->mIsLegacySyntax) {
  1230         aResult.AppendLiteral("at ");
  1232       if (gradient->mBgPos.mXValue.GetUnit() != eCSSUnit_None) {
  1233         gradient->mBgPos.mXValue.AppendToString(eCSSProperty_background_position,
  1234                                                 aResult, aSerialization);
  1235         aResult.AppendLiteral(" ");
  1237       if (gradient->mBgPos.mXValue.GetUnit() != eCSSUnit_None) {
  1238         gradient->mBgPos.mYValue.AppendToString(eCSSProperty_background_position,
  1239                                                 aResult, aSerialization);
  1240         aResult.AppendLiteral(" ");
  1242       if (gradient->mAngle.GetUnit() != eCSSUnit_None) {
  1243         NS_ABORT_IF_FALSE(gradient->mIsLegacySyntax,
  1244                           "angle is allowed only for legacy syntax");
  1245         gradient->mAngle.AppendToString(aProperty, aResult, aSerialization);
  1247       needSep = true;
  1250     if (gradient->mIsRadial && gradient->mIsLegacySyntax &&
  1251         (gradient->GetRadialShape().GetUnit() != eCSSUnit_None ||
  1252          gradient->GetRadialSize().GetUnit() != eCSSUnit_None)) {
  1253       MOZ_ASSERT(!gradient->mIsExplicitSize);
  1254       if (needSep) {
  1255         aResult.AppendLiteral(", ");
  1257       if (gradient->GetRadialShape().GetUnit() != eCSSUnit_None) {
  1258         NS_ABORT_IF_FALSE(gradient->GetRadialShape().GetUnit() ==
  1259                           eCSSUnit_Enumerated,
  1260                           "bad unit for radial gradient shape");
  1261         int32_t intValue = gradient->GetRadialShape().GetIntValue();
  1262         NS_ABORT_IF_FALSE(intValue != NS_STYLE_GRADIENT_SHAPE_LINEAR,
  1263                           "radial gradient with linear shape?!");
  1264         AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(intValue,
  1265                                nsCSSProps::kRadialGradientShapeKTable),
  1266                            aResult);
  1267         aResult.AppendLiteral(" ");
  1270       if (gradient->GetRadialSize().GetUnit() != eCSSUnit_None) {
  1271         NS_ABORT_IF_FALSE(gradient->GetRadialSize().GetUnit() ==
  1272                           eCSSUnit_Enumerated,
  1273                           "bad unit for radial gradient size");
  1274         int32_t intValue = gradient->GetRadialSize().GetIntValue();
  1275         AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(intValue,
  1276                                nsCSSProps::kRadialGradientSizeKTable),
  1277                            aResult);
  1279       needSep = true;
  1281     if (needSep) {
  1282       aResult.AppendLiteral(", ");
  1285     for (uint32_t i = 0 ;;) {
  1286       gradient->mStops[i].mColor.AppendToString(aProperty, aResult,
  1287                                                 aSerialization);
  1288       if (gradient->mStops[i].mLocation.GetUnit() != eCSSUnit_None) {
  1289         aResult.AppendLiteral(" ");
  1290         gradient->mStops[i].mLocation.AppendToString(aProperty, aResult,
  1291                                                      aSerialization);
  1293       if (++i == gradient->mStops.Length()) {
  1294         break;
  1296       aResult.AppendLiteral(", ");
  1299     aResult.AppendLiteral(")");
  1300   } else if (eCSSUnit_TokenStream == unit) {
  1301     nsCSSProperty shorthand = mValue.mTokenStream->mShorthandPropertyID;
  1302     if (shorthand == eCSSProperty_UNKNOWN ||
  1303         nsCSSProps::PropHasFlags(shorthand, CSS_PROPERTY_IS_ALIAS) ||
  1304         aProperty == eCSSProperty__x_system_font) {
  1305       // We treat serialization of aliases like '-moz-transform' as a special
  1306       // case, since it really wants to be serialized as if it were a longhand
  1307       // even though it is implemented as a shorthand.
  1308       aResult.Append(mValue.mTokenStream->mTokenStream);
  1310   } else if (eCSSUnit_Pair == unit) {
  1311     if (eCSSProperty_font_variant_alternates == aProperty) {
  1312       int32_t intValue = GetPairValue().mXValue.GetIntValue();
  1313       nsAutoString out;
  1315       // simple, enumerated values
  1316       nsStyleUtil::AppendBitmaskCSSValue(aProperty,
  1317           intValue & NS_FONT_VARIANT_ALTERNATES_ENUMERATED_MASK,
  1318           NS_FONT_VARIANT_ALTERNATES_HISTORICAL,
  1319           NS_FONT_VARIANT_ALTERNATES_HISTORICAL,
  1320           out);
  1322       // functional values
  1323       const nsCSSValueList *list = GetPairValue().mYValue.GetListValue();
  1324       nsAutoTArray<gfxAlternateValue,8> altValues;
  1326       nsStyleUtil::ComputeFunctionalAlternates(list, altValues);
  1327       nsStyleUtil::SerializeFunctionalAlternates(altValues, out);
  1328       aResult.Append(out);
  1329     } else if (eCSSProperty_grid_auto_position == aProperty) {
  1330       GetPairValue().mXValue.AppendToString(aProperty, aResult, aSerialization);
  1331       aResult.AppendLiteral(" / ");
  1332       GetPairValue().mYValue.AppendToString(aProperty, aResult, aSerialization);
  1333     } else {
  1334       GetPairValue().AppendToString(aProperty, aResult, aSerialization);
  1336   } else if (eCSSUnit_Triplet == unit) {
  1337     GetTripletValue().AppendToString(aProperty, aResult, aSerialization);
  1338   } else if (eCSSUnit_Rect == unit) {
  1339     GetRectValue().AppendToString(aProperty, aResult, aSerialization);
  1340   } else if (eCSSUnit_List == unit || eCSSUnit_ListDep == unit) {
  1341     GetListValue()->AppendToString(aProperty, aResult, aSerialization);
  1342   } else if (eCSSUnit_SharedList == unit) {
  1343     GetSharedListValue()->AppendToString(aProperty, aResult, aSerialization);
  1344   } else if (eCSSUnit_PairList == unit || eCSSUnit_PairListDep == unit) {
  1345     switch (aProperty) {
  1346       case eCSSProperty_font_feature_settings:
  1347         nsStyleUtil::AppendFontFeatureSettings(*this, aResult);
  1348         break;
  1349       default:
  1350         GetPairListValue()->AppendToString(aProperty, aResult, aSerialization);
  1351         break;
  1353   } else if (eCSSUnit_GridTemplateAreas == unit) {
  1354     const mozilla::css::GridTemplateAreasValue* areas = GetGridTemplateAreas();
  1355     MOZ_ASSERT(!areas->mTemplates.IsEmpty(),
  1356                "Unexpected empty array in GridTemplateAreasValue");
  1357     nsStyleUtil::AppendEscapedCSSString(areas->mTemplates[0], aResult);
  1358     for (uint32_t i = 1; i < areas->mTemplates.Length(); i++) {
  1359       aResult.Append(char16_t(' '));
  1360       nsStyleUtil::AppendEscapedCSSString(areas->mTemplates[i], aResult);
  1364   switch (unit) {
  1365     case eCSSUnit_Null:         break;
  1366     case eCSSUnit_Auto:         aResult.AppendLiteral("auto");     break;
  1367     case eCSSUnit_Inherit:      aResult.AppendLiteral("inherit");  break;
  1368     case eCSSUnit_Initial:      aResult.AppendLiteral("initial");  break;
  1369     case eCSSUnit_Unset:        aResult.AppendLiteral("unset");    break;
  1370     case eCSSUnit_None:         aResult.AppendLiteral("none");     break;
  1371     case eCSSUnit_Normal:       aResult.AppendLiteral("normal");   break;
  1372     case eCSSUnit_System_Font:  aResult.AppendLiteral("-moz-use-system-font"); break;
  1373     case eCSSUnit_All:          aResult.AppendLiteral("all"); break;
  1374     case eCSSUnit_Dummy:
  1375     case eCSSUnit_DummyInherit:
  1376       NS_ABORT_IF_FALSE(false, "should never serialize");
  1377       break;
  1379     case eCSSUnit_String:       break;
  1380     case eCSSUnit_Ident:        break;
  1381     case eCSSUnit_Families:     break;
  1382     case eCSSUnit_URL:          break;
  1383     case eCSSUnit_Image:        break;
  1384     case eCSSUnit_Element:      break;
  1385     case eCSSUnit_Array:        break;
  1386     case eCSSUnit_Attr:
  1387     case eCSSUnit_Cubic_Bezier:
  1388     case eCSSUnit_Steps:
  1389     case eCSSUnit_Counter:
  1390     case eCSSUnit_Counters:     aResult.Append(char16_t(')'));    break;
  1391     case eCSSUnit_Local_Font:   break;
  1392     case eCSSUnit_Font_Format:  break;
  1393     case eCSSUnit_Function:     break;
  1394     case eCSSUnit_Calc:         break;
  1395     case eCSSUnit_Calc_Plus:    break;
  1396     case eCSSUnit_Calc_Minus:   break;
  1397     case eCSSUnit_Calc_Times_L: break;
  1398     case eCSSUnit_Calc_Times_R: break;
  1399     case eCSSUnit_Calc_Divided: break;
  1400     case eCSSUnit_Integer:      break;
  1401     case eCSSUnit_Enumerated:   break;
  1402     case eCSSUnit_EnumColor:             break;
  1403     case eCSSUnit_RGBColor:              break;
  1404     case eCSSUnit_RGBAColor:             break;
  1405     case eCSSUnit_HexColor:              break;
  1406     case eCSSUnit_ShortHexColor:         break;
  1407     case eCSSUnit_PercentageRGBColor:    break;
  1408     case eCSSUnit_PercentageRGBAColor:   break;
  1409     case eCSSUnit_HSLColor:              break;
  1410     case eCSSUnit_HSLAColor:             break;
  1411     case eCSSUnit_Percent:      aResult.Append(char16_t('%'));    break;
  1412     case eCSSUnit_Number:       break;
  1413     case eCSSUnit_Gradient:     break;
  1414     case eCSSUnit_TokenStream:  break;
  1415     case eCSSUnit_Pair:         break;
  1416     case eCSSUnit_Triplet:      break;
  1417     case eCSSUnit_Rect:         break;
  1418     case eCSSUnit_List:         break;
  1419     case eCSSUnit_ListDep:      break;
  1420     case eCSSUnit_SharedList:   break;
  1421     case eCSSUnit_PairList:     break;
  1422     case eCSSUnit_PairListDep:  break;
  1423     case eCSSUnit_GridTemplateAreas:     break;
  1425     case eCSSUnit_Inch:         aResult.AppendLiteral("in");   break;
  1426     case eCSSUnit_Millimeter:   aResult.AppendLiteral("mm");   break;
  1427     case eCSSUnit_PhysicalMillimeter: aResult.AppendLiteral("mozmm");   break;
  1428     case eCSSUnit_Centimeter:   aResult.AppendLiteral("cm");   break;
  1429     case eCSSUnit_Point:        aResult.AppendLiteral("pt");   break;
  1430     case eCSSUnit_Pica:         aResult.AppendLiteral("pc");   break;
  1432     case eCSSUnit_ViewportWidth:  aResult.AppendLiteral("vw");   break;
  1433     case eCSSUnit_ViewportHeight: aResult.AppendLiteral("vh");   break;
  1434     case eCSSUnit_ViewportMin:    aResult.AppendLiteral("vmin"); break;
  1435     case eCSSUnit_ViewportMax:    aResult.AppendLiteral("vmax"); break;
  1437     case eCSSUnit_EM:           aResult.AppendLiteral("em");   break;
  1438     case eCSSUnit_XHeight:      aResult.AppendLiteral("ex");   break;
  1439     case eCSSUnit_Char:         aResult.AppendLiteral("ch");   break;
  1440     case eCSSUnit_RootEM:       aResult.AppendLiteral("rem");  break;
  1442     case eCSSUnit_Pixel:        aResult.AppendLiteral("px");   break;
  1444     case eCSSUnit_Degree:       aResult.AppendLiteral("deg");  break;
  1445     case eCSSUnit_Grad:         aResult.AppendLiteral("grad"); break;
  1446     case eCSSUnit_Radian:       aResult.AppendLiteral("rad");  break;
  1447     case eCSSUnit_Turn:         aResult.AppendLiteral("turn");  break;
  1449     case eCSSUnit_Hertz:        aResult.AppendLiteral("Hz");   break;
  1450     case eCSSUnit_Kilohertz:    aResult.AppendLiteral("kHz");  break;
  1452     case eCSSUnit_Seconds:      aResult.Append(char16_t('s'));    break;
  1453     case eCSSUnit_Milliseconds: aResult.AppendLiteral("ms");   break;
  1455     case eCSSUnit_FlexFraction: aResult.AppendLiteral("fr");   break;
  1459 size_t
  1460 nsCSSValue::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
  1462   size_t n = 0;
  1464   switch (GetUnit()) {
  1465     // No value: nothing extra to measure.
  1466     case eCSSUnit_Null:
  1467     case eCSSUnit_Auto:
  1468     case eCSSUnit_Inherit:
  1469     case eCSSUnit_Initial:
  1470     case eCSSUnit_Unset:
  1471     case eCSSUnit_None:
  1472     case eCSSUnit_Normal:
  1473     case eCSSUnit_System_Font:
  1474     case eCSSUnit_All:
  1475     case eCSSUnit_Dummy:
  1476     case eCSSUnit_DummyInherit:
  1477       break;
  1479     // String
  1480     case eCSSUnit_String:
  1481     case eCSSUnit_Ident:
  1482     case eCSSUnit_Families:
  1483     case eCSSUnit_Attr:
  1484     case eCSSUnit_Local_Font:
  1485     case eCSSUnit_Font_Format:
  1486     case eCSSUnit_Element:
  1487       n += mValue.mString->SizeOfIncludingThisIfUnshared(aMallocSizeOf);
  1488       break;
  1490     // Array
  1491     case eCSSUnit_Array:
  1492     case eCSSUnit_Counter:
  1493     case eCSSUnit_Counters:
  1494     case eCSSUnit_Cubic_Bezier:
  1495     case eCSSUnit_Steps:
  1496     case eCSSUnit_Function:
  1497     case eCSSUnit_Calc:
  1498     case eCSSUnit_Calc_Plus:
  1499     case eCSSUnit_Calc_Minus:
  1500     case eCSSUnit_Calc_Times_L:
  1501     case eCSSUnit_Calc_Times_R:
  1502     case eCSSUnit_Calc_Divided:
  1503       break;
  1505     // URL
  1506     case eCSSUnit_URL:
  1507       n += mValue.mURL->SizeOfIncludingThis(aMallocSizeOf);
  1508       break;
  1510     // Image
  1511     case eCSSUnit_Image:
  1512       // Not yet measured.  Measurement may be added later if DMD finds it
  1513       // worthwhile.
  1514       break;
  1516     // Gradient
  1517     case eCSSUnit_Gradient:
  1518       n += mValue.mGradient->SizeOfIncludingThis(aMallocSizeOf);
  1519       break;
  1521     // TokenStream
  1522     case eCSSUnit_TokenStream:
  1523       n += mValue.mTokenStream->SizeOfIncludingThis(aMallocSizeOf);
  1524       break;
  1526     // Pair
  1527     case eCSSUnit_Pair:
  1528       n += mValue.mPair->SizeOfIncludingThis(aMallocSizeOf);
  1529       break;
  1531     // Triplet
  1532     case eCSSUnit_Triplet:
  1533       n += mValue.mTriplet->SizeOfIncludingThis(aMallocSizeOf);
  1534       break;
  1536     // Rect
  1537     case eCSSUnit_Rect:
  1538       n += mValue.mRect->SizeOfIncludingThis(aMallocSizeOf);
  1539       break;
  1541     // List
  1542     case eCSSUnit_List:
  1543       n += mValue.mList->SizeOfIncludingThis(aMallocSizeOf);
  1544       break;
  1546     // ListDep: not measured because it's non-owning.
  1547     case eCSSUnit_ListDep:
  1548       break;
  1550     // SharedList
  1551     case eCSSUnit_SharedList:
  1552       // Makes more sense not to measure, since it most cases the list
  1553       // will be shared.
  1554       break;
  1556     // PairList
  1557     case eCSSUnit_PairList:
  1558       n += mValue.mPairList->SizeOfIncludingThis(aMallocSizeOf);
  1559       break;
  1561     // PairListDep: not measured because it's non-owning.
  1562     case eCSSUnit_PairListDep:
  1563       break;
  1565     // GridTemplateAreas
  1566     case eCSSUnit_GridTemplateAreas:
  1567       n += mValue.mGridTemplateAreas->SizeOfIncludingThis(aMallocSizeOf);
  1568       break;
  1570     // Int: nothing extra to measure.
  1571     case eCSSUnit_Integer:
  1572     case eCSSUnit_Enumerated:
  1573     case eCSSUnit_EnumColor:
  1574       break;
  1576     // Integer Color: nothing extra to measure.
  1577     case eCSSUnit_RGBColor:
  1578     case eCSSUnit_RGBAColor:
  1579     case eCSSUnit_HexColor:
  1580     case eCSSUnit_ShortHexColor:
  1581       break;
  1583     // Float Color
  1584     case eCSSUnit_PercentageRGBColor:
  1585     case eCSSUnit_PercentageRGBAColor:
  1586     case eCSSUnit_HSLColor:
  1587     case eCSSUnit_HSLAColor:
  1588       n += mValue.mFloatColor->SizeOfIncludingThis(aMallocSizeOf);
  1589       break;
  1591     // Float: nothing extra to measure.
  1592     case eCSSUnit_Percent:
  1593     case eCSSUnit_Number:
  1594     case eCSSUnit_PhysicalMillimeter:
  1595     case eCSSUnit_ViewportWidth:
  1596     case eCSSUnit_ViewportHeight:
  1597     case eCSSUnit_ViewportMin:
  1598     case eCSSUnit_ViewportMax:
  1599     case eCSSUnit_EM:
  1600     case eCSSUnit_XHeight:
  1601     case eCSSUnit_Char:
  1602     case eCSSUnit_RootEM:
  1603     case eCSSUnit_Point:
  1604     case eCSSUnit_Inch:
  1605     case eCSSUnit_Millimeter:
  1606     case eCSSUnit_Centimeter:
  1607     case eCSSUnit_Pica:
  1608     case eCSSUnit_Pixel:
  1609     case eCSSUnit_Degree:
  1610     case eCSSUnit_Grad:
  1611     case eCSSUnit_Turn:
  1612     case eCSSUnit_Radian:
  1613     case eCSSUnit_Hertz:
  1614     case eCSSUnit_Kilohertz:
  1615     case eCSSUnit_Seconds:
  1616     case eCSSUnit_Milliseconds:
  1617     case eCSSUnit_FlexFraction:
  1618       break;
  1620     default:
  1621       NS_ABORT_IF_FALSE(false, "bad nsCSSUnit");
  1622       break;
  1625   return n;
  1628 // --- nsCSSValueList -----------------
  1630 nsCSSValueList::~nsCSSValueList()
  1632   MOZ_COUNT_DTOR(nsCSSValueList);
  1633   NS_CSS_DELETE_LIST_MEMBER(nsCSSValueList, this, mNext);
  1636 nsCSSValueList*
  1637 nsCSSValueList::Clone() const
  1639   nsCSSValueList* result = new nsCSSValueList(*this);
  1640   nsCSSValueList* dest = result;
  1641   const nsCSSValueList* src = this->mNext;
  1642   while (src) {
  1643     dest->mNext = new nsCSSValueList(*src);
  1644     dest = dest->mNext;
  1645     src = src->mNext;
  1647   return result;
  1650 void
  1651 nsCSSValueList::CloneInto(nsCSSValueList* aList) const
  1653     NS_ASSERTION(!aList->mNext, "Must be an empty list!");
  1654     aList->mValue = mValue;
  1655     aList->mNext = mNext ? mNext->Clone() : nullptr;
  1658 static void
  1659 AppendValueListToString(const nsCSSValueList* val,
  1660                         nsCSSProperty aProperty, nsAString& aResult,
  1661                         nsCSSValue::Serialization aSerialization)
  1663   for (;;) {
  1664     val->mValue.AppendToString(aProperty, aResult, aSerialization);
  1665     val = val->mNext;
  1666     if (!val)
  1667       break;
  1669     if (nsCSSProps::PropHasFlags(aProperty,
  1670                                  CSS_PROPERTY_VALUE_LIST_USES_COMMAS))
  1671       aResult.Append(char16_t(','));
  1672     aResult.Append(char16_t(' '));
  1676 static void
  1677 AppendGridTemplateToString(const nsCSSValueList* val,
  1678                            nsCSSProperty aProperty, nsAString& aResult,
  1679                            nsCSSValue::Serialization aSerialization)
  1681   // This is called for the "list" that's the top-level value of the property.
  1682   bool isSubgrid = false;
  1683   for (;;) {
  1684     bool addSpaceSeparator = true;
  1685     nsCSSUnit unit = val->mValue.GetUnit();
  1687     if (unit == eCSSUnit_Enumerated &&
  1688         val->mValue.GetIntValue() == NS_STYLE_GRID_TEMPLATE_SUBGRID) {
  1689       isSubgrid = true;
  1690       aResult.AppendLiteral("subgrid");
  1692     } else if (unit == eCSSUnit_Null) {
  1693       // Empty or omitted <line-names>.
  1694       if (isSubgrid) {
  1695         aResult.AppendLiteral("()");
  1696       } else {
  1697         // Serializes to nothing.
  1698         addSpaceSeparator = false;  // Avoid a double space.
  1701     } else if (unit == eCSSUnit_List || unit == eCSSUnit_ListDep) {
  1702       // Non-empty <line-names>
  1703       aResult.AppendLiteral("(");
  1704       AppendValueListToString(val->mValue.GetListValue(), aProperty,
  1705                               aResult, aSerialization);
  1706       aResult.AppendLiteral(")");
  1708     } else {
  1709       // <track-size>
  1710       val->mValue.AppendToString(aProperty, aResult, aSerialization);
  1711       if (!isSubgrid &&
  1712           val->mNext &&
  1713           val->mNext->mValue.GetUnit() == eCSSUnit_Null &&
  1714           !val->mNext->mNext) {
  1715         // Break out of the loop early to avoid a trailing space.
  1716         break;
  1720     val = val->mNext;
  1721     if (!val) {
  1722       break;
  1725     if (addSpaceSeparator) {
  1726       aResult.Append(char16_t(' '));
  1731 void
  1732 nsCSSValueList::AppendToString(nsCSSProperty aProperty, nsAString& aResult,
  1733                                nsCSSValue::Serialization aSerialization) const
  1735   if (aProperty == eCSSProperty_grid_template_columns ||
  1736       aProperty == eCSSProperty_grid_template_rows) {
  1737     AppendGridTemplateToString(this, aProperty, aResult, aSerialization);
  1738   } else {
  1739     AppendValueListToString(this, aProperty, aResult, aSerialization);
  1743 bool
  1744 nsCSSValueList::operator==(const nsCSSValueList& aOther) const
  1746   if (this == &aOther)
  1747     return true;
  1749   const nsCSSValueList *p1 = this, *p2 = &aOther;
  1750   for ( ; p1 && p2; p1 = p1->mNext, p2 = p2->mNext) {
  1751     if (p1->mValue != p2->mValue)
  1752       return false;
  1754   return !p1 && !p2; // true if same length, false otherwise
  1757 size_t
  1758 nsCSSValueList::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
  1760   size_t n = 0;
  1761   const nsCSSValueList* v = this;
  1762   while (v) {
  1763     n += aMallocSizeOf(v);
  1764     n += v->mValue.SizeOfExcludingThis(aMallocSizeOf);
  1765     v = v->mNext;
  1767   return n;
  1770 size_t
  1771 nsCSSValueList_heap::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
  1773   size_t n = aMallocSizeOf(this);
  1774   n += mValue.SizeOfExcludingThis(aMallocSizeOf);
  1775   n += mNext ? mNext->SizeOfIncludingThis(aMallocSizeOf) : 0;
  1776   return n;
  1779 // --- nsCSSValueSharedList -----------------
  1781 nsCSSValueSharedList::~nsCSSValueSharedList()
  1783   MOZ_COUNT_DTOR(nsCSSValueSharedList);
  1784   if (mHead) {
  1785     NS_CSS_DELETE_LIST_MEMBER(nsCSSValueList, mHead, mNext);
  1786     delete mHead;
  1790 void
  1791 nsCSSValueSharedList::AppendToString(nsCSSProperty aProperty, nsAString& aResult,
  1792                                      nsCSSValue::Serialization aSerialization) const
  1794   if (mHead) {
  1795     mHead->AppendToString(aProperty, aResult, aSerialization);
  1799 bool
  1800 nsCSSValueSharedList::operator==(const nsCSSValueSharedList& aOther) const
  1802   return !mHead == !aOther.mHead &&
  1803          (!mHead || *mHead == *aOther.mHead);
  1806 size_t
  1807 nsCSSValueSharedList::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
  1809   size_t n = 0;
  1810   n += aMallocSizeOf(this);
  1811   n += mHead->SizeOfIncludingThis(aMallocSizeOf);
  1812   return n;
  1815 // --- nsCSSRect -----------------
  1817 nsCSSRect::nsCSSRect(void)
  1819   MOZ_COUNT_CTOR(nsCSSRect);
  1822 nsCSSRect::nsCSSRect(const nsCSSRect& aCopy)
  1823   : mTop(aCopy.mTop),
  1824     mRight(aCopy.mRight),
  1825     mBottom(aCopy.mBottom),
  1826     mLeft(aCopy.mLeft)
  1828   MOZ_COUNT_CTOR(nsCSSRect);
  1831 nsCSSRect::~nsCSSRect()
  1833   MOZ_COUNT_DTOR(nsCSSRect);
  1836 void
  1837 nsCSSRect::AppendToString(nsCSSProperty aProperty, nsAString& aResult,
  1838                           nsCSSValue::Serialization aSerialization) const
  1840   NS_ABORT_IF_FALSE(mTop.GetUnit() != eCSSUnit_Null &&
  1841                     mTop.GetUnit() != eCSSUnit_Inherit &&
  1842                     mTop.GetUnit() != eCSSUnit_Initial &&
  1843                     mTop.GetUnit() != eCSSUnit_Unset,
  1844                     "parser should have used a bare value");
  1846   if (eCSSProperty_border_image_slice == aProperty ||
  1847       eCSSProperty_border_image_width == aProperty ||
  1848       eCSSProperty_border_image_outset == aProperty) {
  1849     NS_NAMED_LITERAL_STRING(space, " ");
  1851     mTop.AppendToString(aProperty, aResult, aSerialization);
  1852     aResult.Append(space);
  1853     mRight.AppendToString(aProperty, aResult, aSerialization);
  1854     aResult.Append(space);
  1855     mBottom.AppendToString(aProperty, aResult, aSerialization);
  1856     aResult.Append(space);
  1857     mLeft.AppendToString(aProperty, aResult, aSerialization);
  1858   } else {
  1859     NS_NAMED_LITERAL_STRING(comma, ", ");
  1861     aResult.AppendLiteral("rect(");
  1862     mTop.AppendToString(aProperty, aResult, aSerialization);
  1863     aResult.Append(comma);
  1864     mRight.AppendToString(aProperty, aResult, aSerialization);
  1865     aResult.Append(comma);
  1866     mBottom.AppendToString(aProperty, aResult, aSerialization);
  1867     aResult.Append(comma);
  1868     mLeft.AppendToString(aProperty, aResult, aSerialization);
  1869     aResult.Append(char16_t(')'));
  1873 void nsCSSRect::SetAllSidesTo(const nsCSSValue& aValue)
  1875   mTop = aValue;
  1876   mRight = aValue;
  1877   mBottom = aValue;
  1878   mLeft = aValue;
  1881 size_t
  1882 nsCSSRect_heap::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
  1884   size_t n = aMallocSizeOf(this);
  1885   n += mTop   .SizeOfExcludingThis(aMallocSizeOf);
  1886   n += mRight .SizeOfExcludingThis(aMallocSizeOf);
  1887   n += mBottom.SizeOfExcludingThis(aMallocSizeOf);
  1888   n += mLeft  .SizeOfExcludingThis(aMallocSizeOf);
  1889   return n;
  1892 static_assert(NS_SIDE_TOP == 0 && NS_SIDE_RIGHT == 1 &&
  1893               NS_SIDE_BOTTOM == 2 && NS_SIDE_LEFT == 3,
  1894               "box side constants not top/right/bottom/left == 0/1/2/3");
  1896 /* static */ const nsCSSRect::side_type nsCSSRect::sides[4] = {
  1897   &nsCSSRect::mTop,
  1898   &nsCSSRect::mRight,
  1899   &nsCSSRect::mBottom,
  1900   &nsCSSRect::mLeft,
  1901 };
  1903 // --- nsCSSValuePair -----------------
  1905 void
  1906 nsCSSValuePair::AppendToString(nsCSSProperty aProperty,
  1907                                nsAString& aResult,
  1908                                nsCSSValue::Serialization aSerialization) const
  1910   mXValue.AppendToString(aProperty, aResult, aSerialization);
  1911   if (mYValue.GetUnit() != eCSSUnit_Null) {
  1912     aResult.Append(char16_t(' '));
  1913     mYValue.AppendToString(aProperty, aResult, aSerialization);
  1917 size_t
  1918 nsCSSValuePair::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
  1920   size_t n = 0;
  1921   n += mXValue.SizeOfExcludingThis(aMallocSizeOf);
  1922   n += mYValue.SizeOfExcludingThis(aMallocSizeOf);
  1923   return n;
  1926 size_t
  1927 nsCSSValuePair_heap::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
  1929   size_t n = aMallocSizeOf(this);
  1930   n += mXValue.SizeOfExcludingThis(aMallocSizeOf);
  1931   n += mYValue.SizeOfExcludingThis(aMallocSizeOf);
  1932   return n;
  1935 // --- nsCSSValueTriplet -----------------
  1937 void
  1938 nsCSSValueTriplet::AppendToString(nsCSSProperty aProperty,
  1939                                   nsAString& aResult,
  1940                                   nsCSSValue::Serialization aSerialization) const
  1942     mXValue.AppendToString(aProperty, aResult, aSerialization);
  1943     if (mYValue.GetUnit() != eCSSUnit_Null) {
  1944         aResult.Append(char16_t(' '));
  1945         mYValue.AppendToString(aProperty, aResult, aSerialization);
  1946         if (mZValue.GetUnit() != eCSSUnit_Null) {
  1947             aResult.Append(char16_t(' '));
  1948             mZValue.AppendToString(aProperty, aResult, aSerialization);
  1953 size_t
  1954 nsCSSValueTriplet_heap::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
  1956   size_t n = aMallocSizeOf(this);
  1957   n += mXValue.SizeOfExcludingThis(aMallocSizeOf);
  1958   n += mYValue.SizeOfExcludingThis(aMallocSizeOf);
  1959   n += mZValue.SizeOfExcludingThis(aMallocSizeOf);
  1960   return n;
  1963 // --- nsCSSValuePairList -----------------
  1965 nsCSSValuePairList::~nsCSSValuePairList()
  1967   MOZ_COUNT_DTOR(nsCSSValuePairList);
  1968   NS_CSS_DELETE_LIST_MEMBER(nsCSSValuePairList, this, mNext);
  1971 nsCSSValuePairList*
  1972 nsCSSValuePairList::Clone() const
  1974   nsCSSValuePairList* result = new nsCSSValuePairList(*this);
  1975   nsCSSValuePairList* dest = result;
  1976   const nsCSSValuePairList* src = this->mNext;
  1977   while (src) {
  1978     dest->mNext = new nsCSSValuePairList(*src);
  1979     dest = dest->mNext;
  1980     src = src->mNext;
  1982   return result;
  1985 void
  1986 nsCSSValuePairList::AppendToString(nsCSSProperty aProperty,
  1987                                    nsAString& aResult,
  1988                                    nsCSSValue::Serialization aSerialization) const
  1990   const nsCSSValuePairList* item = this;
  1991   for (;;) {
  1992     NS_ABORT_IF_FALSE(item->mXValue.GetUnit() != eCSSUnit_Null,
  1993                       "unexpected null unit");
  1994     item->mXValue.AppendToString(aProperty, aResult, aSerialization);
  1995     if (item->mXValue.GetUnit() != eCSSUnit_Inherit &&
  1996         item->mXValue.GetUnit() != eCSSUnit_Initial &&
  1997         item->mXValue.GetUnit() != eCSSUnit_Unset &&
  1998         item->mYValue.GetUnit() != eCSSUnit_Null) {
  1999       aResult.Append(char16_t(' '));
  2000       item->mYValue.AppendToString(aProperty, aResult, aSerialization);
  2002     item = item->mNext;
  2003     if (!item)
  2004       break;
  2006     if (nsCSSProps::PropHasFlags(aProperty,
  2007                                  CSS_PROPERTY_VALUE_LIST_USES_COMMAS))
  2008       aResult.Append(char16_t(','));
  2009     aResult.Append(char16_t(' '));
  2013 bool
  2014 nsCSSValuePairList::operator==(const nsCSSValuePairList& aOther) const
  2016   if (this == &aOther)
  2017     return true;
  2019   const nsCSSValuePairList *p1 = this, *p2 = &aOther;
  2020   for ( ; p1 && p2; p1 = p1->mNext, p2 = p2->mNext) {
  2021     if (p1->mXValue != p2->mXValue ||
  2022         p1->mYValue != p2->mYValue)
  2023       return false;
  2025   return !p1 && !p2; // true if same length, false otherwise
  2028 size_t
  2029 nsCSSValuePairList::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
  2031   size_t n = 0;
  2032   const nsCSSValuePairList* v = this;
  2033   while (v) {
  2034     n += aMallocSizeOf(v);
  2035     n += v->mXValue.SizeOfExcludingThis(aMallocSizeOf);
  2036     n += v->mYValue.SizeOfExcludingThis(aMallocSizeOf);
  2037     v = v->mNext;
  2039   return n;
  2042 size_t
  2043 nsCSSValuePairList_heap::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
  2045   size_t n = aMallocSizeOf(this);
  2046   n += mXValue.SizeOfExcludingThis(aMallocSizeOf);
  2047   n += mYValue.SizeOfExcludingThis(aMallocSizeOf);
  2048   n += mNext ? mNext->SizeOfIncludingThis(aMallocSizeOf) : 0;
  2049   return n;
  2052 size_t
  2053 nsCSSValue::Array::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
  2055   size_t n = aMallocSizeOf(this);
  2056   for (size_t i = 0; i < mCount; i++) {
  2057     n += mArray[i].SizeOfExcludingThis(aMallocSizeOf);
  2059   return n;
  2062 css::URLValue::URLValue(nsIURI* aURI, nsStringBuffer* aString,
  2063                         nsIURI* aReferrer, nsIPrincipal* aOriginPrincipal)
  2064   : mURI(aURI),
  2065     mString(aString),
  2066     mReferrer(aReferrer),
  2067     mOriginPrincipal(aOriginPrincipal),
  2068     mURIResolved(true)
  2070   NS_ABORT_IF_FALSE(aOriginPrincipal, "Must have an origin principal");
  2071   mString->AddRef();
  2074 css::URLValue::URLValue(nsStringBuffer* aString, nsIURI* aBaseURI,
  2075                         nsIURI* aReferrer, nsIPrincipal* aOriginPrincipal)
  2076   : mURI(aBaseURI),
  2077     mString(aString),
  2078     mReferrer(aReferrer),
  2079     mOriginPrincipal(aOriginPrincipal),
  2080     mURIResolved(false)
  2082   NS_ABORT_IF_FALSE(aOriginPrincipal, "Must have an origin principal");
  2083   mString->AddRef();
  2086 css::URLValue::~URLValue()
  2088   mString->Release();
  2091 bool
  2092 css::URLValue::operator==(const URLValue& aOther) const
  2094   bool eq;
  2095   return NS_strcmp(nsCSSValue::GetBufferValue(mString),
  2096                    nsCSSValue::GetBufferValue(aOther.mString)) == 0 &&
  2097           (GetURI() == aOther.GetURI() || // handles null == null
  2098            (mURI && aOther.mURI &&
  2099             NS_SUCCEEDED(mURI->Equals(aOther.mURI, &eq)) &&
  2100             eq)) &&
  2101           (mOriginPrincipal == aOther.mOriginPrincipal ||
  2102            (NS_SUCCEEDED(mOriginPrincipal->Equals(aOther.mOriginPrincipal,
  2103                                                   &eq)) && eq));
  2106 bool
  2107 css::URLValue::URIEquals(const URLValue& aOther) const
  2109   NS_ABORT_IF_FALSE(mURIResolved && aOther.mURIResolved,
  2110                     "How do you know the URIs aren't null?");
  2111   bool eq;
  2112   // Worth comparing GetURI() to aOther.GetURI() and mOriginPrincipal to
  2113   // aOther.mOriginPrincipal, because in the (probably common) case when this
  2114   // value was one of the ones that in fact did not change this will be our
  2115   // fast path to equality
  2116   return (mURI == aOther.mURI ||
  2117           (NS_SUCCEEDED(mURI->Equals(aOther.mURI, &eq)) && eq)) &&
  2118          (mOriginPrincipal == aOther.mOriginPrincipal ||
  2119           (NS_SUCCEEDED(mOriginPrincipal->Equals(aOther.mOriginPrincipal,
  2120                                                  &eq)) && eq));
  2123 nsIURI*
  2124 css::URLValue::GetURI() const
  2126   if (!mURIResolved) {
  2127     mURIResolved = true;
  2128     // Be careful to not null out mURI before we've passed it as the base URI
  2129     nsCOMPtr<nsIURI> newURI;
  2130     NS_NewURI(getter_AddRefs(newURI),
  2131               NS_ConvertUTF16toUTF8(nsCSSValue::GetBufferValue(mString)),
  2132               nullptr, mURI);
  2133     newURI.swap(mURI);
  2136   return mURI;
  2139 size_t
  2140 css::URLValue::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
  2142   size_t n = aMallocSizeOf(this);
  2144   // This string is unshared.
  2145   n += mString->SizeOfIncludingThisMustBeUnshared(aMallocSizeOf);
  2147   // Measurement of the following members may be added later if DMD finds it is
  2148   // worthwhile:
  2149   // - mURI
  2150   // - mReferrer
  2151   // - mOriginPrincipal
  2153   return n;
  2157 css::ImageValue::ImageValue(nsIURI* aURI, nsStringBuffer* aString,
  2158                             nsIURI* aReferrer, nsIPrincipal* aOriginPrincipal,
  2159                             nsIDocument* aDocument)
  2160   : URLValue(aURI, aString, aReferrer, aOriginPrincipal)
  2162   // NB: If aDocument is not the original document, we may not be able to load
  2163   // images from aDocument.  Instead we do the image load from the original doc
  2164   // and clone it to aDocument.
  2165   nsIDocument* loadingDoc = aDocument->GetOriginalDocument();
  2166   if (!loadingDoc) {
  2167     loadingDoc = aDocument;
  2170   loadingDoc->StyleImageLoader()->LoadImage(aURI, aOriginPrincipal, aReferrer,
  2171                                             this);
  2173   if (loadingDoc != aDocument) {
  2174     aDocument->StyleImageLoader()->MaybeRegisterCSSImage(this);
  2178 static PLDHashOperator
  2179 ClearRequestHashtable(nsISupports* aKey, nsRefPtr<imgRequestProxy>& aValue,
  2180                       void* aClosure)
  2182   mozilla::css::ImageValue* image =
  2183     static_cast<mozilla::css::ImageValue*>(aClosure);
  2184   nsIDocument* doc = static_cast<nsIDocument*>(aKey);
  2186 #ifdef DEBUG
  2188     nsCOMPtr<nsIDocument> slowDoc = do_QueryInterface(aKey);
  2189     MOZ_ASSERT(slowDoc == doc);
  2191 #endif
  2193   if (doc) {
  2194     doc->StyleImageLoader()->DeregisterCSSImage(image);
  2197   if (aValue) {
  2198     aValue->CancelAndForgetObserver(NS_BINDING_ABORTED);
  2201   return PL_DHASH_REMOVE;
  2204 css::ImageValue::~ImageValue()
  2206   mRequests.Enumerate(&ClearRequestHashtable, this);
  2209 nsCSSValueGradientStop::nsCSSValueGradientStop()
  2210   : mLocation(eCSSUnit_None),
  2211     mColor(eCSSUnit_Null)
  2213   MOZ_COUNT_CTOR(nsCSSValueGradientStop);
  2216 nsCSSValueGradientStop::nsCSSValueGradientStop(const nsCSSValueGradientStop& aOther)
  2217   : mLocation(aOther.mLocation),
  2218     mColor(aOther.mColor)
  2220   MOZ_COUNT_CTOR(nsCSSValueGradientStop);
  2223 nsCSSValueGradientStop::~nsCSSValueGradientStop()
  2225   MOZ_COUNT_DTOR(nsCSSValueGradientStop);
  2228 size_t
  2229 nsCSSValueGradientStop::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
  2231   size_t n = 0;
  2232   n += mLocation.SizeOfExcludingThis(aMallocSizeOf);
  2233   n += mColor   .SizeOfExcludingThis(aMallocSizeOf);
  2234   return n;
  2237 nsCSSValueGradient::nsCSSValueGradient(bool aIsRadial,
  2238                                        bool aIsRepeating)
  2239   : mIsRadial(aIsRadial),
  2240     mIsRepeating(aIsRepeating),
  2241     mIsLegacySyntax(false),
  2242     mIsExplicitSize(false),
  2243     mBgPos(eCSSUnit_None),
  2244     mAngle(eCSSUnit_None)
  2246   mRadialValues[0].SetNoneValue();
  2247   mRadialValues[1].SetNoneValue();
  2250 size_t
  2251 nsCSSValueGradient::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
  2253   size_t n = aMallocSizeOf(this);
  2254   n += mBgPos.SizeOfExcludingThis(aMallocSizeOf);
  2255   n += mAngle.SizeOfExcludingThis(aMallocSizeOf);
  2256   n += mRadialValues[0].SizeOfExcludingThis(aMallocSizeOf);
  2257   n += mRadialValues[1].SizeOfExcludingThis(aMallocSizeOf);
  2258   n += mStops.SizeOfExcludingThis(aMallocSizeOf);
  2259   for (uint32_t i = 0; i < mStops.Length(); i++) {
  2260     n += mStops[i].SizeOfExcludingThis(aMallocSizeOf);
  2262   return n;
  2265 // --- nsCSSValueTokenStream ------------
  2267 nsCSSValueTokenStream::nsCSSValueTokenStream()
  2268   : mPropertyID(eCSSProperty_UNKNOWN)
  2269   , mShorthandPropertyID(eCSSProperty_UNKNOWN)
  2271   MOZ_COUNT_CTOR(nsCSSValueTokenStream);
  2274 nsCSSValueTokenStream::~nsCSSValueTokenStream()
  2276   MOZ_COUNT_DTOR(nsCSSValueTokenStream);
  2279 size_t
  2280 nsCSSValueTokenStream::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
  2282   size_t n = aMallocSizeOf(this);
  2283   n += mTokenStream.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
  2284   return n;
  2287 // --- nsCSSValueFloatColor -------------
  2289 bool
  2290 nsCSSValueFloatColor::operator==(nsCSSValueFloatColor& aOther) const
  2292   return mComponent1 == aOther.mComponent1 &&
  2293          mComponent2 == aOther.mComponent2 &&
  2294          mComponent3 == aOther.mComponent3 &&
  2295          mAlpha == aOther.mAlpha;
  2298 nscolor
  2299 nsCSSValueFloatColor::GetColorValue(nsCSSUnit aUnit) const
  2301   MOZ_ASSERT(nsCSSValue::IsFloatColorUnit(aUnit), "unexpected unit");
  2303   if (aUnit == eCSSUnit_PercentageRGBColor ||
  2304       aUnit == eCSSUnit_PercentageRGBAColor) {
  2305     return NS_RGBA(NSToIntRound(mComponent1 * 255.0f),
  2306                    NSToIntRound(mComponent2 * 255.0f),
  2307                    NSToIntRound(mComponent3 * 255.0f),
  2308                    NSToIntRound(mAlpha * 255.0f));
  2311   // HSL color
  2312   MOZ_ASSERT(aUnit == eCSSUnit_HSLColor ||
  2313              aUnit == eCSSUnit_HSLAColor);
  2314   nscolor hsl = NS_HSL2RGB(mComponent1, mComponent2, mComponent3);
  2315   return NS_RGBA(NS_GET_R(hsl),
  2316                  NS_GET_G(hsl),
  2317                  NS_GET_B(hsl),
  2318                  NSToIntRound(mAlpha * 255.0f));
  2321 bool
  2322 nsCSSValueFloatColor::IsNonTransparentColor() const
  2324   return mAlpha > 0.0f;
  2327 void
  2328 nsCSSValueFloatColor::AppendToString(nsCSSUnit aUnit, nsAString& aResult) const
  2330   MOZ_ASSERT(nsCSSValue::IsFloatColorUnit(aUnit), "unexpected unit");
  2332   bool hasAlpha = aUnit == eCSSUnit_PercentageRGBAColor ||
  2333                   aUnit == eCSSUnit_HSLAColor;
  2334   bool isHSL = aUnit == eCSSUnit_HSLColor ||
  2335                aUnit == eCSSUnit_HSLAColor;
  2337   if (isHSL) {
  2338     aResult.AppendLiteral("hsl");
  2339   } else {
  2340     aResult.AppendLiteral("rgb");
  2342   if (hasAlpha) {
  2343     aResult.AppendLiteral("a(");
  2344   } else {
  2345     aResult.Append('(');
  2347   if (isHSL) {
  2348     aResult.AppendFloat(mComponent1 * 360.0f);
  2349     aResult.AppendLiteral(", ");
  2350   } else {
  2351     aResult.AppendFloat(mComponent1 * 100.0f);
  2352     aResult.AppendLiteral("%, ");
  2354   aResult.AppendFloat(mComponent2 * 100.0f);
  2355   aResult.AppendLiteral("%, ");
  2356   aResult.AppendFloat(mComponent3 * 100.0f);
  2357   if (hasAlpha) {
  2358     aResult.AppendLiteral("%, ");
  2359     aResult.AppendFloat(mAlpha);
  2360     aResult.Append(')');
  2361   } else {
  2362     aResult.AppendLiteral("%)");
  2366 size_t
  2367 nsCSSValueFloatColor::SizeOfIncludingThis(
  2368                                       mozilla::MallocSizeOf aMallocSizeOf) const
  2370   size_t n = aMallocSizeOf(this);
  2371   return n;
  2374 // --- nsCSSCornerSizes -----------------
  2376 nsCSSCornerSizes::nsCSSCornerSizes(void)
  2378   MOZ_COUNT_CTOR(nsCSSCornerSizes);
  2381 nsCSSCornerSizes::nsCSSCornerSizes(const nsCSSCornerSizes& aCopy)
  2382   : mTopLeft(aCopy.mTopLeft),
  2383     mTopRight(aCopy.mTopRight),
  2384     mBottomRight(aCopy.mBottomRight),
  2385     mBottomLeft(aCopy.mBottomLeft)
  2387   MOZ_COUNT_CTOR(nsCSSCornerSizes);
  2390 nsCSSCornerSizes::~nsCSSCornerSizes()
  2392   MOZ_COUNT_DTOR(nsCSSCornerSizes);
  2395 void
  2396 nsCSSCornerSizes::Reset()
  2398   NS_FOR_CSS_FULL_CORNERS(corner) {
  2399     this->GetCorner(corner).Reset();
  2403 static_assert(NS_CORNER_TOP_LEFT == 0 && NS_CORNER_TOP_RIGHT == 1 &&
  2404               NS_CORNER_BOTTOM_RIGHT == 2 && NS_CORNER_BOTTOM_LEFT == 3,
  2405               "box corner constants not tl/tr/br/bl == 0/1/2/3");
  2407 /* static */ const nsCSSCornerSizes::corner_type
  2408 nsCSSCornerSizes::corners[4] = {
  2409   &nsCSSCornerSizes::mTopLeft,
  2410   &nsCSSCornerSizes::mTopRight,
  2411   &nsCSSCornerSizes::mBottomRight,
  2412   &nsCSSCornerSizes::mBottomLeft,
  2413 };
  2415 size_t
  2416 mozilla::css::GridTemplateAreasValue::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
  2418   size_t n = mNamedAreas.SizeOfExcludingThis(aMallocSizeOf);
  2419   n += mTemplates.SizeOfIncludingThis(aMallocSizeOf);
  2420   return n;

mercurial