зеркало из https://github.com/mozilla/gecko-dev.git
Bug 659907 - Expand console object with a dir method that displays an interactive listing of all the properties of an object.; f=rcampbell r=mihai.sucan,bzbarsky sr=bzbarsky
This commit is contained in:
Родитель
4ff31f730a
Коммит
ce5fb346f7
|
@ -158,6 +158,7 @@ const LEVELS = {
|
|||
info: SEVERITY_INFO,
|
||||
log: SEVERITY_LOG,
|
||||
trace: SEVERITY_LOG,
|
||||
dir: SEVERITY_LOG
|
||||
};
|
||||
|
||||
// The lowest HTTP response code (inclusive) that is considered an error.
|
||||
|
@ -1235,6 +1236,10 @@ function pruneConsoleOutputIfNecessary(aHUDId, aCategory)
|
|||
}
|
||||
delete hudRef.cssNodes[desc + location];
|
||||
}
|
||||
else if (messageNodes[i].classList.contains("webconsole-msg-inspector")) {
|
||||
hudRef.pruneConsoleDirNode(messageNodes[i]);
|
||||
continue;
|
||||
}
|
||||
messageNodes[i].parentNode.removeChild(messageNodes[i]);
|
||||
}
|
||||
|
||||
|
@ -1969,6 +1974,13 @@ HUD_SERVICE.prototype =
|
|||
clipboardText = clipboardText.trimRight();
|
||||
break;
|
||||
|
||||
case "dir":
|
||||
body = unwrap(args[0]);
|
||||
clipboardText = body.toString();
|
||||
sourceURL = aMessage.filename;
|
||||
sourceLine = aMessage.lineNumber;
|
||||
break;
|
||||
|
||||
default:
|
||||
Cu.reportError("Unknown Console API log level: " + level);
|
||||
return;
|
||||
|
@ -1980,7 +1992,8 @@ HUD_SERVICE.prototype =
|
|||
body,
|
||||
sourceURL,
|
||||
sourceLine,
|
||||
clipboardText);
|
||||
clipboardText,
|
||||
level);
|
||||
|
||||
// Make the node bring up the property panel, to allow the user to inspect
|
||||
// the stack trace.
|
||||
|
@ -2014,6 +2027,14 @@ HUD_SERVICE.prototype =
|
|||
}
|
||||
|
||||
ConsoleUtils.outputMessageNode(node, aHUDId);
|
||||
|
||||
if (level == "dir") {
|
||||
// Initialize the inspector message node, by setting the PropertyTreeView
|
||||
// object on the tree view. This has to be done *after* the node is
|
||||
// shown, because the tree binding must be attached first.
|
||||
let tree = node.querySelector("tree");
|
||||
tree.view = node.propertyTreeView;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -3786,6 +3807,24 @@ HeadsUpDisplay.prototype = {
|
|||
aToolbar.appendChild(clearButton);
|
||||
},
|
||||
|
||||
/**
|
||||
* Destroy the property inspector message node. This performs the necessary
|
||||
* cleanup for the tree widget and removes it from the DOM.
|
||||
*
|
||||
* @param nsIDOMNode aMessageNode
|
||||
* The message node that contains the property inspector from a
|
||||
* console.dir call.
|
||||
*/
|
||||
pruneConsoleDirNode: function HUD_pruneConsoleDirNode(aMessageNode)
|
||||
{
|
||||
aMessageNode.parentNode.removeChild(aMessageNode);
|
||||
let tree = aMessageNode.querySelector("tree");
|
||||
tree.parentNode.removeChild(tree);
|
||||
aMessageNode.propertyTreeView = null;
|
||||
tree.view = null;
|
||||
tree = null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Create the Web Console UI.
|
||||
*
|
||||
|
@ -4794,8 +4833,15 @@ JSTerm.prototype = {
|
|||
let hud = HUDService.getHudReferenceById(this.hudId);
|
||||
hud.cssNodes = {};
|
||||
|
||||
while (hud.outputNode.firstChild) {
|
||||
hud.outputNode.removeChild(hud.outputNode.firstChild);
|
||||
let node = hud.outputNode;
|
||||
while (node.firstChild) {
|
||||
if (node.firstChild.classList &&
|
||||
node.firstChild.classList.contains("webconsole-msg-inspector")) {
|
||||
hud.pruneConsoleDirNode(node.firstChild);
|
||||
}
|
||||
else {
|
||||
hud.outputNode.removeChild(node.firstChild);
|
||||
}
|
||||
}
|
||||
|
||||
hud.HUDBox.lastTimestamp = 0;
|
||||
|
@ -5400,6 +5446,8 @@ ConsoleUtils = {
|
|||
* The text that should be copied to the clipboard when this node is
|
||||
* copied. If omitted, defaults to the body text. If `aBody` is not
|
||||
* a string, then the clipboard text must be supplied.
|
||||
* @param number aLevel [optional]
|
||||
* The level of the console API message.
|
||||
* @return nsIDOMNode
|
||||
* The message node: a XUL richlistitem ready to be inserted into
|
||||
* the Web Console output node.
|
||||
|
@ -5407,7 +5455,7 @@ ConsoleUtils = {
|
|||
createMessageNode:
|
||||
function ConsoleUtils_createMessageNode(aDocument, aCategory, aSeverity,
|
||||
aBody, aSourceURL, aSourceLine,
|
||||
aClipboardText) {
|
||||
aClipboardText, aLevel) {
|
||||
if (aBody instanceof Ci.nsIDOMNode && aClipboardText == null) {
|
||||
throw new Error("HUDService.createMessageNode(): DOM node supplied " +
|
||||
"without any clipboard text");
|
||||
|
@ -5435,12 +5483,15 @@ ConsoleUtils = {
|
|||
bodyNode.setAttribute("flex", "1");
|
||||
bodyNode.classList.add("webconsole-msg-body");
|
||||
|
||||
// Store the body text, since it is needed later for the property tree
|
||||
// case.
|
||||
let body = aBody;
|
||||
// If a string was supplied for the body, turn it into a DOM node and an
|
||||
// associated clipboard string now.
|
||||
aClipboardText = aClipboardText ||
|
||||
(aBody + (aSourceURL ? " @ " + aSourceURL : "") +
|
||||
(aSourceLine ? ":" + aSourceLine : ""));
|
||||
aBody = aBody instanceof Ci.nsIDOMNode ?
|
||||
aBody = aBody instanceof Ci.nsIDOMNode && !(aLevel == "dir") ?
|
||||
aBody : aDocument.createTextNode(aBody);
|
||||
|
||||
bodyNode.appendChild(aBody);
|
||||
|
@ -5475,12 +5526,47 @@ ConsoleUtils = {
|
|||
node.timestamp = timestamp;
|
||||
ConsoleUtils.setMessageType(node, aCategory, aSeverity);
|
||||
|
||||
node.appendChild(timestampNode); // childNode[0]
|
||||
node.appendChild(iconContainer); // childNode[1]
|
||||
node.appendChild(bodyNode); // childNode[2]
|
||||
node.appendChild(repeatContainer); // childNode[3]
|
||||
node.appendChild(timestampNode);
|
||||
node.appendChild(iconContainer);
|
||||
// Display the object tree after the message node.
|
||||
if (aLevel == "dir") {
|
||||
// Make the body container, which is a vertical box, for grouping the text
|
||||
// and tree widgets.
|
||||
let bodyContainer = aDocument.createElement("vbox");
|
||||
bodyContainer.setAttribute("flex", "1");
|
||||
bodyContainer.appendChild(bodyNode);
|
||||
// Create the tree.
|
||||
let tree = createElement(aDocument, "tree", {
|
||||
flex: 1,
|
||||
hidecolumnpicker: "true"
|
||||
});
|
||||
|
||||
let treecols = aDocument.createElement("treecols");
|
||||
let treecol = createElement(aDocument, "treecol", {
|
||||
primary: "true",
|
||||
flex: 1,
|
||||
hideheader: "true",
|
||||
ignoreincolumnpicker: "true"
|
||||
});
|
||||
treecols.appendChild(treecol);
|
||||
tree.appendChild(treecols);
|
||||
|
||||
tree.appendChild(aDocument.createElement("treechildren"));
|
||||
|
||||
bodyContainer.appendChild(tree);
|
||||
node.appendChild(bodyContainer);
|
||||
node.classList.add("webconsole-msg-inspector");
|
||||
// Create the treeView object.
|
||||
let treeView = node.propertyTreeView = new PropertyTreeView();
|
||||
treeView.data = body;
|
||||
tree.setAttribute("rows", treeView.rowCount);
|
||||
}
|
||||
else {
|
||||
node.appendChild(bodyNode);
|
||||
}
|
||||
node.appendChild(repeatContainer);
|
||||
if (locationNode) {
|
||||
node.appendChild(locationNode); // childNode[4]
|
||||
node.appendChild(locationNode);
|
||||
}
|
||||
|
||||
node.setAttribute("id", "console-msg-" + HUDService.sequenceId());
|
||||
|
@ -5683,7 +5769,7 @@ ConsoleUtils = {
|
|||
let lastMessage = aOutput.lastChild;
|
||||
|
||||
// childNodes[2] is the description element
|
||||
if (lastMessage &&
|
||||
if (lastMessage && !aNode.classList.contains("webconsole-msg-inspector") &&
|
||||
aNode.childNodes[2].textContent ==
|
||||
lastMessage.childNodes[2].textContent) {
|
||||
this.mergeFilteredMessageNode(lastMessage, aNode);
|
||||
|
@ -5717,7 +5803,7 @@ ConsoleUtils = {
|
|||
(aNode.classList.contains("webconsole-msg-console") ||
|
||||
aNode.classList.contains("webconsole-msg-exception") ||
|
||||
aNode.classList.contains("webconsole-msg-error"))) {
|
||||
isRepeated = this.filterRepeatedConsole(aNode, outputNode, aHUDId);
|
||||
isRepeated = this.filterRepeatedConsole(aNode, outputNode);
|
||||
}
|
||||
|
||||
if (!isRepeated) {
|
||||
|
|
|
@ -142,6 +142,7 @@ _BROWSER_TEST_FILES = \
|
|||
browser_webconsole_bug_660806_history_nav.js \
|
||||
browser_webconsole_bug_651501_document_body_autocomplete.js \
|
||||
browser_webconsole_bug_653531_highlighter_console_helper.js \
|
||||
browser_webconsole_bug_659907_console_dir.js \
|
||||
head.js \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
// Tests that console.dir works as intended.
|
||||
|
||||
function test() {
|
||||
addTab("data:text/html,Web Console test for bug 659907: Expand console " +
|
||||
"object with a dir method");
|
||||
browser.addEventListener("load", onLoad, true);
|
||||
}
|
||||
|
||||
function onLoad(aEvent) {
|
||||
browser.removeEventListener(aEvent.type, arguments.callee, true);
|
||||
|
||||
openConsole();
|
||||
let hudId = HUDService.getHudIdByWindow(content);
|
||||
let hud = HUDService.hudReferences[hudId];
|
||||
outputNode = hud.outputNode;
|
||||
content.console.dir(content.document);
|
||||
findLogEntry("[object HTMLDocument");
|
||||
let msg = outputNode.querySelectorAll(".webconsole-msg-inspector");
|
||||
is(msg.length, 1, "one message node displayed");
|
||||
let rows = msg[0].propertyTreeView._rows;
|
||||
let foundQSA = false;
|
||||
let foundLocation = false;
|
||||
let foundWrite = false;
|
||||
for (let i = 0; i < rows.length; i++) {
|
||||
if (rows[i].display == "querySelectorAll: function querySelectorAll()") {
|
||||
foundQSA = true;
|
||||
}
|
||||
else if (rows[i].display == "location: Object") {
|
||||
foundLocation = true;
|
||||
}
|
||||
else if (rows[i].display == "write: function write()") {
|
||||
foundWrite = true;
|
||||
}
|
||||
}
|
||||
ok(foundQSA, "found document.querySelectorAll");
|
||||
ok(foundLocation, "found document.location");
|
||||
ok(foundWrite, "found document.write");
|
||||
finishTest();
|
||||
}
|
|
@ -9,7 +9,6 @@
|
|||
console.exception()
|
||||
console.assert()
|
||||
console.clear()
|
||||
console.dir()
|
||||
console.dirxml()
|
||||
console.group()
|
||||
console.groupCollapsed()
|
||||
|
|
|
@ -83,6 +83,10 @@ ConsoleAPI.prototype = {
|
|||
trace: function CA_trace() {
|
||||
self.notifyObservers(id, "trace", self.getStackTrace());
|
||||
},
|
||||
// Displays an interactive listing of all the properties of an object.
|
||||
dir: function CA_dir() {
|
||||
self.notifyObservers(id, "dir", arguments);
|
||||
},
|
||||
__exposedProps__: {
|
||||
log: "r",
|
||||
info: "r",
|
||||
|
@ -90,6 +94,7 @@ ConsoleAPI.prototype = {
|
|||
error: "r",
|
||||
debug: "r",
|
||||
trace: "r",
|
||||
dir: "r"
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -107,6 +112,7 @@ ConsoleAPI.prototype = {
|
|||
error: genPropDesc('error'),
|
||||
debug: genPropDesc('debug'),
|
||||
trace: genPropDesc('trace'),
|
||||
dir: genPropDesc('dir'),
|
||||
__noSuchMethod__: { enumerable: true, configurable: true, writable: true,
|
||||
value: function() {} },
|
||||
__mozillaConsole__: { value: true }
|
||||
|
|
|
@ -164,6 +164,9 @@ function observeConsoleTest() {
|
|||
expect("warn", "arg", "extra arg", 1);
|
||||
win.console.warn("arg", "extra arg", 1);
|
||||
|
||||
expect("dir", win.toString());
|
||||
win.console.dir(win);
|
||||
|
||||
expect("error", "arg");
|
||||
win.console.error("arg");
|
||||
}
|
||||
|
@ -178,6 +181,7 @@ function consoleAPISanityTest() {
|
|||
ok(win.console.warn, "console.warn is here");
|
||||
ok(win.console.error, "console.error is here");
|
||||
ok(win.console.trace, "console.trace is here");
|
||||
ok(win.console.dir, "console.dir is here");
|
||||
}
|
||||
|
||||
var ConsoleObserver = {
|
||||
|
|
|
@ -27,6 +27,7 @@ function doTest() {
|
|||
"error": "function",
|
||||
"debug": "function",
|
||||
"trace": "function",
|
||||
"dir": "function",
|
||||
"__noSuchMethod__": "function"
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче