--- a/devtools/client/locales/en-US/netmonitor.properties
+++ b/devtools/client/locales/en-US/netmonitor.properties
@@ -419,20 +419,20 @@ netmonitor.toolbar.cause=Cause
# in the network table toolbar, above the "type" column.
netmonitor.toolbar.type=Type
# LOCALIZATION NOTE (netmonitor.toolbar.transferred): This is the label displayed
# in the network table toolbar, above the "transferred" column, which is the
# compressed / encoded size.
netmonitor.toolbar.transferred=Transferred
-# LOCALIZATION NOTE (netmonitor.toolbar.size): This is the label displayed
+# LOCALIZATION NOTE (netmonitor.toolbar.contentSize): This is the label displayed
# in the network table toolbar, above the "size" column, which is the
# uncompressed / decoded size.
-netmonitor.toolbar.size=Size
+netmonitor.toolbar.contentSize=Size
# LOCALIZATION NOTE (netmonitor.toolbar.waterfall): This is the label displayed
# in the network table toolbar, above the "waterfall" column.
netmonitor.toolbar.waterfall=Timeline
# LOCALIZATION NOTE (netmonitor.tab.headers): This is the label displayed
# in the network details pane identifying the headers tab.
netmonitor.tab.headers=Headers
@@ -520,16 +520,20 @@ netmonitor.toolbar.filterFreetext.key=Cm
# LOCALIZATION NOTE (netmonitor.toolbar.clear): This is the label displayed
# in the network toolbar for the "Clear" button.
netmonitor.toolbar.clear=Clear
# LOCALIZATION NOTE (netmonitor.toolbar.perf): This is the label displayed
# in the network toolbar for the performance analysis button.
netmonitor.toolbar.perf=Toggle performance analysis…
+# LOCALIZATION NOTE (netmonitor.toolbar.resetColumns): This is the label
+# displayed in the network table header context menu.
+netmonitor.toolbar.resetColumns=Reset Columns
+
# LOCALIZATION NOTE (netmonitor.summary.url): This is the label displayed
# in the network details headers tab identifying the URL.
netmonitor.summary.url=Request URL:
# LOCALIZATION NOTE (netmonitor.summary.method): This is the label displayed
# in the network details headers tab identifying the method.
netmonitor.summary.method=Request method:
--- a/devtools/client/netmonitor/src/actions/ui.js
+++ b/devtools/client/netmonitor/src/actions/ui.js
@@ -3,17 +3,19 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const {
ACTIVITY_TYPE,
OPEN_NETWORK_DETAILS,
OPEN_STATISTICS,
+ RESET_COLUMNS,
SELECT_DETAILS_PANEL_TAB,
+ TOGGLE_COLUMN,
WATERFALL_RESIZE,
} = require("../constants");
/**
* Change network details panel.
*
* @param {boolean} open - expected network details panel open state
*/
@@ -35,16 +37,26 @@ function openStatistics(open) {
}
return {
type: OPEN_STATISTICS,
open,
};
}
/**
+ * Resets all columns to their default state.
+ *
+ */
+function resetColumns() {
+ return {
+ type: RESET_COLUMNS,
+ };
+}
+
+/**
* Waterfall width has changed (likely on window resize). Update the UI.
*/
function resizeWaterfall(width) {
return {
type: WATERFALL_RESIZE,
width
};
}
@@ -57,16 +69,28 @@ function resizeWaterfall(width) {
function selectDetailsPanelTab(id) {
return {
type: SELECT_DETAILS_PANEL_TAB,
id,
};
}
/**
+ * Toggles a column
+ *
+ * @param {string} column - The column that is going to be toggled
+ */
+function toggleColumn(column) {
+ return {
+ type: TOGGLE_COLUMN,
+ column,
+ };
+}
+
+/**
* Toggle network details panel.
*/
function toggleNetworkDetails() {
return (dispatch, getState) =>
dispatch(openNetworkDetails(!getState().ui.networkDetailsOpen));
}
/**
@@ -75,13 +99,15 @@ function toggleNetworkDetails() {
function toggleStatistics() {
return (dispatch, getState) =>
dispatch(openStatistics(!getState().ui.statisticsOpen));
}
module.exports = {
openNetworkDetails,
openStatistics,
+ resetColumns,
resizeWaterfall,
selectDetailsPanelTab,
+ toggleColumn,
toggleNetworkDetails,
toggleStatistics,
};
--- a/devtools/client/netmonitor/src/components/request-list-content.js
+++ b/devtools/client/netmonitor/src/components/request-list-content.js
@@ -30,16 +30,17 @@ const REQUESTS_TOOLTIP_TOGGLE_DELAY = 50
/**
* Renders the actual contents of the request list.
*/
const RequestListContent = createClass({
displayName: "RequestListContent",
propTypes: {
+ columns: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired,
displayedRequests: PropTypes.object.isRequired,
firstRequestStartedMillis: PropTypes.number.isRequired,
fromCache: PropTypes.bool.isRequired,
onCauseBadgeClick: PropTypes.func.isRequired,
onItemMouseDown: PropTypes.func.isRequired,
onSecurityIconClick: PropTypes.func.isRequired,
onSelectDelta: PropTypes.func.isRequired,
@@ -215,16 +216,17 @@ const RequestListContent = createClass({
* scrolled to bottom, but allow scrolling up with the selection.
*/
onFocusedNodeChange() {
this.shouldScrollBottom = false;
},
render() {
const {
+ columns,
displayedRequests,
firstRequestStartedMillis,
selectedRequestId,
onCauseBadgeClick,
onItemMouseDown,
onSecurityIconClick,
} = this.props;
@@ -233,16 +235,17 @@ const RequestListContent = createClass({
ref: "contentEl",
className: "requests-list-contents",
tabIndex: 0,
onKeyDown: this.onKeyDown,
},
displayedRequests.map((item, index) => RequestListItem({
firstRequestStartedMillis,
fromCache: item.status === "304" || item.fromCache,
+ columns,
item,
index,
isSelected: item.id === selectedRequestId,
key: item.id,
onContextMenu: this.onContextMenu,
onFocusedNodeChange: this.onFocusedNodeChange,
onMouseDown: () => onItemMouseDown(item.id),
onCauseBadgeClick: () => onCauseBadgeClick(item.cause),
@@ -250,16 +253,17 @@ const RequestListContent = createClass({
}))
)
);
},
});
module.exports = connect(
(state) => ({
+ columns: state.ui.columns,
displayedRequests: getDisplayedRequests(state),
firstRequestStartedMillis: state.requests.firstStartedMillis,
selectedRequestId: state.requests.selectedId,
scale: getWaterfallScale(state),
}),
(dispatch) => ({
dispatch,
onItemMouseDown: (id) => dispatch(Actions.selectRequest(id)),
--- a/devtools/client/netmonitor/src/components/request-list-header.js
+++ b/devtools/client/netmonitor/src/components/request-list-header.js
@@ -10,50 +10,61 @@ const {
DOM,
} = require("devtools/client/shared/vendor/react");
const { connect } = require("devtools/client/shared/vendor/react-redux");
const Actions = require("../actions/index");
const { getWaterfallScale } = require("../selectors/index");
const { getFormattedTime } = require("../utils/format-utils");
const { L10N } = require("../utils/l10n");
const WaterfallBackground = require("../waterfall-background");
+const RequestListHeaderContextMenu = require("../request-list-header-context-menu");
const { div, button } = DOM;
const REQUESTS_WATERFALL_HEADER_TICKS_MULTIPLE = 5; // ms
const REQUESTS_WATERFALL_HEADER_TICKS_SPACING_MIN = 60; // px
const HEADERS = [
{ name: "status", label: "status3" },
{ name: "method" },
{ name: "file", boxName: "icon-and-file" },
{ name: "domain", boxName: "security-and-domain" },
{ name: "cause" },
{ name: "type" },
{ name: "transferred" },
- { name: "size" },
+ { name: "contentSize", boxName: "size" },
{ name: "waterfall" }
];
/**
* Render the request list header with sorting arrows for columns.
* Displays tick marks in the waterfall column header.
* Also draws the waterfall background canvas and updates it when needed.
*/
const RequestListHeader = createClass({
displayName: "RequestListHeader",
propTypes: {
+ columns: PropTypes.object.isRequired,
+ dispatch: PropTypes.func.isRequired,
sort: PropTypes.object,
scale: PropTypes.number,
waterfallWidth: PropTypes.number,
onHeaderClick: PropTypes.func.isRequired,
resizeWaterfall: PropTypes.func.isRequired,
},
+ componentWillMount() {
+ const { dispatch } = this.props;
+ this.contextMenu = new RequestListHeaderContextMenu({
+ toggleColumn: (column) => dispatch(Actions.toggleColumn(column)),
+ resetColumns: () => dispatch(Actions.resetColumns()),
+ });
+ },
+
componentDidMount() {
// Create the object that takes care of drawing the waterfall canvas background
this.background = new WaterfallBackground(document);
this.background.draw(this.props);
this.resizeWaterfall();
window.addEventListener("resize", this.resizeWaterfall);
},
@@ -62,32 +73,37 @@ const RequestListHeader = createClass({
},
componentWillUnmount() {
this.background.destroy();
this.background = null;
window.removeEventListener("resize", this.resizeWaterfall);
},
+ onContextMenu(evt) {
+ evt.preventDefault();
+ this.contextMenu.open(evt);
+ },
+
resizeWaterfall() {
// Measure its width and update the 'waterfallWidth' property in the store.
// The 'waterfallWidth' will be further updated on every window resize.
setTimeout(() => {
let { width } = this.refs.header.getBoundingClientRect();
this.props.resizeWaterfall(width);
}, 50);
},
render() {
- const { sort, scale, waterfallWidth, onHeaderClick } = this.props;
+ const { sort, scale, waterfallWidth, onHeaderClick, columns } = this.props;
return div(
{ className: "devtools-toolbar requests-list-toolbar" },
div({ className: "toolbar-labels" },
- HEADERS.map(header => {
+ HEADERS.filter(h => columns.get(h.name)).map(header => {
const name = header.name;
const boxName = header.boxName || name;
const label = L10N.getStr(`netmonitor.toolbar.${header.label || name}`);
let sorted, sortedTitle;
const active = sort.type == name ? true : undefined;
if (active) {
sorted = sort.ascending ? "ascending" : "descending";
@@ -99,16 +115,17 @@ const RequestListHeader = createClass({
return div(
{
id: `requests-list-${boxName}-header-box`,
className: `requests-list-header requests-list-${boxName}`,
key: name,
ref: "header",
// Used to style the next column.
"data-active": active,
+ onContextMenu: this.onContextMenu,
},
button(
{
id: `requests-list-${name}-button`,
className: `requests-list-header-button requests-list-${name}`,
"data-sorted": sorted,
title: sortedTitle,
onClick: () => onHeaderClick(name),
@@ -184,19 +201,21 @@ function WaterfallLabel(waterfallWidth,
className += " requests-list-waterfall-visible";
}
return div({ className }, label);
}
module.exports = connect(
state => ({
+ columns: state.ui.columns,
sort: state.sort,
scale: getWaterfallScale(state),
waterfallWidth: state.ui.waterfallWidth,
firstRequestStartedMillis: state.requests.firstStartedMillis,
timingMarkers: state.timingMarkers,
}),
dispatch => ({
+ dispatch,
onHeaderClick: type => dispatch(Actions.sortBy(type)),
resizeWaterfall: width => dispatch(Actions.resizeWaterfall(width)),
})
)(RequestListHeader);
--- a/devtools/client/netmonitor/src/components/request-list-item.js
+++ b/devtools/client/netmonitor/src/components/request-list-item.js
@@ -5,16 +5,18 @@
"use strict";
const {
createClass,
createFactory,
DOM,
PropTypes,
} = require("devtools/client/shared/vendor/react");
+const I = require("devtools/client/shared/vendor/immutable");
+
const { getFormattedSize } = require("../utils/format-utils");
const { L10N } = require("../utils/l10n");
const { getAbbreviatedMimeType } = require("../utils/request-utils");
const { div, img, span } = DOM;
/**
* Compare two objects on a subset of their properties
@@ -56,16 +58,17 @@ const UPDATED_REQ_PROPS = [
/**
* Render one row in the request list.
*/
const RequestListItem = createClass({
displayName: "RequestListItem",
propTypes: {
+ columns: PropTypes.object.isRequired,
item: PropTypes.object.isRequired,
index: PropTypes.number.isRequired,
isSelected: PropTypes.bool.isRequired,
firstRequestStartedMillis: PropTypes.number.isRequired,
fromCache: PropTypes.bool.isRequired,
onCauseBadgeClick: PropTypes.func.isRequired,
onContextMenu: PropTypes.func.isRequired,
onFocusedNodeChange: PropTypes.func,
@@ -76,30 +79,32 @@ const RequestListItem = createClass({
componentDidMount() {
if (this.props.isSelected) {
this.refs.el.focus();
}
},
shouldComponentUpdate(nextProps) {
return !propertiesEqual(UPDATED_REQ_ITEM_PROPS, this.props.item, nextProps.item) ||
- !propertiesEqual(UPDATED_REQ_PROPS, this.props, nextProps);
+ !propertiesEqual(UPDATED_REQ_PROPS, this.props, nextProps) ||
+ !I.is(this.props.columns, nextProps.columns);
},
componentDidUpdate(prevProps) {
if (!prevProps.isSelected && this.props.isSelected) {
this.refs.el.focus();
if (this.props.onFocusedNodeChange) {
this.props.onFocusedNodeChange();
}
}
},
render() {
const {
+ columns,
item,
index,
isSelected,
firstRequestStartedMillis,
fromCache,
onContextMenu,
onMouseDown,
onCauseBadgeClick,
@@ -121,25 +126,25 @@ const RequestListItem = createClass({
div({
ref: "el",
className: classList.join(" "),
"data-id": item.id,
tabIndex: 0,
onContextMenu,
onMouseDown,
},
- StatusColumn({ item }),
- MethodColumn({ item }),
- FileColumn({ item }),
- DomainColumn({ item, onSecurityIconClick }),
- CauseColumn({ item, onCauseBadgeClick }),
- TypeColumn({ item }),
- TransferredSizeColumn({ item }),
- ContentSizeColumn({ item }),
- WaterfallColumn({ item, firstRequestStartedMillis }),
+ columns.get("status") && StatusColumn({ item }),
+ columns.get("method") && MethodColumn({ item }),
+ columns.get("file") && FileColumn({ item }),
+ columns.get("domain") && DomainColumn({ item, onSecurityIconClick }),
+ columns.get("cause") && CauseColumn({ item, onCauseBadgeClick }),
+ columns.get("type") && TypeColumn({ item }),
+ columns.get("transferred") && TransferredSizeColumn({ item }),
+ columns.get("contentSize") && ContentSizeColumn({ item }),
+ columns.get("waterfall") && WaterfallColumn({ item, firstRequestStartedMillis }),
)
);
}
});
const UPDATED_STATUS_PROPS = [
"status",
"statusText",
--- a/devtools/client/netmonitor/src/constants.js
+++ b/devtools/client/netmonitor/src/constants.js
@@ -11,21 +11,23 @@ const actionTypes = {
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",
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",
SET_REQUEST_FILTER_TEXT: "SET_REQUEST_FILTER_TEXT",
SORT_BY: "SORT_BY",
+ TOGGLE_COLUMN: "TOGGLE_COLUMN",
TOGGLE_REQUEST_FILTER_TYPE: "TOGGLE_REQUEST_FILTER_TYPE",
UPDATE_REQUEST: "UPDATE_REQUEST",
WATERFALL_RESIZE: "WATERFALL_RESIZE",
};
// Descriptions for what this frontend is currently doing.
const ACTIVITY_TYPE = {
// Standing by and handling requests normally.
--- a/devtools/client/netmonitor/src/middleware/prefs.js
+++ b/devtools/client/netmonitor/src/middleware/prefs.js
@@ -1,31 +1,46 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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 {
ENABLE_REQUEST_FILTER_TYPE_ONLY,
+ RESET_COLUMNS,
+ TOGGLE_COLUMN,
TOGGLE_REQUEST_FILTER_TYPE,
} = require("../constants");
const { Prefs } = require("../utils/prefs");
const { getRequestFilterTypes } = require("../selectors/index");
/**
- * Whenever the User clicks on a filter in the network monitor, save the new
- * filters for future tabs
+ * Update the relevant prefs when:
+ * - a column has been toggled
+ * - a filter type has been set
*/
function prefsMiddleware(store) {
return next => action => {
const res = next(action);
- if (action.type === ENABLE_REQUEST_FILTER_TYPE_ONLY ||
- action.type === TOGGLE_REQUEST_FILTER_TYPE) {
- Prefs.filters = getRequestFilterTypes(store.getState())
- .filter(([type, check]) => check)
- .map(([type, check]) => type);
+ switch (action.type) {
+ case ENABLE_REQUEST_FILTER_TYPE_ONLY:
+ case TOGGLE_REQUEST_FILTER_TYPE:
+ Prefs.filters = getRequestFilterTypes(store.getState())
+ .filter(([type, check]) => check)
+ .map(([type, check]) => type);
+ break;
+
+ case TOGGLE_COLUMN:
+ Prefs.hiddenColumns = [...store.getState().ui.columns]
+ .filter(([column, shown]) => !shown)
+ .map(([column, shown]) => column);
+ break;
+
+ case RESET_COLUMNS:
+ Prefs.hiddenColumns = [];
+ break;
}
return res;
};
}
module.exports = prefsMiddleware;
--- a/devtools/client/netmonitor/src/moz.build
+++ b/devtools/client/netmonitor/src/moz.build
@@ -11,11 +11,12 @@ DIRS += [
'selectors',
'utils',
]
DevToolsModules(
'constants.js',
'netmonitor-controller.js',
'request-list-context-menu.js',
+ 'request-list-header-context-menu.js',
'request-list-tooltip.js',
'waterfall-background.js',
)
--- a/devtools/client/netmonitor/src/reducers/ui.js
+++ b/devtools/client/netmonitor/src/reducers/ui.js
@@ -5,66 +5,103 @@
"use strict";
const I = require("devtools/client/shared/vendor/immutable");
const {
CLEAR_REQUESTS,
OPEN_NETWORK_DETAILS,
OPEN_STATISTICS,
REMOVE_SELECTED_CUSTOM_REQUEST,
+ RESET_COLUMNS,
SELECT_DETAILS_PANEL_TAB,
SEND_CUSTOM_REQUEST,
SELECT_REQUEST,
+ TOGGLE_COLUMN,
WATERFALL_RESIZE,
} = require("../constants");
+const Columns = I.Record({
+ status: true,
+ method: true,
+ file: true,
+ domain: true,
+ cause: true,
+ type: true,
+ transferred: true,
+ contentSize: true,
+ waterfall: true,
+});
+
const UI = I.Record({
+ columns: new Columns(),
detailsPanelSelectedTab: "headers",
networkDetailsOpen: false,
statisticsOpen: false,
waterfallWidth: null,
});
// Safe bounds for waterfall width (px)
const REQUESTS_WATERFALL_SAFE_BOUNDS = 90;
+function resetColumns(state) {
+ return state.set("columns", new Columns());
+}
+
function resizeWaterfall(state, action) {
return state.set("waterfallWidth", action.width - REQUESTS_WATERFALL_SAFE_BOUNDS);
}
function openNetworkDetails(state, action) {
return state.set("networkDetailsOpen", action.open);
}
function openStatistics(state, action) {
return state.set("statisticsOpen", action.open);
}
function setDetailsPanelTab(state, action) {
return state.set("detailsPanelSelectedTab", action.id);
}
+function toggleColumn(state, action) {
+ let { column } = action;
+
+ if (!state.has(column)) {
+ return state;
+ }
+
+ let newState = state.withMutations(columns => {
+ columns.set(column, !state.get(column));
+ });
+ return newState;
+}
+
function ui(state = new UI(), action) {
switch (action.type) {
case CLEAR_REQUESTS:
return openNetworkDetails(state, { open: false });
case OPEN_NETWORK_DETAILS:
return openNetworkDetails(state, action);
case OPEN_STATISTICS:
return openStatistics(state, action);
+ case RESET_COLUMNS:
+ return resetColumns(state);
case REMOVE_SELECTED_CUSTOM_REQUEST:
case SEND_CUSTOM_REQUEST:
return openNetworkDetails(state, { open: false });
case SELECT_DETAILS_PANEL_TAB:
return setDetailsPanelTab(state, action);
case SELECT_REQUEST:
return openNetworkDetails(state, { open: true });
+ case TOGGLE_COLUMN:
+ return state.set("columns", toggleColumn(state.columns, action));
case WATERFALL_RESIZE:
return resizeWaterfall(state, action);
default:
return state;
}
}
module.exports = {
+ Columns,
UI,
ui
};
new file mode 100644
--- /dev/null
+++ b/devtools/client/netmonitor/src/request-list-header-context-menu.js
@@ -0,0 +1,59 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * 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 Menu = require("devtools/client/framework/menu");
+const MenuItem = require("devtools/client/framework/menu-item");
+const { L10N } = require("./utils/l10n");
+
+const stringMap = {
+ status: "status3"
+};
+
+class RequestListHeaderContextMenu {
+ constructor({ toggleColumn, resetColumns }) {
+ this.toggleColumn = toggleColumn;
+ this.resetColumns = resetColumns;
+ }
+
+ get columns() {
+ return window.gStore.getState().ui.columns;
+ }
+
+ get visibleColumns() {
+ return [...this.columns].filter(([_, shown]) => shown);
+ }
+
+ /**
+ * Handle the context menu opening.
+ */
+ open({ screenX = 0, screenY = 0 } = {}) {
+ let menu = new Menu();
+ let onlyOneColumn = this.visibleColumns.length === 1;
+
+ for (let [column, shown] of this.columns) {
+ menu.append(new MenuItem({
+ label: L10N.getStr(`netmonitor.toolbar.${stringMap[column] || column}`),
+ type: "checkbox",
+ checked: shown,
+ click: () => this.toggleColumn(column),
+ // We don't want to allow hiding the last visible column
+ disabled: onlyOneColumn && shown,
+ }));
+ }
+
+ menu.append(new MenuItem({ type: "separator" }));
+
+ menu.append(new MenuItem({
+ label: L10N.getStr("netmonitor.toolbar.resetColumns"),
+ click: () => this.resetColumns(),
+ }));
+
+ menu.popup(screenX, screenY, { doc: window.parent.document });
+ return menu;
+ }
+}
+
+module.exports = RequestListHeaderContextMenu;
--- a/devtools/client/netmonitor/src/utils/create-store.js
+++ b/devtools/client/netmonitor/src/utils/create-store.js
@@ -9,31 +9,39 @@ const { thunk } = require("devtools/clie
const batching = require("../middleware/batching");
const prefs = require("../middleware/prefs");
const { Prefs } = require("./prefs");
const rootReducer = require("../reducers/index");
const { FilterTypes, Filters } = require("../reducers/filters");
const { Requests } = require("../reducers/requests");
const { Sort } = require("../reducers/sort");
const { TimingMarkers } = require("../reducers/timing-markers");
-const { UI } = require("../reducers/ui");
+const { UI, Columns } = require("../reducers/ui");
function configureStore() {
let activeFilters = {};
Prefs.filters.forEach((filter) => {
activeFilters[filter] = true;
});
+
+ let inactiveColumns = Prefs.hiddenColumns.reduce((acc, col) => {
+ acc[col] = false;
+ return acc;
+ }, {});
+
const initialState = {
filters: new Filters({
requestFilterTypes: new FilterTypes(activeFilters)
}),
requests: new Requests(),
sort: new Sort(),
timingMarkers: new TimingMarkers(),
- ui: new UI()
+ ui: new UI({
+ columns: new Columns(inactiveColumns)
+ }),
};
return createStore(
rootReducer,
initialState,
applyMiddleware(
thunk,
prefs,
--- a/devtools/client/netmonitor/src/utils/prefs.js
+++ b/devtools/client/netmonitor/src/utils/prefs.js
@@ -7,10 +7,11 @@
const { PrefsHelper } = require("devtools/client/shared/prefs");
/**
* Shortcuts for accessing various network monitor preferences.
*/
exports.Prefs = new PrefsHelper("devtools.netmonitor", {
networkDetailsWidth: ["Int", "panes-network-details-width"],
networkDetailsHeight: ["Int", "panes-network-details-height"],
+ hiddenColumns: ["Json", "hiddenColumns"],
filters: ["Json", "filters"]
});
--- a/devtools/client/netmonitor/src/utils/sort-predicates.js
+++ b/devtools/client/netmonitor/src/utils/sort-predicates.js
@@ -71,24 +71,24 @@ function type(first, second) {
return result || waterfall(first, second);
}
function transferred(first, second) {
const result = compareValues(first.transferredSize, second.transferredSize);
return result || waterfall(first, second);
}
-function size(first, second) {
+function contentSize(first, second) {
const result = compareValues(first.contentSize, second.contentSize);
return result || waterfall(first, second);
}
exports.Sorters = {
status,
method,
file,
domain,
cause,
type,
transferred,
- size,
+ contentSize,
waterfall,
};
--- a/devtools/client/netmonitor/test/browser_net_filter-03.js
+++ b/devtools/client/netmonitor/test/browser_net_filter-03.js
@@ -59,17 +59,17 @@ add_task(function* () {
is(!!document.querySelector(".network-details-panel"), true,
"The network details panel should be visible after toggle button was pressed.");
testFilterButtons(monitor, "all");
testContents([0, 1, 2, 3, 4, 5, 6], 7, 0);
info("Sorting by size, ascending.");
EventUtils.sendMouseEvent({ type: "click" },
- document.querySelector("#requests-list-size-button"));
+ document.querySelector("#requests-list-contentSize-button"));
testFilterButtons(monitor, "all");
testContents([6, 4, 5, 0, 1, 2, 3], 7, 6);
info("Testing html filtering.");
EventUtils.sendMouseEvent({ type: "click" },
document.querySelector(".requests-list-filter-html-button"));
testFilterButtons(monitor, "html");
testContents([6, 4, 5, 0, 1, 2, 3], 1, 6);
@@ -95,17 +95,17 @@ add_task(function* () {
3, 20);
yield teardown(monitor);
function resetSorting() {
EventUtils.sendMouseEvent({ type: "click" },
document.querySelector("#requests-list-waterfall-button"));
EventUtils.sendMouseEvent({ type: "click" },
- document.querySelector("#requests-list-size-button"));
+ document.querySelector("#requests-list-contentSize-button"));
}
function getSelectedIndex(state) {
if (!state.requests.selectedId) {
return -1;
}
return getSortedRequests(state).findIndex(r => r.id === state.requests.selectedId);
}
--- a/devtools/client/netmonitor/test/browser_net_icon-preview.js
+++ b/devtools/client/netmonitor/test/browser_net_icon-preview.js
@@ -23,17 +23,17 @@ add_task(function* () {
let wait = waitForEvents();
yield performRequests();
yield wait;
info("Checking the image thumbnail when all items are shown.");
checkImageThumbnail();
- gStore.dispatch(Actions.sortBy("size"));
+ gStore.dispatch(Actions.sortBy("contentSize"));
info("Checking the image thumbnail when all items are sorted.");
checkImageThumbnail();
gStore.dispatch(Actions.toggleRequestFilterType("images"));
info("Checking the image thumbnail when only images are shown.");
checkImageThumbnail();
info("Reloading the debuggee and performing all requests again...");
--- a/devtools/client/netmonitor/test/browser_net_sort-02.js
+++ b/devtools/client/netmonitor/test/browser_net_sort-02.js
@@ -151,30 +151,30 @@ add_task(function* () {
info("Testing transferred sort, ascending. Checking sort loops correctly.");
EventUtils.sendMouseEvent({ type: "click" },
document.querySelector("#requests-list-transferred-button"));
testHeaders("transferred", "ascending");
testContents([0, 1, 2, 3, 4]);
info("Testing size sort, ascending.");
EventUtils.sendMouseEvent({ type: "click" },
- document.querySelector("#requests-list-size-button"));
- testHeaders("size", "ascending");
+ document.querySelector("#requests-list-contentSize-button"));
+ testHeaders("contentSize", "ascending");
testContents([0, 1, 2, 3, 4]);
info("Testing size sort, descending.");
EventUtils.sendMouseEvent({ type: "click" },
- document.querySelector("#requests-list-size-button"));
- testHeaders("size", "descending");
+ document.querySelector("#requests-list-contentSize-button"));
+ testHeaders("contentSize", "descending");
testContents([4, 3, 2, 1, 0]);
info("Testing size sort, ascending. Checking sort loops correctly.");
EventUtils.sendMouseEvent({ type: "click" },
- document.querySelector("#requests-list-size-button"));
- testHeaders("size", "ascending");
+ document.querySelector("#requests-list-contentSize-button"));
+ testHeaders("contentSize", "ascending");
testContents([0, 1, 2, 3, 4]);
info("Testing waterfall sort, ascending.");
EventUtils.sendMouseEvent({ type: "click" },
document.querySelector("#requests-list-waterfall-button"));
testHeaders("waterfall", "ascending");
testContents([0, 2, 4, 3, 1]);
--- a/devtools/client/preferences/devtools.js
+++ b/devtools/client/preferences/devtools.js
@@ -145,16 +145,17 @@ pref("devtools.serviceWorkers.testing.en
// Enable the Network Monitor
pref("devtools.netmonitor.enabled", true);
// The default Network Monitor UI settings
pref("devtools.netmonitor.panes-network-details-width", 550);
pref("devtools.netmonitor.panes-network-details-height", 450);
pref("devtools.netmonitor.filters", "[\"all\"]");
+pref("devtools.netmonitor.hiddenColumns", "[]");
// The default Network monitor HAR export setting
pref("devtools.netmonitor.har.defaultLogDir", "");
pref("devtools.netmonitor.har.defaultFileName", "Archive %date");
pref("devtools.netmonitor.har.jsonp", false);
pref("devtools.netmonitor.har.jsonpCallback", "");
pref("devtools.netmonitor.har.includeResponseBodies", true);
pref("devtools.netmonitor.har.compress", false);