summaryrefslogtreecommitdiffstats
path: root/devtools/client/webconsole/components/Output/message-types/ConsoleCommand.js
blob: 5cfb87113cef8bc65b6ab263577bd1a4883b3db6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/* 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";

// React & Redux
const {
  createElement,
  createFactory,
} = require("resource://devtools/client/shared/vendor/react.js");
const PropTypes = require("resource://devtools/client/shared/vendor/react-prop-types.js");
const { ELLIPSIS } = require("resource://devtools/shared/l10n.js");
const Message = createFactory(
  require("resource://devtools/client/webconsole/components/Output/Message.js")
);

ConsoleCommand.displayName = "ConsoleCommand";

ConsoleCommand.propTypes = {
  message: PropTypes.object.isRequired,
  timestampsVisible: PropTypes.bool.isRequired,
  serviceContainer: PropTypes.object,
  maybeScrollToBottom: PropTypes.func,
  open: PropTypes.bool,
};

ConsoleCommand.defaultProps = {
  open: false,
};

/**
 * Displays input from the console.
 */
function ConsoleCommand(props) {
  const {
    message,
    timestampsVisible,
    serviceContainer,
    maybeScrollToBottom,
    dispatch,
    open,
  } = props;

  const { indent, source, type, level, timeStamp, id: messageId } = message;

  const messageText = trimCode(message.messageText);
  const messageLines = messageText.split("\n");

  const collapsible = messageLines.length > 5;

  // Show only first 5 lines if its collapsible and closed
  const visibleMessageText =
    collapsible && !open
      ? `${messageLines.slice(0, 5).join("\n")}${ELLIPSIS}`
      : messageText;

  // This uses a Custom Element to syntax highlight when possible. If it's not
  // (no CodeMirror editor), then it will just render text.
  const messageBody = createElement(
    "syntax-highlighted",
    null,
    visibleMessageText
  );

  // Enable collapsing the code if it has multiple lines

  return Message({
    messageId,
    source,
    type,
    level,
    topLevelClasses: [],
    messageBody,
    collapsible,
    open,
    dispatch,
    serviceContainer,
    indent,
    timeStamp,
    timestampsVisible,
    maybeScrollToBottom,
    message,
  });
}

module.exports = ConsoleCommand;

/**
 * Trim user input to avoid blank lines before and after messages
 */
function trimCode(input) {
  if (typeof input !== "string") {
    return input;
  }

  // Trim on both edges if we have a single line of content
  if (input.trim().includes("\n") === false) {
    return input.trim();
  }

  // For multiline input we want to keep the indentation of the first line
  // with non-whitespace, so we can't .trim()/.trimStart().
  return input.replace(/^\s*\n/, "").trimEnd();
}