Bug 580400 - Console should display dividers to separate messages, r+a=dietrich

This commit is contained in:
Patrick Walton 2010-08-09 15:35:33 -03:00
Родитель 27de8f9a36
Коммит 1745134a5b
4 изменённых файлов: 132 добавлений и 27 удалений

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

@ -81,6 +81,10 @@ XPCOMUtils.defineLazyGetter(this, "stringBundle", function () {
return Services.strings.createBundle(HUD_STRINGS_URI);
});
// The amount of time in milliseconds that must pass between messages to
// trigger the display of a new group.
const NEW_GROUP_DELAY = 5000;
const ERRORS = { LOG_MESSAGE_MISSING_ARGS:
"Missing arguments: aMessage, aConsoleNode and aMessageNode are required.",
CANNOT_GET_HUD: "Cannot getHeads Up Display with provided ID",
@ -313,6 +317,8 @@ HUD_SERVICE.prototype =
while (outputNode.firstChild) {
outputNode.removeChild(outputNode.firstChild);
}
outputNode.lastTimestamp = 0;
},
/**
@ -689,23 +695,25 @@ HUD_SERVICE.prototype =
throw new Error(ERRORS.MISSING_ARGS);
}
let lastGroupNode = this.appendGroupIfNecessary(aConsoleNode,
aMessage.timestamp);
if (aFilterString) {
var filtered = this.filterLogMessage(aFilterString, aMessageNode);
if (filtered) {
// we have successfully filtered a message, we need to log it
aConsoleNode.appendChild(aMessageNode);
lastGroupNode.appendChild(aMessageNode);
aMessageNode.scrollIntoView(false);
}
else {
// we need to ignore this message by changing its css class - we are
// still logging this, it is just hidden
var hiddenMessage = ConsoleUtils.hideLogMessage(aMessageNode);
aConsoleNode.appendChild(hiddenMessage);
lastGroupNode.appendChild(hiddenMessage);
}
}
else {
// log everything
aConsoleNode.appendChild(aMessageNode);
lastGroupNode.appendChild(aMessageNode);
aMessageNode.scrollIntoView(false);
}
// store this message in the storage module:
@ -1196,6 +1204,51 @@ HUD_SERVICE.prototype =
}
},
/**
* Builds and appends a group to the console if enough time has passed since
* the last message.
*
* @param nsIDOMNode aConsoleNode
* The DOM node that holds the output of the console (NB: not the HUD
* node itself).
* @param number aTimestamp
* The timestamp of the newest message in milliseconds.
* @returns nsIDOMNode
* The group into which the next message should be written.
*/
appendGroupIfNecessary:
function HS_appendGroupIfNecessary(aConsoleNode, aTimestamp)
{
let hudBox = aConsoleNode;
while (hudBox != null && hudBox.getAttribute("class") !== "hud-box") {
hudBox = hudBox.parentNode;
}
let lastTimestamp = hudBox.lastTimestamp;
let delta = aTimestamp - lastTimestamp;
hudBox.lastTimestamp = aTimestamp;
if (delta < NEW_GROUP_DELAY) {
// No new group needed. Return the most recently-added group, if there is
// one.
let lastGroupNode = aConsoleNode.querySelector(".hud-group:last-child");
if (lastGroupNode != null) {
return lastGroupNode;
}
}
let chromeDocument = aConsoleNode.ownerDocument;
let groupNode = chromeDocument.createElement("vbox");
groupNode.setAttribute("class", "hud-group");
let separatorNode = chromeDocument.createElement("separator");
separatorNode.setAttribute("class", "groove hud-divider");
separatorNode.setAttribute("orient", "horizontal");
groupNode.appendChild(separatorNode);
aConsoleNode.appendChild(groupNode);
return groupNode;
},
/**
* update loadgroup when the window object is re-created
*
@ -1627,6 +1680,8 @@ function HeadsUpDisplay(aConfig)
let console = this.createConsole();
this.HUDBox.lastTimestamp = 0;
this.contentWindow.wrappedJSObject.console = console;
// create the JSTerm input element
@ -1836,6 +1891,8 @@ HeadsUpDisplay.prototype = {
consoleWrap.appendChild(this.outputNode);
outerWrap.appendChild(consoleWrap);
this.HUDBox.lastTimestamp = 0;
this.jsTermParentNode = outerWrap;
this.HUDBox.appendChild(outerWrap);
return this.HUDBox;
@ -2465,6 +2522,9 @@ JSTerm.prototype = {
*/
writeOutput: function JST_writeOutput(aOutputMessage, aIsInput)
{
let lastGroupNode = HUDService.appendGroupIfNecessary(this.outputNode,
Date.now());
var node = this.elementFactory("div");
if (aIsInput) {
node.setAttribute("class", "jsterm-input-line");
@ -2483,7 +2543,8 @@ JSTerm.prototype = {
var textNode = this.textFactory(aOutputMessage);
node.appendChild(textNode);
this.outputNode.appendChild(node);
lastGroupNode.appendChild(node);
node.scrollIntoView(false);
},
@ -2494,6 +2555,8 @@ JSTerm.prototype = {
while (outputNode.firstChild) {
outputNode.removeChild(outputNode.firstChild);
}
outputNode.lastTimestamp = 0;
},
keyDown: function JSTF_keyDown(aEvent)

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

@ -116,7 +116,8 @@ function introspectLogNodes() {
let count = outputNode.childNodes.length;
ok(count > 0, "LogCount: " + count);
let klasses = ["hud-msg-node hud-log",
let klasses = ["hud-group",
"hud-msg-node hud-log",
"hud-msg-node hud-warn",
"hud-msg-node hud-info",
"hud-msg-node hud-error",
@ -247,15 +248,15 @@ function testConsoleLoggingAPI(aMethod)
let HUD = HUDService.hudWeakReferences[hudId].get();
let jsterm = HUD.jsterm;
let outputLogNode = jsterm.outputNode;
ok(/foo bar/.test(outputLogNode.childNodes[0].childNodes[0].nodeValue),
let group = jsterm.outputNode.querySelector(".hud-group");
ok(/foo bar/.test(group.childNodes[1].childNodes[0].nodeValue),
"Emitted both console arguments");
}
function testLogEntry(aOutputNode, aMatchString, aSuccessErrObj)
{
var msgs = aOutputNode.childNodes;
for (var i = 0; i < msgs.length; i++) {
var msgs = aOutputNode.querySelector(".hud-group").childNodes;
for (var i = 1; i < msgs.length; i++) {
var message = msgs[i].innerHTML.indexOf(aMatchString);
if (message > -1) {
ok(true, aSuccessErrObj.success);
@ -299,18 +300,45 @@ function testOutputOrder()
jsterm.clearOutput();
jsterm.execute("console.log('foo', 'bar');");
is(outputNode.childNodes.length, 3, "Three children in output");
let outputChildren = outputNode.childNodes;
let group = outputNode.querySelector(".hud-group");
is(group.childNodes.length, 4, "Four children in output");
let outputChildren = group.childNodes;
let executedStringFirst =
/console\.log\('foo', 'bar'\);/.test(outputChildren[0].childNodes[0].nodeValue);
/console\.log\('foo', 'bar'\);/.test(outputChildren[1].childNodes[0].nodeValue);
let outputSecond =
/foo bar/.test(outputChildren[1].childNodes[0].nodeValue);
/foo bar/.test(outputChildren[2].childNodes[0].nodeValue);
ok(executedStringFirst && outputSecond, "executed string comes first");
}
function testGroups()
{
let HUD = HUDService.hudWeakReferences[hudId].get();
let jsterm = HUD.jsterm;
let outputNode = jsterm.outputNode;
jsterm.clearOutput();
let timestamp0 = Date.now();
jsterm.execute("0");
is(outputNode.querySelectorAll(".hud-group").length, 1,
"one group exists after the first console message");
jsterm.execute("1");
let timestamp1 = Date.now();
if (timestamp1 - timestamp0 < 5000) {
is(outputNode.querySelectorAll(".hud-group").length, 1,
"only one group still exists after the second console message");
}
HUD.HUDBox.lastTimestamp = 0; // a "far past" value
jsterm.execute("2");
is(outputNode.querySelectorAll(".hud-group").length, 2,
"two groups exist after the third console message");
}
function testNullUndefinedOutput()
{
let HUD = HUDService.hudWeakReferences[hudId].get();
@ -320,19 +348,21 @@ function testNullUndefinedOutput()
jsterm.clearOutput();
jsterm.execute("null;");
is(outputNode.childNodes.length, 2, "Two children in output");
let outputChildren = outputNode.childNodes;
let group = outputNode.querySelector(".hud-group");
is(group.childNodes.length, 3, "Three children in output");
let outputChildren = group.childNodes;
is (outputChildren[1].childNodes[0].nodeValue, "null",
is (outputChildren[2].childNodes[0].nodeValue, "null",
"'null' printed to output");
jsterm.clearOutput();
jsterm.execute("undefined;");
is(outputNode.childNodes.length, 2, "Two children in output");
outputChildren = outputNode.childNodes;
group = outputNode.querySelector(".hud-group");
is(group.childNodes.length, 3, "Three children in output");
outputChildren = group.childNodes;
is (outputChildren[1].childNodes[0].nodeValue, "undefined",
is (outputChildren[2].childNodes[0].nodeValue, "undefined",
"'undefined' printed to output");
}
@ -342,14 +372,15 @@ function testJSInputAndOutputStyling() {
jsterm.clearOutput();
jsterm.execute("2 + 2");
let outputChildren = jsterm.outputNode.childNodes;
let jsInputNode = outputChildren[0];
let group = jsterm.outputNode.querySelector(".hud-group");
let outputChildren = group.childNodes;
let jsInputNode = outputChildren[1];
isnot(jsInputNode.childNodes[0].nodeValue.indexOf("2 + 2"), -1,
"JS input node contains '2 + 2'");
isnot(jsInputNode.getAttribute("class").indexOf("jsterm-input-line"), -1,
"JS input node is of the CSS class 'jsterm-input-line'");
let jsOutputNode = outputChildren[1];
let jsOutputNode = outputChildren[2];
isnot(jsOutputNode.childNodes[0].nodeValue.indexOf("4"), -1,
"JS output node contains '4'");
isnot(jsOutputNode.getAttribute("class").indexOf("jsterm-output-line"), -1,
@ -544,18 +575,19 @@ function testExecutionScope()
let HUD = HUDService.hudWeakReferences[hudId].get();
let jsterm = HUD.jsterm;
let outputNode = jsterm.outputNode;
jsterm.clearOutput();
jsterm.execute("location;");
is(outputNode.childNodes.length, 2, "Two children in output");
let outputChildren = outputNode.childNodes;
let group = jsterm.outputNode.querySelector(".hud-group");
is(/location;/.test(outputChildren[0].childNodes[0].nodeValue), true,
is(group.childNodes.length, 3, "Three children in output");
let outputChildren = group.childNodes;
is(/location;/.test(outputChildren[1].childNodes[0].nodeValue), true,
"'location;' written to output");
isnot(outputChildren[1].childNodes[0].nodeValue.indexOf(TEST_URI), -1,
isnot(outputChildren[2].childNodes[0].nodeValue.indexOf(TEST_URI), -1,
"command was executed in the window scope");
}
@ -717,6 +749,7 @@ function test() {
testIteration();
testConsoleHistory();
testOutputOrder();
testGroups();
testNullUndefinedOutput();
testJSInputAndOutputStyling();
testExecutionScope();

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

@ -108,6 +108,10 @@
width: 100%;
}
.hud-group:first-child .hud-divider {
display: none;
}
/* JSTerm Styles */
.jsterm-wrapper-node {

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

@ -20,6 +20,7 @@
*
* Contributor(s):
* David Dahl <ddahl@mozilla.com>
* Patrick Walton <pcwalton@mozilla.com>
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -104,6 +105,10 @@
width: 100%;
}
.hud-group:first-child .hud-divider {
display: none;
}
/* JSTerm Styles */
.jsterm-wrapper-node {