Bug 1359681 - Tap timeline column to open the timing sidebar panel. r=gasolin
authorgabriellesc <gabriellesinghcadieux@gmail.com>
Wed, 07 Jun 2017 11:29:45 -0400
changeset 411362 24ef2aa69cf3366dc9efec033cba4bf61b6322f6
parent 411321 7457b240847db66b78493ed3a6d03663173bd745
child 411363 2ae4d9b0f74c0e0d3bdc8d3e5e70706db713d52a
push id7391
push usermtabara@mozilla.com
push dateMon, 12 Jun 2017 13:08:53 +0000
treeherdermozilla-beta@2191d7f87e2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgasolin
bugs1359681
milestone55.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 1359681 - Tap timeline column to open the timing sidebar panel. r=gasolin
devtools/client/netmonitor/src/components/request-list-column-waterfall.js
devtools/client/netmonitor/src/components/request-list-content.js
devtools/client/netmonitor/src/components/request-list-item.js
devtools/client/netmonitor/test/browser.ini
devtools/client/netmonitor/test/browser_net_waterfall-click.js
--- a/devtools/client/netmonitor/src/components/request-list-column-waterfall.js
+++ b/devtools/client/netmonitor/src/components/request-list-column-waterfall.js
@@ -24,34 +24,36 @@ const UPDATED_WATERFALL_PROPS = [
 const TIMING_KEYS = ["blocked", "dns", "connect", "send", "wait", "receive"];
 
 const RequestListColumnWaterfall = createClass({
   displayName: "RequestListColumnWaterfall",
 
   propTypes: {
     firstRequestStartedMillis: PropTypes.number.isRequired,
     item: PropTypes.object.isRequired,
+    onWaterfallMouseDown: PropTypes.func.isRequired,
   },
 
   shouldComponentUpdate(nextProps) {
     return !propertiesEqual(UPDATED_WATERFALL_PROPS, this.props.item, nextProps.item) ||
       this.props.firstRequestStartedMillis !== nextProps.firstRequestStartedMillis;
   },
 
   render() {
-    let { firstRequestStartedMillis, item } = this.props;
+    let { firstRequestStartedMillis, item, onWaterfallMouseDown } = this.props;
     const { boxes, tooltip } = timingBoxes(item);
 
     return (
       div({ className: "requests-list-column requests-list-waterfall", title: tooltip },
         div({
           className: "requests-list-timings",
           style: {
             paddingInlineStart: `${item.startedMillis - firstRequestStartedMillis}px`,
           },
+          onMouseDown: onWaterfallMouseDown,
         },
           boxes,
         )
       )
     );
   }
 });
 
--- a/devtools/client/netmonitor/src/components/request-list-content.js
+++ b/devtools/client/netmonitor/src/components/request-list-content.js
@@ -40,16 +40,17 @@ const RequestListContent = createClass({
     displayedRequests: PropTypes.object.isRequired,
     firstRequestStartedMillis: PropTypes.number.isRequired,
     fromCache: PropTypes.bool,
     onCauseBadgeMouseDown: PropTypes.func.isRequired,
     onItemMouseDown: PropTypes.func.isRequired,
     onSecurityIconMouseDown: PropTypes.func.isRequired,
     onSelectDelta: PropTypes.func.isRequired,
     onThumbnailMouseDown: PropTypes.func.isRequired,
+    onWaterfallMouseDown: PropTypes.func.isRequired,
     scale: PropTypes.number,
     selectedRequestId: PropTypes.string,
   },
 
   componentWillMount() {
     const { dispatch } = this.props;
     this.contextMenu = new RequestListContextMenu({
       cloneSelectedRequest: () => dispatch(Actions.cloneSelectedRequest()),
@@ -224,16 +225,17 @@ const RequestListContent = createClass({
     const {
       columns,
       displayedRequests,
       firstRequestStartedMillis,
       onCauseBadgeMouseDown,
       onItemMouseDown,
       onSecurityIconMouseDown,
       onThumbnailMouseDown,
+      onWaterfallMouseDown,
       selectedRequestId,
     } = this.props;
 
     return (
       div({ className: "requests-list-wrapper"},
         div({ className: "requests-list-table"},
           div({
             ref: "contentEl",
@@ -250,16 +252,17 @@ const RequestListContent = createClass({
               isSelected: item.id === selectedRequestId,
               key: item.id,
               onContextMenu: this.onContextMenu,
               onFocusedNodeChange: this.onFocusedNodeChange,
               onMouseDown: () => onItemMouseDown(item.id),
               onCauseBadgeMouseDown: () => onCauseBadgeMouseDown(item.cause),
               onSecurityIconMouseDown: () => onSecurityIconMouseDown(item.securityState),
               onThumbnailMouseDown: () => onThumbnailMouseDown(),
+              onWaterfallMouseDown: () => onWaterfallMouseDown(),
             }))
           )
         )
       )
     );
   },
 });
 
@@ -294,10 +297,16 @@ module.exports = connect(
     onSelectDelta: (delta) => dispatch(Actions.selectDelta(delta)),
     /**
      * A handler that opens the response tab in the details view if
      * the thumbnail is clicked.
      */
     onThumbnailMouseDown: () => {
       dispatch(Actions.selectDetailsPanelTab("response"));
     },
+    /**
+     * A handler that opens the timing sidebar panel if the waterfall is clicked.
+     */
+    onWaterfallMouseDown: () => {
+      dispatch(Actions.selectDetailsPanelTab("timings"));
+    },
   }),
 )(RequestListContent);
--- a/devtools/client/netmonitor/src/components/request-list-item.js
+++ b/devtools/client/netmonitor/src/components/request-list-item.js
@@ -82,16 +82,17 @@ const RequestListItem = createClass({
     firstRequestStartedMillis: PropTypes.number.isRequired,
     fromCache: PropTypes.bool,
     onCauseBadgeMouseDown: PropTypes.func.isRequired,
     onContextMenu: PropTypes.func.isRequired,
     onFocusedNodeChange: PropTypes.func,
     onMouseDown: PropTypes.func.isRequired,
     onSecurityIconMouseDown: PropTypes.func.isRequired,
     onThumbnailMouseDown: PropTypes.func.isRequired,
+    onWaterfallMouseDown: PropTypes.func.isRequired,
     waterfallWidth: PropTypes.number,
   },
 
   componentDidMount() {
     if (this.props.isSelected) {
       this.refs.listItem.focus();
     }
   },
@@ -119,16 +120,17 @@ const RequestListItem = createClass({
       isSelected,
       firstRequestStartedMillis,
       fromCache,
       onContextMenu,
       onMouseDown,
       onCauseBadgeMouseDown,
       onSecurityIconMouseDown,
       onThumbnailMouseDown,
+      onWaterfallMouseDown,
     } = this.props;
 
     let classList = ["request-list-item", index % 2 ? "odd" : "even"];
     isSelected && classList.push("selected");
     fromCache && classList.push("fromCache");
 
     return (
       div({
@@ -157,15 +159,16 @@ const RequestListItem = createClass({
           RequestListColumnStartTime({ item, firstRequestStartedMillis }),
         columns.get("endTime") &&
           RequestListColumnEndTime({ item, firstRequestStartedMillis }),
         columns.get("responseTime") &&
           RequestListColumnResponseTime({ item, firstRequestStartedMillis }),
         columns.get("duration") && RequestListColumnDuration({ item }),
         columns.get("latency") && RequestListColumnLatency({ item }),
         columns.get("waterfall") &&
-          RequestListColumnWaterfall({ item, firstRequestStartedMillis }),
+          RequestListColumnWaterfall({ item, firstRequestStartedMillis,
+                                       onWaterfallMouseDown }),
       )
     );
   }
 });
 
 module.exports = RequestListItem;
--- a/devtools/client/netmonitor/test/browser.ini
+++ b/devtools/client/netmonitor/test/browser.ini
@@ -123,16 +123,17 @@ skip-if = (os == 'linux' && debug && bit
 [browser_net_json_custom_mime.js]
 [browser_net_json_text_mime.js]
 [browser_net_jsonp.js]
 [browser_net_large-response.js]
 [browser_net_leak_on_tab_close.js]
 [browser_net_open_request_in_tab.js]
 [browser_net_pane-collapse.js]
 [browser_net_pane-toggle.js]
+[browser_net_persistent_logs.js]
 [browser_net_post-data-01.js]
 [browser_net_post-data-02.js]
 [browser_net_post-data-03.js]
 [browser_net_post-data-04.js]
 [browser_net_prefs-and-l10n.js]
 [browser_net_prefs-reload.js]
 [browser_net_raw_headers.js]
 [browser_net_reload-button.js]
@@ -162,9 +163,9 @@ skip-if = true # Bug 1258809
 [browser_net_status-codes.js]
 [browser_net_streaming-response.js]
 [browser_net_throttle.js]
 [browser_net_thumbnail-click.js]
 [browser_net_timeline_ticks.js]
 skip-if = true # TODO: fix the test
 [browser_net_timing-division.js]
 [browser_net_truncate.js]
-[browser_net_persistent_logs.js]
+[browser_net_waterfall-click.js]
new file mode 100644
--- /dev/null
+++ b/devtools/client/netmonitor/test/browser_net_waterfall-click.js
@@ -0,0 +1,36 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+/**
+ * Test that clicking on the waterfall opens the timing sidebar panel.
+ */
+
+add_task(function* () {
+  let { tab, monitor } = yield initNetMonitor(CONTENT_TYPE_WITHOUT_CACHE_URL);
+  let { document } = monitor.panelWin;
+
+  yield performRequestsAndWait();
+
+  let wait = waitForDOM(document, "#timings-panel");
+  let timing = document.querySelectorAll(".requests-list-timings")[0];
+
+  info("Clicking waterfall and waiting for panel update.");
+  EventUtils.synthesizeMouseAtCenter(timing, {}, monitor.panelWin);
+
+  yield wait;
+
+  ok(document.querySelector("#timings-tab[aria-selected=true]"),
+     "Timings tab is selected.");
+
+  return teardown(monitor);
+
+  function* performRequestsAndWait() {
+    let onAllEvents = waitForNetworkEvents(monitor, CONTENT_TYPE_WITHOUT_CACHE_REQUESTS);
+    yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
+      content.wrappedJSObject.performRequests();
+    });
+    yield onAllEvents;
+  }
+});