Bug 1434885 - Netmonitor list of requests width and height synced with details panel using dedicated action draft
authorglowka <glowka.tom@gmail.com>
Thu, 22 Feb 2018 22:06:36 +0100
changeset 764916 cd7629692d6552d56e4dd2de45e6aaa3f3fae34d
parent 758629 3f474e48db7f7b0f1c2c090f812290a8d9a21650
child 765884 4bff5b3dbc39f3e1505e8392eff252874c04ca95
push id101892
push userbmo:glowka.tom@gmail.com
push dateThu, 08 Mar 2018 16:14:30 +0000
bugs1434885
milestone60.0a1
Bug 1434885 - Netmonitor list of requests width and height synced with details panel using dedicated action 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.func.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);