Bug 1359681 - Tap timeline column to open the timing sidebar panel
MozReview-Commit-ID: C4j6XtcZBs7
--- 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;
+ }
+});