Bug 1419366 - Stop using ImmutableJS in filters reducer. r=Honza draft
authorabhinav <abhinav.koppula@gmail.com>
Sun, 17 Dec 2017 23:56:27 +0530
changeset 713524 16a2168d17ac01f71cb77c3d9278b3e60de2791e
parent 712870 7c4579e705c4a3a3610183fe6f44affff3ad57ef
child 744351 7992d2ddce921238945fd34afe245a7f68b18b13
push id93661
push userbmo:abhinav.koppula@gmail.com
push dateWed, 20 Dec 2017 14:37:53 +0000
reviewersHonza
bugs1419366
milestone59.0a1
Bug 1419366 - Stop using ImmutableJS in filters reducer. r=Honza MozReview-Commit-ID: AgBGfJEy8t7
devtools/client/netmonitor/src/components/RequestListItem.js
devtools/client/netmonitor/src/components/Toolbar.js
devtools/client/netmonitor/src/middleware/prefs.js
devtools/client/netmonitor/src/reducers/filters.js
devtools/client/netmonitor/src/selectors/requests.js
devtools/client/netmonitor/test/browser_net_prefs-reload.js
--- a/devtools/client/netmonitor/src/components/RequestListItem.js
+++ b/devtools/client/netmonitor/src/components/RequestListItem.js
@@ -99,28 +99,28 @@ class RequestListItem extends Component 
 
   componentDidMount() {
     if (this.props.isSelected) {
       this.refs.listItem.focus();
     }
 
     let { connector, item, requestFilterTypes } = this.props;
     // Filtering XHR & WS require to lazily fetch requestHeaders & responseHeaders
-    if (requestFilterTypes.get("xhr") || requestFilterTypes.get("ws")) {
+    if (requestFilterTypes.xhr || requestFilterTypes.ws) {
       fetchNetworkUpdatePacket(connector.requestData, item, [
         "requestHeaders",
         "responseHeaders",
       ]);
     }
   }
 
   componentWillReceiveProps(nextProps) {
     let { connector, item, requestFilterTypes } = nextProps;
     // Filtering XHR & WS require to lazily fetch requestHeaders & responseHeaders
-    if (requestFilterTypes.get("xhr") || requestFilterTypes.get("ws")) {
+    if (requestFilterTypes.xhr || requestFilterTypes.ws) {
       fetchNetworkUpdatePacket(connector.requestData, item, [
         "requestHeaders",
         "responseHeaders",
       ]);
     }
   }
 
   shouldComponentUpdate(nextProps) {
--- a/devtools/client/netmonitor/src/components/Toolbar.js
+++ b/devtools/client/netmonitor/src/components/Toolbar.js
@@ -156,17 +156,17 @@ class Toolbar extends Component {
       togglePersistentLogs,
       persistentLogsEnabled,
       toggleBrowserCache,
       browserCacheDisabled,
       recording,
     } = this.props;
 
     // Render list of filter-buttons.
-    let buttons = requestFilterTypes.entrySeq().toArray().map(([type, checked]) => {
+    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(" "),
           key: type,
           onClick: this.toggleRequestFilterType,
--- a/devtools/client/netmonitor/src/middleware/prefs.js
+++ b/devtools/client/netmonitor/src/middleware/prefs.js
@@ -20,18 +20,17 @@ const {
   *   - a filter type has been set
   */
 function prefsMiddleware(store) {
   return next => action => {
     const res = next(action);
     switch (action.type) {
       case ENABLE_REQUEST_FILTER_TYPE_ONLY:
       case TOGGLE_REQUEST_FILTER_TYPE:
-        let filters = store.getState().filters.requestFilterTypes
-          .entrySeq().toArray()
+        let filters = Object.entries(store.getState().filters.requestFilterTypes)
           .filter(([type, check]) => check)
           .map(([type, check]) => type);
         Services.prefs.setCharPref(
           "devtools.netmonitor.filters", JSON.stringify(filters));
         break;
       case ENABLE_PERSISTENT_LOGS:
         Services.prefs.setBoolPref(
           "devtools.netmonitor.persistlog", store.getState().ui.persistentLogsEnabled);
--- a/devtools/client/netmonitor/src/reducers/filters.js
+++ b/devtools/client/netmonitor/src/reducers/filters.js
@@ -1,79 +1,93 @@
 /* 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 I = require("devtools/client/shared/vendor/immutable");
 const {
   ENABLE_REQUEST_FILTER_TYPE_ONLY,
   TOGGLE_REQUEST_FILTER_TYPE,
   SET_REQUEST_FILTER_TEXT,
   FILTER_TAGS
 } = require("../constants");
 
-const FilterTypes = I.Record(["all"]
-  .concat(FILTER_TAGS)
-  .reduce((o, tag) => Object.assign(o, { [tag]: false }), {})
-);
+function FilterTypes(overrideParams = {}) {
+  let allFilterTypes = ["all"].concat(FILTER_TAGS);
+  // filter only those keys which are valid filter tags
+  overrideParams = Object.keys(overrideParams)
+    .filter(key => allFilterTypes.includes(key))
+    .reduce((obj, key) => {
+      obj[key] = overrideParams[key];
+      return obj;
+    }, {});
+  let filterTypes = allFilterTypes
+    .reduce((o, tag) => Object.assign(o, { [tag]: false }), {});
+  return Object.assign({}, filterTypes, overrideParams);
+}
 
-const Filters = I.Record({
-  requestFilterTypes: new FilterTypes({ all: true }),
-  requestFilterText: "",
-});
+function Filters(overrideParams = {}) {
+  return Object.assign({
+    requestFilterTypes: new FilterTypes({ all: true }),
+    requestFilterText: "",
+  }, overrideParams);
+}
 
 function toggleRequestFilterType(state, action) {
   let { filter } = action;
   let newState;
 
   // Ignore unknown filter type
-  if (!state.has(filter)) {
+  if (!state.hasOwnProperty(filter)) {
     return state;
   }
   if (filter === "all") {
     return new FilterTypes({ all: true });
   }
 
-  newState = state.withMutations(types => {
-    types.set("all", false);
-    types.set(filter, !state.get(filter));
-  });
+  newState = { ...state };
+  newState.all = false;
+  newState[filter] = !state[filter];
 
-  if (!newState.includes(true)) {
+  if (!Object.values(newState).includes(true)) {
     newState = new FilterTypes({ all: true });
   }
 
   return newState;
 }
 
 function enableRequestFilterTypeOnly(state, action) {
   let { filter } = action;
 
   // Ignore unknown filter type
-  if (!state.has(filter)) {
+  if (!state.hasOwnProperty(filter)) {
     return state;
   }
 
   return new FilterTypes({ [filter]: true });
 }
 
 function filters(state = new Filters(), action) {
+  state = { ...state };
   switch (action.type) {
     case ENABLE_REQUEST_FILTER_TYPE_ONLY:
-      return state.set("requestFilterTypes",
-        enableRequestFilterTypeOnly(state.requestFilterTypes, action));
+      state.requestFilterTypes =
+        enableRequestFilterTypeOnly(state.requestFilterTypes, action);
+      break;
     case TOGGLE_REQUEST_FILTER_TYPE:
-      return state.set("requestFilterTypes",
-        toggleRequestFilterType(state.requestFilterTypes, action));
+      state.requestFilterTypes =
+        toggleRequestFilterType(state.requestFilterTypes, action);
+      break;
     case SET_REQUEST_FILTER_TEXT:
-      return state.set("requestFilterText", action.text);
+      state.requestFilterText = action.text;
+      break;
     default:
-      return state;
+      break;
   }
+  return state;
 }
 
 module.exports = {
   FilterTypes,
   Filters,
   filters
 };
--- a/devtools/client/netmonitor/src/selectors/requests.js
+++ b/devtools/client/netmonitor/src/selectors/requests.js
@@ -33,30 +33,29 @@ function sortWithClones(requests, sorter
   }
 
   return sorter(a, b);
 }
 
 const getFilterFn = createSelector(
   state => state.filters,
   filters => r => {
-    const matchesType = filters.requestFilterTypes.some((enabled, filter) => {
-      return enabled && Filters[filter] && Filters[filter](r);
+    const matchesType = Object.keys(filters.requestFilterTypes).some(filter => {
+      return filters.requestFilterTypes[filter] && Filters[filter] && Filters[filter](r);
     });
     return matchesType && isFreetextMatch(r, filters.requestFilterText);
   }
 );
 
 const getTypeFilterFn = createSelector(
   state => state.filters,
   filters => r => {
-    const matchesType = filters.requestFilterTypes.some((enabled, filter) => {
-      return enabled && Filters[filter] && Filters[filter](r);
+    return Object.keys(filters.requestFilterTypes).some(filter => {
+      return filters.requestFilterTypes[filter] && Filters[filter] && Filters[filter](r);
     });
-    return matchesType;
   }
 );
 
 const getSortFn = createSelector(
   state => state.requests,
   state => state.sort,
   ({ requests }, sort) => {
     const sorter = Sorters[sort.type || "waterfall"];
--- a/devtools/client/netmonitor/test/browser_net_prefs-reload.js
+++ b/devtools/client/netmonitor/test/browser_net_prefs-reload.js
@@ -27,18 +27,17 @@ add_task(function* () {
   let getState = () => getStore().getState();
 
   let prefsToCheck = {
     filters: {
       // A custom new value to be used for the verified preference.
       newValue: ["html", "css"],
       // Getter used to retrieve the current value from the frontend, in order
       // to verify that the pref was applied properly.
-      validateValue: () => getState().filters.requestFilterTypes
-        .entrySeq().toArray()
+      validateValue: () => Object.entries(getState().filters.requestFilterTypes)
         .filter(([type, check]) => check)
         .map(([type, check]) => type),
       // Predicate used to modify the frontend when setting the new pref value,
       // before trying to validate the changes.
       modifyFrontend: (value) => value.forEach(e =>
         getStore().dispatch(Actions.toggleRequestFilterType(e)))
     },
     networkDetailsWidth: {