*/
+const TEST_URI = "data:text/html;charset=utf-8,Web Console test for bug 614793: jsterm result scroll";
+
+"use strict";
+
+let test = asyncTest(function* () {
+ let { browser } = yield loadTab(TEST_URI);
+
+ let hud = yield openConsole();
+
+ yield consoleOpened(hud);
+});
+
function consoleOpened(hud) {
+ let deferred = promise.defer();
+
hud.jsterm.clearOutput();
let scrollNode = hud.outputNode.parentNode;
@@ -29,7 +43,7 @@ function consoleOpened(hud) {
oldScrollTop = scrollNode.scrollTop;
isnot(oldScrollTop, 0, "scroll location is not at the top");
- hud.jsterm.execute("'hello world'", onExecute);
+ hud.jsterm.execute("'hello world'").then(onExecute);
});
function onExecute(msg)
@@ -42,15 +56,8 @@ function consoleOpened(hud) {
is(scrollNode.scrollTop, oldScrollTop, "scroll location is the same");
- finishTest();
+ deferred.resolve();
}
-}
-function test() {
- addTab("data:text/html;charset=utf-8,Web Console test for bug 614793: jsterm result scroll");
- browser.addEventListener("load", function onLoad(aEvent) {
- browser.removeEventListener(aEvent.type, onLoad, true);
- openConsole(null, consoleOpened);
- }, true);
+ return deferred.promise;
}
-
diff --git a/browser/devtools/webconsole/test/browser_webconsole_bug_618078_network_exceptions.js b/browser/devtools/webconsole/test/browser_webconsole_bug_618078_network_exceptions.js
index cdd616c72eae..cb98e2c0dc62 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_618078_network_exceptions.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_618078_network_exceptions.js
@@ -6,26 +6,24 @@
// Tests that we report JS exceptions in event handlers coming from
// network requests, like onreadystate for XHR. See bug 618078.
-const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/test-bug-618078-network-exceptions.html";
+const TEST_URI = "data:text/html;charset=utf-8,Web Console test for bug 618078";
+const TEST_URI2 = "http://example.com/browser/browser/devtools/webconsole/test/test-bug-618078-network-exceptions.html";
-function test()
-{
- addTab("data:text/html;charset=utf-8,Web Console test for bug 618078");
+let test = asyncTest(function* () {
+ yield loadTab(TEST_URI);
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
- openConsole(null, function(hud) {
- expectUncaughtException();
- content.location = TEST_URI;
+ let hud = yield openConsole();
- waitForMessages({
- webconsole: hud,
- messages: [{
- text: "bug618078exception",
- category: CATEGORY_JS,
- severity: SEVERITY_ERROR,
- }],
- }).then(finishTest);
- });
- }, true);
-}
+ expectUncaughtException();
+
+ content.location = TEST_URI2;
+
+ yield waitForMessages({
+ webconsole: hud,
+ messages: [{
+ text: "bug618078exception",
+ category: CATEGORY_JS,
+ severity: SEVERITY_ERROR,
+ }],
+ });
+});
diff --git a/browser/devtools/webconsole/test/browser_webconsole_bug_618311_close_panels.js b/browser/devtools/webconsole/test/browser_webconsole_bug_618311_close_panels.js
index 461d2f10e9f4..6d3c9e4e5610 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_618311_close_panels.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_618311_close_panels.js
@@ -5,28 +5,28 @@
const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/test-console.html";
-function test() {
- addTab(TEST_URI);
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
+let test = asyncTest(function* () {
+ yield loadTab(TEST_URI);
- openConsole(null, function(hud) {
- content.location.reload();
+ let hud = yield openConsole();
- waitForMessages({
- webconsole: hud,
- messages: [{
- text: "test-console.html",
- category: CATEGORY_NETWORK,
- severity: SEVERITY_LOG,
- }],
- }).then(performTest);
- });
- }, true);
-}
+ BrowserReload();
-function performTest(results) {
- let HUD = HUDService.getHudByWindow(content);
+ let results = yield waitForMessages({
+ webconsole: hud,
+ messages: [{
+ text: "test-console.html",
+ category: CATEGORY_NETWORK,
+ severity: SEVERITY_LOG,
+ }],
+ })
+
+ yield performTest(hud, results);
+});
+
+
+function performTest(HUD, results) {
+ let deferred = promise.defer();
let networkMessage = [...results[0].matched][0];
ok(networkMessage, "network message element");
@@ -69,7 +69,7 @@ function performTest(results) {
let popups = popupset.querySelectorAll("panel[hudId=" + HUD.hudId + "]");
is(popups.length, 0, "no popups found");
- executeSoon(finishTest);
+ executeSoon(deferred.resolve);
});
};
@@ -85,4 +85,6 @@ function performTest(results) {
EventUtils.sendMouseEvent({ type: "mousedown" }, networkLink, HUD.iframeWindow);
EventUtils.sendMouseEvent({ type: "mouseup" }, networkLink, HUD.iframeWindow);
EventUtils.sendMouseEvent({ type: "click" }, networkLink, HUD.iframeWindow);
+
+ return deferred.promise;
}
diff --git a/browser/devtools/webconsole/test/browser_webconsole_bug_621644_jsterm_dollar.js b/browser/devtools/webconsole/test/browser_webconsole_bug_621644_jsterm_dollar.js
index 3c7f8d95d615..085887e699ac 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_621644_jsterm_dollar.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_621644_jsterm_dollar.js
@@ -9,32 +9,41 @@
const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/test-bug-621644-jsterm-dollar.html";
-function test$(HUD) {
+let test = asyncTest(function* () {
+ yield loadTab(TEST_URI);
+
+ let hud = yield openConsole();
+
+ yield test$(hud);
+ yield test$$(hud);
+});
+
+
+function* test$(HUD) {
+ let deferred = promise.defer();
+
HUD.jsterm.clearOutput();
HUD.jsterm.execute("$(document.body)", (msg) => {
ok(msg.textContent.indexOf("") > -1,
"jsterm output is correct for $()");
-
- test$$(HUD);
+ deferred.resolve();
});
+
+ return deferred.promise;
}
function test$$(HUD) {
+ let deferred = promise.defer();
+
HUD.jsterm.clearOutput();
HUD.jsterm.setInputValue();
HUD.jsterm.execute("$$(document)", (msg) => {
ok(msg.textContent.indexOf("621644") > -1,
"jsterm output is correct for $$()");
- finishTest();
+ deferred.resolve();
});
-}
-function test() {
- addTab(TEST_URI);
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
- openConsole(null, test$);
- }, true);
+ return deferred.promise;
}
diff --git a/browser/devtools/webconsole/test/browser_webconsole_bug_622303_persistent_filters.js b/browser/devtools/webconsole/test/browser_webconsole_bug_622303_persistent_filters.js
index 39d075a560b1..15c603475858 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_622303_persistent_filters.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_622303_persistent_filters.js
@@ -1,7 +1,7 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
-let prefs = {
+const prefs = {
"net": [
"network",
"netwarn",
@@ -25,7 +25,7 @@ let prefs = {
]
};
-function test() {
+let test = asyncTest(function* () {
// Set all prefs to true
for (let category in prefs) {
prefs[category].forEach(function(pref) {
@@ -33,11 +33,25 @@ function test() {
});
}
- addTab("about:blank");
- openConsole(null, onConsoleOpen);
-}
+ yield loadTab("about:blank");
+
+ let hud = yield openConsole();
+
+ let hud2 = yield onConsoleOpen(hud);
+ let hud3 = yield onConsoleReopen1(hud2);
+ yield onConsoleReopen2(hud3);
+
+ // Clear prefs
+ for (let category in prefs) {
+ prefs[category].forEach(function(pref) {
+ Services.prefs.clearUserPref("devtools.webconsole.filter." + pref);
+ });
+ }
+});
function onConsoleOpen(hud) {
+ let deferred = promise.defer();
+
let hudBox = hud.ui.rootElement;
// Check if the filters menuitems exists and are checked
@@ -60,12 +74,17 @@ function onConsoleOpen(hud) {
}
//Re-init the console
- closeConsole(null, function() {
- openConsole(null, onConsoleReopen1);
+ closeConsole().then(() => {
+ openConsole().then(deferred.resolve);
});
+
+ return deferred.promise;
}
function onConsoleReopen1(hud) {
+ info("testing after reopening once");
+ let deferred = promise.defer();
+
let hudBox = hud.ui.rootElement;
// Check if the filter button and menuitems are unchecked
@@ -86,12 +105,16 @@ function onConsoleReopen1(hud) {
}
// Re-init the console
- closeConsole(null, function() {
- openConsole(null, onConsoleReopen2);
+ closeConsole().then(() => {
+ openConsole().then(deferred.resolve);
});
+
+ return deferred.promise;
}
function onConsoleReopen2(hud) {
+ info("testing after reopening again");
+
let hudBox = hud.ui.rootElement;
// Check the main category button is checked and first menuitem is checked
@@ -104,16 +127,6 @@ function onConsoleReopen2(hud) {
let menuitem = hudBox.querySelector("menuitem[prefKey=" + pref + "]");
ok(isChecked(menuitem), "first " + category + " menuitem is checked");
}
-
- // Clear prefs
- for (let category in prefs) {
- prefs[category].forEach(function(pref) {
- Services.prefs.clearUserPref("devtools.webconsole.filter." + pref);
- });
- }
-
- prefs = null;
- finishTest();
}
function isChecked(aNode) {
diff --git a/browser/devtools/webconsole/test/browser_webconsole_bug_623749_ctrl_a_select_all_winnt.js b/browser/devtools/webconsole/test/browser_webconsole_bug_623749_ctrl_a_select_all_winnt.js
index 6e93ce523479..84cd52c4a0ac 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_623749_ctrl_a_select_all_winnt.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_623749_ctrl_a_select_all_winnt.js
@@ -4,16 +4,14 @@
// Test for https://bugzilla.mozilla.org/show_bug.cgi?id=623749
// Map Control + A to Select All, In the web console input, on Windows
-function test() {
- addTab("data:text/html;charset=utf-8,Test console for bug 623749");
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
- openConsole(null, runTest);
- }, true);
-}
+const TEST_URI = "data:text/html;charset=utf-8,Test console for bug 623749";
-function runTest(HUD) {
- let jsterm = HUD.jsterm;
+let test = asyncTest(function* () {
+ yield loadTab(TEST_URI);
+
+ let hud = yield openConsole();
+
+ let jsterm = hud.jsterm;
jsterm.setInputValue("Ignore These Four Words");
let inputNode = jsterm.inputNode;
@@ -27,6 +25,4 @@ function runTest(HUD) {
inputNode.selectionStart = 0;
EventUtils.synthesizeKey("e", { ctrlKey: true });
is(inputNode.selectionStart, 0, "Control + E does not move to end of input");
-
- executeSoon(finishTest);
-}
+});
diff --git a/browser/devtools/webconsole/test/browser_webconsole_bug_630733_response_redirect_headers.js b/browser/devtools/webconsole/test/browser_webconsole_bug_630733_response_redirect_headers.js
index dba3f760589f..88f77127558d 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_630733_response_redirect_headers.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_630733_response_redirect_headers.js
@@ -7,35 +7,51 @@
* Mihai Sucan
*/
-const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/test-bug-630733-response-redirect-headers.sjs";
+const TEST_URI = "data:text/html;charset=utf-8,Web Console test for bug 630733";
+const TEST_URI2 = "http://example.com/browser/browser/devtools/webconsole/test/test-bug-630733-response-redirect-headers.sjs";
let lastFinishedRequests = {};
let webConsoleClient;
+let test = asyncTest(function* () {
+ yield loadTab(TEST_URI);
+
+ let hud = yield openConsole();
+
+ yield consoleOpened(hud);
+ yield getHeaders();
+ yield getContent();
+
+ performTest();
+});
+
function consoleOpened(hud)
{
+ let deferred = promise.defer();
+
webConsoleClient = hud.ui.webConsoleClient;
hud.ui.setSaveRequestAndResponseBodies(true).then(() => {
ok(hud.ui._saveRequestAndResponseBodies,
"The saveRequestAndResponseBodies property was successfully set.");
- HUDService.lastFinishedRequest.callback = requestDoneCallback;
- content.location = TEST_URI;
+ HUDService.lastFinishedRequest.callback = (aHttpRequest) => {
+ let status = aHttpRequest.response.status;
+ lastFinishedRequests[status] = aHttpRequest;
+ if ("301" in lastFinishedRequests &&
+ "404" in lastFinishedRequests) {
+ deferred.resolve();
+ }
+ }
+ content.location = TEST_URI2;
});
-}
-function requestDoneCallback(aHttpRequest)
-{
- let status = aHttpRequest.response.status;
- lastFinishedRequests[status] = aHttpRequest;
- if ("301" in lastFinishedRequests &&
- "404" in lastFinishedRequests) {
- getHeaders();
- }
+ return deferred.promise;
}
function getHeaders()
{
+ let deferred = promise.defer();
+
HUDService.lastFinishedRequest.callback = null;
ok("301" in lastFinishedRequests, "request 1: 301 Moved Permanently");
@@ -48,13 +64,16 @@ function getHeaders()
webConsoleClient.getResponseHeaders(lastFinishedRequests["404"].actor,
function (aResponse) {
lastFinishedRequests["404"].response.headers = aResponse.headers;
- executeSoon(getContent);
+ executeSoon(deferred.resolve);
});
});
+ return deferred.promise;
}
function getContent()
{
+ let deferred = promise.defer();
+
webConsoleClient.getResponseContent(lastFinishedRequests["301"].actor,
function (aResponse) {
lastFinishedRequests["301"].response.content = aResponse.content;
@@ -67,9 +86,10 @@ function getContent()
aResponse.contentDiscarded;
webConsoleClient = null;
- executeSoon(performTest);
+ executeSoon(deferred.resolve);
});
});
+ return deferred.promise;
}
function performTest()
@@ -106,16 +126,5 @@ function performTest()
isnot(body.indexOf("404"), -1,
"body is correct for request 2");
- lastFinishedRequests = null;
- executeSoon(finishTest);
-}
-
-function test()
-{
- addTab("data:text/html;charset=utf-8,
Web Console test for bug 630733");
-
- browser.addEventListener("load", function onLoad(aEvent) {
- browser.removeEventListener(aEvent.type, onLoad, true);
- openConsole(null, consoleOpened);
- }, true);
+ lastFinishedRequests = webConsoleClient = null;
}
diff --git a/browser/devtools/webconsole/test/browser_webconsole_bug_632275_getters_document_width.js b/browser/devtools/webconsole/test/browser_webconsole_bug_632275_getters_document_width.js
index 756cb3e7dcd8..6b0a3d09700f 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_632275_getters_document_width.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_632275_getters_document_width.js
@@ -13,11 +13,9 @@ const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/te
let getterValue = null;
function test() {
- addTab(TEST_URI);
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
- openConsole(null, consoleOpened);
- }, true);
+ loadTab(TEST_URI).then(() => {
+ openConsole().then(consoleOpened);
+ });
}
function consoleOpened(hud) {
@@ -46,6 +44,7 @@ function onViewOpened(hud, event, view)
is(textContent.indexOf("document.body.client"), -1,
"no document.width/height warning displayed");
+ getterValue = null;
finishTest();
});
}
diff --git a/browser/devtools/webconsole/test/browser_webconsole_bug_632347_iterators_generators.js b/browser/devtools/webconsole/test/browser_webconsole_bug_632347_iterators_generators.js
index be5e2d81a4c9..0410a6968a0a 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_632347_iterators_generators.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_632347_iterators_generators.js
@@ -8,11 +8,9 @@ const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/te
function test() {
requestLongerTimeout(6);
- addTab(TEST_URI);
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
- openConsole(null, consoleOpened);
- }, true);
+ loadTab(TEST_URI).then(() => {
+ openConsole().then(consoleOpened);
+ });
}
function consoleOpened(HUD) {
diff --git a/browser/devtools/webconsole/test/browser_webconsole_bug_632817.js b/browser/devtools/webconsole/test/browser_webconsole_bug_632817.js
index e77d7be45b79..c42ff615e9ff 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_632817.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_632817.js
@@ -11,8 +11,11 @@ const TEST_IMG = "http://example.com/browser/browser/devtools/webconsole/test/te
const TEST_DATA_JSON_CONTENT =
'{ id: "test JSON data", myArray: [ "foo", "bar", "baz", "biff" ] }';
+const TEST_URI = "data:text/html;charset=utf-8,Web Console network logging tests";
+
let lastRequest = null;
let requestCallback = null;
+let hud, browser;
function test()
{
@@ -25,12 +28,9 @@ function test()
Services.prefs.clearUserPref(PREF);
});
- addTab("data:text/html;charset=utf-8,Web Console network logging tests");
-
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
-
- openConsole(null, function(aHud) {
+ loadTab(TEST_URI).then((tab) => {
+ browser = tab.browser;
+ openConsole().then((aHud) => {
hud = aHud;
HUDService.lastFinishedRequest.callback = function(aRequest) {
@@ -41,8 +41,8 @@ function test()
};
executeSoon(testPageLoad);
- });
- }, true);
+ })
+ });
}
function testPageLoad()
@@ -186,6 +186,7 @@ function testLiveFilteringOnSearchStrings() {
HUDService.lastFinishedRequest.callback = null;
lastRequest = null;
requestCallback = null;
+ hud = browser = null;
finishTest();
}
diff --git a/browser/devtools/webconsole/test/browser_webconsole_bug_644419_log_limits.js b/browser/devtools/webconsole/test/browser_webconsole_bug_644419_log_limits.js
index 2f3a0127db18..ac489ee42981 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_644419_log_limits.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_644419_log_limits.js
@@ -7,44 +7,54 @@
// Tests that the Web Console limits the number of lines displayed according to
// the limit set for each category.
+const INIT_URI = "data:text/html;charset=utf-8,Web Console test for bug 644419: Console should " +
+ "have user-settable log limits for each message category";
+
const TEST_URI = "http://example.com/browser/browser/devtools/" +
"webconsole/test/test-bug-644419-log-limits.html";
let hud, outputNode;
-function test() {
- addTab("data:text/html;charset=utf-8,Web Console test for bug 644419: Console should " +
- "have user-settable log limits for each message category");
- browser.addEventListener("load", onLoad, true);
-}
+let test = asyncTest(function* () {
+ let { browser } = yield loadTab(INIT_URI);
-function onLoad(aEvent) {
- browser.removeEventListener(aEvent.type, onLoad, true);
+ hud = yield openConsole();
- openConsole(null, function(aHud) {
- aHud.jsterm.clearOutput();
- hud = aHud;
- outputNode = aHud.outputNode;
+ hud.jsterm.clearOutput();
+ outputNode = hud.outputNode;
- browser.addEventListener("load", testWebDevLimits, true);
- expectUncaughtException();
- content.location = TEST_URI;
- });
-}
+ let loaded = loadBrowser(browser);
-function testWebDevLimits(aEvent) {
- browser.removeEventListener(aEvent.type, testWebDevLimits, true);
+ expectUncaughtException();
+
+ content.location = TEST_URI;
+ yield loaded;
+
+ yield testWebDevLimits();
+ yield testWebDevLimits2();
+ yield testJsLimits();
+ yield testJsLimits2();
+
+ yield testNetLimits();
+ yield loadImage();
+ yield testCssLimits();
+ yield testCssLimits2();
+
+ hud = outputNode = null;
+});
+
+function testWebDevLimits() {
Services.prefs.setIntPref("devtools.hud.loglimit.console", 10);
// Find the sentinel entry.
- waitForMessages({
+ return waitForMessages({
webconsole: hud,
messages: [{
text: "bar is not defined",
category: CATEGORY_JS,
severity: SEVERITY_ERROR,
}],
- }).then(testWebDevLimits2);
+ })
}
function testWebDevLimits2() {
@@ -53,7 +63,7 @@ function testWebDevLimits2() {
content.console.log("test message " + i);
}
- waitForMessages({
+ return waitForMessages({
webconsole: hud,
messages: [{
text: "test message 10",
@@ -67,7 +77,6 @@ function testWebDevLimits2() {
findLogEntry("bar is not defined");
Services.prefs.clearUserPref("devtools.hud.loglimit.console");
- testJsLimits();
});
}
@@ -78,14 +87,14 @@ function testJsLimits() {
content.console.log("testing JS limits");
// Find the sentinel entry.
- waitForMessages({
+ return waitForMessages({
webconsole: hud,
messages: [{
text: "testing JS limits",
category: CATEGORY_WEBDEV,
severity: SEVERITY_LOG,
}],
- }).then(testJsLimits2);
+ });
}
function testJsLimits2() {
@@ -94,11 +103,12 @@ function testJsLimits2() {
for (let i = 0; i < 11; i++) {
var script = content.document.createElement("script");
script.text = "fubar" + i + ".bogus(6);";
+
expectUncaughtException();
head.insertBefore(script, head.firstChild);
}
- waitForMessages({
+ return waitForMessages({
webconsole: hud,
messages: [{
text: "fubar10 is not defined",
@@ -112,7 +122,6 @@ function testJsLimits2() {
findLogEntry("testing JS limits");
Services.prefs.clearUserPref("devtools.hud.loglimit.exception");
- testNetLimits();
});
}
@@ -125,7 +134,7 @@ function testNetLimits() {
content.console.log("testing Net limits");
// Find the sentinel entry.
- waitForMessages({
+ return waitForMessages({
webconsole: hud,
messages: [{
text: "testing Net limits",
@@ -135,7 +144,6 @@ function testNetLimits() {
}).then(() => {
// Fill the log with network messages.
gCounter = 0;
- loadImage();
});
}
@@ -153,7 +161,7 @@ function loadImage() {
is(gCounter, 11, "loaded 11 files");
- waitForMessages({
+ return waitForMessages({
webconsole: hud,
messages: [{
text: "test-image.png",
@@ -169,7 +177,6 @@ function loadImage() {
findLogEntry("testing Net limits");
Services.prefs.clearUserPref("devtools.hud.loglimit.network");
- testCssLimits();
});
}
@@ -180,14 +187,14 @@ function testCssLimits() {
content.console.log("testing CSS limits");
// Find the sentinel entry.
- waitForMessages({
+ return waitForMessages({
webconsole: hud,
messages: [{
text: "testing CSS limits",
category: CATEGORY_WEBDEV,
severity: SEVERITY_LOG,
}],
- }).then(testCssLimits2);
+ });
}
function testCssLimits2() {
@@ -199,7 +206,7 @@ function testCssLimits2() {
body.insertBefore(div, body.firstChild);
}
- waitForMessages({
+ return waitForMessages({
webconsole: hud,
messages: [{
text: "-moz-foobar10",
@@ -214,6 +221,5 @@ function testCssLimits2() {
findLogEntry("testing CSS limits");
Services.prefs.clearUserPref("devtools.hud.loglimit.cssparser");
- finishTest();
});
}
diff --git a/browser/devtools/webconsole/test/browser_webconsole_bug_646025_console_file_location.js b/browser/devtools/webconsole/test/browser_webconsole_bug_646025_console_file_location.js
index aeca2751a18e..39be46e41aee 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_646025_console_file_location.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_646025_console_file_location.js
@@ -6,51 +6,49 @@
// Tests that console logging methods display the method location along with
// the output in the console.
-const TEST_URI = "http://example.com/browser/browser/devtools/" +
+const TEST_URI = "data:text/html;charset=utf-8,Web Console file location display test";
+const TEST_URI2 = "http://example.com/browser/browser/devtools/" +
"webconsole/test/" +
"test-bug-646025-console-file-location.html";
-function test() {
- addTab("data:text/html;charset=utf-8,Web Console file location display test");
- browser.addEventListener("load", onLoad, true);
-}
+let test = asyncTest(function* () {
+ yield loadTab(TEST_URI);
-function onLoad(aEvent) {
- browser.removeEventListener(aEvent.type, onLoad, true);
- openConsole(null, function(hud) {
- content.location = TEST_URI;
- waitForMessages({
- webconsole: hud,
- messages: [{
- text: "message for level log",
- category: CATEGORY_WEBDEV,
- severity: SEVERITY_LOG,
- source: { url: "test-file-location.js", line: 5 },
- },
- {
- text: "message for level info",
- category: CATEGORY_WEBDEV,
- severity: SEVERITY_INFO,
- source: { url: "test-file-location.js", line: 6 },
- },
- {
- text: "message for level warn",
- category: CATEGORY_WEBDEV,
- severity: SEVERITY_WARNING,
- source: { url: "test-file-location.js", line: 7 },
- },
- {
- text: "message for level error",
- category: CATEGORY_WEBDEV,
- severity: SEVERITY_ERROR,
- source: { url: "test-file-location.js", line: 8 },
- },
- {
- text: "message for level debug",
- category: CATEGORY_WEBDEV,
- severity: SEVERITY_LOG,
- source: { url: "test-file-location.js", line: 9 },
- }],
- }).then(finishTest);
+ let hud = yield openConsole();
+
+ content.location = TEST_URI2;
+
+ yield waitForMessages({
+ webconsole: hud,
+ messages: [{
+ text: "message for level log",
+ category: CATEGORY_WEBDEV,
+ severity: SEVERITY_LOG,
+ source: { url: "test-file-location.js", line: 5 },
+ },
+ {
+ text: "message for level info",
+ category: CATEGORY_WEBDEV,
+ severity: SEVERITY_INFO,
+ source: { url: "test-file-location.js", line: 6 },
+ },
+ {
+ text: "message for level warn",
+ category: CATEGORY_WEBDEV,
+ severity: SEVERITY_WARNING,
+ source: { url: "test-file-location.js", line: 7 },
+ },
+ {
+ text: "message for level error",
+ category: CATEGORY_WEBDEV,
+ severity: SEVERITY_ERROR,
+ source: { url: "test-file-location.js", line: 8 },
+ },
+ {
+ text: "message for level debug",
+ category: CATEGORY_WEBDEV,
+ severity: SEVERITY_LOG,
+ source: { url: "test-file-location.js", line: 9 },
+ }],
});
-}
+});
diff --git a/browser/devtools/webconsole/test/browser_webconsole_bug_651501_document_body_autocomplete.js b/browser/devtools/webconsole/test/browser_webconsole_bug_651501_document_body_autocomplete.js
index 50c885c57738..9f2969214e8d 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_651501_document_body_autocomplete.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_651501_document_body_autocomplete.js
@@ -5,19 +5,28 @@
*/
// Tests that document.body autocompletes in the web console.
+const TEST_URI = "data:text/html;charset=utf-8,Web Console autocompletion bug in document.body";
-function test() {
- addTab("data:text/html;charset=utf-8,Web Console autocompletion bug in document.body");
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
- openConsole(null, consoleOpened);
- }, true);
-}
+"use strict";
let gHUD;
+let test = asyncTest(function* () {
+ yield loadTab(TEST_URI);
+
+ gHUD = yield openConsole();
+
+ yield consoleOpened();
+ yield autocompletePopupHidden();
+ let view = yield testPropertyPanel();
+ yield onVariablesViewReady(view);
+
+ gHUD = null;
+});
+
function consoleOpened(aHud) {
- gHUD = aHud;
+ let deferred = promise.defer();
+
let jsterm = gHUD.jsterm;
let popup = jsterm.autocompletePopup;
let completeNode = jsterm.completeNode;
@@ -38,17 +47,21 @@ function consoleOpened(aHud) {
isnot(jsterm._autocompleteCache.indexOf("ATTRIBUTE_NODE"), -1,
"ATTRIBUTE_NODE is in the list of suggestions");
- popup._panel.addEventListener("popuphidden", autocompletePopupHidden, false);
+ popup._panel.addEventListener("popuphidden", deferred.resolve, false);
EventUtils.synthesizeKey("VK_ESCAPE", {});
}, false);
jsterm.setInputValue("document.body");
EventUtils.synthesizeKey(".", {});
+
+ return deferred.promise;
}
function autocompletePopupHidden()
{
+ let deferred = promise.defer();
+
let jsterm = gHUD.jsterm;
let popup = jsterm.autocompletePopup;
let completeNode = jsterm.completeNode;
@@ -60,34 +73,37 @@ function autocompletePopupHidden()
jsterm.once("autocomplete-updated", function() {
is(completeNode.value, testStr + "dy", "autocomplete shows document.body");
- testPropertyPanel();
+ deferred.resolve();
});
let inputStr = "document.b";
jsterm.setInputValue(inputStr);
EventUtils.synthesizeKey("o", {});
let testStr = inputStr.replace(/./g, " ") + " ";
+
+ return deferred.promise;
}
function testPropertyPanel()
{
+ let deferred = promise.defer();
+
let jsterm = gHUD.jsterm;
jsterm.clearOutput();
jsterm.execute("document", (msg) => {
- jsterm.once("variablesview-fetched", onVariablesViewReady);
+ jsterm.once("variablesview-fetched", (aEvent, aView) => {
+ deferred.resolve(aView);
+ });
let anchor = msg.querySelector(".message-body a");
EventUtils.synthesizeMouse(anchor, 2, 2, {}, gHUD.iframeWindow);
});
+
+ return deferred.promise;
}
-function onVariablesViewReady(aEvent, aView)
+function onVariablesViewReady(aView)
{
- findVariableViewProperties(aView, [
+ return findVariableViewProperties(aView, [
{ name: "body", value: "
" },
- ], { webconsole: gHUD }).then(finishUp);
-}
-
-function finishUp() {
- gHUD = null;
- finishTest();
+ ], { webconsole: gHUD });
}
diff --git a/browser/devtools/webconsole/test/browser_webconsole_bug_653531_highlighter_console_helper.js b/browser/devtools/webconsole/test/browser_webconsole_bug_653531_highlighter_console_helper.js
index 8874cb11e441..85d2a0466815 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_653531_highlighter_console_helper.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_653531_highlighter_console_helper.js
@@ -6,13 +6,13 @@
///////////////////
//
// Whitelisting this test.
-// As part of bug 1077403, the leaking uncaught rejection should be fixed.
+// As part of bug 1077403, the leaking uncaught rejection should be fixed.
//
thisTestLeaksUncaughtRejectionsAndShouldBeFixed("Protocol error (unknownError): TypeError: this.conn.getActor(...) is null");
// Tests that the $0 console helper works as intended.
-let inspector, h1;
+let inspector, h1, outputNode;
function createDocument() {
let doc = content.document;
@@ -50,7 +50,7 @@ function createDocument() {
function setupHighlighterTests() {
ok(h1, "we have the header node");
- openInspector(runSelectionTests);
+ openInspector().then(runSelectionTests);
}
let runSelectionTests = Task.async(function*(aInspector) {
@@ -95,7 +95,7 @@ function performWebConsoleTests(hud) {
is(inspector.selection.node.textContent, "bug653531",
"node successfully updated");
- inspector = h1 = null;
+ inspector = h1 = outputNode = null;
gBrowser.removeCurrentTab();
finishTest();
}
diff --git a/browser/devtools/webconsole/test/browser_webconsole_bug_658368_time_methods.js b/browser/devtools/webconsole/test/browser_webconsole_bug_658368_time_methods.js
index b45f5ac15f63..8cb87324e51c 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_658368_time_methods.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_658368_time_methods.js
@@ -6,82 +6,61 @@
// Tests that the Console API implements the time() and timeEnd() methods.
-function test() {
- addTab("http://example.com/browser/browser/devtools/webconsole/" +
- "test/test-bug-658368-time-methods.html");
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
- Task.spawn(runner);
- }, true);
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/" +
+ "test/test-bug-658368-time-methods.html";
- function* runner() {
- let hud1 = yield openConsole();
+const TEST_URI2 = "data:text/html;charset=utf-8,";
- yield waitForMessages({
- webconsole: hud1,
- messages: [{
- name: "aTimer started",
- consoleTime: "aTimer",
- }, {
- name: "aTimer end",
- consoleTimeEnd: "aTimer",
- }],
- });
-
- let deferred = promise.defer();
-
- // The next test makes sure that timers with the same name but in separate
- // tabs, do not contain the same value.
- addTab("data:text/html;charset=utf-8,");
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
- openConsole().then((hud) => {
- deferred.resolve(hud);
- });
- }, true);
-
- let hud2 = yield deferred.promise;
-
- testLogEntry(hud2.outputNode, "bTimer: timer started",
- "bTimer was not started", false, true);
-
- // The next test makes sure that timers with the same name but in separate
- // pages, do not contain the same value.
- content.location = "data:text/html;charset=utf-8,";
- yield waitForMessages({
- webconsole: hud2,
- messages: [{
- name: "bTimer started",
- consoleTime: "bTimer",
- }],
- });
-
- hud2.jsterm.clearOutput();
-
- deferred = promise.defer();
-
- // Now the following console.timeEnd() call shouldn't display anything,
- // if the timers in different pages are not related.
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
- deferred.resolve(null);
- }, true);
-
- content.location = "data:text/html;charset=utf-8," +
+const TEST_URI4 = "data:text/html;charset=utf-8," +
"";
- yield deferred.promise;
+let test = asyncTest(function* () {
+ yield loadTab(TEST_URI);
- testLogEntry(hud2.outputNode, "bTimer: timer started",
- "bTimer was not started", false, true);
+ let hud1 = yield openConsole();
- yield closeConsole(gBrowser.selectedTab);
+ yield waitForMessages({
+ webconsole: hud1,
+ messages: [{
+ name: "aTimer started",
+ consoleTime: "aTimer",
+ }, {
+ name: "aTimer end",
+ consoleTimeEnd: "aTimer",
+ }],
+ });
- gBrowser.removeCurrentTab();
+ // The next test makes sure that timers with the same name but in separate
+ // tabs, do not contain the same value.
+ let { browser } = yield loadTab(TEST_URI2);
+ let hud2 = yield openConsole();
- executeSoon(finishTest);
- }
-}
+ testLogEntry(hud2.outputNode, "bTimer: timer started",
+ "bTimer was not started", false, true);
+
+ // The next test makes sure that timers with the same name but in separate
+ // pages, do not contain the same value.
+ content.location = TEST_URI3;
+
+ yield waitForMessages({
+ webconsole: hud2,
+ messages: [{
+ name: "bTimer started",
+ consoleTime: "bTimer",
+ }],
+ });
+
+ hud2.jsterm.clearOutput();
+
+ // Now the following console.timeEnd() call shouldn't display anything,
+ // if the timers in different pages are not related.
+ content.location = TEST_URI4;
+ yield loadBrowser(browser);
+
+ testLogEntry(hud2.outputNode, "bTimer: timer started",
+ "bTimer was not started", false, true);
+});
diff --git a/browser/devtools/webconsole/test/browser_webconsole_bug_659907_console_dir.js b/browser/devtools/webconsole/test/browser_webconsole_bug_659907_console_dir.js
index 431b55981275..1569899a139d 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_659907_console_dir.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_659907_console_dir.js
@@ -6,24 +6,23 @@
// Tests that console.dir works as intended.
-function test() {
- addTab("data:text/html;charset=utf-8,Web Console test for bug 659907: Expand console " +
- "object with a dir method");
- browser.addEventListener("load", function onLoad(aEvent) {
- browser.removeEventListener(aEvent.type, onLoad, true);
- openConsole(null, consoleOpened);
- }, true);
-}
+"use strict";
+
+const TEST_URI = "data:text/html;charset=utf-8,Web Console test for bug 659907: " +
+ "Expand console object with a dir method"
+
+let test = asyncTest(function*() {
+ yield loadTab(TEST_URI);
+ let hud = yield openConsole();
+ hud.jsterm.clearOutput();
-function consoleOpened(hud) {
hud.jsterm.execute("console.dir(document)");
- hud.jsterm.once("variablesview-fetched", testConsoleDir.bind(null, hud));
-}
-function testConsoleDir(hud, ev, view) {
- findVariableViewProperties(view, [
+ let varView = yield hud.jsterm.once("variablesview-fetched");
+
+ yield findVariableViewProperties(varView, [
{ name: "__proto__.__proto__.querySelectorAll", value: "querySelectorAll()" },
{ name: "location", value: /Location \u2192 data:Web/ },
{ name: "__proto__.write", value: "write()" },
- ], { webconsole: hud }).then(finishTest);
-}
+ ], { webconsole: hud });
+});
diff --git a/browser/devtools/webconsole/test/browser_webconsole_bug_660806_history_nav.js b/browser/devtools/webconsole/test/browser_webconsole_bug_660806_history_nav.js
index ade0c09363ae..2f057e4ca0c6 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_660806_history_nav.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_660806_history_nav.js
@@ -4,20 +4,17 @@
const TEST_URI = "data:text/html;charset=utf-8,bug 660806 - history navigation must not show the autocomplete popup";
-function test() {
- addTab(TEST_URI);
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
- openConsole(null, consoleOpened);
- }, true);
-}
+let test = asyncTest(function* () {
+ yield loadTab(TEST_URI);
+
+ let hud = yield openConsole();
+
+ yield consoleOpened(hud);
+});
function consoleOpened(HUD)
{
- content.wrappedJSObject.foobarBug660806 = {
- "location": "value0",
- "locationbar": "value1",
- };
+ let deferred = promise.defer();
let jsterm = HUD.jsterm;
let popup = jsterm.autocompletePopup;
@@ -25,6 +22,11 @@ function consoleOpened(HUD)
ok(false, "popup shown");
};
+ jsterm.execute("window.foobarBug660806 = {\
+ 'location': 'value0',\
+ 'locationbar': 'value1'\
+ }");
+
popup._panel.addEventListener("popupshown", onShown, false);
ok(!popup.isOpen, "popup is not open");
@@ -43,6 +45,7 @@ function consoleOpened(HUD)
executeSoon(function() {
ok(!popup.isOpen, "popup is not open");
popup._panel.removeEventListener("popupshown", onShown, false);
- executeSoon(finishTest);
+ executeSoon(deferred.resolve);
});
+ return deferred.promise;
}
diff --git a/browser/devtools/webconsole/test/browser_webconsole_bug_664131_console_group.js b/browser/devtools/webconsole/test/browser_webconsole_bug_664131_console_group.js
index faaa53cb0f4e..ff719877c8ea 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_664131_console_group.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_664131_console_group.js
@@ -7,73 +7,71 @@
// Tests that console.group/groupEnd works as intended.
const TEST_URI = "data:text/html;charset=utf-8,Web Console test for bug 664131: Expand console object with group methods";
-function test() {
- Task.spawn(runner).then(finishTest);
+let test = asyncTest(function* () {
+ yield loadTab(TEST_URI);
- function* runner() {
- let {tab} = yield loadTab(TEST_URI);
- let hud = yield openConsole(tab);
- let outputNode = hud.outputNode;
+ let hud = yield openConsole();
+ let jsterm = hud.jsterm;
+ let outputNode = hud.outputNode;
- hud.jsterm.clearOutput();
+ hud.jsterm.clearOutput();
- content.console.group("bug664131a");
+ yield jsterm.execute("console.group('bug664131a')")
- yield waitForMessages({
- webconsole: hud,
- messages: [{
- text: "bug664131a",
- consoleGroup: 1,
- }],
- });
+ yield waitForMessages({
+ webconsole: hud,
+ messages: [{
+ text: "bug664131a",
+ consoleGroup: 1,
+ }],
+ });
- content.console.log("bug664131a-inside");
+ yield jsterm.execute("console.log('bug664131a-inside')")
- yield waitForMessages({
- webconsole: hud,
- messages: [{
- text: "bug664131a-inside",
- category: CATEGORY_WEBDEV,
- severity: SEVERITY_LOG,
- groupDepth: 1,
- }],
- });
+ yield waitForMessages({
+ webconsole: hud,
+ messages: [{
+ text: "bug664131a-inside",
+ category: CATEGORY_WEBDEV,
+ severity: SEVERITY_LOG,
+ groupDepth: 1,
+ }],
+ });
- content.console.groupEnd("bug664131a");
- content.console.log("bug664131-outside");
+ yield jsterm.execute('console.groupEnd("bug664131a")');
+ yield jsterm.execute('console.log("bug664131-outside")');
- yield waitForMessages({
- webconsole: hud,
- messages: [{
- text: "bug664131-outside",
- category: CATEGORY_WEBDEV,
- severity: SEVERITY_LOG,
- groupDepth: 0,
- }],
- });
+ yield waitForMessages({
+ webconsole: hud,
+ messages: [{
+ text: "bug664131-outside",
+ category: CATEGORY_WEBDEV,
+ severity: SEVERITY_LOG,
+ groupDepth: 0,
+ }],
+ });
- content.console.groupCollapsed("bug664131b");
+ yield jsterm.execute('console.groupCollapsed("bug664131b")');
- yield waitForMessages({
- webconsole: hud,
- messages: [{
- text: "bug664131b",
- consoleGroup: 1,
- }],
- });
+ yield waitForMessages({
+ webconsole: hud,
+ messages: [{
+ text: "bug664131b",
+ consoleGroup: 1,
+ }],
+ });
- // Test that clearing the console removes the indentation.
- hud.jsterm.clearOutput();
- content.console.log("bug664131-cleared");
+ // Test that clearing the console removes the indentation.
+ hud.jsterm.clearOutput();
+ yield jsterm.execute('console.log("bug664131-cleared")');
- yield waitForMessages({
- webconsole: hud,
- messages: [{
- text: "bug664131-cleared",
- category: CATEGORY_WEBDEV,
- severity: SEVERITY_LOG,
- groupDepth: 0,
- }],
- });
- }
-}
+ yield waitForMessages({
+ webconsole: hud,
+ messages: [{
+ text: "bug664131-cleared",
+ category: CATEGORY_WEBDEV,
+ severity: SEVERITY_LOG,
+ groupDepth: 0,
+ }],
+ });
+});
diff --git a/browser/devtools/webconsole/test/browser_webconsole_bug_686937_autocomplete_JSTerm_helpers.js b/browser/devtools/webconsole/test/browser_webconsole_bug_686937_autocomplete_JSTerm_helpers.js
index c5fe935622dd..d2e45489dad5 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_686937_autocomplete_JSTerm_helpers.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_686937_autocomplete_JSTerm_helpers.js
@@ -7,68 +7,54 @@
const TEST_URI = "data:text/html;charset=utf8,
test JSTerm Helpers autocomplete";
-let testDriver;
+let jsterm;
-function test() {
- addTab(TEST_URI);
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
- openConsole(null, function(hud) {
- testDriver = testCompletion(hud);
- testDriver.next();
- });
- }, true);
-}
+let test = asyncTest(function* () {
+ yield loadTab(TEST_URI);
-function testNext() {
- executeSoon(function() {
- testDriver.next();
- });
-}
+ let hud = yield openConsole();
-function testCompletion(hud) {
- let jsterm = hud.jsterm;
+ jsterm = hud.jsterm;
let input = jsterm.inputNode;
let popup = jsterm.autocompletePopup;
// Test if 'i' gives 'inspect'
input.value = "i";
input.setSelectionRange(1, 1);
- jsterm.complete(jsterm.COMPLETE_HINT_ONLY, testNext);
- yield;
+ yield complete(jsterm.COMPLETE_HINT_ONLY);
let newItems = popup.getItems().map(function(e) {return e.label;});
ok(newItems.indexOf("inspect") > -1, "autocomplete results contain helper 'inspect'");
-
+
// Test if 'window.' does not give 'inspect'.
input.value = "window.";
input.setSelectionRange(7, 7);
- jsterm.complete(jsterm.COMPLETE_HINT_ONLY, testNext);
- yield;
+ yield complete(jsterm.COMPLETE_HINT_ONLY);
newItems = popup.getItems().map(function(e) {return e.label;});
is(newItems.indexOf("inspect"), -1, "autocomplete results do not contain helper 'inspect'");
-
-// Test if 'dump(i' gives 'inspect'
+ // Test if 'dump(i' gives 'inspect'
input.value = "dump(i";
input.setSelectionRange(6, 6);
- jsterm.complete(jsterm.COMPLETE_HINT_ONLY, testNext);
- yield;
+ yield complete(jsterm.COMPLETE_HINT_ONLY);
newItems = popup.getItems().map(function(e) {return e.label;});
ok(newItems.indexOf("inspect") > -1, "autocomplete results contain helper 'inspect'");
-// Test if 'window.dump(i' gives 'inspect'
+ // Test if 'window.dump(i' gives 'inspect'
input.value = "window.dump(i";
input.setSelectionRange(13, 13);
- jsterm.complete(jsterm.COMPLETE_HINT_ONLY, testNext);
- yield;
+ yield complete(jsterm.COMPLETE_HINT_ONLY);
newItems = popup.getItems().map(function(e) {return e.label;});
ok(newItems.indexOf("inspect") > -1, "autocomplete results contain helper 'inspect'");
- testDriver = jsterm = input = popup = newItems = null;
- executeSoon(finishTest);
- yield;
-}
+ jsterm = null;
+});
+
+function complete(type) {
+ let updated = jsterm.once("autocomplete-updated");
+ jsterm.complete(type);
+ return updated;
+}
\ No newline at end of file
diff --git a/browser/devtools/webconsole/test/browser_webconsole_bug_704295.js b/browser/devtools/webconsole/test/browser_webconsole_bug_704295.js
index 043e11c3803e..14d4aeeabcfc 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_704295.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_704295.js
@@ -7,13 +7,13 @@
const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/test-console.html";
-function test() {
- addTab(TEST_URI);
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
- openConsole(null, testCompletion);
- }, true);
-}
+let test = asyncTest(function* () {
+ yield loadTab(TEST_URI);
+
+ let hud = yield openConsole();
+
+ testCompletion(hud);
+});
function testCompletion(hud) {
var jsterm = hud.jsterm;
@@ -27,7 +27,7 @@ function testCompletion(hud) {
is(jsterm.completeNode.value, "", "no completion");
EventUtils.synthesizeKey("VK_RETURN", {});
is(jsterm.completeNode.value, "", "clear completion on execute()");
-
+
// Test typing 'var a = d' and press RETURN
jsterm.setInputValue("var a = ");
EventUtils.synthesizeKey("d", {});
@@ -35,8 +35,5 @@ function testCompletion(hud) {
is(jsterm.completeNode.value, "", "no completion");
EventUtils.synthesizeKey("VK_RETURN", {});
is(jsterm.completeNode.value, "", "clear completion on execute()");
-
- jsterm = input = null;
- finishTest();
}
diff --git a/browser/devtools/webconsole/test/browser_webconsole_bug_734061_No_input_change_and_Tab_key_pressed.js b/browser/devtools/webconsole/test/browser_webconsole_bug_734061_No_input_change_and_Tab_key_pressed.js
index 6433e0f717c3..9aff77a44c1e 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_734061_No_input_change_and_Tab_key_pressed.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_734061_No_input_change_and_Tab_key_pressed.js
@@ -5,15 +5,11 @@
const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/browser/test-console.html";
-function test() {
- addTab(TEST_URI);
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
- openConsole(null, testInputChange);
- }, true);
-}
+let test = asyncTest(function* () {
+ yield loadTab(TEST_URI);
+
+ let hud = yield openConsole();
-function testInputChange(hud) {
var jsterm = hud.jsterm;
var input = jsterm.inputNode;
@@ -33,7 +29,4 @@ function testInputChange(hud) {
EventUtils.synthesizeKey("VK_RIGHT", {});
EventUtils.synthesizeKey("VK_TAB", {});
is(input.getAttribute("focused"), "", "input moved away");
-
- jsterm = input = null;
- finishTest();
-}
+});
diff --git a/browser/devtools/webconsole/test/browser_webconsole_bug_737873_mixedcontent.js b/browser/devtools/webconsole/test/browser_webconsole_bug_737873_mixedcontent.js
index 87d0776bab7c..761645ccde92 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_737873_mixedcontent.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_737873_mixedcontent.js
@@ -10,24 +10,27 @@
// Tests that the Web Console Mixed Content messages are displayed
+const TEST_URI = "data:text/html;charset=utf8,Web Console mixed content test";
const TEST_HTTPS_URI = "https://example.com/browser/browser/devtools/webconsole/test/test-bug-737873-mixedcontent.html";
-function test() {
- addTab("data:text/html;charset=utf8,Web Console mixed content test");
- browser.addEventListener("load", onLoad, true);
-}
-
-function onLoad(aEvent) {
- browser.removeEventListener("load", onLoad, true);
+let test = asyncTest(function* () {
Services.prefs.setBoolPref("security.mixed_content.block_display_content", false);
Services.prefs.setBoolPref("security.mixed_content.block_active_content", false);
- openConsole(null, testMixedContent);
-}
+
+ yield loadTab(TEST_URI);
+
+ let hud = yield openConsole();
+
+ yield testMixedContent(hud);
+
+ Services.prefs.clearUserPref("security.mixed_content.block_display_content");
+ Services.prefs.clearUserPref("security.mixed_content.block_active_content");
+});
function testMixedContent(hud) {
content.location = TEST_HTTPS_URI;
- waitForMessages({
+ return waitForMessages({
webconsole: hud,
messages: [{
text: "example.com",
@@ -64,10 +67,5 @@ function testMixedContent(hud) {
ok(msg.classList.contains("filtered-by-type"), "message is filtered");
hud.setFilterState("netwarn", true);
-
- Services.prefs.clearUserPref("security.mixed_content.block_display_content");
- Services.prefs.clearUserPref("security.mixed_content.block_active_content");
-
- finishTest();
});
}
diff --git a/browser/devtools/webconsole/test/browser_webconsole_bug_752559_ineffective_iframe_sandbox_warning.js b/browser/devtools/webconsole/test/browser_webconsole_bug_752559_ineffective_iframe_sandbox_warning.js
index d745593f9f38..fac6f2cc2cdd 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_752559_ineffective_iframe_sandbox_warning.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_752559_ineffective_iframe_sandbox_warning.js
@@ -18,10 +18,8 @@ const SENTINEL_MSG = "testing ineffective sandboxing message";
function test()
{
- addTab(TEST_URI_WARNING);
- browser.addEventListener("load", function onLoad(aEvent) {
- browser.removeEventListener(aEvent.type, onLoad, true);
- openConsole(null, function testIneffectiveIframeSandboxingLogged (hud) {
+ loadTab(TEST_URI_WARNING).then(() => {
+ openConsole().then((hud) => {
content.console.log(SENTINEL_MSG)
waitForMessages({
webconsole: hud,
@@ -42,16 +40,14 @@ function test()
is(msgs.length, 1, "one security message");
testNoWarning(0);
});
- });
- }, true);
+ })
+ });
}
function testNoWarning(id)
{
- addTab(TEST_URI_NOWARNING[id]);
- browser.addEventListener("load", function onLoad(aEvent) {
- browser.removeEventListener(aEvent.type, onLoad, true);
- openConsole(null, function testIneffectiveIframeSandboxingNotLogged (hud) {
+ loadTab(TEST_URI_NOWARNING[id]).then(() => {
+ openConsole().then((hud) => {
content.console.log(SENTINEL_MSG)
waitForMessages({
webconsole: hud,
@@ -72,6 +68,6 @@ function testNoWarning(id)
finishTest();
}
});
- });
- }, true);
+ })
+ });
}
diff --git a/browser/devtools/webconsole/test/browser_webconsole_bug_762593_insecure_passwords_about_blank_web_console_warning.js b/browser/devtools/webconsole/test/browser_webconsole_bug_762593_insecure_passwords_about_blank_web_console_warning.js
index 3f4f4abaf8f7..d0322f6e9068 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_762593_insecure_passwords_about_blank_web_console_warning.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_762593_insecure_passwords_about_blank_web_console_warning.js
@@ -8,22 +8,21 @@
const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/test-bug-762593-insecure-passwords-about-blank-web-console-warning.html";
const INSECURE_PASSWORD_MSG = "Password fields present on an insecure (http://) page. This is a security risk that allows user login credentials to be stolen.";
-function test() {
- addTab(TEST_URI);
- browser.addEventListener("load", function onLoad(aEvent) {
- browser.removeEventListener(aEvent.type, onLoad, true);
- openConsole(null, function testInsecurePasswordErrorLogged (hud) {
- waitForMessages({
- webconsole: hud,
- messages: [
- {
- name: "Insecure password error displayed successfully",
- text: INSECURE_PASSWORD_MSG,
- category: CATEGORY_SECURITY,
- severity: SEVERITY_WARNING
- },
- ],
- }).then(finishTest);
- });
- }, true);
-}
+
+let test = asyncTest(function* () {
+ yield loadTab(TEST_URI);
+
+ let hud = yield openConsole();
+
+ yield waitForMessages({
+ webconsole: hud,
+ messages: [
+ {
+ name: "Insecure password error displayed successfully",
+ text: INSECURE_PASSWORD_MSG,
+ category: CATEGORY_SECURITY,
+ severity: SEVERITY_WARNING
+ },
+ ],
+ });
+});
diff --git a/browser/devtools/webconsole/test/browser_webconsole_bug_762593_insecure_passwords_web_console_warning.js b/browser/devtools/webconsole/test/browser_webconsole_bug_762593_insecure_passwords_web_console_warning.js
index ff95dda9cd45..f4aa7d617849 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_762593_insecure_passwords_web_console_warning.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_762593_insecure_passwords_web_console_warning.js
@@ -11,37 +11,37 @@ const INSECURE_FORM_ACTION_MSG = "Password fields present in a form with an inse
const INSECURE_IFRAME_MSG = "Password fields present on an insecure (http://) iframe. This is a security risk that allows user login credentials to be stolen.";
const INSECURE_PASSWORDS_URI = "https://developer.mozilla.org/docs/Security/InsecurePasswords";
-function test() {
- addTab(TEST_URI);
- browser.addEventListener("load", function onLoad(aEvent) {
- browser.removeEventListener(aEvent.type, onLoad, true);
- openConsole(null, function testInsecurePasswordErrorLogged (hud) {
- waitForMessages({
- webconsole: hud,
- messages: [
- {
- name: "Insecure password error displayed successfully",
- text: INSECURE_PASSWORD_MSG,
- category: CATEGORY_SECURITY,
- severity: SEVERITY_WARNING
- },
- {
- name: "Insecure iframe error displayed successfully",
- text: INSECURE_IFRAME_MSG,
- category: CATEGORY_SECURITY,
- severity: SEVERITY_WARNING
- },
- {
- name: "Insecure form action error displayed successfully",
- text: INSECURE_FORM_ACTION_MSG,
- category: CATEGORY_SECURITY,
- severity: SEVERITY_WARNING
- },
- ],
- }).then(testClickOpenNewTab.bind(null, hud));
- });
- }, true);
-}
+let test = asyncTest(function* () {
+ yield loadTab(TEST_URI);
+
+ let hud = yield openConsole();
+
+ let result = yield waitForMessages({
+ webconsole: hud,
+ messages: [
+ {
+ name: "Insecure password error displayed successfully",
+ text: INSECURE_PASSWORD_MSG,
+ category: CATEGORY_SECURITY,
+ severity: SEVERITY_WARNING
+ },
+ {
+ name: "Insecure iframe error displayed successfully",
+ text: INSECURE_IFRAME_MSG,
+ category: CATEGORY_SECURITY,
+ severity: SEVERITY_WARNING
+ },
+ {
+ name: "Insecure form action error displayed successfully",
+ text: INSECURE_FORM_ACTION_MSG,
+ category: CATEGORY_SECURITY,
+ severity: SEVERITY_WARNING
+ },
+ ],
+ });
+
+ testClickOpenNewTab(hud, result);
+});
function testClickOpenNewTab(hud, [result]) {
let msg = [...result.matched][0];
@@ -62,6 +62,4 @@ function testClickOpenNewTab(hud, [result]) {
warningNode.ownerDocument.defaultView);
ok(linkOpened, "Clicking the Insecure Passwords Warning node opens the desired page");
window.openUILinkIn = oldOpenUILinkIn;
-
- finishTest();
}
diff --git a/browser/devtools/webconsole/test/browser_webconsole_bug_764572_output_open_url.js b/browser/devtools/webconsole/test/browser_webconsole_bug_764572_output_open_url.js
index 3b936a37cf12..2517c8e94759 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_764572_output_open_url.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_764572_output_open_url.js
@@ -10,40 +10,41 @@ const CONTEXT_MENU_ID = "#menu_openURL";
let HUD = null, outputNode = null, contextMenu = null;
-function test() {
- let original = Services.prefs.getBoolPref("devtools.webconsole.filter.networkinfo");
+let test = asyncTest(function* () {
Services.prefs.setBoolPref("devtools.webconsole.filter.networkinfo", true);
- registerCleanupFunction(() => {
- Services.prefs.setBoolPref("devtools.webconsole.filter.networkinfo", original);
- });
- addTab(TEST_URI);
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
- openConsole(null, consoleOpened);
- }, true);
-}
-function consoleOpened(aHud) {
- HUD = aHud;
- outputNode = aHud.outputNode;
+ yield loadTab(TEST_URI);
+ HUD = yield openConsole();
+
+ let results = yield consoleOpened();
+ yield onConsoleMessage(results);
+
+ let results2 = yield testOnNetActivity();
+ let msg = yield onNetworkMessage(results2);
+
+ yield testOnNetActivity_contextmenu(msg);
+
+ Services.prefs.clearUserPref("devtools.webconsole.filter.networkinfo");
+
+ HUD = null, outputNode = null, contextMenu = null;
+});
+
+function consoleOpened() {
+ outputNode = HUD.outputNode;
contextMenu = HUD.iframeWindow.document.getElementById("output-contextmenu");
- registerCleanupFunction(() => {
- HUD = outputNode = contextMenu = null;
- });
-
HUD.jsterm.clearOutput();
content.console.log("bug 764572");
- waitForMessages({
+ return waitForMessages({
webconsole: HUD,
messages: [{
text: "bug 764572",
category: CATEGORY_WEBDEV,
severity: SEVERITY_LOG,
}],
- }).then(onConsoleMessage);
+ });
}
function onConsoleMessage(aResults) {
@@ -59,10 +60,10 @@ function onConsoleMessage(aResults) {
ok(isDisabled, COMMAND_NAME + " should be disabled.");
outputNode.selectedItem.scrollIntoView();
- waitForContextMenu(contextMenu, outputNode.selectedItem, () => {
+ return waitForContextMenu(contextMenu, outputNode.selectedItem, () => {
let isHidden = contextMenu.querySelector(CONTEXT_MENU_ID).hidden;
ok(isHidden, CONTEXT_MENU_ID + " should be hidden.");
- }, testOnNetActivity);
+ });
}
function testOnNetActivity() {
@@ -71,17 +72,19 @@ function testOnNetActivity() {
// Reload the url to show net activity in console.
content.location.reload();
- waitForMessages({
+ return waitForMessages({
webconsole: HUD,
messages: [{
text: "test-console.html",
category: CATEGORY_NETWORK,
severity: SEVERITY_LOG,
}],
- }).then(onNetworkMessage);
+ });
}
function onNetworkMessage(aResults) {
+ let deferred = promise.defer();
+
outputNode.focus();
let msg = [...aResults[0].matched][0];
ok(msg, "network message");
@@ -100,7 +103,7 @@ function onNetworkMessage(aResults) {
newTab.linkedBrowser.removeEventListener("load", onTabLoaded, true);
gBrowser.removeTab(newTab);
gBrowser.selectedTab = currentTab;
- executeSoon(testOnNetActivity_contextmenu.bind(null, msg));
+ executeSoon(deferred.resolve.bind(null, msg));
}
// Check if the command is enabled for a network message.
@@ -112,15 +115,23 @@ function onNetworkMessage(aResults) {
// Try to open the URL.
goDoCommand(COMMAND_NAME);
+
+ return deferred.promise;
}
function testOnNetActivity_contextmenu(msg) {
+ let deferred = promise.defer();
+
outputNode.focus();
HUD.ui.output.selectMessage(msg);
-
msg.scrollIntoView();
+
+ info("net activity context menu");
+
waitForContextMenu(contextMenu, msg, () => {
let isShown = !contextMenu.querySelector(CONTEXT_MENU_ID).hidden;
ok(isShown, CONTEXT_MENU_ID + " should be shown.");
- }, finishTest);
+ }).then(deferred.resolve);
+
+ return deferred.promise;
}
diff --git a/browser/devtools/webconsole/test/browser_webconsole_bug_766001_JS_Console_in_Debugger.js b/browser/devtools/webconsole/test/browser_webconsole_bug_766001_JS_Console_in_Debugger.js
index 2f2b10947328..05580a7c3a9b 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_766001_JS_Console_in_Debugger.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_766001_JS_Console_in_Debugger.js
@@ -19,6 +19,7 @@ function test() {
function* runner() {
expectUncaughtException();
+
let {tab} = yield loadTab(TEST_URI);
hud = yield openConsole(tab);
diff --git a/browser/devtools/webconsole/test/browser_webconsole_bug_770099_violation.js b/browser/devtools/webconsole/test/browser_webconsole_bug_770099_violation.js
index 79dde9c4e402..6c0400492fb8 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_770099_violation.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_770099_violation.js
@@ -7,40 +7,25 @@
// Tests that the Web Console CSP messages are displayed
+const TEST_URI = "data:text/html;charset=utf8,Web Console CSP violation test";
const TEST_VIOLATION = "https://example.com/browser/browser/devtools/webconsole/test/test_bug_770099_violation.html";
const CSP_VIOLATION_MSG = 'Content Security Policy: The page\'s settings blocked the loading of a resource at http://some.example.com/test.png ("default-src https://example.com").'
-let hud = undefined;
+let test = asyncTest(function* () {
+ let { browser } = yield loadTab(TEST_URI);
-function test() {
- addTab("data:text/html;charset=utf8,Web Console CSP violation test");
- browser.addEventListener("load", function _onLoad() {
- browser.removeEventListener("load", _onLoad, true);
- openConsole(null, loadDocument);
- }, true);
-}
+ let hud = yield openConsole();
-function loadDocument(theHud){
- hud = theHud;
- hud.jsterm.clearOutput()
- browser.addEventListener("load", onLoad, true);
+ hud.jsterm.clearOutput();
+
+ let loaded = loadBrowser(browser);
content.location = TEST_VIOLATION;
-}
+ yield loaded;
-function onLoad(aEvent) {
- browser.removeEventListener("load", onLoad, true);
- testViolationMessage();
-}
-
-function testViolationMessage(){
- let aOutputNode = hud.outputNode;
-
- waitForSuccess({
- name: "CSP policy URI warning displayed successfully",
- validatorFn: function() {
- return hud.outputNode.textContent.indexOf(CSP_VIOLATION_MSG) > -1;
- },
- successFn: finishTest,
- failureFn: finishTest,
- });
-}
+ yield waitForSuccess({
+ name: "CSP policy URI warning displayed successfully",
+ validator: function() {
+ return hud.outputNode.textContent.indexOf(CSP_VIOLATION_MSG) > -1;
+ }
+ });
+});
diff --git a/browser/devtools/webconsole/test/browser_webconsole_bug_782653_CSS_links_in_Style_Editor.js b/browser/devtools/webconsole/test/browser_webconsole_bug_782653_CSS_links_in_Style_Editor.js
index 25d87f28117c..6cc5172c58ef 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_782653_CSS_links_in_Style_Editor.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_782653_CSS_links_in_Style_Editor.js
@@ -9,22 +9,20 @@ const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test" +
let nodes, hud, StyleEditorUI;
-function test()
-{
- addTab(TEST_URI);
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
- openConsole(null, testViewSource);
- }, true);
-}
+let test = asyncTest(function* () {
+ yield loadTab(TEST_URI);
-function testViewSource(aHud)
-{
- hud = aHud;
+ hud = yield openConsole();
- registerCleanupFunction(function() {
- nodes = hud = StyleEditorUI = null;
- });
+ let styleEditor = yield testViewSource();
+ yield onStyleEditorReady(styleEditor);
+
+ nodes = hud = StyleEditorUI = null;
+});
+
+function testViewSource()
+{
+ let deferred = promise.defer();
waitForMessages({
webconsole: hud,
@@ -54,17 +52,21 @@ function testViewSource(aHud)
let count = 0;
StyleEditorUI.on("editor-added", function() {
if (++count == 2) {
- onStyleEditorReady(panel);
+ deferred.resolve(panel);
}
});
});
EventUtils.sendMouseEvent({ type: "click" }, nodes[0]);
});
+
+ return deferred.promise;
}
function onStyleEditorReady(aPanel)
{
+ let deferred = promise.defer();
+
let win = aPanel.panelWindow;
ok(win, "Style Editor Window is defined");
ok(StyleEditorUI, "Style Editor UI is defined");
@@ -76,7 +78,7 @@ function onStyleEditorReady(aPanel)
let line = nodes[0].sourceLine;
ok(line, "found source line");
- checkStyleEditorForSheetAndLine(href, line - 1, function() {
+ checkStyleEditorForSheetAndLine(href, line - 1).then(function() {
info("first check done");
let target = TargetFactory.forTab(gBrowser.selectedTab);
@@ -92,19 +94,18 @@ function onStyleEditorReady(aPanel)
toolbox.once("styleeditor-selected", function(aEvent) {
info(aEvent + " event fired");
- checkStyleEditorForSheetAndLine(href, line - 1, function() {
- info("second check done");
- finishTest();
- });
+ checkStyleEditorForSheetAndLine(href, line - 1).then(deferred.resolve);
});
EventUtils.sendMouseEvent({ type: "click" }, nodes[1]);
});
});
}, win);
+
+ return deferred.promise;
}
-function checkStyleEditorForSheetAndLine(aHref, aLine, aCallback)
+function checkStyleEditorForSheetAndLine(aHref, aLine)
{
let foundEditor = null;
for (let editor of StyleEditorUI.editors) {
@@ -115,11 +116,13 @@ function checkStyleEditorForSheetAndLine(aHref, aLine, aCallback)
}
ok(foundEditor, "found style editor for " + aHref);
- performLineCheck(foundEditor, aLine, aCallback);
+ return performLineCheck(foundEditor, aLine);
}
-function performLineCheck(aEditor, aLine, aCallback)
+function performLineCheck(aEditor, aLine)
{
+ let deferred = promise.defer();
+
function checkForCorrectState()
{
is(aEditor.sourceEditor.getCursor().line, aLine,
@@ -127,7 +130,7 @@ function performLineCheck(aEditor, aLine, aCallback)
is(StyleEditorUI.selectedStyleSheetIndex, aEditor.styleSheet.styleSheetIndex,
"correct stylesheet is selected in the editor");
- aCallback && executeSoon(aCallback);
+ executeSoon(deferred.resolve);
}
info("wait for source editor to load");
@@ -139,4 +142,6 @@ function performLineCheck(aEditor, aLine, aCallback)
executeSoon(checkForCorrectState);
});
});
+
+ return deferred.promise;
}
diff --git a/browser/devtools/webconsole/test/browser_webconsole_bug_804845_ctrl_key_nav.js b/browser/devtools/webconsole/test/browser_webconsole_bug_804845_ctrl_key_nav.js
index 7fbe22e41df8..f6a66572f4bb 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_804845_ctrl_key_nav.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_804845_ctrl_key_nav.js
@@ -11,15 +11,21 @@
// Test navigation of webconsole contents via ctrl-a, ctrl-e, ctrl-p, ctrl-n
// see https://bugzilla.mozilla.org/show_bug.cgi?id=804845
+"use strict";
+
+const TEST_URI = "data:text/html;charset=utf-8,Web Console test for bug 804845 and bug 619598";
let jsterm, inputNode;
-function test() {
- addTab("data:text/html;charset=utf-8,Web Console test for bug 804845 and bug 619598");
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
- openConsole(null, doTests);
- }, true);
-}
+
+let test = asyncTest(function* () {
+ yield loadTab(TEST_URI);
+
+ let hud = yield openConsole();
+
+ doTests(hud);
+
+ jsterm = inputNode = null;
+});
function doTests(HUD) {
jsterm = HUD.jsterm;
@@ -31,9 +37,6 @@ function doTests(HUD) {
testSingleLineInputNavNoHistory();
testMultiLineInputNavNoHistory();
testNavWithHistory();
-
- jsterm = inputNode = null;
- executeSoon(finishTest);
}
function testSingleLineInputNavNoHistory() {
diff --git a/browser/devtools/webconsole/test/browser_webconsole_bug_817834_add_edited_input_to_history.js b/browser/devtools/webconsole/test/browser_webconsole_bug_817834_add_edited_input_to_history.js
index 7600103a6b01..98633c327f98 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_817834_add_edited_input_to_history.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_817834_add_edited_input_to_history.js
@@ -13,13 +13,17 @@
// lost after navigating in history.
// See https://bugzilla.mozilla.org/show_bug.cgi?id=817834
-function test() {
- addTab("data:text/html;charset=utf-8,Web Console test for bug 817834");
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
- openConsole(null, testEditedInputHistory);
- }, true);
-}
+"use strict";
+
+const TEST_URI = "data:text/html;charset=utf-8,Web Console test for bug 817834";
+
+let test = asyncTest(function* () {
+ yield loadTab(TEST_URI);
+
+ let hud = yield openConsole();
+
+ testEditedInputHistory(hud);
+});
function testEditedInputHistory(HUD) {
let jsterm = HUD.jsterm;
@@ -56,6 +60,4 @@ function testEditedInputHistory(HUD) {
EventUtils.synthesizeKey("VK_DOWN", {});
is(inputNode.value, '"editing input 2"',
"test history down restores new in-progress input again");
-
- executeSoon(finishTest);
}
diff --git a/browser/devtools/webconsole/test/browser_webconsole_bug_837351_securityerrors.js b/browser/devtools/webconsole/test/browser_webconsole_bug_837351_securityerrors.js
index 19705326d761..c5d8b22fbf2e 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_837351_securityerrors.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_837351_securityerrors.js
@@ -3,32 +3,34 @@
const TEST_URI = "https://example.com/browser/browser/devtools/webconsole/test/test-bug-837351-security-errors.html";
-function run_test()
-{
- addTab(TEST_URI);
- browser.addEventListener("load", function onLoad(aEvent) {
- browser.removeEventListener(aEvent.type, onLoad, true);
- openConsole(null, function testSecurityErrorLogged (hud) {
- let button = hud.ui.rootElement.querySelector(".webconsole-filter-button[category=\"security\"]");
- ok(button, "Found security button in the web console");
+let test = asyncTest(function* () {
+ yield pushPrefEnv();
- waitForMessages({
- webconsole: hud,
- messages: [
- {
- name: "Logged blocking mixed active content",
- text: "Blocked loading mixed active content \"http://example.com/\"",
- category: CATEGORY_SECURITY,
- severity: SEVERITY_ERROR
- },
- ],
- }).then(finishTest);
- });
- }, true);
-}
-
-function test()
-{
- SpecialPowers.pushPrefEnv({'set': [["security.mixed_content.block_active_content", true]]}, run_test);
+ yield loadTab(TEST_URI);
+
+ let hud = yield openConsole();
+
+ let button = hud.ui.rootElement.querySelector(".webconsole-filter-button[category=\"security\"]");
+ ok(button, "Found security button in the web console");
+
+ yield waitForMessages({
+ webconsole: hud,
+ messages: [
+ {
+ name: "Logged blocking mixed active content",
+ text: "Blocked loading mixed active content \"http://example.com/\"",
+ category: CATEGORY_SECURITY,
+ severity: SEVERITY_ERROR
+ },
+ ],
+ });
+});
+
+function pushPrefEnv()
+{
+ let deferred = promise.defer();
+ let options = {'set': [["security.mixed_content.block_active_content", true]]};
+ SpecialPowers.pushPrefEnv(options, deferred.resolve);
+ return deferred.promise;
}
diff --git a/browser/devtools/webconsole/test/browser_webconsole_bug_846918_hsts_invalid-headers.js b/browser/devtools/webconsole/test/browser_webconsole_bug_846918_hsts_invalid-headers.js
index 33c214cdca57..c101962c75f0 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_846918_hsts_invalid-headers.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_846918_hsts_invalid-headers.js
@@ -8,10 +8,8 @@ const LEARN_MORE_URI = "https://developer.mozilla.org/docs/Security/HTTP_Strict_
function test()
{
- addTab(TEST_URI);
- browser.addEventListener("load", function onLoad(aEvent) {
- browser.removeEventListener(aEvent.type, onLoad, true);
- openConsole(null, function testHSTSErrorLogged (hud) {
+ loadTab(TEST_URI).then(() => {
+ openConsole().then((hud) => {
waitForMessages({
webconsole: hud,
messages: [
@@ -24,8 +22,8 @@ function test()
},
],
}).then((results) => testClickOpenNewTab(hud, results));
- });
- }, true);
+ })
+ });
}
function testClickOpenNewTab(hud, results) {
diff --git a/browser/devtools/webconsole/test/browser_webconsole_bug_915141_toggle_response_logging_with_keyboard.js b/browser/devtools/webconsole/test/browser_webconsole_bug_915141_toggle_response_logging_with_keyboard.js
index d2b7037e9083..56b566654949 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_915141_toggle_response_logging_with_keyboard.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_915141_toggle_response_logging_with_keyboard.js
@@ -65,6 +65,7 @@ function test() {
"Console net menu: 'log responses' is NOT checked after menuitem was selected with keyboard.");
is(hud.ui._saveRequestAndResponseBodies, false,
"Responses are NOT saved after menuitem was selected with keyboard.");
+ hud = null;
})
.then(finishTest);
}
diff --git a/browser/devtools/webconsole/test/browser_webconsole_cached_autocomplete.js b/browser/devtools/webconsole/test/browser_webconsole_cached_autocomplete.js
index cb5aff2dcd67..1c780a3fcfd4 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_cached_autocomplete.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_cached_autocomplete.js
@@ -8,36 +8,21 @@
const TEST_URI = "data:text/html;charset=utf8,
test cached autocompletion results";
-let testDriver;
+let jsterm;
-function test() {
- requestLongerTimeout(2);
- addTab(TEST_URI);
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
- openConsole(null, function(hud) {
- testDriver = testCompletion(hud);
- testDriver.next();
- });
- }, true);
-}
+let test = asyncTest(function* () {
+ yield loadTab(TEST_URI);
-function testNext() {
- executeSoon(function() {
- testDriver.next();
- });
-}
+ let hud = yield openConsole();
-function testCompletion(hud) {
- let jsterm = hud.jsterm;
+ jsterm = hud.jsterm;
let input = jsterm.inputNode;
let popup = jsterm.autocompletePopup;
// Test if 'doc' gives 'document'
input.value = "doc";
input.setSelectionRange(3, 3);
- jsterm.complete(jsterm.COMPLETE_HINT_ONLY, testNext);
- yield undefined;
+ yield complete(jsterm.COMPLETE_HINT_ONLY);
is(input.value, "doc", "'docu' completion (input.value)");
is(jsterm.completeNode.value, " ument", "'docu' completion (completeNode)");
@@ -45,18 +30,16 @@ function testCompletion(hud) {
// Test typing 'window.'.
input.value = "window.";
input.setSelectionRange(7, 7);
- jsterm.complete(jsterm.COMPLETE_HINT_ONLY, testNext);
- yield undefined;
+ yield complete(jsterm.COMPLETE_HINT_ONLY);
ok(popup.getItems().length > 0, "'window.' gave a list of suggestions")
- content.wrappedJSObject.docfoobar = true;
+ yield jsterm.execute("window.docfoobar = true");
// Test typing 'window.doc'.
input.value = "window.doc";
input.setSelectionRange(10, 10);
- jsterm.complete(jsterm.COMPLETE_HINT_ONLY, testNext);
- yield undefined;
+ yield complete(jsterm.COMPLETE_HINT_ONLY);
let newItems = popup.getItems();
ok(newItems.every(function(item) {
@@ -66,25 +49,24 @@ function testCompletion(hud) {
// Test that backspace does not cause a request to the server
input.value = "window.do";
input.setSelectionRange(9, 9);
- jsterm.complete(jsterm.COMPLETE_HINT_ONLY, testNext);
- yield undefined;
+ yield complete(jsterm.COMPLETE_HINT_ONLY);
newItems = popup.getItems();
ok(newItems.every(function(item) {
return item.label != "docfoobar";
}), "autocomplete cached results do not contain docfoobar. list has not been updated");
- delete content.wrappedJSObject.docfoobar;
+ yield jsterm.execute("delete window.docfoobar");
// Test if 'window.getC' gives 'getComputedStyle'
input.value = "window."
input.setSelectionRange(7, 7);
- jsterm.complete(jsterm.COMPLETE_HINT_ONLY, testNext);
- yield undefined;
+ yield complete(jsterm.COMPLETE_HINT_ONLY);
+
input.value = "window.getC";
input.setSelectionRange(11, 11);
- jsterm.complete(jsterm.COMPLETE_HINT_ONLY, testNext);
- yield undefined;
+ yield complete(jsterm.COMPLETE_HINT_ONLY);
+
newItems = popup.getItems();
ok(!newItems.every(function(item) {
return item.label != "getComputedStyle";
@@ -93,33 +75,34 @@ function testCompletion(hud) {
// Test if 'dump(d' gives non-zero results
input.value = "dump(d";
input.setSelectionRange(6, 6);
- jsterm.complete(jsterm.COMPLETE_HINT_ONLY, testNext);
- yield undefined;
+ yield complete(jsterm.COMPLETE_HINT_ONLY);
ok(popup.getItems().length > 0, "'dump(d' gives non-zero results");
// Test that 'dump(window.)' works.
input.value = "dump(window.)";
input.setSelectionRange(12, 12);
- jsterm.complete(jsterm.COMPLETE_HINT_ONLY, testNext);
- yield undefined;
+ yield complete(jsterm.COMPLETE_HINT_ONLY);
- content.wrappedJSObject.docfoobar = true;
+ yield jsterm.execute("window.docfoobar = true");
// Make sure 'dump(window.doc)' does not contain 'docfoobar'.
input.value = "dump(window.doc)";
input.setSelectionRange(15, 15);
- jsterm.complete(jsterm.COMPLETE_HINT_ONLY, testNext);
- yield undefined;
+ yield complete(jsterm.COMPLETE_HINT_ONLY);
newItems = popup.getItems();
ok(newItems.every(function(item) {
return item.label != "docfoobar";
}), "autocomplete cached results do not contain docfoobar. list has not been updated");
- delete content.wrappedJSObject.docfoobar;
+ yield jsterm.execute("delete window.docfoobar");
- testDriver = null;
- executeSoon(finishTest);
- yield undefined;
+ jsterm = null;
+});
+
+function complete(type) {
+ let updated = jsterm.once("autocomplete-updated");
+ jsterm.complete(type);
+ return updated;
}
diff --git a/browser/devtools/webconsole/test/browser_webconsole_cd_iframe.js b/browser/devtools/webconsole/test/browser_webconsole_cd_iframe.js
index 82c667145f41..bc919a258fbf 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_cd_iframe.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_cd_iframe.js
@@ -42,27 +42,27 @@ function test() {
const {tab} = yield loadTab(TEST_URI);
hud = yield openConsole(tab);
- executeWindowTest();
+ yield executeWindowTest();
yield waitForMessages({ webconsole: hud, messages: parentMessages });
info("cd() into the iframe using a selector");
hud.jsterm.clearOutput();
- hud.jsterm.execute("cd('iframe')");
- executeWindowTest();
+ yield hud.jsterm.execute("cd('iframe')");
+ yield executeWindowTest();
yield waitForMessages({ webconsole: hud, messages: childMessages });
info("cd() out of the iframe, reset to default window");
hud.jsterm.clearOutput();
- hud.jsterm.execute("cd()");
- executeWindowTest();
+ yield hud.jsterm.execute("cd()");
+ yield executeWindowTest();
yield waitForMessages({ webconsole: hud, messages: parentMessages });
info("call cd() with unexpected arguments");
hud.jsterm.clearOutput();
- hud.jsterm.execute("cd(document)");
+ yield hud.jsterm.execute("cd(document)");
yield waitForMessages({
webconsole: hud,
@@ -74,7 +74,7 @@ function test() {
});
hud.jsterm.clearOutput();
- hud.jsterm.execute("cd('p')");
+ yield hud.jsterm.execute("cd('p')");
yield waitForMessages({
webconsole: hud,
@@ -87,15 +87,15 @@ function test() {
info("cd() into the iframe using an iframe DOM element");
hud.jsterm.clearOutput();
- hud.jsterm.execute("cd($('iframe'))");
- executeWindowTest();
+ yield hud.jsterm.execute("cd($('iframe'))");
+ yield executeWindowTest();
yield waitForMessages({ webconsole: hud, messages: childMessages });
info("cd(window.parent)");
hud.jsterm.clearOutput();
- hud.jsterm.execute("cd(window.parent)");
- executeWindowTest();
+ yield hud.jsterm.execute("cd(window.parent)");
+ yield executeWindowTest();
yield waitForMessages({ webconsole: hud, messages: parentMessages });
@@ -103,8 +103,8 @@ function test() {
}
function executeWindowTest() {
- hud.jsterm.execute("document.title");
- hud.jsterm.execute("'p: ' + document.querySelector('p').textContent");
- hud.jsterm.execute("'obj: ' + window.foobarBug609872");
+ yield hud.jsterm.execute("document.title");
+ yield hud.jsterm.execute("'p: ' + document.querySelector('p').textContent");
+ yield hud.jsterm.execute("'obj: ' + window.foobarBug609872");
}
}
diff --git a/browser/devtools/webconsole/test/browser_webconsole_certificate_messages.js b/browser/devtools/webconsole/test/browser_webconsole_certificate_messages.js
index 8f41d13222fa..e6efc7dad11a 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_certificate_messages.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_certificate_messages.js
@@ -4,7 +4,9 @@
// Tests that the Web Console shows weak crypto warnings (SHA-1 Certificate, SSLv3, and RC4)
+const TEST_URI = "data:text/html;charset=utf8,Web Console weak crypto warnings test";
const TEST_URI_PATH = "/browser/browser/devtools/webconsole/test/test-certificate-messages.html";
+
let gWebconsoleTests = [
{url: "https://sha1ee.example.com" + TEST_URI_PATH,
name: "SHA1 warning displayed successfully",
@@ -26,31 +28,31 @@ let gWebconsoleTests = [
];
const TRIGGER_MSG = "If you haven't seen ssl warnings yet, you won't";
-let gHud = undefined;
+let gHud = undefined, gContentBrowser;
let gCurrentTest;
function test() {
registerCleanupFunction(function () {
- gHud = null;
+ gHud = gContentBrowser = null;
});
- addTab("data:text/html;charset=utf8,Web Console weak crypto warnings test");
- browser.addEventListener("load", function _onLoad() {
- browser.removeEventListener("load", _onLoad, true);
- openConsole(null, runTestLoop);
- }, true);
+ loadTab(TEST_URI).then(({browser}) => {
+ gContentBrowser = browser;
+ openConsole().then(runTestLoop);
+ });
}
function runTestLoop(theHud) {
gCurrentTest = gWebconsoleTests.shift();
if (!gCurrentTest) {
finishTest();
+ return;
}
if (!gHud) {
gHud = theHud;
}
gHud.jsterm.clearOutput();
- browser.addEventListener("load", onLoad, true);
+ gContentBrowser.addEventListener("load", onLoad, true);
if (gCurrentTest.pref) {
SpecialPowers.pushPrefEnv({"set": gCurrentTest.pref},
function() {
@@ -62,12 +64,12 @@ function runTestLoop(theHud) {
}
function onLoad(aEvent) {
- browser.removeEventListener("load", onLoad, true);
+ gContentBrowser.removeEventListener("load", onLoad, true);
let aOutputNode = gHud.outputNode;
waitForSuccess({
name: gCurrentTest.name,
- validatorFn: function() {
+ validator: function() {
if (gHud.outputNode.textContent.indexOf(TRIGGER_MSG) >= 0) {
for (let warning of gCurrentTest.warning) {
if (gHud.outputNode.textContent.indexOf(warning) < 0) {
@@ -81,8 +83,6 @@ function onLoad(aEvent) {
}
return true;
}
- },
- successFn: runTestLoop,
- failureFn: finishTest,
- });
+ }
+ }).then(runTestLoop);
}
diff --git a/browser/devtools/webconsole/test/browser_webconsole_change_font_size.js b/browser/devtools/webconsole/test/browser_webconsole_change_font_size.js
index 1769cdcc61e9..ab86bb49e6bf 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_change_font_size.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_change_font_size.js
@@ -8,18 +8,15 @@
*
* ***** END LICENSE BLOCK ***** */
+"use strict";
+
const TEST_URI = "http://example.com/";
-function test() {
- addTab(TEST_URI);
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
- Services.prefs.setIntPref("devtools.webconsole.fontSize", 10);
- HUDService.toggleBrowserConsole().then(testFontSizeChange);
- }, true);
-}
+let test = asyncTest(function*() {
+ yield loadTab(TEST_URI);
+ Services.prefs.setIntPref("devtools.webconsole.fontSize", 10);
+ let hud = yield HUDService.toggleBrowserConsole();
-function testFontSizeChange(hud) {
let inputNode = hud.jsterm.inputNode;
let outputNode = hud.jsterm.outputNode;
outputNode.focus();
@@ -39,6 +36,4 @@ function testFontSizeChange(hud) {
EventUtils.synthesizeKey("0", { accelKey: true }, hud.iframeWindow);
is(inputNode.style.fontSize, "", "font reset with ctrl+0");
is(outputNode.style.fontSize, inputNode.style.fontSize, "output font stays at same size with ctrl+0");
-
- finishTest();
-}
+});
diff --git a/browser/devtools/webconsole/test/browser_webconsole_chrome.js b/browser/devtools/webconsole/test/browser_webconsole_chrome.js
index e6ac01f2cf66..f7f3cd0e328e 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_chrome.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_chrome.js
@@ -5,6 +5,8 @@
// Tests that code completion works properly in chrome tabs, like about:credits.
+"use strict";
+
function test() {
Task.spawn(function*() {
const {tab} = yield loadTab("about:config");
diff --git a/browser/devtools/webconsole/test/browser_webconsole_clickable_urls.js b/browser/devtools/webconsole/test/browser_webconsole_clickable_urls.js
index ebfbe5329d28..05f1ee2c9e84 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_clickable_urls.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_clickable_urls.js
@@ -6,6 +6,8 @@
// When strings containing URLs are entered into the webconsole,
// check its output and ensure that the output can be clicked to open those URLs.
+"use strict";
+
const TEST_URI = "data:text/html;charset=utf8,Bug 1005909 - Clickable URLS";
let inputTests = [
diff --git a/browser/devtools/webconsole/test/browser_webconsole_closure_inspection.js b/browser/devtools/webconsole/test/browser_webconsole_closure_inspection.js
index f0b0f839e583..537ef1a72e2e 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_closure_inspection.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_closure_inspection.js
@@ -16,10 +16,8 @@ function test()
gWebConsole = gJSTerm = gVariablesView = null;
});
- addTab(TEST_URI);
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
- openConsole(null, (hud) => {
+ loadTab(TEST_URI).then(() => {
+ openConsole().then((hud) => {
openDebugger().then(({ toolbox, panelWin }) => {
let deferred = promise.defer();
panelWin.gThreadClient.addOneTimeListener("resumed", (aEvent, aPacket) => {
@@ -41,8 +39,8 @@ function test()
return deferred.promise;
});
- });
- }, true);
+ })
+ });
}
function consoleOpened(hud)
diff --git a/browser/devtools/webconsole/test/browser_webconsole_column_numbers.js b/browser/devtools/webconsole/test/browser_webconsole_column_numbers.js
index c255893d5936..bbc5dde8134d 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_column_numbers.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_column_numbers.js
@@ -10,11 +10,9 @@ const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/te
let hud;
function test() {
- addTab(TEST_URI);
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
- openConsole(null, consoleOpened);
- }, true);
+ loadTab(TEST_URI).then(() => {
+ openConsole().then(consoleOpened);
+ });
}
function consoleOpened(aHud) {
diff --git a/browser/devtools/webconsole/test/browser_webconsole_completion.js b/browser/devtools/webconsole/test/browser_webconsole_completion.js
index df7a8ca9558a..d68ae0ac3557 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_completion.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_completion.js
@@ -7,34 +7,20 @@
const TEST_URI = "data:text/html;charset=utf8,
test code completion";
-let testDriver;
+let jsterm;
-function test() {
- addTab(TEST_URI);
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
- openConsole(null, function(hud) {
- testDriver = testCompletion(hud);
- testDriver.next();
- });
- }, true);
-}
+let test = asyncTest(function* () {
+ yield loadTab(TEST_URI);
-function testNext() {
- executeSoon(function() {
- testDriver.next();
- });
-}
+ let hud = yield openConsole();
-function testCompletion(hud) {
- let jsterm = hud.jsterm;
+ jsterm = hud.jsterm;
let input = jsterm.inputNode;
// Test typing 'docu'.
input.value = "docu";
input.setSelectionRange(4, 4);
- jsterm.complete(jsterm.COMPLETE_HINT_ONLY, testNext);
- yield undefined;
+ yield complete(jsterm.COMPLETE_HINT_ONLY);
is(input.value, "docu", "'docu' completion (input.value)");
is(jsterm.completeNode.value, " ment", "'docu' completion (completeNode)");
@@ -42,8 +28,7 @@ function testCompletion(hud) {
// Test typing 'docu' and press tab.
input.value = "docu";
input.setSelectionRange(4, 4);
- jsterm.complete(jsterm.COMPLETE_FORWARD, testNext);
- yield undefined;
+ yield complete(jsterm.COMPLETE_FORWARD);
is(input.value, "document", "'docu' tab completion");
is(input.selectionStart, 8, "start selection is alright");
@@ -54,30 +39,26 @@ function testCompletion(hud) {
// ambiguous: could be window.Object, window.Option, etc.
input.value = "window.Ob";
input.setSelectionRange(9, 9);
- jsterm.complete(jsterm.COMPLETE_FORWARD, testNext);
- yield undefined;
+ yield complete(jsterm.COMPLETE_FORWARD);
is(input.value, "window.Object", "'window.Ob' tab completion");
// Test typing 'document.getElem'.
input.value = "document.getElem";
input.setSelectionRange(16, 16);
- jsterm.complete(jsterm.COMPLETE_FORWARD, testNext);
- yield undefined;
+ yield complete(jsterm.COMPLETE_FORWARD);
is(input.value, "document.getElem", "'document.getElem' completion");
is(jsterm.completeNode.value, " entsByTagNameNS", "'document.getElem' completion");
// Test pressing tab another time.
- jsterm.complete(jsterm.COMPLETE_FORWARD, testNext);
- yield undefined;
+ yield jsterm.complete(jsterm.COMPLETE_FORWARD);
is(input.value, "document.getElem", "'document.getElem' completion");
is(jsterm.completeNode.value, " entsByTagName", "'document.getElem' another tab completion");
// Test pressing shift_tab.
- jsterm.complete(jsterm.COMPLETE_BACKWARD, testNext);
- yield undefined;
+ complete(jsterm.COMPLETE_BACKWARD);
is(input.value, "document.getElem", "'document.getElem' untab completion");
is(jsterm.completeNode.value, " entsByTagNameNS", "'document.getElem' completion");
@@ -85,36 +66,36 @@ function testCompletion(hud) {
jsterm.clearOutput();
input.value = "docu";
- jsterm.complete(jsterm.COMPLETE_HINT_ONLY, testNext);
- yield undefined;
+ yield complete(jsterm.COMPLETE_HINT_ONLY);
is(jsterm.completeNode.value, " ment", "'docu' completion");
- jsterm.execute();
+ yield jsterm.execute();
is(jsterm.completeNode.value, "", "clear completion on execute()");
// Test multi-line completion works
input.value = "console.log('one');\nconsol";
- jsterm.complete(jsterm.COMPLETE_HINT_ONLY, testNext);
- yield undefined;
+ yield complete(jsterm.COMPLETE_HINT_ONLY);
is(jsterm.completeNode.value, " \n e", "multi-line completion");
// Test non-object autocompletion.
input.value = "Object.name.sl";
- jsterm.complete(jsterm.COMPLETE_HINT_ONLY, testNext);
- yield undefined;
+ yield complete(jsterm.COMPLETE_HINT_ONLY);
is(jsterm.completeNode.value, " ice", "non-object completion");
// Test string literal autocompletion.
input.value = "'Asimov'.sl";
- jsterm.complete(jsterm.COMPLETE_HINT_ONLY, testNext);
- yield undefined;
+ yield complete(jsterm.COMPLETE_HINT_ONLY);
is(jsterm.completeNode.value, " ice", "string literal completion");
- testDriver = jsterm = input = null;
- executeSoon(finishTest);
- yield undefined;
-}
+ jsterm = null;
+});
+
+function complete(type) {
+ let updated = jsterm.once("autocomplete-updated");
+ jsterm.complete(type);
+ return updated;
+}
diff --git a/browser/devtools/webconsole/test/browser_webconsole_console_extras.js b/browser/devtools/webconsole/test/browser_webconsole_console_extras.js
index dfb8d6ac08b5..b424374926ae 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_console_extras.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_console_extras.js
@@ -10,11 +10,9 @@
const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/test-console-extras.html";
function test() {
- addTab(TEST_URI);
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
- openConsole(null, consoleOpened);
- }, true);
+ loadTab(TEST_URI).then(() => {
+ openConsole().then(consoleOpened);
+ });
}
function consoleOpened(hud) {
diff --git a/browser/devtools/webconsole/test/browser_webconsole_console_logging_api.js b/browser/devtools/webconsole/test/browser_webconsole_console_logging_api.js
index 9425f1266c06..aeb73c58eed9 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_console_logging_api.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_console_logging_api.js
@@ -5,40 +5,33 @@
// Tests that the basic console.log()-style APIs and filtering work.
+"use strict";
+
const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/test-console.html";
-let hud, outputNode;
+let test = asyncTest(function*() {
+ yield loadTab(TEST_URI);
+ let hud = yield openConsole();
+ hud.jsterm.clearOutput();
-function test() {
- addTab(TEST_URI);
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
- Task.spawn(runner);
- }, true);
+ let outputNode = hud.outputNode;
- function* runner() {
- hud = yield openConsole();
- outputNode = hud.outputNode;
-
- let methods = ["log", "info", "warn", "error", "exception", "debug"];
- for (let method of methods) {
- yield testMethod(method);
- }
-
- executeSoon(finishTest);
+ let methods = ["log", "info", "warn", "error", "exception", "debug"];
+ for (let method of methods) {
+ yield testMethod(method, hud, outputNode);
}
-}
+});
-function* testMethod(aMethod) {
+function* testMethod(aMethod, aHud, aOutputNode) {
let console = content.console;
- hud.jsterm.clearOutput();
+ aHud.jsterm.clearOutput();
console[aMethod]("foo-bar-baz");
console[aMethod]("baar-baz");
yield waitForMessages({
- webconsole: hud,
+ webconsole: aHud,
messages: [{
text: "foo-bar-baz",
}, {
@@ -46,25 +39,25 @@ function* testMethod(aMethod) {
}],
});
- setStringFilter("foo");
+ setStringFilter("foo", aHud);
- is(outputNode.querySelectorAll(".filtered-by-string").length, 1,
+ is(aOutputNode.querySelectorAll(".filtered-by-string").length, 1,
"1 hidden " + aMethod + " node via string filtering")
- hud.jsterm.clearOutput();
+ aHud.jsterm.clearOutput();
// now toggle the current method off - make sure no visible message
// TODO: move all filtering tests into a separate test file: see bug 608135
console[aMethod]("foo-bar-baz");
yield waitForMessages({
- webconsole: hud,
+ webconsole: aHud,
messages: [{
text: "foo-bar-baz",
}],
});
- setStringFilter("");
+ setStringFilter("", aHud);
let filter;
switch(aMethod) {
case "debug":
@@ -78,23 +71,23 @@ function* testMethod(aMethod) {
break;
}
- hud.setFilterState(filter, false);
+ aHud.setFilterState(filter, false);
- is(outputNode.querySelectorAll(".filtered-by-type").length, 1,
+ is(aOutputNode.querySelectorAll(".filtered-by-type").length, 1,
"1 message hidden for " + aMethod + " (logging turned off)")
- hud.setFilterState(filter, true);
+ aHud.setFilterState(filter, true);
- is(outputNode.querySelectorAll(".message:not(.filtered-by-type)").length, 1,
+ is(aOutputNode.querySelectorAll(".message:not(.filtered-by-type)").length, 1,
"1 message shown for " + aMethod + " (logging turned on)")
- hud.jsterm.clearOutput();
+ aHud.jsterm.clearOutput();
// test for multiple arguments.
console[aMethod]("foo", "bar");
yield waitForMessages({
- webconsole: hud,
+ webconsole: aHud,
messages: [{
text: '"foo" "bar"',
category: CATEGORY_WEBDEV,
@@ -102,8 +95,7 @@ function* testMethod(aMethod) {
})
}
-function setStringFilter(aValue) {
- hud.ui.filterBox.value = aValue;
- hud.ui.adjustVisibilityOnSearchStringChange();
+function setStringFilter(aValue, aHud) {
+ aHud.ui.filterBox.value = aValue;
+ aHud.ui.adjustVisibilityOnSearchStringChange();
}
-
diff --git a/browser/devtools/webconsole/test/browser_webconsole_dont_navigate_on_doubleclick.js b/browser/devtools/webconsole/test/browser_webconsole_dont_navigate_on_doubleclick.js
index f1a03da7c83c..34eb87b00653 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_dont_navigate_on_doubleclick.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_dont_navigate_on_doubleclick.js
@@ -5,6 +5,8 @@
// Tests that if a link in console is double clicked, the console frame doesn't
// navigate to that destination (bug 975707).
+"use strict";
+
function test() {
let originalNetPref = Services.prefs.getBoolPref("devtools.webconsole.filter.networkinfo");
registerCleanupFunction(() => {
diff --git a/browser/devtools/webconsole/test/browser_webconsole_execution_scope.js b/browser/devtools/webconsole/test/browser_webconsole_execution_scope.js
index f29c907b3eaf..338b17e16d57 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_execution_scope.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_execution_scope.js
@@ -5,22 +5,17 @@
// Tests that commands run by the user are executed in content space.
+"use strict";
+
const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/test-console.html";
-function test() {
- addTab(TEST_URI);
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
- openConsole(null, testExecutionScope);
- }, true);
-}
+let test = asyncTest(function*() {
+ yield loadTab(TEST_URI);
+ let hud = yield openConsole();
+ hud.jsterm.clearOutput();
+ hud.jsterm.execute("window.location.href;");
-function testExecutionScope(hud) {
- let jsterm = hud.jsterm;
-
- jsterm.clearOutput();
- jsterm.execute("window.location.href;");
- waitForMessages({
+ let [input, output] = yield waitForMessages({
webconsole: hud,
messages: [{
text: "window.location.href;",
@@ -30,12 +25,10 @@ function testExecutionScope(hud) {
text: TEST_URI,
category: CATEGORY_OUTPUT,
}],
- }).then(([input, output]) => {
- let inputNode = [...input.matched][0];
- let outputNode = [...output.matched][0];
- is(inputNode.getAttribute("category"), "input", "input node category is correct");
- is(outputNode.getAttribute("category"), "output", "output node category is correct");
- finishTest();
});
-}
+ let inputNode = [...input.matched][0];
+ let outputNode = [...output.matched][0];
+ is(inputNode.getAttribute("category"), "input", "input node category is correct");
+ is(outputNode.getAttribute("category"), "output", "output node category is correct");
+});
diff --git a/browser/devtools/webconsole/test/browser_webconsole_expandable_timestamps.js b/browser/devtools/webconsole/test/browser_webconsole_expandable_timestamps.js
index 1818fecfe890..efcdaa63ca2b 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_expandable_timestamps.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_expandable_timestamps.js
@@ -4,54 +4,53 @@
// Test for the message timestamps option: check if the preference toggles the
// display of messages in the console output. See bug 722267.
-function test()
+const TEST_URI = "data:text/html;charset=utf-8,Web Console test for bug 722267 - " +
+ "preference for toggling timestamps in messages";
+const PREF_MESSAGE_TIMESTAMP = "devtools.webconsole.timestampMessages";
+let hud;
+
+let test = asyncTest(function* () {
+ yield loadTab(TEST_URI);
+
+ hud = yield openConsole();
+ let panel = yield consoleOpened();
+
+ yield onOptionsPanelSelected(panel);
+ onPrefChanged();
+
+ Services.prefs.clearUserPref(PREF_MESSAGE_TIMESTAMP);
+ hud = null;
+});
+
+function consoleOpened()
{
- const PREF_MESSAGE_TIMESTAMP = "devtools.webconsole.timestampMessages";
- let hud;
+ info("console opened");
+ let prefValue = Services.prefs.getBoolPref(PREF_MESSAGE_TIMESTAMP);
+ ok(!prefValue, "messages have no timestamp by default (pref check)");
+ ok(hud.outputNode.classList.contains("hideTimestamps"),
+ "messages have no timestamp (class name check)");
- registerCleanupFunction(() => {
- Services.prefs.clearUserPref(PREF_MESSAGE_TIMESTAMP);
- });
-
- addTab("data:text/html;charset=utf-8,Web Console test for bug 722267 - " +
- "preference for toggling timestamps in messages");
-
- browser.addEventListener("load", function tabLoad() {
- browser.removeEventListener("load", tabLoad, true);
- openConsole(null, consoleOpened);
- }, true);
-
- function consoleOpened(aHud)
- {
- hud = aHud;
-
- info("console opened");
- let prefValue = Services.prefs.getBoolPref(PREF_MESSAGE_TIMESTAMP);
- ok(!prefValue, "messages have no timestamp by default (pref check)");
- ok(hud.outputNode.classList.contains("hideTimestamps"),
- "messages have no timestamp (class name check)");
-
- let toolbox = gDevTools.getToolbox(hud.target);
- toolbox.selectTool("options").then(onOptionsPanelSelected);
- }
-
- function onOptionsPanelSelected(panel)
- {
- info("options panel opened");
-
- gDevTools.once("pref-changed", onPrefChanged);
-
- let checkbox = panel.panelDoc.getElementById("webconsole-timestamp-messages");
- checkbox.click();
- }
-
- function onPrefChanged()
- {
- info("pref changed");
- let prefValue = Services.prefs.getBoolPref(PREF_MESSAGE_TIMESTAMP);
- ok(prefValue, "messages have timestamps (pref check)");
- ok(!hud.outputNode.classList.contains("hideTimestamps"),
- "messages have timestamps (class name check)");
- finishTest();
- }
+ let toolbox = gDevTools.getToolbox(hud.target);
+ return toolbox.selectTool("options");
+}
+
+function onOptionsPanelSelected(panel)
+{
+ info("options panel opened");
+
+ let prefChanged = gDevTools.once("pref-changed", onPrefChanged);
+
+ let checkbox = panel.panelDoc.getElementById("webconsole-timestamp-messages");
+ checkbox.click();
+
+ return prefChanged;
+}
+
+function onPrefChanged()
+{
+ info("pref changed");
+ let prefValue = Services.prefs.getBoolPref(PREF_MESSAGE_TIMESTAMP);
+ ok(prefValue, "messages have timestamps (pref check)");
+ ok(!hud.outputNode.classList.contains("hideTimestamps"),
+ "messages have timestamps (class name check)");
}
diff --git a/browser/devtools/webconsole/test/browser_webconsole_filter_buttons_contextmenu.js b/browser/devtools/webconsole/test/browser_webconsole_filter_buttons_contextmenu.js
index 6b18bd7c0bd2..058b52afa6ae 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_filter_buttons_contextmenu.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_filter_buttons_contextmenu.js
@@ -6,11 +6,9 @@
const TEST_URI = "http://example.com/";
function test() {
- addTab(TEST_URI);
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
- openConsole(null, testFilterButtons);
- }, true);
+ loadTab(TEST_URI).then(() => {
+ openConsole().then(testFilterButtons);
+ })
}
function testFilterButtons(aHud) {
diff --git a/browser/devtools/webconsole/test/browser_webconsole_for_of.js b/browser/devtools/webconsole/test/browser_webconsole_for_of.js
index cfae6f2ea736..b5b6304f6ece 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_for_of.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_for_of.js
@@ -5,20 +5,23 @@
const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/test-for-of.html";
-function test() {
- addTab(TEST_URI);
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
- openConsole(null, testForOf);
- }, true);
-}
+let test = asyncTest(function* () {
+ yield loadTab(TEST_URI);
+
+ let hud = yield openConsole();
+ yield testForOf(hud);
+});
function testForOf(hud) {
+ let deferred = promise.defer();
+
var jsterm = hud.jsterm;
jsterm.execute("{ [x.tagName for (x of document.body.childNodes) if (x.nodeType === 1)].join(' '); }",
(node) => {
ok(/H1 DIV H2 P/.test(node.textContent),
"for-of loop should find all top-level nodes");
- finishTest();
+ deferred.resolve();
});
+
+ return deferred.promise;
}
diff --git a/browser/devtools/webconsole/test/browser_webconsole_history.js b/browser/devtools/webconsole/test/browser_webconsole_history.js
index bb39cd60fff3..42d957afbb26 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_history.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_history.js
@@ -5,21 +5,19 @@
// Tests the console history feature accessed via the up and down arrow keys.
+"use strict";
+
const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/test-console.html";
// Constants used for defining the direction of JSTerm input history navigation.
const HISTORY_BACK = -1;
const HISTORY_FORWARD = 1;
-function test() {
- addTab(TEST_URI);
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
- openConsole(null, testHistory);
- }, true);
-}
+let test = asyncTest(function*() {
+ yield loadTab(TEST_URI);
+ let hud = yield openConsole();
+ hud.jsterm.clearOutput();
-function testHistory(hud) {
let jsterm = hud.jsterm;
let input = jsterm.inputNode;
@@ -27,7 +25,7 @@ function testHistory(hud) {
for each (var item in executeList) {
input.value = item;
- jsterm.execute();
+ yield jsterm.execute();
}
for (var i = executeList.length - 1; i != -1; i--) {
@@ -60,7 +58,4 @@ function testHistory(hud) {
let idxLast = executeList.length - 1;
jsterm.historyPeruse(HISTORY_BACK);
is (input.value, executeList[idxLast], "check history next idx:" + idxLast);
-
- executeSoon(finishTest);
-}
-
+});
diff --git a/browser/devtools/webconsole/test/browser_webconsole_input_field_focus_on_panel_select.js b/browser/devtools/webconsole/test/browser_webconsole_input_field_focus_on_panel_select.js
index 02dc2274096d..192fc55950a4 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_input_field_focus_on_panel_select.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_input_field_focus_on_panel_select.js
@@ -5,19 +5,15 @@
// Test that the JS input field is focused when the user switches back to the
// web console from other tools, see bug 891581.
+"use strict";
+
const TEST_URI = "data:text/html;charset=utf8,
hello";
-function test()
-{
- addTab(TEST_URI);
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
- openConsole(null, consoleOpened);
- }, true);
-}
+let test = asyncTest(function*() {
+ yield loadTab(TEST_URI);
+ let hud = yield openConsole();
+ hud.jsterm.clearOutput();
-function consoleOpened(hud)
-{
is(hud.jsterm.inputNode.hasAttribute("focused"), true,
"inputNode should be focused");
@@ -29,18 +25,9 @@ function consoleOpened(hud)
is(hud.jsterm.inputNode.hasAttribute("focused"), false,
"inputNode shouldn't be focused");
- openDebugger().then(debuggerOpened);
-}
+ yield openDebugger();
+ hud = yield openConsole();
-function debuggerOpened()
-{
- openConsole(null, consoleReopened);
-}
-
-function consoleReopened(hud)
-{
is(hud.jsterm.inputNode.hasAttribute("focused"), true,
"inputNode should be focused");
-
- finishTest();
-}
+});
diff --git a/browser/devtools/webconsole/test/browser_webconsole_inspect-parsed-documents.js b/browser/devtools/webconsole/test/browser_webconsole_inspect-parsed-documents.js
index 0d00ded90a12..e55e021c25f9 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_inspect-parsed-documents.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_inspect-parsed-documents.js
@@ -1,11 +1,12 @@
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
-"use strict";
// Test that dynamically created (HTML|XML|SVG)Documents can be inspected by
// clicking on the object in console (bug 1035198).
+"use strict;"
+
const TEST_CASES = [
{
input: '(new DOMParser()).parseFromString("", "text/html")',
diff --git a/browser/devtools/webconsole/test/browser_webconsole_js_input_expansion.js b/browser/devtools/webconsole/test/browser_webconsole_js_input_expansion.js
index 2dce912932ef..fe048323302c 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_js_input_expansion.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_js_input_expansion.js
@@ -5,19 +5,16 @@
// Tests that the input box expands as the user types long lines.
+"use strict";
+
const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/test-console.html";
-function test() {
- addTab(TEST_URI);
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
- openConsole(null, testJSInputExpansion);
- }, true);
-}
+let test = asyncTest(function*() {
+ yield loadTab(TEST_URI);
+ let hud = yield openConsole();
+ hud.jsterm.clearOutput();
-function testJSInputExpansion(hud) {
- let jsterm = hud.jsterm;
- let input = jsterm.inputNode;
+ let input = hud.jsterm.inputNode;
input.focus();
is(input.getAttribute("multiline"), "true", "multiline is enabled");
@@ -55,6 +52,4 @@ function testJSInputExpansion(hud) {
info("initialHeight: " + initialHeight);
let finalHeightDifference = Math.abs(initialHeight - height);
ok(finalHeightDifference <= 1, "height shrank to original size within 1px");
-
- finishTest();
-}
+});
diff --git a/browser/devtools/webconsole/test/browser_webconsole_jsterm.js b/browser/devtools/webconsole/test/browser_webconsole_jsterm.js
index 2c81dc24d44e..8b9100d0ebea 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_jsterm.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_jsterm.js
@@ -5,24 +5,18 @@
const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/test-console.html";
-let jsterm, testDriver;
+let jsterm;
-function test() {
- addTab(TEST_URI);
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
- openConsole(null, function(hud) {
- testDriver = testJSTerm(hud);
- testDriver.next();
- });
- }, true);
-}
-
-function nextTest() {
- testDriver.next();
-}
+let test = asyncTest(function* () {
+ yield loadTab(TEST_URI);
+ let hud = yield openConsole();
+ jsterm = hud.jsterm;
+ yield testJSTerm(hud);
+ jsterm = null;
+});
function checkResult(msg, desc) {
+ let def = promise.defer();
waitForMessages({
webconsole: jsterm.hud.owner,
messages: [{
@@ -39,59 +33,49 @@ function checkResult(msg, desc) {
ok(msg(node), "correct message shown for " + desc);
}
- nextTest();
+ def.resolve();
});
+ return def.promise;
}
function testJSTerm(hud)
{
- jsterm = hud.jsterm;
const HELP_URL = "https://developer.mozilla.org/docs/Tools/Web_Console/Helpers";
jsterm.clearOutput();
- jsterm.execute("$('#header').getAttribute('id')");
- checkResult('"header"', "$() worked");
- yield undefined;
+ yield jsterm.execute("$('#header').getAttribute('id')");
+ yield checkResult('"header"', "$() worked");
jsterm.clearOutput();
- jsterm.execute("$$('h1').length");
- checkResult("1", "$$() worked");
- yield undefined;
+ yield jsterm.execute("$$('h1').length");
+ yield checkResult("1", "$$() worked");
jsterm.clearOutput();
- jsterm.execute("$x('.//*', document.body)[0] == $$('h1')[0]");
- checkResult("true", "$x() worked");
- yield undefined;
+ yield jsterm.execute("$x('.//*', document.body)[0] == $$('h1')[0]");
+ yield checkResult("true", "$x() worked");
// no jsterm.clearOutput() here as we clear the output using the clear() fn.
- jsterm.execute("clear()");
+ yield jsterm.execute("clear()");
- waitForSuccess({
+ yield waitForSuccess({
name: "clear() worked",
- validatorFn: function()
+ validator: function()
{
return jsterm.outputNode.childNodes.length == 0;
- },
- successFn: nextTest,
- failureFn: nextTest,
+ }
});
- yield undefined;
+ jsterm.clearOutput();
+ yield jsterm.execute("keys({b:1})[0] == 'b'");
+ yield checkResult("true", "keys() worked", 1);
jsterm.clearOutput();
- jsterm.execute("keys({b:1})[0] == 'b'");
- checkResult("true", "keys() worked", 1);
- yield undefined;
-
- jsterm.clearOutput();
- jsterm.execute("values({b:1})[0] == 1");
- checkResult("true", "values() worked", 1);
- yield undefined;
+ yield jsterm.execute("values({b:1})[0] == 1");
+ yield checkResult("true", "values() worked", 1);
jsterm.clearOutput();
let openedLinks = 0;
- let onExecuteCalls = 0;
let oldOpenLink = hud.openLink;
hud.openLink = (url) => {
if (url == HELP_URL) {
@@ -99,17 +83,9 @@ function testJSTerm(hud)
}
};
- function onExecute() {
- onExecuteCalls++;
- if (onExecuteCalls == 3) {
- nextTest();
- }
- }
-
- jsterm.execute("help()", onExecute);
- jsterm.execute("help", onExecute);
- jsterm.execute("?", onExecute);
- yield undefined;
+ yield jsterm.execute("help()");
+ yield jsterm.execute("help");
+ yield jsterm.execute("?");
let output = jsterm.outputNode.querySelector(".message[category='output']");
ok(!output, "no output for help() calls");
@@ -117,66 +93,52 @@ function testJSTerm(hud)
hud.openLink = oldOpenLink;
jsterm.clearOutput();
- jsterm.execute("pprint({b:2, a:1})");
- checkResult("\" b: 2\n a: 1\"", "pprint()");
- yield undefined;
+ yield jsterm.execute("pprint({b:2, a:1})");
+ yield checkResult("\" b: 2\n a: 1\"", "pprint()");
// check instanceof correctness, bug 599940
jsterm.clearOutput();
- jsterm.execute("[] instanceof Array");
- checkResult("true", "[] instanceof Array == true");
- yield undefined;
+ yield jsterm.execute("[] instanceof Array");
+ yield checkResult("true", "[] instanceof Array == true");
jsterm.clearOutput();
- jsterm.execute("({}) instanceof Object");
- checkResult("true", "({}) instanceof Object == true");
- yield undefined;
+ yield jsterm.execute("({}) instanceof Object");
+ yield checkResult("true", "({}) instanceof Object == true");
// check for occurrences of Object XRayWrapper, bug 604430
jsterm.clearOutput();
- jsterm.execute("document");
- checkResult(function(node) {
+ yield jsterm.execute("document");
+ yield checkResult(function(node) {
return node.textContent.search(/\[object xraywrapper/i) == -1;
}, "document - no XrayWrapper");
- yield undefined;
// check that pprint(window) and keys(window) don't throw, bug 608358
jsterm.clearOutput();
- jsterm.execute("pprint(window)");
- checkResult(null, "pprint(window)");
- yield undefined;
+ yield jsterm.execute("pprint(window)");
+ yield checkResult(null, "pprint(window)");
jsterm.clearOutput();
- jsterm.execute("keys(window)");
- checkResult(null, "keys(window)");
- yield undefined;
+ yield jsterm.execute("keys(window)");
+ yield checkResult(null, "keys(window)");
// bug 614561
jsterm.clearOutput();
- jsterm.execute("pprint('hi')");
- checkResult("\" 0: \"h\"\n 1: \"i\"\"", "pprint('hi')");
- yield undefined;
+ yield jsterm.execute("pprint('hi')");
+ yield checkResult("\" 0: \"h\"\n 1: \"i\"\"", "pprint('hi')");
// check that pprint(function) shows function source, bug 618344
jsterm.clearOutput();
- jsterm.execute("pprint(function() { var someCanaryValue = 42; })");
- checkResult(function(node) {
+ yield jsterm.execute("pprint(function() { var someCanaryValue = 42; })");
+ yield checkResult(function(node) {
return node.textContent.indexOf("someCanaryValue") > -1;
}, "pprint(function) shows source");
- yield undefined;
// check that an evaluated null produces "null", bug 650780
jsterm.clearOutput();
- jsterm.execute("null");
- checkResult("null", "null is null");
- yield undefined;
+ yield jsterm.execute("null");
+ yield checkResult("null", "null is null");
jsterm.clearOutput();
- jsterm.execute("undefined");
- checkResult("undefined", "undefined is printed");
- yield undefined;
-
- jsterm = testDriver = null;
- executeSoon(finishTest);
- yield undefined;
+ yield jsterm.execute("undefined");
+ yield checkResult("undefined", "undefined is printed");
}
diff --git a/browser/devtools/webconsole/test/browser_webconsole_live_filtering_of_message_types.js b/browser/devtools/webconsole/test/browser_webconsole_live_filtering_of_message_types.js
index d05ee988d2e8..02b79b6e954f 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_live_filtering_of_message_types.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_live_filtering_of_message_types.js
@@ -5,20 +5,13 @@
// Tests that the message type filter checkboxes work.
+"use strict";
+
const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/test-console.html";
-let hud;
-
-function test() {
- addTab(TEST_URI);
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
- openConsole(null, consoleOpened);
- }, true);
-}
-
-function consoleOpened(aHud) {
- hud = aHud;
+let test = asyncTest(function*() {
+ yield loadTab(TEST_URI);
+ let hud = yield openConsole();
hud.jsterm.clearOutput();
let console = content.console;
@@ -27,31 +20,27 @@ function consoleOpened(aHud) {
console.log("foobarz #" + i);
}
- waitForMessages({
+ yield waitForMessages({
webconsole: hud,
messages: [{
text: "foobarz #49",
category: CATEGORY_WEBDEV,
severity: SEVERITY_LOG,
}],
- }).then(testLiveFilteringOfMessageTypes);
-}
+ });
-function testLiveFilteringOfMessageTypes() {
is(hud.outputNode.children.length, 50, "number of messages");
hud.setFilterState("log", false);
- is(countMessageNodes(), 0, "the log nodes are hidden when the " +
+ is(countMessageNodes(hud), 0, "the log nodes are hidden when the " +
"corresponding filter is switched off");
hud.setFilterState("log", true);
- is(countMessageNodes(), 50, "the log nodes reappear when the " +
+ is(countMessageNodes(hud), 50, "the log nodes reappear when the " +
"corresponding filter is switched on");
+});
- finishTest();
-}
-
-function countMessageNodes() {
+function countMessageNodes(hud) {
let messageNodes = hud.outputNode.querySelectorAll(".message");
let displayedMessageNodes = 0;
let view = hud.iframeWindow;
diff --git a/browser/devtools/webconsole/test/browser_webconsole_live_filtering_on_search_strings.js b/browser/devtools/webconsole/test/browser_webconsole_live_filtering_on_search_strings.js
index 6a1e21e6d173..fb229075a123 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_live_filtering_on_search_strings.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_live_filtering_on_search_strings.js
@@ -5,84 +5,74 @@
// Tests that the text filter box works.
+"use strict";
+
const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/test-console.html";
-let hud;
-
-function test() {
- addTab(TEST_URI);
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
- openConsole(null, consoleOpened);
- }, true);
-}
-
-function consoleOpened(aHud) {
- hud = aHud;
+let test = asyncTest(function*() {
+ yield loadTab(TEST_URI);
+ let hud = yield openConsole();
hud.jsterm.clearOutput();
+
let console = content.console;
for (let i = 0; i < 50; i++) {
console.log("http://www.example.com/ " + i);
}
- waitForMessages({
+ yield waitForMessages({
webconsole: hud,
messages: [{
text: "http://www.example.com/ 49",
category: CATEGORY_WEBDEV,
severity: SEVERITY_LOG,
}],
- }).then(testLiveFilteringOnSearchStrings);
-}
+ })
-function testLiveFilteringOnSearchStrings() {
is(hud.outputNode.children.length, 50, "number of messages");
- setStringFilter("http");
- isnot(countMessageNodes(), 0, "the log nodes are not hidden when the " +
+ setStringFilter(hud, "http");
+ isnot(countMessageNodes(hud), 0, "the log nodes are not hidden when the " +
"search string is set to \"http\"");
- setStringFilter("hxxp");
- is(countMessageNodes(), 0, "the log nodes are hidden when the search " +
+ setStringFilter(hud, "hxxp");
+ is(countMessageNodes(hud), 0, "the log nodes are hidden when the search " +
"string is set to \"hxxp\"");
- setStringFilter("ht tp");
- isnot(countMessageNodes(), 0, "the log nodes are not hidden when the " +
+ setStringFilter(hud, "ht tp");
+ isnot(countMessageNodes(hud), 0, "the log nodes are not hidden when the " +
"search string is set to \"ht tp\"");
- setStringFilter(" zzzz zzzz ");
- is(countMessageNodes(), 0, "the log nodes are hidden when the search " +
+ setStringFilter(hud, " zzzz zzzz ");
+ is(countMessageNodes(hud), 0, "the log nodes are hidden when the search " +
"string is set to \" zzzz zzzz \"");
- setStringFilter("");
- isnot(countMessageNodes(), 0, "the log nodes are not hidden when the " +
+ setStringFilter(hud, "");
+ isnot(countMessageNodes(hud), 0, "the log nodes are not hidden when the " +
"search string is removed");
- setStringFilter("\u9f2c");
- is(countMessageNodes(), 0, "the log nodes are hidden when searching " +
+ setStringFilter(hud, "\u9f2c");
+ is(countMessageNodes(hud), 0, "the log nodes are hidden when searching " +
"for weasels");
- setStringFilter("\u0007");
- is(countMessageNodes(), 0, "the log nodes are hidden when searching for " +
+ setStringFilter(hud, "\u0007");
+ is(countMessageNodes(hud), 0, "the log nodes are hidden when searching for " +
"the bell character");
- setStringFilter('"foo"');
- is(countMessageNodes(), 0, "the log nodes are hidden when searching for " +
+ setStringFilter(hud, '"foo"');
+ is(countMessageNodes(hud), 0, "the log nodes are hidden when searching for " +
'the string "foo"');
- setStringFilter("'foo'");
- is(countMessageNodes(), 0, "the log nodes are hidden when searching for " +
+ setStringFilter(hud, "'foo'");
+ is(countMessageNodes(hud), 0, "the log nodes are hidden when searching for " +
"the string 'foo'");
- setStringFilter("foo\"bar'baz\"boo'");
- is(countMessageNodes(), 0, "the log nodes are hidden when searching for " +
+ setStringFilter(hud, "foo\"bar'baz\"boo'");
+ is(countMessageNodes(hud), 0, "the log nodes are hidden when searching for " +
"the string \"foo\"bar'baz\"boo'\"");
+});
- finishTest();
-}
-
-function countMessageNodes() {
+function countMessageNodes(hud) {
let outputNode = hud.outputNode;
let messageNodes = outputNode.querySelectorAll(".message");
@@ -98,7 +88,7 @@ function countMessageNodes() {
return displayedMessageNodes;
}
-function setStringFilter(aValue)
+function setStringFilter(hud, aValue)
{
hud.ui.filterBox.value = aValue;
hud.ui.adjustVisibilityOnSearchStringChange();
diff --git a/browser/devtools/webconsole/test/browser_webconsole_log_file_filter.js b/browser/devtools/webconsole/test/browser_webconsole_log_file_filter.js
index fcb31780382d..906bb2b4883e 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_log_file_filter.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_log_file_filter.js
@@ -9,26 +9,30 @@ const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/te
let hud;
-function test() {
- addTab(TEST_URI);
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
- openConsole(null, consoleOpened);
- }, true);
-}
+"use strict";
-function consoleOpened(aHud) {
- hud = aHud;
+let test = asyncTest(function* () {
+ yield loadTab(TEST_URI);
+
+ hud = yield openConsole();
+ yield consoleOpened();
+
+ testLiveFilteringOnSearchStrings();
+
+ hud = null;
+});
+
+function consoleOpened() {
let console = content.console;
console.log("sentinel log");
- waitForMessages({
+ return waitForMessages({
webconsole: hud,
messages: [{
text: "sentinel log",
category: CATEGORY_WEBDEV,
severity: SEVERITY_LOG
}],
- }).then(testLiveFilteringOnSearchStrings);
+ })
}
function testLiveFilteringOnSearchStrings() {
@@ -51,8 +55,6 @@ function testLiveFilteringOnSearchStrings() {
setStringFilter("");
is(countMessageNodes(), 4, "show all log nodes on setting filter string " +
"as \"\".");
-
- finishTest();
}
function countMessageNodes() {
diff --git a/browser/devtools/webconsole/test/browser_webconsole_message_node_id.js b/browser/devtools/webconsole/test/browser_webconsole_message_node_id.js
index 825fd5d631c8..0a94538e6a85 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_message_node_id.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_message_node_id.js
@@ -3,29 +3,25 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+"use strict";
+
const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/test-console.html";
-function test() {
- addTab(TEST_URI);
- browser.addEventListener("DOMContentLoaded", onLoad, false);
-}
+let test = asyncTest(function*() {
+ yield loadTab(TEST_URI);
+ let hud = yield openConsole();
-function onLoad() {
- browser.removeEventListener("DOMContentLoaded", onLoad, false);
- openConsole(null, function(hud) {
- content.console.log("a log message");
+ hud.jsterm.execute("console.log('a log message')");
- waitForMessages({
+ let [result] = yield waitForMessages({
webconsole: hud,
messages: [{
text: "a log message",
category: CATEGORY_WEBDEV,
severity: SEVERITY_LOG,
}],
- }).then(([result]) => {
- let msg = [...result.matched][0];
- ok(msg.getAttribute("id"), "log message has an ID");
- finishTest();
- });
});
-}
+
+ let msg = [...result.matched][0];
+ ok(msg.getAttribute("id"), "log message has an ID");
+});
diff --git a/browser/devtools/webconsole/test/browser_webconsole_netlogging.js b/browser/devtools/webconsole/test/browser_webconsole_netlogging.js
index 8d55ccf80a35..7cf95822ef65 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_netlogging.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_netlogging.js
@@ -12,6 +12,8 @@
// Tests that network log messages bring up the network panel.
+const TEST_URI = "data:text/html;charset=utf-8,Web Console network logging tests";
+
const TEST_NETWORK_REQUEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/test-network-request.html";
const TEST_IMG = "http://example.com/browser/browser/devtools/webconsole/test/test-image.png";
@@ -21,22 +23,21 @@ const TEST_DATA_JSON_CONTENT =
let lastRequest = null;
let requestCallback = null;
+let browser, hud;
function test()
{
- addTab("data:text/html;charset=utf-8,Web Console network logging tests");
+ loadTab(TEST_URI).then((tab) => {
+ browser = tab.browser;
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
-
- openConsole(null, function(aHud) {
+ openConsole().then((aHud) => {
hud = aHud;
HUDService.lastFinishedRequest.callback = requestCallbackWrapper;
executeSoon(testPageLoad);
});
- }, true);
+ });
}
function requestCallbackWrapper(aRequest)
@@ -205,6 +206,7 @@ function testNetworkPanel()
networkPanel.panel.hidePopup();
lastRequest = null;
HUDService.lastFinishedRequest.callback = null;
+ browser = requestCallback = hud = null;
executeSoon(finishTest);
}, true);
}
diff --git a/browser/devtools/webconsole/test/browser_webconsole_network_panel.js b/browser/devtools/webconsole/test/browser_webconsole_network_panel.js
index 82f9d1ef9763..0cea84fea650 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_network_panel.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_network_panel.js
@@ -19,17 +19,16 @@ const TEST_IMG_BASE64 =
"A16/JvfiigMSYyzqJXlw/XKUyOORMUaBor6YavgdjKa8xGOnidadmwtwsnMu18q83/kHSou+bFND" +
"Dr4AAAAASUVORK5CYII=";
-let testDriver;
+let testDriver, hud;
function test() {
- addTab(TEST_URI);
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
- openConsole(null, testNetworkPanel);
- }, true);
+ loadTab(TEST_URI).then(() => {
+ openConsole().then(testNetworkPanel);
+ });
}
-function testNetworkPanel() {
+function testNetworkPanel(aHud) {
+ hud = aHud;
testDriver = testGen();
testDriver.next();
}
@@ -71,7 +70,6 @@ function checkNodeKeyValue(aPanel, aId, aKey, aValue) {
}
function testGen() {
- let hud = HUDService.getHudByWindow(content);
let filterBox = hud.ui.filterBox;
let httpActivity = {
@@ -536,7 +534,7 @@ function testGen() {
networkPanel.panel.hidePopup(); */
// All done!
- testDriver = null;
+ testDriver = hud = null;
executeSoon(finishTest);
yield undefined;
diff --git a/browser/devtools/webconsole/test/browser_webconsole_notifications.js b/browser/devtools/webconsole/test/browser_webconsole_notifications.js
index 1c7f34fe2337..bc0ca015cf14 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_notifications.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_notifications.js
@@ -5,66 +5,73 @@
const TEST_URI = "data:text/html;charset=utf-8,
Web Console test for notifications";
-function test() {
- observer.init();
- addTab(TEST_URI);
- browser.addEventListener("load", onLoad, true);
-}
+let test = asyncTest(function* () {
+ yield loadTab(TEST_URI);
-function webConsoleCreated(aID)
-{
- Services.obs.removeObserver(observer, "web-console-created");
- ok(HUDService.getHudReferenceById(aID), "We have a hud reference");
- content.wrappedJSObject.console.log("adding a log message");
-}
+ let gotEvents = waitForEvents();
-function webConsoleDestroyed(aID)
-{
- Services.obs.removeObserver(observer, "web-console-destroyed");
- ok(!HUDService.getHudReferenceById(aID), "We do not have a hud reference");
- executeSoon(finishTest);
-}
+ let hud = yield openConsole();
-function webConsoleMessage(aID, aNodeID)
-{
- Services.obs.removeObserver(observer, "web-console-message-created");
- ok(aID, "we have a console ID");
- is(typeof aNodeID, "string", "message node id is a string");
- executeSoon(closeConsole);
-}
+ yield gotEvents;
+});
-let observer = {
+function waitForEvents() {
+ let deferred = promise.defer();
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
-
- observe: function observe(aSubject, aTopic, aData)
+ function webConsoleCreated(aID)
{
- aSubject = aSubject.QueryInterface(Ci.nsISupportsString);
-
- switch(aTopic) {
- case "web-console-created":
- webConsoleCreated(aSubject.data);
- break;
- case "web-console-destroyed":
- webConsoleDestroyed(aSubject.data);
- break;
- case "web-console-message-created":
- webConsoleMessage(aSubject, aData);
- break;
- default:
- break;
- }
- },
-
- init: function init()
- {
- Services.obs.addObserver(this, "web-console-created", false);
- Services.obs.addObserver(this, "web-console-destroyed", false);
- Services.obs.addObserver(this, "web-console-message-created", false);
+ Services.obs.removeObserver(observer, "web-console-created");
+ ok(HUDService.getHudReferenceById(aID), "We have a hud reference");
+ content.wrappedJSObject.console.log("adding a log message");
}
-};
-function onLoad() {
- browser.removeEventListener("load", onLoad, true);
- openConsole();
+ function webConsoleDestroyed(aID)
+ {
+ Services.obs.removeObserver(observer, "web-console-destroyed");
+ ok(!HUDService.getHudReferenceById(aID), "We do not have a hud reference");
+ executeSoon(deferred.resolve);
+ }
+
+ function webConsoleMessage(aID, aNodeID)
+ {
+ Services.obs.removeObserver(observer, "web-console-message-created");
+ ok(aID, "we have a console ID");
+ is(typeof aNodeID, "string", "message node id is a string");
+ executeSoon(closeConsole);
+ }
+
+ let observer = {
+
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
+
+ observe: function observe(aSubject, aTopic, aData)
+ {
+ aSubject = aSubject.QueryInterface(Ci.nsISupportsString);
+
+ switch(aTopic) {
+ case "web-console-created":
+ webConsoleCreated(aSubject.data);
+ break;
+ case "web-console-destroyed":
+ webConsoleDestroyed(aSubject.data);
+ break;
+ case "web-console-message-created":
+ webConsoleMessage(aSubject, aData);
+ break;
+ default:
+ break;
+ }
+ },
+
+ init: function init()
+ {
+ Services.obs.addObserver(this, "web-console-created", false);
+ Services.obs.addObserver(this, "web-console-destroyed", false);
+ Services.obs.addObserver(this, "web-console-message-created", false);
+ }
+ }
+
+ observer.init();
+
+ return deferred.promise;
}
diff --git a/browser/devtools/webconsole/test/browser_webconsole_open-links-without-callback.js b/browser/devtools/webconsole/test/browser_webconsole_open-links-without-callback.js
index 8f1eb758ae3f..225a340ef5a5 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_open-links-without-callback.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_open-links-without-callback.js
@@ -5,6 +5,8 @@
// Tests that if a link without an onclick callback is clicked the link is
// opened in a new tab and no exception occurs (bug 999236).
+"use strict";
+
function test() {
function* runner() {
const TEST_EVAL_STRING = "document";
diff --git a/browser/devtools/webconsole/test/browser_webconsole_output_01.js b/browser/devtools/webconsole/test/browser_webconsole_output_01.js
index c5c5df79f2e6..12e96a992b92 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_output_01.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_output_01.js
@@ -108,6 +108,8 @@ if (typeof Symbol !== "undefined") {
longString = initialString = null;
function test() {
+ requestLongerTimeout(2);
+
registerCleanupFunction(() => {
DebuggerServer.LONG_STRING_LENGTH = LONG_STRING_LENGTH;
DebuggerServer.LONG_STRING_INITIAL_LENGTH = LONG_STRING_INITIAL_LENGTH;
@@ -121,6 +123,6 @@ function test() {
}
function finishUp() {
- inputTests = null;
+ longString = initialString = inputTests = null;
finishTest();
}
diff --git a/browser/devtools/webconsole/test/browser_webconsole_output_04.js b/browser/devtools/webconsole/test/browser_webconsole_output_04.js
index cd24521273a9..f50f4d073085 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_output_04.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_output_04.js
@@ -117,6 +117,7 @@ let inputTests = [
];
function test() {
+ requestLongerTimeout(2);
Task.spawn(function*() {
const {tab} = yield loadTab(TEST_URI);
const hud = yield openConsole(tab);
diff --git a/browser/devtools/webconsole/test/browser_webconsole_output_05.js b/browser/devtools/webconsole/test/browser_webconsole_output_05.js
index 9dc6618363fc..43c0dae16814 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_output_05.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_output_05.js
@@ -107,6 +107,7 @@ let inputTests = [
];
function test() {
+ requestLongerTimeout(2);
Task.spawn(function*() {
let {tab} = yield loadTab(TEST_URI);
let hud = yield openConsole(tab);
@@ -115,6 +116,6 @@ function test() {
}
function finishUp() {
- inputTests = null;
+ inputTests = dateNow = null;
finishTest();
}
diff --git a/browser/devtools/webconsole/test/browser_webconsole_output_06.js b/browser/devtools/webconsole/test/browser_webconsole_output_06.js
index ebe9d8760e76..1925acd5678e 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_output_06.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_output_06.js
@@ -101,6 +101,7 @@ let inputTests = [
];
function test() {
+ requestLongerTimeout(2);
Task.spawn(function*() {
let {tab} = yield loadTab(TEST_URI);
let hud = yield openConsole(tab);
diff --git a/browser/devtools/webconsole/test/browser_webconsole_output_copy_newlines.js b/browser/devtools/webconsole/test/browser_webconsole_output_copy_newlines.js
index ff2cf2506a72..3760996611a5 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_output_copy_newlines.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_output_copy_newlines.js
@@ -4,74 +4,64 @@
// Test that multiple messages are copied into the clipboard and that they are
// separated by new lines. See bug 916997.
-function test()
-{
+"use strict";
+
+let test = asyncTest(function*() {
const TEST_URI = "data:text/html;charset=utf8,
hello world, bug 916997";
let clipboardValue = "";
- addTab(TEST_URI);
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
- openConsole(null, consoleOpened);
- }, true);
+ yield loadTab(TEST_URI);
+ let hud = yield openConsole();
+ hud.jsterm.clearOutput();
- function consoleOpened(hud)
- {
- hud.jsterm.clearOutput();
+ let controller = top.document.commandDispatcher.
+ getControllerForCommand("cmd_copy");
+ is(controller.isCommandEnabled("cmd_copy"), false, "cmd_copy is disabled");
- let controller = top.document.commandDispatcher.
- getControllerForCommand("cmd_copy");
- is(controller.isCommandEnabled("cmd_copy"), false, "cmd_copy is disabled");
+ content.console.log("Hello world! bug916997a");
+ content.console.log("Hello world 2! bug916997b");
- content.console.log("Hello world! bug916997a");
- content.console.log("Hello world 2! bug916997b");
+ yield waitForMessages({
+ webconsole: hud,
+ messages: [{
+ text: "Hello world! bug916997a",
+ category: CATEGORY_WEBDEV,
+ severity: SEVERITY_LOG,
+ }, {
+ text: "Hello world 2! bug916997b",
+ category: CATEGORY_WEBDEV,
+ severity: SEVERITY_LOG,
+ }],
+ });
- waitForMessages({
- webconsole: hud,
- messages: [{
- text: "Hello world! bug916997a",
- category: CATEGORY_WEBDEV,
- severity: SEVERITY_LOG,
- }, {
- text: "Hello world 2! bug916997b",
- category: CATEGORY_WEBDEV,
- severity: SEVERITY_LOG,
- }],
- }).then(() => {
- hud.ui.output.selectAllMessages();
- hud.outputNode.focus();
+ hud.ui.output.selectAllMessages();
+ hud.outputNode.focus();
- goUpdateCommand("cmd_copy");
- controller = top.document.commandDispatcher.getControllerForCommand("cmd_copy");
- is(controller.isCommandEnabled("cmd_copy"), true, "cmd_copy is enabled");
+ goUpdateCommand("cmd_copy");
+ controller = top.document.commandDispatcher.getControllerForCommand("cmd_copy");
+ is(controller.isCommandEnabled("cmd_copy"), true, "cmd_copy is enabled");
- let selection = hud.iframeWindow.getSelection() + "";
- info("selection '" + selection + "'");
- waitForClipboard((str) => {
- clipboardValue = str;
- return str.indexOf("bug916997a") > -1 && str.indexOf("bug916997b") > -1;
- },
- () => { goDoCommand("cmd_copy"); },
- checkClipboard.bind(null, hud),
- () => {
- info("last clipboard value: '" + clipboardValue + "'");
- finishTest();
- });
+ let selection = hud.iframeWindow.getSelection() + "";
+ info("selection '" + selection + "'");
+
+ waitForClipboard((str) => {
+ clipboardValue = str;
+ return str.indexOf("bug916997a") > -1 && str.indexOf("bug916997b") > -1;
+ },
+ () => { goDoCommand("cmd_copy"); },
+ () => {
+ info("clipboard value '" + clipboardValue + "'");
+ let lines = clipboardValue.trim().split("\n");
+ is(hud.outputNode.children.length, 2, "number of messages");
+ is(lines.length, hud.outputNode.children.length, "number of lines");
+ isnot(lines[0].indexOf("bug916997a"), -1,
+ "first message text includes 'bug916997a'");
+ isnot(lines[1].indexOf("bug916997b"), -1,
+ "second message text includes 'bug916997b'");
+ is(lines[0].indexOf("bug916997b"), -1,
+ "first message text does not include 'bug916997b'");
+ },
+ () => {
+ info("last clipboard value: '" + clipboardValue + "'");
});
- }
-
- function checkClipboard(hud)
- {
- info("clipboard value '" + clipboardValue + "'");
- let lines = clipboardValue.trim().split("\n");
- is(hud.outputNode.children.length, 2, "number of messages");
- is(lines.length, hud.outputNode.children.length, "number of lines");
- isnot(lines[0].indexOf("bug916997a"), -1,
- "first message text includes 'bug916997a'");
- isnot(lines[1].indexOf("bug916997b"), -1,
- "second message text includes 'bug916997b'");
- is(lines[0].indexOf("bug916997b"), -1,
- "first message text does not include 'bug916997b'");
- finishTest();
- }
-}
+});
diff --git a/browser/devtools/webconsole/test/browser_webconsole_output_dom_elements_01.js b/browser/devtools/webconsole/test/browser_webconsole_output_dom_elements_01.js
index a61c478891e6..e7cc49369693 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_output_dom_elements_01.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_output_dom_elements_01.js
@@ -99,6 +99,7 @@ let inputTests = [
];
function test() {
+ requestLongerTimeout(2);
Task.spawn(function*() {
let {tab} = yield loadTab(TEST_URI);
let hud = yield openConsole(tab);
diff --git a/browser/devtools/webconsole/test/browser_webconsole_output_dom_elements_02.js b/browser/devtools/webconsole/test/browser_webconsole_output_dom_elements_02.js
index 4dbd900710a0..d6db04ea161f 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_output_dom_elements_02.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_output_dom_elements_02.js
@@ -14,19 +14,27 @@ const TEST_DATA = [
// default selected node, so re-selecting it won't fire the inspector-updated
// event
input: "testNode()",
- output: '
'
+ output: '
',
+ tagName: 'P',
+ attrs: [{name: "some-attribute", value: "some-value"}]
},
{
input: "testBodyNode()",
- output: '
'
+ output: '',
+ tagName: 'BODY',
+ attrs: [{name: "id", value: "body-id"}, {name: "class", value: "body-class"}]
},
{
input: "testNodeInIframe()",
- output: ''
+ output: '
',
+ tagName: 'P',
+ attrs: []
},
{
input: "testDocumentElement()",
- output: ''
+ output: '',
+ tagName: 'HTML',
+ attrs: [{name: "lang", value: "en-US"}, {name: "dir", value: "ltr"}]
}
];
@@ -53,18 +61,23 @@ function test() {
info("Clicking on the inspector icon and waiting for the inspector to be selected");
let onInspectorSelected = toolbox.once("inspector-selected");
let onInspectorUpdated = inspector.once("inspector-updated");
- let onNewNode = toolbox.selection.once("new-node");
+ let onNewNode = toolbox.selection.once("new-node-front");
EventUtils.synthesizeMouseAtCenter(inspectorIcon, {},
inspectorIcon.ownerDocument.defaultView);
yield onInspectorSelected;
yield onInspectorUpdated;
- yield onNewNode;
+ let nodeFront = yield onNewNode;
+
ok(true, "Inspector selected and new node got selected");
- let rawNode = content.wrappedJSObject[data.input.replace(/\(\)/g, "")]();
- is(inspector.selection.node.wrappedJSObject, rawNode,
- "The current inspector selection is correct");
+ is(nodeFront.tagName, data.tagName, "The correct node was highlighted");
+
+ let attrs = nodeFront.attributes;
+ for (let i in data.attrs) {
+ is(attrs[i].name, data.attrs[i].name, "The correct node was highlighted");
+ is(attrs[i].value, data.attrs[i].value, "The correct node was highlighted");
+ }
info("Switching back to the console");
yield toolbox.selectTool("webconsole");
diff --git a/browser/devtools/webconsole/test/browser_webconsole_output_events.js b/browser/devtools/webconsole/test/browser_webconsole_output_events.js
index 079abaa23c92..72b2ec93d46a 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_output_events.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_output_events.js
@@ -14,54 +14,40 @@ thisTestLeaksUncaughtRejectionsAndShouldBeFixed("null");
const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/test-console-output-events.html";
-function test() {
- addTab(TEST_URI);
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
- Task.spawn(runner);
- }, true);
+let test = asyncTest(function* () {
+ yield loadTab(TEST_URI);
- function* runner()
- {
- let hud = yield openConsole();
+ let hud = yield openConsole();
- hud.jsterm.clearOutput();
- hud.jsterm.execute("testDOMEvents()");
+ hud.jsterm.clearOutput();
+ hud.jsterm.execute("testDOMEvents()");
- yield waitForMessages({
- webconsole: hud,
- messages: [{
- name: "testDOMEvents() output",
- text: "undefined",
- category: CATEGORY_OUTPUT,
- }],
- });
+ yield waitForMessages({
+ webconsole: hud,
+ messages: [{
+ name: "testDOMEvents() output",
+ text: "undefined",
+ category: CATEGORY_OUTPUT,
+ }],
+ });
- EventUtils.synthesizeMouse(content.document.body, 2, 2, {type: "mousemove"}, content);
+ yield waitForMessages({
+ webconsole: hud,
+ messages: [{
+ name: "console.log() output for mousemove",
+ text: /"eventLogger" mousemove { target: .+, buttons: 0, clientX: \d+, clientY: \d+, layerX: \d+, layerY: \d+ }/,
+ category: CATEGORY_WEBDEV,
+ severity: SEVERITY_LOG,
+ }],
+ });
- yield waitForMessages({
- webconsole: hud,
- messages: [{
- name: "console.log() output for mousemove",
- text: /"eventLogger" mousemove { target: .+, buttons: 1, clientX: \d+, clientY: \d+, layerX: \d+, layerY: \d+ }/,
- category: CATEGORY_WEBDEV,
- severity: SEVERITY_LOG,
- }],
- });
-
- content.focus();
- EventUtils.synthesizeKey("a", {shiftKey: true}, content);
-
- yield waitForMessages({
- webconsole: hud,
- messages: [{
- name: "console.log() output for keypress",
- text: /"eventLogger" keypress Shift { target: .+, key: .+, charCode: \d+, keyCode: \d+ }/,
- category: CATEGORY_WEBDEV,
- severity: SEVERITY_LOG,
- }],
- });
-
- finishTest();
- }
-}
+ yield waitForMessages({
+ webconsole: hud,
+ messages: [{
+ name: "console.log() output for keypress",
+ text: /"eventLogger" keypress Shift { target: .+, key: .+, charCode: \d+, keyCode: \d+ }/,
+ category: CATEGORY_WEBDEV,
+ severity: SEVERITY_LOG,
+ }],
+ });
+});
\ No newline at end of file
diff --git a/browser/devtools/webconsole/test/browser_webconsole_output_order.js b/browser/devtools/webconsole/test/browser_webconsole_output_order.js
index 4712be52de29..4a2a9f6be537 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_output_order.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_output_order.js
@@ -6,24 +6,21 @@
// Tests that any output created from calls to the console API comes after the
// echoed JavaScript.
+"use strict";
+
const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/test-console.html";
-function test() {
- addTab(TEST_URI);
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
- openConsole(null, testOutputOrder);
- }, true);
-}
+let test = asyncTest(function*() {
+ yield loadTab(TEST_URI);
+ let hud = yield openConsole();
-function testOutputOrder(hud) {
let jsterm = hud.jsterm;
let outputNode = jsterm.outputNode;
jsterm.clearOutput();
jsterm.execute("console.log('foo', 'bar');");
- waitForMessages({
+ let [function_call, result, console_message] = yield waitForMessages({
webconsole: hud,
messages: [{
text: "console.log('foo', 'bar');",
@@ -38,14 +35,13 @@ function testOutputOrder(hud) {
category: CATEGORY_WEBDEV,
severity: SEVERITY_LOG,
}],
- }).then(([function_call, result, console_message]) => {
- let fncall_node = [...function_call.matched][0];
- let result_node = [...result.matched][0];
- let console_message_node = [...console_message.matched][0];
- is(fncall_node.nextElementSibling, result_node,
- "console.log() is followed by undefined");
- is(result_node.nextElementSibling, console_message_node,
- "undefined is followed by 'foo' 'bar'");
- finishTest();
});
-}
+
+ let fncall_node = [...function_call.matched][0];
+ let result_node = [...result.matched][0];
+ let console_message_node = [...console_message.matched][0];
+ is(fncall_node.nextElementSibling, result_node,
+ "console.log() is followed by undefined");
+ is(result_node.nextElementSibling, console_message_node,
+ "undefined is followed by 'foo' 'bar'");
+});
diff --git a/browser/devtools/webconsole/test/browser_webconsole_property_provider.js b/browser/devtools/webconsole/test/browser_webconsole_property_provider.js
index 2ca742d48178..14c054d36cc5 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_property_provider.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_property_provider.js
@@ -9,11 +9,10 @@
const TEST_URI = "data:text/html;charset=utf8,
test the JS property provider";
function test() {
- addTab(TEST_URI);
- browser.addEventListener("load", testPropertyProvider, true);
+ loadTab(TEST_URI).then(testPropertyProvider);
}
-function testPropertyProvider() {
+function testPropertyProvider({browser}) {
browser.removeEventListener("load", testPropertyProvider, true);
let tools = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools;
let JSPropertyProvider = tools.require("devtools/toolkit/webconsole/utils").JSPropertyProvider;
diff --git a/browser/devtools/webconsole/test/browser_webconsole_reflow.js b/browser/devtools/webconsole/test/browser_webconsole_reflow.js
index a357c8b581d4..328b296de37d 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_reflow.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_reflow.js
@@ -3,33 +3,30 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-function test()
-{
- addTab("data:text/html;charset=utf-8,Web Console test for reflow activity");
+"use strict";
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
- openConsole(gBrowser.selectedTab, function(hud) {
+const TEST_URI = "data:text/html;charset=utf-8,Web Console test for reflow activity";
- function onReflowListenersReady(aType, aPacket) {
- browser.contentDocument.body.style.display = "none";
- browser.contentDocument.body.clientTop;
- }
+let test = asyncTest(function* () {
+ let { browser } = yield loadTab(TEST_URI);
- Services.prefs.setBoolPref("devtools.webconsole.filter.csslog", true);
- hud.ui._updateReflowActivityListener(onReflowListenersReady);
- Services.prefs.clearUserPref("devtools.webconsole.filter.csslog");
+ let hud = yield openConsole();
- waitForMessages({
- webconsole: hud,
- messages: [{
- text: /reflow: /,
- category: CATEGORY_CSS,
- severity: SEVERITY_LOG,
- }],
- }).then(() => {
- finishTest();
- });
- });
- }, true);
-}
+ function onReflowListenersReady(aType, aPacket) {
+ browser.contentDocument.body.style.display = "none";
+ browser.contentDocument.body.clientTop;
+ }
+
+ Services.prefs.setBoolPref("devtools.webconsole.filter.csslog", true);
+ hud.ui._updateReflowActivityListener(onReflowListenersReady);
+ Services.prefs.clearUserPref("devtools.webconsole.filter.csslog");
+
+ yield waitForMessages({
+ webconsole: hud,
+ messages: [{
+ text: /reflow: /,
+ category: CATEGORY_CSS,
+ severity: SEVERITY_LOG,
+ }],
+ })
+});
diff --git a/browser/devtools/webconsole/test/browser_webconsole_scratchpad_panel_link.js b/browser/devtools/webconsole/test/browser_webconsole_scratchpad_panel_link.js
index 04077cdafe75..0d1db73c5828 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_scratchpad_panel_link.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_scratchpad_panel_link.js
@@ -15,14 +15,12 @@ function test()
{
waitForExplicitFinish();
- addTab(TEST_URI);
- gBrowser.selectedBrowser.addEventListener("load", function onTabLoad() {
- gBrowser.selectedBrowser.removeEventListener("load", onTabLoad, true);
+ loadTab(TEST_URI).then(() => {
info("Opening toolbox with Scratchpad panel");
let target = TargetFactory.forTab(gBrowser.selectedTab);
gDevTools.showToolbox(target, "scratchpad", "window").then(runTests);
- }, true);
+ });
}
function runTests(aToolbox)
diff --git a/browser/devtools/webconsole/test/browser_webconsole_split.js b/browser/devtools/webconsole/test/browser_webconsole_split.js
index 30ae9ce70852..9501cd238e0f 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_split.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_split.js
@@ -3,6 +3,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+const TEST_URI = "data:text/html;charset=utf-8,Web Console test for splitting";
+
function test()
{
// Test is slow on Linux EC2 instances - Bug 962931
@@ -13,11 +15,7 @@ function test()
let Toolbox = devtools.Toolbox;
let toolbox;
- addTab("data:text/html;charset=utf-8,Web Console test for splitting");
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
- testConsoleLoadOnDifferentPanel()
- }, true);
+ loadTab(TEST_URI).then(testConsoleLoadOnDifferentPanel);
function testConsoleLoadOnDifferentPanel()
{
diff --git a/browser/devtools/webconsole/test/browser_webconsole_view_source.js b/browser/devtools/webconsole/test/browser_webconsole_view_source.js
index 33d364166aa3..ad008478df71 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_view_source.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_view_source.js
@@ -11,11 +11,9 @@ let Sources;
let getItemInvoked = false;
function test() {
- addTab(TEST_URI);
- browser.addEventListener("load", function onLoad() {
- browser.removeEventListener("load", onLoad, true);
- openConsole(null, testViewSource);
- }, true);
+ loadTab(TEST_URI).then(() => {
+ openConsole(null).then(testViewSource);
+ });
}
function testViewSource(hud) {
@@ -30,7 +28,7 @@ function testViewSource(hud) {
openDebugger().then(({panelWin: { DebuggerView }}) => {
info("debugger opened");
Sources = DebuggerView.Sources;
- openConsole(null, (hud) => {
+ openConsole().then((hud) => {
info("console opened again");
waitForMessages({
diff --git a/browser/devtools/webconsole/test/head.js b/browser/devtools/webconsole/test/head.js
index cdf81ee3069c..e842f3ad93de 100644
--- a/browser/devtools/webconsole/test/head.js
+++ b/browser/devtools/webconsole/test/head.js
@@ -15,6 +15,7 @@ let {Utils: WebConsoleUtils} = require("devtools/toolkit/webconsole/utils");
let {Messages} = require("devtools/webconsole/console-output");
// promise._reportErrors = true; // please never leave me.
+//Services.prefs.setBoolPref("devtools.debugger.log", true);
let gPendingOutputTest = 0;
@@ -40,35 +41,13 @@ const WEBCONSOLE_STRINGS_URI = "chrome://browser/locale/devtools/webconsole.prop
let WCU_l10n = new WebConsoleUtils.l10n(WEBCONSOLE_STRINGS_URI);
gDevTools.testing = true;
-SimpleTest.registerCleanupFunction(() => {
- gDevTools.testing = false;
-});
-function log(aMsg)
-{
- dump("*** WebConsoleTest: " + aMsg + "\n");
+function asyncTest(generator) {
+ return () => {
+ Task.spawn(generator).then(finishTest);
+ };
}
-function pprint(aObj)
-{
- for (let prop in aObj) {
- if (typeof aObj[prop] == "function") {
- log("function " + prop);
- }
- else {
- log(prop + ": " + aObj[prop]);
- }
- }
-}
-
-let tab, browser, hudId, hud, hudBox, filterBox, outputNode, cs;
-
-function addTab(aURL)
-{
- gBrowser.selectedTab = gBrowser.addTab(aURL);
- tab = gBrowser.selectedTab;
- browser = gBrowser.getBrowserForTab(tab);
-}
function loadTab(url) {
let deferred = promise.defer();
@@ -89,7 +68,7 @@ function loadBrowser(browser) {
browser.addEventListener("load", function onLoad() {
browser.removeEventListener("load", onLoad, true);
- deferred.resolve(null)
+ deferred.resolve(null);
}, true);
return deferred.promise;
@@ -198,18 +177,16 @@ function findLogEntry(aString)
* @return object
* A promise that is resolved once the web console is open.
*/
-function openConsole(aTab, aCallback = function() { })
-{
- let deferred = promise.defer();
- let target = TargetFactory.forTab(aTab || tab);
- gDevTools.showToolbox(target, "webconsole").then(function(toolbox) {
+let openConsole = function(aTab) {
+ let webconsoleOpened = promise.defer();
+ let target = TargetFactory.forTab(aTab || gBrowser.selectedTab);
+ gDevTools.showToolbox(target, "webconsole").then(toolbox => {
let hud = toolbox.getCurrentPanel().hud;
hud.jsterm._lazyVariablesView = false;
- aCallback(hud);
- deferred.resolve(hud);
+ webconsoleOpened.resolve(hud);
});
- return deferred.promise;
-}
+ return webconsoleOpened.promise;
+};
/**
* Close the Web Console for the given tab.
@@ -223,22 +200,13 @@ function openConsole(aTab, aCallback = function() { })
* @return object
* A promise that is resolved once the web console is closed.
*/
-function closeConsole(aTab, aCallback = function() { })
-{
- let target = TargetFactory.forTab(aTab || tab);
+let closeConsole = Task.async(function* (aTab) {
+ let target = TargetFactory.forTab(aTab || gBrowser.selectedTab);
let toolbox = gDevTools.getToolbox(target);
if (toolbox) {
- let panel = toolbox.getPanel("webconsole");
- if (panel) {
- let hudId = panel.hud.hudId;
- return toolbox.destroy().then(aCallback.bind(null, hudId)).then(null, console.debug);
- }
- return toolbox.destroy().then(aCallback.bind(null));
+ yield toolbox.destroy();
}
-
- aCallback();
- return promise.resolve(null);
-}
+});
/**
* Wait for a context menu popup to open.
@@ -252,6 +220,9 @@ function closeConsole(aTab, aCallback = function() { })
* Function to invoke on popupshown event.
* @param function aOnHidden
* Function to invoke on popuphidden event.
+ * @return object
+ * A Promise object that is resolved after the popuphidden event
+ * callback is invoked.
*/
function waitForContextMenu(aPopup, aButton, aOnShown, aOnHidden)
{
@@ -259,7 +230,7 @@ function waitForContextMenu(aPopup, aButton, aOnShown, aOnHidden)
info("onPopupShown");
aPopup.removeEventListener("popupshown", onPopupShown);
- aOnShown();
+ aOnShown && aOnShown();
// Use executeSoon() to get out of the popupshown event.
aPopup.addEventListener("popuphidden", onPopupHidden);
@@ -268,15 +239,20 @@ function waitForContextMenu(aPopup, aButton, aOnShown, aOnHidden)
function onPopupHidden() {
info("onPopupHidden");
aPopup.removeEventListener("popuphidden", onPopupHidden);
- aOnHidden();
+
+ aOnHidden && aOnHidden();
+
+ deferred.resolve(aPopup);
}
+ let deferred = promise.defer();
aPopup.addEventListener("popupshown", onPopupShown);
info("wait for the context menu to open");
let eventDetails = { type: "contextmenu", button: 2};
EventUtils.synthesizeMouse(aButton, 2, 2, eventDetails,
aButton.ownerDocument.defaultView);
+ return deferred.promise;
}
/**
@@ -326,10 +302,7 @@ function dumpMessageElement(aMessage)
"text", text);
}
-function finishTest()
-{
- browser = hudId = hud = filterBox = outputNode = cs = hudBox = null;
-
+let finishTest = Task.async(function* () {
dumpConsoles();
let browserConsole = HUDService.getBrowserConsole();
@@ -337,27 +310,19 @@ function finishTest()
if (browserConsole.jsterm) {
browserConsole.jsterm.clearOutput(true);
}
- HUDService.toggleBrowserConsole().then(finishTest);
- return;
+ yield HUDService.toggleBrowserConsole();
}
- let contentHud = HUDService.getHudByWindow(content);
- if (!contentHud) {
- finish();
- return;
- }
+ let target = TargetFactory.forTab(gBrowser.selectedTab);
+ yield gDevTools.closeToolbox(target);
- if (contentHud.jsterm) {
- contentHud.jsterm.clearOutput(true);
- }
-
- closeConsole(contentHud.target.tab, finish);
-
- contentHud = null;
-}
+ finish();
+});
function tearDown()
{
+ gDevTools.testing = false;
+
dumpConsoles();
if (HUDService.getBrowserConsole()) {
@@ -366,10 +331,10 @@ function tearDown()
let target = TargetFactory.forTab(gBrowser.selectedTab);
gDevTools.closeToolbox(target);
+
while (gBrowser.tabs.length > 1) {
gBrowser.removeCurrentTab();
}
- WCU_l10n = tab = browser = hudId = hud = filterBox = outputNode = cs = null;
}
registerCleanupFunction(tearDown);
@@ -381,55 +346,56 @@ waitForExplicitFinish();
*
* @param object aOptions
* Options object with the following properties:
- * - validatorFn
+ * - validator
* A validator function that returns a boolean. This is called every few
- * milliseconds to check if the result is true. When it is true, succesFn
- * is called and polling stops. If validatorFn never returns true, then
- * polling timeouts after several tries and a failure is recorded.
- * - successFn
- * A function called when the validator function returns true.
- * - failureFn
- * A function called if the validator function timeouts - fails to return
- * true in the given time.
+ * milliseconds to check if the result is true. When it is true, the
+ * promise is resolved and polling stops. If validator never returns
+ * true, then polling timeouts after several tries and the promise is
+ * rejected.
* - name
* Name of test. This is used to generate the success and failure
* messages.
* - timeout
* Timeout for validator function, in milliseconds. Default is 5000.
+ * @return object
+ * A Promise object that is resolved based on the validator function.
*/
function waitForSuccess(aOptions)
{
+ let deferred = promise.defer();
let start = Date.now();
let timeout = aOptions.timeout || 5000;
+ let {validator} = aOptions;
- function wait(validatorFn, successFn, failureFn)
+
+ function wait()
{
if ((Date.now() - start) > timeout) {
// Log the failure.
ok(false, "Timed out while waiting for: " + aOptions.name);
- failureFn(aOptions);
+ deferred.reject(null);
return;
}
- if (validatorFn(aOptions)) {
+ if (validator(aOptions)) {
ok(true, aOptions.name);
- successFn();
+ deferred.resolve(null);
}
else {
- setTimeout(function() wait(validatorFn, successFn, failureFn), 100);
+ setTimeout(wait, 100);
}
}
- wait(aOptions.validatorFn, aOptions.successFn, aOptions.failureFn);
+ setTimeout(wait, 100);
+
+ return deferred.promise;
}
-function openInspector(aCallback, aTab = gBrowser.selectedTab)
-{
+let openInspector = Task.async(function* (aTab = gBrowser.selectedTab) {
let target = TargetFactory.forTab(aTab);
- gDevTools.showToolbox(target, "inspector").then(function(toolbox) {
- aCallback(toolbox.getCurrentPanel());
- });
-}
+ let toolbox = yield gDevTools.showToolbox(target, "inspector");
+ return toolbox.getCurrentPanel();
+});
/**
* Find variables or properties in a VariablesView instance.
@@ -773,10 +739,10 @@ function variablesViewExpandTo(aOptions)
* - or "value" to change the property value.
* - string: the new string to write into the field.
* - webconsole: reference to the Web Console instance we work with.
- * - callback: function to invoke after the property is updated.
+ * @return object
+ * A Promise object that is resolved once the property is updated.
*/
-function updateVariablesViewProperty(aOptions)
-{
+let updateVariablesViewProperty = Task.async(function* (aOptions) {
let view = aOptions.property._variablesView;
view.window.focus();
aOptions.property.focus();
@@ -790,27 +756,34 @@ function updateVariablesViewProperty(aOptions)
break;
default:
throw new Error("options.field is incorrect");
- return;
}
+ let deferred = promise.defer();
+
executeSoon(() => {
EventUtils.synthesizeKey("A", { accelKey: true }, view.window);
for (let c of aOptions.string) {
- EventUtils.synthesizeKey(c, {}, gVariablesView.window);
+ EventUtils.synthesizeKey(c, {}, view.window);
}
if (aOptions.webconsole) {
- aOptions.webconsole.jsterm.once("variablesview-fetched", aOptions.callback);
+ aOptions.webconsole.jsterm.once("variablesview-fetched").then((varView) => {
+ deferred.resolve(varView);
+ });
}
EventUtils.synthesizeKey("VK_RETURN", {}, view.window);
if (!aOptions.webconsole) {
- executeSoon(aOptions.callback);
+ executeSoon(() => {
+ deferred.resolve(null);
+ });
}
});
-}
+
+ return deferred.promise;
+});
/**
* Open the JavaScript debugger.
diff --git a/browser/devtools/webconsole/test/test-console-assert.html b/browser/devtools/webconsole/test/test-console-assert.html
index 5358eb31f092..b104d72d4350 100644
--- a/browser/devtools/webconsole/test/test-console-assert.html
+++ b/browser/devtools/webconsole/test/test-console-assert.html
@@ -19,6 +19,5 @@
test console.assert()
-
diff --git a/browser/devtools/webconsole/test/test-console-output-events.html b/browser/devtools/webconsole/test/test-console-output-events.html
index 921c1002949e..908a86fabde1 100644
--- a/browser/devtools/webconsole/test/test-console-output-events.html
+++ b/browser/devtools/webconsole/test/test-console-output-events.html
@@ -10,6 +10,7 @@
hello world!
+
diff --git a/browser/devtools/webconsole/webconsole.js b/browser/devtools/webconsole/webconsole.js
index 55cfde3c55b6..e84c83406953 100644
--- a/browser/devtools/webconsole/webconsole.js
+++ b/browser/devtools/webconsole/webconsole.js
@@ -3318,9 +3318,20 @@ JSTerm.prototype = {
* user input is used - taken from |this.inputNode.value|.
* @param function [aCallback]
* Optional function to invoke when the result is displayed.
+ * This is deprecated - please use the promise return value instead.
+ * @returns Promise
+ * Resolves with the message once the result is displayed.
*/
execute: function JST_execute(aExecuteString, aCallback)
{
+ let deferred = promise.defer();
+ let callback = function(msg) {
+ deferred.resolve(msg);
+ if (aCallback) {
+ aCallback(msg);
+ }
+ }
+
// attempt to execute the content of the inputNode
aExecuteString = aExecuteString || this.inputNode.value;
if (!aExecuteString) {
@@ -3338,7 +3349,7 @@ JSTerm.prototype = {
severity: "log",
});
this.hud.output.addMessage(message);
- let onResult = this._executeResultCallback.bind(this, message, aCallback);
+ let onResult = this._executeResultCallback.bind(this, message, callback);
let options = {
frame: this.SELECTED_FRAME,
@@ -3355,6 +3366,7 @@ JSTerm.prototype = {
WebConsoleUtils.usageCount++;
this.setInputValue("");
this.clearCompletion();
+ return deferred.promise;
},
/**
@@ -3405,7 +3417,7 @@ JSTerm.prototype = {
selectedNodeActor: aOptions.selectedNodeActor,
};
- this.webConsoleClient.evaluateJS(aString, onResult, evalOptions);
+ this.webConsoleClient.evaluateJSAsync(aString, onResult, evalOptions);
return deferred.promise;
},
diff --git a/browser/devtools/webide/content/newapp.js b/browser/devtools/webide/content/newapp.js
index 83f5ea18a0f6..60151c0e8911 100644
--- a/browser/devtools/webide/content/newapp.js
+++ b/browser/devtools/webide/content/newapp.js
@@ -127,7 +127,7 @@ function doOK() {
}
// Create subfolder with fs-friendly name of project
- let subfolder = projectName.replace(/\W/g, '').toLowerCase();
+ let subfolder = projectName.replace(/[\\/:*?"<>|]/g, '').toLowerCase();
folder.append(subfolder);
try {
diff --git a/browser/themes/shared/devedition.inc.css b/browser/themes/shared/devedition.inc.css
index e6dcb824e61e..7e2fc7f02d64 100644
--- a/browser/themes/shared/devedition.inc.css
+++ b/browser/themes/shared/devedition.inc.css
@@ -127,20 +127,20 @@
/* Override @tabCurveHalfWidth@ and @tabCurveWidth@. XXX: Switch to a CSS variable once the perf is sorted out - bug 1088771 */
.tab-background-middle {
- border-left: 2px solid transparent;
- border-right: 2px solid transparent;
- margin: 0 -2px;
+ border-left-width: 0;
+ border-right-width: 0;
+ margin: 0;
}
.tab-background,
.tabs-newtab-button {
- -moz-margin-end: -2px;
- -moz-margin-start: -2px;
+ -moz-margin-end: 0;
+ -moz-margin-start: 0;
}
.tabbrowser-arrowscrollbox > .arrowscrollbox-scrollbox {
- -moz-padding-end: 2px;
- -moz-padding-start: 2px;
+ -moz-padding-end: 0;
+ -moz-padding-start: 0;
}
.tab-background-start[selected=true]::after,
@@ -149,12 +149,12 @@
.tab-background-end,
.tab-background-end[selected=true]::after,
.tab-background-end[selected=true]::before {
- width: 4px;
+ width: 0;
}
.tab-background-start[selected=true]::after,
.tab-background-end[selected=true]::after {
- -moz-margin-start: -4px;
+ -moz-margin-start: 0;
}
/* End override @tabCurveHalfWidth@ and @tabCurveWidth@ */
diff --git a/dom/apps/AppsService.js b/dom/apps/AppsService.js
index d5558fdb3691..63483a58be63 100644
--- a/dom/apps/AppsService.js
+++ b/dom/apps/AppsService.js
@@ -15,6 +15,11 @@ const Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Promise.jsm");
+try {
+ if (Services.prefs.getBoolPref("dom.apps.customization.enabled")) {
+ Cu.import("resource://gre/modules/UserCustomizations.jsm");
+ }
+} catch(e) {}
const APPS_SERVICE_CID = Components.ID("{05072afa-92fe-45bf-ae22-39b69c117058}");
diff --git a/dom/apps/AppsUtils.jsm b/dom/apps/AppsUtils.jsm
index da801e4b2d2f..1c11dea0d04c 100644
--- a/dom/apps/AppsUtils.jsm
+++ b/dom/apps/AppsUtils.jsm
@@ -479,9 +479,12 @@ this.AppsUtils = {
return true;
},
+ allowUnsignedAddons: false, // for testing purposes.
+
/**
- * Checks if the app role is allowed.
+ * Checks if the app role is allowed:
* Only certified apps can be themes.
+ * Only privileged or certified apps can be addons.
* @param aRole : the role assigned to this app.
* @param aStatus : the APP_STATUS_* for this app.
*/
@@ -489,6 +492,12 @@ this.AppsUtils = {
if (aRole == "theme" && aStatus !== Ci.nsIPrincipal.APP_STATUS_CERTIFIED) {
return false;
}
+ if (!this.allowUnsignedAddons &&
+ (aRole == "addon" &&
+ aStatus !== Ci.nsIPrincipal.APP_STATUS_CERTIFIED &&
+ aStatus !== Ci.nsIPrincipal.APP_STATUS_PRIVILEGED)) {
+ return false;
+ }
return true;
},
@@ -718,6 +727,11 @@ this.AppsUtils = {
// Convert the binary hash data to a hex string.
return [toHexString(hash.charCodeAt(i)) for (i in hash)].join("");
+ },
+
+ // Returns the hash for a JS object.
+ computeObjectHash: function(aObject) {
+ return this.computeHash(JSON.stringify(aObject));
}
}
diff --git a/dom/apps/UserCustomizations.jsm b/dom/apps/UserCustomizations.jsm
new file mode 100644
index 000000000000..96e37fe85df8
--- /dev/null
+++ b/dom/apps/UserCustomizations.jsm
@@ -0,0 +1,368 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const Cu = Components.utils;
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+this.EXPORTED_SYMBOLS = ["UserCustomizations"];
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/AppsUtils.jsm");
+
+XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
+ "@mozilla.org/parentprocessmessagemanager;1",
+ "nsIMessageBroadcaster");
+
+XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
+ "@mozilla.org/childprocessmessagemanager;1",
+ "nsIMessageSender");
+
+XPCOMUtils.defineLazyServiceGetter(this, "console",
+ "@mozilla.org/consoleservice;1",
+ "nsIConsoleService");
+/**
+ * Customization scripts and CSS stylesheets can be specified in an
+ * application manifest with the following syntax:
+ * "customizations": [
+ * {
+ * "filter": "http://youtube.com",
+ * "css": ["file1.css", "file2.css"],
+ * "scripts": ["script1.js", "script2.js"]
+ * }
+ * ]
+ */
+
+let debug = Services.prefs.getBoolPref("dom.mozApps.debug")
+ ? (aMsg) => {
+ dump("-*-*- UserCustomizations (" +
+ (UserCustomizations._inParent ? "parent" : "child") +
+ "): " + aMsg + "\n");
+ }
+ : (aMsg) => {};
+
+function log(aStr) {
+ console.logStringMessage(aStr);
+}
+
+this.UserCustomizations = {
+ _items: [],
+ _loaded : {}, // Keep track per manifestURL of css and scripts loaded.
+ _windows: null, // Set of currently opened windows.
+ _enabled: false,
+
+ _addItem: function(aItem) {
+ debug("_addItem: " + uneval(aItem));
+ this._items.push(aItem);
+ if (this._inParent) {
+ ppmm.broadcastAsyncMessage("UserCustomizations:Add", [aItem]);
+ }
+ },
+
+ _removeItem: function(aHash) {
+ debug("_removeItem: " + aHash);
+ let index = -1;
+ this._items.forEach((script, pos) => {
+ if (script.hash == aHash ) {
+ index = pos;
+ }
+ });
+
+ if (index != -1) {
+ this._items.splice(index, 1);
+ }
+
+ if (this._inParent) {
+ ppmm.broadcastAsyncMessage("UserCustomizations:Remove", aHash);
+ }
+ },
+
+ register: function(aManifest, aApp) {
+ debug("Starting customization registration for " + aApp.manifestURL);
+
+ if (!this._enabled || !aApp.enabled || aApp.role != "addon") {
+ debug("Rejecting registration (global enabled=" + this._enabled +
+ ") (app role=" + aApp.role +
+ ", enabled=" + aApp.enabled + ")");
+ debug(uneval(aApp));
+ return;
+ }
+
+ let customizations = aManifest.customizations;
+ if (customizations === undefined || !Array.isArray(customizations)) {
+ return;
+ }
+
+ let base = Services.io.newURI(aApp.origin, null, null);
+
+ customizations.forEach(item => {
+ // The filter property is mandatory.
+ if (!item.filter || (typeof item.filter !== "string")) {
+ log("Mandatory filter property not found in this customization item: " +
+ uneval(item) + " in " + aApp.manifestURL);
+ return;
+ }
+
+ // Create a new object with resolved urls and a hash that we reuse to
+ // remove items.
+ let custom = {
+ filter: item.filter,
+ status: aApp.appStatus,
+ manifestURL: aApp.manifestURL,
+ css: [],
+ scripts: []
+ };
+ custom.hash = AppsUtils.computeObjectHash(item);
+
+ if (item.css && Array.isArray(item.css)) {
+ item.css.forEach((css) => {
+ custom.css.push(base.resolve(css));
+ });
+ }
+
+ if (item.scripts && Array.isArray(item.scripts)) {
+ item.scripts.forEach((script) => {
+ custom.scripts.push(base.resolve(script));
+ });
+ }
+
+ this._addItem(custom);
+ });
+ this._updateAllWindows();
+ },
+
+ _updateAllWindows: function() {
+ debug("UpdateWindows");
+ if (this._inParent) {
+ ppmm.broadcastAsyncMessage("UserCustomizations:UpdateWindows", {});
+ }
+ // Inject in all currently opened windows.
+ this._windows.forEach(this._injectInWindow.bind(this));
+ },
+
+ unregister: function(aManifest, aApp) {
+ if (!this._enabled) {
+ return;
+ }
+
+ debug("Starting customization unregistration for " + aApp.manifestURL);
+ let customizations = aManifest.customizations;
+ if (customizations === undefined || !Array.isArray(customizations)) {
+ return;
+ }
+
+ customizations.forEach(item => {
+ this._removeItem(AppsUtils.computeObjectHash(item));
+ });
+ this._unloadForManifestURL(aApp.manifestURL);
+ },
+
+ _unloadForManifestURL: function(aManifestURL) {
+ debug("_unloadForManifestURL " + aManifestURL);
+
+ if (this._inParent) {
+ ppmm.broadcastAsyncMessage("UserCustomizations:Unload", aManifestURL);
+ }
+
+ if (!this._loaded[aManifestURL]) {
+ return;
+ }
+
+ if (this._loaded[aManifestURL].scripts &&
+ this._loaded[aManifestURL].scripts.length > 0) {
+ // We can't rollback script changes, so don't even try to unload in this
+ // situation.
+ return;
+ }
+
+ this._loaded[aManifestURL].css.forEach(aItem => {
+ try {
+ debug("unloading " + aItem.uri.spec);
+ let utils = aItem.window.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindowUtils);
+ utils.removeSheet(aItem.uri, Ci.nsIDOMWindowUtils.AUTHOR_SHEET);
+ } catch(e) {
+ log("Error unloading stylesheet " + aItem.uri.spec + " : " + e);
+ }
+ });
+
+ this._loaded[aManifestURL] = null;
+ },
+
+ _injectItem: function(aWindow, aItem, aInjected) {
+ debug("Injecting item " + uneval(aItem) + " in " + aWindow.location.href);
+ let utils = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindowUtils);
+
+ let manifestURL = aItem.manifestURL;
+
+ // Load the stylesheets only in this window.
+ aItem.css.forEach(aCss => {
+ if (aInjected.indexOf(aCss) !== -1) {
+ debug("Skipping duplicated css: " + aCss);
+ return;
+ }
+
+ let uri = Services.io.newURI(aCss, null, null);
+ try {
+ utils.loadSheet(uri, Ci.nsIDOMWindowUtils.AUTHOR_SHEET);
+ if (!this._loaded[manifestURL]) {
+ this._loaded[manifestURL] = { css: [], scripts: [] };
+ }
+ this._loaded[manifestURL].css.push({ window: aWindow, uri: uri });
+ aInjected.push(aCss);
+ } catch(e) {
+ log("Error loading stylesheet " + aCss + " : " + e);
+ }
+ });
+
+ let sandbox;
+ if (aItem.scripts.length > 0) {
+ sandbox = Cu.Sandbox([aWindow],
+ { wantComponents: false,
+ sandboxPrototype: aWindow });
+ }
+
+ // Load the scripts using a sandbox.
+ aItem.scripts.forEach(aScript => {
+ debug("Sandboxing " + aScript);
+ if (aInjected.indexOf(aScript) !== -1) {
+ debug("Skipping duplicated script: " + aScript);
+ return;
+ }
+
+ try {
+ Services.scriptloader.loadSubScript(aScript, sandbox, "UTF-8");
+ if (!this._loaded[manifestURL]) {
+ this._loaded[manifestURL] = { css: [], scripts: [] };
+ }
+ this._loaded[manifestURL].scripts.push({ sandbox: sandbox, uri: aScript });
+ aInjected.push(aScript);
+ } catch(e) {
+ log("Error sandboxing " + aScript + " : " + e);
+ }
+ });
+
+ // Makes sure we get rid of the sandbox.
+ if (sandbox) {
+ aWindow.addEventListener("unload", () => {
+ Cu.nukeSandbox(sandbox);
+ sandbox = null;
+ });
+ }
+ },
+
+ _injectInWindow: function(aWindow) {
+ debug("_injectInWindow");
+
+ if (!aWindow || !aWindow.document) {
+ return;
+ }
+
+ let principal = aWindow.document.nodePrincipal;
+ debug("principal status: " + principal.appStatus);
+
+ let href = aWindow.location.href;
+
+ // The list of resources loaded in this window, used to filter out
+ // duplicates.
+ let injected = [];
+
+ this._items.forEach((aItem) => {
+ // We only allow customizations to apply to apps with an equal or lower
+ // privilege level.
+ if (principal.appStatus > aItem.status) {
+ return;
+ }
+
+ let regexp = new RegExp(aItem.filter, "g");
+ if (regexp.test(href)) {
+ this._injectItem(aWindow, aItem, injected);
+ debug("Currently injected: " + injected.toString());
+ }
+ });
+ },
+
+ observe: function(aSubject, aTopic, aData) {
+ if (aTopic === "content-document-global-created") {
+ let window = aSubject.QueryInterface(Ci.nsIDOMWindow);
+ let href = window.location.href;
+ if (!href || href == "about:blank") {
+ return;
+ }
+
+ let id = window.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindowUtils)
+ .currentInnerWindowID;
+ this._windows.set(id, window);
+
+ debug("document created: " + href);
+ this._injectInWindow(window);
+ } else if (aTopic === "inner-window-destroyed") {
+ let winId = aSubject.QueryInterface(Ci.nsISupportsPRUint64).data;
+ this._windows.delete(winId);
+ }
+ },
+
+ init: function() {
+ this._enabled = false;
+ try {
+ this._enabled = Services.prefs.getBoolPref("dom.apps.customization.enabled");
+ } catch(e) {}
+
+ if (!this._enabled) {
+ return;
+ }
+
+ this._windows = new Map(); // Can't be a WeakMap because we need to enumerate.
+ this._inParent = Cc["@mozilla.org/xre/runtime;1"]
+ .getService(Ci.nsIXULRuntime)
+ .processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
+
+ debug("init");
+
+ Services.obs.addObserver(this, "content-document-global-created",
+ /* ownsWeak */ false);
+ Services.obs.addObserver(this, "inner-window-destroyed",
+ /* ownsWeak */ false);
+
+ if (this._inParent) {
+ ppmm.addMessageListener("UserCustomizations:List", this);
+ } else {
+ cpmm.addMessageListener("UserCustomizations:Add", this);
+ cpmm.addMessageListener("UserCustomizations:Remove", this);
+ cpmm.addMessageListener("UserCustomizations:Unload", this);
+ cpmm.addMessageListener("UserCustomizations:UpdateWindows", this);
+ cpmm.sendAsyncMessage("UserCustomizations:List", {});
+ }
+ },
+
+ receiveMessage: function(aMessage) {
+ let name = aMessage.name;
+ let data = aMessage.data;
+
+ switch(name) {
+ case "UserCustomizations:List":
+ aMessage.target.sendAsyncMessage("UserCustomizations:Add", this._items);
+ break;
+ case "UserCustomizations:Add":
+ data.forEach(this._addItem, this);
+ break;
+ case "UserCustomizations:Remove":
+ this._removeItem(data);
+ break;
+ case "UserCustomizations:Unload":
+ this._unloadForManifestURL(data);
+ break;
+ case "UserCustomizations:UpdateWindows":
+ this._updateAllWindows();
+ break;
+ }
+ }
+}
+
+UserCustomizations.init();
diff --git a/dom/apps/Webapps.jsm b/dom/apps/Webapps.jsm
index 0623ce4de056..40d49008895c 100755
--- a/dom/apps/Webapps.jsm
+++ b/dom/apps/Webapps.jsm
@@ -43,6 +43,23 @@ Cu.import("resource://gre/modules/osfile.jsm");
Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://gre/modules/Promise.jsm");
+XPCOMUtils.defineLazyGetter(this, "UserCustomizations", function() {
+ let enabled = false;
+ try {
+ enabled = Services.prefs.getBoolPref("dom.apps.customization.enabled");
+ } catch(e) {}
+
+ if (enabled) {
+ return Cu.import("resource://gre/modules/UserCustomizations.jsm", {})
+ .UserCustomizations;
+ } else {
+ return {
+ register: function() {},
+ unregister: function() {}
+ };
+ }
+});
+
XPCOMUtils.defineLazyModuleGetter(this, "TrustedRootCertificate",
"resource://gre/modules/StoreTrustAnchor.jsm");
@@ -406,6 +423,7 @@ this.DOMApplicationRegistry = {
app.redirects = this.sanitizeRedirects(aResult.redirects);
}
app.kind = this.appKind(app, aResult.manifest);
+ UserCustomizations.register(aResult.manifest, app);
});
// Nothing else to do but notifying we're ready.
@@ -1097,6 +1115,7 @@ this.DOMApplicationRegistry = {
this._registerSystemMessages(manifest, app);
this._registerInterAppConnections(manifest, app);
appsToRegister.push({ manifest: manifest, app: app });
+ UserCustomizations.register(manifest, app);
});
this._safeToClone.resolve();
this._registerActivitiesForApps(appsToRegister, aRunUpdate);
@@ -1991,7 +2010,8 @@ this.DOMApplicationRegistry = {
// Updates the redirect mapping, activities and system message handlers.
// aOldManifest can be null if we don't have any handler to unregister.
updateAppHandlers: function(aOldManifest, aNewManifest, aApp) {
- debug("updateAppHandlers: old=" + aOldManifest + " new=" + aNewManifest);
+ debug("updateAppHandlers: old=" + uneval(aOldManifest) +
+ " new=" + uneval(aNewManifest));
this.notifyAppsRegistryStart();
if (aApp.appStatus >= Ci.nsIPrincipal.APP_STATUS_PRIVILEGED) {
aApp.redirects = this.sanitizeRedirects(aNewManifest.redirects);
@@ -2001,6 +2021,8 @@ this.DOMApplicationRegistry = {
new ManifestHelper(aNewManifest, aApp.origin, aApp.manifestURL);
this._saveWidgetsFullPath(manifest, aApp);
+ aApp.role = manifest.role ? manifest.role : "";
+
if (supportSystemMessages()) {
if (aOldManifest) {
this._unregisterActivities(aOldManifest, aApp);
@@ -2012,6 +2034,12 @@ this.DOMApplicationRegistry = {
// Nothing else to do but notifying we're ready.
this.notifyAppsRegistryReady();
}
+
+ // Update user customizations.
+ if (aOldManifest) {
+ UserCustomizations.unregister(aOldManifest, aApp);
+ }
+ UserCustomizations.register(aNewManifest, aApp);
},
checkForUpdate: function(aData, aMm) {
@@ -4019,6 +4047,7 @@ this.DOMApplicationRegistry = {
if (supportSystemMessages()) {
this._unregisterActivities(aApp.manifest, aApp);
}
+ UserCustomizations.unregister(aApp.manifest, aApp);
let dir = this._getAppDir(id);
try {
@@ -4388,6 +4417,12 @@ this.DOMApplicationRegistry = {
});
this.broadcastMessage("Webapps:SetEnabled:Return", app);
});
+
+ // Update customization.
+ this.getManifestFor(app.manifestURL).then((aManifest) => {
+ app.enabled ? UserCustomizations.register(aManifest, app)
+ : UserCustomizations.unregister(aManifest, app);
+ });
},
getManifestFor: function(aManifestURL) {
diff --git a/dom/apps/moz.build b/dom/apps/moz.build
index f4b68c4cbd64..925e7b5a7304 100644
--- a/dom/apps/moz.build
+++ b/dom/apps/moz.build
@@ -38,6 +38,7 @@ EXTRA_JS_MODULES += [
'PermissionsInstaller.jsm',
'PermissionsTable.jsm',
'StoreTrustAnchor.jsm',
+ 'UserCustomizations.jsm',
]
EXTRA_PP_JS_MODULES += [
diff --git a/dom/apps/tests/addons/application.zip b/dom/apps/tests/addons/application.zip
new file mode 100644
index 000000000000..543587c8869b
Binary files /dev/null and b/dom/apps/tests/addons/application.zip differ
diff --git a/dom/apps/tests/addons/index.html b/dom/apps/tests/addons/index.html
new file mode 100644
index 000000000000..b8f4c54eb3a7
--- /dev/null
+++ b/dom/apps/tests/addons/index.html
@@ -0,0 +1,22 @@
+
+
+
+ This page will be modified by the add-on
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/dom/apps/tests/addons/manifest.webapp b/dom/apps/tests/addons/manifest.webapp
new file mode 100644
index 000000000000..3d9e095e3aae
--- /dev/null
+++ b/dom/apps/tests/addons/manifest.webapp
@@ -0,0 +1,12 @@
+{
+ "name": "Addon app",
+ "description": "Let me inject script and css!",
+ "customizations" : [
+ {
+ "filter": "http://mochi.test:8888/tests/dom/apps/tests/addons",
+ "css": ["style.css", "style2.css", "invalid.css", "style.css"],
+ "scripts": ["script.js", "script2.js", "invalid.js", "script.js"]
+ }
+ ],
+ "role": "addon"
+}
diff --git a/dom/apps/tests/addons/script.js b/dom/apps/tests/addons/script.js
new file mode 100644
index 000000000000..aac734710fb3
--- /dev/null
+++ b/dom/apps/tests/addons/script.js
@@ -0,0 +1,4 @@
+document.addEventListener("DOMContentLoaded", function() {
+ var head = document.getElementById("header");
+ head.innerHTML = "Hello World!";
+}, false);
\ No newline at end of file
diff --git a/dom/apps/tests/addons/style.css b/dom/apps/tests/addons/style.css
new file mode 100644
index 000000000000..4e395e6f31cb
--- /dev/null
+++ b/dom/apps/tests/addons/style.css
@@ -0,0 +1,3 @@
+#header {
+ color: red;
+}
\ No newline at end of file
diff --git a/dom/apps/tests/addons/update.webapp b/dom/apps/tests/addons/update.webapp
new file mode 100644
index 000000000000..e7df00358291
--- /dev/null
+++ b/dom/apps/tests/addons/update.webapp
@@ -0,0 +1,5 @@
+{
+ "name": "Addon app",
+ "description": "Let me inject script and css!",
+ "package_path" : "application.zip"
+}
diff --git a/dom/apps/tests/addons/update.webapp^headers^ b/dom/apps/tests/addons/update.webapp^headers^
new file mode 100644
index 000000000000..3cea33fec8b6
--- /dev/null
+++ b/dom/apps/tests/addons/update.webapp^headers^
@@ -0,0 +1 @@
+Content-Type: application/manifest+json
\ No newline at end of file
diff --git a/dom/apps/tests/mochitest.ini b/dom/apps/tests/mochitest.ini
index 1c90136f1096..798a32bd9617 100644
--- a/dom/apps/tests/mochitest.ini
+++ b/dom/apps/tests/mochitest.ini
@@ -1,6 +1,10 @@
[DEFAULT]
skip-if = e10s
support-files =
+ addons/application.zip
+ addons/update.webapp
+ addons/update.webapp^headers^
+ addons/index.html
chromeAddCert.js
file_app.sjs
file_app.template.html
@@ -25,6 +29,8 @@ support-files =
marketplace/*
pkg_install_iframe.html
+[test_app_addons.html]
+skip-if = os == "android" || toolkit == "gonk" # embed-apps doesn't work in mochitest app
[test_app_enabled.html]
[test_app_update.html]
skip-if = os == "android" || toolkit == "gonk" # embed-apps doesn't work in mochitest app
diff --git a/dom/apps/tests/test_app_addons.html b/dom/apps/tests/test_app_addons.html
new file mode 100644
index 000000000000..689d49d7cecb
--- /dev/null
+++ b/dom/apps/tests/test_app_addons.html
@@ -0,0 +1,186 @@
+
+
+
+
+ Test for Bug 923897 - Test apps as addons
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dom/base/Console.cpp b/dom/base/Console.cpp
index 5123d69140d0..5ef2259bf8b3 100644
--- a/dom/base/Console.cpp
+++ b/dom/base/Console.cpp
@@ -131,7 +131,7 @@ ConsoleStructuredCloneCallbacksError(JSContext* /* aCx */,
NS_WARNING("Failed to clone data for the Console API in workers.");
}
-JSStructuredCloneCallbacks gConsoleCallbacks = {
+static const JSStructuredCloneCallbacks gConsoleCallbacks = {
ConsoleStructuredCloneCallbacksRead,
ConsoleStructuredCloneCallbacksWrite,
ConsoleStructuredCloneCallbacksError
diff --git a/dom/base/MessagePort.cpp b/dom/base/MessagePort.cpp
index ebccfb50907d..e0bc4ab991dd 100644
--- a/dom/base/MessagePort.cpp
+++ b/dom/base/MessagePort.cpp
@@ -287,7 +287,7 @@ PostMessageFreeTransferStructuredClone(uint32_t aTag, JS::TransferableOwnership
}
}
-JSStructuredCloneCallbacks kPostMessageCallbacks = {
+const JSStructuredCloneCallbacks kPostMessageCallbacks = {
PostMessageReadStructuredClone,
PostMessageWriteStructuredClone,
nullptr,
diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp
index f1a729c6702b..897315d22067 100644
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -8054,7 +8054,7 @@ PostMessageFreeTransferStructuredClone(uint32_t aTag, JS::TransferableOwnership
}
}
-JSStructuredCloneCallbacks kPostMessageCallbacks = {
+const JSStructuredCloneCallbacks kPostMessageCallbacks = {
PostMessageReadStructuredClone,
PostMessageWriteStructuredClone,
nullptr,
diff --git a/dom/base/nsJSEnvironment.cpp b/dom/base/nsJSEnvironment.cpp
index e427654b22c6..fdd5a37ba253 100644
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -2748,7 +2748,7 @@ nsJSContext::EnsureStatics()
sPrevGCSliceCallback = JS::SetGCSliceCallback(sRuntime, DOMGCSliceCallback);
// Set up the structured clone callbacks.
- static JSStructuredCloneCallbacks cloneCallbacks = {
+ static const JSStructuredCloneCallbacks cloneCallbacks = {
NS_DOMReadStructuredClone,
NS_DOMWriteStructuredClone,
NS_DOMStructuredCloneError,
@@ -2759,7 +2759,7 @@ nsJSContext::EnsureStatics()
JS_SetStructuredCloneCallbacks(sRuntime, &cloneCallbacks);
// Set up the asm.js cache callbacks
- static JS::AsmJSCacheOps asmJSCacheOps = {
+ static const JS::AsmJSCacheOps asmJSCacheOps = {
AsmJSCacheOpenEntryForRead,
asmjscache::CloseEntryForRead,
AsmJSCacheOpenEntryForWrite,
diff --git a/dom/indexedDB/IDBObjectStore.cpp b/dom/indexedDB/IDBObjectStore.cpp
index f8e35c101009..f9c36c4873a8 100644
--- a/dom/indexedDB/IDBObjectStore.cpp
+++ b/dom/indexedDB/IDBObjectStore.cpp
@@ -1001,7 +1001,7 @@ IDBObjectStore::DeserializeValue(JSContext* aCx,
JSAutoRequest ar(aCx);
- static JSStructuredCloneCallbacks callbacks = {
+ static const JSStructuredCloneCallbacks callbacks = {
CommonStructuredCloneReadCallback,
nullptr,
nullptr,
@@ -1042,7 +1042,7 @@ IDBObjectStore::DeserializeIndexValue(JSContext* aCx,
JSAutoRequest ar(aCx);
- static JSStructuredCloneCallbacks callbacks = {
+ static const JSStructuredCloneCallbacks callbacks = {
CommonStructuredCloneReadCallback,
nullptr,
nullptr
diff --git a/dom/ipc/StructuredCloneUtils.cpp b/dom/ipc/StructuredCloneUtils.cpp
index 8f3b10492cc6..349e3ea95c2f 100644
--- a/dom/ipc/StructuredCloneUtils.cpp
+++ b/dom/ipc/StructuredCloneUtils.cpp
@@ -101,7 +101,7 @@ Write(JSContext* aCx, JSStructuredCloneWriter* aWriter,
return NS_DOMWriteStructuredClone(aCx, aWriter, aObj, nullptr);
}
-JSStructuredCloneCallbacks gCallbacks = {
+const JSStructuredCloneCallbacks gCallbacks = {
Read,
Write,
Error,
diff --git a/dom/ipc/preload.js b/dom/ipc/preload.js
index 891635e56e46..194b212cee33 100644
--- a/dom/ipc/preload.js
+++ b/dom/ipc/preload.js
@@ -27,6 +27,11 @@ const BrowserElementIsPreloaded = true;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/SettingsDB.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+ try {
+ if (Services.prefs.getBoolPref("dom.apps.customization.enabled")) {
+ Cu.import("resource://gre/modules/UserCustomizations.jsm");
+ }
+ } catch(e) {}
Cc["@mozilla.org/appshell/appShellService;1"].getService(Ci["nsIAppShellService"]);
Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci["nsIWindowMediator"]);
diff --git a/dom/promise/Promise.cpp b/dom/promise/Promise.cpp
index eb9f05f2c47c..6c50e03278aa 100644
--- a/dom/promise/Promise.cpp
+++ b/dom/promise/Promise.cpp
@@ -1246,7 +1246,7 @@ class PromiseWorkerProxyRunnable : public workers::WorkerRunnable
{
public:
PromiseWorkerProxyRunnable(PromiseWorkerProxy* aPromiseWorkerProxy,
- JSStructuredCloneCallbacks* aCallbacks,
+ const JSStructuredCloneCallbacks* aCallbacks,
JSAutoStructuredCloneBuffer&& aBuffer,
PromiseWorkerProxy::RunCallbackFunc aFunc)
: WorkerRunnable(aPromiseWorkerProxy->GetWorkerPrivate(),
@@ -1292,7 +1292,7 @@ protected:
private:
nsRefPtr mPromiseWorkerProxy;
- JSStructuredCloneCallbacks* mCallbacks;
+ const JSStructuredCloneCallbacks* mCallbacks;
JSAutoStructuredCloneBuffer mBuffer;
// Function pointer for calling Promise::{ResolveInternal,RejectInternal}.
@@ -1301,7 +1301,7 @@ private:
PromiseWorkerProxy::PromiseWorkerProxy(WorkerPrivate* aWorkerPrivate,
Promise* aWorkerPromise,
- JSStructuredCloneCallbacks* aCallbacks)
+ const JSStructuredCloneCallbacks* aCallbacks)
: mWorkerPrivate(aWorkerPrivate)
, mWorkerPromise(aWorkerPromise)
, mCleanedUp(false)
diff --git a/dom/promise/PromiseWorkerProxy.h b/dom/promise/PromiseWorkerProxy.h
index 3b83e2fbf0ac..09249e9eba12 100644
--- a/dom/promise/PromiseWorkerProxy.h
+++ b/dom/promise/PromiseWorkerProxy.h
@@ -67,7 +67,7 @@ class PromiseWorkerProxy : public PromiseNativeHandler,
public:
PromiseWorkerProxy(workers::WorkerPrivate* aWorkerPrivate,
Promise* aWorkerPromise,
- JSStructuredCloneCallbacks* aCallbacks = nullptr);
+ const JSStructuredCloneCallbacks* aCallbacks = nullptr);
workers::WorkerPrivate* GetWorkerPrivate() const;
@@ -104,7 +104,7 @@ private:
bool mCleanedUp; // To specify if the cleanUp() has been done.
- JSStructuredCloneCallbacks* mCallbacks;
+ const JSStructuredCloneCallbacks* mCallbacks;
// Aimed to keep objects alive when doing the structured-clone read/write,
// which can be added by calling StoreISupports() on the main thread.
diff --git a/dom/system/gonk/NetworkUtils.cpp b/dom/system/gonk/NetworkUtils.cpp
index 2ac7cb3df6e2..20e2e1c3fc66 100644
--- a/dom/system/gonk/NetworkUtils.cpp
+++ b/dom/system/gonk/NetworkUtils.cpp
@@ -123,7 +123,7 @@ static nsTArray gReason;
static NetworkParams *gWifiTetheringParms = 0;
-CommandFunc NetworkUtils::sWifiEnableChain[] = {
+const CommandFunc NetworkUtils::sWifiEnableChain[] = {
NetworkUtils::clearWifiTetherParms,
NetworkUtils::wifiFirmwareReload,
NetworkUtils::startAccessPointDriver,
@@ -139,7 +139,7 @@ CommandFunc NetworkUtils::sWifiEnableChain[] = {
NetworkUtils::wifiTetheringSuccess
};
-CommandFunc NetworkUtils::sWifiDisableChain[] = {
+const CommandFunc NetworkUtils::sWifiDisableChain[] = {
NetworkUtils::clearWifiTetherParms,
NetworkUtils::stopSoftAP,
NetworkUtils::stopAccessPointDriver,
@@ -153,14 +153,14 @@ CommandFunc NetworkUtils::sWifiDisableChain[] = {
NetworkUtils::wifiTetheringSuccess
};
-CommandFunc NetworkUtils::sWifiFailChain[] = {
+const CommandFunc NetworkUtils::sWifiFailChain[] = {
NetworkUtils::clearWifiTetherParms,
NetworkUtils::stopSoftAP,
NetworkUtils::setIpForwardingEnabled,
NetworkUtils::stopTethering
};
-CommandFunc NetworkUtils::sWifiRetryChain[] = {
+const CommandFunc NetworkUtils::sWifiRetryChain[] = {
NetworkUtils::clearWifiTetherParms,
NetworkUtils::stopSoftAP,
NetworkUtils::stopTethering,
@@ -180,12 +180,12 @@ CommandFunc NetworkUtils::sWifiRetryChain[] = {
NetworkUtils::wifiTetheringSuccess
};
-CommandFunc NetworkUtils::sWifiOperationModeChain[] = {
+const CommandFunc NetworkUtils::sWifiOperationModeChain[] = {
NetworkUtils::wifiFirmwareReload,
NetworkUtils::wifiOperationModeSuccess
};
-CommandFunc NetworkUtils::sUSBEnableChain[] = {
+const CommandFunc NetworkUtils::sUSBEnableChain[] = {
NetworkUtils::setInterfaceUp,
NetworkUtils::enableNat,
NetworkUtils::setIpForwardingEnabled,
@@ -196,7 +196,7 @@ CommandFunc NetworkUtils::sUSBEnableChain[] = {
NetworkUtils::usbTetheringSuccess
};
-CommandFunc NetworkUtils::sUSBDisableChain[] = {
+const CommandFunc NetworkUtils::sUSBDisableChain[] = {
NetworkUtils::untetherInterface,
NetworkUtils::preTetherInterfaceList,
NetworkUtils::postTetherInterfaceList,
@@ -206,48 +206,48 @@ CommandFunc NetworkUtils::sUSBDisableChain[] = {
NetworkUtils::usbTetheringSuccess
};
-CommandFunc NetworkUtils::sUSBFailChain[] = {
+const CommandFunc NetworkUtils::sUSBFailChain[] = {
NetworkUtils::stopSoftAP,
NetworkUtils::setIpForwardingEnabled,
NetworkUtils::stopTethering
};
-CommandFunc NetworkUtils::sUpdateUpStreamChain[] = {
+const CommandFunc NetworkUtils::sUpdateUpStreamChain[] = {
NetworkUtils::cleanUpStream,
NetworkUtils::createUpStream,
NetworkUtils::updateUpStreamSuccess
};
-CommandFunc NetworkUtils::sStartDhcpServerChain[] = {
+const CommandFunc NetworkUtils::sStartDhcpServerChain[] = {
NetworkUtils::setInterfaceUp,
NetworkUtils::startTethering,
NetworkUtils::setDhcpServerSuccess
};
-CommandFunc NetworkUtils::sStopDhcpServerChain[] = {
+const CommandFunc NetworkUtils::sStopDhcpServerChain[] = {
NetworkUtils::stopTethering,
NetworkUtils::setDhcpServerSuccess
};
-CommandFunc NetworkUtils::sNetworkInterfaceEnableAlarmChain[] = {
+const CommandFunc NetworkUtils::sNetworkInterfaceEnableAlarmChain[] = {
NetworkUtils::enableAlarm,
NetworkUtils::setQuota,
NetworkUtils::setAlarm,
NetworkUtils::networkInterfaceAlarmSuccess
};
-CommandFunc NetworkUtils::sNetworkInterfaceDisableAlarmChain[] = {
+const CommandFunc NetworkUtils::sNetworkInterfaceDisableAlarmChain[] = {
NetworkUtils::removeQuota,
NetworkUtils::disableAlarm,
NetworkUtils::networkInterfaceAlarmSuccess
};
-CommandFunc NetworkUtils::sNetworkInterfaceSetAlarmChain[] = {
+const CommandFunc NetworkUtils::sNetworkInterfaceSetAlarmChain[] = {
NetworkUtils::setAlarm,
NetworkUtils::networkInterfaceAlarmSuccess
};
-CommandFunc NetworkUtils::sSetDnsChain[] = {
+const CommandFunc NetworkUtils::sSetDnsChain[] = {
NetworkUtils::setDefaultInterface,
NetworkUtils::setInterfaceDns
};
diff --git a/dom/system/gonk/NetworkUtils.h b/dom/system/gonk/NetworkUtils.h
index f352c9343ba8..fcf9763b1c0b 100644
--- a/dom/system/gonk/NetworkUtils.h
+++ b/dom/system/gonk/NetworkUtils.h
@@ -164,7 +164,7 @@ class CommandChain MOZ_FINAL
{
public:
CommandChain(const NetworkParams& aParams,
- CommandFunc aCmds[],
+ const CommandFunc aCmds[],
uint32_t aLength,
ErrorCallback aError)
: mIndex(-1)
@@ -196,7 +196,7 @@ public:
private:
uint32_t mIndex;
NetworkParams mParams;
- CommandFunc* mCommands;
+ const CommandFunc* mCommands;
uint32_t mLength;
ErrorCallback mError;
};
@@ -263,21 +263,21 @@ private:
* function pointer array holds all netd commands should be executed
* in sequence to accomplish a given command by other module.
*/
- static CommandFunc sWifiEnableChain[];
- static CommandFunc sWifiDisableChain[];
- static CommandFunc sWifiFailChain[];
- static CommandFunc sWifiRetryChain[];
- static CommandFunc sWifiOperationModeChain[];
- static CommandFunc sUSBEnableChain[];
- static CommandFunc sUSBDisableChain[];
- static CommandFunc sUSBFailChain[];
- static CommandFunc sUpdateUpStreamChain[];
- static CommandFunc sStartDhcpServerChain[];
- static CommandFunc sStopDhcpServerChain[];
- static CommandFunc sNetworkInterfaceEnableAlarmChain[];
- static CommandFunc sNetworkInterfaceDisableAlarmChain[];
- static CommandFunc sNetworkInterfaceSetAlarmChain[];
- static CommandFunc sSetDnsChain[];
+ static const CommandFunc sWifiEnableChain[];
+ static const CommandFunc sWifiDisableChain[];
+ static const CommandFunc sWifiFailChain[];
+ static const CommandFunc sWifiRetryChain[];
+ static const CommandFunc sWifiOperationModeChain[];
+ static const CommandFunc sUSBEnableChain[];
+ static const CommandFunc sUSBDisableChain[];
+ static const CommandFunc sUSBFailChain[];
+ static const CommandFunc sUpdateUpStreamChain[];
+ static const CommandFunc sStartDhcpServerChain[];
+ static const CommandFunc sStopDhcpServerChain[];
+ static const CommandFunc sNetworkInterfaceEnableAlarmChain[];
+ static const CommandFunc sNetworkInterfaceDisableAlarmChain[];
+ static const CommandFunc sNetworkInterfaceSetAlarmChain[];
+ static const CommandFunc sSetDnsChain[];
/**
* Individual netd command stored in command chain.
diff --git a/dom/system/gonk/RadioInterfaceLayer.js b/dom/system/gonk/RadioInterfaceLayer.js
index 4371f869abab..c256f8983cb7 100644
--- a/dom/system/gonk/RadioInterfaceLayer.js
+++ b/dom/system/gonk/RadioInterfaceLayer.js
@@ -494,19 +494,13 @@ XPCOMUtils.defineLazyGetter(this, "gRadioEnabledController", function() {
_getNumCards: function() {
let numCards = 0;
for (let i = 0, N = _ril.numRadioInterfaces; i < N; ++i) {
- if (this._isCardPresentAtClient(i)) {
+ if (_ril.getRadioInterface(i).isCardPresent()) {
numCards++;
}
}
return numCards;
},
- _isCardPresentAtClient: function(clientId) {
- let cardState = _ril.getRadioInterface(clientId).rilContext.cardState;
- return cardState !== Ci.nsIIccProvider.CARD_STATE_UNDETECTED &&
- cardState !== Ci.nsIIccProvider.CARD_STATE_UNKNOWN;
- },
-
_isRadioAbleToEnableAtClient: function(clientId, numCards) {
if (!RILQUIRKS_RADIO_OFF_WO_CARD) {
return true;
@@ -516,7 +510,7 @@ XPCOMUtils.defineLazyGetter(this, "gRadioEnabledController", function() {
// 1. a SIM card is presented or
// 2. it is the default clientId and there is no any SIM card at any client.
- if (this._isCardPresentAtClient(clientId)) {
+ if (_ril.getRadioInterface(clientId).isCardPresent()) {
return true;
}
@@ -1511,12 +1505,15 @@ RadioInterfaceLayer.prototype = {
},
getClientIdForEmergencyCall: function() {
+ // Select the client with sim card first.
for (let cid = 0; cid < this.numRadioInterfaces; ++cid) {
- if (gRadioEnabledController._isRadioAbleToEnableAtClient(cid)) {
+ if (this.getRadioInterface(cid).isCardPresent()) {
return cid;
}
}
- return -1;
+
+ // Use the defualt client if no card presents.
+ return HW_DEFAULT_CLIENT_ID;
},
setMicrophoneMuted: function(muted) {
@@ -1824,6 +1821,12 @@ RadioInterface.prototype = {
return false;
},
+ isCardPresent: function() {
+ let cardState = this.rilContext.cardState;
+ return cardState !== Ci.nsIIccProvider.CARD_STATE_UNDETECTED &&
+ cardState !== Ci.nsIIccProvider.CARD_STATE_UNKNOWN;
+ },
+
/**
* Process a message from the content process.
*/
diff --git a/dom/telephony/Telephony.cpp b/dom/telephony/Telephony.cpp
index 47863ae828fe..8d05798c4b8c 100644
--- a/dom/telephony/Telephony.cpp
+++ b/dom/telephony/Telephony.cpp
@@ -62,27 +62,17 @@ public:
}
};
-class Telephony::EnumerationAck : public nsRunnable
-{
- nsRefPtr mTelephony;
-
-public:
- explicit EnumerationAck(Telephony* aTelephony)
- : mTelephony(aTelephony)
- {
- MOZ_ASSERT(mTelephony);
- }
-
- NS_IMETHOD Run()
- {
- mTelephony->NotifyEvent(NS_LITERAL_STRING("ready"));
- return NS_OK;
- }
-};
-
Telephony::Telephony(nsPIDOMWindow* aOwner)
- : DOMEventTargetHelper(aOwner), mEnumerated(false)
+ : DOMEventTargetHelper(aOwner)
{
+ nsCOMPtr global = do_QueryInterface(aOwner);
+ MOZ_ASSERT(global);
+
+ ErrorResult rv;
+ nsRefPtr promise = Promise::Create(global, rv);
+ MOZ_ASSERT(!rv.Failed());
+
+ mReadyPromise = promise;
}
Telephony::~Telephony()
@@ -327,6 +317,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(Telephony,
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCalls)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCallsList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGroup)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mReadyPromise)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(Telephony,
@@ -335,6 +326,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(Telephony,
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCalls)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCallsList)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mGroup)
+ NS_IMPL_CYCLE_COLLECTION_UNLINK(mReadyPromise)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(Telephony)
@@ -462,14 +454,16 @@ Telephony::ConferenceGroup() const
return group.forget();
}
-// EventTarget
-
-void
-Telephony::EventListenerAdded(nsIAtom* aType)
+already_AddRefed
+Telephony::GetReady(ErrorResult& aRv) const
{
- if (aType == nsGkAtoms::onready) {
- EnqueueEnumerationAck();
+ if (!mReadyPromise) {
+ aRv.Throw(NS_ERROR_UNEXPECTED);
+ return nullptr;
}
+
+ nsRefPtr promise = mReadyPromise;
+ return promise.forget();
}
// nsITelephonyListener
@@ -548,8 +542,6 @@ Telephony::ConferenceCallStateChanged(uint16_t aCallState)
NS_IMETHODIMP
Telephony::EnumerateCallStateComplete()
{
- MOZ_ASSERT(!mEnumerated);
-
// Set conference state.
if (mGroup->CallsArray().Length() >= 2) {
const nsTArray > &calls = mGroup->CallsArray();
@@ -565,10 +557,8 @@ Telephony::EnumerateCallStateComplete()
mGroup->ChangeState(callState);
}
- mEnumerated = true;
-
- if (NS_FAILED(NotifyEvent(NS_LITERAL_STRING("ready")))) {
- NS_WARNING("Failed to notify ready!");
+ if (mReadyPromise) {
+ mReadyPromise->MaybeResolve(JS::UndefinedHandleValue);
}
if (NS_FAILED(mService->RegisterListener(mListener))) {
@@ -693,19 +683,6 @@ Telephony::DispatchCallEvent(const nsAString& aType,
return DispatchTrustedEvent(event);
}
-void
-Telephony::EnqueueEnumerationAck()
-{
- if (!mEnumerated) {
- return;
- }
-
- nsCOMPtr task = new EnumerationAck(this);
- if (NS_FAILED(NS_DispatchToCurrentThread(task))) {
- NS_WARNING("Failed to dispatch to current thread!");
- }
-}
-
already_AddRefed
NS_CreateTelephonyService()
{
diff --git a/dom/telephony/Telephony.h b/dom/telephony/Telephony.h
index 98ac27bfd131..c800bd1426d7 100644
--- a/dom/telephony/Telephony.h
+++ b/dom/telephony/Telephony.h
@@ -40,9 +40,7 @@ class Telephony MOZ_FINAL : public DOMEventTargetHelper,
* also bug 775997 comment #51.
*/
class Listener;
- class EnumerationAck;
- friend class EnumerationAck;
friend class telephony::TelephonyDialCallback;
nsCOMPtr mService;
@@ -53,7 +51,7 @@ class Telephony MOZ_FINAL : public DOMEventTargetHelper,
nsRefPtr mGroup;
- bool mEnumerated;
+ nsRefPtr mReadyPromise;
public:
NS_DECL_ISUPPORTS_INHERITED
@@ -109,7 +107,9 @@ public:
already_AddRefed
ConferenceGroup() const;
- IMPL_EVENT_HANDLER(ready)
+ already_AddRefed
+ GetReady(ErrorResult& aRv) const;
+
IMPL_EVENT_HANDLER(incoming)
IMPL_EVENT_HANDLER(callschanged)
IMPL_EVENT_HANDLER(remoteheld)
@@ -146,8 +146,6 @@ public:
return mCalls;
}
- virtual void EventListenerAdded(nsIAtom* aType) MOZ_OVERRIDE;
-
private:
explicit Telephony(nsPIDOMWindow* aOwner);
~Telephony();
@@ -198,9 +196,6 @@ private:
nsresult
DispatchCallEvent(const nsAString& aType, TelephonyCall* aCall);
- void
- EnqueueEnumerationAck();
-
already_AddRefed
GetCall(uint32_t aServiceId, uint32_t aCallIndex);
diff --git a/dom/telephony/test/marionette/test_ready.js b/dom/telephony/test/marionette/test_ready.js
index f73347971b69..2e0cfb49d51a 100644
--- a/dom/telephony/test/marionette/test_ready.js
+++ b/dom/telephony/test/marionette/test_ready.js
@@ -13,10 +13,10 @@ function cleanUp() {
let telephony = window.navigator.mozTelephony;
ok(telephony);
-telephony.onready = function() {
- log("Receive 'ready' event");
+telephony.ready.then(function() {
+ log("Telephony got ready");
- // Test registering 'ready' event in another window.
+ // Test telephony.ready in another window.
let iframe = document.createElement("iframe");
iframe.addEventListener("load", function load() {
iframe.removeEventListener("load", load);
@@ -24,12 +24,12 @@ telephony.onready = function() {
let iframeTelephony = iframe.contentWindow.navigator.mozTelephony;
ok(iframeTelephony);
- iframeTelephony.onready = function() {
- log("Receive 'ready' event in iframe");
+ iframeTelephony.ready.then(function() {
+ log("Telephony in iframe got ready");
cleanUp();
- };
+ });
});
document.body.appendChild(iframe);
-};
+});
diff --git a/dom/webidl/Telephony.webidl b/dom/webidl/Telephony.webidl
index d0fc9eb4755c..a2c79cef072d 100644
--- a/dom/webidl/Telephony.webidl
+++ b/dom/webidl/Telephony.webidl
@@ -46,8 +46,9 @@ interface Telephony : EventTarget {
readonly attribute CallsList calls;
readonly attribute TelephonyCallGroup conferenceGroup;
- // The 'ready' event will be fired when the telephony object is ready.
- attribute EventHandler onready;
+ // Async notification that object initialization is done.
+ [Throws]
+ readonly attribute Promise ready;
attribute EventHandler onincoming;
attribute EventHandler oncallschanged;
diff --git a/dom/workers/ChromeWorkerScope.cpp b/dom/workers/ChromeWorkerScope.cpp
index 3b576985e062..9cb25652e5ef 100644
--- a/dom/workers/ChromeWorkerScope.cpp
+++ b/dom/workers/ChromeWorkerScope.cpp
@@ -59,7 +59,7 @@ DefineChromeWorkerFunctions(JSContext* aCx, JS::Handle aGlobal)
return false;
}
- static JSCTypesCallbacks callbacks = {
+ static const JSCTypesCallbacks callbacks = {
UnicodeToNative
};
diff --git a/dom/workers/Navigator.cpp b/dom/workers/Navigator.cpp
index 025289df0938..5f26d5794f57 100644
--- a/dom/workers/Navigator.cpp
+++ b/dom/workers/Navigator.cpp
@@ -194,7 +194,7 @@ GetDataStoresStructuredCloneCallbacksWrite(JSContext* aCx,
return true;
}
-static JSStructuredCloneCallbacks kGetDataStoresStructuredCloneCallbacks = {
+static const JSStructuredCloneCallbacks kGetDataStoresStructuredCloneCallbacks = {
GetDataStoresStructuredCloneCallbacksRead,
GetDataStoresStructuredCloneCallbacksWrite,
nullptr
diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp
index 0f3537dabfcc..49bbd61031c5 100644
--- a/dom/workers/RuntimeService.cpp
+++ b/dom/workers/RuntimeService.cpp
@@ -775,13 +775,13 @@ CreateJSContextForWorker(WorkerPrivate* aWorkerPrivate, JSRuntime* aRuntime)
JS_SetNativeStackQuota(aRuntime, WORKER_CONTEXT_NATIVE_STACK_LIMIT);
// Security policy:
- static JSSecurityCallbacks securityCallbacks = {
+ static const JSSecurityCallbacks securityCallbacks = {
ContentSecurityPolicyAllows
};
JS_SetSecurityCallbacks(aRuntime, &securityCallbacks);
// Set up the asm.js cache callbacks
- static JS::AsmJSCacheOps asmJSCacheOps = {
+ static const JS::AsmJSCacheOps asmJSCacheOps = {
AsmJSCacheOpenEntryForRead,
asmjscache::CloseEntryForRead,
AsmJSCacheOpenEntryForWrite,
diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp
index 9493b887248b..8b50eed819bb 100644
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -386,7 +386,7 @@ struct WorkerStructuredCloneCallbacks
}
};
-JSStructuredCloneCallbacks gWorkerStructuredCloneCallbacks = {
+const JSStructuredCloneCallbacks gWorkerStructuredCloneCallbacks = {
WorkerStructuredCloneCallbacks::Read,
WorkerStructuredCloneCallbacks::Write,
WorkerStructuredCloneCallbacks::Error,
@@ -483,7 +483,7 @@ struct MainThreadWorkerStructuredCloneCallbacks
}
};
-JSStructuredCloneCallbacks gMainThreadWorkerStructuredCloneCallbacks = {
+const JSStructuredCloneCallbacks gMainThreadWorkerStructuredCloneCallbacks = {
MainThreadWorkerStructuredCloneCallbacks::Read,
MainThreadWorkerStructuredCloneCallbacks::Write,
MainThreadWorkerStructuredCloneCallbacks::Error,
@@ -516,7 +516,7 @@ struct ChromeWorkerStructuredCloneCallbacks
}
};
-JSStructuredCloneCallbacks gChromeWorkerStructuredCloneCallbacks = {
+const JSStructuredCloneCallbacks gChromeWorkerStructuredCloneCallbacks = {
ChromeWorkerStructuredCloneCallbacks::Read,
ChromeWorkerStructuredCloneCallbacks::Write,
ChromeWorkerStructuredCloneCallbacks::Error,
@@ -577,7 +577,7 @@ struct MainThreadChromeWorkerStructuredCloneCallbacks
}
};
-JSStructuredCloneCallbacks gMainThreadChromeWorkerStructuredCloneCallbacks = {
+const JSStructuredCloneCallbacks gMainThreadChromeWorkerStructuredCloneCallbacks = {
MainThreadChromeWorkerStructuredCloneCallbacks::Read,
MainThreadChromeWorkerStructuredCloneCallbacks::Write,
MainThreadChromeWorkerStructuredCloneCallbacks::Error,
@@ -2663,7 +2663,7 @@ WorkerPrivateParent::PostMessageInternal(
}
}
- JSStructuredCloneCallbacks* callbacks;
+ const JSStructuredCloneCallbacks* callbacks;
if (GetParent()) {
if (IsChromeWorker()) {
callbacks = &gChromeWorkerStructuredCloneCallbacks;
@@ -5161,7 +5161,7 @@ WorkerPrivate::PostMessageToParentInternal(
transferable.setObject(*array);
}
- JSStructuredCloneCallbacks* callbacks =
+ const JSStructuredCloneCallbacks* callbacks =
IsChromeWorker() ?
&gChromeWorkerStructuredCloneCallbacks :
&gWorkerStructuredCloneCallbacks;
@@ -6184,7 +6184,7 @@ GetWorkerCrossThreadDispatcher(JSContext* aCx, JS::Value aWorker)
return w->GetCrossThreadDispatcher();
}
-JSStructuredCloneCallbacks*
+const JSStructuredCloneCallbacks*
WorkerStructuredCloneCallbacks(bool aMainRuntime)
{
return aMainRuntime ?
@@ -6192,7 +6192,7 @@ WorkerStructuredCloneCallbacks(bool aMainRuntime)
&gWorkerStructuredCloneCallbacks;
}
-JSStructuredCloneCallbacks*
+const JSStructuredCloneCallbacks*
ChromeWorkerStructuredCloneCallbacks(bool aMainRuntime)
{
return aMainRuntime ?
diff --git a/dom/workers/WorkerPrivate.h b/dom/workers/WorkerPrivate.h
index 17c79cfd00db..449141a6595b 100644
--- a/dom/workers/WorkerPrivate.h
+++ b/dom/workers/WorkerPrivate.h
@@ -1296,10 +1296,10 @@ enum WorkerStructuredDataType
DOMWORKER_SCTAG_END
};
-JSStructuredCloneCallbacks*
+const JSStructuredCloneCallbacks*
WorkerStructuredCloneCallbacks(bool aMainRuntime);
-JSStructuredCloneCallbacks*
+const JSStructuredCloneCallbacks*
ChromeWorkerStructuredCloneCallbacks(bool aMainRuntime);
class AutoSyncLoopHolder
diff --git a/dom/workers/XMLHttpRequest.cpp b/dom/workers/XMLHttpRequest.cpp
index b176e4992461..e213aa3425a1 100644
--- a/dom/workers/XMLHttpRequest.cpp
+++ b/dom/workers/XMLHttpRequest.cpp
@@ -1219,7 +1219,7 @@ EventRunnable::PreDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
if (doClone) {
// Anything subject to GC must be cloned.
- JSStructuredCloneCallbacks* callbacks =
+ const JSStructuredCloneCallbacks* callbacks =
aWorkerPrivate->IsChromeWorker() ?
workers::ChromeWorkerStructuredCloneCallbacks(true) :
workers::WorkerStructuredCloneCallbacks(true);
@@ -1331,7 +1331,7 @@ EventRunnable::WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
JSAutoStructuredCloneBuffer responseBuffer(Move(mResponseBuffer));
- JSStructuredCloneCallbacks* callbacks =
+ const JSStructuredCloneCallbacks* callbacks =
aWorkerPrivate->IsChromeWorker() ?
workers::ChromeWorkerStructuredCloneCallbacks(false) :
workers::WorkerStructuredCloneCallbacks(false);
@@ -1515,7 +1515,7 @@ SendRunnable::MainThreadRun()
nsresult rv = NS_OK;
- JSStructuredCloneCallbacks* callbacks =
+ const JSStructuredCloneCallbacks* callbacks =
mWorkerPrivate->IsChromeWorker() ?
workers::ChromeWorkerStructuredCloneCallbacks(true) :
workers::WorkerStructuredCloneCallbacks(true);
@@ -2139,7 +2139,7 @@ XMLHttpRequest::Send(JS::Handle aBody, ErrorResult& aRv)
valToClone.setString(bodyStr);
}
- JSStructuredCloneCallbacks* callbacks =
+ const JSStructuredCloneCallbacks* callbacks =
mWorkerPrivate->IsChromeWorker() ?
ChromeWorkerStructuredCloneCallbacks(false) :
WorkerStructuredCloneCallbacks(false);
@@ -2177,7 +2177,7 @@ XMLHttpRequest::Send(File& aBody, ErrorResult& aRv)
return;
}
- JSStructuredCloneCallbacks* callbacks =
+ const JSStructuredCloneCallbacks* callbacks =
mWorkerPrivate->IsChromeWorker() ?
ChromeWorkerStructuredCloneCallbacks(false) :
WorkerStructuredCloneCallbacks(false);
diff --git a/gfx/layers/opengl/X11TextureSourceOGL.cpp b/gfx/layers/opengl/X11TextureSourceOGL.cpp
index 7ecd4e624e89..b744e92b3761 100644
--- a/gfx/layers/opengl/X11TextureSourceOGL.cpp
+++ b/gfx/layers/opengl/X11TextureSourceOGL.cpp
@@ -101,7 +101,7 @@ X11TextureSourceOGL::ContentTypeToSurfaceFormat(gfxContentType aType)
}
}
-#endif
+}
+}
-}
-}
+#endif
diff --git a/hal/gonk/GonkHal.cpp b/hal/gonk/GonkHal.cpp
index f366d3d662c5..69b40766f289 100644
--- a/hal/gonk/GonkHal.cpp
+++ b/hal/gonk/GonkHal.cpp
@@ -27,7 +27,11 @@
#include
#include
#include
+#if ANDROID_VERSION >= 21
+#include
+#else
#include
+#endif
#include "mozilla/DebugOnly.h"
diff --git a/js/src/ctypes/CTypes.cpp b/js/src/ctypes/CTypes.cpp
index 79da39fc80d9..10e0b1670d82 100644
--- a/js/src/ctypes/CTypes.cpp
+++ b/js/src/ctypes/CTypes.cpp
@@ -1320,7 +1320,7 @@ IsCTypesGlobal(HandleValue v)
}
// Get the JSCTypesCallbacks struct from the 'ctypes' object 'obj'.
-JSCTypesCallbacks*
+const JSCTypesCallbacks*
GetCallbacks(JSObject* obj)
{
MOZ_ASSERT(IsCTypesGlobal(obj));
@@ -1329,7 +1329,7 @@ GetCallbacks(JSObject* obj)
if (result.isUndefined())
return nullptr;
- return static_cast(result.toPrivate());
+ return static_cast(result.toPrivate());
}
// Utility function to access a property of an object as an object
@@ -1406,13 +1406,14 @@ JS_InitCTypesClass(JSContext* cx, HandleObject global)
}
JS_PUBLIC_API(void)
-JS_SetCTypesCallbacks(JSObject *ctypesObj, JSCTypesCallbacks* callbacks)
+JS_SetCTypesCallbacks(JSObject *ctypesObj, const JSCTypesCallbacks* callbacks)
{
MOZ_ASSERT(callbacks);
MOZ_ASSERT(IsCTypesGlobal(ctypesObj));
// Set the callbacks on a reserved slot.
- JS_SetReservedSlot(ctypesObj, SLOT_CALLBACKS, PRIVATE_TO_JSVAL(callbacks));
+ JS_SetReservedSlot(ctypesObj, SLOT_CALLBACKS,
+ PRIVATE_TO_JSVAL(const_cast(callbacks)));
}
namespace js {
diff --git a/js/src/ctypes/CTypes.h b/js/src/ctypes/CTypes.h
index 7e971661675b..bb118f2cc217 100644
--- a/js/src/ctypes/CTypes.h
+++ b/js/src/ctypes/CTypes.h
@@ -344,7 +344,7 @@ struct ClosureInfo
bool IsCTypesGlobal(HandleValue v);
bool IsCTypesGlobal(JSObject* obj);
-JSCTypesCallbacks* GetCallbacks(JSObject* obj);
+const JSCTypesCallbacks* GetCallbacks(JSObject* obj);
/*******************************************************************************
** JSClass reserved slot definitions
@@ -461,7 +461,7 @@ namespace CType {
JSString* GetName(JSContext* cx, HandleObject obj);
JSObject* GetProtoFromCtor(JSObject* obj, CTypeProtoSlot slot);
JSObject* GetProtoFromType(JSContext* cx, JSObject* obj, CTypeProtoSlot slot);
- JSCTypesCallbacks* GetCallbacksFromType(JSObject* obj);
+ const JSCTypesCallbacks* GetCallbacksFromType(JSObject* obj);
}
namespace PointerType {
diff --git a/js/src/ctypes/Library.cpp b/js/src/ctypes/Library.cpp
index a880fd4688cb..c084a1e1a591 100644
--- a/js/src/ctypes/Library.cpp
+++ b/js/src/ctypes/Library.cpp
@@ -80,7 +80,7 @@ Library::Name(JSContext* cx, unsigned argc, jsval *vp)
}
JSObject*
-Library::Create(JSContext* cx, jsval path_, JSCTypesCallbacks* callbacks)
+Library::Create(JSContext* cx, jsval path_, const JSCTypesCallbacks* callbacks)
{
RootedValue path(cx, path_);
RootedObject libraryObj(cx,
diff --git a/js/src/ctypes/Library.h b/js/src/ctypes/Library.h
index e37ea0f95116..2413afd6e537 100644
--- a/js/src/ctypes/Library.h
+++ b/js/src/ctypes/Library.h
@@ -23,7 +23,7 @@ namespace Library
{
bool Name(JSContext* cx, unsigned argc, JS::Value *vp);
- JSObject* Create(JSContext* cx, JS::Value path, JSCTypesCallbacks* callbacks);
+ JSObject* Create(JSContext* cx, JS::Value path, const JSCTypesCallbacks* callbacks);
bool IsLibrary(JSObject* obj);
PRLibrary* GetLibrary(JSObject* obj);
diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp
index 6513202d042a..a4fa7901d2c8 100644
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -5542,13 +5542,13 @@ JS_ResetDefaultLocale(JSRuntime *rt)
}
JS_PUBLIC_API(void)
-JS_SetLocaleCallbacks(JSRuntime *rt, JSLocaleCallbacks *callbacks)
+JS_SetLocaleCallbacks(JSRuntime *rt, const JSLocaleCallbacks *callbacks)
{
AssertHeapIsIdle(rt);
rt->localeCallbacks = callbacks;
}
-JS_PUBLIC_API(JSLocaleCallbacks *)
+JS_PUBLIC_API(const JSLocaleCallbacks *)
JS_GetLocaleCallbacks(JSRuntime *rt)
{
/* This function can be called by a finalizer. */
diff --git a/js/src/jsapi.h b/js/src/jsapi.h
index 85c835908b83..7f62093d4c73 100644
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -1948,7 +1948,7 @@ typedef struct JSCTypesCallbacks JSCTypesCallbacks;
* to call this function again.
*/
extern JS_PUBLIC_API(void)
-JS_SetCTypesCallbacks(JSObject *ctypesObj, JSCTypesCallbacks *callbacks);
+JS_SetCTypesCallbacks(JSObject *ctypesObj, const JSCTypesCallbacks *callbacks);
#endif
typedef bool
@@ -4699,13 +4699,13 @@ struct JSLocaleCallbacks {
* JSRuntime. Passing nullptr restores the default behaviour.
*/
extern JS_PUBLIC_API(void)
-JS_SetLocaleCallbacks(JSRuntime *rt, JSLocaleCallbacks *callbacks);
+JS_SetLocaleCallbacks(JSRuntime *rt, const JSLocaleCallbacks *callbacks);
/*
* Return the address of the current locale callbacks struct, which may
* be nullptr.
*/
-extern JS_PUBLIC_API(JSLocaleCallbacks *)
+extern JS_PUBLIC_API(const JSLocaleCallbacks *)
JS_GetLocaleCallbacks(JSRuntime *rt);
/************************************************************************/
diff --git a/js/src/vm/Runtime.h b/js/src/vm/Runtime.h
index c36e4c89553d..5e07400d1ed9 100644
--- a/js/src/vm/Runtime.h
+++ b/js/src/vm/Runtime.h
@@ -808,7 +808,7 @@ struct JSRuntime : public JS::shadow::Runtime,
size_t numCompartments;
/* Locale-specific callbacks for string conversion. */
- JSLocaleCallbacks *localeCallbacks;
+ const JSLocaleCallbacks *localeCallbacks;
/* Default locale for Internationalization API */
char *defaultLocale;
diff --git a/js/xpconnect/loader/mozJSSubScriptLoader.cpp b/js/xpconnect/loader/mozJSSubScriptLoader.cpp
index 48d1a3efdfde..ab9e4e0024c8 100644
--- a/js/xpconnect/loader/mozJSSubScriptLoader.cpp
+++ b/js/xpconnect/loader/mozJSSubScriptLoader.cpp
@@ -346,7 +346,7 @@ mozJSSubScriptLoader::DoLoadSubScriptWithOptions(const nsAString &url,
return ReportError(cx, LOAD_ERROR_NOSCHEME, uri);
}
- if (!scheme.EqualsLiteral("chrome")) {
+ if (!scheme.EqualsLiteral("chrome") && !scheme.EqualsLiteral("app")) {
// This might be a URI to a local file, though!
nsCOMPtr innerURI = NS_GetInnermostURI(uri);
nsCOMPtr fileURL = do_QueryInterface(innerURI);
diff --git a/js/xpconnect/src/XPCLocale.cpp b/js/xpconnect/src/XPCLocale.cpp
index ca48629f547f..f7fe2c6c6fa7 100644
--- a/js/xpconnect/src/XPCLocale.cpp
+++ b/js/xpconnect/src/XPCLocale.cpp
@@ -60,16 +60,16 @@ struct XPCLocaleCallbacks : public JSLocaleCallbacks
{
// Locale information for |rt| was associated using xpc_LocalizeRuntime;
// assert and double-check this.
- JSLocaleCallbacks* lc = JS_GetLocaleCallbacks(rt);
+ const JSLocaleCallbacks* lc = JS_GetLocaleCallbacks(rt);
MOZ_ASSERT(lc);
MOZ_ASSERT(lc->localeToUpperCase == LocaleToUpperCase);
MOZ_ASSERT(lc->localeToLowerCase == LocaleToLowerCase);
MOZ_ASSERT(lc->localeCompare == LocaleCompare);
MOZ_ASSERT(lc->localeToUnicode == LocaleToUnicode);
- XPCLocaleCallbacks* ths = static_cast(lc);
+ const XPCLocaleCallbacks* ths = static_cast(lc);
ths->AssertThreadSafety();
- return ths;
+ return const_cast(ths);
}
static bool
@@ -233,7 +233,7 @@ private:
return false;
}
- void AssertThreadSafety()
+ void AssertThreadSafety() const
{
MOZ_ASSERT(mThread == PR_GetCurrentThread(),
"XPCLocaleCallbacks used unsafely!");
@@ -273,7 +273,7 @@ xpc_LocalizeRuntime(JSRuntime *rt)
void
xpc_DelocalizeRuntime(JSRuntime *rt)
{
- XPCLocaleCallbacks* lc = XPCLocaleCallbacks::This(rt);
+ const XPCLocaleCallbacks* lc = XPCLocaleCallbacks::This(rt);
JS_SetLocaleCallbacks(rt, nullptr);
delete lc;
}
diff --git a/mobile/android/base/BrowserApp.java b/mobile/android/base/BrowserApp.java
index f89be2a67085..e9f9abb0d6be 100644
--- a/mobile/android/base/BrowserApp.java
+++ b/mobile/android/base/BrowserApp.java
@@ -148,7 +148,6 @@ public class BrowserApp extends GeckoApp
LayerView.OnMetricsChangedListener,
BrowserSearch.OnSearchListener,
BrowserSearch.OnEditSuggestionListener,
- HomePager.OnNewTabsListener,
OnUrlOpenListener,
OnUrlOpenInBackgroundListener,
ActionModeCompat.Presenter,
@@ -3158,18 +3157,6 @@ public class BrowserApp extends GeckoApp
}).execute();
}
- // HomePager.OnNewTabsListener
- @Override
- public void onNewTabs(List urls) {
- final EnumSet flags = EnumSet.of(OnUrlOpenListener.Flags.ALLOW_SWITCH_TO_TAB);
-
- for (String url : urls) {
- if (!maybeSwitchToTab(url, flags)) {
- openUrlAndStopEditing(url, true);
- }
- }
- }
-
// HomePager.OnUrlOpenListener
@Override
public void onUrlOpen(String url, EnumSet flags) {
diff --git a/mobile/android/base/home/HomePager.java b/mobile/android/base/home/HomePager.java
index 5d16c8f05c16..f826a7d4d1e0 100644
--- a/mobile/android/base/home/HomePager.java
+++ b/mobile/android/base/home/HomePager.java
@@ -102,10 +102,6 @@ public class HomePager extends ViewPager {
public void onUrlOpenInBackground(String url, EnumSet flags);
}
- public interface OnNewTabsListener {
- public void onNewTabs(List urls);
- }
-
/**
* Interface for listening into ViewPager panel changes
*/
diff --git a/mobile/android/base/home/RecentTabsPanel.java b/mobile/android/base/home/RecentTabsPanel.java
index 9e55ccd2fe37..7485d4169aa1 100644
--- a/mobile/android/base/home/RecentTabsPanel.java
+++ b/mobile/android/base/home/RecentTabsPanel.java
@@ -8,6 +8,9 @@ package org.mozilla.gecko.home;
import java.util.ArrayList;
import java.util.List;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
import org.mozilla.gecko.AboutPages;
import org.mozilla.gecko.EventDispatcher;
import org.mozilla.gecko.GeckoAppShell;
@@ -19,8 +22,8 @@ import org.mozilla.gecko.Telemetry;
import org.mozilla.gecko.TelemetryContract;
import org.mozilla.gecko.db.BrowserContract.CommonColumns;
import org.mozilla.gecko.db.BrowserContract.URLColumns;
-import org.mozilla.gecko.home.HomePager.OnNewTabsListener;
import org.mozilla.gecko.util.EventCallback;
+import org.mozilla.gecko.util.GeckoRequest;
import org.mozilla.gecko.util.NativeEventListener;
import org.mozilla.gecko.util.NativeJSObject;
import org.mozilla.gecko.util.ThreadUtils;
@@ -33,6 +36,7 @@ import android.database.MatrixCursor.RowBuilder;
import android.os.Bundle;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.Loader;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -65,24 +69,35 @@ public class RecentTabsPanel extends HomeFragment
// Callbacks used for the search and favicon cursor loaders
private CursorLoaderCallbacks mCursorLoaderCallbacks;
- // On new tabs listener
- private OnNewTabsListener mNewTabsListener;
-
// Recently closed tabs from gecko
private ClosedTab[] mClosedTabs;
+ private void restoreSessionWithHistory(List dataList) {
+ JSONObject json = new JSONObject();
+ try {
+ json.put("tabs", new JSONArray(dataList));
+ } catch (JSONException e) {
+ Log.e(LOGTAG, "JSON error", e);
+ }
+
+ GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Session:RestoreRecentTabs", json.toString()));
+ }
+
private static final class ClosedTab {
public final String url;
public final String title;
+ public final String data;
- public ClosedTab(String url, String title) {
+ public ClosedTab(String url, String title, String data) {
this.url = url;
this.title = title;
+ this.data = data;
}
}
public static final class RecentTabs implements URLColumns, CommonColumns {
public static final String TYPE = "type";
+ public static final String DATA = "data";
public static final int TYPE_HEADER = 0;
public static final int TYPE_LAST_TIME = 1;
@@ -91,25 +106,6 @@ public class RecentTabsPanel extends HomeFragment
public static final int TYPE_OPEN_ALL_CLOSED = 4;
}
- @Override
- public void onAttach(Activity activity) {
- super.onAttach(activity);
-
- try {
- mNewTabsListener = (OnNewTabsListener) activity;
- } catch (ClassCastException e) {
- throw new ClassCastException(activity.toString()
- + " must implement HomePager.OnNewTabsListener");
- }
- }
-
- @Override
- public void onDetach() {
- super.onDetach();
-
- mNewTabsListener = null;
- }
-
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.home_recent_tabs_panel, container, false);
@@ -142,10 +138,9 @@ public class RecentTabsPanel extends HomeFragment
Telemetry.sendUIEvent(TelemetryContract.Event.LOAD_URL, TelemetryContract.Method.LIST_ITEM);
- final ArrayList urls = new ArrayList();
- urls.add(c.getString(c.getColumnIndexOrThrow(RecentTabs.URL)));
-
- mNewTabsListener.onNewTabs(urls);
+ final List dataList = new ArrayList<>();
+ dataList.add(c.getString(c.getColumnIndexOrThrow(RecentTabs.DATA)));
+ restoreSessionWithHistory(dataList);
}
});
@@ -227,7 +222,7 @@ public class RecentTabsPanel extends HomeFragment
final ClosedTab[] closedTabs = new ClosedTab[length];
for (int i = 0; i < length; i++) {
final NativeJSObject tab = tabs[i];
- closedTabs[i] = new ClosedTab(tab.getString("url"), tab.getString("title"));
+ closedTabs[i] = new ClosedTab(tab.getString("url"), tab.getString("title"), tab.getObject("data").toString());
}
// Only modify mClosedTabs on the UI thread
@@ -252,16 +247,16 @@ public class RecentTabsPanel extends HomeFragment
return;
}
- final List urls = new ArrayList();
+ final List dataList = new ArrayList();
do {
if (c.getInt(c.getColumnIndexOrThrow(RecentTabs.TYPE)) == type) {
- urls.add(c.getString(c.getColumnIndexOrThrow(RecentTabs.URL)));
+ dataList.add(c.getString(c.getColumnIndexOrThrow(RecentTabs.DATA)));
}
} while (c.moveToNext());
Telemetry.sendUIEvent(TelemetryContract.Event.LOAD_URL, TelemetryContract.Method.BUTTON);
- mNewTabsListener.onNewTabs(urls);
+ restoreSessionWithHistory(dataList);
}
private static class RecentTabsCursorLoader extends SimpleCursorLoader {
@@ -272,12 +267,13 @@ public class RecentTabsPanel extends HomeFragment
this.closedTabs = closedTabs;
}
- private void addRow(MatrixCursor c, String url, String title, int type) {
+ private void addRow(MatrixCursor c, String url, String title, int type, String data) {
final RowBuilder row = c.newRow();
row.add(-1);
row.add(url);
row.add(title);
row.add(type);
+ row.add(data);
}
@Override
@@ -287,7 +283,8 @@ public class RecentTabsPanel extends HomeFragment
final MatrixCursor c = new MatrixCursor(new String[] { RecentTabs._ID,
RecentTabs.URL,
RecentTabs.TITLE,
- RecentTabs.TYPE });
+ RecentTabs.TYPE,
+ RecentTabs.DATA});
if (closedTabs != null && closedTabs.length > 0) {
// How many closed tabs are actually displayed.
@@ -301,16 +298,16 @@ public class RecentTabsPanel extends HomeFragment
if (!AboutPages.isTitlelessAboutPage(url)) {
// If this is the first closed tab we're adding, add a header for the section.
if (visibleClosedTabs == 0) {
- addRow(c, null, context.getString(R.string.home_closed_tabs_title), RecentTabs.TYPE_HEADER);
+ addRow(c, null, context.getString(R.string.home_closed_tabs_title), RecentTabs.TYPE_HEADER, null);
}
- addRow(c, url, closedTabs[i].title, RecentTabs.TYPE_CLOSED);
+ addRow(c, url, closedTabs[i].title, RecentTabs.TYPE_CLOSED, closedTabs[i].data);
visibleClosedTabs++;
}
}
// Add an "Open all" button if more than 2 tabs were added to the list.
if (visibleClosedTabs > 1) {
- addRow(c, null, null, RecentTabs.TYPE_OPEN_ALL_CLOSED);
+ addRow(c, null, null, RecentTabs.TYPE_OPEN_ALL_CLOSED, null);
}
}
@@ -334,16 +331,16 @@ public class RecentTabsPanel extends HomeFragment
// If this is the first tab we're reading, add a header.
if (c.getCount() == count) {
- addRow(c, null, context.getString(R.string.home_last_tabs_title), RecentTabs.TYPE_HEADER);
+ addRow(c, null, context.getString(R.string.home_last_tabs_title), RecentTabs.TYPE_HEADER, null);
}
- addRow(c, url, tab.getTitle(), RecentTabs.TYPE_LAST_TIME);
+ addRow(c, url, tab.getTitle(), RecentTabs.TYPE_LAST_TIME, tab.getTabObject().toString());
}
}.parse(jsonString);
// Add an "Open all" button if more than 2 tabs were added to the list (account for the header)
if (c.getCount() - count > 2) {
- addRow(c, null, null, RecentTabs.TYPE_OPEN_ALL_LAST_TIME);
+ addRow(c, null, null, RecentTabs.TYPE_OPEN_ALL_LAST_TIME, null);
}
return c;
diff --git a/mobile/android/base/tests/testReadingListCache.js b/mobile/android/base/tests/testReadingListCache.js
index be7c3a28e51a..8de822dcf591 100644
--- a/mobile/android/base/tests/testReadingListCache.js
+++ b/mobile/android/base/tests/testReadingListCache.js
@@ -5,6 +5,7 @@
const { utils: Cu } = Components;
+Cu.import("resource://gre/modules/ReaderMode.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Task.jsm");
@@ -39,13 +40,13 @@ let TEST_PAGES = [
add_task(function* test_article_not_found() {
let uri = Services.io.newURI(TEST_PAGES[0].url, null, null);
- let article = yield Reader.getArticleFromCache(uri);
+ let article = yield ReaderMode.getArticleFromCache(uri);
do_check_eq(article, null);
});
add_task(function* test_store_article() {
// Create an article object to store in the cache.
- yield Reader.storeArticleInCache({
+ yield ReaderMode.storeArticleInCache({
url: TEST_PAGES[0].url,
content: "Lorem ipsum",
title: TEST_PAGES[0].expected.title,
@@ -55,14 +56,14 @@ add_task(function* test_store_article() {
});
let uri = Services.io.newURI(TEST_PAGES[0].url, null, null);
- let article = yield Reader.getArticleFromCache(uri);
+ let article = yield ReaderMode.getArticleFromCache(uri);
checkArticle(article, TEST_PAGES[0]);
});
add_task(function* test_remove_article() {
let uri = Services.io.newURI(TEST_PAGES[0].url, null, null);
- yield Reader.removeArticleFromCache(uri);
- let article = yield Reader.getArticleFromCache(uri);
+ yield ReaderMode.removeArticleFromCache(uri);
+ let article = yield ReaderMode.getArticleFromCache(uri);
do_check_eq(article, null);
});
@@ -110,7 +111,7 @@ add_task(function* test_migrate_cache() {
// Check to make sure the article made it into the new cache.
let uri = Services.io.newURI(TEST_PAGES[0].url, null, null);
- let article = yield Reader.getArticleFromCache(uri);
+ let article = yield ReaderMode.getArticleFromCache(uri);
checkArticle(article, TEST_PAGES[0]);
});
diff --git a/mobile/android/chrome/content/Reader.js b/mobile/android/chrome/content/Reader.js
index 09021e9dc624..6fcca2e64391 100644
--- a/mobile/android/chrome/content/Reader.js
+++ b/mobile/android/chrome/content/Reader.js
@@ -4,21 +4,7 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
-XPCOMUtils.defineLazyModuleGetter(this, "CommonUtils",
- "resource://services-common/utils.js");
-
let Reader = {
- // Version of the cache schema.
- CACHE_VERSION: 1,
-
- DEBUG: 0,
-
- // Don't try to parse the page if it has too many elements (for memory and
- // performance reasons)
- MAX_ELEMS_TO_PARSE: 3000,
-
- _requests: {},
-
get isEnabledForParseOnLoad() {
delete this.isEnabledForParseOnLoad;
@@ -84,14 +70,7 @@ let Reader = {
switch(aTopic) {
case "Reader:Removed": {
let uri = Services.io.newURI(aData, null, null);
- this.removeArticleFromCache(uri).catch(e => Cu.reportError("Error removing article from cache: " + e));
- break;
- }
-
- case "nsPref:changed": {
- if (aData.startsWith("reader.parse-on-load.")) {
- this.isEnabledForParseOnLoad = this._getStateForParseOnLoad();
- }
+ ReaderMode.removeArticleFromCache(uri).catch(e => Cu.reportError("Error removing article from cache: " + e));
break;
}
}
@@ -133,7 +112,7 @@ let Reader = {
excerpt: article.excerpt || "",
});
- this.storeArticleInCache(article).catch(e => Cu.reportError("Error storing article in cache: " + e));
+ ReaderMode.storeArticleInCache(article).catch(e => Cu.reportError("Error storing article in cache: " + e));
},
_getStateForParseOnLoad: function () {
@@ -159,16 +138,14 @@ let Reader = {
if (tab) {
let article = tab.savedArticle;
if (article && article.url == url) {
- this.log("Saved article found in tab");
return article;
}
}
// Next, try to find a parsed article in the cache.
let uri = Services.io.newURI(url, null, null);
- let article = yield this.getArticleFromCache(uri);
+ let article = yield ReaderMode.getArticleFromCache(uri);
if (article) {
- this.log("Saved article found in cache");
return article;
}
@@ -177,146 +154,6 @@ let Reader = {
return yield this._downloadAndParseDocument(url);
}),
- /**
- * Gets an article from a loaded tab's document. This method will parse the document
- * if it does not find the article in the tab data or the cache.
- *
- * @param tab The loaded tab.
- * @return {Promise}
- * @resolves JS object representing the article, or null if no article is found.
- */
- parseDocumentFromTab: Task.async(function* (tab) {
- let uri = tab.browser.currentURI;
- if (!this._shouldCheckUri(uri)) {
- this.log("Reader mode disabled for URI");
- return null;
- }
-
- // First, try to find a parsed article in the cache.
- let article = yield this.getArticleFromCache(uri);
- if (article) {
- this.log("Page found in cache, return article immediately");
- return article;
- }
-
- let doc = tab.browser.contentWindow.document;
- return yield this._readerParse(uri, doc);
- }),
-
- /**
- * Retrieves an article from the cache given an article URI.
- *
- * @param uri The article URI.
- * @return {Promise}
- * @resolves JS object representing the article, or null if no article is found.
- * @rejects OS.File.Error
- */
- getArticleFromCache: Task.async(function* (uri) {
- let path = this._toHashedPath(uri.specIgnoringRef);
- try {
- let array = yield OS.File.read(path);
- return JSON.parse(new TextDecoder().decode(array));
- } catch (e if e instanceof OS.File.Error && e.becauseNoSuchFile) {
- return null;
- }
- }),
-
- /**
- * Stores an article in the cache.
- *
- * @param article JS object representing article.
- * @return {Promise}
- * @resolves When the article is stored.
- * @rejects OS.File.Error
- */
- storeArticleInCache: Task.async(function* (article) {
- let array = new TextEncoder().encode(JSON.stringify(article));
- let path = this._toHashedPath(article.url);
- yield this._ensureCacheDir();
- yield OS.File.writeAtomic(path, array, { tmpPath: path + ".tmp" });
- }),
-
- /**
- * Removes an article from the cache given an article URI.
- *
- * @param uri The article URI.
- * @return {Promise}
- * @resolves When the article is removed.
- * @rejects OS.File.Error
- */
- removeArticleFromCache: Task.async(function* (uri) {
- let path = this._toHashedPath(uri.specIgnoringRef);
- yield OS.File.remove(path);
- }),
-
- log: function(msg) {
- if (this.DEBUG)
- dump("Reader: " + msg);
- },
-
- _shouldCheckUri: function (uri) {
- if ((uri.prePath + "/") === uri.spec) {
- this.log("Not parsing home page: " + uri.spec);
- return false;
- }
-
- if (!(uri.schemeIs("http") || uri.schemeIs("https") || uri.schemeIs("file"))) {
- this.log("Not parsing URI scheme: " + uri.scheme);
- return false;
- }
-
- return true;
- },
-
- _readerParse: function (uri, doc) {
- return new Promise((resolve, reject) => {
- let numTags = doc.getElementsByTagName("*").length;
- if (numTags > this.MAX_ELEMS_TO_PARSE) {
- this.log("Aborting parse for " + uri.spec + "; " + numTags + " elements found");
- resolve(null);
- return;
- }
-
- let worker = new ChromeWorker("readerWorker.js");
- worker.onmessage = evt => {
- let article = evt.data;
-
- if (!article) {
- this.log("Worker did not return an article");
- resolve(null);
- return;
- }
-
- // Append URL to the article data. specIgnoringRef will ignore any hash
- // in the URL.
- article.url = uri.specIgnoringRef;
- let flags = Ci.nsIDocumentEncoder.OutputSelectionOnly | Ci.nsIDocumentEncoder.OutputAbsoluteLinks;
- article.title = Cc["@mozilla.org/parserutils;1"].getService(Ci.nsIParserUtils)
- .convertToPlainText(article.title, flags, 0);
- resolve(article);
- };
-
- worker.onerror = evt => {
- reject("Error in worker: " + evt.message);
- };
-
- try {
- worker.postMessage({
- uri: {
- spec: uri.spec,
- host: uri.host,
- prePath: uri.prePath,
- scheme: uri.scheme,
- pathBase: Services.io.newURI(".", null, uri).spec
- },
- doc: new XMLSerializer().serializeToString(doc)
- });
- } catch (e) {
- reject("Reader: could not build Readability arguments: " + e);
- }
- });
- },
-
_downloadDocument: function (url) {
return new Promise((resolve, reject) => {
// We want to parse those arbitrary pages safely, outside the privileged
@@ -344,7 +181,6 @@ let Reader = {
return;
}
- this.log("Done loading: " + doc);
if (doc.location.href == "about:blank") {
reject("about:blank loaded; aborting");
@@ -362,65 +198,17 @@ let Reader = {
},
_downloadAndParseDocument: Task.async(function* (url) {
- this.log("Needs to fetch page, creating request: " + url);
let { browser, doc } = yield this._downloadDocument(url);
- this.log("Finished loading page: " + doc);
try {
let uri = Services.io.newURI(url, null, null);
- let article = yield this._readerParse(uri, doc);
- this.log("Document parsed successfully");
+ let article = yield ReaderMode.readerParse(uri, doc);
return article;
} finally {
browser.parentNode.removeChild(browser);
}
}),
- get _cryptoHash() {
- delete this._cryptoHash;
- return this._cryptoHash = Cc["@mozilla.org/security/hash;1"].createInstance(Ci.nsICryptoHash);
- },
-
- get _unicodeConverter() {
- delete this._unicodeConverter;
- this._unicodeConverter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
- .createInstance(Ci.nsIScriptableUnicodeConverter);
- this._unicodeConverter.charset = "utf8";
- return this._unicodeConverter;
- },
-
- /**
- * Calculate the hashed path for a stripped article URL.
- *
- * @param url The article URL. This should have referrers removed.
- * @return The file path to the cached article.
- */
- _toHashedPath: function (url) {
- let value = this._unicodeConverter.convertToByteArray(url);
- this._cryptoHash.init(this._cryptoHash.MD5);
- this._cryptoHash.update(value, value.length);
-
- let hash = CommonUtils.encodeBase32(this._cryptoHash.finish(false));
- let fileName = hash.substring(0, hash.indexOf("=")) + ".json";
- return OS.Path.join(OS.Constants.Path.profileDir, "readercache", fileName);
- },
-
- /**
- * Ensures the cache directory exists.
- *
- * @return Promise
- * @resolves When the cache directory exists.
- * @rejects OS.File.Error
- */
- _ensureCacheDir: function () {
- let dir = OS.Path.join(OS.Constants.Path.profileDir, "readercache");
- return OS.File.exists(dir).then(exists => {
- if (!exists) {
- return OS.File.makeDir(dir);
- }
- });
- },
-
/**
* Migrates old indexedDB reader mode cache to new JSON cache.
*/
@@ -458,7 +246,7 @@ let Reader = {
});
for (let article of articles) {
- yield this.storeArticleInCache(article);
+ yield ReaderMode.storeArticleInCache(article);
}
// Delete the database.
diff --git a/mobile/android/chrome/content/browser.js b/mobile/android/chrome/content/browser.js
index fb2e15894d87..535adc80b0df 100644
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -109,11 +109,14 @@ XPCOMUtils.defineLazyModuleGetter(this, "SharedPreferences",
XPCOMUtils.defineLazyModuleGetter(this, "Notifications",
"resource://gre/modules/Notifications.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "ReaderMode",
+ "resource://gre/modules/ReaderMode.jsm");
+
// Lazily-loaded browser scripts:
[
["SelectHelper", "chrome://browser/content/SelectHelper.js"],
["InputWidgetHelper", "chrome://browser/content/InputWidgetHelper.js"],
- ["AboutReader", "chrome://browser/content/aboutReader.js"],
+ ["AboutReader", "chrome://global/content/reader/aboutReader.js"],
["MasterPassword", "chrome://browser/content/MasterPassword.js"],
["PluginHelper", "chrome://browser/content/PluginHelper.js"],
["OfflineApps", "chrome://browser/content/OfflineApps.js"],
@@ -4282,7 +4285,7 @@ Tab.prototype = {
Reader.updatePageAction(this);
// Once document is fully loaded, parse it
- Reader.parseDocumentFromTab(this).then(article => {
+ ReaderMode.parseDocumentFromBrowser(this.browser).then(article => {
// The loaded page may have changed while we were parsing the document.
// Make sure we've got the current one.
let currentURL = this.browser.currentURI.specIgnoringRef;
diff --git a/mobile/android/chrome/jar.mn b/mobile/android/chrome/jar.mn
index 1560a2dc6b76..f87d6c6384e9 100644
--- a/mobile/android/chrome/jar.mn
+++ b/mobile/android/chrome/jar.mn
@@ -19,12 +19,7 @@ chrome.jar:
content/aboutFeedback.js (content/aboutFeedback.js)
content/aboutPrivateBrowsing.xhtml (content/aboutPrivateBrowsing.xhtml)
content/aboutPrivateBrowsing.js (content/aboutPrivateBrowsing.js)
- content/aboutReader.html (content/aboutReader.html)
- content/aboutReader.js (content/aboutReader.js)
- content/Readability.js (content/Readability.js)
content/Reader.js (content/Reader.js)
- content/JSDOMParser.js (content/JSDOMParser.js)
- content/readerWorker.js (content/readerWorker.js)
content/aboutHome.xhtml (content/aboutHome.xhtml)
content/aboutRights.xhtml (content/aboutRights.xhtml)
* content/aboutApps.xhtml (content/aboutApps.xhtml)
diff --git a/mobile/android/components/AboutRedirector.js b/mobile/android/components/AboutRedirector.js
index 137acd07ca18..e197f474e454 100644
--- a/mobile/android/components/AboutRedirector.js
+++ b/mobile/android/components/AboutRedirector.js
@@ -60,7 +60,7 @@ let modules = {
privileged: true
},
reader: {
- uri: "chrome://browser/content/aboutReader.html",
+ uri: "chrome://global/content/reader/aboutReader.html",
privileged: false,
hide: true
},
diff --git a/mobile/android/components/SessionStore.js b/mobile/android/components/SessionStore.js
index 30a016976d5a..34cc208b6b0c 100644
--- a/mobile/android/components/SessionStore.js
+++ b/mobile/android/components/SessionStore.js
@@ -86,6 +86,7 @@ SessionStore.prototype = {
observerService.addObserver(this, "ClosedTabs:StartNotifications", true);
observerService.addObserver(this, "ClosedTabs:StopNotifications", true);
observerService.addObserver(this, "last-pb-context-exited", true);
+ observerService.addObserver(this, "Session:RestoreRecentTabs", true);
break;
case "final-ui-startup":
observerService.removeObserver(this, "final-ui-startup");
@@ -176,6 +177,11 @@ SessionStore.prototype = {
}
this._lastClosedTabIndex = -1;
break;
+ case "Session:RestoreRecentTabs": {
+ let data = JSON.parse(aData);
+ this._restoreTabsWithHistory(data);
+ break;
+ }
}
},
@@ -758,7 +764,23 @@ SessionStore.prototype = {
return shEntry;
},
- _restoreHistory: function _restoreHistory(aTabData, aHistory) {
+ // This function iterates through a list of tab data restoring history for each of them.
+ _restoreTabsWithHistory: function ss_restoreTabsWithHistory(data) {
+ let window = Services.wm.getMostRecentWindow("navigator:browser");
+ for (let i = 0; i < data.tabs.length; i++) {
+ let tabData = JSON.parse(data.tabs[i]);
+ let params = {
+ selected: (i == data.tabs.length - 1),
+ isPrivate: tabData.isPrivate,
+ desktopMode: tabData.desktopMode,
+ };
+
+ let tab = window.BrowserApp.addTab(tabData.entries[tabData.index - 1].url, params);
+ this._restoreHistory(tabData, tab.browser.sessionHistory);
+ }
+ },
+
+ _restoreHistory: function ss_restoreHistory(aTabData, aHistory) {
if (aHistory.count > 0)
aHistory.PurgeHistory(aHistory.count);
aHistory.QueryInterface(Ci.nsISHistoryInternal);
@@ -934,7 +956,8 @@ SessionStore.prototype = {
let lastEntry = tab.entries[tab.entries.length - 1];
return {
url: lastEntry.url,
- title: lastEntry.title || ""
+ title: lastEntry.title || "",
+ data: tab
};
});
diff --git a/mobile/android/locales/jar.mn b/mobile/android/locales/jar.mn
index 34b5569b1959..1632455d8258 100644
--- a/mobile/android/locales/jar.mn
+++ b/mobile/android/locales/jar.mn
@@ -20,7 +20,6 @@
locale/@AB_CD@/browser/aboutHome.dtd (%chrome/aboutHome.dtd)
locale/@AB_CD@/browser/aboutHome.properties (%chrome/aboutHome.properties)
locale/@AB_CD@/browser/aboutPrivateBrowsing.dtd (%chrome/aboutPrivateBrowsing.dtd)
- locale/@AB_CD@/browser/aboutReader.properties (%chrome/aboutReader.properties)
#ifdef MOZ_SERVICES_HEALTHREPORT
locale/@AB_CD@/browser/aboutHealthReport.dtd (%chrome/aboutHealthReport.dtd)
#endif
diff --git a/mobile/android/themes/core/jar.mn b/mobile/android/themes/core/jar.mn
index 8472579a149f..2df29526258d 100644
--- a/mobile/android/themes/core/jar.mn
+++ b/mobile/android/themes/core/jar.mn
@@ -30,6 +30,7 @@ chrome.jar:
skin/netError.css (netError.css)
% override chrome://global/skin/about.css chrome://browser/skin/about.css
% override chrome://global/skin/aboutMemory.css chrome://browser/skin/aboutMemory.css
+% override chrome://global/skin/aboutReader.css chrome://browser/skin/aboutReader.css
% override chrome://global/skin/aboutSupport.css chrome://browser/skin/aboutSupport.css
% override chrome://global/skin/media/videocontrols.css chrome://browser/skin/touchcontrols.css
% override chrome://global/skin/netError.css chrome://browser/skin/netError.css
diff --git a/other-licenses/android/getaddrinfo.c b/other-licenses/android/getaddrinfo.c
index 7edabbc2d057..c2267b6c0958 100644
--- a/other-licenses/android/getaddrinfo.c
+++ b/other-licenses/android/getaddrinfo.c
@@ -414,6 +414,14 @@ extern int
__wrap_getaddrinfo(const char *hostname, const char *servname,
const struct addrinfo *hints, struct addrinfo **res);
+extern const char *
+__real_gai_strerror(int ecode);
+extern void
+__real_freeaddrinfo(struct addrinfo *ai);
+extern int
+__real_getaddrinfo(const char *hostname, const char *servname,
+ const struct addrinfo *hints, struct addrinfo **res);
+
int android_sdk_version;
#pragma GCC visibility pop
@@ -434,7 +442,7 @@ const char *
__wrap_gai_strerror(int ecode)
{
if (honeycomb_or_later())
- return gai_strerror(ecode);
+ return __real_gai_strerror(ecode);
if (ecode < 0 || ecode > EAI_MAX)
ecode = EAI_MAX;
return ai_errlist[ecode];
@@ -446,7 +454,7 @@ __wrap_freeaddrinfo(struct addrinfo *ai)
struct addrinfo *next;
if (honeycomb_or_later()) {
- freeaddrinfo(ai);
+ __real_freeaddrinfo(ai);
return;
}
@@ -545,7 +553,7 @@ __wrap_getaddrinfo(const char *hostname, const char *servname,
const struct explore *ex;
if (honeycomb_or_later())
- return getaddrinfo(hostname, servname, hints, res);
+ return __real_getaddrinfo(hostname, servname, hints, res);
/* hostname is allowed to be NULL */
/* servname is allowed to be NULL */
diff --git a/testing/profiles/prefs_general.js b/testing/profiles/prefs_general.js
index b6495975310b..3e3080ced0bc 100644
--- a/testing/profiles/prefs_general.js
+++ b/testing/profiles/prefs_general.js
@@ -251,6 +251,8 @@ user_pref("browser.aboutHomeSnippets.updateUrl", "nonexistent://test");
// Enable debug logging in the mozApps implementation.
user_pref("dom.mozApps.debug", true);
+// Enable apps customizations
+user_pref("dom.apps.customization.enabled", true);
// Don't fetch or send directory tiles data from real servers
user_pref("browser.newtabpage.directory.source", 'data:application/json,{"testing":1}');
diff --git a/testing/specialpowers/content/SpecialPowersObserverAPI.js b/testing/specialpowers/content/SpecialPowersObserverAPI.js
index 3ea7fba54120..4cdb2402510e 100644
--- a/testing/specialpowers/content/SpecialPowersObserverAPI.js
+++ b/testing/specialpowers/content/SpecialPowersObserverAPI.js
@@ -353,6 +353,13 @@ SpecialPowersObserverAPI.prototype = {
let val = Webapps.DOMApplicationRegistry.allAppsLaunchable;
Webapps.DOMApplicationRegistry.allAppsLaunchable = aMessage.json.launchable;
return val;
+ case "allow-unsigned-addons":
+ {
+ let utils = {};
+ Components.utils.import("resource://gre/modules/AppsUtils.jsm", utils);
+ utils.AppsUtils.allowUnsignedAddons = true;
+ return;
+ }
default:
throw new SpecialPowersException("Invalid operation for SPWebAppsService");
}
diff --git a/testing/specialpowers/content/specialpowersAPI.js b/testing/specialpowers/content/specialpowersAPI.js
index 0687eb99a41a..8d6c6b611841 100644
--- a/testing/specialpowers/content/specialpowersAPI.js
+++ b/testing/specialpowers/content/specialpowersAPI.js
@@ -1099,6 +1099,13 @@ SpecialPowersAPI.prototype = {
});
},
+ // Allow tests to install addons without signing the package, for convenience.
+ allowUnsignedAddons: function() {
+ this._sendSyncMessage("SPWebAppService", {
+ op: "allow-unsigned-addons"
+ });
+ },
+
// Restore the launchable property to its default value.
flushAllAppsLaunchable: function() {
this._sendSyncMessage("SPWebAppService", {
diff --git a/toolkit/components/autocomplete/nsAutoCompleteController.cpp b/toolkit/components/autocomplete/nsAutoCompleteController.cpp
index 5d15421cfef9..bb0df56f5ce9 100644
--- a/toolkit/components/autocomplete/nsAutoCompleteController.cpp
+++ b/toolkit/components/autocomplete/nsAutoCompleteController.cpp
@@ -52,7 +52,8 @@ nsAutoCompleteController::nsAutoCompleteController() :
mSearchesOngoing(0),
mSearchesFailed(0),
mFirstSearchResult(false),
- mImmediateSearchesCount(0)
+ mImmediateSearchesCount(0),
+ mCompletedSelectionIndex(-1)
{
}
@@ -122,6 +123,7 @@ nsAutoCompleteController::SetInput(nsIAutoCompleteInput *aInput)
mSearchStatus = nsIAutoCompleteController::STATUS_NONE;
mRowCount = 0;
mSearchesOngoing = 0;
+ mCompletedSelectionIndex = -1;
// Initialize our list of search objects
uint32_t searchCount;
@@ -421,10 +423,12 @@ nsAutoCompleteController::HandleKeyNavigation(uint32_t aKey, bool *_retval)
input->SetTextValue(value);
input->SelectTextRange(value.Length(), value.Length());
}
+ mCompletedSelectionIndex = selectedIndex;
} else {
// Nothing is selected, so fill in the last typed value
input->SetTextValue(mSearchString);
input->SelectTextRange(mSearchString.Length(), mSearchString.Length());
+ mCompletedSelectionIndex = -1;
}
}
} else {
@@ -1244,17 +1248,29 @@ nsAutoCompleteController::EnterMatch(bool aIsPopupSelection)
int32_t selectedIndex;
popup->GetSelectedIndex(&selectedIndex);
if (selectedIndex >= 0) {
+ nsAutoString finalValue;
// If completeselectedindex is false or a row was selected from the popup,
- // enter it into the textbox. If completeselectedindex is true, or
- // EnterMatch was called via other means, for instance pressing Enter,
- // don't fill in the value as it will have already been filled in as
- // needed, unless the final complete value differs.
- nsAutoString finalValue, inputValue;
- GetResultValueAt(selectedIndex, true, finalValue);
- input->GetTextValue(inputValue);
- if (!completeSelection || aIsPopupSelection ||
- !finalValue.Equals(inputValue)) {
+ // enter it into the textbox.
+ if (!completeSelection || aIsPopupSelection) {
+ GetResultValueAt(selectedIndex, true, finalValue);
value = finalValue;
+ } else if (mCompletedSelectionIndex != -1) {
+ // If completeselectedindex is true, and EnterMatch was not invoked by
+ // mouse-clicking a match (for example the user pressed Enter),
+ // don't fill in the value as it will have already been filled in as
+ // needed, unless the selected match has a final complete value that
+ // differs from the user-facing value.
+ GetResultValueAt(mCompletedSelectionIndex, true, finalValue);
+ nsAutoString inputValue;
+ input->GetTextValue(inputValue);
+ if (!finalValue.Equals(inputValue)) {
+ value = finalValue;
+ }
+ // Note that if the user opens the popup, mouses over entries without
+ // ever selecting one with the keyboard, and then hits enter, none of
+ // the above cases will be hitt, since mouseover doesn't activate
+ // completeselectedindex and thus mCompletedSelectionIndex would be
+ // -1.
}
}
else if (shouldComplete) {
diff --git a/toolkit/components/autocomplete/nsAutoCompleteController.h b/toolkit/components/autocomplete/nsAutoCompleteController.h
index 556d5eb68cb4..f96e55f3ab6b 100644
--- a/toolkit/components/autocomplete/nsAutoCompleteController.h
+++ b/toolkit/components/autocomplete/nsAutoCompleteController.h
@@ -151,6 +151,14 @@ protected:
uint32_t mSearchesFailed;
bool mFirstSearchResult;
uint32_t mImmediateSearchesCount;
+ // The index of the match on the popup that was selected using the keyboard,
+ // if the completeselectedindex attribute is set.
+ // This is used to distinguish that selection (which would have been put in
+ // the input on being selected) from a moused-over selectedIndex value. This
+ // distinction is used to prevent mouse moves from inadvertently changing
+ // what happens once the user hits Enter on the keyboard.
+ // See bug 1043584 for more details.
+ int32_t mCompletedSelectionIndex;
};
#endif /* __nsAutoCompleteController__ */
diff --git a/toolkit/components/autocomplete/tests/unit/test_finalCompleteValue.js b/toolkit/components/autocomplete/tests/unit/test_finalCompleteValue.js
index 8607809eb8e2..27304d03aab4 100644
--- a/toolkit/components/autocomplete/tests/unit/test_finalCompleteValue.js
+++ b/toolkit/components/autocomplete/tests/unit/test_finalCompleteValue.js
@@ -1,7 +1,3 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
function AutoCompleteResult(aValues, aFinalCompleteValues) {
this._values = aValues;
this._finalCompleteValues = aFinalCompleteValues;
diff --git a/toolkit/components/autocomplete/tests/unit/test_finalCompleteValueSelectedIndex.js b/toolkit/components/autocomplete/tests/unit/test_finalCompleteValueSelectedIndex.js
new file mode 100644
index 000000000000..a1fcf158f01f
--- /dev/null
+++ b/toolkit/components/autocomplete/tests/unit/test_finalCompleteValueSelectedIndex.js
@@ -0,0 +1,97 @@
+function AutoCompleteResult(aResultValues) {
+ this._values = aResultValues.map(x => x[0]);
+ this._finalCompleteValues = aResultValues.map(x => x[1]);
+}
+AutoCompleteResult.prototype = Object.create(AutoCompleteResultBase.prototype);
+
+let selectByWasCalled = false;
+function AutoCompleteInput(aSearches) {
+ this.searches = aSearches;
+ this.popup.selectedIndex = 0;
+ this.popup.selectBy = function(reverse, page) {
+ Assert.equal(selectByWasCalled, false);
+ selectByWasCalled = true;
+ Assert.equal(reverse, false);
+ Assert.equal(page, false);
+ this.selectedIndex += (reverse ? -1 : 1) * (page ? 100 : 1);
+ };
+ this.completeSelectedIndex = true;
+}
+AutoCompleteInput.prototype = Object.create(AutoCompleteInputBase.prototype);
+
+function run_test() {
+ run_next_test();
+}
+
+add_test(function test_handleEnter() {
+ let results = [
+ ["mozilla.com", "http://www.mozilla.com"],
+ ["mozilla.org", "http://www.mozilla.org"],
+ ];
+ // First check the case where we do select a value with the keyboard:
+ doSearch("moz", results, function(aController) {
+ Assert.equal(aController.input.textValue, "moz");
+ Assert.equal(aController.getFinalCompleteValueAt(0), "http://www.mozilla.com");
+ Assert.equal(aController.getFinalCompleteValueAt(1), "http://www.mozilla.org");
+
+ Assert.equal(aController.input.popup.selectedIndex, 0);
+ aController.handleKeyNavigation(Ci.nsIDOMKeyEvent.DOM_VK_DOWN);
+ Assert.equal(aController.input.popup.selectedIndex, 1);
+ // Simulate mouse interaction changing selectedIndex
+ // ie NOT keyboard interaction:
+ aController.input.popup.selectedIndex = 0;
+
+ aController.handleEnter(false);
+ // Verify that the keyboard-selected thing got inserted,
+ // and not the mouse selection:
+ Assert.equal(aController.input.textValue, "http://www.mozilla.org");
+ });
+
+ // Then the case where we do not:
+ doSearch("moz", results, function(aController) {
+ Assert.equal(aController.input.textValue, "moz");
+ Assert.equal(aController.getFinalCompleteValueAt(0), "http://www.mozilla.com");
+ Assert.equal(aController.getFinalCompleteValueAt(1), "http://www.mozilla.org");
+
+ Assert.equal(aController.input.popup.selectedIndex, 0);
+ aController.input.popupOpen = true;
+ // Simulate mouse interaction changing selectedIndex
+ // ie NOT keyboard interaction:
+ aController.input.popup.selectedIndex = 1;
+ Assert.equal(selectByWasCalled, false);
+ Assert.equal(aController.input.popup.selectedIndex, 1);
+
+ aController.handleEnter(false);
+ // Verify that the input stayed the same, because no selection was made
+ // with the keyboard:
+ Assert.equal(aController.input.textValue, "moz");
+ });
+});
+
+function doSearch(aSearchString, aResults, aOnCompleteCallback) {
+ selectByWasCalled = false;
+ let search = new AutoCompleteSearchBase(
+ "search",
+ new AutoCompleteResult(aResults)
+ );
+ registerAutoCompleteSearch(search);
+
+ let controller = Cc["@mozilla.org/autocomplete/controller;1"].
+ getService(Ci.nsIAutoCompleteController);
+
+ // Make an AutoCompleteInput that uses our searches and confirms results.
+ let input = new AutoCompleteInput([ search.name ]);
+ input.textValue = aSearchString;
+
+ controller.input = input;
+ controller.startSearch(aSearchString);
+
+ input.onSearchComplete = function onSearchComplete() {
+ aOnCompleteCallback(controller);
+
+ // Clean up.
+ unregisterAutoCompleteSearch(search);
+ run_next_test();
+ };
+}
+
diff --git a/toolkit/components/autocomplete/tests/unit/xpcshell.ini b/toolkit/components/autocomplete/tests/unit/xpcshell.ini
index 86ac0df84f83..7f0ba577e6f3 100644
--- a/toolkit/components/autocomplete/tests/unit/xpcshell.ini
+++ b/toolkit/components/autocomplete/tests/unit/xpcshell.ini
@@ -14,6 +14,7 @@ skip-if = toolkit == 'gonk'
[test_completeDefaultIndex_casing.js]
[test_finalCompleteValue.js]
[test_finalCompleteValue_forceComplete.js]
+[test_finalCompleteValueSelectedIndex.js]
[test_finalDefaultCompleteValue.js]
[test_hiddenResult.js]
[test_immediate_search.js]
diff --git a/toolkit/components/moz.build b/toolkit/components/moz.build
index f54634b2fc58..f5e3bdc3b36f 100644
--- a/toolkit/components/moz.build
+++ b/toolkit/components/moz.build
@@ -40,6 +40,7 @@ DIRS += [
'promiseworker',
'prompts',
'protobuf',
+ 'reader',
'reflect',
'sqlite',
'startup',
diff --git a/toolkit/components/reader/ReaderMode.jsm b/toolkit/components/reader/ReaderMode.jsm
new file mode 100644
index 000000000000..555a4ce50cb6
--- /dev/null
+++ b/toolkit/components/reader/ReaderMode.jsm
@@ -0,0 +1,236 @@
+// -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+"use strict";
+
+this.EXPORTED_SYMBOLS = ["ReaderMode"];
+
+const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
+
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+Cu.importGlobalProperties(["XMLHttpRequest"]);
+
+XPCOMUtils.defineLazyModuleGetter(this, "CommonUtils", "resource://services-common/utils.js");
+XPCOMUtils.defineLazyModuleGetter(this, "OS", "resource://gre/modules/osfile.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Task", "resource://gre/modules/Task.jsm");
+
+let ReaderMode = {
+ // Version of the cache schema.
+ CACHE_VERSION: 1,
+
+ DEBUG: 0,
+
+ // Don't try to parse the page if it has too many elements (for memory and
+ // performance reasons)
+ MAX_ELEMS_TO_PARSE: 3000,
+
+ observe: function(aMessage, aTopic, aData) {
+ switch(aTopic) {
+ case "nsPref:changed": {
+ if (aData.startsWith("reader.parse-on-load.")) {
+ this.isEnabledForParseOnLoad = this._getStateForParseOnLoad();
+ }
+ break;
+ }
+ }
+ },
+
+ /**
+ * Gets an article from a loaded browser's document. This method will parse the document
+ * if it does not find the article in the cache.
+ *
+ * @param browser A browser with a loaded page.
+ * @return {Promise}
+ * @resolves JS object representing the article, or null if no article is found.
+ */
+ parseDocumentFromBrowser: Task.async(function* (browser) {
+ let uri = browser.currentURI;
+ if (!this._shouldCheckUri(uri)) {
+ this.log("Reader mode disabled for URI");
+ return null;
+ }
+
+ // First, try to find a parsed article in the cache.
+ let article = yield this.getArticleFromCache(uri);
+ if (article) {
+ this.log("Page found in cache, return article immediately");
+ return article;
+ }
+
+ let doc = browser.contentWindow.document;
+ return yield this.readerParse(uri, doc);
+ }),
+
+ /**
+ * Retrieves an article from the cache given an article URI.
+ *
+ * @param uri The article URI.
+ * @return {Promise}
+ * @resolves JS object representing the article, or null if no article is found.
+ * @rejects OS.File.Error
+ */
+ getArticleFromCache: Task.async(function* (uri) {
+ let path = this._toHashedPath(uri.specIgnoringRef);
+ try {
+ let array = yield OS.File.read(path);
+ return JSON.parse(new TextDecoder().decode(array));
+ } catch (e if e instanceof OS.File.Error && e.becauseNoSuchFile) {
+ return null;
+ }
+ }),
+
+ /**
+ * Stores an article in the cache.
+ *
+ * @param article JS object representing article.
+ * @return {Promise}
+ * @resolves When the article is stored.
+ * @rejects OS.File.Error
+ */
+ storeArticleInCache: Task.async(function* (article) {
+ let array = new TextEncoder().encode(JSON.stringify(article));
+ let path = this._toHashedPath(article.url);
+ yield this._ensureCacheDir();
+ yield OS.File.writeAtomic(path, array, { tmpPath: path + ".tmp" });
+ }),
+
+ /**
+ * Removes an article from the cache given an article URI.
+ *
+ * @param uri The article URI.
+ * @return {Promise}
+ * @resolves When the article is removed.
+ * @rejects OS.File.Error
+ */
+ removeArticleFromCache: Task.async(function* (uri) {
+ let path = this._toHashedPath(uri.specIgnoringRef);
+ yield OS.File.remove(path);
+ }),
+
+ log: function(msg) {
+ if (this.DEBUG)
+ dump("Reader: " + msg);
+ },
+
+ _shouldCheckUri: function (uri) {
+ if ((uri.prePath + "/") === uri.spec) {
+ this.log("Not parsing home page: " + uri.spec);
+ return false;
+ }
+
+ if (!(uri.schemeIs("http") || uri.schemeIs("https") || uri.schemeIs("file"))) {
+ this.log("Not parsing URI scheme: " + uri.scheme);
+ return false;
+ }
+
+ return true;
+ },
+
+ /**
+ * Attempts to parse a document into an article. Heavy lifting happens
+ * in readerWorker.js.
+ *
+ * @param uri The article URI.
+ * @param doc The document to parse.
+ * @return {Promise}
+ * @resolves JS object representing the article, or null if no article is found.
+ */
+ readerParse: function (uri, doc) {
+ return new Promise((resolve, reject) => {
+ let numTags = doc.getElementsByTagName("*").length;
+ if (numTags > this.MAX_ELEMS_TO_PARSE) {
+ this.log("Aborting parse for " + uri.spec + "; " + numTags + " elements found");
+ resolve(null);
+ return;
+ }
+
+ let worker = new ChromeWorker("chrome://global/content/reader/readerWorker.js");
+ worker.onmessage = evt => {
+ let article = evt.data;
+
+ if (!article) {
+ this.log("Worker did not return an article");
+ resolve(null);
+ return;
+ }
+
+ // Append URL to the article data. specIgnoringRef will ignore any hash
+ // in the URL.
+ article.url = uri.specIgnoringRef;
+ let flags = Ci.nsIDocumentEncoder.OutputSelectionOnly | Ci.nsIDocumentEncoder.OutputAbsoluteLinks;
+ article.title = Cc["@mozilla.org/parserutils;1"].getService(Ci.nsIParserUtils)
+ .convertToPlainText(article.title, flags, 0);
+ resolve(article);
+ };
+
+ worker.onerror = evt => {
+ reject("Error in worker: " + evt.message);
+ };
+
+ try {
+ let serializer = Cc["@mozilla.org/xmlextras/xmlserializer;1"].
+ createInstance(Ci.nsIDOMSerializer);
+ worker.postMessage({
+ uri: {
+ spec: uri.spec,
+ host: uri.host,
+ prePath: uri.prePath,
+ scheme: uri.scheme,
+ pathBase: Services.io.newURI(".", null, uri).spec
+ },
+ doc: serializer.serializeToString(doc)
+ });
+ } catch (e) {
+ reject("Reader: could not build Readability arguments: " + e);
+ }
+ });
+ },
+
+ get _cryptoHash() {
+ delete this._cryptoHash;
+ return this._cryptoHash = Cc["@mozilla.org/security/hash;1"].createInstance(Ci.nsICryptoHash);
+ },
+
+ get _unicodeConverter() {
+ delete this._unicodeConverter;
+ this._unicodeConverter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
+ .createInstance(Ci.nsIScriptableUnicodeConverter);
+ this._unicodeConverter.charset = "utf8";
+ return this._unicodeConverter;
+ },
+
+ /**
+ * Calculate the hashed path for a stripped article URL.
+ *
+ * @param url The article URL. This should have referrers removed.
+ * @return The file path to the cached article.
+ */
+ _toHashedPath: function (url) {
+ let value = this._unicodeConverter.convertToByteArray(url);
+ this._cryptoHash.init(this._cryptoHash.MD5);
+ this._cryptoHash.update(value, value.length);
+
+ let hash = CommonUtils.encodeBase32(this._cryptoHash.finish(false));
+ let fileName = hash.substring(0, hash.indexOf("=")) + ".json";
+ return OS.Path.join(OS.Constants.Path.profileDir, "readercache", fileName);
+ },
+
+ /**
+ * Ensures the cache directory exists.
+ *
+ * @return Promise
+ * @resolves When the cache directory exists.
+ * @rejects OS.File.Error
+ */
+ _ensureCacheDir: function () {
+ let dir = OS.Path.join(OS.Constants.Path.profileDir, "readercache");
+ return OS.File.exists(dir).then(exists => {
+ if (!exists) {
+ return OS.File.makeDir(dir);
+ }
+ });
+ }
+};
diff --git a/mobile/android/chrome/content/JSDOMParser.js b/toolkit/components/reader/content/JSDOMParser.js
similarity index 100%
rename from mobile/android/chrome/content/JSDOMParser.js
rename to toolkit/components/reader/content/JSDOMParser.js
diff --git a/mobile/android/chrome/content/Readability.js b/toolkit/components/reader/content/Readability.js
similarity index 100%
rename from mobile/android/chrome/content/Readability.js
rename to toolkit/components/reader/content/Readability.js
diff --git a/toolkit/components/reader/content/ReaderMode.jsm b/toolkit/components/reader/content/ReaderMode.jsm
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/mobile/android/chrome/content/aboutReader.html b/toolkit/components/reader/content/aboutReader.html
similarity index 92%
rename from mobile/android/chrome/content/aboutReader.html
rename to toolkit/components/reader/content/aboutReader.html
index 731ba3739985..22ef846ef9ac 100644
--- a/mobile/android/chrome/content/aboutReader.html
+++ b/toolkit/components/reader/content/aboutReader.html
@@ -5,7 +5,7 @@
-
+
diff --git a/mobile/android/chrome/content/aboutReader.js b/toolkit/components/reader/content/aboutReader.js
similarity index 99%
rename from mobile/android/chrome/content/aboutReader.js
rename to toolkit/components/reader/content/aboutReader.js
index 8ea53c0c014a..d380cb9cf66d 100644
--- a/mobile/android/chrome/content/aboutReader.js
+++ b/toolkit/components/reader/content/aboutReader.js
@@ -24,7 +24,7 @@ function dump(s) {
Services.console.logStringMessage("AboutReader: " + s);
}
-let gStrings = Services.strings.createBundle("chrome://browser/locale/aboutReader.properties");
+let gStrings = Services.strings.createBundle("chrome://global/locale/aboutReader.properties");
let AboutReader = function(doc, win) {
dump("Init()");
diff --git a/mobile/android/chrome/content/readerWorker.js b/toolkit/components/reader/content/readerWorker.js
similarity index 100%
rename from mobile/android/chrome/content/readerWorker.js
rename to toolkit/components/reader/content/readerWorker.js
diff --git a/toolkit/components/reader/jar.mn b/toolkit/components/reader/jar.mn
new file mode 100644
index 000000000000..a8c21fc582d4
--- /dev/null
+++ b/toolkit/components/reader/jar.mn
@@ -0,0 +1,10 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+toolkit.jar:
+ content/global/reader/aboutReader.html (content/aboutReader.html)
+ content/global/reader/aboutReader.js (content/aboutReader.js)
+ content/global/reader/Readability.js (content/Readability.js)
+ content/global/reader/JSDOMParser.js (content/JSDOMParser.js)
+ content/global/reader/readerWorker.js (content/readerWorker.js)
diff --git a/toolkit/components/reader/moz.build b/toolkit/components/reader/moz.build
new file mode 100644
index 000000000000..fd4ec038a70b
--- /dev/null
+++ b/toolkit/components/reader/moz.build
@@ -0,0 +1,11 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+JAR_MANIFESTS += ['jar.mn']
+
+EXTRA_JS_MODULES += [
+ 'ReaderMode.jsm'
+]
diff --git a/toolkit/components/search/nsSearchService.js b/toolkit/components/search/nsSearchService.js
index ceb59ff122fd..775e1af1e96f 100644
--- a/toolkit/components/search/nsSearchService.js
+++ b/toolkit/components/search/nsSearchService.js
@@ -404,6 +404,15 @@ loadListener.prototype = {
// Hacky method that tries to determine if this user is in a US geography, and
// using an en-US build.
function getIsUS() {
+ let geoSpecificDefaults = false;
+ try {
+ geoSpecificDefaults = Services.prefs.getBoolPref("browser.search.geoSpecificDefaults");
+ } catch(e) {}
+
+ if (!geoSpecificDefaults) {
+ return false;
+ }
+
// If we've set the pref before, just return that result.
let cachePref = "browser.search.isUS";
try {
diff --git a/toolkit/devtools/client/dbg-client.jsm b/toolkit/devtools/client/dbg-client.jsm
index a7f559a1beb8..92d1afc41761 100644
--- a/toolkit/devtools/client/dbg-client.jsm
+++ b/toolkit/devtools/client/dbg-client.jsm
@@ -234,7 +234,8 @@ const UnsolicitedNotifications = {
"appOpen": "appOpen",
"appClose": "appClose",
"appInstall": "appInstall",
- "appUninstall": "appUninstall"
+ "appUninstall": "appUninstall",
+ "evaluationResult": "evaluationResult",
};
/**
diff --git a/toolkit/devtools/server/actors/webconsole.js b/toolkit/devtools/server/actors/webconsole.js
index 6a499e35494e..b52f6acb5159 100644
--- a/toolkit/devtools/server/actors/webconsole.js
+++ b/toolkit/devtools/server/actors/webconsole.js
@@ -728,6 +728,39 @@ WebConsoleActor.prototype =
};
},
+ /**
+ * Handler for the "evaluateJSAsync" request. This method evaluates the given
+ * JavaScript string and sends back a packet with a unique ID.
+ * The result will be returned later as an unsolicited `evaluationResult`,
+ * that can be associated back to this request via the `resultID` field.
+ *
+ * @param object aRequest
+ * The JSON request object received from the Web Console client.
+ * @return object
+ * The response packet to send to with the unique id in the
+ * `resultID` field.
+ */
+ onEvaluateJSAsync: function WCA_onEvaluateJSAsync(aRequest)
+ {
+ // We want to be able to run console commands without waiting
+ // for the first to return (see Bug 1088861).
+
+ // First, send a response packet with the id only.
+ let resultID = Date.now();
+ this.conn.send({
+ from: this.actorID,
+ resultID: resultID
+ });
+
+ // Then, execute the script that may pause.
+ let response = this.onEvaluateJS(aRequest);
+ response.resultID = resultID;
+
+ // Finally, send an unsolicited evaluationResult packet with
+ // the normal return value
+ this.conn.sendActorEvent(this.actorID, "evaluationResult", response);
+ },
+
/**
* Handler for the "evaluateJS" request. This method evaluates the given
* JavaScript string and sends back the result.
@@ -1471,6 +1504,7 @@ WebConsoleActor.prototype.requestTypes =
stopListeners: WebConsoleActor.prototype.onStopListeners,
getCachedMessages: WebConsoleActor.prototype.onGetCachedMessages,
evaluateJS: WebConsoleActor.prototype.onEvaluateJS,
+ evaluateJSAsync: WebConsoleActor.prototype.onEvaluateJSAsync,
autocomplete: WebConsoleActor.prototype.onAutocomplete,
clearMessagesCache: WebConsoleActor.prototype.onClearMessagesCache,
getPreferences: WebConsoleActor.prototype.onGetPreferences,
diff --git a/toolkit/devtools/webconsole/client.js b/toolkit/devtools/webconsole/client.js
index f1eb08980adf..e50577e833c5 100644
--- a/toolkit/devtools/webconsole/client.js
+++ b/toolkit/devtools/webconsole/client.js
@@ -7,6 +7,7 @@
"use strict";
const {Cc, Ci, Cu} = require("chrome");
+const DevToolsUtils = require("devtools/toolkit/DevToolsUtils");
loader.lazyImporter(this, "LongStringClient", "resource://gre/modules/devtools/dbg-client.jsm");
@@ -27,7 +28,13 @@ function WebConsoleClient(aDebuggerClient, aResponse)
this._longStrings = {};
this.traits = aResponse.traits || {};
this.events = [];
+
+ this.pendingEvaluationResults = new Map();
+ this.onEvaluationResult = this.onEvaluationResult.bind(this);
+
+ this._client.addListener("evaluationResult", this.onEvaluationResult);
}
+
exports.WebConsoleClient = WebConsoleClient;
WebConsoleClient.prototype = {
@@ -124,6 +131,44 @@ WebConsoleClient.prototype = {
this._client.request(packet, aOnResponse);
},
+ /**
+ * Evaluate a JavaScript expression asynchronously.
+ * See evaluateJS for parameter and response information.
+ */
+ evaluateJSAsync: function(aString, aOnResponse, aOptions = {})
+ {
+ let packet = {
+ to: this._actor,
+ type: "evaluateJSAsync",
+ text: aString,
+ bindObjectActor: aOptions.bindObjectActor,
+ frameActor: aOptions.frameActor,
+ url: aOptions.url,
+ selectedNodeActor: aOptions.selectedNodeActor,
+ };
+
+ this._client.request(packet, response => {
+ this.pendingEvaluationResults.set(response.resultID, aOnResponse);
+ });
+ },
+
+ /**
+ * Handler for the actors's unsolicited evaluationResult packet.
+ */
+ onEvaluationResult: function(aNotification, aPacket) {
+ // Find the associated callback based on this ID, and fire it.
+ // In a sync evaluation, this would have already been called in
+ // direct response to the client.request function.
+ let onResponse = this.pendingEvaluationResults.get(aPacket.resultID);
+ if (onResponse) {
+ onResponse(aPacket);
+ this.pendingEvaluationResults.delete(aPacket.resultID);
+ } else {
+ DevToolsUtils.reportException("onEvaluationResult",
+ "No response handler for an evaluateJSAsync result (resultID: " + aPacket.resultID + ")");
+ }
+ },
+
/**
* Autocomplete a JavaScript expression.
*
@@ -400,8 +445,11 @@ WebConsoleClient.prototype = {
*/
detach: function WCC_detach(aOnResponse)
{
+ this._client.removeListener("evaluationResult", this.onEvaluationResult);
this.stopListeners(null, aOnResponse);
this._longStrings = null;
this._client = null;
+ this.pendingEvaluationResults.clear();
+ this.pendingEvaluationResults = null;
},
};
diff --git a/toolkit/devtools/webconsole/test/test_jsterm.html b/toolkit/devtools/webconsole/test/test_jsterm.html
index 19784c1091e9..a7022fd2622a 100644
--- a/toolkit/devtools/webconsole/test/test_jsterm.html
+++ b/toolkit/devtools/webconsole/test/test_jsterm.html
@@ -19,6 +19,17 @@ let gState;
let {devtools} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
let {MAX_AUTOCOMPLETE_ATTEMPTS,MAX_AUTOCOMPLETIONS} = devtools.require("devtools/toolkit/webconsole/utils");
+// This test runs all of its assertions twice - once with
+// evaluateJS and once with evaluateJSAsync.
+let evaluatingSync = true;
+function evaluateJS(input, callback) {
+ if (evaluatingSync) {
+ gState.client.evaluateJS(input, callback);
+ } else {
+ gState.client.evaluateJSAsync(input, callback);
+ }
+}
+
function startTest()
{
removeEventListener("load", startTest);
@@ -162,7 +173,7 @@ function onAutocompleteLarge2(aResponse)
function doSimpleEval()
{
info("test eval '2+2'");
- gState.client.evaluateJS("2+2", onSimpleEval);
+ evaluateJS("2+2", onSimpleEval);
}
function onSimpleEval(aResponse)
@@ -182,7 +193,7 @@ function onSimpleEval(aResponse)
function doWindowEval()
{
info("test eval 'document'");
- gState.client.evaluateJS("document", onWindowEval);
+ evaluateJS("document", onWindowEval);
}
function onWindowEval(aResponse)
@@ -206,7 +217,7 @@ function onWindowEval(aResponse)
function doEvalWithException()
{
info("test eval with exception");
- gState.client.evaluateJS("window.doTheImpossible()", onEvalWithException);
+ evaluateJS("window.doTheImpossible()", onEvalWithException);
}
function onEvalWithException(aResponse)
@@ -229,7 +240,7 @@ function onEvalWithException(aResponse)
function doEvalWithHelper()
{
info("test eval with helper");
- gState.client.evaluateJS("clear()", onEvalWithHelper);
+ evaluateJS("clear()", onEvalWithHelper);
}
function onEvalWithHelper(aResponse)
@@ -250,7 +261,7 @@ function onEvalWithHelper(aResponse)
function doEvalString()
{
- gState.client.evaluateJS("window.foobarObject.strfoo", onEvalString);
+ evaluateJS("window.foobarObject.strfoo", onEvalString);
}
function onEvalString(aResponse)
@@ -266,7 +277,7 @@ function onEvalString(aResponse)
function doEvalLongString()
{
- gState.client.evaluateJS("window.foobarObject.omgstr", onEvalLongString);
+ evaluateJS("window.foobarObject.omgstr", onEvalLongString);
}
function onEvalLongString(aResponse)
@@ -289,9 +300,16 @@ function onEvalLongString(aResponse)
function testEnd()
{
+ // If this is the first run, reload the page and do it again.
+ // Otherwise, end the test.
closeDebugger(gState, function() {
gState = null;
- SimpleTest.finish();
+ if (evaluatingSync) {
+ evaluatingSync = false;
+ startTest();
+ } else {
+ SimpleTest.finish();
+ }
});
}
diff --git a/mobile/android/locales/en-US/chrome/aboutReader.properties b/toolkit/locales/en-US/chrome/global/aboutReader.properties
similarity index 100%
rename from mobile/android/locales/en-US/chrome/aboutReader.properties
rename to toolkit/locales/en-US/chrome/global/aboutReader.properties
diff --git a/toolkit/locales/jar.mn b/toolkit/locales/jar.mn
index d03a6fafd661..cea951d0f0cc 100644
--- a/toolkit/locales/jar.mn
+++ b/toolkit/locales/jar.mn
@@ -8,6 +8,7 @@
% locale global @AB_CD@ %locale/@AB_CD@/global/
locale/@AB_CD@/global/about.dtd (%chrome/global/about.dtd)
locale/@AB_CD@/global/aboutAbout.dtd (%chrome/global/aboutAbout.dtd)
+ locale/@AB_CD@/global/aboutReader.properties (%chrome/global/aboutReader.properties)
locale/@AB_CD@/global/aboutRights.dtd (%chrome/global/aboutRights.dtd)
locale/@AB_CD@/global/aboutNetworking.dtd (%chrome/global/aboutNetworking.dtd)
locale/@AB_CD@/global/aboutSupport.dtd (%chrome/global/aboutSupport.dtd)
diff --git a/toolkit/themes/osx/global/jar.mn b/toolkit/themes/osx/global/jar.mn
index f5e9320b53c5..13e7d8c8eb2f 100644
--- a/toolkit/themes/osx/global/jar.mn
+++ b/toolkit/themes/osx/global/jar.mn
@@ -10,6 +10,7 @@ toolkit.jar:
skin/classic/global/aboutCache.css (../../windows/global/aboutCache.css)
skin/classic/global/aboutCacheEntry.css (../../windows/global/aboutCacheEntry.css)
skin/classic/global/aboutMemory.css (../../windows/global/aboutMemory.css)
+ skin/classic/global/aboutReader.css (../../windows/global/aboutReader.css)
skin/classic/global/aboutSupport.css (../../windows/global/aboutSupport.css)
skin/classic/global/appPicker.css (../../windows/global/appPicker.css)
skin/classic/global/arrow.css
diff --git a/toolkit/themes/shared/in-content/common.inc.css b/toolkit/themes/shared/in-content/common.inc.css
index 256eccff04f8..d3a7ad44f0fd 100644
--- a/toolkit/themes/shared/in-content/common.inc.css
+++ b/toolkit/themes/shared/in-content/common.inc.css
@@ -212,7 +212,7 @@ xul|button[type="menu"] > xul|*.button-box > xul|*.button-menu-dropmarker {
xul|*.help-button {
min-width: 30px;
border-radius: 2px;
- border: 1px solid #c1c1c1;
+ border-width: 0;
background-color: #ffcb00;
background-image: none;
box-shadow: none;
diff --git a/toolkit/themes/windows/global/aboutReader.css b/toolkit/themes/windows/global/aboutReader.css
new file mode 100644
index 000000000000..630b26ab6aa4
--- /dev/null
+++ b/toolkit/themes/windows/global/aboutReader.css
@@ -0,0 +1,3 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
diff --git a/toolkit/themes/windows/global/jar.mn b/toolkit/themes/windows/global/jar.mn
index 2df14192165a..c05b76ca7bdf 100644
--- a/toolkit/themes/windows/global/jar.mn
+++ b/toolkit/themes/windows/global/jar.mn
@@ -11,6 +11,7 @@ toolkit.jar:
skin/classic/global/aboutCache.css
skin/classic/global/aboutCacheEntry.css
skin/classic/global/aboutMemory.css
+ skin/classic/global/aboutReader.css
skin/classic/global/aboutSupport.css
skin/classic/global/appPicker.css
skin/classic/global/arrow.css
@@ -206,6 +207,7 @@ toolkit.jar:
skin/classic/aero/global/aboutCache.css
skin/classic/aero/global/aboutCacheEntry.css
skin/classic/aero/global/aboutMemory.css
+ skin/classic/aero/global/aboutReader.css
skin/classic/aero/global/aboutSupport.css
skin/classic/aero/global/appPicker.css
skin/classic/aero/global/arrow.css