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. this.updateState(this.props.animation); } // FIXME: https://bugzilla.mozilla.org/show_bug.cgi?id=1774507 UNSAFE_componentWillReceiveProps(nextProps) { this.setState({ isStateUpdating: true }); this.updateState(nextProps.animation); } shouldComponentUpdate(nextProps, nextState) { return !nextState.isStateUpdating; } getPropertyState(property) { const { animation } = this.props; for (const propState of animation.state.propertyState) { if (propState.property === property) { return propState; } } return null; } async updateState(animation) { const { getAnimatedPropertyMap, emitEventForTest } = this.props; let propertyMap = null; let propertyNames = null; let types = null; try { propertyMap = 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({ animatedProperties, isStateUpdating: false, }); emitEventForTest("animation-keyframes-rendered"); } render() { const { getComputedStyle, simulateAnimation } = this.props; const { animatedProperties } = this.state; if (!animatedProperties) { return null; } return dom.ul( { className: "animated-property-list", }, animatedProperties.map(({ isUnchanged, keyframes, name, type }) => { const state = this.getPropertyState(name); return AnimatedPropertyItem({ getComputedStyle, isUnchanged, keyframes, name, simulateAnimation, state, type, }); }) ); } } module.exports = AnimatedPropertyList; PK