Bug 686281 - Implement CSS mask animation; r?:dbaron draft
authorCJKu <cku@mozilla.com>
Thu, 12 Nov 2015 17:04:50 +0800
changeset 308388 b8cb9aba2e365318ce527873cf415ab2ef92eae2
parent 308387 7105ac05517c1dc0ed17d73de49a9cfa78a9768e
child 308389 e385823e9ef300b18e0eba87b99da19d7326506c
push id7465
push usercku@mozilla.com
push dateThu, 12 Nov 2015 09:05:57 +0000
bugs686281
milestone45.0a1
Bug 686281 - Implement CSS mask animation; r?:dbaron
layout/generic/nsFrame.cpp
layout/style/StyleAnimationValue.cpp
layout/style/nsCSSPropList.h
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -842,17 +842,17 @@ nsFrame::DidSetStyleContext(nsStyleConte
     // calls GetUsed(Margin|Border|Padding)() before the next reflow, we
     // can give an accurate answer.
     // We don't want to set the property if one already exists.
     FrameProperties props = Properties();
     nsMargin oldValue(0, 0, 0, 0);
     nsMargin newValue(0, 0, 0, 0);
     const nsStyleMargin* oldMargin = aOldStyleContext->PeekStyleMargin();
     if (oldMargin && oldMargin->GetMargin(oldValue)) {
-      if ((!StyleMargin()->GetMargin(newValue) || oldValue != newValue) &&
+    if ((!StyleMargin()->GetMargin(newValue) || oldValue != newValue) &&
           !props.Get(UsedMarginProperty())) {
         props.Set(UsedMarginProperty(), new nsMargin(oldValue));
       }
     }
 
     const nsStylePadding* oldPadding = aOldStyleContext->PeekStylePadding();
     if (oldPadding && oldPadding->GetPadding(oldValue)) {
       if ((!StylePadding()->GetPadding(newValue) || oldValue != newValue) &&
--- a/layout/style/StyleAnimationValue.cpp
+++ b/layout/style/StyleAnimationValue.cpp
@@ -2973,16 +2973,104 @@ SubstitutePixelValues(nsStyleContext* aS
                                          conditions);
     aOutput.SetFloatValue(nsPresContext::AppUnitsToFloatCSSPixels(len),
                           eCSSUnit_Pixel);
   } else {
     aOutput = aInput;
   }
 }
 
+static void
+ExtractStyleLayerPosition(const nsStyleImageLayers &layers,
+                          StyleAnimationValue& aComputedValue)
+{
+  nsAutoPtr<nsCSSValueList> result;
+  nsCSSValueList **resultTail = getter_Transfers(result);
+  for (uint32_t i = 0, i_end = layers.mPositionCount; i != i_end; ++i) {
+    nsCSSValueList *item = new nsCSSValueList;
+    *resultTail = item;
+    resultTail = &item->mNext;
+    SetPositionValue(layers.mLayers[i].mPosition, item->mValue);
+  }
+
+  aComputedValue.SetAndAdoptCSSValueListValue(result.forget(),
+    StyleAnimationValue::eUnit_BackgroundPosition);
+}
+
+static void
+ExtractStyleLayerSize(const nsStyleImageLayers &layers,
+                      StyleAnimationValue& aComputedValue)
+{
+  nsAutoPtr<nsCSSValuePairList> result;
+  nsCSSValuePairList **resultTail = getter_Transfers(result);
+  for (uint32_t i = 0, i_end = layers.mSizeCount; i != i_end; ++i) {
+    nsCSSValuePairList *item = new nsCSSValuePairList;
+    *resultTail = item;
+    resultTail = &item->mNext;
+
+    const nsStyleImageLayers::Size &size = layers.mLayers[i].mSize;
+    switch (size.mWidthType) {
+      case nsStyleImageLayers::Size::eContain:
+      case nsStyleImageLayers::Size::eCover:
+        item->mXValue.SetIntValue(size.mWidthType,
+                                  eCSSUnit_Enumerated);
+        break;
+      case nsStyleImageLayers::Size::eAuto:
+        item->mXValue.SetAutoValue();
+        break;
+      case nsStyleImageLayers::Size::eLengthPercentage:
+        // XXXbz is there a good reason we can't just
+        // SetCalcValue(&size.mWidth, item->mXValue) here?
+        if (!size.mWidth.mHasPercent &&
+            // negative values must have come from calc()
+            size.mWidth.mLength >= 0) {
+          MOZ_ASSERT(size.mWidth.mPercent == 0.0f,
+                     "Shouldn't have mPercent");
+          nscoordToCSSValue(size.mWidth.mLength, item->mXValue);
+        } else if (size.mWidth.mLength == 0 &&
+                   // negative values must have come from calc()
+                   size.mWidth.mPercent >= 0.0f) {
+          item->mXValue.SetPercentValue(size.mWidth.mPercent);
+        } else {
+          SetCalcValue(&size.mWidth, item->mXValue);
+        }
+        break;
+    }
+
+    switch (size.mHeightType) {
+      case nsStyleImageLayers::Size::eContain:
+      case nsStyleImageLayers::Size::eCover:
+        // leave it null
+        break;
+      case nsStyleImageLayers::Size::eAuto:
+        item->mYValue.SetAutoValue();
+        break;
+      case nsStyleImageLayers::Size::eLengthPercentage:
+        // XXXbz is there a good reason we can't just
+        // SetCalcValue(&size.mHeight, item->mYValue) here?
+        if (!size.mHeight.mHasPercent &&
+            // negative values must have come from calc()
+            size.mHeight.mLength >= 0) {
+          MOZ_ASSERT(size.mHeight.mPercent == 0.0f,
+                     "Shouldn't have mPercent");
+          nscoordToCSSValue(size.mHeight.mLength, item->mYValue);
+        } else if (size.mHeight.mLength == 0 &&
+                   // negative values must have come from calc()
+                   size.mHeight.mPercent >= 0.0f) {
+          item->mYValue.SetPercentValue(size.mHeight.mPercent);
+        } else {
+          SetCalcValue(&size.mHeight, item->mYValue);
+        }
+        break;
+    }
+  }
+
+  aComputedValue.SetAndAdoptCSSValuePairListValue(result.forget());
+}
+
 bool
 StyleAnimationValue::ExtractComputedValue(nsCSSProperty aProperty,
                                           nsStyleContext* aStyleContext,
                                           StyleAnimationValue& aComputedValue)
 {
   MOZ_ASSERT(0 <= aProperty && aProperty < eCSSProperty_COUNT_no_shorthands,
              "bad property");
   const void* styleStruct =
@@ -3271,102 +3359,42 @@ StyleAnimationValue::ExtractComputedValu
           SetPositionValue(stylePos->mObjectPosition, *val);
 
           aComputedValue.SetAndAdoptCSSValueValue(val.forget(),
                                                   eUnit_ObjectPosition);
           break;
         }
 
         case eCSSProperty_background_position: {
-          const nsStyleBackground *bg =
-            static_cast<const nsStyleBackground*>(styleStruct);
-          nsAutoPtr<nsCSSValueList> result;
-          nsCSSValueList **resultTail = getter_Transfers(result);
-          MOZ_ASSERT(bg->mLayers.mPositionCount > 0, "unexpected count");
-          for (uint32_t i = 0, i_end = bg->mLayers.mPositionCount; i != i_end; ++i) {
-            nsCSSValueList *item = new nsCSSValueList;
-            *resultTail = item;
-            resultTail = &item->mNext;
-            SetPositionValue(bg->mLayers.mLayers[i].mPosition, item->mValue);
-          }
-
-          aComputedValue.SetAndAdoptCSSValueListValue(result.forget(),
-                                                      eUnit_BackgroundPosition);
+          const nsStyleImageLayers &layers =
+            static_cast<const nsStyleBackground*>(styleStruct)->mLayers;
+          MOZ_ASSERT(layers.mPositionCount > 0, "unexpected count");
+          ExtractStyleLayerPosition(layers, aComputedValue);
+          break;
+        }
+
+        case eCSSProperty_mask_position: {
+          const nsStyleImageLayers &layers =
+            static_cast<const nsStyleSVGReset*>(styleStruct)->mLayers;
+          ExtractStyleLayerPosition(layers, aComputedValue);
           break;
         }
 
         case eCSSProperty_background_size: {
-          const nsStyleBackground *bg =
-            static_cast<const nsStyleBackground*>(styleStruct);
-          nsAutoPtr<nsCSSValuePairList> result;
-          nsCSSValuePairList **resultTail = getter_Transfers(result);
-          MOZ_ASSERT(bg->mLayers.mSizeCount > 0, "unexpected count");
-          for (uint32_t i = 0, i_end = bg->mLayers.mSizeCount; i != i_end; ++i) {
-            nsCSSValuePairList *item = new nsCSSValuePairList;
-            *resultTail = item;
-            resultTail = &item->mNext;
-
-            const nsStyleImageLayers::Size &size = bg->mLayers.mLayers[i].mSize;
-            switch (size.mWidthType) {
-              case nsStyleImageLayers::Size::eContain:
-              case nsStyleImageLayers::Size::eCover:
-                item->mXValue.SetIntValue(size.mWidthType,
-                                          eCSSUnit_Enumerated);
-                break;
-              case nsStyleImageLayers::Size::eAuto:
-                item->mXValue.SetAutoValue();
-                break;
-              case nsStyleImageLayers::Size::eLengthPercentage:
-                // XXXbz is there a good reason we can't just
-                // SetCalcValue(&size.mWidth, item->mXValue) here?
-                if (!size.mWidth.mHasPercent &&
-                    // negative values must have come from calc()
-                    size.mWidth.mLength >= 0) {
-                  MOZ_ASSERT(size.mWidth.mPercent == 0.0f,
-                             "Shouldn't have mPercent");
-                  nscoordToCSSValue(size.mWidth.mLength, item->mXValue);
-                } else if (size.mWidth.mLength == 0 &&
-                           // negative values must have come from calc()
-                           size.mWidth.mPercent >= 0.0f) {
-                  item->mXValue.SetPercentValue(size.mWidth.mPercent);
-                } else {
-                  SetCalcValue(&size.mWidth, item->mXValue);
-                }
-                break;
-            }
-
-            switch (size.mHeightType) {
-              case nsStyleImageLayers::Size::eContain:
-              case nsStyleImageLayers::Size::eCover:
-                // leave it null
-                break;
-              case nsStyleImageLayers::Size::eAuto:
-                item->mYValue.SetAutoValue();
-                break;
-              case nsStyleImageLayers::Size::eLengthPercentage:
-                // XXXbz is there a good reason we can't just
-                // SetCalcValue(&size.mHeight, item->mYValue) here?
-                if (!size.mHeight.mHasPercent &&
-                    // negative values must have come from calc()
-                    size.mHeight.mLength >= 0) {
-                  MOZ_ASSERT(size.mHeight.mPercent == 0.0f,
-                             "Shouldn't have mPercent");
-                  nscoordToCSSValue(size.mHeight.mLength, item->mYValue);
-                } else if (size.mHeight.mLength == 0 &&
-                           // negative values must have come from calc()
-                           size.mHeight.mPercent >= 0.0f) {
-                  item->mYValue.SetPercentValue(size.mHeight.mPercent);
-                } else {
-                  SetCalcValue(&size.mHeight, item->mYValue);
-                }
-                break;
-            }
-          }
-
-          aComputedValue.SetAndAdoptCSSValuePairListValue(result.forget());
+          const nsStyleImageLayers &layers =
+            static_cast<const nsStyleBackground*>(styleStruct)->mLayers;
+          MOZ_ASSERT(layers.mSizeCount > 0, "unexpected count");
+          ExtractStyleLayerSize(layers, aComputedValue);
+          break;
+        }
+
+        case eCSSProperty_mask_size: {
+          const nsStyleImageLayers &layers =
+            static_cast<const nsStyleSVGReset*>(styleStruct)->mLayers;
+          ExtractStyleLayerSize(layers, aComputedValue);
           break;
         }
 
         case eCSSProperty_filter: {
           const nsStyleSVGReset *svgReset =
             static_cast<const nsStyleSVGReset*>(styleStruct);
           const nsTArray<nsStyleFilter>& filters = svgReset->mFilters;
           nsAutoPtr<nsCSSValueList> result;
--- a/layout/style/nsCSSPropList.h
+++ b/layout/style/nsCSSPropList.h
@@ -4062,30 +4062,30 @@ CSS_PROP_SVGRESET(
     MaskPosition,
     CSS_PROPERTY_PARSE_FUNCTION |
         CSS_PROPERTY_VALUE_LIST_USES_COMMAS |
         CSS_PROPERTY_STORES_CALC,
     "layout.css.masking.enabled",
     0,
     kImageLayerPositionKTable,
     CSS_PROP_NO_OFFSET,
-    eStyleAnimType_None)
+    eStyleAnimType_Custom)
 CSS_PROP_SVGRESET(
     mask-size,
     mask_size,
     MaskSize,
     CSS_PROPERTY_PARSE_FUNCTION |
         CSS_PROPERTY_VALUE_LIST_USES_COMMAS |
         CSS_PROPERTY_VALUE_NONNEGATIVE |
         CSS_PROPERTY_STORES_CALC,
     "layout.css.masking.enabled",
     0,
     kImageLayerSizeKTable,
     CSS_PROP_NO_OFFSET,
-    eStyleAnimType_None)
+    eStyleAnimType_Custom)
 CSS_PROP_SVGRESET(
     mask-type,
     mask_type,
     MaskType,
     CSS_PROPERTY_PARSE_VALUE,
     "layout.css.masking.enabled",
     VARIANT_HK,
     kMaskTypeKTable,