From 85055ecb5c15cf8780136a314ad0a7a43c808cc1 Mon Sep 17 00:00:00 2001 From: Mihai Sucan Date: Tue, 12 Apr 2011 21:18:37 +0300 Subject: [PATCH 01/20] Bug 632275 - Web Console: Error message when click on an object to create an inspect window; f=rcampbell r=dcamp,sdwilsh --- .../console/hudservice/PropertyPanel.jsm | 42 ++++++++++++-- .../hudservice/tests/browser/Makefile.in | 2 + ...nsole_bug_632275_getters_document_width.js | 58 +++++++++++++++++++ .../browser/test-bug-632275-getters.html | 19 ++++++ 4 files changed, 115 insertions(+), 6 deletions(-) create mode 100644 toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_632275_getters_document_width.js create mode 100644 toolkit/components/console/hudservice/tests/browser/test-bug-632275-getters.html diff --git a/toolkit/components/console/hudservice/PropertyPanel.jsm b/toolkit/components/console/hudservice/PropertyPanel.jsm index 3ebad1877a18..9cff654e376d 100644 --- a/toolkit/components/console/hudservice/PropertyPanel.jsm +++ b/toolkit/components/console/hudservice/PropertyPanel.jsm @@ -134,6 +134,20 @@ function presentableValueFor(aObject) } } +/** + * Tells if the given function is native or not. + * + * @param function aFunction + * The function you want to check if it is native or not. + * + * @return boolean + * True if the given function is native, false otherwise. + */ +function isNativeFunction(aFunction) +{ + return typeof aFunction == "function" && !("prototype" in aFunction); +} + /** * Get an array of property name value pairs for the tree. * @@ -145,17 +159,33 @@ function presentableValueFor(aObject) function namesAndValuesOf(aObject) { let pairs = []; - let value, presentable; + let value, presentable, getter; + + let isDOMDocument = aObject instanceof Ci.nsIDOMDocument; for (var propName in aObject) { - try { - value = aObject[propName]; - presentable = presentableValueFor(value); - } - catch (ex) { + // See bug 632275: skip deprecated width and height properties. + if (isDOMDocument && (propName == "width" || propName == "height")) { continue; } + // Also skip non-native getters. + // TODO: implement a safer way to skip non-native getters. See bug 647235. + getter = aObject.__lookupGetter__(propName); + if (getter && !isNativeFunction(getter)) { + value = ""; // Value is never displayed. + presentable = {type: TYPE_OTHER, display: "Getter"}; + } + else { + try { + value = aObject[propName]; + presentable = presentableValueFor(value); + } + catch (ex) { + continue; + } + } + let pair = {}; pair.name = propName; pair.display = propName + ": " + presentable.display; diff --git a/toolkit/components/console/hudservice/tests/browser/Makefile.in b/toolkit/components/console/hudservice/tests/browser/Makefile.in index 87dd39e2d23a..b33842e3070e 100644 --- a/toolkit/components/console/hudservice/tests/browser/Makefile.in +++ b/toolkit/components/console/hudservice/tests/browser/Makefile.in @@ -131,6 +131,7 @@ _BROWSER_TEST_FILES = \ browser_webconsole_bug_632347_iterators_generators.js \ browser_webconsole_bug_642108_refForOutputNode.js \ browser_webconsole_bug_642108_pruneTest.js \ + browser_webconsole_bug_632275_getters_document_width.js \ head.js \ $(NULL) @@ -199,6 +200,7 @@ _BROWSER_TEST_PAGES = \ test-bug-630733-response-redirect-headers.sjs \ test-bug-621644-jsterm-dollar.html \ test-bug-632347-iterators-generators.html \ + test-bug-632275-getters.html \ $(NULL) libs:: $(_BROWSER_TEST_FILES) diff --git a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_632275_getters_document_width.js b/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_632275_getters_document_width.js new file mode 100644 index 000000000000..08b34e22ef7b --- /dev/null +++ b/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_632275_getters_document_width.js @@ -0,0 +1,58 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-bug-632275-getters.html"; + +function test() { + addTab(TEST_URI); + browser.addEventListener("load", tabLoaded, true); +} + +function tabLoaded() { + browser.removeEventListener("load", tabLoaded, true); + openConsole(); + + let hudId = HUDService.getHudIdByWindow(content); + let HUD = HUDService.hudReferences[hudId]; + let jsterm = HUD.jsterm; + + let doc = content.wrappedJSObject.document; + + let panel = jsterm.openPropertyPanel("Test1", doc); + + let rows = panel.treeView._rows; + let find = function(regex) { + return rows.some(function(row) { + return regex.test(row.display); + }); + }; + + ok(!find(/^(width|height):/), "no document.width/height"); + + panel.destroy(); + + let getterValue = doc.foobar._val; + + panel = jsterm.openPropertyPanel("Test2", doc.foobar); + rows = panel.treeView._rows; + + is(getterValue, doc.foobar._val, "getter did not execute"); + is(getterValue+1, doc.foobar.val, "getter executed"); + is(getterValue+1, doc.foobar._val, "getter executed (recheck)"); + + ok(find(/^val: Getter$/), + "getter is properly displayed"); + + ok(find(new RegExp("^_val: " + getterValue + "$")), + "getter _val is properly displayed"); + + panel.destroy(); + + executeSoon(function() { + let textContent = HUD.outputNode.textContent; + is(textContent.indexOf("document.body.client"), -1, + "no document.width/height warning displayed"); + + finishTest(); + }); +} diff --git a/toolkit/components/console/hudservice/tests/browser/test-bug-632275-getters.html b/toolkit/components/console/hudservice/tests/browser/test-bug-632275-getters.html new file mode 100644 index 000000000000..fbe4c7bf678a --- /dev/null +++ b/toolkit/components/console/hudservice/tests/browser/test-bug-632275-getters.html @@ -0,0 +1,19 @@ + + + + Web Console test for bug 632275 - getters + + + + + + +

Web Console test for bug 632275 - getters.

+ + From 1efb09873157dc0017b66237b4aa1c5280cc70f7 Mon Sep 17 00:00:00 2001 From: Mihai Sucan Date: Tue, 12 Apr 2011 17:00:29 -0300 Subject: [PATCH 02/20] Bug 620832 - Web console attempts to remove its observers multiple times; f=ddahl,rcampbell r=sdwilsh,rcampbell --- toolkit/components/console/hudservice/HUDService.jsm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/toolkit/components/console/hudservice/HUDService.jsm b/toolkit/components/console/hudservice/HUDService.jsm index 6537de01233e..15491379f7ee 100644 --- a/toolkit/components/console/hudservice/HUDService.jsm +++ b/toolkit/components/console/hudservice/HUDService.jsm @@ -3527,7 +3527,7 @@ let ConsoleAPIObserver = { HUDService.logConsoleAPIMessage(hudId, aMessage.level, aMessage.arguments); } else if (aTopic == "quit-application-granted") { - this.shutdown(); + HUDService.shutdown(); } }, @@ -5845,7 +5845,7 @@ HUDWindowObserver = { uninit: function HWO_uninit() { Services.obs.removeObserver(this, "content-document-global-created"); - HUDService.shutdown(); + Services.obs.removeObserver(this, "xpcom-shutdown"); this.initialConsoleCreated = false; }, From 3f79db3c8cd904da455da09340a55fa0298d329d Mon Sep 17 00:00:00 2001 From: Rob Campbell Date: Tue, 12 Apr 2011 20:54:14 -0300 Subject: [PATCH 03/20] backout bug 632275 and bug 620832, a=rcampbell,orange --- .../console/hudservice/HUDService.jsm | 4 +- .../console/hudservice/PropertyPanel.jsm | 42 ++------------ .../hudservice/tests/browser/Makefile.in | 2 - ...nsole_bug_632275_getters_document_width.js | 58 ------------------- .../browser/test-bug-632275-getters.html | 19 ------ 5 files changed, 8 insertions(+), 117 deletions(-) delete mode 100644 toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_632275_getters_document_width.js delete mode 100644 toolkit/components/console/hudservice/tests/browser/test-bug-632275-getters.html diff --git a/toolkit/components/console/hudservice/HUDService.jsm b/toolkit/components/console/hudservice/HUDService.jsm index 15491379f7ee..6537de01233e 100644 --- a/toolkit/components/console/hudservice/HUDService.jsm +++ b/toolkit/components/console/hudservice/HUDService.jsm @@ -3527,7 +3527,7 @@ let ConsoleAPIObserver = { HUDService.logConsoleAPIMessage(hudId, aMessage.level, aMessage.arguments); } else if (aTopic == "quit-application-granted") { - HUDService.shutdown(); + this.shutdown(); } }, @@ -5845,7 +5845,7 @@ HUDWindowObserver = { uninit: function HWO_uninit() { Services.obs.removeObserver(this, "content-document-global-created"); - Services.obs.removeObserver(this, "xpcom-shutdown"); + HUDService.shutdown(); this.initialConsoleCreated = false; }, diff --git a/toolkit/components/console/hudservice/PropertyPanel.jsm b/toolkit/components/console/hudservice/PropertyPanel.jsm index 9cff654e376d..3ebad1877a18 100644 --- a/toolkit/components/console/hudservice/PropertyPanel.jsm +++ b/toolkit/components/console/hudservice/PropertyPanel.jsm @@ -134,20 +134,6 @@ function presentableValueFor(aObject) } } -/** - * Tells if the given function is native or not. - * - * @param function aFunction - * The function you want to check if it is native or not. - * - * @return boolean - * True if the given function is native, false otherwise. - */ -function isNativeFunction(aFunction) -{ - return typeof aFunction == "function" && !("prototype" in aFunction); -} - /** * Get an array of property name value pairs for the tree. * @@ -159,33 +145,17 @@ function isNativeFunction(aFunction) function namesAndValuesOf(aObject) { let pairs = []; - let value, presentable, getter; - - let isDOMDocument = aObject instanceof Ci.nsIDOMDocument; + let value, presentable; for (var propName in aObject) { - // See bug 632275: skip deprecated width and height properties. - if (isDOMDocument && (propName == "width" || propName == "height")) { + try { + value = aObject[propName]; + presentable = presentableValueFor(value); + } + catch (ex) { continue; } - // Also skip non-native getters. - // TODO: implement a safer way to skip non-native getters. See bug 647235. - getter = aObject.__lookupGetter__(propName); - if (getter && !isNativeFunction(getter)) { - value = ""; // Value is never displayed. - presentable = {type: TYPE_OTHER, display: "Getter"}; - } - else { - try { - value = aObject[propName]; - presentable = presentableValueFor(value); - } - catch (ex) { - continue; - } - } - let pair = {}; pair.name = propName; pair.display = propName + ": " + presentable.display; diff --git a/toolkit/components/console/hudservice/tests/browser/Makefile.in b/toolkit/components/console/hudservice/tests/browser/Makefile.in index b33842e3070e..87dd39e2d23a 100644 --- a/toolkit/components/console/hudservice/tests/browser/Makefile.in +++ b/toolkit/components/console/hudservice/tests/browser/Makefile.in @@ -131,7 +131,6 @@ _BROWSER_TEST_FILES = \ browser_webconsole_bug_632347_iterators_generators.js \ browser_webconsole_bug_642108_refForOutputNode.js \ browser_webconsole_bug_642108_pruneTest.js \ - browser_webconsole_bug_632275_getters_document_width.js \ head.js \ $(NULL) @@ -200,7 +199,6 @@ _BROWSER_TEST_PAGES = \ test-bug-630733-response-redirect-headers.sjs \ test-bug-621644-jsterm-dollar.html \ test-bug-632347-iterators-generators.html \ - test-bug-632275-getters.html \ $(NULL) libs:: $(_BROWSER_TEST_FILES) diff --git a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_632275_getters_document_width.js b/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_632275_getters_document_width.js deleted file mode 100644 index 08b34e22ef7b..000000000000 --- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_632275_getters_document_width.js +++ /dev/null @@ -1,58 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-bug-632275-getters.html"; - -function test() { - addTab(TEST_URI); - browser.addEventListener("load", tabLoaded, true); -} - -function tabLoaded() { - browser.removeEventListener("load", tabLoaded, true); - openConsole(); - - let hudId = HUDService.getHudIdByWindow(content); - let HUD = HUDService.hudReferences[hudId]; - let jsterm = HUD.jsterm; - - let doc = content.wrappedJSObject.document; - - let panel = jsterm.openPropertyPanel("Test1", doc); - - let rows = panel.treeView._rows; - let find = function(regex) { - return rows.some(function(row) { - return regex.test(row.display); - }); - }; - - ok(!find(/^(width|height):/), "no document.width/height"); - - panel.destroy(); - - let getterValue = doc.foobar._val; - - panel = jsterm.openPropertyPanel("Test2", doc.foobar); - rows = panel.treeView._rows; - - is(getterValue, doc.foobar._val, "getter did not execute"); - is(getterValue+1, doc.foobar.val, "getter executed"); - is(getterValue+1, doc.foobar._val, "getter executed (recheck)"); - - ok(find(/^val: Getter$/), - "getter is properly displayed"); - - ok(find(new RegExp("^_val: " + getterValue + "$")), - "getter _val is properly displayed"); - - panel.destroy(); - - executeSoon(function() { - let textContent = HUD.outputNode.textContent; - is(textContent.indexOf("document.body.client"), -1, - "no document.width/height warning displayed"); - - finishTest(); - }); -} diff --git a/toolkit/components/console/hudservice/tests/browser/test-bug-632275-getters.html b/toolkit/components/console/hudservice/tests/browser/test-bug-632275-getters.html deleted file mode 100644 index fbe4c7bf678a..000000000000 --- a/toolkit/components/console/hudservice/tests/browser/test-bug-632275-getters.html +++ /dev/null @@ -1,19 +0,0 @@ - - - - Web Console test for bug 632275 - getters - - - - - - -

Web Console test for bug 632275 - getters.

- - From 5e1f6515a2f9cb42c70915e35fd1fe62f20fb8a1 Mon Sep 17 00:00:00 2001 From: Mihai Sucan Date: Wed, 13 Apr 2011 19:04:12 +0300 Subject: [PATCH 04/20] Bug 620832 - Web console attempts to remove its observers multiple times; f=ddahl,rcampbell r=sdwilsh,rcampbell --- toolkit/components/console/hudservice/HUDService.jsm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/toolkit/components/console/hudservice/HUDService.jsm b/toolkit/components/console/hudservice/HUDService.jsm index 20d87ca6a188..1c573e7f5d00 100644 --- a/toolkit/components/console/hudservice/HUDService.jsm +++ b/toolkit/components/console/hudservice/HUDService.jsm @@ -3527,7 +3527,7 @@ let ConsoleAPIObserver = { HUDService.logConsoleAPIMessage(hudId, aMessage.level, aMessage.arguments); } else if (aTopic == "quit-application-granted") { - this.shutdown(); + HUDService.shutdown(); } }, @@ -5845,7 +5845,7 @@ HUDWindowObserver = { uninit: function HWO_uninit() { Services.obs.removeObserver(this, "content-document-global-created"); - HUDService.shutdown(); + Services.obs.removeObserver(this, "xpcom-shutdown"); this.initialConsoleCreated = false; }, From 77fc545081e3624f8ed479e31062c8223fb3ca01 Mon Sep 17 00:00:00 2001 From: Mihai Sucan Date: Mon, 11 Apr 2011 20:48:15 +0300 Subject: [PATCH 05/20] Bug 585956 - Implement console.trace() in web console; f=ddahl r=rcampbell,jonas --- dom/base/ConsoleAPI.js | 33 +++++++- dom/tests/browser/browser_ConsoleAPITests.js | 34 +++++++- dom/tests/browser/test-console-api.html | 14 ++++ .../mochitest/general/test_consoleAPI.html | 1 + .../console/hudservice/HUDService.jsm | 84 ++++++++++++++++++- .../hudservice/tests/browser/Makefile.in | 2 + ...ser_webconsole_bug_585956_console_trace.js | 76 +++++++++++++++++ .../test-bug-585956-console-trace.html | 27 ++++++ .../tests/browser/test-console-extras.html | 1 - .../chrome/global/headsUpDisplay.properties | 11 +++ 10 files changed, 274 insertions(+), 9 deletions(-) create mode 100644 toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_585956_console_trace.js create mode 100644 toolkit/components/console/hudservice/tests/browser/test-bug-585956-console-trace.html diff --git a/dom/base/ConsoleAPI.js b/dom/base/ConsoleAPI.js index 1a383f7d37a2..194595ee4690 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 aa82a285809b..4c086a85ae26 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 235275b430e3..ea58306f420f 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 65f5675fffc5..cb5f958a2806 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 14719e375e0e..34f6c504ad07 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. From c60aded6c2930bebd7f7e3eeaf4b5bf0296b6b16 Mon Sep 17 00:00:00 2001 From: Mihai Sucan Date: Wed, 13 Apr 2011 23:02:36 +0300 Subject: [PATCH 06/20] Bug 595223 - Keep track of file:// url 'loadGroups'; f=ddahl r=dcamp,dolske --- .../console/hudservice/HUDService.jsm | 119 ++++++++++++++---- .../hudservice/tests/browser/Makefile.in | 1 + .../browser_webconsole_bug_595223_file_uri.js | 79 ++++++++++++ 3 files changed, 175 insertions(+), 24 deletions(-) create mode 100644 toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_595223_file_uri.js diff --git a/toolkit/components/console/hudservice/HUDService.jsm b/toolkit/components/console/hudservice/HUDService.jsm index 6936a76810c8..b9ceec95daab 100644 --- a/toolkit/components/console/hudservice/HUDService.jsm +++ b/toolkit/components/console/hudservice/HUDService.jsm @@ -1439,7 +1439,8 @@ HUD_SERVICE.prototype = */ deactivateHUDForContext: function HS_deactivateHUDForContext(aContext, aAnimated) { - let window = aContext.linkedBrowser.contentWindow; + let browser = aContext.linkedBrowser; + let window = browser.contentWindow; let nBox = aContext.ownerDocument.defaultView. getNotificationBox(window); let hudId = "hud_" + nBox.id; @@ -1450,7 +1451,12 @@ HUD_SERVICE.prototype = this.storeHeight(hudId); } + let hud = this.hudReferences[hudId]; + browser.webProgress.removeProgressListener(hud.progressListener); + delete hud.progressListener; + this.unregisterDisplay(displayNode); + window.focus(); } }, @@ -2718,27 +2724,6 @@ HUD_SERVICE.prototype = 13: "typeWarning", // JSREPORT_STRICT_MODE_ERROR | JSREPORT_WARNING | JSREPORT_ERROR }, - /** - * Closes the Console, if any, that resides on the given tab. - * - * @param nsIDOMNode aTab - * The tab on which to close the console. - * @returns void - */ - closeConsoleOnTab: function HS_closeConsoleOnTab(aTab) - { - let xulDocument = aTab.ownerDocument; - let xulWindow = xulDocument.defaultView; - let gBrowser = xulWindow.gBrowser; - let linkedBrowser = aTab.linkedBrowser; - let notificationBox = gBrowser.getNotificationBox(linkedBrowser); - let hudId = "hud_" + notificationBox.getAttribute("id"); - let outputNode = xulDocument.getElementById(hudId); - if (outputNode != null) { - this.unregisterDisplay(outputNode); - } - }, - /** * onTabClose event handler function * @@ -2747,7 +2732,7 @@ HUD_SERVICE.prototype = */ onTabClose: function HS_onTabClose(aEvent) { - this.closeConsoleOnTab(aEvent.target); + this.deactivateHUDForContext(aEvent.target, false); }, /** @@ -2765,7 +2750,7 @@ HUD_SERVICE.prototype = let tab = tabContainer.firstChild; while (tab != null) { - this.closeConsoleOnTab(tab); + this.deactivateHUDForContext(tab, false); tab = tab.nextSibling; } }, @@ -2837,6 +2822,11 @@ HUD_SERVICE.prototype = HUDService.registerHUDReference(hud); let windowId = this.getWindowId(aContentWindow.top); this.windowIds[windowId] = hudId; + + hud.progressListener = new ConsoleProgressListener(hudId); + + _browser.webProgress.addProgressListener(hud.progressListener, + Ci.nsIWebProgress.NOTIFY_STATE_ALL); } else { hud = this.hudReferences[hudId]; @@ -6085,6 +6075,87 @@ HUDConsoleObserver = { } }; +/** + * A WebProgressListener that listens for location changes, to update HUDService + * state information on page navigation. + * + * @constructor + * @param string aHudId + * The HeadsUpDisplay ID. + */ +function ConsoleProgressListener(aHudId) +{ + this.hudId = aHudId; +} + +ConsoleProgressListener.prototype = { + QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener, + Ci.nsISupportsWeakReference]), + + onStateChange: function CPL_onStateChange(aProgress, aRequest, aState, + aStatus) + { + if (!(aState & Ci.nsIWebProgressListener.STATE_START)) { + return; + } + + let uri = null; + if (aRequest instanceof Ci.imgIRequest) { + let imgIRequest = aRequest.QueryInterface(Ci.imgIRequest); + uri = imgIRequest.URI; + } + else if (aRequest instanceof Ci.nsIChannel) { + let nsIChannel = aRequest.QueryInterface(Ci.nsIChannel); + uri = nsIChannel.URI; + } + + if (!uri || !uri.schemeIs("file") && !uri.schemeIs("ftp")) { + return; + } + + let outputNode = HUDService.hudReferences[this.hudId].outputNode; + + let chromeDocument = outputNode.ownerDocument; + let msgNode = chromeDocument.createElementNS(HTML_NS, "html:span"); + + // Create the clickable URL part of the message. + let linkNode = chromeDocument.createElementNS(HTML_NS, "html:span"); + linkNode.appendChild(chromeDocument.createTextNode(uri.spec)); + linkNode.classList.add("hud-clickable"); + linkNode.classList.add("webconsole-msg-url"); + + linkNode.addEventListener("mousedown", function(aEvent) { + this._startX = aEvent.clientX; + this._startY = aEvent.clientY; + }, false); + + linkNode.addEventListener("click", function(aEvent) { + if (aEvent.detail == 1 && aEvent.button == 0 && + this._startX == aEvent.clientX && this._startY == aEvent.clientY) { + let viewSourceUtils = chromeDocument.defaultView.gViewSourceUtils; + viewSourceUtils.viewSource(uri.spec, null, chromeDocument); + } + }, false); + + msgNode.appendChild(linkNode); + + let messageNode = ConsoleUtils.createMessageNode(chromeDocument, + CATEGORY_NETWORK, + SEVERITY_LOG, + msgNode, + null, + null, + uri.spec); + + ConsoleUtils.outputMessageNode(messageNode, this.hudId); + }, + + onLocationChange: function() {}, + onStatusChange: function() {}, + onProgressChange: function() {}, + onSecurityChange: function() {}, +}; + /////////////////////////////////////////////////////////////////////////// // appName /////////////////////////////////////////////////////////////////////////// diff --git a/toolkit/components/console/hudservice/tests/browser/Makefile.in b/toolkit/components/console/hudservice/tests/browser/Makefile.in index 2da05635fa93..2f18d02814b6 100644 --- a/toolkit/components/console/hudservice/tests/browser/Makefile.in +++ b/toolkit/components/console/hudservice/tests/browser/Makefile.in @@ -132,6 +132,7 @@ _BROWSER_TEST_FILES = \ browser_webconsole_bug_642108_refForOutputNode.js \ browser_webconsole_bug_642108_pruneTest.js \ browser_webconsole_bug_585956_console_trace.js \ + browser_webconsole_bug_595223_file_uri.js \ head.js \ $(NULL) diff --git a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_595223_file_uri.js b/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_595223_file_uri.js new file mode 100644 index 000000000000..1fd37b4ea35a --- /dev/null +++ b/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_595223_file_uri.js @@ -0,0 +1,79 @@ +/* vim:set ts=2 sw=2 sts=2 et: */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Web Console test suite. + * + * The Initial Developer of the Original Code is + * The Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2011 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * 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 + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +const TEST_FILE = "test-network.html"; + +function tabLoad(aEvent) { + browser.removeEventListener(aEvent.type, arguments.callee, true); + + openConsole(); + + let hudId = HUDService.getHudIdByWindow(content); + hud = HUDService.hudReferences[hudId]; + + browser.addEventListener("load", tabReload, true); + + content.location.reload(); +} + +function tabReload(aEvent) { + browser.removeEventListener(aEvent.type, arguments.callee, true); + + let textContent = hud.outputNode.textContent; + isnot(textContent.indexOf("test-network.html"), -1, + "found test-network.html"); + isnot(textContent.indexOf("test-image.png"), -1, "found test-image.png"); + isnot(textContent.indexOf("testscript.js"), -1, "found testscript.js"); + isnot(textContent.indexOf("running network console logging tests"), -1, + "found the console.log() message from testscript.js"); + + finishTest(); +} + +function test() { + let jar = getJar(getRootDirectory(gTestPath)); + let dir = jar ? + extractJarToTmp(jar) : + getChromeDir(getResolvedURI(gTestPath)); + dir.append(TEST_FILE); + + let uri = Services.io.newFileURI(dir); + + addTab(uri.spec); + browser.addEventListener("load", tabLoad, true); +} From 8a438cd825f8bb8c3e28df5a811ff961340b6d39 Mon Sep 17 00:00:00 2001 From: Mihai Sucan Date: Wed, 13 Apr 2011 21:05:15 +0300 Subject: [PATCH 07/20] Bug 632275 - Web Console: Error message when click on an object to create an inspect window; f=rcampbell r=dcamp,sdwilsh --- .../console/hudservice/PropertyPanel.jsm | 43 ++++++++++++-- .../hudservice/tests/browser/Makefile.in | 2 + ...nsole_bug_632275_getters_document_width.js | 58 +++++++++++++++++++ .../browser/test-bug-632275-getters.html | 19 ++++++ 4 files changed, 116 insertions(+), 6 deletions(-) create mode 100644 toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_632275_getters_document_width.js create mode 100644 toolkit/components/console/hudservice/tests/browser/test-bug-632275-getters.html diff --git a/toolkit/components/console/hudservice/PropertyPanel.jsm b/toolkit/components/console/hudservice/PropertyPanel.jsm index 3ebad1877a18..b23ba617c8ee 100644 --- a/toolkit/components/console/hudservice/PropertyPanel.jsm +++ b/toolkit/components/console/hudservice/PropertyPanel.jsm @@ -134,6 +134,20 @@ function presentableValueFor(aObject) } } +/** + * Tells if the given function is native or not. + * + * @param function aFunction + * The function you want to check if it is native or not. + * + * @return boolean + * True if the given function is native, false otherwise. + */ +function isNativeFunction(aFunction) +{ + return typeof aFunction == "function" && !("prototype" in aFunction); +} + /** * Get an array of property name value pairs for the tree. * @@ -145,17 +159,34 @@ function presentableValueFor(aObject) function namesAndValuesOf(aObject) { let pairs = []; - let value, presentable; + let value, presentable, getter; + + let isDOMDocument = aObject instanceof Ci.nsIDOMDocument; for (var propName in aObject) { - try { - value = aObject[propName]; - presentable = presentableValueFor(value); - } - catch (ex) { + // See bug 632275: skip deprecated width and height properties. + if (isDOMDocument && (propName == "width" || propName == "height")) { continue; } + // Also skip non-native getters. + // TODO: implement a safer way to skip non-native getters. See bug 647235. + getter = aObject.__lookupGetter__ ? + aObject.__lookupGetter__(propName) : null; + if (getter && !isNativeFunction(getter)) { + value = ""; // Value is never displayed. + presentable = {type: TYPE_OTHER, display: "Getter"}; + } + else { + try { + value = aObject[propName]; + presentable = presentableValueFor(value); + } + catch (ex) { + continue; + } + } + let pair = {}; pair.name = propName; pair.display = propName + ": " + presentable.display; diff --git a/toolkit/components/console/hudservice/tests/browser/Makefile.in b/toolkit/components/console/hudservice/tests/browser/Makefile.in index 2f18d02814b6..1f5e71eb67fe 100644 --- a/toolkit/components/console/hudservice/tests/browser/Makefile.in +++ b/toolkit/components/console/hudservice/tests/browser/Makefile.in @@ -133,6 +133,7 @@ _BROWSER_TEST_FILES = \ browser_webconsole_bug_642108_pruneTest.js \ browser_webconsole_bug_585956_console_trace.js \ browser_webconsole_bug_595223_file_uri.js \ + browser_webconsole_bug_632275_getters_document_width.js \ head.js \ $(NULL) @@ -202,6 +203,7 @@ _BROWSER_TEST_PAGES = \ test-bug-621644-jsterm-dollar.html \ test-bug-632347-iterators-generators.html \ test-bug-585956-console-trace.html \ + test-bug-632275-getters.html \ $(NULL) libs:: $(_BROWSER_TEST_FILES) diff --git a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_632275_getters_document_width.js b/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_632275_getters_document_width.js new file mode 100644 index 000000000000..08b34e22ef7b --- /dev/null +++ b/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_632275_getters_document_width.js @@ -0,0 +1,58 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-bug-632275-getters.html"; + +function test() { + addTab(TEST_URI); + browser.addEventListener("load", tabLoaded, true); +} + +function tabLoaded() { + browser.removeEventListener("load", tabLoaded, true); + openConsole(); + + let hudId = HUDService.getHudIdByWindow(content); + let HUD = HUDService.hudReferences[hudId]; + let jsterm = HUD.jsterm; + + let doc = content.wrappedJSObject.document; + + let panel = jsterm.openPropertyPanel("Test1", doc); + + let rows = panel.treeView._rows; + let find = function(regex) { + return rows.some(function(row) { + return regex.test(row.display); + }); + }; + + ok(!find(/^(width|height):/), "no document.width/height"); + + panel.destroy(); + + let getterValue = doc.foobar._val; + + panel = jsterm.openPropertyPanel("Test2", doc.foobar); + rows = panel.treeView._rows; + + is(getterValue, doc.foobar._val, "getter did not execute"); + is(getterValue+1, doc.foobar.val, "getter executed"); + is(getterValue+1, doc.foobar._val, "getter executed (recheck)"); + + ok(find(/^val: Getter$/), + "getter is properly displayed"); + + ok(find(new RegExp("^_val: " + getterValue + "$")), + "getter _val is properly displayed"); + + panel.destroy(); + + executeSoon(function() { + let textContent = HUD.outputNode.textContent; + is(textContent.indexOf("document.body.client"), -1, + "no document.width/height warning displayed"); + + finishTest(); + }); +} diff --git a/toolkit/components/console/hudservice/tests/browser/test-bug-632275-getters.html b/toolkit/components/console/hudservice/tests/browser/test-bug-632275-getters.html new file mode 100644 index 000000000000..fbe4c7bf678a --- /dev/null +++ b/toolkit/components/console/hudservice/tests/browser/test-bug-632275-getters.html @@ -0,0 +1,19 @@ + + + + Web Console test for bug 632275 - getters + + + + + + +

Web Console test for bug 632275 - getters.

+ + From 3b6a01e37a16abae5b04e8dba73cf7cd71666081 Mon Sep 17 00:00:00 2001 From: Mihai Sucan Date: Wed, 20 Apr 2011 11:18:00 +0300 Subject: [PATCH 08/20] Bug 642176 - Integrate Workspace extension into the browser; f=rcampbell r=ddahl,sdwilsh --- browser/app/profile/firefox.js | 3 + browser/base/content/browser-appmenu.inc | 5 + browser/base/content/browser-menubar.inc | 5 + browser/base/content/browser-sets.inc | 3 + browser/base/content/browser.js | 24 + browser/base/content/workspace.js | 552 ++++++++++++++++++ browser/base/content/workspace.xul | 331 +++++++++++ browser/base/jar.mn | 2 + .../locales/en-US/chrome/browser/browser.dtd | 4 + .../en-US/chrome/browser/workspace.dtd | 88 +++ .../en-US/chrome/browser/workspace.properties | 30 + browser/locales/jar.mn | 2 + .../console/hudservice/HUDService.jsm | 12 + 13 files changed, 1061 insertions(+) create mode 100644 browser/base/content/workspace.js create mode 100644 browser/base/content/workspace.xul create mode 100644 browser/locales/en-US/chrome/browser/workspace.dtd create mode 100644 browser/locales/en-US/chrome/browser/workspace.properties diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js index 7cdde5cc8f31..f71d071e2cd2 100644 --- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -1047,6 +1047,9 @@ pref("services.sync.prefs.sync.xpinstall.whitelist.required", true); pref("devtools.errorconsole.enabled", false); pref("devtools.inspector.enabled", false); +// Enable the Workspace tool. +pref("devtools.workspace.enabled", true); + // The last Web Console height. This is initially 0 which means that the Web // Console will use the default height next time it shows. // Change to -1 if you do not want the Web Console to remember its last height. diff --git a/browser/base/content/browser-appmenu.inc b/browser/base/content/browser-appmenu.inc index 17ed11006397..296b7cd207db 100644 --- a/browser/base/content/browser-appmenu.inc +++ b/browser/base/content/browser-appmenu.inc @@ -187,6 +187,11 @@ type="checkbox" command="Tools:Inspect" key="key_inspect"/> +