Bug 1438072 - Part 1: Put unchanged item to bottom of list. r?pbro draft
authorDaisuke Akatsuka <dakatsuka@mozilla.com>
Tue, 20 Mar 2018 15:25:51 +0900
changeset 769833 c493a571f39213b5ba15d7154a36f85b95d5477f
parent 769832 c2c6ae14fc15f9e4be26bd9fac12ae2bd9eb53e0
child 769834 5597dea5e90ab60f23adf2074aec5aff8b07d83d
push id103230
push userbmo:dakatsuka@mozilla.com
push dateTue, 20 Mar 2018 06:32:07 +0000
reviewerspbro
bugs1438072
milestone61.0a1
Bug 1438072 - Part 1: Put unchanged item to bottom of list. r?pbro MozReview-Commit-ID: KresprCD08d
devtools/client/inspector/animation/components/AnimatedPropertyList.js
--- a/devtools/client/inspector/animation/components/AnimatedPropertyList.js
+++ b/devtools/client/inspector/animation/components/AnimatedPropertyList.js
@@ -20,21 +20,19 @@ class AnimatedPropertyList extends PureC
       simulateAnimation: PropTypes.func.isRequired,
     };
   }
 
   constructor(props) {
     super(props);
 
     this.state = {
-      // Map which is mapped property name and the keyframes.
-      animatedPropertyMap: null,
-      // Object which is mapped property name and the animation type
-      // such the "color", "discrete", "length" and so on.
-      animationTypes: null,
+      // Array of object which has the property name, the keyframes, its aniamtion type
+      // and unchanged flag.
+      animatedProperties: null,
       // To avoid rendering while the state is updating
       // since we call an async function in updateState.
       isStateUpdating: false,
     };
   }
 
   componentDidMount() {
     // No need to set isStateUpdating state since paint sequence is finish here.
@@ -63,61 +61,76 @@ class AnimatedPropertyList extends PureC
   }
 
   async updateState(animation) {
     const {
       getAnimatedPropertyMap,
       emitEventForTest,
     } = this.props;
 
-    let animatedPropertyMap = null;
-    let animationTypes = null;
+    let propertyMap = null;
+    let propertyNames = null;
+    let types = null;
 
     try {
-      animatedPropertyMap = await getAnimatedPropertyMap(animation);
-      animationTypes = await animation.getAnimationTypes(animatedPropertyMap.keys());
+      propertyMap = await getAnimatedPropertyMap(animation);
+      propertyNames = [...propertyMap.keys()];
+      types = await animation.getAnimationTypes(propertyNames);
     } catch (e) {
       // Expected if we've already been destroyed or other node have been selected
       // in the meantime.
       console.error(e);
       return;
     }
 
+    const animatedProperties = propertyNames.map(name => {
+      const keyframes = propertyMap.get(name);
+      const type = types[name];
+      const isUnchanged =
+        keyframes.every(keyframe => keyframe.value === keyframes[0].value);
+      return { isUnchanged, keyframes, name, type };
+    });
+
+    animatedProperties.sort((a, b) => {
+      if (a.isUnchanged === b.isUnchanged) {
+        return a.name > b.name ? 1 : -1;
+      }
+
+      return a.isUnchanged ? 1 : -1;
+    });
+
     this.setState(
       {
-        animatedPropertyMap,
-        animationTypes,
+        animatedProperties,
         isStateUpdating: false
       }
     );
 
     emitEventForTest("animation-keyframes-rendered");
   }
 
   render() {
     const {
       getComputedStyle,
       simulateAnimation,
     } = this.props;
     const {
-      animatedPropertyMap,
-      animationTypes,
+      animatedProperties,
     } = this.state;
 
-    if (!animatedPropertyMap) {
+    if (!animatedProperties) {
       return null;
     }
 
     return dom.ul(
       {
         className: "animated-property-list"
       },
-      [...animatedPropertyMap.entries()].map(([name, keyframes]) => {
+      animatedProperties.map(({ keyframes, name, type }) => {
         const state = this.getPropertyState(name);
-        const type = animationTypes[name];
         return AnimatedPropertyItem(
           {
             getComputedStyle,
             keyframes,
             name,
             simulateAnimation,
             state,
             type,