Bug 1368022 - Remove autoscroll property from UI reducer; r=nchevobbe draft
authorJan Odvarko <odvarko@gmail.com>
Tue, 30 May 2017 17:03:34 +0200
changeset 586489 b2711c0b8f52a66da44aab1a94d1b26da9463699
parent 585803 4541134e973a6bd5e667a603e844854c8e5361da
child 631010 11f832da748a0830cc1c43452549268b49127d13
push id61430
push userjodvarko@mozilla.com
push dateTue, 30 May 2017 15:04:02 +0000
reviewersnchevobbe
bugs1368022
milestone55.0a1
Bug 1368022 - Remove autoscroll property from UI reducer; r=nchevobbe MozReview-Commit-ID: IwOvNrJjS1l
devtools/client/webconsole/new-console-output/components/console-output.js
devtools/client/webconsole/new-console-output/components/message-container.js
devtools/client/webconsole/new-console-output/components/message-types/console-command.js
devtools/client/webconsole/new-console-output/components/message-types/evaluation-result.js
devtools/client/webconsole/new-console-output/reducers/ui.js
devtools/client/webconsole/new-console-output/selectors/ui.js
--- a/devtools/client/webconsole/new-console-output/components/console-output.js
+++ b/devtools/client/webconsole/new-console-output/components/console-output.js
@@ -11,58 +11,55 @@ const {
 } = require("devtools/client/shared/vendor/react");
 const { connect } = require("devtools/client/shared/vendor/react-redux");
 
 const {
   getAllMessages,
   getAllMessagesUiById,
   getAllMessagesTableDataById,
 } = require("devtools/client/webconsole/new-console-output/selectors/messages");
-const { getScrollSetting } = require("devtools/client/webconsole/new-console-output/selectors/ui");
 const MessageContainer = createFactory(require("devtools/client/webconsole/new-console-output/components/message-container").MessageContainer);
 
 const ConsoleOutput = createClass({
 
   displayName: "ConsoleOutput",
 
   propTypes: {
     messages: PropTypes.object.isRequired,
     messagesUi: PropTypes.object.isRequired,
     serviceContainer: PropTypes.shape({
       attachRefToHud: PropTypes.func.isRequired,
       openContextMenu: PropTypes.func.isRequired,
       sourceMapService: PropTypes.object,
     }),
-    autoscroll: PropTypes.bool.isRequired,
     dispatch: PropTypes.func.isRequired,
     timestampsVisible: PropTypes.bool,
     messagesTableData: PropTypes.object.isRequired,
   },
 
   componentDidMount() {
     // Do the scrolling in the nextTick since this could hit console startup performances.
     // See https://bugzilla.mozilla.org/show_bug.cgi?id=1355869
     setTimeout(() => {
       scrollToBottom(this.outputNode);
     }, 0);
     this.props.serviceContainer.attachRefToHud("outputScroller", this.outputNode);
   },
 
   componentWillUpdate(nextProps, nextState) {
-    if (!this.outputNode) {
+    const outputNode = this.outputNode;
+    if (!outputNode || !outputNode.lastChild) {
       return;
     }
 
-    const outputNode = this.outputNode;
-
     // Figure out if we are at the bottom. If so, then any new message should be scrolled
     // into view.
-    if (this.props.autoscroll && outputNode.lastChild) {
-      this.shouldScrollBottom = isScrolledToBottom(outputNode.lastChild, outputNode);
-    }
+    const lastChild = outputNode.lastChild;
+    const delta = nextProps.messages.size - this.props.messages.size;
+    this.shouldScrollBottom = delta > 0 && isScrolledToBottom(lastChild, outputNode);
   },
 
   componentDidUpdate() {
     if (this.shouldScrollBottom) {
       scrollToBottom(this.outputNode);
     }
   },
 
@@ -70,34 +67,32 @@ const ConsoleOutput = createClass({
     this.props.serviceContainer.openContextMenu(e);
     e.stopPropagation();
     e.preventDefault();
   },
 
   render() {
     let {
       dispatch,
-      autoscroll,
       messages,
       messagesUi,
       messagesTableData,
       serviceContainer,
       timestampsVisible,
     } = this.props;
 
     let messageNodes = messages.map((message) => {
       return (
         MessageContainer({
           dispatch,
           message,
           key: message.id,
           serviceContainer,
           open: messagesUi.includes(message.id),
           tableData: messagesTableData.get(message.id),
-          autoscroll,
           indent: message.indent,
           timestampsVisible,
         })
       );
     });
 
     return (
       dom.div({
@@ -123,14 +118,13 @@ function isScrolledToBottom(outputNode, 
          scrollNode.scrollHeight - lastNodeHeight / 2;
 }
 
 function mapStateToProps(state, props) {
   return {
     messages: getAllMessages(state),
     messagesUi: getAllMessagesUiById(state),
     messagesTableData: getAllMessagesTableDataById(state),
-    autoscroll: getScrollSetting(state),
     timestampsVisible: state.ui.timestampsVisible,
   };
 }
 
 module.exports = connect(mapStateToProps)(ConsoleOutput);
--- a/devtools/client/webconsole/new-console-output/components/message-container.js
+++ b/devtools/client/webconsole/new-console-output/components/message-container.js
@@ -29,17 +29,16 @@ const componentMap = new Map([
 
 const MessageContainer = createClass({
   displayName: "MessageContainer",
 
   propTypes: {
     message: PropTypes.object.isRequired,
     open: PropTypes.bool.isRequired,
     serviceContainer: PropTypes.object.isRequired,
-    autoscroll: PropTypes.bool.isRequired,
     indent: PropTypes.number.isRequired,
     tableData: PropTypes.object,
     timestampsVisible: PropTypes.bool.isRequired,
   },
 
   getDefaultProps: function () {
     return {
       open: false,
--- a/devtools/client/webconsole/new-console-output/components/message-types/console-command.js
+++ b/devtools/client/webconsole/new-console-output/components/message-types/console-command.js
@@ -12,32 +12,30 @@ const {
   PropTypes
 } = require("devtools/client/shared/vendor/react");
 const Message = createFactory(require("devtools/client/webconsole/new-console-output/components/message"));
 
 ConsoleCommand.displayName = "ConsoleCommand";
 
 ConsoleCommand.propTypes = {
   message: PropTypes.object.isRequired,
-  autoscroll: PropTypes.bool.isRequired,
   indent: PropTypes.number.isRequired,
   timestampsVisible: PropTypes.bool.isRequired,
   serviceContainer: PropTypes.object,
 };
 
 ConsoleCommand.defaultProps = {
   indent: 0,
 };
 
 /**
  * Displays input from the console.
  */
 function ConsoleCommand(props) {
   const {
-    autoscroll,
     indent,
     message,
     timestampsVisible,
     serviceContainer,
   } = props;
 
   const {
     source,
@@ -47,16 +45,15 @@ function ConsoleCommand(props) {
   } = message;
 
   return Message({
     source,
     type,
     level,
     topLevelClasses: [],
     messageBody,
-    scrollToMessage: autoscroll,
     serviceContainer,
     indent,
     timestampsVisible,
   });
 }
 
 module.exports = ConsoleCommand;
--- a/devtools/client/webconsole/new-console-output/components/message-types/evaluation-result.js
+++ b/devtools/client/webconsole/new-console-output/components/message-types/evaluation-result.js
@@ -71,17 +71,16 @@ function EvaluationResult(props) {
   return Message({
     source,
     type,
     level,
     indent,
     topLevelClasses,
     messageBody,
     messageId,
-    scrollToMessage: props.autoscroll,
     serviceContainer,
     exceptionDocURL,
     frame,
     timeStamp,
     parameters,
     notes,
     timestampsVisible,
   });
--- a/devtools/client/webconsole/new-console-output/reducers/ui.js
+++ b/devtools/client/webconsole/new-console-output/reducers/ui.js
@@ -2,46 +2,32 @@
 /* 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 {
   FILTER_BAR_TOGGLE,
-  MESSAGE_ADD,
-  REMOVED_MESSAGES_CLEAR,
   TIMESTAMPS_TOGGLE
 } = require("devtools/client/webconsole/new-console-output/constants");
 const Immutable = require("devtools/client/shared/vendor/immutable");
 
 const UiState = Immutable.Record({
   filterBarVisible: false,
   filteredMessageVisible: false,
-  autoscroll: true,
   timestampsVisible: true,
 });
 
 function ui(state = new UiState(), action) {
-  // Autoscroll should be set for all action types. If the last action was not message
-  // add, then turn it off. This prevents us from scrolling after someone toggles a
-  // filter, or to the bottom of the attachment when an expandable message at the bottom
-  // of the list is expanded. It does depend on the MESSAGE_ADD action being the last in
-  // its batch, though.
-  // It also depends on REMOVED_MESSAGES_CLEAR action being sent after MESSAGE_ADD
-  // if number of messages reached the maximum limit.
-  let autoscroll = action.type == MESSAGE_ADD || action.type == REMOVED_MESSAGES_CLEAR;
-  state = state.set("autoscroll", autoscroll);
-
   switch (action.type) {
     case FILTER_BAR_TOGGLE:
       return state.set("filterBarVisible", !state.filterBarVisible);
     case TIMESTAMPS_TOGGLE:
       return state.set("timestampsVisible", action.visible);
-
   }
 
   return state;
 }
 
 module.exports = {
   UiState,
   ui,
--- a/devtools/client/webconsole/new-console-output/selectors/ui.js
+++ b/devtools/client/webconsole/new-console-output/selectors/ui.js
@@ -5,16 +5,11 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 function getAllUi(state) {
   return state.ui;
 }
 
-function getScrollSetting(state) {
-  return getAllUi(state).autoscroll;
-}
-
 module.exports = {
   getAllUi,
-  getScrollSetting,
 };