Bug 1217946 - Fix all validation failures and deprecated components. r=fitzgen
authorJordan Santell <jsantell@mozilla.com>
Wed, 28 Oct 2015 08:34:47 -0700
changeset 305213 64767e3b5082f02e355ca382041bc240a533cf51
parent 305212 197f18c10455a431ab2d8e189b074115a5457f5a
child 305214 601528a16cf9a0b2d7d82dd9f163ff556b56f100
push id1001
push userraliiev@mozilla.com
push dateMon, 18 Jan 2016 19:06:03 +0000
treeherdermozilla-release@8b89261f3ac4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfitzgen
bugs1217946
milestone44.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 1217946 - Fix all validation failures and deprecated components. r=fitzgen
devtools/client/memory/app.js
devtools/client/memory/components/heap.js
devtools/client/memory/components/list.js
devtools/client/memory/components/toolbar.js
devtools/client/memory/components/tree.js
devtools/client/memory/models.js
devtools/client/themes/memory.css
--- a/devtools/client/memory/app.js
+++ b/devtools/client/memory/app.js
@@ -1,30 +1,38 @@
 /* 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/. */
 
 const { DOM: dom, createClass, createFactory, PropTypes } = require("devtools/client/shared/vendor/react");
 const { connect } = require("devtools/client/shared/vendor/react-redux");
+const { breakdowns } = require("./constants");
 const { toggleRecordingAllocationStacks } = require("./actions/allocations");
 const { setBreakdownAndRefresh } = require("./actions/breakdown");
 const { toggleInvertedAndRefresh } = require("./actions/inverted");
 const { selectSnapshotAndRefresh, takeSnapshotAndCensus } = require("./actions/snapshot");
 const { breakdownNameToSpec, getBreakdownDisplayData } = require("./utils");
 const Toolbar = createFactory(require("./components/toolbar"));
 const List = createFactory(require("./components/list"));
 const SnapshotListItem = createFactory(require("./components/snapshot-list-item"));
 const HeapView = createFactory(require("./components/heap"));
 const { app: appModel } = require("./models");
 
 const App = createClass({
   displayName: "memory-tool",
 
   propTypes: appModel,
 
+  getDefaultProps() {
+    return {
+      breakdown: breakdowns.coarseType.breakdown,
+      inverted: false,
+    };
+  },
+
   childContextTypes: {
     front: PropTypes.any,
     heapWorker: PropTypes.any,
   },
 
   getChildContext() {
     return {
       front: this.props.front,
@@ -41,44 +49,44 @@ const App = createClass({
       breakdown,
       allocations,
       inverted
     } = this.props;
 
     let selectedSnapshot = snapshots.find(s => s.selected);
 
     return (
-      dom.div({ id: "memory-tool" }, [
+      dom.div({ id: "memory-tool" },
 
         Toolbar({
           breakdowns: getBreakdownDisplayData(),
           onTakeSnapshotClick: () => dispatch(takeSnapshotAndCensus(front, heapWorker)),
           onBreakdownChange: breakdown =>
             dispatch(setBreakdownAndRefresh(heapWorker, breakdownNameToSpec(breakdown))),
           onToggleRecordAllocationStacks: () =>
             dispatch(toggleRecordingAllocationStacks(front)),
           allocations,
           inverted,
           onToggleInverted: () =>
             dispatch(toggleInvertedAndRefresh(heapWorker))
         }),
 
-        dom.div({ id: "memory-tool-container" }, [
+        dom.div({ id: "memory-tool-container" },
           List({
             itemComponent: SnapshotListItem,
             items: snapshots,
             onClick: snapshot => dispatch(selectSnapshotAndRefresh(heapWorker, snapshot))
           }),
 
           HeapView({
             snapshot: selectedSnapshot,
             onSnapshotClick: () => dispatch(takeSnapshotAndCensus(front, heapWorker)),
-          }),
-        ])
-      ])
+          })
+        )
+      )
     );
   },
 });
 
 /**
  * Passed into react-redux's `connect` method that is called on store change
  * and passed to components.
  */
--- a/devtools/client/memory/components/heap.js
+++ b/devtools/client/memory/components/heap.js
@@ -71,50 +71,50 @@ const Heap = module.exports = createClas
     let { snapshot, onSnapshotClick } = this.props;
     let census = snapshot ? snapshot.census : null;
     let state = snapshot ? snapshot.state : "initial";
     let statusText = snapshot ? getSnapshotStatusTextFull(snapshot) : "";
     let content;
 
     switch (state) {
       case "initial":
-        content = dom.button({
+        content = [dom.button({
           className: "devtools-toolbarbutton take-snapshot",
           onClick: onSnapshotClick,
           // Want to use the [standalone] tag to leverage our styles,
           // but React hates that evidently
           "data-standalone": true,
           "data-text-only": true,
-        }, TAKE_SNAPSHOT_TEXT)
+        }, TAKE_SNAPSHOT_TEXT)];
         break;
       case states.ERROR:
         content = [
           dom.span({ className: "snapshot-status error" }, statusText),
           dom.pre({}, safeErrorString(snapshot.error || new Error("blahblah"))),
         ];
         break;
       case states.SAVING:
       case states.SAVED:
       case states.READING:
       case states.READ:
       case states.SAVING_CENSUS:
-        content = dom.span({ className: "snapshot-status devtools-throbber" }, statusText)
+        content = [dom.span({ className: "snapshot-status devtools-throbber" }, statusText)];
         break;
       case states.SAVED_CENSUS:
         content = [
           dom.div({ className: "header" },
             dom.span({ className: "heap-tree-item-bytes" }, "Bytes"),
             dom.span({ className: "heap-tree-item-count" }, "Count"),
             dom.span({ className: "heap-tree-item-total-bytes" }, "Total Bytes"),
             dom.span({ className: "heap-tree-item-total-count" }, "Total Count"),
             dom.span({ className: "heap-tree-item-name" }, "Name")
           ),
           Tree(createTreeProperties(snapshot.census))
         ];
         break;
     }
-    let pane = dom.div({ className: "heap-view-panel", "data-state": state }, content);
+    let pane = dom.div({ className: "heap-view-panel", "data-state": state }, ...content);
 
     return (
       dom.div({ id: "heap-view", "data-state": state }, pane)
     )
   }
 });
--- a/devtools/client/memory/components/list.js
+++ b/devtools/client/memory/components/list.js
@@ -17,16 +17,16 @@ const List = module.exports = createClas
     onClick: PropTypes.func,
     items: PropTypes.array.isRequired,
   },
 
   render() {
     let { items, onClick, itemComponent: Item } = this.props;
 
     return (
-      dom.ul({ className: "list" }, items.map((item, index) => {
+      dom.ul({ className: "list" }, ...items.map((item, index) => {
         return Item({
-          item, index, onClick: () => onClick(item),
+          key: index, item, index, onClick: () => onClick(item),
         });
       }))
     );
   }
 });
--- a/devtools/client/memory/components/toolbar.js
+++ b/devtools/client/memory/components/toolbar.js
@@ -1,13 +1,13 @@
 /* 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/. */
 
-const { DOM, createClass, PropTypes } = require("devtools/client/shared/vendor/react");
+const { DOM: dom, createClass, PropTypes } = require("devtools/client/shared/vendor/react");
 
 const models = require("../models");
 
 const Toolbar = module.exports = createClass({
   displayName: "toolbar",
   propTypes: {
     breakdowns: PropTypes.arrayOf(PropTypes.shape({
       name: PropTypes.string.isRequired,
@@ -28,43 +28,43 @@ const Toolbar = module.exports = createC
       breakdowns,
       onToggleRecordAllocationStacks,
       allocations,
       onToggleInverted,
       inverted
     } = this.props;
 
     return (
-      DOM.div({ className: "devtools-toolbar" }, [
-        DOM.button({ className: `take-snapshot devtools-button`, onClick: onTakeSnapshotClick }),
+      dom.div({ className: "devtools-toolbar" },
+        dom.button({ className: `take-snapshot devtools-button`, onClick: onTakeSnapshotClick }),
 
-        DOM.label({},
+        dom.label({},
           "Breakdown by ",
-          DOM.select({
+          dom.select({
             className: `select-breakdown`,
             onChange: e => onBreakdownChange(e.target.value),
-          }, breakdowns.map(({ name, displayName }) => DOM.option({ value: name }, displayName)))
+          }, ...breakdowns.map(({ name, displayName }) => dom.option({ key: name, value: name }, displayName)))
         ),
 
-        DOM.label({}, [
-          DOM.input({
+        dom.label({},
+          dom.input({
             type: "checkbox",
             checked: inverted,
             onChange: onToggleInverted,
           }),
           // TODO bug 1214799
           "Invert tree"
-        ]),
+        ),
 
-        DOM.label({}, [
-          DOM.input({
+        dom.label({},
+          dom.input({
             type: "checkbox",
             checked: allocations.recording,
             disabled: allocations.togglingInProgress,
             onChange: onToggleRecordAllocationStacks,
           }),
           // TODO bug 1214799
           "Record allocation stacks"
-        ])
-])
+        )
+      )
     );
   }
 });
--- a/devtools/client/memory/components/tree.js
+++ b/devtools/client/memory/components/tree.js
@@ -40,17 +40,17 @@ const ArrowExpander = createFactory(crea
 
     return dom.div(attrs);
   }
 }));
 
 const TreeNode = createFactory(createClass({
   componentDidUpdate() {
     if (this.props.focused) {
-      this.refs.button.getDOMNode().focus();
+      this.refs.button.focus();
     }
   },
 
   render() {
     const arrow = ArrowExpander({
       item: this.props.item,
       expanded: this.props.expanded,
       visible: this.props.hasChildren,
@@ -239,17 +239,17 @@ const Tree = module.exports = createClas
     );
   },
 
   /**
    * Updates the state's height based on clientHeight.
    */
   _updateHeight() {
     this.setState({
-      height: this.refs.tree.getDOMNode().clientHeight
+      height: this.refs.tree.clientHeight
     });
   },
 
   /**
    * Perform a pre-order depth-first search from item.
    */
   _dfs(item, maxDepth = Infinity, traversal = [], _depth = 0) {
     if (!this.props.filter(item)) {
@@ -356,18 +356,18 @@ const Tree = module.exports = createClas
   /**
    * Fired on a scroll within the tree's container, updates
    * the stored position of the view port to handle virtual view rendering.
    *
    * @param {Event} e
    */
   _onScroll(e) {
     this.setState({
-      scroll: Math.max(this.refs.tree.getDOMNode().scrollTop, 0),
-      height: this.refs.tree.getDOMNode().clientHeight
+      scroll: Math.max(this.refs.tree.scrollTop, 0),
+      height: this.refs.tree.clientHeight
     });
   },
 
   /**
    * Handles key down events in the tree's container.
    *
    * @param {Event} e
    */
--- a/devtools/client/memory/models.js
+++ b/devtools/client/memory/models.js
@@ -14,16 +14,17 @@ const { snapshotState: states } = requir
  */
 let breakdownModel = exports.breakdown = PropTypes.shape({
   by: PropTypes.oneOf(["coarseType", "allocationStack", "objectClass", "internalType"]).isRequired,
 });
 
 /**
  * Snapshot model.
  */
+let stateKeys = Object.keys(states).map(state => states[state]);
 let snapshotModel = exports.snapshot = PropTypes.shape({
   // Unique ID for a snapshot
   id: PropTypes.number.isRequired,
   // Whether or not this snapshot is currently selected.
   selected: PropTypes.bool.isRequired,
   // fs path to where the snapshot is stored; used to
   // identify the snapshot for HeapAnalysesClient.
   path: PropTypes.string,
@@ -32,29 +33,28 @@ let snapshotModel = exports.snapshot = P
   // The breakdown used to generate the current census
   breakdown: breakdownModel,
   // Whether the currently cached census tree is inverted or not.
   inverted: PropTypes.bool,
   // If an error was thrown while processing this snapshot, the `Error` instance is attached here.
   error: PropTypes.object,
   // State the snapshot is in
   // @see ./constants.js
-  state: function (props, propName) {
-    let stateNames = Object.keys(states);
-    let current = props.state;
+  state: function (snapshot, propName) {
+    let current = snapshot.state;
     let shouldHavePath = [states.SAVED, states.READ, states.SAVING_CENSUS, states.SAVED_CENSUS];
     let shouldHaveCensus = [states.SAVED_CENSUS];
 
-    if (!stateNames.includes(current)) {
-      throw new Error(`Snapshot state must be one of ${stateNames}.`);
+    if (!stateKeys.includes(current)) {
+      throw new Error(`Snapshot state must be one of ${stateKeys}.`);
     }
-    if (shouldHavePath.includes(current) && !path) {
+    if (shouldHavePath.includes(current) && !snapshot.path) {
       throw new Error(`Snapshots in state ${current} must have a snapshot path.`);
     }
-    if (shouldHaveCensus.includes(current) && (!props.census || !props.breakdown)) {
+    if (shouldHaveCensus.includes(current) && (!snapshot.census || !snapshot.breakdown)) {
       throw new Error(`Snapshots in state ${current} must have a census and breakdown.`);
     }
   },
 });
 
 let allocationsModel = exports.allocations = PropTypes.shape({
   // True iff we are recording allocation stacks right now.
   recording: PropTypes.bool.isRequired,
--- a/devtools/client/themes/memory.css
+++ b/devtools/client/themes/memory.css
@@ -117,17 +117,16 @@ html, .theme-body, #app, #memory-tool, #
 }
 
 .list > li {
   height: 40px;
   color: var(--theme-body-color);
   border-bottom: 1px solid rgba(128,128,128,0.15);
   padding: 8px;
   cursor: pointer;
-  color: var(--theme-selection-color);
 }
 
 .list > li.selected {
   background-color: var(--theme-selection-background);
   color: var(--theme-selection-color);
 }
 
 .snapshot-list-item span {