--- a/devtools/client/netmonitor/src/components/MonitorPanel.js
+++ b/devtools/client/netmonitor/src/components/MonitorPanel.js
@@ -22,17 +22,18 @@ const {
const SplitBox = createFactory(require("devtools/client/shared/components/splitter/SplitBox"));
const RequestList = createFactory(require("./RequestList"));
const Toolbar = createFactory(require("./Toolbar"));
loader.lazyGetter(this, "NetworkDetailsPanel", function () {
return createFactory(require("./NetworkDetailsPanel"));
});
-const MediaQueryList = window.matchMedia("(min-width: 700px)");
+const MediaQueryVert = window.matchMedia("(min-width: 700px)");
+const MediaQuerySingleRow = window.matchMedia("(min-width: 920px)");
/**
* Monitor panel component
* The main panel for displaying various network request information
*/
class MonitorPanel extends Component {
static get propTypes() {
return {
@@ -47,55 +48,59 @@ class MonitorPanel extends Component {
updateRequest: PropTypes.func.isRequired,
};
}
constructor(props) {
super(props);
this.state = {
- isVerticalSpliter: MediaQueryList.matches,
+ isSingleRow: MediaQuerySingleRow.matches,
+ isVerticalSpliter: MediaQueryVert.matches,
};
this.onLayoutChange = this.onLayoutChange.bind(this);
}
componentDidMount() {
- MediaQueryList.addListener(this.onLayoutChange);
+ MediaQuerySingleRow.addListener(this.onLayoutChange);
+ MediaQueryVert.addListener(this.onLayoutChange);
}
componentWillReceiveProps(nextProps) {
updateFormDataSections(nextProps);
}
componentDidUpdate() {
let { selectedRequestVisible, openNetworkDetails } = this.props;
if (!selectedRequestVisible) {
openNetworkDetails(false);
}
}
componentWillUnmount() {
- MediaQueryList.removeListener(this.onLayoutChange);
+ MediaQuerySingleRow.removeListener(this.onLayoutChange);
+ MediaQueryVert.removeListener(this.onLayoutChange);
let { clientWidth, clientHeight } = findDOMNode(this.refs.endPanel) || {};
if (this.state.isVerticalSpliter && clientWidth) {
Services.prefs.setIntPref(
"devtools.netmonitor.panes-network-details-width", clientWidth);
}
if (!this.state.isVerticalSpliter && clientHeight) {
Services.prefs.setIntPref(
"devtools.netmonitor.panes-network-details-height", clientHeight);
}
}
onLayoutChange() {
this.setState({
- isVerticalSpliter: MediaQueryList.matches,
+ isSingleRow: MediaQuerySingleRow.matches,
+ isVerticalSpliter: MediaQueryVert.matches,
});
}
render() {
let {
connector,
isEmpty,
networkDetailsOpen,
@@ -105,17 +110,20 @@ class MonitorPanel extends Component {
let initialWidth = Services.prefs.getIntPref(
"devtools.netmonitor.panes-network-details-width");
let initialHeight = Services.prefs.getIntPref(
"devtools.netmonitor.panes-network-details-height");
return (
div({ className: "monitor-panel" },
- Toolbar({ connector }),
+ Toolbar({
+ connector,
+ singleRow: this.state.isSingleRow,
+ }),
SplitBox({
className: "devtools-responsive-container",
initialWidth: `${initialWidth}px`,
initialHeight: `${initialHeight}px`,
minSize: "50px",
maxSize: "80%",
splitterSize: 1,
startPanel: RequestList({ isEmpty, connector }),
--- a/devtools/client/netmonitor/src/components/Toolbar.js
+++ b/devtools/client/netmonitor/src/components/Toolbar.js
@@ -68,16 +68,17 @@ class Toolbar extends Component {
enablePersistentLogs: PropTypes.func.isRequired,
togglePersistentLogs: PropTypes.func.isRequired,
persistentLogsEnabled: PropTypes.bool.isRequired,
disableBrowserCache: PropTypes.func.isRequired,
toggleBrowserCache: PropTypes.func.isRequired,
browserCacheDisabled: PropTypes.bool.isRequired,
toggleRequestFilterType: PropTypes.func.isRequired,
filteredRequests: PropTypes.array.isRequired,
+ singleRow: PropTypes.bool.isRequired,
};
}
constructor(props) {
super(props);
this.autocompleteProvider = this.autocompleteProvider.bind(this);
this.onSearchBoxFocus = this.onSearchBoxFocus.bind(this);
this.toggleRequestFilterType = this.toggleRequestFilterType.bind(this);
@@ -93,16 +94,17 @@ class Toolbar extends Component {
}
shouldComponentUpdate(nextProps) {
return this.props.networkDetailsOpen !== nextProps.networkDetailsOpen
|| this.props.networkDetailsToggleDisabled !== nextProps.networkDetailsToggleDisabled
|| this.props.persistentLogsEnabled !== nextProps.persistentLogsEnabled
|| this.props.browserCacheDisabled !== nextProps.browserCacheDisabled
|| this.props.recording !== nextProps.recording
+ || this.props.singleRow !== nextProps.singleRow
|| !I.is(this.props.requestFilterTypes, nextProps.requestFilterTypes)
// Filtered requests are useful only when searchbox is focused
|| !!(this.refs.searchbox && this.refs.searchbox.focused);
}
componentWillUnmount() {
Services.prefs.removeObserver(DEVTOOLS_ENABLE_PERSISTENT_LOG_PREF,
@@ -139,32 +141,90 @@ class Toolbar extends Component {
filteredRequests.forEach((request) => {
fetchNetworkUpdatePacket(connector.requestData, request, [
"responseCookies",
"responseHeaders",
]);
});
}
- render() {
- let {
- toggleRecording,
- clearRequests,
- requestFilterTypes,
- setRequestFilterText,
- networkDetailsToggleDisabled,
- networkDetailsOpen,
- toggleNetworkDetails,
- togglePersistentLogs,
- persistentLogsEnabled,
- toggleBrowserCache,
- browserCacheDisabled,
- recording,
- } = this.props;
+ /**
+ * Render a separator.
+ */
+ renderSeparator() {
+ return span({ className: "devtools-separator" });
+ }
+
+ /**
+ * Render a clear button.
+ */
+ renderClearButton(clearRequests) {
+ return (
+ button({
+ className: "devtools-button devtools-clear-icon requests-list-clear-button",
+ title: TOOLBAR_CLEAR,
+ onClick: clearRequests,
+ })
+ );
+ }
+
+ /**
+ * Render a Detail button.
+ */
+ renderDetailButton(networkDetailsOpen, networkDetailsToggleDisabled,
+ toggleNetworkDetails) {
+ // Detail toggle button
+ let toggleDetailButtonClassList = [
+ "network-details-panel-toggle",
+ "devtools-button",
+ ];
+ if (!networkDetailsOpen) {
+ toggleDetailButtonClassList.push("pane-collapsed");
+ }
+ let toggleDetailButtonClass = toggleDetailButtonClassList.join(" ");
+ let toggleDetailButtonTitle = networkDetailsOpen ? COLLAPSE_DETAILS_PANE :
+ EXPAND_DETAILS_PANE;
+
+ return (
+ button({
+ className: toggleDetailButtonClass,
+ title: toggleDetailButtonTitle,
+ disabled: networkDetailsToggleDisabled,
+ tabIndex: "0",
+ onClick: toggleNetworkDetails,
+ })
+ );
+ }
+
+ /**
+ * Render a ToggleRecording button.
+ */
+ renderToggleRecordingButton(recording, toggleRecording) {
+ // Calcula[te class-list for toggle recording button.
+ // The button has two states: pause/play.
+ let toggleRecordingButtonClass = [
+ "devtools-button",
+ "requests-list-pause-button",
+ recording ? "devtools-pause-icon" : "devtools-play-icon",
+ ].join(" ");
+
+ return (
+ button({
+ className: toggleRecordingButtonClass,
+ title: TOOLBAR_TOGGLE_RECORDING,
+ onClick: toggleRecording,
+ })
+ );
+ }
+
+ /**
+ * Render filter buttons.
+ */
+ renderFilterButtons(requestFilterTypes) {
// Render list of filter-buttons.
let buttons = Object.entries(requestFilterTypes).map(([type, checked]) => {
let classList = ["devtools-button", `requests-list-filter-${type}-button`];
checked && classList.push("checked");
return (
button({
className: classList.join(" "),
@@ -174,99 +234,140 @@ class Toolbar extends Component {
"aria-pressed": checked,
"data-key": type,
},
TOOLBAR_FILTER_LABELS[type]
)
);
});
- // Calculate class-list for toggle recording button. The button
- // has two states: pause/play.
- let toggleRecordingButtonClass = [
- "devtools-button",
- "requests-list-pause-button",
- recording ? "devtools-pause-icon" : "devtools-play-icon",
- ].join(" ");
+ return div({ className: "requests-list-filter-buttons" }, buttons);
+ }
+
+ /**
+ * Render a Persistlog checkbox.
+ */
+ renderPersistlogCheckbox(persistentLogsEnabled, togglePersistentLogs) {
+ return (
+ label(
+ {
+ className: "devtools-checkbox-label",
+ title: ENABLE_PERSISTENT_LOGS_TOOLTIP,
+ },
+ input({
+ id: "devtools-persistlog-checkbox",
+ className: "devtools-checkbox",
+ type: "checkbox",
+ checked: persistentLogsEnabled,
+ onChange: togglePersistentLogs,
+ }),
+ ENABLE_PERSISTENT_LOGS_LABEL,
+ )
+ );
+ }
- // Detail toggle button
- let toggleDetailButtonClassList = [
- "network-details-panel-toggle",
- "devtools-button",
- ];
+ /**
+ * Render a Cache checkbox.
+ */
+ renderCacheCheckbox(browserCacheDisabled, toggleBrowserCache) {
+ return (
+ label(
+ {
+ className: "devtools-checkbox-label",
+ title: DISABLE_CACHE_TOOLTIP,
+ },
+ input({
+ id: "devtools-cache-checkbox",
+ className: "devtools-checkbox",
+ type: "checkbox",
+ checked: browserCacheDisabled,
+ onChange: toggleBrowserCache,
+ }),
+ DISABLE_CACHE_LABEL,
+ )
+ );
+ }
- if (!networkDetailsOpen) {
- toggleDetailButtonClassList.push("pane-collapsed");
- }
- let toggleDetailButtonClass = toggleDetailButtonClassList.join(" ");
- let toggleDetailButtonTitle = networkDetailsOpen ? COLLAPSE_DETAILS_PANE :
- EXPAND_DETAILS_PANE;
+ /**
+ * Render filter Searchbox.
+ */
+ renderFilterBox(setRequestFilterText) {
+ return (
+ SearchBox({
+ delay: FILTER_SEARCH_DELAY,
+ keyShortcut: SEARCH_KEY_SHORTCUT,
+ placeholder: SEARCH_PLACE_HOLDER,
+ plainStyle: true,
+ type: "filter",
+ ref: "searchbox",
+ onChange: setRequestFilterText,
+ onFocus: this.onSearchBoxFocus,
+ autocompleteProvider: this.autocompleteProvider,
+ })
+ );
+ }
+
+ render() {
+ let {
+ toggleRecording,
+ clearRequests,
+ requestFilterTypes,
+ setRequestFilterText,
+ networkDetailsToggleDisabled,
+ networkDetailsOpen,
+ toggleNetworkDetails,
+ togglePersistentLogs,
+ persistentLogsEnabled,
+ toggleBrowserCache,
+ browserCacheDisabled,
+ recording,
+ singleRow,
+ } = this.props;
// Render the entire toolbar.
- return (
+ // dock at bottom or dock at side has different layout
+ return singleRow ? (
span({ className: "devtools-toolbar devtools-toolbar-container" },
- span({ className: "devtools-toolbar-group" },
- button({
- className: toggleRecordingButtonClass,
- title: TOOLBAR_TOGGLE_RECORDING,
- onClick: toggleRecording,
- }),
- button({
- className: "devtools-button devtools-clear-icon requests-list-clear-button",
- title: TOOLBAR_CLEAR,
- onClick: clearRequests,
- }),
- div({ className: "requests-list-filter-buttons" }, buttons),
- label(
- {
- className: "devtools-checkbox-label",
- title: ENABLE_PERSISTENT_LOGS_TOOLTIP,
- },
- input({
- id: "devtools-persistlog-checkbox",
- className: "devtools-checkbox",
- type: "checkbox",
- checked: persistentLogsEnabled,
- onChange: togglePersistentLogs,
- }),
- ENABLE_PERSISTENT_LOGS_LABEL
- ),
- label(
- {
- className: "devtools-checkbox-label",
- title: DISABLE_CACHE_TOOLTIP,
- },
- input({
- id: "devtools-cache-checkbox",
- className: "devtools-checkbox",
- type: "checkbox",
- checked: browserCacheDisabled,
- onChange: toggleBrowserCache,
- }),
- DISABLE_CACHE_LABEL,
- ),
+ span({ className: "devtools-toolbar-group devtools-toolbar-single-row" },
+ this.renderClearButton(clearRequests),
+ this.renderSeparator(),
+ this.renderFilterBox(setRequestFilterText),
+ this.renderSeparator(),
+ this.renderToggleRecordingButton(recording, toggleRecording),
+ this.renderSeparator(),
+ this.renderFilterButtons(requestFilterTypes),
+ this.renderSeparator(),
+ this.renderPersistlogCheckbox(persistentLogsEnabled, togglePersistentLogs),
+ this.renderCacheCheckbox(browserCacheDisabled, toggleBrowserCache),
),
span({ className: "devtools-toolbar-group" },
- SearchBox({
- delay: FILTER_SEARCH_DELAY,
- keyShortcut: SEARCH_KEY_SHORTCUT,
- placeholder: SEARCH_PLACE_HOLDER,
- type: "filter",
- ref: "searchbox",
- onChange: setRequestFilterText,
- onFocus: this.onSearchBoxFocus,
- autocompleteProvider: this.autocompleteProvider,
- }),
- button({
- className: toggleDetailButtonClass,
- title: toggleDetailButtonTitle,
- disabled: networkDetailsToggleDisabled,
- tabIndex: "0",
- onClick: toggleNetworkDetails,
- }),
+ this.renderSeparator(),
+ this.renderDetailButton(networkDetailsOpen,
+ networkDetailsToggleDisabled, toggleNetworkDetails),
+ )
+ )
+ ) : (
+ span({ className: "devtools-toolbar devtools-toolbar-container" },
+ span({ className: "devtools-toolbar-group devtools-toolbar-two-rows-1" },
+ this.renderClearButton(clearRequests),
+ this.renderSeparator(),
+ this.renderFilterBox(setRequestFilterText),
+ this.renderSeparator(),
+ this.renderToggleRecordingButton(recording, toggleRecording),
+ this.renderSeparator(),
+ this.renderPersistlogCheckbox(persistentLogsEnabled, togglePersistentLogs),
+ this.renderCacheCheckbox(browserCacheDisabled, toggleBrowserCache),
+ ),
+ span({ className: "devtools-toolbar-group devtools-toolbar-two-rows-2" },
+ this.renderFilterButtons(requestFilterTypes),
+ span({},
+ this.renderSeparator(),
+ this.renderDetailButton(networkDetailsOpen,
+ networkDetailsToggleDisabled, toggleNetworkDetails),
+ ),
)
)
);
}
}
module.exports = connect(
(state) => ({