Bug 1416104 - Part 9: Add close button. r?gl draft
authorDaisuke Akatsuka <dakatsuka@mozilla.com>
Fri, 19 Jan 2018 16:40:36 +0900
changeset 722549 f7c1f3cf3098df74d773bc833d068b434141c8b2
parent 722548 c7aef85da72f55a31a04d8dd6820c51c71584388
child 722550 a1720f07daaca1831395ff0348b690f948b5c438
push id96169
push userbmo:dakatsuka@mozilla.com
push dateFri, 19 Jan 2018 07:44:47 +0000
reviewersgl
bugs1416104
milestone59.0a1
Bug 1416104 - Part 9: Add close button. r?gl MozReview-Commit-ID: AMFpjjYdcxr
devtools/client/inspector/animation/actions/animations.js
devtools/client/inspector/animation/actions/index.js
devtools/client/inspector/animation/animation.js
devtools/client/inspector/animation/components/AnimationDetailContainer.js
devtools/client/inspector/animation/components/AnimationDetailHeader.js
devtools/client/inspector/animation/components/App.js
devtools/client/inspector/animation/reducers/animations.js
devtools/client/themes/animation.css
--- a/devtools/client/inspector/animation/actions/animations.js
+++ b/devtools/client/inspector/animation/actions/animations.js
@@ -1,16 +1,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 const {
   UPDATE_ANIMATIONS,
+  UPDATE_DETAIL_VISIBILITY,
   UPDATE_ELEMENT_PICKER_ENABLED,
   UPDATE_SELECTED_ANIMATION,
   UPDATE_SIDEBAR_SIZE
 } = require("./index");
 
 module.exports = {
   /**
    * Update the list of animation in the animation inspector.
@@ -18,16 +19,26 @@ module.exports = {
   updateAnimations(animations) {
     return {
       type: UPDATE_ANIMATIONS,
       animations,
     };
   },
 
   /**
+   * Update visibility of detail pane.
+   */
+  updateDetailVisibility(detailVisibility) {
+    return {
+      type: UPDATE_DETAIL_VISIBILITY,
+      detailVisibility,
+    };
+  },
+
+  /**
    * Update the state of element picker in animation inspector.
    */
   updateElementPickerEnabled(elementPickerEnabled) {
     return {
       type: UPDATE_ELEMENT_PICKER_ENABLED,
       elementPickerEnabled,
     };
   },
--- a/devtools/client/inspector/animation/actions/index.js
+++ b/devtools/client/inspector/animation/actions/index.js
@@ -6,16 +6,19 @@
 
 const { createEnum } = require("devtools/client/shared/enum");
 
 createEnum([
 
   // Update the list of animation.
   "UPDATE_ANIMATIONS",
 
+  // Update visibility of detail pane.
+  "UPDATE_DETAIL_VISIBILITY",
+
   // Update state of the picker enabled.
   "UPDATE_ELEMENT_PICKER_ENABLED",
 
   // Update selected animation.
   "UPDATE_SELECTED_ANIMATION",
 
   // Update sidebar size.
   "UPDATE_SIDEBAR_SIZE",
--- a/devtools/client/inspector/animation/animation.js
+++ b/devtools/client/inspector/animation/animation.js
@@ -9,30 +9,32 @@ const { createElement, createFactory } =
 const { Provider } = require("devtools/client/shared/vendor/react-redux");
 
 const EventEmitter = require("devtools/shared/event-emitter");
 
 const App = createFactory(require("./components/App"));
 
 const {
   updateAnimations,
+  updateDetailVisibility,
   updateElementPickerEnabled,
   updateSelectedAnimation,
   updateSidebarSize
 } = require("./actions/animations");
 const { isAllAnimationEqual } = require("./utils/utils");
 
 class AnimationInspector {
   constructor(inspector, win) {
     this.inspector = inspector;
     this.win = win;
 
     this.getAnimatedPropertyMap = this.getAnimatedPropertyMap.bind(this);
     this.getNodeFromActor = this.getNodeFromActor.bind(this);
     this.selectAnimation = this.selectAnimation.bind(this);
+    this.setDetailVisibility = this.setDetailVisibility.bind(this);
     this.simulateAnimation = this.simulateAnimation.bind(this);
     this.toggleElementPicker = this.toggleElementPicker.bind(this);
     this.update = this.update.bind(this);
     this.onElementPickerStarted = this.onElementPickerStarted.bind(this);
     this.onElementPickerStopped = this.onElementPickerStopped.bind(this);
     this.onSidebarResized = this.onSidebarResized.bind(this);
     this.onSidebarSelect = this.onSidebarSelect.bind(this);
 
@@ -52,16 +54,17 @@ class AnimationInspector {
       onHideBoxModelHighlighter,
     } = this.inspector.getPanel("boxmodel").getComponentProps();
 
     const {
       emit: emitEventForTest,
       getAnimatedPropertyMap,
       getNodeFromActor,
       selectAnimation,
+      setDetailVisibility,
       simulateAnimation,
       toggleElementPicker,
     } = this;
 
     const target = this.inspector.target;
     this.animationsFront = new AnimationsFront(target.client, target.form);
 
     const provider = createElement(Provider,
@@ -73,16 +76,17 @@ class AnimationInspector {
       App(
         {
           emitEventForTest,
           getAnimatedPropertyMap,
           getNodeFromActor,
           onHideBoxModelHighlighter,
           onShowBoxModelHighlighterForNode,
           selectAnimation,
+          setDetailVisibility,
           setSelectedNode,
           simulateAnimation,
           toggleElementPicker,
         }
       )
     );
     this.provider = provider;
 
@@ -232,16 +236,20 @@ class AnimationInspector {
 
     done();
   }
 
   selectAnimation(animation) {
     this.inspector.store.dispatch(updateSelectedAnimation(animation));
   }
 
+  setDetailVisibility(isVisible) {
+    this.inspector.store.dispatch(updateDetailVisibility(isVisible));
+  }
+
   onElementPickerStarted() {
     this.inspector.store.dispatch(updateElementPickerEnabled(true));
   }
 
   onElementPickerStopped() {
     this.inspector.store.dispatch(updateElementPickerEnabled(false));
   }
 
--- a/devtools/client/inspector/animation/components/AnimationDetailContainer.js
+++ b/devtools/client/inspector/animation/components/AnimationDetailContainer.js
@@ -13,33 +13,36 @@ const AnimationDetailHeader = createFact
 const AnimatedPropertyListContainer =
   createFactory(require("./AnimatedPropertyListContainer"));
 
 class AnimationDetailContainer extends PureComponent {
   static get propTypes() {
     return {
       animation: PropTypes.object.isRequired,
       getAnimatedPropertyMap: PropTypes.func.isRequired,
+      setDetailVisibility: PropTypes.func.isRequired,
     };
   }
 
   render() {
     const {
       animation,
       getAnimatedPropertyMap,
+      setDetailVisibility,
     } = this.props;
 
     return dom.div(
       {
         className: "animation-detail-container"
       },
       animation ?
         AnimationDetailHeader(
           {
             animation,
+            setDetailVisibility,
           }
         )
       :
         null,
       animation ?
         AnimatedPropertyListContainer(
           {
             animation,
--- a/devtools/client/inspector/animation/components/AnimationDetailHeader.js
+++ b/devtools/client/inspector/animation/components/AnimationDetailHeader.js
@@ -9,24 +9,41 @@ const dom = require("devtools/client/sha
 const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
 
 const { getFormattedTitle } = require("../utils/l10n");
 
 class AnimationDetailHeader extends PureComponent {
   static get propTypes() {
     return {
       animation: PropTypes.object.isRequired,
+      setDetailVisibility: PropTypes.func.isRequired,
     };
   }
 
+  onClick() {
+    const { setDetailVisibility } = this.props;
+    setDetailVisibility(false);
+  }
+
   render() {
     const { animation } = this.props;
 
     return dom.div(
       {
         className: "animation-detail-header devtools-toolbar",
       },
-      getFormattedTitle(animation.state)
+      dom.div(
+        {
+          className: "animation-detail-title",
+        },
+        getFormattedTitle(animation.state)
+      ),
+      dom.button(
+        {
+          className: "animation-detail-close-button devtools-button",
+          onClick: this.onClick.bind(this),
+        }
+      )
     );
   }
 }
 
 module.exports = AnimationDetailHeader;
--- a/devtools/client/inspector/animation/components/App.js
+++ b/devtools/client/inspector/animation/components/App.js
@@ -20,16 +20,17 @@ class App extends PureComponent {
       animations: PropTypes.arrayOf(PropTypes.object).isRequired,
       detailVisibility: PropTypes.bool.isRequired,
       emitEventForTest: PropTypes.func.isRequired,
       getAnimatedPropertyMap: PropTypes.func.isRequired,
       getNodeFromActor: PropTypes.func.isRequired,
       onHideBoxModelHighlighter: PropTypes.func.isRequired,
       onShowBoxModelHighlighterForNode: PropTypes.func.isRequired,
       selectAnimation: PropTypes.func.isRequired,
+      setDetailVisibility: PropTypes.func.isRequired,
       setSelectedNode: PropTypes.func.isRequired,
       simulateAnimation: PropTypes.func.isRequired,
       toggleElementPicker: PropTypes.func.isRequired,
     };
   }
 
   shouldComponentUpdate(nextProps, nextState) {
     return this.props.animations.length !== 0 || nextProps.animations.length !== 0;
@@ -40,32 +41,34 @@ class App extends PureComponent {
       animations,
       detailVisibility,
       emitEventForTest,
       getAnimatedPropertyMap,
       getNodeFromActor,
       onHideBoxModelHighlighter,
       onShowBoxModelHighlighterForNode,
       selectAnimation,
+      setDetailVisibility,
       setSelectedNode,
       simulateAnimation,
       toggleElementPicker,
     } = this.props;
 
     return dom.div(
       {
         id: "animation-container",
         className: detailVisibility ? "animation-detail-visible" : "",
       },
       animations.length ?
       SplitBox({
         className: "animation-container-splitter",
         endPanel: AnimationDetailContainer(
           {
             getAnimatedPropertyMap,
+            setDetailVisibility,
           }
         ),
         endPanelControl: true,
         initialHeight: "50%",
         splitterSize: 1,
         startPanel: AnimationListContainer(
           {
             animations,
--- a/devtools/client/inspector/animation/reducers/animations.js
+++ b/devtools/client/inspector/animation/reducers/animations.js
@@ -1,16 +1,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 const {
   UPDATE_ANIMATIONS,
+  UPDATE_DETAIL_VISIBILITY,
   UPDATE_ELEMENT_PICKER_ENABLED,
   UPDATE_SELECTED_ANIMATION,
   UPDATE_SIDEBAR_SIZE,
 } = require("../actions/index");
 
 const INITIAL_STATE = {
   animations: [],
   detailVisibility: false,
@@ -24,16 +25,22 @@ const INITIAL_STATE = {
 
 const reducers = {
   [UPDATE_ANIMATIONS](state, { animations }) {
     return Object.assign({}, state, {
       animations,
     });
   },
 
+  [UPDATE_DETAIL_VISIBILITY](state, { detailVisibility }) {
+    return Object.assign({}, state, {
+      detailVisibility
+    });
+  },
+
   [UPDATE_ELEMENT_PICKER_ENABLED](state, { elementPickerEnabled }) {
     return Object.assign({}, state, {
       elementPickerEnabled
     });
   },
 
   [UPDATE_SELECTED_ANIMATION](state, { selectedAnimation }) {
     const detailVisibility = !!selectedAnimation;
--- a/devtools/client/themes/animation.css
+++ b/devtools/client/themes/animation.css
@@ -235,19 +235,28 @@
   display: flex;
   flex-direction: column;
   height: 100%;
   overflow: hidden;
   width: 100%;
 }
 
 .animation-detail-header {
+  display: flex;
+}
+
+.animation-detail-title {
+  flex: 1;
   white-space: nowrap;
 }
 
+.animation-detail-close-button::before {
+  background-image: url(chrome://devtools/skin/images/close.svg);
+}
+
 /* Animated Property List Container */
 .animated-property-list-container {
   display: flex;
   flex: 1;
   flex-direction: column;
   overflow-y: auto;
 }