Bug 1429299 - Part 2: Implement offset-distance. r=emilio
authorBoris Chiou <boris.chiou@gmail.com>
Mon, 20 May 2019 23:42:52 +0000
changeset 474641 9d417fb6fcc29efd42b2b3f8070fca6518ae0c89
parent 474640 4d20aaa34b107d8abaeb11020862776858678a11
child 474642 e6343b742e91be084079764c242a4cca569423d1
push id36042
push userdvarga@mozilla.com
push dateTue, 21 May 2019 04:19:40 +0000
treeherdermozilla-central@ca560ff55451 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio
bugs1429299
milestone69.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
Bug 1429299 - Part 2: Implement offset-distance. r=emilio Define the offset-distance property in style system. Differential Revision: https://phabricator.services.mozilla.com/D30582
devtools/server/actors/animation-type-longhand.js
devtools/shared/css/generated/properties-db.js
layout/style/nsStyleStruct.cpp
layout/style/nsStyleStruct.h
layout/style/test/mochitest.ini
layout/style/test/property_database.js
servo/components/style/properties/longhands/box.mako.rs
testing/web-platform/meta/css/motion/animation/offset-distance-interpolation.html.ini
testing/web-platform/meta/css/motion/parsing/offset-distance-parsing-valid.html.ini
testing/web-platform/tests/css/motion/parsing/offset-distance-parsing-valid.html
--- a/devtools/server/actors/animation-type-longhand.js
+++ b/devtools/server/actors/animation-type-longhand.js
@@ -306,16 +306,17 @@ exports.ANIMATION_TYPE_FOR_LONGHANDS = [
     "max-height",
     "max-width",
     "min-height",
     "min-width",
     "-moz-outline-radius-bottomleft",
     "-moz-outline-radius-bottomright",
     "-moz-outline-radius-topleft",
     "-moz-outline-radius-topright",
+    "offset-distance",
     "padding-bottom",
     "padding-left",
     "padding-right",
     "padding-top",
     "perspective",
     "right",
     "row-gap",
     "scroll-padding-block-start",
--- a/devtools/shared/css/generated/properties-db.js
+++ b/devtools/shared/css/generated/properties-db.js
@@ -3088,16 +3088,17 @@ exports.CSS_PROPERTIES = {
       "scroll-snap-points-y",
       "scroll-snap-destination",
       "scroll-snap-coordinate",
       "transform",
       "rotate",
       "scale",
       "translate",
       "offset-path",
+      "offset-distance",
       "scroll-behavior",
       "scroll-snap-align",
       "scroll-snap-type",
       "overscroll-behavior-x",
       "overscroll-behavior-y",
       "isolation",
       "break-after",
       "break-before",
@@ -8246,16 +8247,29 @@ exports.CSS_PROPERTIES = {
       "initial",
       "left",
       "revert",
       "right",
       "top",
       "unset"
     ]
   },
+  "offset-distance": {
+    "isInherited": false,
+    "subproperties": [
+      "offset-distance"
+    ],
+    "supports": [],
+    "values": [
+      "inherit",
+      "initial",
+      "revert",
+      "unset"
+    ]
+  },
   "offset-path": {
     "isInherited": false,
     "subproperties": [
       "offset-path"
     ],
     "supports": [],
     "values": [
       "inherit",
@@ -10613,16 +10627,20 @@ exports.PREFERENCES = [
     "scrollbar-color",
     "layout.css.scrollbar-color.enabled"
   ],
   [
     "translate",
     "layout.css.individual-transform.enabled"
   ],
   [
+    "offset-distance",
+    "layout.css.motion-path.enabled"
+  ],
+  [
     "scroll-snap-points-x",
     "layout.css.scroll-snap.enabled"
   ],
   [
     "scroll-snap-points-y",
     "layout.css.scroll-snap.enabled"
   ],
   [
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -2980,16 +2980,17 @@ nsStyleDisplay::nsStyleDisplay(const Doc
       mScrollSnapPointsX(eStyleUnit_None),
       mScrollSnapPointsY(eStyleUnit_None),
       mScrollSnapDestination(
           {LengthPercentage::Zero(), LengthPercentage::Zero()}),
       mBackfaceVisibility(NS_STYLE_BACKFACE_VISIBILITY_VISIBLE),
       mTransformStyle(NS_STYLE_TRANSFORM_STYLE_FLAT),
       mTransformBox(StyleGeometryBox::BorderBox),
       mOffsetPath(StyleOffsetPath::None()),
+      mOffsetDistance(LengthPercentage::Zero()),
       mTransformOrigin{LengthPercentage::FromPercentage(0.5),
                        LengthPercentage::FromPercentage(0.5),
                        {0.}},
       mChildPerspective(StylePerspective::None()),
       mPerspectiveOrigin(Position::FromPercentage(0.5f)),
       mVerticalAlign(
           StyleVerticalAlign::Keyword(StyleVerticalAlignKeyword::Baseline)),
       mShapeMargin(LengthPercentage::Zero()) {
@@ -3048,16 +3049,17 @@ nsStyleDisplay::nsStyleDisplay(const nsS
       mTransform(aSource.mTransform),
       mRotate(aSource.mRotate),
       mTranslate(aSource.mTranslate),
       mScale(aSource.mScale),
       mBackfaceVisibility(aSource.mBackfaceVisibility),
       mTransformStyle(aSource.mTransformStyle),
       mTransformBox(aSource.mTransformBox),
       mOffsetPath(aSource.mOffsetPath),
+      mOffsetDistance(aSource.mOffsetDistance),
       mTransformOrigin(aSource.mTransformOrigin),
       mChildPerspective(aSource.mChildPerspective),
       mPerspectiveOrigin(aSource.mPerspectiveOrigin),
       mVerticalAlign(aSource.mVerticalAlign),
       mShapeImageThreshold(aSource.mShapeImageThreshold),
       mShapeMargin(aSource.mShapeMargin),
       mShapeOutside(aSource.mShapeOutside) {
   MOZ_COUNT_CTOR(nsStyleDisplay);
@@ -3090,28 +3092,34 @@ static inline nsChangeHint CompareTransf
       result |= nsChangeHint_UpdateOverflow;
     }
   }
 
   return result;
 }
 
 static inline nsChangeHint CompareMotionValues(
-    const StyleOffsetPath& aOffsetPath, const StyleOffsetPath& aNewOffsetPath) {
-  nsChangeHint result = nsChangeHint(0);
-
+    const StyleOffsetPath& aOffsetPath, const LengthPercentage& aOffsetDistance,
+    const StyleOffsetPath& aNewOffsetPath,
+    const LengthPercentage& aNewOffsetDistance) {
   if (aOffsetPath == aNewOffsetPath) {
-    return result;
+    if (aOffsetDistance == aNewOffsetDistance) {
+      return nsChangeHint(0);
+    }
+
+    if (aOffsetPath.IsNone()) {
+      return nsChangeHint_NeutralChange;
+    }
   }
 
   // TODO: Bug 1482737: This probably doesn't need to UpdateOverflow
   // (or UpdateTransformLayer) if there's already a transform.
   // Set the same hints as what we use for transform because motion path is
   // a kind of transform and will be combined with other transforms.
-  result |= nsChangeHint_UpdateTransformLayer;
+  nsChangeHint result = nsChangeHint_UpdateTransformLayer;
   if (!aOffsetPath.IsNone() && !aNewOffsetPath.IsNone()) {
     result |= nsChangeHint_UpdatePostTransformOverflow;
   } else {
     result |= nsChangeHint_UpdateOverflow;
   }
   return result;
 }
 
@@ -3233,17 +3241,19 @@ nsChangeHint nsStyleDisplay::CalcDiffere
      * nsChangeHint_NeutralChange.
      */
     nsChangeHint transformHint = nsChangeHint(0);
 
     transformHint |= CompareTransformValues(mTransform, aNewData.mTransform);
     transformHint |= CompareTransformValues(mRotate, aNewData.mRotate);
     transformHint |= CompareTransformValues(mTranslate, aNewData.mTranslate);
     transformHint |= CompareTransformValues(mScale, aNewData.mScale);
-    transformHint |= CompareMotionValues(mOffsetPath, aNewData.mOffsetPath);
+    transformHint |=
+        CompareMotionValues(mOffsetPath, mOffsetDistance, aNewData.mOffsetPath,
+                            aNewData.mOffsetDistance);
 
     if (mTransformOrigin != aNewData.mTransformOrigin) {
       transformHint |= nsChangeHint_UpdateTransformLayer |
                        nsChangeHint_UpdatePostTransformOverflow;
     }
 
     if (mPerspectiveOrigin != aNewData.mPerspectiveOrigin ||
         mTransformStyle != aNewData.mTransformStyle ||
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -1748,16 +1748,17 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsSt
   mozilla::StyleTranslate mTranslate;
   mozilla::StyleScale mScale;
 
   uint8_t mBackfaceVisibility;
   uint8_t mTransformStyle;
   StyleGeometryBox mTransformBox;
 
   mozilla::StyleOffsetPath mOffsetPath;
+  mozilla::LengthPercentage mOffsetDistance;
 
   mozilla::StyleTransformOrigin mTransformOrigin;
   mozilla::StylePerspective mChildPerspective;
   mozilla::Position mPerspectiveOrigin;
 
   mozilla::StyleVerticalAlign mVerticalAlign;
 
   nsCSSPropertyID GetTransitionProperty(uint32_t aIndex) const {
--- a/layout/style/test/mochitest.ini
+++ b/layout/style/test/mochitest.ini
@@ -2,16 +2,17 @@
 prefs =
   dom.animations-api.compositing.enabled=true
   dom.animations-api.core.enabled=true
   dom.animations-api.getAnimations.enabled=true
   dom.animations-api.implicit-keyframes.enabled=true
   dom.animations-api.timelines.enabled=true
   gfx.omta.background-color=true
   layout.css.individual-transform.enabled=true
+  layout.css.motion-path.enabled=true
   layout.css.step-position-jump.enabled=true
 support-files =
   animation_utils.js
   ccd-quirks.html
   ccd.sjs
   ccd-standards.html
   chrome/bug418986-2.js
   chrome/match.png
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -8740,16 +8740,25 @@ if (IsCSSPropertyPrefEnabled("layout.css
       "path('M 10 80 Q 52.5 10, 95 80 T 180 80')",
       "path('M 80 80 A 45 45, 0, 0, 0, 1.25e2 1.25e2 L 125 80 Z')",
       "path('M100-200h20z')",
       "path('M10,10L20.6.5z')"
     ],
     invalid_values: [ "path('')", "path()", "path(a)", "path('M 10 Z')" ,
                       "path('M 10-10 20')", "path('M 10 10 C 20 20 40 20')" ]
   };
+
+  gCSSProperties["offset-distance"] = {
+    domProp: "offsetDistance",
+    inherited: false,
+    type: CSS_TYPE_LONGHAND,
+    initial_values: [ "0" ],
+    other_values: [ "10px", "10%", "190%", "-280%", "calc(30px + 40%)" ],
+    invalid_values: [ "none", "45deg" ]
+  };
 }
 
 if (IsCSSPropertyPrefEnabled("layout.css.clip-path-path.enabled")) {
   gCSSProperties["clip-path"].other_values.push(
     "path(nonzero, 'M 10 10 h 100 v 100 h-100 v-100 z')",
     "path(evenodd, 'M 10 10 h 100 v 100 h-100 v-100 z')",
     "path('M10,30A20,20 0,0,1 50,30A20,20 0,0,1 90,30Q90,60 50,90Q10,60 10,30z')",
   );
--- a/servo/components/style/properties/longhands/box.mako.rs
+++ b/servo/components/style/properties/longhands/box.mako.rs
@@ -399,16 +399,29 @@
     "offset-path",
     "OffsetPath",
     "computed::OffsetPath::none()",
     products="gecko",
     animation_value_type="ComputedValue",
     gecko_pref="layout.css.motion-path.enabled",
     flags="CREATES_STACKING_CONTEXT FIXPOS_CB",
     spec="https://drafts.fxtf.org/motion-1/#offset-path-property",
+    servo_restyle_damage="reflow_out_of_flow"
+)}
+
+// Motion Path Module Level 1
+${helpers.predefined_type(
+    "offset-distance",
+    "LengthPercentage",
+    "computed::LengthPercentage::zero()",
+    products="gecko",
+    animation_value_type="none",
+    gecko_pref="layout.css.motion-path.enabled",
+    spec="https://drafts.fxtf.org/motion-1/#offset-distance-property",
+    servo_restyle_damage="reflow_out_of_flow"
 )}
 
 // CSSOM View Module
 // https://www.w3.org/TR/cssom-view-1/
 ${helpers.single_keyword(
     "scroll-behavior",
     "auto smooth",
     products="gecko",
--- a/testing/web-platform/meta/css/motion/animation/offset-distance-interpolation.html.ini
+++ b/testing/web-platform/meta/css/motion/animation/offset-distance-interpolation.html.ini
@@ -1,12 +1,9 @@
 [offset-distance-interpolation.html]
-  ["-30px" and "50px" are valid offset-distance values]
-    expected: FAIL
-
   [Animation between "-30px" and "50px" at progress -1]
     expected: FAIL
 
   [Animation between "-30px" and "50px" at progress 0]
     expected: FAIL
 
   [Animation between "-30px" and "50px" at progress 0.125]
     expected: FAIL
@@ -15,19 +12,16 @@
     expected: FAIL
 
   [Animation between "-30px" and "50px" at progress 1]
     expected: FAIL
 
   [Animation between "-30px" and "50px" at progress 2]
     expected: FAIL
 
-  ["20%" and "100%" are valid offset-distance values]
-    expected: FAIL
-
   [Animation between "20%" and "100%" at progress -1]
     expected: FAIL
 
   [Animation between "20%" and "100%" at progress 0]
     expected: FAIL
 
   [Animation between "20%" and "100%" at progress 0.125]
     expected: FAIL
@@ -36,19 +30,16 @@
     expected: FAIL
 
   [Animation between "20%" and "100%" at progress 1]
     expected: FAIL
 
   [Animation between "20%" and "100%" at progress 2]
     expected: FAIL
 
-  ["calc(20% - 30px)" and "calc(50px + 100%)" are valid offset-distance values]
-    expected: FAIL
-
   [Animation between "calc(20% - 30px)" and "calc(50px + 100%)" at progress -1]
     expected: FAIL
 
   [Animation between "calc(20% - 30px)" and "calc(50px + 100%)" at progress 0]
     expected: FAIL
 
   [Animation between "calc(20% - 30px)" and "calc(50px + 100%)" at progress 0.125]
     expected: FAIL
deleted file mode 100644
--- a/testing/web-platform/meta/css/motion/parsing/offset-distance-parsing-valid.html.ini
+++ /dev/null
@@ -1,25 +0,0 @@
-[offset-distance-parsing-valid.html]
-  [Serialization should round-trip after setting e.style['offset-distance'\] = "0"]
-    expected: FAIL
-
-  [e.style['offset-distance'\] = "10px" should set the property value]
-    expected: FAIL
-
-  [Serialization should round-trip after setting e.style['offset-distance'\] = "10px"]
-    expected: FAIL
-
-  [e.style['offset-distance'\] = "20%" should set the property value]
-    expected: FAIL
-
-  [Serialization should round-trip after setting e.style['offset-distance'\] = "20%"]
-    expected: FAIL
-
-  [e.style['offset-distance'\] = "calc(30px + 40%)" should set the property value]
-    expected: FAIL
-
-  [Serialization should round-trip after setting e.style['offset-distance'\] = "calc(30px + 40%)"]
-    expected: FAIL
-
-  [e.style['offset-distance'\] = "0" should set the property value]
-    expected: FAIL
-
--- a/testing/web-platform/tests/css/motion/parsing/offset-distance-parsing-valid.html
+++ b/testing/web-platform/tests/css/motion/parsing/offset-distance-parsing-valid.html
@@ -9,13 +9,13 @@
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/css/support/parsing-testcommon.js"></script>
 </head>
 <body>
 <script>
 test_valid_value("offset-distance", "10px");
 test_valid_value("offset-distance", "20%");
-test_valid_value("offset-distance", "calc(30px + 40%)");
+test_valid_value("offset-distance", "calc(40% + 30px)");
 test_valid_value("offset-distance", "0", "0px");
 </script>
 </body>
 </html>