diff --git a/dom/base/ConsoleAPI.js b/dom/base/ConsoleAPI.js index 1a383f7d37a..194595ee469 100644 --- a/dom/base/ConsoleAPI.js +++ b/dom/base/ConsoleAPI.js @@ -21,6 +21,7 @@ * David Dahl (Original Author) * Ryan Flint * Rob Campbell + * Mihai Sucan * * 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 @@ -79,12 +80,16 @@ ConsoleAPI.prototype = { debug: function CA_debug() { self.notifyObservers(id, "log", arguments); }, + trace: function CA_trace() { + self.notifyObservers(id, "trace", self.getStackTrace()); + }, __exposedProps__: { log: "r", info: "r", warn: "r", error: "r", debug: "r", + trace: "r", } }; @@ -100,6 +105,7 @@ ConsoleAPI.prototype = { warn: bind.call(x.warn, x),\ error: bind.call(x.error, x),\ debug: bind.call(x.debug, x),\ + trace: bind.call(x.trace, x),\ __noSuchMethod__: function() {}\ };\ Object.defineProperty(obj, '__mozillaConsole__', { value: true });\ @@ -126,7 +132,32 @@ ConsoleAPI.prototype = { Services.obs.notifyObservers(consoleEvent, "console-api-log-event", aID); - } + }, + + /** + * Build the stacktrace array for the console.trace() call. + * + * @return array + * Each element is a stack frame that holds the following properties: + * filename, lineNumber, functionName and language. + **/ + getStackTrace: function CA_getStackTrace() { + let stack = []; + let frame = Components.stack.caller; + while (frame = frame.caller) { + if (frame.language == Ci.nsIProgrammingLanguage.JAVASCRIPT || + frame.language == Ci.nsIProgrammingLanguage.JAVASCRIPT2) { + stack.push({ + filename: frame.filename, + lineNumber: frame.lineNumber, + functionName: frame.name, + language: frame.language, + }); + } + } + + return stack; + }, }; let NSGetFactory = XPCOMUtils.generateNSGetFactory([ConsoleAPI]); diff --git a/dom/tests/browser/browser_ConsoleAPITests.js b/dom/tests/browser/browser_ConsoleAPITests.js index aa82a285809..4c086a85ae2 100644 --- a/dom/tests/browser/browser_ConsoleAPITests.js +++ b/dom/tests/browser/browser_ConsoleAPITests.js @@ -21,6 +21,7 @@ * Contributor(s): * David Dahl * Rob Campbell + * Mihai Sucan * * 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 @@ -73,15 +74,39 @@ function testConsoleData(aMessageObject) { is(aMessageObject.level, gLevel, "expected level received"); ok(aMessageObject.arguments, "we have arguments"); is(aMessageObject.arguments.length, gArgs.length, "arguments.length matches"); - gArgs.forEach(function (a, i) { - is(aMessageObject.arguments[i], a, "correct arg " + i); - }); - if (aMessageObject.level == "error") { + if (gLevel == "trace") { + is(aMessageObject.arguments.toSource(), gArgs.toSource(), + "stack trace is correct"); + // Test finished ConsoleObserver.destroy(); finish(); } + else { + gArgs.forEach(function (a, i) { + is(aMessageObject.arguments[i], a, "correct arg " + i); + }); + } + + if (aMessageObject.level == "error") { + // Now test console.trace() + startTraceTest(); + } +} + +function startTraceTest() { + gLevel = "trace"; + gArgs = [ + {filename: TEST_URI, lineNumber: 6, functionName: null, language: 2}, + {filename: TEST_URI, lineNumber: 11, functionName: "foobar585956b", language: 2}, + {filename: TEST_URI, lineNumber: 15, functionName: "foobar585956a", language: 2}, + {filename: TEST_URI, lineNumber: 1, functionName: "onclick", language: 2} + ]; + + let button = gWindow.document.getElementById("test-trace"); + ok(button, "found #test-trace button"); + EventUtils.synthesizeMouse(button, 2, 2, {}, gWindow); } var gLevel, gArgs; @@ -114,6 +139,7 @@ function consoleAPISanityTest() { ok(win.console.info, "console.info is here"); ok(win.console.warn, "console.warn is here"); ok(win.console.error, "console.error is here"); + ok(win.console.trace, "console.trace is here"); } var ConsoleObserver = { diff --git a/dom/tests/browser/test-console-api.html b/dom/tests/browser/test-console-api.html index 235275b430e..ea58306f420 100644 --- a/dom/tests/browser/test-console-api.html +++ b/dom/tests/browser/test-console-api.html @@ -2,6 +2,19 @@ Console API test page + + +

Web Console test for bug 585956 - console.trace().

+ + diff --git a/toolkit/components/console/hudservice/tests/browser/test-console-extras.html b/toolkit/components/console/hudservice/tests/browser/test-console-extras.html index 65f5675fffc..cb5f958a280 100644 --- a/toolkit/components/console/hudservice/tests/browser/test-console-extras.html +++ b/toolkit/components/console/hudservice/tests/browser/test-console-extras.html @@ -11,7 +11,6 @@ console.clear() console.dir() console.dirxml() - console.trace() console.group() console.groupCollapsed() console.groupEnd() diff --git a/toolkit/locales/en-US/chrome/global/headsUpDisplay.properties b/toolkit/locales/en-US/chrome/global/headsUpDisplay.properties index 14719e375e0..34f6c504ad0 100644 --- a/toolkit/locales/en-US/chrome/global/headsUpDisplay.properties +++ b/toolkit/locales/en-US/chrome/global/headsUpDisplay.properties @@ -114,3 +114,14 @@ NetworkPanel.imageSizeDeltaDurationMS=%Sx%Spx, Δ%Sms # o music/crescendo NetworkPanel.responseBodyUnableToDisplay.content=Unable to display responses of type "%S" ConsoleAPIDisabled=The Web Console logging API (console.log, console.info, console.warn, console.error) has been disabled by a script on this page. + +# LOCALIZATION NOTE (stacktrace.anonymousFunction): +# This string is used to display JavaScript functions that have no given name - +# they are said to be anonymous. See stacktrace.outputMessage. +stacktrace.anonymousFunction= + +# LOCALIZATION NOTE (stacktrace.outputMessage): +# This string is used in the Web Console output to identify a web developer call +# to console.trace(). The stack trace of JavaScript function calls is displayed. +# In this minimal message we only show the last call. +stacktrace.outputMessage=Stack trace from %S, function %S, line %S.