Serialize border-image shorthand to shortest form, with the exception that we'll always serialize 'border-image-source'. (Bug 713643, patch 1) r=bzbarsky
authorL. David Baron <dbaron@dbaron.org>
Wed, 30 May 2012 22:19:49 -0700
changeset 99399 8653e5e29ceab8658849fe155012e1e8c7e461b3
parent 99398 1ac05e654dd90fc72a4e243da8f5efa8946390ab
child 99400 55e6c2ca07e43fccc6b529cbcfbca2b171b3364f
push id1116
push userlsblakk@mozilla.com
push dateMon, 16 Jul 2012 19:38:18 +0000
treeherdermozilla-beta@95f959a8b4dc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbzbarsky
bugs713643
milestone15.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Serialize border-image shorthand to shortest form, with the exception that we'll always serialize 'border-image-source'. (Bug 713643, patch 1) r=bzbarsky
layout/style/Declaration.cpp
layout/style/nsCSSDataBlock.cpp
layout/style/nsCSSDataBlock.h
layout/style/nsCSSValue.h
--- a/layout/style/Declaration.cpp
+++ b/layout/style/Declaration.cpp
@@ -259,27 +259,50 @@ Declaration::GetValue(nsCSSProperty aPro
             vals[i]->AppendToString(subprops[i], aValue);
           }
           if (i < 3)
             aValue.Append(PRUnichar(' '));
         }
       }
       break;
     }
-    case eCSSProperty_border_image:
+    case eCSSProperty_border_image: {
+      // Even though there are some cases where we could omit
+      // 'border-image-source' (when it's none), it's probably not a
+      // good idea since it's likely to be confusing.  It would also
+      // require adding the extra check that we serialize *something*.
       AppendValueToString(eCSSProperty_border_image_source, aValue);
-      aValue.Append(PRUnichar(' '));
-      AppendValueToString(eCSSProperty_border_image_slice, aValue);
-      aValue.Append(NS_LITERAL_STRING(" / "));
-      AppendValueToString(eCSSProperty_border_image_width, aValue);
-      aValue.Append(NS_LITERAL_STRING(" / "));
-      AppendValueToString(eCSSProperty_border_image_outset, aValue);
-      aValue.Append(PRUnichar(' '));
-      AppendValueToString(eCSSProperty_border_image_repeat, aValue);
+
+      bool sliceDefault = data->HasDefaultBorderImageSlice();
+      bool widthDefault = data->HasDefaultBorderImageWidth();
+      bool outsetDefault = data->HasDefaultBorderImageOutset();
+
+      if (!sliceDefault || !widthDefault || !outsetDefault) {
+        aValue.Append(PRUnichar(' '));
+        AppendValueToString(eCSSProperty_border_image_slice, aValue);
+        if (!widthDefault || !outsetDefault) {
+          aValue.Append(NS_LITERAL_STRING(" /"));
+          if (!widthDefault) {
+            aValue.Append(PRUnichar(' '));
+            AppendValueToString(eCSSProperty_border_image_width, aValue);
+          }
+          if (!outsetDefault) {
+            aValue.Append(NS_LITERAL_STRING(" / "));
+            AppendValueToString(eCSSProperty_border_image_outset, aValue);
+          }
+        }
+      }
+
+      bool repeatDefault = data->HasDefaultBorderImageRepeat();
+      if (!repeatDefault) {
+        aValue.Append(PRUnichar(' '));
+        AppendValueToString(eCSSProperty_border_image_repeat, aValue);
+      }
       break;
+    }
     case eCSSProperty_border: {
       const nsCSSProperty* subproptables[3] = {
         nsCSSProps::SubpropertyEntryFor(eCSSProperty_border_color),
         nsCSSProps::SubpropertyEntryFor(eCSSProperty_border_style),
         nsCSSProps::SubpropertyEntryFor(eCSSProperty_border_width)
       };
       bool match = true;
       for (const nsCSSProperty** subprops = subproptables,
--- a/layout/style/nsCSSDataBlock.cpp
+++ b/layout/style/nsCSSDataBlock.cpp
@@ -220,16 +220,51 @@ nsCSSCompressedDataBlock::SizeOfIncludin
 {
     size_t n = aMallocSizeOf(this);
     for (PRUint32 i = 0; i < mNumProps; i++) {
         n += ValueAtIndex(i)->SizeOfExcludingThis(aMallocSizeOf);
     }
     return n;
 }
 
+bool
+nsCSSCompressedDataBlock::HasDefaultBorderImageSlice() const
+{
+  const nsCSSValueList *slice =
+    ValueFor(eCSSProperty_border_image_slice)->GetListValue();
+  return !slice->mNext &&
+         slice->mValue.GetRectValue().AllSidesEqualTo(
+           nsCSSValue(1.0f, eCSSUnit_Percent));
+}
+
+bool
+nsCSSCompressedDataBlock::HasDefaultBorderImageWidth() const
+{
+  const nsCSSRect &width =
+    ValueFor(eCSSProperty_border_image_width)->GetRectValue();
+  return width.AllSidesEqualTo(nsCSSValue(1.0f, eCSSUnit_Number));
+}
+
+bool
+nsCSSCompressedDataBlock::HasDefaultBorderImageOutset() const
+{
+  const nsCSSRect &outset =
+    ValueFor(eCSSProperty_border_image_outset)->GetRectValue();
+  return outset.AllSidesEqualTo(nsCSSValue(0.0f, eCSSUnit_Number));
+}
+
+bool
+nsCSSCompressedDataBlock::HasDefaultBorderImageRepeat() const
+{
+  const nsCSSValuePair &repeat =
+    ValueFor(eCSSProperty_border_image_repeat)->GetPairValue();
+  return repeat.BothValuesEqualTo(
+    nsCSSValue(NS_STYLE_BORDER_IMAGE_REPEAT_STRETCH, eCSSUnit_Enumerated));
+}
+
 /*****************************************************************************/
 
 nsCSSExpandedDataBlock::nsCSSExpandedDataBlock()
 {
     AssertInitialState();
 }
 
 nsCSSExpandedDataBlock::~nsCSSExpandedDataBlock()
--- a/layout/style/nsCSSDataBlock.h
+++ b/layout/style/nsCSSDataBlock.h
@@ -78,16 +78,21 @@ public:
 
     /**
      * Create a new nsCSSCompressedDataBlock holding no declarations.
      */
     static nsCSSCompressedDataBlock* CreateEmptyBlock();
 
     size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
 
+    bool HasDefaultBorderImageSlice() const;
+    bool HasDefaultBorderImageWidth() const;
+    bool HasDefaultBorderImageOutset() const;
+    bool HasDefaultBorderImageRepeat() const;
+
 private:
     void* operator new(size_t aBaseSize, PRUint32 aNumProps) {
         NS_ABORT_IF_FALSE(aBaseSize == sizeof(nsCSSCompressedDataBlock),
                           "unexpected size for nsCSSCompressedDataBlock");
         return ::operator new(aBaseSize + DataSize(aNumProps));
     }
 
 public:
--- a/layout/style/nsCSSValue.h
+++ b/layout/style/nsCSSValue.h
@@ -701,16 +701,23 @@ struct nsCSSRect {
     return mTop != aOther.mTop ||
            mRight != aOther.mRight ||
            mBottom != aOther.mBottom ||
            mLeft != aOther.mLeft;
   }
 
   void SetAllSidesTo(const nsCSSValue& aValue);
 
+  bool AllSidesEqualTo(const nsCSSValue& aValue) const {
+    return mTop == aValue &&
+           mRight == aValue &&
+           mBottom == aValue &&
+           mLeft == aValue;
+  }
+
   void Reset() {
     mTop.Reset();
     mRight.Reset();
     mBottom.Reset();
     mLeft.Reset();
   }
 
   bool HasValue() const {
@@ -785,16 +792,21 @@ struct nsCSSValuePair {
            mYValue == aOther.mYValue;
   }
 
   bool operator!=(const nsCSSValuePair& aOther) const {
     return mXValue != aOther.mXValue ||
            mYValue != aOther.mYValue;
   }
 
+  bool BothValuesEqualTo(const nsCSSValue& aValue) const {
+    return mXValue == aValue &&
+           mYValue == aValue;
+  }
+
   void SetBothValuesTo(const nsCSSValue& aValue) {
     mXValue = aValue;
     mYValue = aValue;
   }
 
   void Reset() {
     mXValue.Reset();
     mYValue.Reset();
@@ -861,16 +873,22 @@ struct nsCSSValueTriplet {
     }
 
     bool operator!=(const nsCSSValueTriplet& aOther) const {
         return mXValue != aOther.mXValue ||
                mYValue != aOther.mYValue ||
                mZValue != aOther.mZValue;
     }
 
+    bool AllValuesEqualTo(const nsCSSValue& aValue) const {
+        return mXValue == aValue &&
+               mYValue == aValue &&
+               mZValue == aValue;
+    }
+
     void SetAllValuesTo(const nsCSSValue& aValue) {
         mXValue = aValue;
         mYValue = aValue;
         mZValue = aValue;
     }
 
     void Reset() {
         mXValue.Reset();