Bug 569719 part 7: Add AppendToString methods to nsCSSRect and friends as well, replacing Declaration::AppendStorageToString. r=dbaron
authorZack Weinberg <zweinberg@mozilla.com>
Fri, 23 Jul 2010 11:00:29 -0700
changeset 48855 6d6e4fea65296b07719b1a9668d2234b299581b4
parent 48854 aa2c754aff8b8e588c3cb0e80b82bafc4f17fe6f
child 48856 1ff1c94e6153b002a9ffaef83bc8886020b177ee
push idunknown
push userunknown
push dateunknown
reviewersdbaron
bugs569719
milestone2.0b4pre
Bug 569719 part 7: Add AppendToString methods to nsCSSRect and friends as well, replacing Declaration::AppendStorageToString. r=dbaron
layout/style/Declaration.cpp
layout/style/Declaration.h
layout/style/nsCSSStruct.cpp
layout/style/nsCSSStruct.h
layout/style/nsStyleAnimation.cpp
--- a/layout/style/Declaration.cpp
+++ b/layout/style/Declaration.cpp
@@ -117,120 +117,50 @@ Declaration::RemoveProperty(nsCSSPropert
 
   CompressFrom(&data);
   return NS_OK;
 }
 
 PRBool Declaration::AppendValueToString(nsCSSProperty aProperty,
                                         nsAString& aResult) const
 {
+  NS_ABORT_IF_FALSE(0 <= aProperty &&
+                    aProperty < eCSSProperty_COUNT_no_shorthands,
+                    "property ID out of range");
+
   nsCSSCompressedDataBlock *data = GetValueIsImportant(aProperty)
                                       ? mImportantData : mData;
   const void *storage = data->StorageFor(aProperty);
-  return Declaration::AppendStorageToString(aProperty, storage, aResult);
-}
+  if (!storage) {
+    return PR_FALSE;
+  }
 
-/* static */ PRBool
-Declaration::AppendStorageToString(nsCSSProperty aProperty,
-                                   const void* aStorage,
-                                   nsAString& aResult)
-{
-  if (aStorage) {
-    switch (nsCSSProps::kTypeTable[aProperty]) {
-      case eCSSType_Value: {
-        const nsCSSValue *val = static_cast<const nsCSSValue*>(aStorage);
-        val->AppendToString(aProperty, aResult);
-      } break;
-      case eCSSType_Rect: {
-        const nsCSSRect *rect = static_cast<const nsCSSRect*>(aStorage);
-        const nsCSSUnit topUnit = rect->mTop.GetUnit();
-        if (topUnit == eCSSUnit_Inherit ||
-            topUnit == eCSSUnit_Initial ||
-            topUnit == eCSSUnit_RectIsAuto) {
-          NS_ASSERTION(rect->mRight.GetUnit() == topUnit &&
-                       rect->mBottom.GetUnit() == topUnit &&
-                       rect->mLeft.GetUnit() == topUnit,
-                       "parser should make all sides have the same unit");
-          if (topUnit == eCSSUnit_RectIsAuto)
-            aResult.AppendLiteral("auto");
-          else
-            rect->mTop.AppendToString(aProperty, aResult);
-        } else {
-          aResult.AppendLiteral("rect(");
-          rect->mTop.AppendToString(aProperty, aResult);
-          NS_NAMED_LITERAL_STRING(comma, ", ");
-          aResult.Append(comma);
-          rect->mRight.AppendToString(aProperty, aResult);
-          aResult.Append(comma);
-          rect->mBottom.AppendToString(aProperty, aResult);
-          aResult.Append(comma);
-          rect->mLeft.AppendToString(aProperty, aResult);
-          aResult.Append(PRUnichar(')'));
-        }
-      } break;
-      case eCSSType_ValuePair: {
-        const nsCSSValuePair *pair = static_cast<const nsCSSValuePair*>(aStorage);
-        pair->mXValue.AppendToString(aProperty, aResult);
-        if (pair->mYValue != pair->mXValue ||
-            ((aProperty == eCSSProperty_background_position ||
-              aProperty == eCSSProperty__moz_transform_origin) &&
-             pair->mXValue.GetUnit() != eCSSUnit_Inherit &&
-             pair->mXValue.GetUnit() != eCSSUnit_Initial) ||
-            (aProperty == eCSSProperty_background_size &&
-             pair->mXValue.GetUnit() != eCSSUnit_Inherit &&
-             pair->mXValue.GetUnit() != eCSSUnit_Initial &&
-             pair->mXValue.GetUnit() != eCSSUnit_Enumerated)) {
-          // Only output a Y value if it's different from the X value,
-          // or if it's a background-position value other than 'initial'
-          // or 'inherit', or if it's a -moz-transform-origin value other
-          // than 'initial' or 'inherit', or if it's a background-size
-          // value other than 'initial' or 'inherit' or 'contain' or 'cover'.
-          aResult.Append(PRUnichar(' '));
-          pair->mYValue.AppendToString(aProperty, aResult);
-        }
-      } break;
-      case eCSSType_ValueList: {
-        const nsCSSValueList* val =
-            *static_cast<nsCSSValueList*const*>(aStorage);
-        do {
-          val->mValue.AppendToString(aProperty, aResult);
-          val = val->mNext;
-          if (val) {
-            if (nsCSSProps::PropHasFlags(aProperty,
-                                         CSS_PROPERTY_VALUE_LIST_USES_COMMAS))
-              aResult.Append(PRUnichar(','));
-            aResult.Append(PRUnichar(' '));
-          }
-        } while (val);
-      } break;
-      case eCSSType_ValuePairList: {
-        const nsCSSValuePairList* item =
-            *static_cast<nsCSSValuePairList*const*>(aStorage);
-        do {
-          NS_ASSERTION(item->mXValue.GetUnit() != eCSSUnit_Null,
-                       "unexpected null unit");
-          item->mXValue.AppendToString(aProperty, aResult);
-          if (item->mXValue.GetUnit() != eCSSUnit_Inherit &&
-              item->mXValue.GetUnit() != eCSSUnit_Initial &&
-              item->mYValue.GetUnit() != eCSSUnit_Null) {
-            aResult.Append(PRUnichar(' '));
-            item->mYValue.AppendToString(aProperty, aResult);
-          }
-          item = item->mNext;
-          if (item) {
-            if (nsCSSProps::PropHasFlags(aProperty,
-                                         CSS_PROPERTY_VALUE_LIST_USES_COMMAS))
-              aResult.Append(PRUnichar(','));
-            aResult.Append(PRUnichar(' '));
-          }
-        } while (item);
-      } break;
-    }
+  switch (nsCSSProps::kTypeTable[aProperty]) {
+    case eCSSType_Value:
+      static_cast<const nsCSSValue*>(storage)->
+        AppendToString(aProperty, aResult);
+      break;
+    case eCSSType_Rect:
+      static_cast<const nsCSSRect*>(storage)->
+        AppendToString(aProperty, aResult);
+      break;
+    case eCSSType_ValuePair:
+      static_cast<const nsCSSValuePair*>(storage)->
+        AppendToString(aProperty, aResult);
+      break;
+    case eCSSType_ValueList:
+      (*static_cast<nsCSSValueList*const*>(storage))->
+        AppendToString(aProperty, aResult);
+      break;
+    case eCSSType_ValuePairList:
+      (*static_cast<nsCSSValuePairList*const*>(storage))->
+        AppendToString(aProperty, aResult);
+      break;
   }
-  return aStorage != nsnull;
+  return PR_TRUE;
 }
 
 nsresult
 Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue) const
 {
   aValue.Truncate(0);
 
   // simple properties are easy.
--- a/layout/style/Declaration.h
+++ b/layout/style/Declaration.h
@@ -182,21 +182,16 @@ public:
     mImportantData = nsnull;
     mOrder.Clear();
   }
 
 #ifdef DEBUG
   void List(FILE* out = stdout, PRInt32 aIndent = 0) const;
 #endif
 
-  // return whether there was a value in |aStorage| (i.e., it was non-null)
-  static PRBool AppendStorageToString(nsCSSProperty aProperty,
-                                      const void* aStorage,
-                                      nsAString& aResult);
-
 private:
   // Not implemented, and not supported.
   Declaration& operator=(const Declaration& aCopy);
   PRBool operator==(const Declaration& aCopy) const;
 
   static void AppendImportanceToString(PRBool aIsImportant, nsAString& aString);
   // return whether there was a value in |aValue| (i.e., it had a non-null unit)
   PRBool   AppendValueToString(nsCSSProperty aProperty, nsAString& aResult) const;
--- a/layout/style/nsCSSStruct.cpp
+++ b/layout/style/nsCSSStruct.cpp
@@ -88,16 +88,32 @@ nsCSSValueList::Clone() const
   while (src) {
     dest->mNext = new nsCSSValueList(*src);
     dest = dest->mNext;
     src = src->mNext;
   }
   return result;
 }
 
+void
+nsCSSValueList::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const
+{
+  const nsCSSValueList* val = this;
+  for (;;) {
+    val->mValue.AppendToString(aProperty, aResult);
+    val = val->mNext;
+    if (!val)
+      break;
+
+    if (nsCSSProps::PropHasFlags(aProperty, CSS_PROPERTY_VALUE_LIST_USES_COMMAS))
+      aResult.Append(PRUnichar(','));
+    aResult.Append(PRUnichar(' '));
+  }
+}
+
 bool
 nsCSSValueList::operator==(const nsCSSValueList& aOther) const
 {
   if (this == &aOther)
     return true;
 
   const nsCSSValueList *p1 = this, *p2 = &aOther;
   for ( ; p1 && p2; p1 = p1->mNext, p2 = p2->mNext) {
@@ -164,16 +180,45 @@ nsCSSRect::nsCSSRect(const nsCSSRect& aC
   MOZ_COUNT_CTOR(nsCSSRect);
 }
 
 nsCSSRect::~nsCSSRect()
 {
   MOZ_COUNT_DTOR(nsCSSRect);
 }
 
+void
+nsCSSRect::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const
+{
+  const nsCSSUnit topUnit = mTop.GetUnit();
+  if (topUnit == eCSSUnit_Inherit ||
+      topUnit == eCSSUnit_Initial ||
+      topUnit == eCSSUnit_RectIsAuto) {
+    NS_ASSERTION(mRight.GetUnit() == topUnit &&
+                 mBottom.GetUnit() == topUnit &&
+                 mLeft.GetUnit() == topUnit,
+                 "parser should make all sides have the same unit");
+    if (topUnit == eCSSUnit_RectIsAuto)
+      aResult.AppendLiteral("auto");
+    else
+      mTop.AppendToString(aProperty, aResult);
+  } else {
+    aResult.AppendLiteral("rect(");
+    mTop.AppendToString(aProperty, aResult);
+    NS_NAMED_LITERAL_STRING(comma, ", ");
+    aResult.Append(comma);
+    mRight.AppendToString(aProperty, aResult);
+    aResult.Append(comma);
+    mBottom.AppendToString(aProperty, aResult);
+    aResult.Append(comma);
+    mLeft.AppendToString(aProperty, aResult);
+    aResult.Append(PRUnichar(')'));
+  }
+}
+
 void nsCSSRect::SetAllSidesTo(const nsCSSValue& aValue)
 {
   mTop = aValue;
   mRight = aValue;
   mBottom = aValue;
   mLeft = aValue;
 }
 
@@ -345,17 +390,42 @@ nsCSSPage::nsCSSPage(void)
   MOZ_COUNT_CTOR(nsCSSPage);
 }
 
 nsCSSPage::~nsCSSPage(void)
 {
   MOZ_COUNT_DTOR(nsCSSPage);
 }
 
-// --- nsCSSContent support -----------------
+// --- nsCSSValuePair -----------------
+
+void
+nsCSSValuePair::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const
+{
+  mXValue.AppendToString(aProperty, aResult);
+  if (mYValue != mXValue ||
+      ((aProperty == eCSSProperty_background_position ||
+        aProperty == eCSSProperty__moz_transform_origin) &&
+       mXValue.GetUnit() != eCSSUnit_Inherit &&
+       mXValue.GetUnit() != eCSSUnit_Initial) ||
+      (aProperty == eCSSProperty_background_size &&
+       mXValue.GetUnit() != eCSSUnit_Inherit &&
+       mXValue.GetUnit() != eCSSUnit_Initial &&
+       mXValue.GetUnit() != eCSSUnit_Enumerated)) {
+    // Only output a Y value if it's different from the X value,
+    // or if it's a background-position value other than 'initial'
+    // or 'inherit', or if it's a -moz-transform-origin value other
+    // than 'initial' or 'inherit', or if it's a background-size
+    // value other than 'initial' or 'inherit' or 'contain' or 'cover'.
+    aResult.Append(PRUnichar(' '));
+    mYValue.AppendToString(aProperty, aResult);
+  }
+}
+
+// --- nsCSSValuePairList -----------------
 
 nsCSSValuePairList::~nsCSSValuePairList()
 {
   MOZ_COUNT_DTOR(nsCSSValuePairList);
   NS_CSS_DELETE_LIST_MEMBER(nsCSSValuePairList, this, mNext);
 }
 
 nsCSSValuePairList*
@@ -367,16 +437,41 @@ nsCSSValuePairList::Clone() const
   while (src) {
     dest->mNext = new nsCSSValuePairList(*src);
     dest = dest->mNext;
     src = src->mNext;
   }
   return result;
 }
 
+void
+nsCSSValuePairList::AppendToString(nsCSSProperty aProperty,
+                                   nsAString& aResult) const
+{
+  const nsCSSValuePairList* val = this;
+  for (;;) {
+    NS_ABORT_IF_FALSE(val->mXValue.GetUnit() != eCSSUnit_Null,
+                      "unexpected null unit");
+    val->mXValue.AppendToString(aProperty, aResult);
+    if (val->mXValue.GetUnit() != eCSSUnit_Inherit &&
+        val->mXValue.GetUnit() != eCSSUnit_Initial &&
+        val->mYValue.GetUnit() != eCSSUnit_Null) {
+      aResult.Append(PRUnichar(' '));
+      val->mYValue.AppendToString(aProperty, aResult);
+    }
+    val = val->mNext;
+    if (!val)
+      break;
+
+    if (nsCSSProps::PropHasFlags(aProperty, CSS_PROPERTY_VALUE_LIST_USES_COMMAS))
+      aResult.Append(PRUnichar(','));
+    aResult.Append(PRUnichar(' '));
+  }
+}
+
 bool
 nsCSSValuePairList::operator==(const nsCSSValuePairList& aOther) const
 {
   if (this == &aOther)
     return true;
 
   const nsCSSValuePairList *p1 = this, *p2 = &aOther;
   for ( ; p1 && p2; p1 = p1->mNext, p2 = p2->mNext) {
--- a/layout/style/nsCSSStruct.h
+++ b/layout/style/nsCSSStruct.h
@@ -49,16 +49,17 @@
 #include "nsStyleConsts.h"
 
 // Prefer nsCSSValue::Array for lists of fixed size.
 struct nsCSSValueList {
   nsCSSValueList() : mNext(nsnull) { MOZ_COUNT_CTOR(nsCSSValueList); }
   ~nsCSSValueList();
 
   nsCSSValueList* Clone() const;  // makes a deep copy
+  void AppendToString(nsCSSProperty aProperty, nsAString& aResult) const;
 
   bool operator==(nsCSSValueList const& aOther) const; // deep comparison
   bool operator!=(const nsCSSValueList& aOther) const
   { return !(*this == aOther); }
 
   nsCSSValue      mValue;
   nsCSSValueList* mNext;
 
@@ -70,16 +71,18 @@ private:
   }
 };
 
 struct nsCSSRect {
   nsCSSRect(void);
   nsCSSRect(const nsCSSRect& aCopy);
   ~nsCSSRect();
 
+  void AppendToString(nsCSSProperty aProperty, nsAString& aResult) const;
+
   PRBool operator==(const nsCSSRect& aOther) const {
     return mTop == aOther.mTop &&
            mRight == aOther.mRight &&
            mBottom == aOther.mBottom &&
            mLeft == aOther.mLeft;
   }
 
   PRBool operator!=(const nsCSSRect& aOther) const {
@@ -155,16 +158,18 @@ struct nsCSSValuePair {
     mYValue.Reset();
   }
 
   PRBool HasValue() const {
     return mXValue.GetUnit() != eCSSUnit_Null ||
            mYValue.GetUnit() != eCSSUnit_Null;
   }
 
+  void AppendToString(nsCSSProperty aProperty, nsAString& aResult) const;
+
   nsCSSValue mXValue;
   nsCSSValue mYValue;
 };
 
 struct nsCSSCornerSizes {
   nsCSSCornerSizes(void);
   nsCSSCornerSizes(const nsCSSCornerSizes& aCopy);
   ~nsCSSCornerSizes();
@@ -238,16 +243,17 @@ struct nsCSSValueListRect {
 };
 
 // Maybe should be replaced with nsCSSValueList and nsCSSValue::Array?
 struct nsCSSValuePairList {
   nsCSSValuePairList() : mNext(nsnull) { MOZ_COUNT_CTOR(nsCSSValuePairList); }
   ~nsCSSValuePairList();
 
   nsCSSValuePairList* Clone() const; // makes a deep copy
+  void AppendToString(nsCSSProperty aProperty, nsAString& aResult) const;
 
   bool operator==(const nsCSSValuePairList& aOther) const; // deep comparison
   bool operator!=(const nsCSSValuePairList& aOther) const
   { return !(*this == aOther); }
 
   nsCSSValue          mXValue;
   nsCSSValue          mYValue;
   nsCSSValuePairList* mNext;
--- a/layout/style/nsStyleAnimation.cpp
+++ b/layout/style/nsStyleAnimation.cpp
@@ -1867,45 +1867,67 @@ nsStyleAnimation::UncomputeValue(nsCSSPr
   aSpecifiedValue.Truncate(); // Clear outparam, if it's not already empty
 
   if (aComputedValue.GetUnit() == eUnit_UnparsedString) {
     aComputedValue.GetStringValue(aSpecifiedValue);
     return PR_TRUE;
   }
   nsCSSValuePair vp;
   nsCSSRect rect;
-  void *ptr = nsnull;
+  nsCSSValueList* vl = nsnull;
+  nsCSSValuePairList* vpl = nsnull;
   void *storage;
   switch (nsCSSProps::kTypeTable[aProperty]) {
     case eCSSType_Value:
       storage = &vp.mXValue;
       break;
     case eCSSType_Rect:
       storage = &rect;
       break;
     case eCSSType_ValuePair:
       storage = &vp;
       break;
     case eCSSType_ValueList:
+      storage = &vl;
+      break;
     case eCSSType_ValuePairList:
-      storage = &ptr;
+      storage = &vpl;
       break;
     default:
       NS_ABORT_IF_FALSE(PR_FALSE, "unexpected case");
       storage = nsnull;
       break;
   }
 
-  nsCSSValue value;
   if (!nsStyleAnimation::UncomputeValue(aProperty, aPresContext,
                                         aComputedValue, storage)) {
     return PR_FALSE;
   }
-  return css::Declaration::AppendStorageToString(aProperty, storage,
-                                                 aSpecifiedValue);
+
+  switch (nsCSSProps::kTypeTable[aProperty]) {
+    case eCSSType_Value:
+      vp.mXValue.AppendToString(aProperty, aSpecifiedValue);
+      break;
+    case eCSSType_Rect:
+      rect.AppendToString(aProperty, aSpecifiedValue);
+      break;
+    case eCSSType_ValuePair:
+      vp.AppendToString(aProperty, aSpecifiedValue);
+      break;
+    case eCSSType_ValueList:
+      vl->AppendToString(aProperty, aSpecifiedValue);
+      break;
+    case eCSSType_ValuePairList:
+      vpl->AppendToString(aProperty, aSpecifiedValue);
+      break;
+    default:
+      NS_ABORT_IF_FALSE(PR_FALSE, "unexpected case");
+      return PR_FALSE;
+  }
+  return PR_TRUE;
 }
 
 inline const void*
 StyleDataAtOffset(const void* aStyleStruct, ptrdiff_t aOffset)
 {
   return reinterpret_cast<const char*>(aStyleStruct) + aOffset;
 }