Bug 1359681 - Tap timeline column to open the timing sidebar panel draft
authorgasolin <gasolin@gmail.com>
Tue, 06 Jun 2017 11:20:14 +0800
changeset 589344 6e8a9ba76e91d9fdb077c7461938f8a9d0f812f4
parent 589301 2c6289f56812c30254acfdddabcfec1e149c0336
child 631847 115c34b09cac778c5a643545ff0855380f7f1072
push id62338
push userbmo:gasolin@mozilla.com
push dateTue, 06 Jun 2017 03:20:29 +0000
bugs1359681
milestone55.0a1
Bug 1359681 - Tap timeline column to open the timing sidebar panel MozReview-Commit-ID: C4j6XtcZBs7
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,15 @@ 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;
+  }
+});