Backed out changeset 634b361b1b9d (bug 1364150) for scroll position failures in devtools' browser_webconsole_keyboard_accessibility.js. r=backout
authorSebastian Hengst <archaeopteryx@coole-files.de>
Thu, 08 Jun 2017 20:40:08 +0200
changeset 413531 a3f4e0c311543afe8fb094bad0460befb679e235
parent 413530 1961976dc596ea0ce5c712ab26b011dd72df22b5
child 413532 e4606d8c6c6c010e0be3a4ab6cf20ba4dbfdde70
push id1490
push usermtabara@mozilla.com
push dateMon, 31 Jul 2017 14:08:16 +0000
treeherdermozilla-release@70e32e6bf15e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbackout
bugs1364150
milestone55.0a1
backs out634b361b1b9db2b26d64a5944c7ebaa88fd5991a
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
Backed out changeset 634b361b1b9d (bug 1364150) for scroll position failures in devtools' browser_webconsole_keyboard_accessibility.js. r=backout
devtools/client/shared/redux/middleware/debounce.js
devtools/client/shared/redux/middleware/moz.build
devtools/client/webconsole/new-console-output/actions/enhancers.js
devtools/client/webconsole/new-console-output/actions/index.js
devtools/client/webconsole/new-console-output/actions/messages.js
devtools/client/webconsole/new-console-output/actions/moz.build
devtools/client/webconsole/new-console-output/new-console-output-wrapper.js
devtools/client/webconsole/new-console-output/store.js
devtools/client/webconsole/new-console-output/test/helpers.js
devtools/client/webconsole/webpack.config.js
deleted file mode 100644
--- a/devtools/client/shared/redux/middleware/debounce.js
+++ /dev/null
@@ -1,84 +0,0 @@
-/* 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";
-
-/**
- * Redux middleware for debouncing actions.
- *
- * Schedules actions with { meta: { debounce: true } } to be delayed
- * by wait milliseconds. If another action is fired during this
- * time-frame both actions are inserted into a queue and delayed.
- * Maximum delay is defined by maxWait argument.
- *
- * Handling more actions at once results in better performance since
- * components need to be re-rendered less often.
- *
- * @param string wait Wait for specified amount of milliseconds
- *                    before executing an action. The time is used
- *                    to collect more actions and handle them all
- *                    at once.
- * @param string maxWait Max waiting time. It's used in case of
- *                       a long stream of actions.
- */
-function debounceActions(wait, maxWait) {
-  let queuedActions = [];
-
-  return store => next => {
-    let debounced = debounce(() => {
-      next(batchActions(queuedActions));
-      queuedActions = [];
-    }, wait, maxWait);
-
-    return action => {
-      if (!action.meta || !action.meta.debounce) {
-        return next(action);
-      }
-
-      if (action.type == BATCH_ACTIONS) {
-        queuedActions.push(...action.actions);
-      } else {
-        queuedActions.push(action);
-      }
-
-      return debounced();
-    };
-  };
-}
-
-function debounce(cb, wait, maxWait) {
-  let timeout, maxTimeout;
-  let doFunction = () => {
-    clearTimeout(timeout);
-    clearTimeout(maxTimeout);
-    timeout = maxTimeout = null;
-    cb();
-  };
-
-  return () => {
-    clearTimeout(timeout);
-    timeout = setTimeout(doFunction, wait);
-    if (!maxTimeout) {
-      maxTimeout = setTimeout(doFunction, maxWait);
-    }
-  };
-}
-
-const BATCH_ACTIONS = Symbol("BATCH_ACTIONS");
-
-/**
- * Action creator for action-batching.
- */
-function batchActions(batchedActions, debounceFlag = true) {
-  return {
-    type: BATCH_ACTIONS,
-    meta: { debounce: debounceFlag },
-    actions: batchedActions,
-  };
-}
-
-module.exports = {
-  BATCH_ACTIONS,
-  batchActions,
-  debounceActions,
-};
--- a/devtools/client/shared/redux/middleware/moz.build
+++ b/devtools/client/shared/redux/middleware/moz.build
@@ -1,16 +1,15 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 DevToolsModules(
-    'debounce.js',
     'history.js',
     'log.js',
     'promise.js',
     'task.js',
     'thunk.js',
     'wait-service.js',
 )
 
new file mode 100644
--- /dev/null
+++ b/devtools/client/webconsole/new-console-output/actions/enhancers.js
@@ -0,0 +1,20 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
+/* 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 { BATCH_ACTIONS } = require("../constants");
+
+function batchActions(batchedActions) {
+  return {
+    type: BATCH_ACTIONS,
+    actions: batchedActions,
+  };
+}
+
+module.exports = {
+  batchActions
+};
--- a/devtools/client/webconsole/new-console-output/actions/index.js
+++ b/devtools/client/webconsole/new-console-output/actions/index.js
@@ -2,16 +2,17 @@
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* 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 actionModules = [
+  require("./enhancers"),
   require("./filters"),
   require("./messages"),
   require("./ui"),
 ];
 
 const actions = Object.assign({}, ...actionModules);
 
 module.exports = actions;
--- a/devtools/client/webconsole/new-console-output/actions/messages.js
+++ b/devtools/client/webconsole/new-console-output/actions/messages.js
@@ -5,17 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 const {
   prepareMessage
 } = require("devtools/client/webconsole/new-console-output/utils/messages");
 const { IdGenerator } = require("devtools/client/webconsole/new-console-output/utils/id-generator");
-const { batchActions } = require("devtools/client/shared/redux/middleware/debounce");
+const { batchActions } = require("devtools/client/webconsole/new-console-output/actions/enhancers");
 const {
   MESSAGE_ADD,
   NETWORK_MESSAGE_UPDATE,
   MESSAGES_CLEAR,
   MESSAGE_OPEN,
   MESSAGE_CLOSE,
   MESSAGE_TYPE,
   MESSAGE_TABLE_RECEIVE,
@@ -25,17 +25,16 @@ const defaultIdGenerator = new IdGenerat
 
 function messageAdd(packet, idGenerator = null) {
   if (idGenerator == null) {
     idGenerator = defaultIdGenerator;
   }
   let message = prepareMessage(packet, idGenerator);
   const addMessageAction = {
     type: MESSAGE_ADD,
-    meta: { debounce: true },
     message
   };
 
   if (message.type === MESSAGE_TYPE.CLEAR) {
     return batchActions([
       messagesClear(),
       addMessageAction,
     ]);
@@ -96,17 +95,16 @@ function networkMessageUpdate(packet, id
   if (idGenerator == null) {
     idGenerator = defaultIdGenerator;
   }
 
   let message = prepareMessage(packet, idGenerator);
 
   return {
     type: NETWORK_MESSAGE_UPDATE,
-    meta: { debounce: true },
     message,
   };
 }
 
 module.exports = {
   messageAdd,
   messagesClear,
   messageOpen,
--- a/devtools/client/webconsole/new-console-output/actions/moz.build
+++ b/devtools/client/webconsole/new-console-output/actions/moz.build
@@ -1,11 +1,12 @@
 # vim: set filetype=python:
 # 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/.
 
 DevToolsModules(
+    'enhancers.js',
     'filters.js',
     'index.js',
     'messages.js',
     'ui.js',
 )
--- a/devtools/client/webconsole/new-console-output/new-console-output-wrapper.js
+++ b/devtools/client/webconsole/new-console-output/new-console-output-wrapper.js
@@ -6,23 +6,24 @@
 // React & Redux
 const React = require("devtools/client/shared/vendor/react");
 const ReactDOM = require("devtools/client/shared/vendor/react-dom");
 const { Provider } = require("devtools/client/shared/vendor/react-redux");
 
 const actions = require("devtools/client/webconsole/new-console-output/actions/index");
 const { createContextMenu } = require("devtools/client/webconsole/new-console-output/utils/context-menu");
 const { configureStore } = require("devtools/client/webconsole/new-console-output/store");
-const { batchActions } = require("devtools/client/shared/redux/middleware/debounce");
 
 const EventEmitter = require("devtools/shared/event-emitter");
 const ConsoleOutput = React.createFactory(require("devtools/client/webconsole/new-console-output/components/console-output"));
 const FilterBar = React.createFactory(require("devtools/client/webconsole/new-console-output/components/filter-bar"));
 
 let store = null;
+let queuedActions = [];
+let throttledDispatchTimeout = false;
 
 function NewConsoleOutputWrapper(parentNode, jsterm, toolbox, owner, document) {
   EventEmitter.decorate(this);
 
   this.parentNode = parentNode;
   this.jsterm = jsterm;
   this.toolbox = toolbox;
   this.owner = owner;
@@ -139,17 +140,17 @@ NewConsoleOutputWrapper.prototype = {
         childComponent
     ));
 
     this.body = ReactDOM.render(provider, this.parentNode);
   },
 
   dispatchMessageAdd: function (message, waitForResponse) {
     let action = actions.messageAdd(message);
-    store.dispatch(action);
+    batchedMessageAdd(action);
 
     // Wait for the message to render to resolve with the DOM node.
     // This is just for backwards compatibility with old tests, and should
     // be removed once it's not needed anymore.
     // Can only wait for response if the action contains a valid message.
     if (waitForResponse && action.message) {
       let messageId = action.message.get("id");
       return new Promise(resolve => {
@@ -166,36 +167,47 @@ NewConsoleOutputWrapper.prototype = {
       });
     }
 
     return Promise.resolve();
   },
 
   dispatchMessagesAdd: function (messages) {
     const batchedActions = messages.map(message => actions.messageAdd(message));
-    store.dispatch(batchActions(batchedActions));
+    store.dispatch(actions.batchActions(batchedActions));
   },
 
   dispatchMessagesClear: function () {
     store.dispatch(actions.messagesClear());
   },
 
   dispatchTimestampsToggle: function (enabled) {
     store.dispatch(actions.timestampsToggle(enabled));
   },
 
   dispatchMessageUpdate: function (message, res) {
     // network-message-updated will emit when eventTimings message arrives
     // which is the last one of 8 updates happening on network message update.
     if (res.packet.updateType === "eventTimings") {
-      store.dispatch(actions.networkMessageUpdate(message));
+      batchedMessageAdd(actions.networkMessageUpdate(message));
       this.jsterm.hud.emit("network-message-updated", res);
     }
   },
 
   // Should be used for test purpose only.
   getStore: function () {
     return store;
   }
 };
 
+function batchedMessageAdd(action) {
+  queuedActions.push(action);
+  if (!throttledDispatchTimeout) {
+    throttledDispatchTimeout = setTimeout(() => {
+      store.dispatch(actions.batchActions(queuedActions));
+      queuedActions = [];
+      throttledDispatchTimeout = null;
+    }, 50);
+  }
+}
+
 // Exports from this module
 module.exports = NewConsoleOutputWrapper;
--- a/devtools/client/webconsole/new-console-output/store.js
+++ b/devtools/client/webconsole/new-console-output/store.js
@@ -8,23 +8,20 @@ const {PrefState} = require("devtools/cl
 const {UiState} = require("devtools/client/webconsole/new-console-output/reducers/ui");
 const {
   applyMiddleware,
   compose,
   createStore
 } = require("devtools/client/shared/vendor/redux");
 const { thunk } = require("devtools/client/shared/redux/middleware/thunk");
 const {
-  debounceActions,
-  BATCH_ACTIONS
-} = require("devtools/client/shared/redux/middleware/debounce");
-const {
   MESSAGE_ADD,
   MESSAGES_CLEAR,
   REMOVED_MESSAGES_CLEAR,
+  BATCH_ACTIONS,
   PREFS,
 } = require("devtools/client/webconsole/new-console-output/constants");
 const { reducers } = require("./reducers/index");
 const Services = require("Services");
 
 function configureStore(hud, options = {}) {
   const logLimit = options.logLimit
     || Math.max(Services.prefs.getIntPref("devtools.hud.loglimit"), 1);
@@ -41,26 +38,20 @@ function configureStore(hud, options = {
       net: Services.prefs.getBoolPref(PREFS.FILTER.NET),
       netxhr: Services.prefs.getBoolPref(PREFS.FILTER.NETXHR),
     }),
     ui: new UiState({
       filterBarVisible: Services.prefs.getBoolPref(PREFS.UI.FILTER_BAR),
     })
   };
 
-  let args = [thunk];
-  if (!options.noDebounce) {
-    args.push(debounceActions(16, 500));
-  }
-
-  let middleware = applyMiddleware(...args);
   return createStore(
     createRootReducer(),
     initialState,
-    compose(middleware, enableActorReleaser(hud), enableBatching())
+    compose(applyMiddleware(thunk), enableActorReleaser(hud), enableBatching())
   );
 }
 
 function createRootReducer() {
   return function rootReducer(state, action) {
     // We want to compute the new state for all properties except "messages".
     const newState = [...Object.entries(reducers)].reduce((res, [key, reducer]) => {
       if (key !== "messages") {
--- a/devtools/client/webconsole/new-console-output/test/helpers.js
+++ b/devtools/client/webconsole/new-console-output/test/helpers.js
@@ -29,21 +29,17 @@ function setupActions() {
   };
 
   return wrappedActions;
 }
 
 /**
  * Prepare the store for use in testing.
  */
-function setupStore(input, hud, options = {}) {
-  // Disable debouncing for tests. It makes tests simpler
-  // if actions are dispatched and handled synchronously.
-  options.noDebounce = true;
-
+function setupStore(input, hud, options) {
   const store = configureStore(hud, options);
 
   // Add the messages from the input commands to the store.
   input.forEach((cmd) => {
     store.dispatch(actions.messageAdd(stubPackets.get(cmd)));
   });
 
   return store;
--- a/devtools/client/webconsole/webpack.config.js
+++ b/devtools/client/webconsole/webpack.config.js
@@ -65,17 +65,16 @@ webpackConfig.resolve = {
     "devtools/shared/l10n": path.join(__dirname, "../../shared/l10n"),
 
     "devtools/client/framework/devtools": path.join(__dirname, "../../client/shims/devtools"),
     "devtools/client/framework/menu": "devtools-modules/client/framework/menu",
     "devtools/client/framework/menu-item": path.join(__dirname, "../../client/framework/menu-item"),
 
     "devtools/client/shared/components/reps/reps": path.join(__dirname, "../../client/shared/components/reps/reps"),
     "devtools/client/shared/redux/middleware/thunk": path.join(__dirname, "../../client/shared/redux/middleware/thunk"),
-    "devtools/client/shared/redux/middleware/debounce": path.join(__dirname, "../../client/shared/redux/middleware/debounce"),
     "devtools/client/shared/components/stack-trace": path.join(__dirname, "../../client/shared/components/stack-trace"),
     "devtools/client/shared/source-utils": path.join(__dirname, "../../client/shared/source-utils"),
     "devtools/client/shared/components/frame": path.join(__dirname, "../../client/shared/components/frame"),
 
     "devtools/shared/defer": path.join(__dirname, "../../shared/defer"),
     "devtools/shared/event-emitter": "devtools-modules/shared/event-emitter",
     "devtools/shared/client/main": path.join(__dirname, "new-console-output/test/fixtures/ObjectClient"),
     "devtools/shared/platform/clipboard": path.join(__dirname, "../../shared/platform/content/clipboard"),