summaryrefslogtreecommitdiffstats
path: root/devtools/client/webconsole/new-console-output/components/console-output.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/client/webconsole/new-console-output/components/console-output.js')
-rw-r--r--devtools/client/webconsole/new-console-output/components/console-output.js125
1 files changed, 125 insertions, 0 deletions
diff --git a/devtools/client/webconsole/new-console-output/components/console-output.js b/devtools/client/webconsole/new-console-output/components/console-output.js
new file mode 100644
index 000000000..1ba7f8dda
--- /dev/null
+++ b/devtools/client/webconsole/new-console-output/components/console-output.js
@@ -0,0 +1,125 @@
+/* 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 {
+ createClass,
+ createFactory,
+ DOM: dom,
+ PropTypes
+} = require("devtools/client/shared/vendor/react");
+const ReactDOM = require("devtools/client/shared/vendor/react-dom");
+const { connect } = require("devtools/client/shared/vendor/react-redux");
+
+const {
+ getAllMessages,
+ getAllMessagesUiById,
+ getAllMessagesTableDataById,
+ getAllGroupsById,
+} = 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,
+ }),
+ autoscroll: PropTypes.bool.isRequired,
+ },
+
+ componentDidMount() {
+ scrollToBottom(this.outputNode);
+ this.props.serviceContainer.attachRefToHud("outputScroller", this.outputNode);
+ },
+
+ componentWillUpdate(nextProps, nextState) {
+ if (!this.outputNode) {
+ 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);
+ }
+ },
+
+ componentDidUpdate() {
+ if (this.shouldScrollBottom) {
+ scrollToBottom(this.outputNode);
+ }
+ },
+
+ render() {
+ let {
+ dispatch,
+ autoscroll,
+ messages,
+ messagesUi,
+ messagesTableData,
+ serviceContainer,
+ groups,
+ } = this.props;
+
+ let messageNodes = messages.map((message) => {
+ const parentGroups = message.groupId ? (
+ (groups.get(message.groupId) || [])
+ .concat([message.groupId])
+ ) : [];
+
+ return (
+ MessageContainer({
+ dispatch,
+ message,
+ key: message.id,
+ serviceContainer,
+ open: messagesUi.includes(message.id),
+ tableData: messagesTableData.get(message.id),
+ autoscroll,
+ indent: parentGroups.length,
+ })
+ );
+ });
+ return (
+ dom.div({
+ className: "webconsole-output",
+ ref: node => {
+ this.outputNode = node;
+ },
+ }, messageNodes
+ )
+ );
+ }
+});
+
+function scrollToBottom(node) {
+ node.scrollTop = node.scrollHeight;
+}
+
+function isScrolledToBottom(outputNode, scrollNode) {
+ let lastNodeHeight = outputNode.lastChild ?
+ outputNode.lastChild.clientHeight : 0;
+ return scrollNode.scrollTop + scrollNode.clientHeight >=
+ scrollNode.scrollHeight - lastNodeHeight / 2;
+}
+
+function mapStateToProps(state, props) {
+ return {
+ messages: getAllMessages(state),
+ messagesUi: getAllMessagesUiById(state),
+ messagesTableData: getAllMessagesTableDataById(state),
+ autoscroll: getScrollSetting(state),
+ groups: getAllGroupsById(state),
+ };
+}
+
+module.exports = connect(mapStateToProps)(ConsoleOutput);