Bug 1434885 - Netmonitor list of requests width and height synced with details panel using dedicated action r=Honza
authorglowka <glowka.tom@gmail.com>
Thu, 22 Feb 2018 22:06:36 +0100
changeset 462259 0922530dcf5f140ba6ac44c6b405725a3121716b
parent 462258 4e5253710464b7ae1bbe600ae7f36a95212b5f90
child 462260 3836a743ba539056cb8b38240861e339cad579c3
push id1683
push usersfraser@mozilla.com
push dateThu, 26 Apr 2018 16:43:40 +0000
treeherdermozilla-release@5af6cb21869d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersHonza
bugs1434885
milestone60.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 1434885 - Netmonitor list of requests width and height synced with details panel using dedicated action r=Honza MozReview-Commit-ID: KNaTyJE0nbR
devtools/client/netmonitor/src/actions/ui.js
devtools/client/netmonitor/src/assets/styles/RequestList.css
devtools/client/netmonitor/src/components/MonitorPanel.js
devtools/client/netmonitor/src/components/RequestListContent.js
devtools/client/netmonitor/src/constants.js
devtools/client/netmonitor/src/reducers/ui.js
--- a/devtools/client/netmonitor/src/actions/ui.js
+++ b/devtools/client/netmonitor/src/actions/ui.js
@@ -2,16 +2,17 @@
  * 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/. */
 
 "use strict";
 
 const {
   ACTIVITY_TYPE,
   OPEN_NETWORK_DETAILS,
+  RESIZE_NETWORK_DETAILS,
   ENABLE_PERSISTENT_LOGS,
   DISABLE_BROWSER_CACHE,
   OPEN_STATISTICS,
   RESET_COLUMNS,
   SELECT_DETAILS_PANEL_TAB,
   TOGGLE_COLUMN,
   WATERFALL_RESIZE,
 } = require("../constants");
@@ -24,16 +25,30 @@ const {
 function openNetworkDetails(open) {
   return {
     type: OPEN_NETWORK_DETAILS,
     open,
   };
 }
 
 /**
+ * Change network details panel size.
+ *
+ * @param {integer} width
+ * @param {integer} height
+ */
+function resizeNetworkDetails(width, height) {
+  return {
+    type: RESIZE_NETWORK_DETAILS,
+    width,
+    height,
+  };
+}
+
+/**
  * Change persistent logs state.
  *
  * @param {boolean} enabled - expected persistent logs enabled state
  */
 function enablePersistentLogs(enabled) {
   return {
     type: ENABLE_PERSISTENT_LOGS,
     enabled,
@@ -141,16 +156,17 @@ function toggleBrowserCache() {
  */
 function toggleStatistics(connector) {
   return (dispatch, getState) =>
     dispatch(openStatistics(connector, !getState().ui.statisticsOpen));
 }
 
 module.exports = {
   openNetworkDetails,
+  resizeNetworkDetails,
   enablePersistentLogs,
   disableBrowserCache,
   openStatistics,
   resetColumns,
   resizeWaterfall,
   selectDetailsPanelTab,
   toggleColumn,
   toggleNetworkDetails,
--- a/devtools/client/netmonitor/src/assets/styles/RequestList.css
+++ b/devtools/client/netmonitor/src/assets/styles/RequestList.css
@@ -60,17 +60,16 @@
   position: relative;
   width: 100%;
   height: 100%;
 }
 
 .requests-list-contents {
   display: table-row-group;
   position: absolute;
-  width: 100%;
   overflow-x: hidden;
   overflow-y: auto;
   --timings-scale: 1;
   --timings-rev-scale: 1;
 }
 
 .requests-list-column {
   display: table-cell;
--- a/devtools/client/netmonitor/src/components/MonitorPanel.js
+++ b/devtools/client/netmonitor/src/components/MonitorPanel.js
@@ -35,32 +35,34 @@ const MediaQueryList = window.matchMedia
  */
 class MonitorPanel extends Component {
   static get propTypes() {
     return {
       connector: PropTypes.object.isRequired,
       isEmpty: PropTypes.bool.isRequired,
       networkDetailsOpen: PropTypes.bool.isRequired,
       openNetworkDetails: PropTypes.func.isRequired,
+      onNetworkDetailsResized: PropTypes.func.isRequired,
       request: PropTypes.object,
       selectedRequestVisible: PropTypes.bool.isRequired,
       sourceMapService: PropTypes.object,
       openLink: PropTypes.func,
       updateRequest: PropTypes.func.isRequired,
     };
   }
 
   constructor(props) {
     super(props);
 
     this.state = {
       isVerticalSpliter: MediaQueryList.matches,
     };
 
     this.onLayoutChange = this.onLayoutChange.bind(this);
+    this.onNetworkDetailsResized = this.onNetworkDetailsResized.bind(this);
   }
 
   componentDidMount() {
     MediaQueryList.addListener(this.onLayoutChange);
   }
 
   componentWillReceiveProps(nextProps) {
     updateFormDataSections(nextProps);
@@ -89,16 +91,26 @@ class MonitorPanel extends Component {
   }
 
   onLayoutChange() {
     this.setState({
       isVerticalSpliter: MediaQueryList.matches,
     });
   }
 
+  onNetworkDetailsResized(width, height) {
+   // Cleaning width and height parameters, because SplitBox passes ALWAYS two values,
+   // while depending on orientation ONLY ONE dimension is managed by it at a time.
+    let { isVerticalSpliter }  = this.state;
+    return this.props.onNetworkDetailsResized(
+      isVerticalSpliter ? width : null,
+      isVerticalSpliter ? null : height
+    );
+  }
+
   render() {
     let {
       connector,
       isEmpty,
       networkDetailsOpen,
       openLink,
       sourceMapService,
     } = this.props;
@@ -123,26 +135,30 @@ class MonitorPanel extends Component {
             ref: "endPanel",
             connector,
             openLink,
             sourceMapService,
           }),
           endPanelCollapsed: !networkDetailsOpen,
           endPanelControl: true,
           vert: this.state.isVerticalSpliter,
+          onControlledPanelResized: this.onNetworkDetailsResized,
         }),
       )
     );
   }
 }
 
 module.exports = connect(
   (state) => ({
     isEmpty: state.requests.requests.size == 0,
     networkDetailsOpen: state.ui.networkDetailsOpen,
     request: getSelectedRequest(state),
     selectedRequestVisible: isSelectedRequestVisible(state),
   }),
   (dispatch) => ({
     openNetworkDetails: (open) => dispatch(Actions.openNetworkDetails(open)),
+    onNetworkDetailsResized: (width, height) => dispatch(
+      Actions.resizeNetworkDetails(width, height)
+    ),
     updateRequest: (id, data, batch) => dispatch(Actions.updateRequest(id, data, batch)),
   }),
 )(MonitorPanel);
--- a/devtools/client/netmonitor/src/components/RequestListContent.js
+++ b/devtools/client/netmonitor/src/components/RequestListContent.js
@@ -45,16 +45,19 @@ const MAX_SCROLL_HEIGHT = 2147483647;
 /**
  * Renders the actual contents of the request list.
  */
 class RequestListContent extends Component {
   static get propTypes() {
     return {
       connector: PropTypes.object.isRequired,
       columns: PropTypes.object.isRequired,
+      networkDetailsOpen: PropTypes.bool.isRequired,
+      networkDetailsWidth: PropTypes.number.isRequired,
+      networkDetailsHeight: PropTypes.number.isRequired,
       cloneSelectedRequest: PropTypes.func.isRequired,
       displayedRequests: PropTypes.array.isRequired,
       firstRequestStartedMillis: PropTypes.number.isRequired,
       fromCache: PropTypes.bool,
       onCauseBadgeMouseDown: PropTypes.func.isRequired,
       onItemMouseDown: PropTypes.func.isRequired,
       onSecurityIconMouseDown: PropTypes.func.isRequired,
       onSelectDelta: PropTypes.func.isRequired,
@@ -109,28 +112,35 @@ class RequestListContent extends Compone
 
   componentDidUpdate(prevProps) {
     let node = this.refs.contentEl;
     // Keep the list scrolled to bottom if a new row was added
     if (this.shouldScrollBottom && node.scrollTop !== MAX_SCROLL_HEIGHT) {
       // Using maximum scroll height rather than node.scrollHeight to avoid sync reflow.
       node.scrollTop = MAX_SCROLL_HEIGHT;
     }
+    if (prevProps.networkDetailsOpen !== this.props.networkDetailsOpen ||
+      prevProps.networkDetailsWidth !== this.props.networkDetailsWidth ||
+      prevProps.networkDetailsHeight !== this.props.networkDetailsHeight
+    ) {
+      this.onResize();
+    }
   }
 
   componentWillUnmount() {
     this.refs.contentEl.removeEventListener("scroll", this.onScroll, true);
 
     // Uninstall the tooltip event handler
     this.tooltip.stopTogglingOnHover();
     window.removeEventListener("resize", this.onResize);
   }
 
   onResize() {
     let parent = this.refs.contentEl.parentNode;
+    this.refs.contentEl.style.width = parent.offsetWidth + "px";
     this.refs.contentEl.style.height = parent.offsetHeight + "px";
   }
 
   isScrolledToBottom() {
     const { contentEl } = this.refs;
     const lastChildEl = contentEl.lastElementChild;
 
     if (!lastChildEl) {
@@ -295,16 +305,19 @@ class RequestListContent extends Compone
       )
     );
   }
 }
 
 module.exports = connect(
   (state) => ({
     columns: state.ui.columns,
+    networkDetailsOpen: state.ui.networkDetailsOpen,
+    networkDetailsWidth: state.ui.networkDetailsWidth,
+    networkDetailsHeight: state.ui.networkDetailsHeight,
     displayedRequests: getDisplayedRequests(state),
     firstRequestStartedMillis: state.requests.firstStartedMillis,
     selectedRequest: getSelectedRequest(state),
     scale: getWaterfallScale(state),
     sortedRequests: getSortedRequests(state),
     requestFilterTypes: state.filters.requestFilterTypes,
   }),
   (dispatch, props) => ({
--- a/devtools/client/netmonitor/src/constants.js
+++ b/devtools/client/netmonitor/src/constants.js
@@ -9,16 +9,17 @@ const actionTypes = {
   ADD_TIMING_MARKER: "ADD_TIMING_MARKER",
   BATCH_ACTIONS: "BATCH_ACTIONS",
   BATCH_ENABLE: "BATCH_ENABLE",
   CLEAR_REQUESTS: "CLEAR_REQUESTS",
   CLEAR_TIMING_MARKERS: "CLEAR_TIMING_MARKERS",
   CLONE_SELECTED_REQUEST: "CLONE_SELECTED_REQUEST",
   ENABLE_REQUEST_FILTER_TYPE_ONLY: "ENABLE_REQUEST_FILTER_TYPE_ONLY",
   OPEN_NETWORK_DETAILS: "OPEN_NETWORK_DETAILS",
+  RESIZE_NETWORK_DETAILS: "RESIZE_NETWORK_DETAILS",
   ENABLE_PERSISTENT_LOGS: "ENABLE_PERSISTENT_LOGS",
   DISABLE_BROWSER_CACHE: "DISABLE_BROWSER_CACHE",
   OPEN_STATISTICS: "OPEN_STATISTICS",
   REMOVE_SELECTED_CUSTOM_REQUEST: "REMOVE_SELECTED_CUSTOM_REQUEST",
   RESET_COLUMNS: "RESET_COLUMNS",
   SELECT_REQUEST: "SELECT_REQUEST",
   SELECT_DETAILS_PANEL_TAB: "SELECT_DETAILS_PANEL_TAB",
   SEND_CUSTOM_REQUEST: "SEND_CUSTOM_REQUEST",
--- a/devtools/client/netmonitor/src/reducers/ui.js
+++ b/devtools/client/netmonitor/src/reducers/ui.js
@@ -3,16 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 const Services = require("Services");
 const {
   CLEAR_REQUESTS,
   OPEN_NETWORK_DETAILS,
+  RESIZE_NETWORK_DETAILS,
   ENABLE_PERSISTENT_LOGS,
   DISABLE_BROWSER_CACHE,
   OPEN_STATISTICS,
   REMOVE_SELECTED_CUSTOM_REQUEST,
   RESET_COLUMNS,
   RESPONSE_HEADERS,
   SELECT_DETAILS_PANEL_TAB,
   SEND_CUSTOM_REQUEST,
@@ -50,16 +51,18 @@ function Columns() {
   );
 }
 
 function UI(initialState = {}) {
   return {
     columns: Columns(),
     detailsPanelSelectedTab: PANELS.HEADERS,
     networkDetailsOpen: false,
+    networkDetailsWidth: null,
+    networkDetailsHeight: null,
     persistentLogsEnabled: Services.prefs.getBoolPref("devtools.netmonitor.persistlog"),
     browserCacheDisabled: Services.prefs.getBoolPref("devtools.cache.disabled"),
     statisticsOpen: false,
     waterfallWidth: null,
     ...initialState,
   };
 }
 
@@ -79,16 +82,24 @@ function resizeWaterfall(state, action) 
 
 function openNetworkDetails(state, action) {
   return {
     ...state,
     networkDetailsOpen: action.open
   };
 }
 
+function resizeNetworkDetails(state, action) {
+  return {
+    ...state,
+    networkDetailsWidth: action.width,
+    networkDetailsHeight: action.height,
+  };
+}
+
 function enablePersistentLogs(state, action) {
   return {
     ...state,
     persistentLogsEnabled: action.enabled
   };
 }
 
 function disableBrowserCache(state, action) {
@@ -129,16 +140,18 @@ function toggleColumn(state, action) {
 }
 
 function ui(state = UI(), action) {
   switch (action.type) {
     case CLEAR_REQUESTS:
       return openNetworkDetails(state, { open: false });
     case OPEN_NETWORK_DETAILS:
       return openNetworkDetails(state, action);
+    case RESIZE_NETWORK_DETAILS:
+      return resizeNetworkDetails(state, action);
     case ENABLE_PERSISTENT_LOGS:
       return enablePersistentLogs(state, action);
     case DISABLE_BROWSER_CACHE:
       return disableBrowserCache(state, action);
     case OPEN_STATISTICS:
       return openStatistics(state, action);
     case RESET_COLUMNS:
       return resetColumns(state);