Bug 1358383 - [devtools] Adds a command history list. r=bomsy

Differential Revision: https://phabricator.services.mozilla.com/D122264
This commit is contained in:
Claudia 2021-09-02 15:22:19 +00:00
Родитель 3d1e69b292
Коммит cb89693561
12 изменённых файлов: 293 добавлений и 3 удалений

Просмотреть файл

@ -848,6 +848,50 @@ a.learn-more-link.webconsole-learn-more-link {
background-color: var(--table-zebra-background);
}
/* Simple Table */
.message .simple-table {
width: 100%;
border-collapse: collapse;
--simpletable-border: var(--theme-splitter-color);
margin-block-end: var(--attachment-margin-block-end);
color: var(--theme-body-color);
text-align: left;
max-height: 250px;
overflow-y: auto;
border: 1px solid var(--simpletable-border);
table-layout: fixed;
margin-top: 3px;
}
.simple-table-header {
background-color: var(--theme-toolbar-background);
text-overflow: ellipsis;
border-bottom: 1px solid var(--simpletable-border);
}
.simple-table-header > th {
padding: 5px 4px;
font-weight: inherit;
}
.simple-table-header > th:nth-child(odd) {
width: 10%;
}
.simple-table td {
padding: 3px 4px;
text-overflow: ellipsis;
border-left: 1px solid var(--simpletable-border);
}
.simple-table td:nth-child(2n) span {
color: var(--theme-body-color);
}
.simple-table tr:nth-child(even) {
background-color: var(--table-zebra-background);
}
/* Object Inspector */
.webconsole-app .object-inspector.tree {
display: inline-block;

Просмотреть файл

@ -49,6 +49,12 @@ loader.lazyRequireGetter(
"devtools/client/shared/screenshot",
true
);
loader.lazyRequireGetter(
this,
"createSimpleTableMessage",
"devtools/client/webconsole/utils/messages",
true
);
const HELP_URL = "https://developer.mozilla.org/docs/Tools/Web_Console/Helpers";
@ -168,7 +174,7 @@ function onExpressionEvaluated(response) {
function handleHelperResult(response) {
// eslint-disable-next-line complexity
return async ({ dispatch, hud, toolbox, webConsoleUI }) => {
return async ({ dispatch, hud, toolbox, webConsoleUI, getState }) => {
const { result, helperResult } = response;
const helperHasRawOutput = !!helperResult?.rawOutput;
const hasNetworkResourceCommandSupport = hud.resourceCommand.hasResourceCommandSupport(
@ -188,6 +194,25 @@ function handleHelperResult(response) {
case "clearHistory":
dispatch(historyActions.clearHistory());
break;
case "historyOutput":
const history = getState().history.entries || [];
const columns = new Map([
["_index", "(index)"],
["expression", "Expressions"],
]);
dispatch(
messagesActions.messagesAdd([
{
...createSimpleTableMessage(
columns,
history.map((expression, index) => {
return { _index: index, expression };
})
),
},
])
);
break;
case "inspectObject": {
const objectActor = helperResult.object;
if (hud.toolbox && !helperResult.forceExpandInConsole) {

Просмотреть файл

@ -52,6 +52,10 @@ const componentMap = new Map([
"PageError",
require("devtools/client/webconsole/components/Output/message-types/PageError"),
],
[
"SimpleTable",
require("devtools/client/webconsole/components/Output/message-types/SimpleTable"),
],
[
"WarningGroup",
require("devtools/client/webconsole/components/Output/message-types/WarningGroup"),
@ -136,6 +140,9 @@ function getMessageComponent(message) {
if (isWarningGroup(message)) {
return componentMap.get("WarningGroup");
}
if (message.type === MESSAGE_TYPE.SIMPLE_TABLE) {
return componentMap.get("SimpleTable");
}
break;
}

Просмотреть файл

@ -0,0 +1,131 @@
/* 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 { createFactory } = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories");
const GripMessageBody = createFactory(
require("devtools/client/webconsole/components/Output/GripMessageBody")
);
loader.lazyRequireGetter(
this,
"PropTypes",
"devtools/client/shared/vendor/react-prop-types"
);
loader.lazyGetter(this, "MODE", function() {
return require("devtools/client/shared/components/reps/index").MODE;
});
const Message = createFactory(
require("devtools/client/webconsole/components/Output/Message")
);
SimpleTable.displayName = "SimpleTable";
SimpleTable.propTypes = {
columns: PropTypes.object.isRequired,
items: PropTypes.array.isRequired,
dispatch: PropTypes.func.isRequired,
serviceContainer: PropTypes.object.isRequired,
};
function SimpleTable(props) {
const {
dispatch,
message,
serviceContainer,
timestampsVisible,
badge,
open,
} = props;
const {
source,
type,
level,
id: messageId,
indent,
timeStamp,
columns,
items,
} = message;
// if we don't have any data, don't show anything.
if (!items.length) {
return null;
}
const headerItems = [];
columns.forEach((value, key) =>
headerItems.push(
dom.th(
{
key,
title: value,
},
value
)
)
);
const rowItems = items.map((item, index) => {
const cells = [];
columns.forEach((_, key) => {
const cellValue = item[key];
const cellContent =
typeof cellValue === "undefined"
? ""
: GripMessageBody({
grip: cellValue,
mode: MODE.SHORT,
useQuotes: false,
serviceContainer,
dispatch,
});
cells.push(
dom.td(
{
key,
},
cellContent
)
);
});
return dom.tr({ key: index }, cells);
});
const attachment = dom.table(
{
className: "simple-table",
role: "grid",
},
dom.thead({}, dom.tr({ className: "simple-table-header" }, headerItems)),
dom.tbody({}, rowItems)
);
const topLevelClasses = ["cm-s-mozilla"];
return Message({
attachment,
badge,
dispatch,
indent,
level,
messageId,
open,
serviceContainer,
source,
timeStamp,
timestampsVisible,
topLevelClasses,
type,
message,
messageBody: [],
});
}
module.exports = SimpleTable;

Просмотреть файл

@ -11,5 +11,6 @@ DevToolsModules(
"EvaluationResult.js",
"NetworkEventMessage.js",
"PageError.js",
"SimpleTable.js",
"WarningGroup.js",
)

Просмотреть файл

@ -173,6 +173,7 @@ const chromeRDPEnums = {
// output anything (e.g. `console.time()` calls).
NULL_MESSAGE: "nullMessage",
NAVIGATION_MARKER: "navigationMarker",
SIMPLE_TABLE: "simpleTable",
},
MESSAGE_LEVEL: {
LOG: "log",

Просмотреть файл

@ -129,6 +129,7 @@ skip-if = !fission # context selector is only visible when fission is enabled.
[browser_jsterm_helper_keys_values.js]
[browser_jsterm_hide_when_devtools_chrome_enabled_false.js]
[browser_jsterm_history.js]
[browser_jsterm_history_command.js]
[browser_jsterm_history_arrow_keys.js]
[browser_jsterm_history_nav.js]
[browser_jsterm_history_persist.js]

Просмотреть файл

@ -18,7 +18,13 @@ add_task(async function() {
EventUtils.sendString(":");
await onAutocompleUpdated;
const expectedCommands = [":block", ":help", ":screenshot", ":unblock"];
const expectedCommands = [
":block",
":help",
":history",
":screenshot",
":unblock",
];
ok(
hasExactPopupLabels(autocompletePopup, expectedCommands),
"popup contains expected commands"

Просмотреть файл

@ -0,0 +1,43 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
// Tests if the command history shows a table with the content we expected.
"use strict";
const TEST_URI = "data:text/html;charset=UTF-8,test";
const COMMANDS = ["document", "window", "window.location"];
add_task(async function() {
const hud = await openNewTabAndConsole(TEST_URI);
const { jsterm } = hud;
jsterm.focus();
for (const command of COMMANDS) {
info(`Executing command ${command}`);
await executeAndWaitForMessage(hud, command, "", ".result");
}
info(`Executing command :history`);
await executeAndWaitForMessage(hud, ":history", "", ".simpleTable");
const historyTableRows = hud.ui.outputNode.querySelectorAll(
".message.simpleTable tbody tr"
);
const expectedCommands = [...COMMANDS, ":history"];
for (let i = 0; i < historyTableRows.length; i++) {
const cells = historyTableRows[i].querySelectorAll("td");
is(
cells[0].textContent,
String(i),
"Check the value of the column (index)"
);
is(
cells[1].textContent,
expectedCommands[i],
"Check if the value of the column Expressions is the value expected"
);
}
});

Просмотреть файл

@ -522,6 +522,18 @@ function createWarningGroupMessage(id, type, firstMessage) {
});
}
function createSimpleTableMessage(columns, items, timeStamp) {
return new ConsoleMessage({
allowRepeating: false,
level: MESSAGE_LEVEL.LOG,
source: MESSAGE_SOURCE.CONSOLE_FRONTEND,
type: MESSAGE_TYPE.SIMPLE_TABLE,
columns,
items,
timeStamp: timeStamp,
});
}
/**
* Given the a regular warning message, compute the label of the warning group the message
* could be in.
@ -778,6 +790,7 @@ function isMessageNetworkError(message) {
module.exports = {
createWarningGroupMessage,
createSimpleTableMessage,
getArrayTypeNames,
getDescriptorValue,
getInitialMessageCountForViewport,

Просмотреть файл

@ -4,7 +4,7 @@
"use strict";
const validCommands = ["block", "help", "screenshot", "unblock"];
const validCommands = ["block", "help", "history", "screenshot", "unblock"];
const COMMAND = "command";
const KEY = "key";

Просмотреть файл

@ -580,6 +580,24 @@ WebConsoleCommands._registerOriginal("screenshot", function(owner, args = {}) {
})();
});
/**
* Shows a history of commands and expressions previously executed within the command line.
*
* @param object args
* The arguments to be passed to the history
* @return void
*/
WebConsoleCommands._registerOriginal("history", function(owner, args = {}) {
owner.helperResult = (async () => {
// everything is handled on the client side, so we return a very simple object with
// the args
return {
type: "historyOutput",
args,
};
})();
});
/**
* Block specific resource from loading
*