Backed out changeset 634b361b1b9d (bug 1364150) for scroll position failures in devtools' browser_webconsole_keyboard_accessibility.js. r=backout a=merge
authorSebastian Hengst <archaeopteryx@coole-files.de>
Thu, 08 Jun 2017 20:40:08 +0200
changeset 413484 f4262773c4331d4ae139be536ce278ea9aad3436
parent 413483 1fe323870581b963b970822efd1497cc186f3d4e
child 413589 6f8f19201f7e7fa655091fc6fe6b3395869e927b
child 413626 85f387a3a99b932d1fa0e1306f1e2bfe318c3666
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, merge
bugs1364150
milestone55.0a1
backs out634b361b1b9db2b26d64a5944c7ebaa88fd5991a
first release with
nightly linux32
f4262773c433 / 55.0a1 / 20170609100251 / files
nightly linux64
f4262773c433 / 55.0a1 / 20170609100251 / files
nightly mac
f4262773c433 / 55.0a1 / 20170609030207 / files
nightly win32
f4262773c433 / 55.0a1 / 20170609030207 / files
nightly win64
f4262773c433 / 55.0a1 / 20170609030207 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
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 a=merge MozReview-Commit-ID: KjkF0dbDrWa
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"),