зеркало из https://github.com/mozilla/gecko-dev.git
Bug 762996 - Add errors count to the Web Console button in the developer toolbar; r=paul
This commit is contained in:
Родитель
0195bfa381
Коммит
f37e168b92
|
@ -8,6 +8,9 @@ const EXPORTED_SYMBOLS = [ "DeveloperToolbar" ];
|
|||
|
||||
const NS_XHTML = "http://www.w3.org/1999/xhtml";
|
||||
|
||||
const WEBCONSOLE_CONTENT_SCRIPT_URL =
|
||||
"chrome://browser/content/devtools/HUDService-content.js";
|
||||
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
|
@ -36,6 +39,10 @@ function DeveloperToolbar(aChromeWindow, aToolbarElement)
|
|||
this._lastState = NOTIFICATIONS.HIDE;
|
||||
this._pendingShowCallback = undefined;
|
||||
this._pendingHide = false;
|
||||
this._errorsCount = {};
|
||||
this._webConsoleButton = this._doc
|
||||
.getElementById("developer-toolbar-webconsole");
|
||||
this._webConsoleButtonLabel = this._webConsoleButton.label;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -58,6 +65,9 @@ const NOTIFICATIONS = {
|
|||
*/
|
||||
DeveloperToolbar.prototype.NOTIFICATIONS = NOTIFICATIONS;
|
||||
|
||||
DeveloperToolbar.prototype._contentMessageListeners =
|
||||
["WebConsole:CachedMessages", "WebConsole:PageError"];
|
||||
|
||||
/**
|
||||
* Is the toolbar open?
|
||||
*/
|
||||
|
@ -68,6 +78,18 @@ Object.defineProperty(DeveloperToolbar.prototype, 'visible', {
|
|||
enumerable: true
|
||||
});
|
||||
|
||||
var _gSequenceId = 0;
|
||||
|
||||
/**
|
||||
* Getter for a unique ID.
|
||||
*/
|
||||
Object.defineProperty(DeveloperToolbar.prototype, 'sequenceId', {
|
||||
get: function DT_visible() {
|
||||
return _gSequenceId++;
|
||||
},
|
||||
enumerable: true
|
||||
});
|
||||
|
||||
/**
|
||||
* Called from browser.xul in response to menu-click or keyboard shortcut to
|
||||
* toggle the toolbar
|
||||
|
@ -152,9 +174,13 @@ DeveloperToolbar.prototype._onload = function DT_onload()
|
|||
this.display.onOutput.add(this.outputPanel._outputChanged, this.outputPanel);
|
||||
|
||||
this._chromeWindow.getBrowser().tabContainer.addEventListener("TabSelect", this, false);
|
||||
this._chromeWindow.getBrowser().tabContainer.addEventListener("TabClose", this, false);
|
||||
this._chromeWindow.getBrowser().addEventListener("load", this, true);
|
||||
this._chromeWindow.getBrowser().addEventListener("beforeunload", this, true);
|
||||
this._chromeWindow.addEventListener("resize", this, false);
|
||||
|
||||
this._initErrorsCount(this._chromeWindow.getBrowser().selectedTab);
|
||||
|
||||
this._element.hidden = false;
|
||||
this._input.focus();
|
||||
|
||||
|
@ -178,6 +204,67 @@ DeveloperToolbar.prototype._onload = function DT_onload()
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize the listeners needed for tracking the number of errors for a given
|
||||
* tab.
|
||||
*
|
||||
* @private
|
||||
* @param nsIDOMNode aTab the xul:tab for which you want to track the number of
|
||||
* errors.
|
||||
*/
|
||||
DeveloperToolbar.prototype._initErrorsCount = function DT__initErrorsCount(aTab)
|
||||
{
|
||||
let tabId = aTab.linkedPanel;
|
||||
if (tabId in this._errorsCount) {
|
||||
this._updateErrorsCount();
|
||||
return;
|
||||
}
|
||||
|
||||
let messageManager = aTab.linkedBrowser.messageManager;
|
||||
messageManager.loadFrameScript(WEBCONSOLE_CONTENT_SCRIPT_URL, true);
|
||||
|
||||
this._errorsCount[tabId] = 0;
|
||||
|
||||
this._contentMessageListeners.forEach(function(aName) {
|
||||
messageManager.addMessageListener(aName, this);
|
||||
}, this);
|
||||
|
||||
let message = {
|
||||
features: ["PageError"],
|
||||
cachedMessages: ["PageError"],
|
||||
};
|
||||
|
||||
this.sendMessageToTab(aTab, "WebConsole:Init", message);
|
||||
this._updateErrorsCount();
|
||||
};
|
||||
|
||||
/**
|
||||
* Stop the listeners needed for tracking the number of errors for a given
|
||||
* tab.
|
||||
*
|
||||
* @private
|
||||
* @param nsIDOMNode aTab the xul:tab for which you want to stop tracking the
|
||||
* number of errors.
|
||||
*/
|
||||
DeveloperToolbar.prototype._stopErrorsCount = function DT__stopErrorsCount(aTab)
|
||||
{
|
||||
let tabId = aTab.linkedPanel;
|
||||
if (!(tabId in this._errorsCount)) {
|
||||
this._updateErrorsCount();
|
||||
return;
|
||||
}
|
||||
|
||||
this.sendMessageToTab(aTab, "WebConsole:Destroy", {});
|
||||
|
||||
let messageManager = aTab.linkedBrowser.messageManager;
|
||||
this._contentMessageListeners.forEach(function(aName) {
|
||||
messageManager.removeMessageListener(aName, this);
|
||||
}, this);
|
||||
|
||||
delete this._errorsCount[tabId];
|
||||
this._updateErrorsCount();
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide the developer toolbar.
|
||||
*/
|
||||
|
@ -207,6 +294,11 @@ DeveloperToolbar.prototype.destroy = function DT_destroy()
|
|||
{
|
||||
this._chromeWindow.getBrowser().tabContainer.removeEventListener("TabSelect", this, false);
|
||||
this._chromeWindow.getBrowser().removeEventListener("load", this, true);
|
||||
this._chromeWindow.getBrowser().removeEventListener("beforeunload", this, true);
|
||||
this._chromeWindow.removeEventListener("resize", this, false);
|
||||
|
||||
let tabs = this._chromeWindow.getBrowser().tabs;
|
||||
Array.prototype.forEach.call(tabs, this._stopErrorsCount, this);
|
||||
|
||||
this.display.onVisibilityChange.remove(this.outputPanel._visibilityChanged, this.outputPanel);
|
||||
this.display.onVisibilityChange.remove(this.tooltipPanel._visibilityChanged, this.tooltipPanel);
|
||||
|
@ -261,11 +353,148 @@ DeveloperToolbar.prototype.handleEvent = function DT_handleEvent(aEvent)
|
|||
contentDocument: contentDocument
|
||||
},
|
||||
});
|
||||
|
||||
if (aEvent.type == "TabSelect") {
|
||||
this._initErrorsCount(aEvent.target);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (aEvent.type == "resize") {
|
||||
this.outputPanel._resize();
|
||||
}
|
||||
else if (aEvent.type == "TabClose") {
|
||||
this._stopErrorsCount(aEvent.target);
|
||||
}
|
||||
else if (aEvent.type == "beforeunload") {
|
||||
this._onPageBeforeUnload(aEvent);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The handler of messages received from the nsIMessageManager.
|
||||
*
|
||||
* @param object aMessage the message received from the content process.
|
||||
*/
|
||||
DeveloperToolbar.prototype.receiveMessage = function DT_receiveMessage(aMessage)
|
||||
{
|
||||
if (!aMessage.json || !(aMessage.json.hudId in this._errorsCount)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let tabId = aMessage.json.hudId;
|
||||
let errors = this._errorsCount[tabId];
|
||||
|
||||
switch (aMessage.name) {
|
||||
case "WebConsole:PageError":
|
||||
this._onPageError(tabId, aMessage.json.pageError);
|
||||
break;
|
||||
case "WebConsole:CachedMessages":
|
||||
aMessage.json.messages.forEach(this._onPageError.bind(this, tabId));
|
||||
break;
|
||||
}
|
||||
|
||||
if (errors != this._errorsCount[tabId]) {
|
||||
this._updateErrorsCount(tabId);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Send a message to the content process using the nsIMessageManager of the
|
||||
* given tab.
|
||||
*
|
||||
* @param nsIDOMNode aTab the tab you want to send a message to.
|
||||
* @param string aName the name of the message you want to send.
|
||||
* @param object aMessage the message to send.
|
||||
*/
|
||||
DeveloperToolbar.prototype.sendMessageToTab =
|
||||
function DT_sendMessageToTab(aTab, aName, aMessage)
|
||||
{
|
||||
let tabId = aTab.linkedPanel;
|
||||
aMessage.hudId = tabId;
|
||||
if (!("id" in aMessage)) {
|
||||
aMessage.id = "DevToolbar-" + this.sequenceId;
|
||||
}
|
||||
|
||||
aTab.linkedBrowser.messageManager.sendAsyncMessage(aName, aMessage);
|
||||
};
|
||||
|
||||
/**
|
||||
* Process a "WebConsole:PageError" message received from the given tab. This
|
||||
* method counts the JavaScript exceptions received.
|
||||
*
|
||||
* @private
|
||||
* @param string aTabId the ID of the tab from where the page error comes.
|
||||
* @param object aPageError the page error object received from the content
|
||||
* process.
|
||||
*/
|
||||
DeveloperToolbar.prototype._onPageError =
|
||||
function DT__onPageError(aTabId, aPageError)
|
||||
{
|
||||
if (aPageError.category == "CSS Parser" ||
|
||||
aPageError.category == "CSS Loader" ||
|
||||
(aPageError.flags & aPageError.warningFlag) ||
|
||||
(aPageError.flags & aPageError.strictFlag)) {
|
||||
return; // just a CSS or JS warning
|
||||
}
|
||||
|
||||
this._errorsCount[aTabId]++;
|
||||
};
|
||||
|
||||
/**
|
||||
* The |beforeunload| event handler. This function resets the errors count when
|
||||
* a different page starts loading.
|
||||
*
|
||||
* @private
|
||||
* @param nsIDOMEvent aEvent the beforeunload DOM event.
|
||||
*/
|
||||
DeveloperToolbar.prototype._onPageBeforeUnload =
|
||||
function DT__onPageBeforeUnload(aEvent)
|
||||
{
|
||||
let window = aEvent.target.defaultView;
|
||||
if (window.top !== window) {
|
||||
return;
|
||||
}
|
||||
|
||||
let tabs = this._chromeWindow.getBrowser().tabs;
|
||||
Array.prototype.some.call(tabs, function(aTab) {
|
||||
if (aTab.linkedBrowser.contentWindow === window) {
|
||||
let tabId = aTab.linkedPanel;
|
||||
if (tabId in this._errorsCount) {
|
||||
this._errorsCount[tabId] = 0;
|
||||
this._updateErrorsCount(tabId);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}, this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Update the page errors count displayed in the Web Console button for the
|
||||
* currently selected tab.
|
||||
*
|
||||
* @private
|
||||
* @param string [aChangedTabId] Optional. The tab ID that had its page errors
|
||||
* count changed. If this is provided and it doesn't match the currently
|
||||
* selected tab, then the button is not updated.
|
||||
*/
|
||||
DeveloperToolbar.prototype._updateErrorsCount =
|
||||
function DT__updateErrorsCount(aChangedTabId)
|
||||
{
|
||||
let tabId = this._chromeWindow.getBrowser().selectedTab.linkedPanel;
|
||||
if (aChangedTabId && tabId != aChangedTabId) {
|
||||
return;
|
||||
}
|
||||
|
||||
let errors = this._errorsCount[tabId];
|
||||
|
||||
if (errors) {
|
||||
this._webConsoleButton.label =
|
||||
this._webConsoleButtonLabel + " (" + errors + ")";
|
||||
}
|
||||
else {
|
||||
this._webConsoleButton.label = this._webConsoleButtonLabel;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -19,12 +19,14 @@ _BROWSER_TEST_FILES = \
|
|||
browser_templater_basic.js \
|
||||
browser_toolbar_basic.js \
|
||||
browser_toolbar_tooltip.js \
|
||||
browser_toolbar_webconsole_errors_count.js \
|
||||
head.js \
|
||||
$(NULL)
|
||||
|
||||
_BROWSER_TEST_PAGES = \
|
||||
browser_templater_basic.html \
|
||||
browser_toolbar_basic.html \
|
||||
browser_toolbar_webconsole_errors_count.html \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_BROWSER_TEST_FILES)
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
<!DOCTYPE HTML>
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Developer Toolbar Tests - errors count in the Web Console button</title>
|
||||
<script type="text/javascript">
|
||||
console.log("foobarBug762996consoleLog");
|
||||
window.onload = function() {
|
||||
window.foobarBug762996load();
|
||||
};
|
||||
window.foobarBug762996a();
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
window.foobarBug762996b();
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<p>Hello world! Test for errors count in the Web Console button (developer
|
||||
toolbar).</p>
|
||||
<p style="color: foobarBug762996css"><button>click me</button></p>
|
||||
<script type="text/javascript">
|
||||
document.querySelector("button").onclick = function() {
|
||||
window.foobarBug762996click();
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,208 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests that the developer toolbar errors count works properly.
|
||||
|
||||
function test() {
|
||||
const TEST_URI = "http://example.com/browser/browser/devtools/shared/test/browser_toolbar_webconsole_errors_count.html";
|
||||
|
||||
let imported = {};
|
||||
Components.utils.import("resource:///modules/HUDService.jsm", imported);
|
||||
let HUDService = imported.HUDService;
|
||||
|
||||
let webconsole = document.getElementById("developer-toolbar-webconsole");
|
||||
let toolbar = document.getElementById("Tools:DevToolbar");
|
||||
let tab1, tab2;
|
||||
|
||||
function openToolbar(browser, tab) {
|
||||
tab1 = tab;
|
||||
ignoreAllUncaughtExceptions(false);
|
||||
|
||||
ok(!DeveloperToolbar.visible, "DeveloperToolbar is not visible");
|
||||
|
||||
expectUncaughtException();
|
||||
oneTimeObserve(DeveloperToolbar.NOTIFICATIONS.SHOW, onOpenToolbar);
|
||||
toolbar.doCommand();
|
||||
}
|
||||
|
||||
ignoreAllUncaughtExceptions();
|
||||
addTab(TEST_URI, openToolbar);
|
||||
|
||||
function getErrorsCount() {
|
||||
let match = webconsole.label.match(/\((\d+)\)$/);
|
||||
return (match || [])[1];
|
||||
}
|
||||
|
||||
function onOpenToolbar() {
|
||||
ok(DeveloperToolbar.visible, "DeveloperToolbar is visible");
|
||||
|
||||
waitForValue({
|
||||
name: "web console button shows page errors",
|
||||
validator: getErrorsCount,
|
||||
value: 3,
|
||||
success: addErrors,
|
||||
failure: finish,
|
||||
});
|
||||
}
|
||||
|
||||
function addErrors() {
|
||||
expectUncaughtException();
|
||||
let button = content.document.querySelector("button");
|
||||
EventUtils.synthesizeMouse(button, 2, 2, {}, content);
|
||||
|
||||
waitForValue({
|
||||
name: "button shows one more error after click in page",
|
||||
validator: getErrorsCount,
|
||||
value: 4,
|
||||
success: function() {
|
||||
ignoreAllUncaughtExceptions();
|
||||
addTab(TEST_URI, onOpenSecondTab);
|
||||
},
|
||||
failure: finish,
|
||||
});
|
||||
}
|
||||
|
||||
function onOpenSecondTab(browser, tab) {
|
||||
tab2 = tab;
|
||||
|
||||
ignoreAllUncaughtExceptions(false);
|
||||
expectUncaughtException();
|
||||
|
||||
waitForValue({
|
||||
name: "button shows correct number of errors after new tab is open",
|
||||
validator: getErrorsCount,
|
||||
value: 3,
|
||||
success: switchToTab1,
|
||||
failure: finish,
|
||||
});
|
||||
}
|
||||
|
||||
function switchToTab1() {
|
||||
gBrowser.selectedTab = tab1;
|
||||
waitForValue({
|
||||
name: "button shows the page errors from tab 1",
|
||||
validator: getErrorsCount,
|
||||
value: 4,
|
||||
success: function() {
|
||||
openWebConsole(tab1, onWebConsoleOpen);
|
||||
},
|
||||
failure: finish,
|
||||
});
|
||||
}
|
||||
|
||||
function openWebConsole(tab, callback)
|
||||
{
|
||||
function _onWebConsoleOpen(subject)
|
||||
{
|
||||
subject.QueryInterface(Ci.nsISupportsString);
|
||||
let hud = HUDService.getHudReferenceById(subject.data);
|
||||
executeSoon(callback.bind(null, hud));
|
||||
}
|
||||
|
||||
oneTimeObserve("web-console-created", _onWebConsoleOpen);
|
||||
|
||||
HUDService.activateHUDForContext(tab);
|
||||
}
|
||||
|
||||
function onWebConsoleOpen(hud) {
|
||||
waitForValue({
|
||||
name: "web console shows the page errors",
|
||||
validator: function() {
|
||||
return hud.outputNode.querySelectorAll(".hud-exception").length;
|
||||
},
|
||||
value: 4,
|
||||
success: checkConsoleOutput.bind(null, hud),
|
||||
failure: finish,
|
||||
});
|
||||
}
|
||||
|
||||
function checkConsoleOutput(hud) {
|
||||
let errors = ["foobarBug762996a", "foobarBug762996b", "foobarBug762996load",
|
||||
"foobarBug762996click", "foobarBug762996consoleLog",
|
||||
"foobarBug762996css"];
|
||||
errors.forEach(function(error) {
|
||||
isnot(hud.outputNode.textContent.indexOf(error), -1,
|
||||
error + " found in the Web Console output");
|
||||
});
|
||||
|
||||
hud.jsterm.clearOutput();
|
||||
|
||||
is(hud.outputNode.textContent.indexOf("foobarBug762996color"), -1,
|
||||
"clearOutput() worked");
|
||||
|
||||
expectUncaughtException();
|
||||
let button = content.document.querySelector("button");
|
||||
EventUtils.synthesizeMouse(button, 2, 2, {}, content);
|
||||
|
||||
waitForValue({
|
||||
name: "button shows one more error after another click in page",
|
||||
validator: getErrorsCount,
|
||||
value: 5,
|
||||
success: function() {
|
||||
waitForValue(waitForNewError);
|
||||
},
|
||||
failure: finish,
|
||||
});
|
||||
|
||||
let waitForNewError = {
|
||||
name: "the Web Console displays the new error",
|
||||
validator: function() {
|
||||
return hud.outputNode.textContent.indexOf("foobarBug762996click") > -1;
|
||||
},
|
||||
success: doPageReload.bind(null, hud),
|
||||
failure: finish,
|
||||
};
|
||||
}
|
||||
|
||||
function doPageReload(hud) {
|
||||
tab1.linkedBrowser.addEventListener("load", function _onReload() {
|
||||
tab1.linkedBrowser.removeEventListener("load", _onReload, true);
|
||||
ignoreAllUncaughtExceptions(false);
|
||||
expectUncaughtException();
|
||||
}, true);
|
||||
|
||||
ignoreAllUncaughtExceptions();
|
||||
content.location.reload();
|
||||
|
||||
waitForValue({
|
||||
name: "the Web Console button count has been reset after page reload",
|
||||
validator: getErrorsCount,
|
||||
value: 3,
|
||||
success: function() {
|
||||
waitForValue(waitForConsoleOutputAfterReload);
|
||||
},
|
||||
failure: finish,
|
||||
});
|
||||
|
||||
let waitForConsoleOutputAfterReload = {
|
||||
name: "the Web Console displays the correct number of errors after reload",
|
||||
validator: function() {
|
||||
return hud.outputNode.querySelectorAll(".hud-exception").length;
|
||||
},
|
||||
value: 4,
|
||||
success: function() {
|
||||
isnot(hud.outputNode.textContent.indexOf("foobarBug762996load"), -1,
|
||||
"foobarBug762996load found in console output after page reload");
|
||||
testEnd();
|
||||
},
|
||||
failure: testEnd,
|
||||
};
|
||||
}
|
||||
|
||||
function testEnd() {
|
||||
document.getElementById("developer-toolbar-closebutton").doCommand();
|
||||
HUDService.deactivateHUDForContext(tab1);
|
||||
gBrowser.removeTab(tab1);
|
||||
gBrowser.removeTab(tab2);
|
||||
finish();
|
||||
}
|
||||
|
||||
function oneTimeObserve(name, callback) {
|
||||
function _onObserve(aSubject, aTopic, aData) {
|
||||
Services.obs.removeObserver(_onObserve, name);
|
||||
callback(aSubject, aTopic, aData);
|
||||
};
|
||||
Services.obs.addObserver(_onObserve, name, false);
|
||||
}
|
||||
}
|
||||
|
|
@ -131,3 +131,67 @@ function catchFail(func) {
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Polls a given function waiting for the given value.
|
||||
*
|
||||
* @param object aOptions
|
||||
* Options object with the following properties:
|
||||
* - validator
|
||||
* A validator function that should return the expected value. This is
|
||||
* called every few milliseconds to check if the result is the expected
|
||||
* one. When the returned result is the expected one, then the |success|
|
||||
* function is called and polling stops. If |validator| never returns
|
||||
* the expected value, then polling timeouts after several tries and
|
||||
* a failure is recorded - the given |failure| function is invoked.
|
||||
* - success
|
||||
* A function called when the validator function returns the expected
|
||||
* value.
|
||||
* - failure
|
||||
* A function called if the validator function timeouts - fails to return
|
||||
* the expected value in the given time.
|
||||
* - name
|
||||
* Name of test. This is used to generate the success and failure
|
||||
* messages.
|
||||
* - timeout
|
||||
* Timeout for validator function, in milliseconds. Default is 5000 ms.
|
||||
* - value
|
||||
* The expected value. If this option is omitted then the |validator|
|
||||
* function must return a trueish value.
|
||||
* Each of the provided callback functions will receive two arguments:
|
||||
* the |aOptions| object and the last value returned by |validator|.
|
||||
*/
|
||||
function waitForValue(aOptions)
|
||||
{
|
||||
let start = Date.now();
|
||||
let timeout = aOptions.timeout || 5000;
|
||||
let lastValue;
|
||||
|
||||
function wait(validatorFn, successFn, failureFn)
|
||||
{
|
||||
if ((Date.now() - start) > timeout) {
|
||||
// Log the failure.
|
||||
ok(false, "Timed out while waiting for: " + aOptions.name);
|
||||
let expected = "value" in aOptions ?
|
||||
"'" + aOptions.value + "'" :
|
||||
"a trueish value";
|
||||
info("timeout info :: got '" + lastValue + "', expected " + expected);
|
||||
failureFn(aOptions, lastValue);
|
||||
return;
|
||||
}
|
||||
|
||||
lastValue = validatorFn(aOptions, lastValue);
|
||||
let successful = "value" in aOptions ?
|
||||
lastValue == aOptions.value :
|
||||
lastValue;
|
||||
if (successful) {
|
||||
ok(true, aOptions.name);
|
||||
successFn(aOptions, lastValue);
|
||||
}
|
||||
else {
|
||||
setTimeout(function() wait(validatorFn, successFn, failureFn), 100);
|
||||
}
|
||||
}
|
||||
|
||||
wait(aOptions.validator, aOptions.success, aOptions.failure);
|
||||
}
|
||||
|
|
|
@ -88,21 +88,19 @@ let Manager = {
|
|||
*/
|
||||
receiveMessage: function Manager_receiveMessage(aMessage)
|
||||
{
|
||||
if (!_alive) {
|
||||
if (!_alive || !aMessage.json) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!aMessage.json || (aMessage.name != "WebConsole:Init" &&
|
||||
aMessage.json.hudId != this.hudId)) {
|
||||
Cu.reportError("Web Console content script: received message " +
|
||||
aMessage.name + " from wrong hudId!");
|
||||
if (aMessage.name == "WebConsole:Init" && !this.hudId) {
|
||||
this._onInit(aMessage.json);
|
||||
return;
|
||||
}
|
||||
if (aMessage.json.hudId != this.hudId) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (aMessage.name) {
|
||||
case "WebConsole:Init":
|
||||
this._onInit(aMessage.json);
|
||||
break;
|
||||
case "WebConsole:EnableFeature":
|
||||
this.enableFeature(aMessage.json.feature, aMessage.json);
|
||||
break;
|
||||
|
@ -1286,17 +1284,8 @@ let ConsoleListener = {
|
|||
return;
|
||||
}
|
||||
|
||||
switch (aScriptError.category) {
|
||||
// We ignore chrome-originating errors as we only care about content.
|
||||
case "XPConnect JavaScript":
|
||||
case "component javascript":
|
||||
case "chrome javascript":
|
||||
case "chrome registration":
|
||||
case "XBL":
|
||||
case "XBL Prototype Handler":
|
||||
case "XBL Content Sink":
|
||||
case "xbl javascript":
|
||||
return;
|
||||
if (!this.isCategoryAllowed(aScriptError.category)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let errorWindow =
|
||||
|
@ -1309,6 +1298,33 @@ let ConsoleListener = {
|
|||
Manager.sendMessage("WebConsole:PageError", { pageError: aScriptError });
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Check if the given script error category is allowed to be tracked or not.
|
||||
* We ignore chrome-originating errors as we only care about content.
|
||||
*
|
||||
* @param string aCategory
|
||||
* The nsIScriptError category you want to check.
|
||||
* @return boolean
|
||||
* True if the category is allowed to be logged, false otherwise.
|
||||
*/
|
||||
isCategoryAllowed: function CL_isCategoryAllowed(aCategory)
|
||||
{
|
||||
switch (aCategory) {
|
||||
case "XPConnect JavaScript":
|
||||
case "component javascript":
|
||||
case "chrome javascript":
|
||||
case "chrome registration":
|
||||
case "XBL":
|
||||
case "XBL Prototype Handler":
|
||||
case "XBL Content Sink":
|
||||
case "xbl javascript":
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the cached page errors for the current inner window.
|
||||
*
|
||||
|
@ -1326,14 +1342,15 @@ let ConsoleListener = {
|
|||
|
||||
(errors.value || []).forEach(function(aError) {
|
||||
if (!(aError instanceof Ci.nsIScriptError) ||
|
||||
aError.innerWindowID != innerWindowId) {
|
||||
aError.innerWindowID != innerWindowId ||
|
||||
!this.isCategoryAllowed(aError.category)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let remoteMessage = WebConsoleUtils.cloneObject(aError);
|
||||
remoteMessage._type = "PageError";
|
||||
result.push(remoteMessage);
|
||||
});
|
||||
}, this);
|
||||
|
||||
return result;
|
||||
},
|
||||
|
|
|
@ -1412,10 +1412,8 @@ HeadsUpDisplay.prototype = {
|
|||
switch (aMessage._type) {
|
||||
case "PageError": {
|
||||
let category = this.categoryForScriptError(aMessage.category);
|
||||
if (category != -1) {
|
||||
this.outputMessage(category, this.reportPageError,
|
||||
[category, aMessage]);
|
||||
}
|
||||
this.outputMessage(category, this.reportPageError,
|
||||
[category, aMessage]);
|
||||
break;
|
||||
}
|
||||
case "ConsoleAPI":
|
||||
|
@ -2053,10 +2051,6 @@ HeadsUpDisplay.prototype = {
|
|||
*/
|
||||
reportPageError: function HUD_reportPageError(aCategory, aScriptError)
|
||||
{
|
||||
if (!aScriptError.outerWindowID) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Warnings and legacy strict errors become warnings; other types become
|
||||
// errors.
|
||||
let severity = SEVERITY_ERROR;
|
||||
|
@ -2083,24 +2077,13 @@ HeadsUpDisplay.prototype = {
|
|||
*
|
||||
* @param nsIScriptError aScriptError
|
||||
* The script error you want to determine the category for.
|
||||
* @return CATEGORY_JS|CATEGORY_CSS|-1
|
||||
* @return CATEGORY_JS|CATEGORY_CSS
|
||||
* Depending on the script error CATEGORY_JS or CATEGORY_CSS can be
|
||||
* returned. If the category is unknown -1 is returned.
|
||||
* returned.
|
||||
*/
|
||||
categoryForScriptError: function HUD_categoryForScriptError(aScriptError)
|
||||
{
|
||||
switch (aScriptError.category) {
|
||||
// We ignore chrome-originating errors as we only care about content.
|
||||
case "XPConnect JavaScript":
|
||||
case "component javascript":
|
||||
case "chrome javascript":
|
||||
case "chrome registration":
|
||||
case "XBL":
|
||||
case "XBL Prototype Handler":
|
||||
case "XBL Content Sink":
|
||||
case "xbl javascript":
|
||||
return -1;
|
||||
|
||||
case "CSS Parser":
|
||||
case "CSS Loader":
|
||||
return CATEGORY_CSS;
|
||||
|
@ -2282,8 +2265,6 @@ HeadsUpDisplay.prototype = {
|
|||
receiveMessage: function HUD_receiveMessage(aMessage)
|
||||
{
|
||||
if (!aMessage.json || aMessage.json.hudId != this.hudId) {
|
||||
Cu.reportError("JSTerm: received message " + aMessage.name +
|
||||
" from wrong hudId.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2306,10 +2287,8 @@ HeadsUpDisplay.prototype = {
|
|||
case "WebConsole:PageError": {
|
||||
let pageError = aMessage.json.pageError;
|
||||
let category = this.categoryForScriptError(pageError);
|
||||
if (category != -1) {
|
||||
this.outputMessage(category, this.reportPageError,
|
||||
[category, pageError]);
|
||||
}
|
||||
this.outputMessage(category, this.reportPageError,
|
||||
[category, pageError]);
|
||||
break;
|
||||
}
|
||||
case "WebConsole:CachedMessages":
|
||||
|
|
Загрузка…
Ссылка в новой задаче