Merge m-i to m-c, a=merge

This commit is contained in:
Phil Ringnalda 2017-01-21 15:24:42 -08:00
commit 74f10163fe
251 changed files with 32601 additions and 43129 deletions

View File

@ -1771,6 +1771,19 @@ function textChangeChecker(aID, aStart, aEnd, aTextOrFunc, aIsInserted, aFromUse
this.endOffset = aEnd;
this.textOrFunc = aTextOrFunc;
this.match = function stextChangeChecker_match(aEvent)
{
if (!(aEvent instanceof nsIAccessibleTextChangeEvent) ||
aEvent.accessible !== getAccessible(this.target)) {
return false;
}
let tcEvent = aEvent.QueryInterface(nsIAccessibleTextChangeEvent);
let modifiedText = (typeof this.textOrFunc === "function") ?
this.textOrFunc() : this.textOrFunc;
return modifiedText === tcEvent.modifiedText;
};
this.check = function textChangeChecker_check(aEvent)
{
aEvent.QueryInterface(nsIAccessibleTextChangeEvent);

View File

@ -595,7 +595,7 @@
<p id="badStsCertExplanation" hidden="true">&certerror.whatShouldIDo.badStsCertExplanation;</p>
<div id="wrongSystemTimePanel" style="display: none;">
&certerror.wrongSystemTime;
&certerror.wrongSystemTime2;
</div>
<div id="wrongSystemTimeWithoutReferencePanel" style="display: none;">

View File

@ -16,42 +16,38 @@
const Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://gre/modules/Promise.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
SimpleTest.waitForExplicitFinish();
// Load error pages do not fire "load" events, so let's use a progressListener.
function waitForErrorPage(frame) {
let errorPageDeferred = Promise.defer();
return new Promise(resolve => {
let progressListener = {
onLocationChange: function(aWebProgress, aRequest, aLocation, aFlags) {
if (aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_ERROR_PAGE) {
frame.docShell.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebProgress)
.removeProgressListener(progressListener,
Ci.nsIWebProgress.NOTIFY_LOCATION);
let progressListener = {
onLocationChange: function(aWebProgress, aRequest, aLocation, aFlags) {
if (aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_ERROR_PAGE) {
frame.docShell.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebProgress)
.removeProgressListener(progressListener,
Ci.nsIWebProgress.NOTIFY_LOCATION);
resolve();
}
},
errorPageDeferred.resolve();
}
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
Ci.nsISupportsWeakReference])
};
QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
Ci.nsISupportsWeakReference])
};
frame.docShell.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebProgress)
.addProgressListener(progressListener,
Ci.nsIWebProgress.NOTIFY_LOCATION);
return errorPageDeferred.promise;
frame.docShell.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebProgress)
.addProgressListener(progressListener,
Ci.nsIWebProgress.NOTIFY_LOCATION);
});
}
function doTest() {
Task.spawn(function test_aboutCrashed() {
(async function testBody() {
let frame1 = document.getElementById("frame1");
let frame2 = document.getElementById("frame2");
let uri1 = Services.io.newURI("http://www.example.com/1", null, null);
@ -61,7 +57,7 @@
frame1.docShell.chromeEventHandler.setAttribute("crashedPageTitle", "pageTitle");
frame1.docShell.displayLoadError(Components.results.NS_ERROR_CONTENT_CRASHED, uri1, null);
yield errorPageReady;
await errorPageReady;
frame1.docShell.chromeEventHandler.removeAttribute("crashedPageTitle");
SimpleTest.is(frame1.contentDocument.documentURI,
@ -71,14 +67,14 @@
errorPageReady = waitForErrorPage(frame2);
frame2.docShell.displayLoadError(Components.results.NS_ERROR_CONTENT_CRASHED, uri2, null);
yield errorPageReady;
await errorPageReady;
SimpleTest.is(frame2.contentDocument.documentURI,
"about:tabcrashed?e=tabcrashed&u=http%3A//www.example.com/2&c=UTF-8&f=regular&d=%20",
"Correct about:tabcrashed displayed for page with no title.");
SimpleTest.finish();
});
})().catch(ex => SimpleTest.ok(false, ex));
}
]]></script>

View File

@ -30,7 +30,7 @@ let gWhitelist = [{
type: "single-quote"
}, {
file: "netError.dtd",
key: "certerror.wrongSystemTime",
key: "certerror.wrongSystemTime2",
type: "single-quote"
}, {
file: "netError.dtd",

View File

@ -178,6 +178,9 @@ var tests = [
{ id: "Test#7",
*run() {
this.oldSelectedTab = gBrowser.selectedTab;
yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com/");
let firstTab = gBrowser.selectedTab;
yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com/");
let shown = waitForNotificationPanel();
@ -186,11 +189,14 @@ var tests = [
this.notification = showNotification(notifyObj);
yield shown;
ok(notifyObj.shownCallbackTriggered, "Should have triggered the shown callback");
ok(notifyObj.shownCallbackTriggered, "Should have triggered the shown event");
ok(notifyObj.showingCallbackTriggered, "Should have triggered the showing event");
// Reset to false so that we can ensure these are not fired a second time.
notifyObj.shownCallbackTriggered = false;
notifyObj.showingCallbackTriggered = false;
yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com/");
let promiseWin = BrowserTestUtils.waitForNewWindow();
gBrowser.replaceTabWithWindow(gBrowser.selectedTab);
gBrowser.replaceTabWithWindow(firstTab);
let win = yield promiseWin;
let anchor = win.document.getElementById("default-notification-icon");
@ -203,7 +209,15 @@ var tests = [
let id = PopupNotifications.panel.firstChild.getAttribute("popupid");
ok(id.endsWith("Test#7"), "Should have found the notification from Test7");
ok(PopupNotifications.isPanelOpen, "Should have shown the popup again after getting back to the window");
ok(PopupNotifications.isPanelOpen,
"Should have kept the popup on the first window");
ok(!notifyObj.dismissalCallbackTriggered,
"Should not have triggered a dismissed event");
ok(!notifyObj.shownCallbackTriggered,
"Should not have triggered a second shown event");
ok(!notifyObj.showingCallbackTriggered,
"Should not have triggered a second showing event");
this.notification.remove();
gBrowser.removeTab(gBrowser.selectedTab);
gBrowser.selectedTab = this.oldSelectedTab;

View File

@ -17,17 +17,17 @@ add_task(function* test_indicatorDrop() {
let EventUtils = {};
scriptLoader.loadSubScript("chrome://mochikit/content/tests/SimpleTest/EventUtils.js", EventUtils);
function task_drop(win, urls) {
async function drop(win, urls) {
let dragData = [[{type: "text/plain", data: urls.join("\n")}]];
let listBox = win.document.getElementById("downloadsRichListBox");
ok(listBox, "download list box present");
let list = yield Downloads.getList(Downloads.ALL);
let list = await Downloads.getList(Downloads.ALL);
let added = new Set();
let succeeded = new Set();
yield new Promise(function(resolve) {
await new Promise(resolve => {
let view = {
onDownloadAdded: function(download) {
added.add(download.source.url);
@ -65,8 +65,8 @@ add_task(function* test_indicatorDrop() {
win.close();
});
yield* task_drop(win, [httpUrl("file1.txt")]);
yield* task_drop(win, [httpUrl("file1.txt"),
httpUrl("file2.txt"),
httpUrl("file3.txt")]);
yield drop(win, [httpUrl("file1.txt")]);
yield drop(win, [httpUrl("file1.txt"),
httpUrl("file2.txt"),
httpUrl("file3.txt")]);
});

View File

@ -7,8 +7,7 @@ var gTests;
function test() {
waitForExplicitFinish();
requestLongerTimeout(2);
gTests = runTest();
gTests.next();
runTest().catch(ex => ok(false, ex));
}
/*
@ -17,34 +16,22 @@ function test() {
* ================
*/
function moveAlong(aResult) {
try {
gTests.send(aResult);
} catch (x if x instanceof StopIteration) {
finish();
}
}
function createWindow(aOptions) {
whenNewWindowLoaded(aOptions, function(win) {
moveAlong(win);
});
return new Promise(resolve => whenNewWindowLoaded(aOptions, resolve));
}
function getFile(downloadLastDir, aURI) {
downloadLastDir.getFileAsync(aURI, function(result) {
moveAlong(result);
});
return new Promise(resolve => downloadLastDir.getFileAsync(aURI, resolve));
}
function setFile(downloadLastDir, aURI, aValue) {
downloadLastDir.setFile(aURI, aValue);
executeSoon(moveAlong);
return new Promise(resolve => executeSoon(resolve));
}
function clearHistoryAndWait() {
clearHistory();
executeSoon(() => executeSoon(moveAlong));
return new Promise(resolve => executeSoon(_ => executeSoon(resolve)));
}
/*
@ -53,7 +40,7 @@ function clearHistoryAndWait() {
* ===================
*/
function runTest() {
async function runTest() {
let FileUtils =
Cu.import("resource://gre/modules/FileUtils.jsm", {}).FileUtils;
let DownloadLastDir =
@ -81,12 +68,12 @@ function runTest() {
function checkDownloadLastDir(gDownloadLastDir, aLastDir) {
is(gDownloadLastDir.file.path, aLastDir.path,
"gDownloadLastDir should point to the expected last directory");
getFile(gDownloadLastDir, uri1);
return getFile(gDownloadLastDir, uri1);
}
function checkDownloadLastDirNull(gDownloadLastDir) {
is(gDownloadLastDir.file, null, "gDownloadLastDir should be null");
getFile(gDownloadLastDir, uri1);
return getFile(gDownloadLastDir, uri1);
}
/*
@ -95,8 +82,8 @@ function runTest() {
* ================================
*/
let win = yield createWindow({private: false});
let pbWin = yield createWindow({private: true});
let win = await createWindow({private: false});
let pbWin = await createWindow({private: true});
let downloadLastDir = new DownloadLastDir(win);
let pbDownloadLastDir = new DownloadLastDir(pbWin);
@ -113,7 +100,7 @@ function runTest() {
"LastDir pref should be null to start with");
// set up last dir
yield setFile(downloadLastDir, null, tmpDir);
await setFile(downloadLastDir, null, tmpDir);
is(downloadLastDir.file.path, tmpDir.path,
"LastDir should point to the tmpDir");
isnot(downloadLastDir.file, tmpDir,
@ -121,111 +108,111 @@ function runTest() {
// set uri1 to dir1, all should now return dir1
// also check that a new object is returned
yield setFile(downloadLastDir, uri1, dir1);
await setFile(downloadLastDir, uri1, dir1);
is(downloadLastDir.file.path, dir1.path,
"downloadLastDir should return dir1");
isnot(downloadLastDir.file, dir1,
"downloadLastDir.file should not return dir1");
is((yield getFile(downloadLastDir, uri1)).path, dir1.path,
is((await getFile(downloadLastDir, uri1)).path, dir1.path,
"uri1 should return dir1"); // set in CPS
isnot((yield getFile(downloadLastDir, uri1)), dir1,
isnot((await getFile(downloadLastDir, uri1)), dir1,
"getFile on uri1 should not return dir1");
is((yield getFile(downloadLastDir, uri2)).path, dir1.path,
is((await getFile(downloadLastDir, uri2)).path, dir1.path,
"uri2 should return dir1"); // fallback
isnot((yield getFile(downloadLastDir, uri2)), dir1,
isnot((await getFile(downloadLastDir, uri2)), dir1,
"getFile on uri2 should not return dir1");
is((yield getFile(downloadLastDir, uri3)).path, dir1.path,
is((await getFile(downloadLastDir, uri3)).path, dir1.path,
"uri3 should return dir1"); // fallback
isnot((yield getFile(downloadLastDir, uri3)), dir1,
isnot((await getFile(downloadLastDir, uri3)), dir1,
"getFile on uri3 should not return dir1");
is((yield getFile(downloadLastDir, uri4)).path, dir1.path,
is((await getFile(downloadLastDir, uri4)).path, dir1.path,
"uri4 should return dir1"); // fallback
isnot((yield getFile(downloadLastDir, uri4)), dir1,
isnot((await getFile(downloadLastDir, uri4)), dir1,
"getFile on uri4 should not return dir1");
// set uri2 to dir2, all except uri1 should now return dir2
yield setFile(downloadLastDir, uri2, dir2);
await setFile(downloadLastDir, uri2, dir2);
is(downloadLastDir.file.path, dir2.path,
"downloadLastDir should point to dir2");
is((yield getFile(downloadLastDir, uri1)).path, dir1.path,
is((await getFile(downloadLastDir, uri1)).path, dir1.path,
"uri1 should return dir1"); // set in CPS
is((yield getFile(downloadLastDir, uri2)).path, dir2.path,
is((await getFile(downloadLastDir, uri2)).path, dir2.path,
"uri2 should return dir2"); // set in CPS
is((yield getFile(downloadLastDir, uri3)).path, dir2.path,
is((await getFile(downloadLastDir, uri3)).path, dir2.path,
"uri3 should return dir2"); // fallback
is((yield getFile(downloadLastDir, uri4)).path, dir2.path,
is((await getFile(downloadLastDir, uri4)).path, dir2.path,
"uri4 should return dir2"); // fallback
// set uri3 to dir3, all except uri1 and uri2 should now return dir3
yield setFile(downloadLastDir, uri3, dir3);
await setFile(downloadLastDir, uri3, dir3);
is(downloadLastDir.file.path, dir3.path,
"downloadLastDir should point to dir3");
is((yield getFile(downloadLastDir, uri1)).path, dir1.path,
is((await getFile(downloadLastDir, uri1)).path, dir1.path,
"uri1 should return dir1"); // set in CPS
is((yield getFile(downloadLastDir, uri2)).path, dir2.path,
is((await getFile(downloadLastDir, uri2)).path, dir2.path,
"uri2 should return dir2"); // set in CPS
is((yield getFile(downloadLastDir, uri3)).path, dir3.path,
is((await getFile(downloadLastDir, uri3)).path, dir3.path,
"uri3 should return dir3"); // set in CPS
is((yield getFile(downloadLastDir, uri4)).path, dir3.path,
is((await getFile(downloadLastDir, uri4)).path, dir3.path,
"uri4 should return dir4"); // fallback
// set uri1 to dir2, all except uri3 should now return dir2
yield setFile(downloadLastDir, uri1, dir2);
await setFile(downloadLastDir, uri1, dir2);
is(downloadLastDir.file.path, dir2.path,
"downloadLastDir should point to dir2");
is((yield getFile(downloadLastDir, uri1)).path, dir2.path,
is((await getFile(downloadLastDir, uri1)).path, dir2.path,
"uri1 should return dir2"); // set in CPS
is((yield getFile(downloadLastDir, uri2)).path, dir2.path,
is((await getFile(downloadLastDir, uri2)).path, dir2.path,
"uri2 should return dir2"); // set in CPS
is((yield getFile(downloadLastDir, uri3)).path, dir3.path,
is((await getFile(downloadLastDir, uri3)).path, dir3.path,
"uri3 should return dir3"); // set in CPS
is((yield getFile(downloadLastDir, uri4)).path, dir2.path,
is((await getFile(downloadLastDir, uri4)).path, dir2.path,
"uri4 should return dir2"); // fallback
yield clearHistoryAndWait();
await clearHistoryAndWait();
// check clearHistory removes all data
is(downloadLastDir.file, null, "clearHistory removes all data");
//is(Services.contentPrefs.hasPref(uri1, "browser.download.lastDir", null),
// false, "LastDir preference should be absent");
is((yield getFile(downloadLastDir, uri1)), null, "uri1 should point to null");
is((yield getFile(downloadLastDir, uri2)), null, "uri2 should point to null");
is((yield getFile(downloadLastDir, uri3)), null, "uri3 should point to null");
is((yield getFile(downloadLastDir, uri4)), null, "uri4 should point to null");
is((await getFile(downloadLastDir, uri1)), null, "uri1 should point to null");
is((await getFile(downloadLastDir, uri2)), null, "uri2 should point to null");
is((await getFile(downloadLastDir, uri3)), null, "uri3 should point to null");
is((await getFile(downloadLastDir, uri4)), null, "uri4 should point to null");
yield setFile(downloadLastDir, null, tmpDir);
await setFile(downloadLastDir, null, tmpDir);
// check data set outside PB mode is remembered
is((yield checkDownloadLastDir(pbDownloadLastDir, tmpDir)).path, tmpDir.path, "uri1 should return the expected last directory");
is((yield checkDownloadLastDir(downloadLastDir, tmpDir)).path, tmpDir.path, "uri1 should return the expected last directory");
yield clearHistoryAndWait();
is((await checkDownloadLastDir(pbDownloadLastDir, tmpDir)).path, tmpDir.path, "uri1 should return the expected last directory");
is((await checkDownloadLastDir(downloadLastDir, tmpDir)).path, tmpDir.path, "uri1 should return the expected last directory");
await clearHistoryAndWait();
yield setFile(downloadLastDir, uri1, dir1);
await setFile(downloadLastDir, uri1, dir1);
// check data set using CPS outside PB mode is remembered
is((yield checkDownloadLastDir(pbDownloadLastDir, dir1)).path, dir1.path, "uri1 should return the expected last directory");
is((yield checkDownloadLastDir(downloadLastDir, dir1)).path, dir1.path, "uri1 should return the expected last directory");
yield clearHistoryAndWait();
is((await checkDownloadLastDir(pbDownloadLastDir, dir1)).path, dir1.path, "uri1 should return the expected last directory");
is((await checkDownloadLastDir(downloadLastDir, dir1)).path, dir1.path, "uri1 should return the expected last directory");
await clearHistoryAndWait();
// check data set inside PB mode is forgotten
yield setFile(pbDownloadLastDir, null, tmpDir);
await setFile(pbDownloadLastDir, null, tmpDir);
is((yield checkDownloadLastDir(pbDownloadLastDir, tmpDir)).path, tmpDir.path, "uri1 should return the expected last directory");
is((yield checkDownloadLastDirNull(downloadLastDir)), null, "uri1 should return the expected last directory");
is((await checkDownloadLastDir(pbDownloadLastDir, tmpDir)).path, tmpDir.path, "uri1 should return the expected last directory");
is((await checkDownloadLastDirNull(downloadLastDir)), null, "uri1 should return the expected last directory");
yield clearHistoryAndWait();
await clearHistoryAndWait();
// check data set using CPS inside PB mode is forgotten
yield setFile(pbDownloadLastDir, uri1, dir1);
await setFile(pbDownloadLastDir, uri1, dir1);
is((yield checkDownloadLastDir(pbDownloadLastDir, dir1)).path, dir1.path, "uri1 should return the expected last directory");
is((yield checkDownloadLastDirNull(downloadLastDir)), null, "uri1 should return the expected last directory");
is((await checkDownloadLastDir(pbDownloadLastDir, dir1)).path, dir1.path, "uri1 should return the expected last directory");
is((await checkDownloadLastDirNull(downloadLastDir)), null, "uri1 should return the expected last directory");
// check data set outside PB mode but changed inside is remembered correctly
yield setFile(downloadLastDir, uri1, dir1);
yield setFile(pbDownloadLastDir, uri1, dir2);
is((yield checkDownloadLastDir(pbDownloadLastDir, dir2)).path, dir2.path, "uri1 should return the expected last directory");
is((yield checkDownloadLastDir(downloadLastDir, dir1)).path, dir1.path, "uri1 should return the expected last directory");
await setFile(downloadLastDir, uri1, dir1);
await setFile(pbDownloadLastDir, uri1, dir2);
is((await checkDownloadLastDir(pbDownloadLastDir, dir2)).path, dir2.path, "uri1 should return the expected last directory");
is((await checkDownloadLastDir(downloadLastDir, dir1)).path, dir1.path, "uri1 should return the expected last directory");
/*
* ====================
@ -236,47 +223,49 @@ function runTest() {
// check that the last dir store got cleared in a new PB window
pbWin.close();
// And give it time to close
executeSoon(moveAlong);
yield;
pbWin = yield createWindow({private: true});
await new Promise(resolve => executeSoon(resolve));
pbWin = await createWindow({private: true});
pbDownloadLastDir = new DownloadLastDir(pbWin);
is((yield checkDownloadLastDir(pbDownloadLastDir, dir1)).path, dir1.path, "uri1 should return the expected last directory");
is((await checkDownloadLastDir(pbDownloadLastDir, dir1)).path, dir1.path, "uri1 should return the expected last directory");
yield clearHistoryAndWait();
await clearHistoryAndWait();
// check clearHistory inside PB mode clears data outside PB mode
yield setFile(pbDownloadLastDir, uri1, dir2);
await setFile(pbDownloadLastDir, uri1, dir2);
yield clearHistoryAndWait();
await clearHistoryAndWait();
is((yield checkDownloadLastDirNull(downloadLastDir)), null, "uri1 should return the expected last directory");
is((yield checkDownloadLastDirNull(pbDownloadLastDir)), null, "uri1 should return the expected last directory");
is((await checkDownloadLastDirNull(downloadLastDir)), null, "uri1 should return the expected last directory");
is((await checkDownloadLastDirNull(pbDownloadLastDir)), null, "uri1 should return the expected last directory");
// check that disabling CPS works
Services.prefs.setBoolPref("browser.download.lastDir.savePerSite", false);
yield setFile(downloadLastDir, uri1, dir1);
await setFile(downloadLastDir, uri1, dir1);
is(downloadLastDir.file.path, dir1.path, "LastDir should be set to dir1");
is((yield getFile(downloadLastDir, uri1)).path, dir1.path, "uri1 should return dir1");
is((yield getFile(downloadLastDir, uri2)).path, dir1.path, "uri2 should return dir1");
is((yield getFile(downloadLastDir, uri3)).path, dir1.path, "uri3 should return dir1");
is((yield getFile(downloadLastDir, uri4)).path, dir1.path, "uri4 should return dir1");
is((await getFile(downloadLastDir, uri1)).path, dir1.path, "uri1 should return dir1");
is((await getFile(downloadLastDir, uri2)).path, dir1.path, "uri2 should return dir1");
is((await getFile(downloadLastDir, uri3)).path, dir1.path, "uri3 should return dir1");
is((await getFile(downloadLastDir, uri4)).path, dir1.path, "uri4 should return dir1");
downloadLastDir.setFile(uri2, dir2);
is(downloadLastDir.file.path, dir2.path, "LastDir should be set to dir2");
is((yield getFile(downloadLastDir, uri1)).path, dir2.path, "uri1 should return dir2");
is((yield getFile(downloadLastDir, uri2)).path, dir2.path, "uri2 should return dir2");
is((yield getFile(downloadLastDir, uri3)).path, dir2.path, "uri3 should return dir2");
is((yield getFile(downloadLastDir, uri4)).path, dir2.path, "uri4 should return dir2");
is((await getFile(downloadLastDir, uri1)).path, dir2.path, "uri1 should return dir2");
is((await getFile(downloadLastDir, uri2)).path, dir2.path, "uri2 should return dir2");
is((await getFile(downloadLastDir, uri3)).path, dir2.path, "uri3 should return dir2");
is((await getFile(downloadLastDir, uri4)).path, dir2.path, "uri4 should return dir2");
Services.prefs.clearUserPref("browser.download.lastDir.savePerSite");
// check that passing null to setFile clears the stored value
yield setFile(downloadLastDir, uri3, dir3);
is((yield getFile(downloadLastDir, uri3)).path, dir3.path, "LastDir should be set to dir3");
yield setFile(downloadLastDir, uri3, null);
is((yield getFile(downloadLastDir, uri3)), null, "uri3 should return null");
await setFile(downloadLastDir, uri3, dir3);
is((await getFile(downloadLastDir, uri3)).path, dir3.path, "LastDir should be set to dir3");
await setFile(downloadLastDir, uri3, null);
is((await getFile(downloadLastDir, uri3)), null, "uri3 should return null");
yield clearHistoryAndWait();
await clearHistoryAndWait();
finish();
}

View File

@ -17,7 +17,7 @@ add_task(function* setup() {
});
});
add_task(function test() {
add_task(function* test() {
let prefix = 'http://mochi.test:8888/browser/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_concurrent_page.html';
function getElts(browser) {

View File

@ -5,7 +5,7 @@
// This test makes sure that the Clear Recent History menu item and command
// is disabled inside the private browsing mode.
add_task(function test() {
add_task(function* test() {
function checkDisableOption(aPrivateMode, aWindow) {
let crhCommand = aWindow.document.getElementById("Tools:Sanitize");
ok(crhCommand, "The clear recent history command should exist");

View File

@ -75,31 +75,29 @@ add_task(function* test_downloads_last_dir_toggle() {
*
* @returns Promise
*/
function testHelper(options) {
return new Task.spawn(function() {
let win = yield BrowserTestUtils.openNewBrowserWindow(options);
let gDownloadLastDir = new DownloadLastDir(win);
async function testHelper(options) {
let win = await BrowserTestUtils.openNewBrowserWindow(options);
let gDownloadLastDir = new DownloadLastDir(win);
if (options.clearHistory) {
clearHistory();
}
if (options.clearHistory) {
clearHistory();
}
if (options.setDir) {
gDownloadLastDir.file = options.setDir;
}
if (options.setDir) {
gDownloadLastDir.file = options.setDir;
}
let expectedDir = options.expectedDir;
let expectedDir = options.expectedDir;
if (expectedDir) {
is(gDownloadLastDir.file.path, expectedDir.path,
"gDownloadLastDir should point to the expected last directory");
isnot(gDownloadLastDir.file, expectedDir,
"gDownloadLastDir.file should not be pointing to the last directory");
} else {
is(gDownloadLastDir.file, null, "gDownloadLastDir should be null");
}
if (expectedDir) {
is(gDownloadLastDir.file.path, expectedDir.path,
"gDownloadLastDir should point to the expected last directory");
isnot(gDownloadLastDir.file, expectedDir,
"gDownloadLastDir.file should not be pointing to the last directory");
} else {
is(gDownloadLastDir.file, null, "gDownloadLastDir should be null");
}
gDownloadLastDir.cleanupPrivateFile();
yield BrowserTestUtils.closeWindow(win);
});
gDownloadLastDir.cleanupPrivateFile();
await BrowserTestUtils.closeWindow(win);
}

View File

@ -2,7 +2,7 @@
* 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/. */
add_task(function test() {
add_task(function* test() {
requestLongerTimeout(2);
const page1 = 'http://mochi.test:8888/browser/browser/components/privatebrowsing/test/browser/' +
'browser_privatebrowsing_localStorage_page1.html'

View File

@ -10,7 +10,7 @@
// Step 2: Load the same page in a non-private tab, ensuring that the storage instance reports only one item
// existing.
add_task(function test() {
add_task(function* test() {
let testURI = "about:blank";
let prefix = 'http://mochi.test:8888/browser/browser/components/privatebrowsing/test/browser/';

View File

@ -5,7 +5,7 @@
// This test makes sure that the window title changes correctly while switching
// from and to private browsing mode.
add_task(function test() {
add_task(function* test() {
const testPageURL = "http://mochi.test:8888/browser/" +
"browser/components/privatebrowsing/test/browser/browser_privatebrowsing_windowtitle_page.html";
requestLongerTimeout(2);
@ -37,12 +37,12 @@ add_task(function test() {
pb_about_pb_title = "Private Browsing - " + app_name + " (Private Browsing)";
}
function* testTabTitle(aWindow, url, insidePB, expected_title) {
let tab = (yield BrowserTestUtils.openNewForegroundTab(aWindow.gBrowser));
yield BrowserTestUtils.loadURI(tab.linkedBrowser, url);
yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
async function testTabTitle(aWindow, url, insidePB, expected_title) {
let tab = (await BrowserTestUtils.openNewForegroundTab(aWindow.gBrowser));
await BrowserTestUtils.loadURI(tab.linkedBrowser, url);
await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
yield BrowserTestUtils.waitForCondition(() => {
await BrowserTestUtils.waitForCondition(() => {
return aWindow.document.title === expected_title;
}, `Window title should be ${expected_title}, got ${aWindow.document.title}`);
@ -51,9 +51,9 @@ add_task(function test() {
" private browsing mode)");
let win = aWindow.gBrowser.replaceTabWithWindow(tab);
yield BrowserTestUtils.waitForEvent(win, "load", false);
await BrowserTestUtils.waitForEvent(win, "load", false);
yield BrowserTestUtils.waitForCondition(() => {
await BrowserTestUtils.waitForCondition(() => {
return win.document.title === expected_title;
}, `Window title should be ${expected_title}, got ${aWindow.document.title}`);
@ -61,17 +61,17 @@ add_task(function test() {
" detached tab is correct (" + (insidePB ? "inside" : "outside") +
" private browsing mode)");
yield Promise.all([ BrowserTestUtils.closeWindow(win),
await Promise.all([ BrowserTestUtils.closeWindow(win),
BrowserTestUtils.closeWindow(aWindow) ]);
}
function openWin(private) {
return BrowserTestUtils.openNewBrowserWindow({ private });
}
yield Task.spawn(testTabTitle((yield openWin(false)), "about:blank", false, page_without_title));
yield Task.spawn(testTabTitle((yield openWin(false)), testPageURL, false, page_with_title));
yield Task.spawn(testTabTitle((yield openWin(false)), "about:privatebrowsing", false, about_pb_title));
yield Task.spawn(testTabTitle((yield openWin(true)), "about:blank", true, pb_page_without_title));
yield Task.spawn(testTabTitle((yield openWin(true)), testPageURL, true, pb_page_with_title));
yield Task.spawn(testTabTitle((yield openWin(true)), "about:privatebrowsing", true, pb_about_pb_title));
yield testTabTitle((yield openWin(false)), "about:blank", false, page_without_title);
yield testTabTitle((yield openWin(false)), testPageURL, false, page_with_title);
yield testTabTitle((yield openWin(false)), "about:privatebrowsing", false, about_pb_title);
yield testTabTitle((yield openWin(true)), "about:blank", true, pb_page_without_title);
yield testTabTitle((yield openWin(true)), testPageURL, true, pb_page_with_title);
yield testTabTitle((yield openWin(true)), "about:privatebrowsing", true, pb_about_pb_title);
});

View File

@ -66,11 +66,11 @@ var SessionMigrationInternal = {
* Asynchronously read session restore state (JSON) from a path
*/
readState: function(aPath) {
return Task.spawn(function() {
return Task.spawn(function*() {
let bytes = yield OS.File.read(aPath);
let text = gDecoder.decode(bytes);
let state = JSON.parse(text);
throw new Task.Result(state);
return state;
});
},
/**
@ -87,7 +87,7 @@ var SessionMigration = {
* Migrate a limited set of session data from one path to another.
*/
migrate: function(aFromPath, aToPath) {
return Task.spawn(function() {
return Task.spawn(function*() {
let inState = yield SessionMigrationInternal.readState(aFromPath);
let outState = SessionMigrationInternal.convertState(inState);
// Unfortunately, we can't use SessionStore's own SessionFile to

View File

@ -8,7 +8,7 @@ const URL = "about:config";
/**
* Bug 393716 - Basic tests for getTabState(), setTabState(), and duplicateTab().
*/
add_task(function test_set_tabstate() {
add_task(function* test_set_tabstate() {
let key = "Unique key: " + Date.now();
let value = "Unique value: " + Math.random();
@ -35,7 +35,7 @@ add_task(function test_set_tabstate() {
gBrowser.removeTab(tab);
});
add_task(function test_set_tabstate_and_duplicate() {
add_task(function* test_set_tabstate_and_duplicate() {
let key2 = "key2";
let value2 = "Value " + Math.random();
let value3 = "Another value: " + Date.now();

View File

@ -8,7 +8,7 @@ const URL = ROOT + "browser_456342_sample.xhtml";
/**
* Bug 456342 - Restore values from non-standard input field types.
*/
add_task(function test_restore_nonstandard_input_values() {
add_task(function* test_restore_nonstandard_input_values() {
// Add tab with various non-standard input field types.
let tab = gBrowser.addTab(URL);
let browser = tab.linkedBrowser;

View File

@ -10,7 +10,7 @@ const URL = ROOT + "browser_463205_sample.html";
* website can't modify frame URLs and make us inject form data into the wrong
* web pages.
*/
add_task(function test_check_urls_before_restoring() {
add_task(function* test_check_urls_before_restoring() {
// Add a blank tab.
let tab = gBrowser.addTab("about:blank");
let browser = tab.linkedBrowser;

View File

@ -8,7 +8,7 @@ const URL = ROOT + "browser_466937_sample.html";
/**
* Bug 466937 - Prevent file stealing with sessionstore.
*/
add_task(function test_prevent_file_stealing() {
add_task(function* test_prevent_file_stealing() {
// Add a tab with some file input fields.
let tab = gBrowser.addTab(URL);
let browser = tab.linkedBrowser;

View File

@ -30,7 +30,7 @@ function createEntries(sessionData) {
};
}
add_task(function test_nested_about_sessionrestore() {
add_task(function* test_nested_about_sessionrestore() {
// Prepare a blank tab.
let tab = gBrowser.addTab("about:blank");
let browser = tab.linkedBrowser;

View File

@ -9,7 +9,7 @@ const URL = ROOT + "browser_485482_sample.html";
* Bug 485482 - Make sure that we produce valid XPath expressions even for very
* weird HTML documents.
*/
add_task(function test_xpath_exp_for_strange_documents() {
add_task(function* test_xpath_exp_for_strange_documents() {
// Load a page with weird tag names.
let tab = gBrowser.addTab(URL);
let browser = tab.linkedBrowser;

View File

@ -11,7 +11,7 @@ function browserWindowsCount(expected) {
"number of open browser windows according to getBrowserState");
}
add_task(function() {
add_task(function*() {
browserWindowsCount(1);
let win = yield BrowserTestUtils.openNewBrowserWindow();

View File

@ -9,7 +9,7 @@ const INITIAL_VALUE = "browser_broadcast.js-initial-value-" + Date.now();
* This test ensures we won't lose tab data queued in the content script when
* closing a tab.
*/
add_task(function flush_on_tabclose() {
add_task(function* flush_on_tabclose() {
let tab = yield createTabWithStorageData(["http://example.com"]);
let browser = tab.linkedBrowser;
@ -25,7 +25,7 @@ add_task(function flush_on_tabclose() {
* This test ensures we won't lose tab data queued in the content script when
* duplicating a tab.
*/
add_task(function flush_on_duplicate() {
add_task(function* flush_on_duplicate() {
let tab = yield createTabWithStorageData(["http://example.com"]);
let browser = tab.linkedBrowser;
@ -45,7 +45,7 @@ add_task(function flush_on_duplicate() {
* This test ensures we won't lose tab data queued in the content script when
* a window is closed.
*/
add_task(function flush_on_windowclose() {
add_task(function* flush_on_windowclose() {
let win = yield promiseNewWindow();
let tab = yield createTabWithStorageData(["http://example.com"], win);
let browser = tab.linkedBrowser;
@ -62,7 +62,7 @@ add_task(function flush_on_windowclose() {
* This test ensures that stale tab data is ignored when reusing a tab
* (via e.g. setTabState) and does not overwrite the new data.
*/
add_task(function flush_on_settabstate() {
add_task(function* flush_on_settabstate() {
let tab = yield createTabWithStorageData(["http://example.com"]);
let browser = tab.linkedBrowser;
@ -90,7 +90,7 @@ add_task(function flush_on_settabstate() {
* asynchronously just before closing a tab. Flushing must re-send all data
* that hasn't been received by chrome, yet.
*/
add_task(function flush_on_tabclose_racy() {
add_task(function* flush_on_tabclose_racy() {
let tab = yield createTabWithStorageData(["http://example.com"]);
let browser = tab.linkedBrowser;
@ -115,17 +115,15 @@ function promiseNewWindow() {
return deferred.promise;
}
function createTabWithStorageData(urls, win = window) {
return Task.spawn(function task() {
let tab = win.gBrowser.addTab();
let browser = tab.linkedBrowser;
async function createTabWithStorageData(urls, win = window) {
let tab = win.gBrowser.addTab();
let browser = tab.linkedBrowser;
for (let url of urls) {
browser.loadURI(url);
yield promiseBrowserLoaded(browser);
yield modifySessionStorage(browser, {test: INITIAL_VALUE});
}
for (let url of urls) {
browser.loadURI(url);
await promiseBrowserLoaded(browser);
await modifySessionStorage(browser, {test: INITIAL_VALUE});
}
throw new Task.Result(tab);
});
return tab;
}

View File

@ -8,7 +8,7 @@
* properties are (re)stored as disabled. Disallowed features must be
* re-enabled when the tab is re-used by another tab restoration.
*/
add_task(function docshell_capabilities() {
add_task(function* docshell_capabilities() {
let tab = yield createTab();
let browser = tab.linkedBrowser;
let docShell = browser.docShell;
@ -69,8 +69,9 @@ add_task(function docshell_capabilities() {
gBrowser.removeTab(tab);
});
function createTab() {
async function createTab() {
let tab = gBrowser.addTab("about:mozilla");
let browser = tab.linkedBrowser;
return promiseBrowserLoaded(browser).then(() => tab);
await promiseBrowserLoaded(browser);
return tab;
}

View File

@ -84,7 +84,7 @@ add_task(function* test_run() {
* different cookie domains given in the Set-Cookie header. See above for some
* usage examples.
*/
var testCookieCollection = Task.async(function (params) {
var testCookieCollection = async function (params) {
let tab = gBrowser.addTab("about:blank");
let browser = tab.linkedBrowser;
@ -102,14 +102,14 @@ var testCookieCollection = Task.async(function (params) {
// Wait for the browser to load and the cookie to be set.
// These two events can probably happen in no particular order,
// so let's wait for them in parallel.
yield Promise.all([
await Promise.all([
waitForNewCookie(),
replaceCurrentURI(browser, uri)
]);
// Check all URIs for which the cookie should be collected.
for (let uri of params.cookieURIs || []) {
yield replaceCurrentURI(browser, uri);
await replaceCurrentURI(browser, uri);
// Check the cookie.
let cookie = getCookie();
@ -121,7 +121,7 @@ var testCookieCollection = Task.async(function (params) {
// Check all URIs for which the cookie should NOT be collected.
for (let uri of params.noCookieURIs || []) {
yield replaceCurrentURI(browser, uri);
await replaceCurrentURI(browser, uri);
// Cookie should be ignored.
ok(!getCookie(), "no cookie collected");
@ -130,22 +130,22 @@ var testCookieCollection = Task.async(function (params) {
// Clean up.
gBrowser.removeTab(tab);
Services.cookies.removeAll();
});
};
/**
* Replace the current URI of the given browser by loading a new URI. The
* browser's session history will be completely replaced. This function ensures
* that the parent process has the lastest shistory data before resolving.
*/
var replaceCurrentURI = Task.async(function* (browser, uri) {
var replaceCurrentURI = async function(browser, uri) {
// Replace the tab's current URI with the parent domain.
let flags = Ci.nsIWebNavigation.LOAD_FLAGS_REPLACE_HISTORY;
browser.loadURIWithFlags(uri, flags);
yield promiseBrowserLoaded(browser);
await promiseBrowserLoaded(browser);
// Ensure the tab's session history is up-to-date.
yield TabStateFlusher.flush(browser);
});
await TabStateFlusher.flush(browser);
};
/**
* Waits for a new "*example.com" cookie to be added.

View File

@ -125,7 +125,7 @@ function promiseTabCrashedReady(browser) {
* Checks that if a tab crashes, that information about the tab crashed
* page does not get added to the tab history.
*/
add_task(function test_crash_page_not_in_history() {
add_task(function* test_crash_page_not_in_history() {
let newTab = gBrowser.addTab();
gBrowser.selectedTab = newTab;
let browser = newTab.linkedBrowser;
@ -154,7 +154,7 @@ add_task(function test_crash_page_not_in_history() {
* to a non-blacklisted site (so the browser becomes remote again), that
* we record history for that new visit.
*/
add_task(function test_revived_history_from_remote() {
add_task(function* test_revived_history_from_remote() {
let newTab = gBrowser.addTab();
gBrowser.selectedTab = newTab;
let browser = newTab.linkedBrowser;
@ -193,7 +193,7 @@ add_task(function test_revived_history_from_remote() {
* to a blacklisted site (so the browser stays non-remote), that
* we record history for that new visit.
*/
add_task(function test_revived_history_from_non_remote() {
add_task(function* test_revived_history_from_non_remote() {
let newTab = gBrowser.addTab();
gBrowser.selectedTab = newTab;
let browser = newTab.linkedBrowser;
@ -231,7 +231,7 @@ add_task(function test_revived_history_from_non_remote() {
* Checks that we can revive a crashed tab back to the page that
* it was on when it crashed.
*/
add_task(function test_revive_tab_from_session_store() {
add_task(function* test_revive_tab_from_session_store() {
let newTab = gBrowser.addTab();
gBrowser.selectedTab = newTab;
let browser = newTab.linkedBrowser;
@ -284,7 +284,7 @@ add_task(function test_revive_tab_from_session_store() {
* Checks that we can revive multiple crashed tabs back to the pages
* that they were on when they crashed.
*/
add_task(function test_revive_all_tabs_from_session_store() {
add_task(function* test_revive_all_tabs_from_session_store() {
let newTab = gBrowser.addTab();
gBrowser.selectedTab = newTab;
let browser = newTab.linkedBrowser;
@ -344,7 +344,7 @@ add_task(function test_revive_all_tabs_from_session_store() {
/**
* Checks that about:tabcrashed can close the current tab
*/
add_task(function test_close_tab_after_crash() {
add_task(function* test_close_tab_after_crash() {
let newTab = gBrowser.addTab();
gBrowser.selectedTab = newTab;
let browser = newTab.linkedBrowser;

View File

@ -7,7 +7,7 @@
* Ensure that static frames of framesets are serialized but dynamically
* inserted iframes are ignored.
*/
add_task(function () {
add_task(function*() {
// This URL has the following frames:
// + data:text/html,A (static)
// + data:text/html,B (static)
@ -45,7 +45,7 @@ add_task(function () {
* dynamically inserted iframes are ignored. Navigating a subframe should
* create a second root entry that doesn't contain any dynamic children either.
*/
add_task(function () {
add_task(function*() {
// This URL has the following frames:
// + data:text/html,A (static)
// + data:text/html,C (dynamic iframe)

View File

@ -9,7 +9,7 @@ const URL = ROOT + "browser_form_restore_events_sample.html";
* Originally a test for Bug 476161, but then expanded to include all input
* types in bug 640136.
*/
add_task(function () {
add_task(function*() {
// Load a page with some form elements.
let tab = gBrowser.addTab(URL);
let browser = tab.linkedBrowser;

View File

@ -9,7 +9,7 @@ requestLongerTimeout(2);
* This test ensures that form data collection respects the privacy level as
* set by the user.
*/
add_task(function test_formdata() {
add_task(function* test_formdata() {
const URL = "http://mochi.test:8888/browser/browser/components/" +
"sessionstore/test/browser_formdata_sample.html";
@ -18,23 +18,21 @@ add_task(function test_formdata() {
// Creates a tab, loads a page with some form fields,
// modifies their values and closes the tab.
function createAndRemoveTab() {
return Task.spawn(function () {
// Create a new tab.
let tab = gBrowser.addTab(URL);
let browser = tab.linkedBrowser;
yield promiseBrowserLoaded(browser);
function* createAndRemoveTab() {
// Create a new tab.
let tab = gBrowser.addTab(URL);
let browser = tab.linkedBrowser;
yield promiseBrowserLoaded(browser);
// Modify form data.
yield setInputValue(browser, {id: "txt", value: OUTER_VALUE});
yield setInputValue(browser, {id: "txt", value: INNER_VALUE, frame: 0});
// Modify form data.
yield setInputValue(browser, {id: "txt", value: OUTER_VALUE});
yield setInputValue(browser, {id: "txt", value: INNER_VALUE, frame: 0});
// Remove the tab.
yield promiseRemoveTab(tab);
});
// Remove the tab.
yield promiseRemoveTab(tab);
}
yield createAndRemoveTab();
yield* createAndRemoveTab();
let [{state: {formdata}}] = JSON.parse(ss.getClosedTabData(window));
is(formdata.id.txt, OUTER_VALUE, "outer value is correct");
is(formdata.children[0].id.txt, INNER_VALUE, "inner value is correct");
@ -42,7 +40,7 @@ add_task(function test_formdata() {
// Disable saving data for encrypted sites.
Services.prefs.setIntPref("browser.sessionstore.privacy_level", 1);
yield createAndRemoveTab();
yield* createAndRemoveTab();
[{state: {formdata}}] = JSON.parse(ss.getClosedTabData(window));
is(formdata.id.txt, OUTER_VALUE, "outer value is correct");
ok(!formdata.children, "inner value was *not* stored");
@ -50,7 +48,7 @@ add_task(function test_formdata() {
// Disable saving data for any site.
Services.prefs.setIntPref("browser.sessionstore.privacy_level", 2);
yield createAndRemoveTab();
yield* createAndRemoveTab();
[{state: {formdata}}] = JSON.parse(ss.getClosedTabData(window));
ok(!formdata, "form data has *not* been stored");
@ -63,7 +61,7 @@ add_task(function test_formdata() {
* form data into a wrong website and that we always check the stored URL
* before doing so.
*/
add_task(function test_url_check() {
add_task(function* test_url_check() {
const URL = "data:text/html;charset=utf-8,<input%20id=input>";
const VALUE = "value-" + Math.random();
@ -98,7 +96,7 @@ add_task(function test_url_check() {
* This test ensures that collecting form data works as expected when having
* nested frame sets.
*/
add_task(function test_nested() {
add_task(function* test_nested() {
const URL = "data:text/html;charset=utf-8," +
"<iframe src='data:text/html;charset=utf-8," +
"<input autofocus=true>'/>";
@ -143,7 +141,7 @@ add_task(function test_nested() {
* This test ensures that collecting form data for documents with
* designMode=on works as expected.
*/
add_task(function test_design_mode() {
add_task(function* test_design_mode() {
const URL = "data:text/html;charset=utf-8,<h1>mozilla</h1>" +
"<script>document.designMode='on'</script>";

View File

@ -53,21 +53,16 @@ function test() {
[ "value29", "value30" ],
[ "", "value33" ]
];
let testTabCount = 0;
let callback = function() {
testTabCount--;
if (testTabCount == 0) {
finish();
}
};
let promises = [];
for (let i = 0; i < formData.length; i++) {
testTabCount++;
testTabRestoreData(formData[i], expectedValues[i], callback);
promises.push(testTabRestoreData(formData[i], expectedValues[i]));
}
Promise.all(promises).then(() => finish(), ex => ok(false, ex));
}
function testTabRestoreData(aFormData, aExpectedValue, aCallback) {
async function testTabRestoreData(aFormData, aExpectedValue) {
let URL = ROOT + "browser_formdata_format_sample.html";
let tab = gBrowser.addTab("about:blank");
let browser = tab.linkedBrowser;
@ -75,39 +70,35 @@ function testTabRestoreData(aFormData, aExpectedValue, aCallback) {
aFormData.url = URL;
let tabState = { entries: [{ url: URL }], formdata: aFormData };
Task.spawn(function () {
yield promiseBrowserLoaded(tab.linkedBrowser);
yield promiseTabState(tab, tabState);
await promiseBrowserLoaded(tab.linkedBrowser);
await promiseTabState(tab, tabState);
yield TabStateFlusher.flush(tab.linkedBrowser);
let restoredTabState = JSON.parse(ss.getTabState(tab));
let restoredFormData = restoredTabState.formdata;
await TabStateFlusher.flush(tab.linkedBrowser);
let restoredTabState = JSON.parse(ss.getTabState(tab));
let restoredFormData = restoredTabState.formdata;
if (restoredFormData) {
let doc = tab.linkedBrowser.contentDocument;
let input1 = doc.getElementById("input1");
let input2 = doc.querySelector("input[name=input2]");
if (restoredFormData) {
let doc = tab.linkedBrowser.contentDocument;
let input1 = doc.getElementById("input1");
let input2 = doc.querySelector("input[name=input2]");
// test format
ok("id" in restoredFormData || "xpath" in restoredFormData,
"FormData format is valid: " + restoredFormData);
// validate that there are no old keys
for (let key of Object.keys(restoredFormData)) {
if (["id", "xpath", "url"].indexOf(key) === -1) {
ok(false, "FormData format is invalid.");
}
// test format
ok("id" in restoredFormData || "xpath" in restoredFormData,
"FormData format is valid: " + restoredFormData);
// validate that there are no old keys
for (let key of Object.keys(restoredFormData)) {
if (["id", "xpath", "url"].indexOf(key) === -1) {
ok(false, "FormData format is invalid.");
}
// test id
is(input1.value, aExpectedValue[0],
"FormData by 'id' has been restored correctly");
// test xpath
is(input2.value, aExpectedValue[1],
"FormData by 'xpath' has been restored correctly");
}
// test id
is(input1.value, aExpectedValue[0],
"FormData by 'id' has been restored correctly");
// test xpath
is(input2.value, aExpectedValue[1],
"FormData by 'xpath' has been restored correctly");
}
// clean up
gBrowser.removeTab(tab);
// This test might time out if the task fails.
}).then(aCallback);
// clean up
gBrowser.removeTab(tab);
}

View File

@ -38,7 +38,7 @@ const FIELDS = {
"//input[@type='file'][2]": [FILE1, FILE2]
};
add_task(function test_form_data_restoration() {
add_task(function* test_form_data_restoration() {
// Load page with some input fields.
let tab = gBrowser.addTab(URL);
let browser = tab.linkedBrowser;

View File

@ -8,7 +8,7 @@
*/
// Loading a toplevel frameset
add_task(function() {
add_task(function*() {
let testURL = getRootDirectory(gTestPath) + "browser_frame_history_index.html";
let tab = gBrowser.addTab(testURL);
gBrowser.selectedTab = tab;
@ -51,7 +51,7 @@ add_task(function() {
});
// Loading the frameset inside an iframe
add_task(function() {
add_task(function*() {
let testURL = getRootDirectory(gTestPath) + "browser_frame_history_index2.html";
let tab = gBrowser.addTab(testURL);
gBrowser.selectedTab = tab;
@ -98,7 +98,7 @@ add_task(function() {
});
// Now, test that we don't record history if the iframe is added dynamically
add_task(function() {
add_task(function*() {
// Start with an empty history
let blankState = JSON.stringify({
windows: [{

View File

@ -13,7 +13,7 @@ const URL_FRAMESET = HTTPROOT + "browser_frametree_sample_frameset.html";
* when a page starts loading and we also expect a valid frame tree to exist
* when it has stopped loading.
*/
add_task(function test_frametree() {
add_task(function* test_frametree() {
const FRAME_TREE_SINGLE = { href: URL };
const FRAME_TREE_FRAMESET = {
href: URL_FRAMESET,
@ -65,7 +65,7 @@ add_task(function test_frametree() {
* after the load event. SessionStore can't handle these and will not restore
* or collect any data for them.
*/
add_task(function test_frametree_dynamic() {
add_task(function* test_frametree_dynamic() {
// The frame tree as expected. The first two frames are static
// and the third one was created on DOMContentLoaded.
const FRAME_TREE = {

View File

@ -7,7 +7,7 @@
* Ensure that history entries that should not be persisted are restored in the
* same state.
*/
add_task(function check_history_not_persisted() {
add_task(function* check_history_not_persisted() {
// Create an about:blank tab
let tab = gBrowser.addTab("about:blank");
let browser = tab.linkedBrowser;
@ -44,7 +44,7 @@ add_task(function check_history_not_persisted() {
* Check that entries default to being persisted when the attribute doesn't
* exist
*/
add_task(function check_history_default_persisted() {
add_task(function* check_history_default_persisted() {
// Create an about:blank tab
let tab = gBrowser.addTab("about:blank");
let browser = tab.linkedBrowser;

View File

@ -20,7 +20,7 @@ add_task(function setup() {
/**
* Ensure that a pending tab has label and icon correctly set.
*/
add_task(function test_label_and_icon() {
add_task(function* test_label_and_icon() {
// Create a new tab.
let tab = gBrowser.addTab("about:robots");
let browser = tab.linkedBrowser;

View File

@ -5,7 +5,7 @@
* This test ensures that closed tabs are merged when restoring
* a window state without overwriting tabs.
*/
add_task(function () {
add_task(function* () {
const initialState = {
windows: [{
tabs: [

View File

@ -9,7 +9,7 @@ const URL_NESTED = getRootDirectory(gTestPath) + "browser_pageStyle_sample_neste
/**
* This test ensures that page style information is correctly persisted.
*/
add_task(function page_style() {
add_task(function* page_style() {
let tab = gBrowser.addTab(URL);
let browser = tab.linkedBrowser;
yield promiseBrowserLoaded(browser);
@ -53,7 +53,7 @@ add_task(function page_style() {
* This test ensures that page style notification from nested documents are
* received and the page style is persisted correctly.
*/
add_task(function nested_page_style() {
add_task(function* nested_page_style() {
let tab = gBrowser.addTab(URL_NESTED);
let browser = tab.linkedBrowser;
yield promiseBrowserLoaded(browser);

View File

@ -8,7 +8,7 @@ add_task(function cleanup() {
}
});
add_task(function() {
add_task(function*() {
let URL_PUBLIC = "http://example.com/public/" + Math.random();
let URL_PRIVATE = "http://example.com/private/" + Math.random();
let tab1, tab2;
@ -59,7 +59,7 @@ add_task(function() {
}
});
add_task(function () {
add_task(function* () {
const FRAME_SCRIPT = "data:," +
"docShell.QueryInterface%28Components.interfaces.nsILoadContext%29.usePrivateBrowsing%3Dtrue";
@ -101,7 +101,7 @@ add_task(function () {
is(ss.getClosedWindowCount(), 0, "no windows to restore");
});
add_task(function () {
add_task(function* () {
// Clear the list of closed windows.
forgetClosedWindows();

View File

@ -6,7 +6,7 @@ const TARGET = BASE + "restore_redirect_target.html";
/**
* Ensure that a http redirect leaves a working tab.
*/
add_task(function check_http_redirect() {
add_task(function* check_http_redirect() {
let state = {
entries: [{ url: BASE + "restore_redirect_http.html" }]
};
@ -32,7 +32,7 @@ add_task(function check_http_redirect() {
/**
* Ensure that a js redirect leaves a working tab.
*/
add_task(function check_js_redirect() {
add_task(function* check_js_redirect() {
let state = {
entries: [{ url: BASE + "restore_redirect_js.html" }]
};

View File

@ -22,7 +22,7 @@ requestLongerTimeout(2);
* This test ensures that we properly serialize and restore scroll positions
* for an average page without any frames.
*/
add_task(function test_scroll() {
add_task(function* test_scroll() {
let tab = gBrowser.addTab(URL);
let browser = tab.linkedBrowser;
yield promiseBrowserLoaded(browser);
@ -65,7 +65,7 @@ add_task(function test_scroll() {
* This tests ensures that we properly serialize and restore scroll positions
* for multiple frames of pages with framesets.
*/
add_task(function test_scroll_nested() {
add_task(function* test_scroll_nested() {
let tab = gBrowser.addTab(URL_FRAMESET);
let browser = tab.linkedBrowser;
yield promiseBrowserLoaded(browser);
@ -109,7 +109,7 @@ add_task(function test_scroll_nested() {
* Test that scroll positions persist after restoring background tabs in
* a restored window (bug 1228518).
*/
add_task(function test_scroll_background_tabs() {
add_task(function* test_scroll_background_tabs() {
pushPrefs(["browser.sessionstore.restore_on_demand", true]);
let newWin = yield BrowserTestUtils.openNewBrowserWindow();

View File

@ -17,7 +17,7 @@ requestLongerTimeout(2);
* Test that scroll positions of about reader page after restoring background
* tabs in a restored window (bug 1153393).
*/
add_task(function test_scroll_background_about_reader_tabs() {
add_task(function* test_scroll_background_about_reader_tabs() {
pushPrefs(["browser.sessionstore.restore_on_demand", true]);
let newWin = yield BrowserTestUtils.openNewBrowserWindow();

View File

@ -8,7 +8,7 @@ requestLongerTimeout(2);
/**
* Ensure that starting a load invalidates shistory.
*/
add_task(function test_load_start() {
add_task(function* test_load_start() {
// Create a new tab.
let tab = gBrowser.addTab("about:blank");
let browser = tab.linkedBrowser;
@ -36,7 +36,7 @@ add_task(function test_load_start() {
/**
* Ensure that anchor navigation invalidates shistory.
*/
add_task(function test_hashchange() {
add_task(function* test_hashchange() {
const URL = "data:text/html;charset=utf-8,<a id=a href=%23>clickme</a>";
// Create a new tab.
@ -65,7 +65,7 @@ add_task(function test_hashchange() {
/**
* Ensure that loading pages from the bfcache invalidates shistory.
*/
add_task(function test_pageshow() {
add_task(function* test_pageshow() {
const URL = "data:text/html;charset=utf-8,<h1>first</h1>";
const URL2 = "data:text/html;charset=utf-8,<h1>second</h1>";
@ -95,7 +95,7 @@ add_task(function test_pageshow() {
/**
* Ensure that subframe navigation invalidates shistory.
*/
add_task(function test_subframes() {
add_task(function* test_subframes() {
const URL = "data:text/html;charset=utf-8," +
"<iframe src=http%3A//example.com/ name=t></iframe>" +
"<a id=a1 href=http%3A//example.com/1 target=t>clickme</a>" +
@ -143,7 +143,7 @@ add_task(function test_subframes() {
/**
* Ensure that navigating from an about page invalidates shistory.
*/
add_task(function test_about_page_navigate() {
add_task(function* test_about_page_navigate() {
// Create a new tab.
let tab = gBrowser.addTab("about:blank");
let browser = tab.linkedBrowser;
@ -171,7 +171,7 @@ add_task(function test_about_page_navigate() {
/**
* Ensure that history.pushState and history.replaceState invalidate shistory.
*/
add_task(function test_pushstate_replacestate() {
add_task(function* test_pushstate_replacestate() {
// Create a new tab.
let tab = gBrowser.addTab("http://example.com/1");
let browser = tab.linkedBrowser;
@ -210,7 +210,7 @@ add_task(function test_pushstate_replacestate() {
/**
* Ensure that slow loading subframes will invalidate shistory.
*/
add_task(function test_slow_subframe_load() {
add_task(function* test_slow_subframe_load() {
const SLOW_URL = "http://mochi.test:8888/browser/browser/components/" +
"sessionstore/test/browser_sessionHistory_slow.sjs";

View File

@ -15,7 +15,7 @@ const INNER_VALUE = "inner-value-" + RAND;
* This test ensures that setting, modifying and restoring sessionStorage data
* works as expected.
*/
add_task(function session_storage() {
add_task(function* session_storage() {
let tab = gBrowser.addTab(URL);
let browser = tab.linkedBrowser;
yield promiseBrowserLoaded(browser);
@ -102,7 +102,7 @@ add_task(function session_storage() {
* This test ensures that purging domain data also purges data from the
* sessionStorage data collected for tabs.
*/
add_task(function purge_domain() {
add_task(function* purge_domain() {
let tab = gBrowser.addTab(URL);
let browser = tab.linkedBrowser;
yield promiseBrowserLoaded(browser);
@ -126,7 +126,7 @@ add_task(function purge_domain() {
* This test ensures that collecting sessionStorage data respects the privacy
* levels as set by the user.
*/
add_task(function respect_privacy_level() {
add_task(function* respect_privacy_level() {
let tab = gBrowser.addTab(URL + "&secure");
yield promiseBrowserLoaded(tab.linkedBrowser);
yield promiseRemoveTab(tab);

View File

@ -197,10 +197,10 @@ was trying to connect. -->
<!ENTITY weakCryptoAdvanced.longDesc "<span class='hostname'></span> uses security technology that is outdated and vulnerable to attack. An attacker could easily reveal information which you thought to be safe.">
<!ENTITY weakCryptoAdvanced.override "(Not secure) Try loading <span class='hostname'></span> using outdated security">
<!-- LOCALIZATION NOTE (certerror.wrongSystemTime,
<!-- LOCALIZATION NOTE (certerror.wrongSystemTime2,
certerror.wrongSystemTimeWithoutReference) - The <span id='..' />
tags will be injected with actual values, please leave them unchanged. -->
<!ENTITY certerror.wrongSystemTime "<p> &brandShortName; did not connect to <span id='wrongSystemTime_URL'/> because your computers clock appears to show the wrong time and this is preventing a secure connection.</p> <p>Your computer is set to <span id='wrongSystemTime_systemDate'/>, when it should be <span id='wrongSystemTime_actualDate'/>. To fix this problem, change your date and time settings to match the correct time.</p>">
<!ENTITY certerror.wrongSystemTime2 "<p> &brandShortName; did not connect to <span id='wrongSystemTime_URL'/> because your computers clock appears to show the wrong time and this is preventing a secure connection.</p> <p>Your computer is set to <span id='wrongSystemTime_systemDate'/>, when it should be <span id='wrongSystemTime_actualDate'/>. To fix this problem, change your date and time settings to match the correct time.</p>">
<!ENTITY certerror.wrongSystemTimeWithoutReference "<p>&brandShortName; did not connect to <span id='wrongSystemTimeWithoutReference_URL'/> because your computers clock appears to show the wrong time and this is preventing a secure connection.</p> <p>Your computer is set to <span id='wrongSystemTimeWithoutReference_systemDate'/>. To fix this problem, change your date and time settings to match the correct time.</p>">
<!ENTITY certerror.pagetitle1 "Insecure Connection">

View File

@ -253,7 +253,6 @@ this.ExtensionsUI = {
"webextPerms.hostDescription.tooManySites");
}
let rendered = false;
let popupOptions = {
hideClose: true,
popupIconURL: info.icon,
@ -261,11 +260,6 @@ this.ExtensionsUI = {
eventCallback(topic) {
if (topic == "showing") {
// This check can be removed when bug 1325223 is resolved.
if (rendered) {
return false;
}
let doc = this.browser.ownerDocument;
doc.getElementById("addon-webext-perm-header").innerHTML = header;
@ -287,11 +281,7 @@ this.ExtensionsUI = {
item.textContent = msg;
list.appendChild(item);
}
rendered = true;
} else if (topic == "dismissed") {
rendered = false;
} else if (topic == "swapping") {
rendered = false;
return true;
}
return false;

View File

@ -34,20 +34,29 @@ function* setup() {
});
}
/**
* Used by pre-defined sets of configurations to decide whether to run for a build.
* @note This is not used by browser_screenshots.js which handles when MOZSCREENSHOTS_SETS is set.
* @return {bool} whether to capture screenshots.
*/
function shouldCapture() {
// Try pushes only capture in browser_screenshots.js with MOZSCREENSHOTS_SETS.
if (env.get("MOZSCREENSHOTS_SETS")) {
ok(true, "MOZSCREENSHOTS_SETS was specified so only capture what was " +
"requested (in browser_screenshots.js)");
return false;
}
// Automation isn't able to schedule test jobs to only run on nightlies so we handle it here
// (see also: bug 1116275).
let capture = AppConstants.MOZ_UPDATE_CHANNEL == "nightly" ||
AppConstants.SOURCE_REVISION_URL == "";
if (AppConstants.MOZ_UPDATE_CHANNEL == "nightly") {
ok(true, "Screenshots aren't captured on Nightlies");
return false;
}
// Don't run pre-defined sets (e.g. primaryUI) on try, require MOZSCREENSHOTS_SETS.
// The job is only scheduled on specific repos:
// https://dxr.mozilla.org/build-central/search?q=MOCHITEST_BC_SCREENSHOTS
let capture = !AppConstants.SOURCE_REVISION_URL.includes("/try/rev/");
if (!capture) {
ok(true, "Capturing is disabled for this MOZ_UPDATE_CHANNEL or REPO");
ok(true, "Capturing is disabled for this REPO. You may need to use MOZSCREENSHOTS_SETS");
}
return capture;
}

View File

@ -71,17 +71,5 @@ this.LightweightThemes = {
});
},
},
compactLight: {
applyConfig: Task.async(() => {
LightweightThemeManager.currentTheme = LightweightThemeManager.getUsedTheme("firefox-compact-light@mozilla.org");
}),
},
compactDark: {
applyConfig: Task.async(() => {
LightweightThemeManager.currentTheme = LightweightThemeManager.getUsedTheme("firefox-compact-dark@mozilla.org");
}),
},
},
};

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -5,6 +5,30 @@ var Debugger =
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // SingleModulePlugin
/******/ const smpCache = this.smpCache = this.smpCache || {};
/******/ const smpMap = this.smpMap = this.smpMap || new Map();
/******/ function sanitizeString(text) {
/******/ return text.replace(/__webpack_require__\(\d+\)/g,"");
/******/ }
/******/ function getModuleBody(id) {
/******/ if (smpCache.hasOwnProperty(id)) {
/******/ return smpCache[id];
/******/ }
/******/
/******/ const body = sanitizeString(String(modules[id]));
/******/ smpCache[id] = body;
/******/ return body;
/******/ }
/******/ if (!installedModules[moduleId]) {
/******/ const body = getModuleBody(moduleId);
/******/ if (smpMap.has(body)) {
/******/ installedModules[moduleId] = installedModules[smpMap.get(body)];
/******/ }
/******/ else {
/******/ smpMap.set(body, moduleId)
/******/ }
/******/ }
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId])
@ -35,7 +59,7 @@ var Debugger =
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "/public/build";
/******/ __webpack_require__.p = "/assets/build";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(0);
@ -46,13 +70,34 @@ var Debugger =
/***/ 0:
/***/ function(module, exports, __webpack_require__) {
var prettyFast = __webpack_require__(460);
var assert = __webpack_require__(247);
module.exports = __webpack_require__(543);
/***/ },
/***/ 235:
/***/ function(module, exports) {
function assert(condition, message) {
if (!condition) {
throw new Error(`Assertion failure: ${ message }`);
}
}
module.exports = assert;
/***/ },
/***/ 543:
/***/ function(module, exports, __webpack_require__) {
var prettyFast = __webpack_require__(544);
var assert = __webpack_require__(235);
function prettyPrint(_ref) {
var url = _ref.url;
var indent = _ref.indent;
var source = _ref.source;
var url = _ref.url,
indent = _ref.indent,
source = _ref.source;
try {
var prettified = prettyFast(source, {
@ -65,7 +110,7 @@ var Debugger =
mappings: prettified.map._mappings
};
} catch (e) {
return new Error(e.message + "\n" + e.stack);
return new Error(`${ e.message }\n${ e.stack }`);
}
}
@ -90,17 +135,16 @@ var Debugger =
}
self.onmessage = function (msg) {
var _msg$data = msg.data;
var id = _msg$data.id;
var args = _msg$data.args;
var _msg$data = msg.data,
id = _msg$data.id,
args = _msg$data.args;
assert(msg.data.method === "prettyPrint", "Method must be `prettyPrint`");
try {
var _prettyPrint = prettyPrint(args[0]);
var code = _prettyPrint.code;
var mappings = _prettyPrint.mappings;
var _prettyPrint = prettyPrint(args[0]),
code = _prettyPrint.code,
mappings = _prettyPrint.mappings;
self.postMessage({ id, response: {
code, mappings: invertMappings(mappings)
@ -112,20 +156,7 @@ var Debugger =
/***/ },
/***/ 247:
/***/ function(module, exports) {
function assert(condition, message) {
if (!condition) {
throw new Error("Assertion failure: " + message);
}
}
module.exports = assert;
/***/ },
/***/ 460:
/***/ 544:
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/* -*- indent-tabs-mode: nil; js-indent-level: 2; fill-column: 80 -*- */
@ -147,8 +178,8 @@ var Debugger =
}(this, function () {
"use strict";
var acorn = this.acorn || __webpack_require__(461);
var sourceMap = this.sourceMap || __webpack_require__(462);
var acorn = this.acorn || __webpack_require__(545);
var sourceMap = this.sourceMap || __webpack_require__(546);
var SourceNode = sourceMap.SourceNode;
// If any of these tokens are seen before a "[" token, we know that "[" token
@ -1007,7 +1038,7 @@ var Debugger =
/***/ },
/***/ 461:
/***/ 545:
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// Acorn is a tiny, fast JavaScript parser written in JavaScript.
@ -3667,7 +3698,7 @@ var Debugger =
/***/ },
/***/ 462:
/***/ 546:
/***/ function(module, exports, __webpack_require__) {
/*
@ -3675,14 +3706,14 @@ var Debugger =
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
*/
exports.SourceMapGenerator = __webpack_require__(463).SourceMapGenerator;
exports.SourceMapConsumer = __webpack_require__(469).SourceMapConsumer;
exports.SourceNode = __webpack_require__(471).SourceNode;
exports.SourceMapGenerator = __webpack_require__(547).SourceMapGenerator;
exports.SourceMapConsumer = __webpack_require__(553).SourceMapConsumer;
exports.SourceNode = __webpack_require__(555).SourceNode;
/***/ },
/***/ 463:
/***/ 547:
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- Mode: js; js-indent-level: 2; -*- */
@ -3696,10 +3727,10 @@ var Debugger =
}
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) {
var base64VLQ = __webpack_require__(464);
var util = __webpack_require__(466);
var ArraySet = __webpack_require__(467).ArraySet;
var MappingList = __webpack_require__(468).MappingList;
var base64VLQ = __webpack_require__(548);
var util = __webpack_require__(550);
var ArraySet = __webpack_require__(551).ArraySet;
var MappingList = __webpack_require__(552).MappingList;
/**
* An instance of the SourceMapGenerator represents a source map which is
@ -4089,7 +4120,7 @@ var Debugger =
/***/ },
/***/ 464:
/***/ 548:
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- Mode: js; js-indent-level: 2; -*- */
@ -4133,7 +4164,7 @@ var Debugger =
}
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) {
var base64 = __webpack_require__(465);
var base64 = __webpack_require__(549);
// A single base 64 digit can contain 6 bits of data. For the base 64 variable
// length quantities we use in the source map spec, the first bit is the sign,
@ -4238,7 +4269,7 @@ var Debugger =
/***/ },
/***/ 465:
/***/ 549:
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- Mode: js; js-indent-level: 2; -*- */
@ -4287,7 +4318,7 @@ var Debugger =
/***/ },
/***/ 466:
/***/ 550:
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- Mode: js; js-indent-level: 2; -*- */
@ -4613,7 +4644,7 @@ var Debugger =
/***/ },
/***/ 467:
/***/ 551:
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- Mode: js; js-indent-level: 2; -*- */
@ -4627,7 +4658,7 @@ var Debugger =
}
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) {
var util = __webpack_require__(466);
var util = __webpack_require__(550);
/**
* A data structure which is a combination of an array and a set. Adding a new
@ -4717,7 +4748,7 @@ var Debugger =
/***/ },
/***/ 468:
/***/ 552:
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- Mode: js; js-indent-level: 2; -*- */
@ -4731,7 +4762,7 @@ var Debugger =
}
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) {
var util = __webpack_require__(466);
var util = __webpack_require__(550);
/**
* Determine whether mappingB is after mappingA with respect to generated
@ -4810,7 +4841,7 @@ var Debugger =
/***/ },
/***/ 469:
/***/ 553:
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- Mode: js; js-indent-level: 2; -*- */
@ -4824,10 +4855,10 @@ var Debugger =
}
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) {
var util = __webpack_require__(466);
var binarySearch = __webpack_require__(470);
var ArraySet = __webpack_require__(467).ArraySet;
var base64VLQ = __webpack_require__(464);
var util = __webpack_require__(550);
var binarySearch = __webpack_require__(554);
var ArraySet = __webpack_require__(551).ArraySet;
var base64VLQ = __webpack_require__(548);
/**
* A SourceMapConsumer instance represents a parsed source map which we can
@ -5392,7 +5423,7 @@ var Debugger =
/***/ },
/***/ 470:
/***/ 554:
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- Mode: js; js-indent-level: 2; -*- */
@ -5479,7 +5510,7 @@ var Debugger =
/***/ },
/***/ 471:
/***/ 555:
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- Mode: js; js-indent-level: 2; -*- */
@ -5493,8 +5524,8 @@ var Debugger =
}
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) {
var SourceMapGenerator = __webpack_require__(463).SourceMapGenerator;
var util = __webpack_require__(466);
var SourceMapGenerator = __webpack_require__(547).SourceMapGenerator;
var util = __webpack_require__(550);
// Matches a Windows-style `\r\n` newline or a `\n` newline used by all other
// operating systems these days (capturing the result).

File diff suppressed because it is too large Load Diff

View File

@ -31,8 +31,7 @@ function enableBreakpoint(dbg, index) {
function toggleBreakpoints(dbg) {
return Task.spawn(function* () {
const btn = findElement(dbg, "toggleBreakpoints");
btn.click();
clickElement(dbg, "toggleBreakpoints");
yield waitForDispatch(dbg, "TOGGLE_BREAKPOINTS");
});
}

View File

@ -13,7 +13,7 @@ function getSplitConsole(dbg) {
}
if (!toolbox.splitConsole) {
EventUtils.synthesizeKey("VK_ESCAPE", {}, win);
pressKey(dbg, "Escape");
}
return new Promise(resolve => {
@ -29,6 +29,14 @@ add_task(function* () {
Services.prefs.setBoolPref("devtools.toolbox.splitconsoleEnabled", true);
const dbg = yield initDebugger("doc-script-switching.html");
yield selectSource(dbg, "switching-01");
// open the console
yield getSplitConsole(dbg);
ok(dbg.toolbox.splitConsole, "Split console is shown.");
// close the console
clickElement(dbg, "codeMirror");
pressKey(dbg, "Escape");
ok(!dbg.toolbox.splitConsole, "Split console is hidden.");
});

View File

@ -17,11 +17,6 @@ add_task(function* () {
invokeInTab("firstCall");
yield waitForPaused(dbg);
toggleNode(dbg, 1);
toggleNode(dbg, 2);
yield waitForDispatch(dbg, "LOAD_OBJECT_PROPERTIES");
is(getLabel(dbg, 1), "secondCall");
is(getLabel(dbg, 2), "<this>");
});

View File

@ -15,6 +15,8 @@ add_task(function* () {
const dbg = yield initDebugger("doc-sources.html");
const { selectors: { getSelectedSource }, getState } = dbg;
yield waitForSources(dbg, "simple1");
// Expand nodes and make sure more sources appear.
is(findAllElements(dbg, "sourceNodes").length, 2);

View File

@ -1,96 +0,0 @@
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId])
/******/ return installedModules[moduleId].exports;
/******/
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ exports: {},
/******/ id: moduleId,
/******/ loaded: false
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.loaded = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {
const times2 = __webpack_require__(1);
const { output } = __webpack_require__(2);
const opts = __webpack_require__(3);
output(times2(1));
output(times2(2));
if(opts.extra) {
output(times2(3));
}
window.keepMeAlive = function() {
// This function exists to make sure this script is never garbage
// collected. It is also callable from tests.
return times2(4);
}
/***/ },
/* 1 */
/***/ function(module, exports) {
module.exports = function(x) {
return x * 2;
}
/***/ },
/* 2 */
/***/ function(module, exports) {
function output(str) {
console.log(str);
}
module.exports = { output };
/***/ },
/* 3 */
/***/ function(module, exports) {
module.exports = {
extra: true
};
/***/ }
/******/ ]);
//# sourceMappingURL=bundle.js.map

View File

@ -1 +0,0 @@
{"version":3,"sources":["webpack:///webpack/bootstrap 4ef8c7ec7c1df790781e","webpack:///./entry.js","webpack:///./times2.js","webpack:///./output.js","webpack:///./opts.js"],"names":[],"mappings":";AAAA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,uBAAe;AACf;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;;ACtCA;AACA,QAAO,SAAS;AAChB;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;;;;;;ACfA;AACA;AACA;;;;;;;ACFA;AACA;AACA;;AAEA,mBAAkB;;;;;;;ACJlB;AACA;AACA","file":"bundle.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 4ef8c7ec7c1df790781e","const times2 = require(\"./times2\");\nconst { output } = require(\"./output\");\nconst opts = require(\"./opts\");\n\noutput(times2(1));\noutput(times2(2));\n\nif(opts.extra) {\n output(times2(3));\n}\n\nwindow.keepMeAlive = function() {\n // This function exists to make sure this script is never garbage\n // collected. It is also callable from tests.\n return times2(4);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./entry.js\n// module id = 0\n// module chunks = 0","module.exports = function(x) {\n return x * 2;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./times2.js\n// module id = 1\n// module chunks = 0","function output(str) {\n console.log(str);\n}\n\nmodule.exports = { output };\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./output.js\n// module id = 2\n// module chunks = 0","module.exports = {\n extra: true\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./opts.js\n// module id = 3\n// module chunks = 0"],"sourceRoot":""}

View File

@ -38,6 +38,9 @@ var { Toolbox } = require("devtools/client/framework/toolbox");
const EXAMPLE_URL = "http://example.com/browser/devtools/client/debugger/new/test/mochitest/examples/";
Services.prefs.setBoolPref("devtools.debugger.new-debugger-frontend", true);
Services.prefs.clearUserPref("devtools.debugger.tabs")
Services.prefs.clearUserPref("devtools.debugger.pending-selected-location")
registerCleanupFunction(() => {
Services.prefs.clearUserPref("devtools.debugger.new-debugger-frontend");
delete window.resumeTest;
@ -301,6 +304,8 @@ function createDebuggerContext(toolbox) {
*/
function initDebugger(url, ...sources) {
return Task.spawn(function* () {
Services.prefs.clearUserPref("devtools.debugger.tabs")
Services.prefs.clearUserPref("devtools.debugger.pending-selected-location")
const toolbox = yield openNewTabAndToolbox(EXAMPLE_URL + url, "jsdebugger");
return createDebuggerContext(toolbox);
});
@ -534,6 +539,7 @@ const keyMappings = {
"Enter": { code: "VK_RETURN" },
"Up": { code: "VK_UP" },
"Down": { code: "VK_DOWN" },
"Escape": { code: "VK_ESCAPE" },
pauseKey: { code: "VK_F8" },
resumeKey: { code: "VK_F8" },
stepOverKey: { code: "VK_F10" },
@ -592,7 +598,7 @@ const selectors = {
stepOver: ".stepOver.active",
stepOut: ".stepOut.active",
stepIn: ".stepIn.active",
toggleBreakpoints: ".toggleBreakpoints",
toggleBreakpoints: ".breakpoints-toggle",
prettyPrintButton: ".prettyPrint",
sourceFooter: ".source-footer",
sourceNode: i => `.sources-list .tree-node:nth-child(${i})`,

View File

@ -31,6 +31,7 @@ devtools.jar:
content/sourceeditor/codemirror/codemirror.bundle.js (sourceeditor/codemirror/codemirror.bundle.js)
content/sourceeditor/codemirror/lib/codemirror.css (sourceeditor/codemirror/lib/codemirror.css)
content/sourceeditor/codemirror/mozilla.css (sourceeditor/codemirror/mozilla.css)
content/sourceeditor/codemirror/old-debugger.css (sourceeditor/codemirror/old-debugger.css)
content/debugger/new/index.html (debugger/new/index.html)
content/debugger/new/images/angle-brackets.svg (debugger/new/images/angle-brackets.svg)
content/debugger/new/images/arrow.svg (debugger/new/images/arrow.svg)

View File

@ -20,7 +20,7 @@ expandPanes=Expand panes
# LOCALIZATION NOTE (pauseButtonTooltip): The tooltip that is displayed for the pause
# button when the debugger is in a running state.
pauseButtonTooltip=Click to pause (%S)
pauseButtonTooltip=Pause %S
# LOCALIZATION NOTE (pausePendingButtonTooltip): The tooltip that is displayed for
# the pause button after it's been clicked but before the next JavaScript to run.
@ -28,19 +28,19 @@ pausePendingButtonTooltip=Waiting for next execution
# LOCALIZATION NOTE (resumeButtonTooltip): The label that is displayed on the pause
# button when the debugger is in a paused state.
resumeButtonTooltip=Click to resume (%S)
resumeButtonTooltip=Resume %S
# LOCALIZATION NOTE (stepOverTooltip): The label that is displayed on the
# button that steps over a function call.
stepOverTooltip=Step Over (%S)
stepOverTooltip=Step Over %S
# LOCALIZATION NOTE (stepInTooltip): The label that is displayed on the
# button that steps into a function call.
stepInTooltip=Step In (%S)
stepInTooltip=Step In %S
# LOCALIZATION NOTE (stepOutTooltip): The label that is displayed on the
# button that steps out of a function call.
stepOutTooltip=Step Out (%S)
stepOutTooltip=Step Out %S
# LOCALIZATION NOTE (noWorkersText): The text to display in the workers list
# when there are no workers.
@ -54,6 +54,10 @@ noSourcesText=This page has no sources.
# when there are no events.
noEventListenersText=No event listeners to display
# LOCALIZATION NOTE (eventListenersHeader): The text to display in the events
# header.
eventListenersHeader=Event Listeners
# LOCALIZATION NOTE (noStackFramesText): The text to display in the call stack tab
# when there are no stack frames.
noStackFramesText=No stack frames to display
@ -108,6 +112,22 @@ otherEvents=Other
# source.
blackBoxCheckboxTooltip=Toggle black boxing
# LOCALIZATION NOTE (sources.search.key): Key shortcut to open the search for
# searching all the source files the debugger has seen.
sources.search.key=P
# LOCALIZATION NOTE (sourceSearch.search.key): Key shortcut to open the search
# for searching within a the currently opened files in the editor
sourceSearch.search.key=F
# LOCALIZATION NOTE (sourceSearch.search.again.key): Key shortcut to re-open
# the search for re-searching the same search triggered from a sourceSearch
sourceSearch.search.again.key=G
# LOCALIZATION NOTE (sourceSearch.search.resultsSummary): Shows a summary of
# the number of matches for autocomplete
sourceSearch.resultsSummary=%d instances of “%S”
# LOCALIZATION NOTE (noMatchingStringsText): The text to display in the
# global search results when there are no matching strings after filtering.
noMatchingStringsText=No matches found
@ -164,6 +184,22 @@ breakpointMenuItem.deleteAll=Remove all breakpoints
# LOCALIZATION NOTE (breakpoints.header): Breakpoints right sidebar pane header.
breakpoints.header=Breakpoints
# LOCALIZATION NOTE (breakpoints.none): The text that appears when there are
# no breakpoints present
breakpoints.none=No Breakpoints
# LOCALIZATION NOTE (breakpoints.enable): The text that may appear as a tooltip
# when hovering over the 'disable breakpoints' switch button in right sidebar
breakpoints.enable=Enable Breakpoints
# LOCALIZATION NOTE (breakpoints.disable): The text that may appear as a tooltip
# when hovering over the 'disable breakpoints' switch button in right sidebar
breakpoints.disable=Disable Breakpoints
# LOCALIZATION NOTE (breakpoints.removeBreakpointTooltip): The tooltip that is displayed
# for remove breakpoint button in right sidebar
breakpoints.removeBreakpointTooltip=Remove Breakpoint
# LOCALIZATION NOTE (callStack.header): Call Stack right sidebar pane header.
callStack.header=Call Stack
@ -187,22 +223,48 @@ editor.searchResults=%d of %d results
# for when no results found.
editor.noResults=no results
# LOCALIZATION NOTE(editor.addBreakpoint): Editor gutter context menu item
# LOCALIZATION NOTE (editor.addBreakpoint): Editor gutter context menu item
# for adding a breakpoint on a line.
editor.addBreakpoint=Add Breakpoint
# LOCALIZATION NOTE(editor.removeBreakpoint): Editor gutter context menu item
# LOCALIZATION NOTE (editor.disableBreakpoint): Editor gutter context menu item
# for disabling a breakpoint on a line.
editor.disableBreakpoint=Disable Breakpoint
# LOCALIZATION NOTE (editor.enableBreakpoint): Editor gutter context menu item
# for enabling a breakpoint on a line.
editor.enableBreakpoint=Enable Breakpoint
# LOCALIZATION NOTE (editor.removeBreakpoint): Editor gutter context menu item
# for removing a breakpoint on a line.
editor.removeBreakpoint=Remove Breakpoint
# LOCALIZATION NOTE(editor.editBreakpoint): Editor gutter context menu item
# LOCALIZATION NOTE (editor.editBreakpoint): Editor gutter context menu item
# for setting a breakpoint condition on a line.
editor.editBreakpoint=Edit Breakpoint
# LOCALIZATION NOTE(editor.addConditionalBreakpoint): Editor gutter context
# LOCALIZATION NOTE (editor.addConditionalBreakpoint): Editor gutter context
# menu item for adding a breakpoint condition on a line.
editor.addConditionalBreakpoint=Add Conditional Breakpoint
# LOCALIZATION NOTE (editor.conditionalPanel.placeholder): Placeholder text for
# input element inside ConditionalPanel component
editor.conditionalPanel.placeholder=This breakpoint will pause when the expression is true
# LOCALIZATION NOTE (editor.jumpToMappedLocation): Context menu item
# for navigating to a source mapped location
editor.jumpToMappedLocation=Jump to %s location
# LOCALIZATION NOTE (generated): Source Map term for a server source location
generated=generated
# LOCALIZATION NOTE (original): Source Map term for a debugger UI source location
original=original
# LOCALIZATION NOTE (expressions.placeholder): Placeholder text for expression
# input element
expressions.placeholder=Add Watch Expression
# LOCALIZATION NOTE (sourceTabs.closeTab): Editor source tab context menu item
# for closing the selected tab below the mouse.
sourceTabs.closeTab=Close tab
@ -219,6 +281,14 @@ sourceTabs.closeTabsToRight=Close tabs to the right
# for closing all tabs.
sourceTabs.closeAllTabs=Close all tabs
# LOCALIZATION NOTE (sourceTabs.closeTabButtonTooltip): The tooltip that is displayed
# for close tab button in source tabs.
sourceTabs.closeTabButtonTooltip=Close tab
# LOCALIZATION NOTE (sourceTabs.newTabButtonTooltip): The tooltip that is displayed for
# new tab button in source tabs.
sourceTabs.newTabButtonTooltip=Search for sources (%S)
# LOCALIZATION NOTE (scopes.header): Scopes right sidebar pane header.
scopes.header=Scopes
@ -230,6 +300,9 @@ scopes.notAvailable=Scopes Unavailable
# for when the debugger is not paused.
scopes.notPaused=Not Paused
# LOCALIZATION NOTE (scopes.block): Scopes right sidebar block subheading
scopes.block=Block
# LOCALIZATION NOTE (sources.header): Sources left sidebar header
sources.header=Sources
@ -242,19 +315,27 @@ sources.search=%S to search
# pane header.
watchExpressions.header=Watch Expressions
# LOCALIZATION NOTE (watchExpressions.refreshButton): Watch Expressions header
# button for refreshing the expressions.
watchExpressions.refreshButton=Refresh
# LOCALIZATION NOTE (welcome.search): The center pane welcome panel's
# search prompt. e.g. cmd+p to search for files. On windows, it's ctrl, on
# a mac we use the unicode character.
welcome.search=%S to search for files
welcome.search=%S to search for sources
# LOCALIZATION NOTE (sourceSearch.search): The center pane Source Search
# prompt for searching for files.
sourceSearch.search=Search
sourceSearch.search=Search Sources
# LOCALIZATION NOTE (sourceSearch.noResults): The center pane Source Search
# message when the query did not match any of the sources.
sourceSearch.noResults=No files matching %S found
# LOCALIZATION NOTE (sourceFooter.debugBtnTooltip): Tooltip text associated
# with the pretty-print button
sourceFooter.debugBtnTooltip=Prettify Source
# LOCALIZATION NOTE (ignoreExceptions): The pause on exceptions button tooltip
# when the debugger will not pause on exceptions.
ignoreExceptions=Ignore exceptions. Click to pause on uncaught exceptions
@ -381,3 +462,51 @@ variablesViewMissingArgs=(unavailable)
anonymousSourcesLabel=Anonymous Sources
experimental=This is an experimental feature
# LOCALIZATION NOTE (whyPaused.debuggerStatement): The text that is displayed
# in a info block explaining how the debugger is currently paused due to a `debugger`
# statement in the code
whyPaused.debuggerStatement=Paused on debugger statement
# LOCALIZATION NOTE (whyPaused.breakpoint): The text that is displayed
# in a info block explaining how the debugger is currently paused on a breakpoint
whyPaused.breakpoint=Paused on breakpoint
# LOCALIZATION NOTE (whyPaused.exception): The text that is displayed
# in a info block explaining how the debugger is currently paused on an exception
whyPaused.exception=Paused on exception
# LOCALIZATION NOTE (whyPaused.resumeLimit): The text that is displayed
# in a info block explaining how the debugger is currently paused while stepping
# in or out of the stack
whyPaused.resumeLimit=Paused while stepping
# LOCALIZATION NOTE (whyPaused.pauseOnDOMEvents): The text that is displayed
# in a info block explaining how the debugger is currently paused on a
# dom event
whyPaused.pauseOnDOMEvents=Paused on event listener
# LOCALIZATION NOTE (whyPaused.xhr): The text that is displayed
# in a info block explaining how the debugger is currently paused on an
# xml http request
whyPaused.xhr=Paused on XMLHttpRequest
# LOCALIZATION NOTE (whyPaused.promiseRejection): The text that is displayed
# in a info block explaining how the debugger is currently paused on a
# promise rejection
whyPaused.promiseRejection=Paused on promise rejection
# LOCALIZATION NOTE (whyPaused.assert): The text that is displayed
# in a info block explaining how the debugger is currently paused on an
# assert
whyPaused.assert=Paused on assertion
# LOCALIZATION NOTE (whyPaused.debugCommand): The text that is displayed
# in a info block explaining how the debugger is currently paused on a
# debugger statement
whyPaused.debugCommand=Paused on debugged function
# LOCALIZATION NOTE (whyPaused.other): The text that is displayed
# in a info block explaining how the debugger is currently paused on an event
# listener breakpoint set
whyPaused.other=Debugger paused

View File

@ -0,0 +1,11 @@
{
"name": "devtools",
"version": "0.0.1",
"description": "Devtools",
"dependencies": {
"debugger.html": "0.0.13"
},
"devDependencies": {
"dir-compare": "^1.3.0"
}
}

View File

@ -107,7 +107,12 @@ pref("devtools.debugger.pretty-print-enabled", true);
pref("devtools.debugger.auto-pretty-print", false);
pref("devtools.debugger.auto-black-box", true);
pref("devtools.debugger.workers", false);
#ifdef RELEASE_OR_BETA
pref("devtools.debugger.new-debugger-frontend", false);
#else
pref("devtools.debugger.new-debugger-frontend", true);
#endif
// The default Debugger UI settings
pref("devtools.debugger.ui.panes-workers-and-sources-width", 200);
@ -116,6 +121,12 @@ pref("devtools.debugger.ui.panes-visible-on-startup", false);
pref("devtools.debugger.ui.variables-sorting-enabled", true);
pref("devtools.debugger.ui.variables-only-enum-visible", false);
pref("devtools.debugger.ui.variables-searchbox-visible", false);
pref("devtools.debugger.call-stack-visible", false);
pref("devtools.debugger.scopes-visible", false);
pref("devtools.debugger.start-panel-collapsed", false);
pref("devtools.debugger.end-panel-collapsed", false);
pref("devtools.debugger.tabs", "[]");
pref("devtools.debugger.pending-selected-location", "{}");
// Enable the Memory tools
pref("devtools.memory.enabled", true);

View File

@ -2,23 +2,15 @@
* 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/. */
:root {
--breakpoint-background: url("chrome://devtools/skin/images/breakpoint.svg#light");
--breakpoint-hover-background: url("chrome://devtools/skin/images/breakpoint.svg#light-hover");
--breakpoint-active-color: rgba(44,187,15,.2);
--breakpoint-conditional-background: url("chrome://devtools/skin/images/breakpoint.svg#light-conditional");
--breakpoint-active-color-hover: rgba(44,187,15,.5);
}
.theme-dark:root {
--breakpoint-background: url("chrome://devtools/skin/images/breakpoint.svg#dark");
--breakpoint-hover-background: url("chrome://devtools/skin/images/breakpoint.svg#dark-hover");
--breakpoint-active-color: rgba(112,191,83,.4);
--breakpoint-conditional-background: url("chrome://devtools/skin/images/breakpoint.svg#dark-conditional");
}
.CodeMirror {
height: 100%;
cursor: text;
--breakpoint-active-color: rgba(0,255,175,.4);
--breakpoint-active-color-hover: rgba(0,255,175,.7);
}
.CodeMirror .errors {
@ -33,7 +25,6 @@
background-repeat: no-repeat;
background-position: center;
background-size: contain;
background-image: url("chrome://devtools/skin/images/editor-error.png");
opacity: 0.75;
}
@ -71,14 +62,6 @@
color: var(--theme-body-background);
}
.breakpoint .CodeMirror-linenumber:before {
background-image: var(--breakpoint-background) !important;
}
.conditional .CodeMirror-linenumber:before {
background-image: var(--breakpoint-conditional-background) !important;
}
.debug-line .CodeMirror-linenumber {
background-color: var(--breakpoint-active-color);
}
@ -97,6 +80,11 @@
display: none;
}
.CodeMirror {
cursor: text;
height: 100%;
}
.CodeMirror-gutters {
cursor: default;
}
@ -124,6 +112,48 @@ selector in floating-scrollbar-light.css across all platforms. */
background-repeat: repeat-x;
}
.cm-highlight {
position: relative;
}
.cm-highlight:before {
position: absolute;
border-top-style: solid;
border-bottom-style: solid;
border-top-color: var(--theme-comment-alt);
border-bottom-color: var(--theme-comment-alt);
border-top-width: 1px;
border-bottom-width: 1px;
top: -1px;
bottom: 0;
left: 0;
right: 0;
content: "";
margin-bottom: -1px;
}
.cm-highlight-full:before {
border: 1px solid var(--theme-comment-alt);
}
.cm-highlight-start:before {
border-left-width: 1px;
border-left-style: solid;
border-left-color: var(--theme-comment-alt);
margin: 0 0 -1px -1px;
border-top-left-radius: 2px;
border-bottom-left-radius: 2px;
}
.cm-highlight-end:before {
border-right-width: 1px;
border-right-style: solid;
border-right-color: var(--theme-comment-alt);
margin: 0 -1px -1px 0;
border-top-right-radius: 2px;
border-bottom-right-radius: 2px;
}
/* CodeMirror dialogs styling */
.CodeMirror-dialog {

View File

@ -0,0 +1,23 @@
:root {
--breakpoint-background: url("chrome://devtools/skin/images/breakpoint.svg#light");
--breakpoint-hover-background: url("chrome://devtools/skin/images/breakpoint.svg#light-hover");
--breakpoint-conditional-background: url("chrome://devtools/skin/images/breakpoint.svg#light-conditional");
}
.theme-dark:root {
--breakpoint-background: url("chrome://devtools/skin/images/breakpoint.svg#dark");
--breakpoint-hover-background: url("chrome://devtools/skin/images/breakpoint.svg#dark-hover");
--breakpoint-conditional-background: url("chrome://devtools/skin/images/breakpoint.svg#dark-conditional");
}
.breakpoint .CodeMirror-linenumber:before {
background-image: var(--breakpoint-background) !important;
}
.conditional .CodeMirror-linenumber:before {
background-image: var(--breakpoint-conditional-background) !important;
}
.CodeMirror .error {
background-image: url("chrome://devtools/skin/images/editor-error.png");
}

View File

@ -51,6 +51,10 @@ const CM_STYLES = [
"chrome://devtools/content/sourceeditor/codemirror/mozilla.css"
];
CM_STYLES.push(
"chrome://devtools/content/sourceeditor/codemirror/old-debugger.css"
);
const CM_SCRIPTS = [
"chrome://devtools/content/sourceeditor/codemirror/codemirror.bundle.js",
];

View File

@ -0,0 +1,104 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* 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";
/* global process */
/*
Update Tools is responsible for synking projects in github and mc
1. checking if assets have changed
2. updating assets in m-c
### Check for changes
```
node update-tools.js --check
```
### Update Assets
```
node update-tools.js --update
```
*/
const ps = require("child_process");
const fs = require("fs");
const { dirname } = require("path");
var dircompare = require("dir-compare");
/*eslint-disable */
const paths = [
"./node_modules/debugger.html/assets/build/debugger.js ./debugger/new/debugger.js",
"./node_modules/debugger.html/assets/build/source-map-worker.js ./debugger/new/source-map-worker.js",
"./node_modules/debugger.html/assets/build/pretty-print-worker.js ./debugger/new/pretty-print-worker.js",
"./node_modules/debugger.html/assets/build/debugger.css ./debugger/new/debugger.css",
"./node_modules/debugger.html/assets/build/debugger.properties ./locales/en-US/debugger.properties",
"./node_modules/debugger.html/assets/build/codemirror-mozilla.css ./sourceeditor/codemirror/mozilla.css",
];
const dirs = [
"./node_modules/debugger.html/assets/build/mochitest ./debugger/new/test/mochitest"
];
/*eslint-enable */
function isDirectory(path) {
return fs.statSync(path).isDirectory();
}
function checkFile(path) {
const result = ps.spawnSync(`diff`, path.split(" "), {
encoding: "utf8"
});
const stdout = result.output[1].trim();
return stdout.length > 0;
}
function copyFile(path) {
const [ghPath, mcFile] = path.split(" ");
const destPath = isDirectory(mcFile) ? dirname(mcFile) : mcFile;
ps.execSync(`cp -r ${ghPath} ${destPath}`);
}
function checkAssets() {
paths.forEach(path => {
if (checkFile(path)) {
console.log(`Changed: diff: ${path}`);
}
});
dirs.forEach(dir => {
const filesChanged = checkDir(dir);
if (filesChanged) {
filesChanged.forEach(file => {
const { name1, path1, name2, path2 } = file;
console.log(`Changed: diff ${path1}/${name1} ${path2}/${name2}`);
});
}
});
}
function checkDir(path) {
const [ghDir, mcDir] = path.split(" ");
const res = dircompare.compareSync(ghDir, mcDir, { compareSize: true });
return res.diffSet.filter(entry => entry.state != "equal");
}
function copyAssets(files) {
paths.forEach(copyFile);
dirs.forEach(copyFile);
}
if (process.argv.includes("--check")) {
checkAssets();
}
if (process.argv.includes("--update")) {
copyAssets();
}

View File

@ -656,7 +656,7 @@ skip-if = (toolkit == 'android') # Android: Bug 775227
[test_innersize_scrollport.html]
[test_integer_attr_with_leading_zero.html]
[test_intersectionobservers.html]
skip-if = true # Track Bug 1320704
skip-if = (os == "android") # Timing issues
[test_link_prefetch.html]
skip-if = !e10s # Track Bug 1281415
[test_link_stylesheet.html]

View File

@ -1,5 +1,5 @@
[DEFAULT]
skip-if = e10s || toolkit == 'android' # Bug 1287720: takes too long on android
skip-if = e10s
support-files =
audio.ogg

View File

@ -57,6 +57,8 @@ AudioTrackEncoder::NotifyQueuedTrackChanges(MediaStreamGraph* aGraph,
uint32_t aTrackEvents,
const MediaSegment& aQueuedMedia)
{
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
if (mCanceled) {
return;
}
@ -109,13 +111,14 @@ AudioTrackEncoder::NotifyQueuedTrackChanges(MediaStreamGraph* aGraph,
void
AudioTrackEncoder::NotifyEndOfStream()
{
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
// If source audio track is completely silent till the end of encoding,
// initialize the encoder with default channel counts and sampling rate.
if (!mCanceled && !mInitialized) {
Init(DEFAULT_CHANNELS, DEFAULT_SAMPLING_RATE);
}
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
mEndOfStream = true;
mReentrantMonitor.NotifyAll();
}
@ -195,6 +198,8 @@ AudioTrackEncoder::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) cons
void
VideoTrackEncoder::Init(const VideoSegment& aSegment)
{
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
if (mInitialized) {
return;
}
@ -227,12 +232,13 @@ VideoTrackEncoder::Init(const VideoSegment& aSegment)
NotifyEndOfStream();
return;
}
}
void
VideoTrackEncoder::SetCurrentFrames(const VideoSegment& aSegment)
{
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
if (mCanceled) {
return;
}
@ -248,6 +254,8 @@ VideoTrackEncoder::NotifyQueuedTrackChanges(MediaStreamGraph* aGraph,
uint32_t aTrackEvents,
const MediaSegment& aQueuedMedia)
{
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
if (mCanceled) {
return;
}
@ -277,6 +285,11 @@ VideoTrackEncoder::AppendVideoSegment(const VideoSegment& aSegment)
{
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
if (mEndOfStream) {
MOZ_ASSERT(false);
return NS_OK;
}
// Append all video segments from MediaStreamGraph, including null an
// non-null frames.
VideoSegment::ConstChunkIterator iter(aSegment);
@ -296,15 +309,19 @@ VideoTrackEncoder::AppendVideoSegment(const VideoSegment& aSegment)
MOZ_ASSERT(!chunk.mTimeStamp.IsNull());
const StreamTime nullDuration = mLastChunk.mDuration;
mLastChunk = chunk;
chunk.mDuration = 0;
TRACK_LOG(LogLevel::Verbose,
("[VideoTrackEncoder]: Got first video chunk after %lld ticks.",
nullDuration));
// Adapt to the time before the first frame. This extends the first frame
// from [start, end] to [0, end], but it'll do for now.
mLastChunk.mTimeStamp -=
TimeDuration::FromMicroseconds(
RateConvertTicksRoundUp(PR_USEC_PER_SEC, mTrackRate, nullDuration));
CheckedInt64 diff = FramesToUsecs(nullDuration, mTrackRate);
MOZ_ASSERT(diff.isValid());
if (diff.isValid()) {
mLastChunk.mTimeStamp -= TimeDuration::FromMicroseconds(diff.value());
mLastChunk.mDuration += nullDuration;
}
}
MOZ_ASSERT(!mLastChunk.IsNull());
@ -330,6 +347,9 @@ VideoTrackEncoder::AppendVideoSegment(const VideoSegment& aSegment)
// to the encoder to make sure there is some output.
chunk.mTimeStamp = mLastChunk.mTimeStamp + TimeDuration::FromSeconds(1);
// chunk's duration has already been accounted for.
chunk.mDuration = 0;
if (chunk.IsNull()) {
// Ensure that we don't pass null to the encoder by making mLastChunk
// null later on.
@ -353,14 +373,16 @@ VideoTrackEncoder::AppendVideoSegment(const VideoSegment& aSegment)
TRACK_LOG(LogLevel::Verbose,
("[VideoTrackEncoder]: Appending video frame %p, duration=%.5f",
lastImage.get(), diff.ToSeconds()));
mRawSegment.AppendFrame(lastImage.forget(),
RateConvertTicksRoundUp(
mTrackRate, PR_USEC_PER_SEC,
diff.ToMicroseconds()),
mLastChunk.mFrame.GetIntrinsicSize(),
PRINCIPAL_HANDLE_NONE,
mLastChunk.mFrame.GetForceBlack(),
mLastChunk.mTimeStamp);
CheckedInt64 duration = UsecsToFrames(diff.ToMicroseconds(), mTrackRate);
MOZ_ASSERT(duration.isValid());
if (duration.isValid()) {
mRawSegment.AppendFrame(lastImage.forget(),
duration.value(),
mLastChunk.mFrame.GetIntrinsicSize(),
PRINCIPAL_HANDLE_NONE,
mLastChunk.mFrame.GetForceBlack(),
mLastChunk.mTimeStamp);
}
}
mLastChunk = chunk;
@ -376,6 +398,8 @@ VideoTrackEncoder::AppendVideoSegment(const VideoSegment& aSegment)
void
VideoTrackEncoder::NotifyEndOfStream()
{
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
// If source video track is muted till the end of encoding, initialize the
// encoder with default frame width, frame height, and track rate.
if (!mCanceled && !mInitialized) {
@ -383,8 +407,27 @@ VideoTrackEncoder::NotifyEndOfStream()
DEFAULT_FRAME_WIDTH, DEFAULT_FRAME_HEIGHT);
}
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
if (mEndOfStream) {
// We have already been notified.
return;
}
mEndOfStream = true;
TRACK_LOG(LogLevel::Info, ("[VideoTrackEncoder]: Reached end of stream"));
if (!mLastChunk.IsNull() && mLastChunk.mDuration > 0) {
RefPtr<layers::Image> lastImage = mLastChunk.mFrame.GetImage();
TRACK_LOG(LogLevel::Debug,
("[VideoTrackEncoder]: Appending last video frame %p, "
"duration=%.5f", lastImage.get(),
FramesToTimeUnit(mLastChunk.mDuration, mTrackRate).ToSeconds()));
mRawSegment.AppendFrame(lastImage.forget(),
mLastChunk.mDuration,
mLastChunk.mFrame.GetIntrinsicSize(),
PRINCIPAL_HANDLE_NONE,
mLastChunk.mFrame.GetForceBlack(),
mLastChunk.mTimeStamp);
}
mReentrantMonitor.NotifyAll();
}

View File

@ -19,9 +19,9 @@
namespace mozilla {
LazyLogModule gVP8TrackEncoderLog("VP8TrackEncoder");
#define VP8LOG(msg, ...) MOZ_LOG(gVP8TrackEncoderLog, mozilla::LogLevel::Debug, \
(msg, ##__VA_ARGS__))
// Debug logging macro with object pointer and class name.
#define VP8LOG(level, msg, ...) MOZ_LOG(gVP8TrackEncoderLog, \
level, \
(msg, ##__VA_ARGS__))
#define DEFAULT_BITRATE_BPS 2500000
@ -229,9 +229,10 @@ VP8TrackEncoder::GetEncodedPartitions(EncodedFrameContainer& aData)
videoData->SetDuration((uint64_t)duration.value());
}
videoData->SwapInFrameData(frameData);
VP8LOG("GetEncodedPartitions TimeStamp %lld Duration %lld\n",
videoData->GetTimeStamp(), videoData->GetDuration());
VP8LOG("frameType %d\n", videoData->GetFrameType());
VP8LOG(LogLevel::Verbose,
"GetEncodedPartitions TimeStamp %lld, Duration %lld, FrameType %d",
videoData->GetTimeStamp(), videoData->GetDuration(),
videoData->GetFrameType());
aData.AppendEncodedFrame(videoData);
}
@ -277,7 +278,8 @@ nsresult VP8TrackEncoder::PrepareRawFrame(VideoChunk &aChunk)
}
if (img->GetSize() != IntSize(mFrameWidth, mFrameHeight)) {
VP8LOG("Dynamic resolution changes (was %dx%d, now %dx%d) are unsupported\n",
VP8LOG(LogLevel::Error,
"Dynamic resolution changes (was %dx%d, now %dx%d) are unsupported",
mFrameWidth, mFrameHeight, img->GetSize().width, img->GetSize().height);
return NS_ERROR_FAILURE;
}
@ -370,29 +372,29 @@ nsresult VP8TrackEncoder::PrepareRawFrame(VideoChunk &aChunk)
mFrameWidth, mFrameHeight);
yuvFormat = "I422";
} else {
VP8LOG("Unsupported planar format\n");
VP8LOG(LogLevel::Error, "Unsupported planar format");
NS_ASSERTION(false, "Unsupported planar format");
return NS_ERROR_NOT_IMPLEMENTED;
}
if (rv != 0) {
VP8LOG("Converting an %s frame to I420 failed\n", yuvFormat.c_str());
VP8LOG(LogLevel::Error, "Converting an %s frame to I420 failed", yuvFormat.c_str());
return NS_ERROR_FAILURE;
}
VP8LOG("Converted an %s frame to I420\n", yuvFormat.c_str());
VP8LOG(LogLevel::Verbose, "Converted an %s frame to I420", yuvFormat.c_str());
} else {
// Not YCbCr at all. Try to get access to the raw data and convert.
RefPtr<SourceSurface> surf = GetSourceSurface(img.forget());
if (!surf) {
VP8LOG("Getting surface from %s image failed\n", Stringify(format).c_str());
VP8LOG(LogLevel::Error, "Getting surface from %s image failed", Stringify(format).c_str());
return NS_ERROR_FAILURE;
}
RefPtr<DataSourceSurface> data = surf->GetDataSurface();
if (!data) {
VP8LOG("Getting data surface from %s image with %s (%s) surface failed\n",
VP8LOG(LogLevel::Error, "Getting data surface from %s image with %s (%s) surface failed",
Stringify(format).c_str(), Stringify(surf->GetType()).c_str(),
Stringify(surf->GetFormat()).c_str());
return NS_ERROR_FAILURE;
@ -400,7 +402,7 @@ nsresult VP8TrackEncoder::PrepareRawFrame(VideoChunk &aChunk)
DataSourceSurface::ScopedMap map(data, DataSourceSurface::READ);
if (!map.IsMapped()) {
VP8LOG("Reading DataSourceSurface from %s image with %s (%s) surface failed\n",
VP8LOG(LogLevel::Error, "Reading DataSourceSurface from %s image with %s (%s) surface failed",
Stringify(format).c_str(), Stringify(surf->GetType()).c_str(),
Stringify(surf->GetFormat()).c_str());
return NS_ERROR_FAILURE;
@ -426,20 +428,20 @@ nsresult VP8TrackEncoder::PrepareRawFrame(VideoChunk &aChunk)
mFrameWidth, mFrameHeight);
break;
default:
VP8LOG("Unsupported SourceSurface format %s\n",
VP8LOG(LogLevel::Error, "Unsupported SourceSurface format %s",
Stringify(surf->GetFormat()).c_str());
NS_ASSERTION(false, "Unsupported SourceSurface format");
return NS_ERROR_NOT_IMPLEMENTED;
}
if (rv != 0) {
VP8LOG("%s to I420 conversion failed\n",
VP8LOG(LogLevel::Error, "%s to I420 conversion failed",
Stringify(surf->GetFormat()).c_str());
return NS_ERROR_FAILURE;
}
VP8LOG("Converted a %s frame to I420\n",
Stringify(surf->GetFormat()).c_str());
VP8LOG(LogLevel::Verbose, "Converted a %s frame to I420",
Stringify(surf->GetFormat()).c_str());
}
mVPXImageWrapper->planes[VPX_PLANE_Y] = y;
@ -527,8 +529,8 @@ VP8TrackEncoder::GetEncodedTrack(EncodedFrameContainer& aData)
for (VideoSegment::ChunkIterator iter(mSourceSegment);
!iter.IsEnded(); iter.Next()) {
VideoChunk &chunk = *iter;
VP8LOG("nextEncodeOperation is %d for frame of duration %lld\n",
nextEncodeOperation, chunk.GetDuration());
VP8LOG(LogLevel::Verbose, "nextEncodeOperation is %d for frame of duration %lld",
nextEncodeOperation, chunk.GetDuration());
// Encode frame.
if (nextEncodeOperation != SKIP_FRAME) {
@ -536,8 +538,11 @@ VP8TrackEncoder::GetEncodedTrack(EncodedFrameContainer& aData)
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
// Encode the data with VP8 encoder
int flags = (nextEncodeOperation == ENCODE_NORMAL_FRAME) ?
0 : VPX_EFLAG_FORCE_KF;
int flags = 0;
if (nextEncodeOperation == ENCODE_I_FRAME) {
VP8LOG(LogLevel::Warning, "MediaRecorder lagging behind. Encoding keyframe.");
flags |= VPX_EFLAG_FORCE_KF;
}
if (vpx_codec_encode(mVPXContext, mVPXImageWrapper, mEncodedTimestamp,
(unsigned long)chunk.GetDuration(), flags,
VPX_DL_REALTIME)) {
@ -549,7 +554,7 @@ VP8TrackEncoder::GetEncodedTrack(EncodedFrameContainer& aData)
// SKIP_FRAME
// Extend the duration of the last encoded data in aData
// because this frame will be skip.
NS_WARNING("MediaRecorder lagging behind. Skipping a frame.");
VP8LOG(LogLevel::Warning, "MediaRecorder lagging behind. Skipping a frame.");
RefPtr<EncodedFrame> last = aData.GetEncodedFrames().LastElement();
if (last) {
last->SetDuration(last->GetDuration() + chunk.GetDuration());
@ -571,7 +576,7 @@ VP8TrackEncoder::GetEncodedTrack(EncodedFrameContainer& aData)
// End of stream, pull the rest frames in encoder.
if (EOS) {
VP8LOG("mEndOfStream is true\n");
VP8LOG(LogLevel::Debug, "mEndOfStream is true");
mEncodingComplete = true;
// Bug 1243611, keep calling vpx_codec_encode and vpx_codec_get_cx_data
// until vpx_codec_get_cx_data return null.

View File

@ -46,11 +46,19 @@ public:
return mImageSize;
}
void Generate(nsTArray<RefPtr<Image> > &aImages)
already_AddRefed<Image> GenerateI420Image()
{
aImages.AppendElement(CreateI420Image());
aImages.AppendElement(CreateNV12Image());
aImages.AppendElement(CreateNV21Image());
return do_AddRef(CreateI420Image());
}
already_AddRefed<Image> GenerateNV12Image()
{
return do_AddRef(CreateNV12Image());
}
already_AddRefed<Image> GenerateNV21Image()
{
return do_AddRef(CreateNV21Image());
}
private:
@ -260,7 +268,9 @@ TEST(VP8VideoTrackEncoder, FrameEncode)
nsTArray<RefPtr<Image>> images;
YUVBufferGenerator generator;
generator.Init(mozilla::gfx::IntSize(640, 480));
generator.Generate(images);
images.AppendElement(generator.GenerateI420Image());
images.AppendElement(generator.GenerateNV12Image());
images.AppendElement(generator.GenerateNV21Image());
// Put generated YUV frame into video segment.
// Duration of each frame is 1 second.
@ -285,6 +295,140 @@ TEST(VP8VideoTrackEncoder, FrameEncode)
EXPECT_TRUE(NS_SUCCEEDED(encoder.GetEncodedTrack(container)));
}
// Test that encoding a single frame gives useful output.
TEST(VP8VideoTrackEncoder, SingleFrameEncode)
{
// Initiate VP8 encoder
TestVP8TrackEncoder encoder;
InitParam param = {true, 640, 480};
encoder.TestInit(param);
// Pass a half-second frame to the encoder.
YUVBufferGenerator generator;
generator.Init(mozilla::gfx::IntSize(640, 480));
VideoSegment segment;
segment.AppendFrame(generator.GenerateI420Image(),
mozilla::StreamTime(45000), // 1/2 second
generator.GetSize(),
PRINCIPAL_HANDLE_NONE);
encoder.SetCurrentFrames(segment);
// End the track.
segment.Clear();
encoder.NotifyQueuedTrackChanges(nullptr, 0, 0, TrackEventCommand::TRACK_EVENT_ENDED, segment);
EncodedFrameContainer container;
ASSERT_TRUE(NS_SUCCEEDED(encoder.GetEncodedTrack(container)));
EXPECT_TRUE(encoder.IsEncodingComplete());
// Read out encoded data, and verify.
const nsTArray<RefPtr<EncodedFrame>>& frames = container.GetEncodedFrames();
const size_t oneElement = 1;
ASSERT_EQ(oneElement, frames.Length());
EXPECT_EQ(EncodedFrame::VP8_I_FRAME, frames[0]->GetFrameType()) <<
"We only have one frame, so it should be a keyframe";
const uint64_t halfSecond = PR_USEC_PER_SEC / 2;
EXPECT_EQ(halfSecond, frames[0]->GetDuration());
}
// Test that encoding a couple of identical images gives useful output.
TEST(VP8VideoTrackEncoder, SameFrameEncode)
{
// Initiate VP8 encoder
TestVP8TrackEncoder encoder;
InitParam param = {true, 640, 480};
encoder.TestInit(param);
// Pass 15 100ms frames to the encoder.
YUVBufferGenerator generator;
generator.Init(mozilla::gfx::IntSize(640, 480));
RefPtr<Image> image = generator.GenerateI420Image();
TimeStamp now = TimeStamp::Now();
VideoSegment segment;
for (uint32_t i = 0; i < 15; ++i) {
segment.AppendFrame(do_AddRef(image),
mozilla::StreamTime(9000), // 100ms
generator.GetSize(),
PRINCIPAL_HANDLE_NONE,
false,
now + TimeDuration::FromSeconds(i * 0.1));
}
encoder.SetCurrentFrames(segment);
// End the track.
segment.Clear();
encoder.NotifyQueuedTrackChanges(nullptr, 0, 0, TrackEventCommand::TRACK_EVENT_ENDED, segment);
EncodedFrameContainer container;
ASSERT_TRUE(NS_SUCCEEDED(encoder.GetEncodedTrack(container)));
EXPECT_TRUE(encoder.IsEncodingComplete());
// Verify total duration being 1.5s.
uint64_t totalDuration = 0;
for (auto& frame : container.GetEncodedFrames()) {
totalDuration += frame->GetDuration();
}
const uint64_t oneAndAHalf = (PR_USEC_PER_SEC / 2) * 3;
EXPECT_EQ(oneAndAHalf, totalDuration);
}
// Test encoding a track that starts with null data
TEST(VP8VideoTrackEncoder, NullFrameFirst)
{
// Initiate VP8 encoder
TestVP8TrackEncoder encoder;
InitParam param = {true, 640, 480};
encoder.TestInit(param);
YUVBufferGenerator generator;
generator.Init(mozilla::gfx::IntSize(640, 480));
RefPtr<Image> image = generator.GenerateI420Image();
TimeStamp now = TimeStamp::Now();
VideoSegment segment;
// Pass 2 100ms null frames to the encoder.
for (uint32_t i = 0; i < 2; ++i) {
segment.AppendFrame(nullptr,
mozilla::StreamTime(9000), // 100ms
generator.GetSize(),
PRINCIPAL_HANDLE_NONE,
false,
now + TimeDuration::FromSeconds(i * 0.1));
}
// Pass a real 100ms frame to the encoder.
segment.AppendFrame(image.forget(),
mozilla::StreamTime(9000), // 100ms
generator.GetSize(),
PRINCIPAL_HANDLE_NONE,
false,
now + TimeDuration::FromSeconds(0.3));
encoder.SetCurrentFrames(segment);
// End the track.
segment.Clear();
encoder.NotifyQueuedTrackChanges(nullptr, 0, 0, TrackEventCommand::TRACK_EVENT_ENDED, segment);
EncodedFrameContainer container;
ASSERT_TRUE(NS_SUCCEEDED(encoder.GetEncodedTrack(container)));
EXPECT_TRUE(encoder.IsEncodingComplete());
// Verify total duration being 0.3s.
uint64_t totalDuration = 0;
for (auto& frame : container.GetEncodedFrames()) {
totalDuration += frame->GetDuration();
}
const uint64_t pointThree = (PR_USEC_PER_SEC / 10) * 3;
EXPECT_EQ(pointThree, totalDuration);
}
// EOS test
TEST(VP8VideoTrackEncoder, EncodeComplete)
{
@ -302,4 +446,6 @@ TEST(VP8VideoTrackEncoder, EncodeComplete)
// NS_OK immidiately.
EncodedFrameContainer container;
EXPECT_TRUE(NS_SUCCEEDED(encoder.GetEncodedTrack(container)));
EXPECT_TRUE(encoder.IsEncodingComplete());
}

View File

@ -621,9 +621,9 @@ var interfaceNamesInGlobalScope =
// IMPORTANT: Do not change this list without review from a DOM peer!
"InstallTrigger",
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "IntersectionObserver", disabled: true},
"IntersectionObserver",
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "IntersectionObserverEntry", disabled: true},
"IntersectionObserverEntry",
// IMPORTANT: Do not change this list without review from a DOM peer!
"KeyEvent",
// IMPORTANT: Do not change this list without review from a DOM peer!

View File

@ -2859,7 +2859,7 @@ WorkerThreadPrimaryRunnable::Run()
{
#ifdef MOZ_ENABLE_PROFILER_SPS
PseudoStack* stack = mozilla_get_pseudo_stack();
PseudoStack* stack = profiler_get_pseudo_stack();
if (stack) {
stack->sampleContext(cx);
}

View File

@ -71,7 +71,7 @@ protected:
MOZ_IS_CLASS_INIT
void Init() {
#ifdef MOZ_ENABLE_PROFILER_SPS
mPseudoStackHack = mozilla_get_pseudo_stack();
mPseudoStackHack = profiler_get_pseudo_stack();
#endif
}

View File

@ -1115,7 +1115,7 @@ JSObject*
AtomicsObject::initClass(JSContext* cx, Handle<GlobalObject*> global)
{
// Create Atomics Object.
RootedObject objProto(cx, global->getOrCreateObjectPrototype(cx));
RootedObject objProto(cx, GlobalObject::getOrCreateObjectPrototype(cx, global));
if (!objProto)
return nullptr;
RootedObject Atomics(cx, NewObjectWithGivenProto(cx, &AtomicsObject::class_, objProto,

View File

@ -1004,7 +1004,7 @@ Collator(JSContext* cx, const CallArgs& args, bool construct)
// See https://github.com/tc39/ecma402/issues/57
if (!construct) {
// ES Intl 1st ed., 10.1.2.1 step 3
JSObject* intl = cx->global()->getOrCreateIntlObject(cx);
JSObject* intl = GlobalObject::getOrCreateIntlObject(cx, cx->global());
if (!intl)
return false;
RootedValue self(cx, args.thisv());
@ -1033,7 +1033,7 @@ Collator(JSContext* cx, const CallArgs& args, bool construct)
return false;
if (!proto) {
proto = cx->global()->getOrCreateCollatorPrototype(cx);
proto = GlobalObject::getOrCreateCollatorPrototype(cx, cx->global());
if (!proto)
return false;
}
@ -1093,11 +1093,12 @@ collator_finalize(FreeOp* fop, JSObject* obj)
static JSObject*
CreateCollatorPrototype(JSContext* cx, HandleObject Intl, Handle<GlobalObject*> global)
{
RootedFunction ctor(cx, global->createConstructor(cx, &Collator, cx->names().Collator, 0));
RootedFunction ctor(cx, GlobalObject::createConstructor(cx, &Collator, cx->names().Collator,
0));
if (!ctor)
return nullptr;
RootedNativeObject proto(cx, global->createBlankPrototype(cx, &CollatorClass));
RootedNativeObject proto(cx, GlobalObject::createBlankPrototype(cx, global, &CollatorClass));
if (!proto)
return nullptr;
proto->setReservedSlot(UCOLLATOR_SLOT, PrivateValue(nullptr));
@ -1504,7 +1505,7 @@ NumberFormat(JSContext* cx, const CallArgs& args, bool construct)
// See https://github.com/tc39/ecma402/issues/57
if (!construct) {
// ES Intl 1st ed., 11.1.2.1 step 3
JSObject* intl = cx->global()->getOrCreateIntlObject(cx);
JSObject* intl = GlobalObject::getOrCreateIntlObject(cx, cx->global());
if (!intl)
return false;
RootedValue self(cx, args.thisv());
@ -1533,7 +1534,7 @@ NumberFormat(JSContext* cx, const CallArgs& args, bool construct)
return false;
if (!proto) {
proto = cx->global()->getOrCreateNumberFormatPrototype(cx);
proto = GlobalObject::getOrCreateNumberFormatPrototype(cx, cx->global());
if (!proto)
return false;
}
@ -1595,11 +1596,12 @@ static JSObject*
CreateNumberFormatPrototype(JSContext* cx, HandleObject Intl, Handle<GlobalObject*> global)
{
RootedFunction ctor(cx);
ctor = global->createConstructor(cx, &NumberFormat, cx->names().NumberFormat, 0);
ctor = GlobalObject::createConstructor(cx, &NumberFormat, cx->names().NumberFormat, 0);
if (!ctor)
return nullptr;
RootedNativeObject proto(cx, global->createBlankPrototype(cx, &NumberFormatClass));
RootedNativeObject proto(cx, GlobalObject::createBlankPrototype(cx, global,
&NumberFormatClass));
if (!proto)
return nullptr;
proto->setReservedSlot(UNUMBER_FORMAT_SLOT, PrivateValue(nullptr));
@ -2515,7 +2517,7 @@ DateTimeFormat(JSContext* cx, const CallArgs& args, bool construct)
// See https://github.com/tc39/ecma402/issues/57
if (!construct) {
// ES Intl 1st ed., 12.1.2.1 step 3
JSObject* intl = cx->global()->getOrCreateIntlObject(cx);
JSObject* intl = GlobalObject::getOrCreateIntlObject(cx, cx->global());
if (!intl)
return false;
RootedValue self(cx, args.thisv());
@ -2544,7 +2546,7 @@ DateTimeFormat(JSContext* cx, const CallArgs& args, bool construct)
return false;
if (!proto) {
proto = cx->global()->getOrCreateDateTimeFormatPrototype(cx);
proto = GlobalObject::getOrCreateDateTimeFormatPrototype(cx, cx->global());
if (!proto)
return false;
}
@ -2606,11 +2608,12 @@ static JSObject*
CreateDateTimeFormatPrototype(JSContext* cx, HandleObject Intl, Handle<GlobalObject*> global)
{
RootedFunction ctor(cx);
ctor = global->createConstructor(cx, &DateTimeFormat, cx->names().DateTimeFormat, 0);
ctor = GlobalObject::createConstructor(cx, &DateTimeFormat, cx->names().DateTimeFormat, 0);
if (!ctor)
return nullptr;
RootedNativeObject proto(cx, global->createBlankPrototype(cx, &DateTimeFormatClass));
RootedNativeObject proto(cx, GlobalObject::createBlankPrototype(cx, global,
&DateTimeFormatClass));
if (!proto)
return nullptr;
proto->setReservedSlot(UDATE_FORMAT_SLOT, PrivateValue(nullptr));
@ -3639,7 +3642,7 @@ PluralRules(JSContext* cx, unsigned argc, Value* vp)
return false;
if (!proto) {
proto = cx->global()->getOrCreatePluralRulesPrototype(cx);
proto = GlobalObject::getOrCreatePluralRulesPrototype(cx, cx->global());
if (!proto)
return false;
}
@ -3685,7 +3688,8 @@ CreatePluralRulesPrototype(JSContext* cx, HandleObject Intl, Handle<GlobalObject
if (!ctor)
return nullptr;
RootedNativeObject proto(cx, global->createBlankPrototype(cx, &PluralRulesClass));
RootedNativeObject proto(cx, GlobalObject::createBlankPrototype(cx, global,
&PluralRulesClass));
if (!proto)
return nullptr;
MOZ_ASSERT(proto->getReservedSlot(UPLURAL_RULES_SLOT).isUndefined(),
@ -4418,10 +4422,10 @@ static const JSFunctionSpec intl_static_methods[] = {
* Initializes the Intl Object and its standard built-in properties.
* Spec: ECMAScript Internationalization API Specification, 8.0, 8.1
*/
bool
/* static */ bool
GlobalObject::initIntlObject(JSContext* cx, Handle<GlobalObject*> global)
{
RootedObject proto(cx, global->getOrCreateObjectPrototype(cx));
RootedObject proto(cx, GlobalObject::getOrCreateObjectPrototype(cx, global));
if (!proto)
return false;

View File

@ -164,7 +164,7 @@ MapIteratorObject::kind() const
return MapObject::IteratorKind(i);
}
bool
/* static */ bool
GlobalObject::initMapIteratorProto(JSContext* cx, Handle<GlobalObject*> global)
{
Rooted<JSObject*> base(cx, GlobalObject::getOrCreateIteratorPrototype(cx, global));
@ -281,7 +281,7 @@ MapIteratorObject::createResultPair(JSContext* cx)
static JSObject*
CreateMapPrototype(JSContext* cx, JSProtoKey key)
{
return cx->global()->createBlankPrototype(cx, &MapObject::protoClass_);
return GlobalObject::createBlankPrototype(cx, cx->global(), &MapObject::protoClass_);
}
const ClassOps MapObject::classOps_ = {
@ -899,7 +899,7 @@ SetIteratorObject::kind() const
return SetObject::IteratorKind(i);
}
bool
/* static */ bool
GlobalObject::initSetIteratorProto(JSContext* cx, Handle<GlobalObject*> global)
{
Rooted<JSObject*> base(cx, GlobalObject::getOrCreateIteratorPrototype(cx, global));
@ -1003,7 +1003,7 @@ SetIteratorObject::createResult(JSContext* cx)
static JSObject*
CreateSetPrototype(JSContext* cx, JSProtoKey key)
{
return cx->global()->createBlankPrototype(cx, &SetObject::protoClass_);
return GlobalObject::createBlankPrototype(cx, cx->global(), &SetObject::protoClass_);
}
const ClassOps SetObject::classOps_ = {

View File

@ -103,7 +103,7 @@ GlobalObject::initImportEntryProto(JSContext* cx, Handle<GlobalObject*> global)
JS_PS_END
};
RootedObject proto(cx, global->createBlankPrototype<PlainObject>(cx));
RootedObject proto(cx, GlobalObject::createBlankPrototype<PlainObject>(cx, global));
if (!proto)
return false;
@ -169,7 +169,7 @@ GlobalObject::initExportEntryProto(JSContext* cx, Handle<GlobalObject*> global)
JS_PS_END
};
RootedObject proto(cx, global->createBlankPrototype<PlainObject>(cx));
RootedObject proto(cx, GlobalObject::createBlankPrototype<PlainObject>(cx, global));
if (!proto)
return false;
@ -996,7 +996,7 @@ GlobalObject::initModuleProto(JSContext* cx, Handle<GlobalObject*> global)
JS_FS_END
};
RootedObject proto(cx, global->createBlankPrototype<PlainObject>(cx));
RootedObject proto(cx, GlobalObject::createBlankPrototype<PlainObject>(cx, global));
if (!proto)
return false;

View File

@ -2691,7 +2691,7 @@ PromiseTask::executeAndFinish(JSContext* cx)
static JSObject*
CreatePromisePrototype(JSContext* cx, JSProtoKey key)
{
return cx->global()->createBlankPrototype(cx, &PromiseObject::protoClass_);
return GlobalObject::createBlankPrototype(cx, cx->global(), &PromiseObject::protoClass_);
}
static const JSFunctionSpec promise_methods[] = {

View File

@ -268,7 +268,8 @@ static const JSFunctionSpec methods[] = {
JSObject*
js::InitReflect(JSContext* cx, HandleObject obj)
{
RootedObject proto(cx, obj->as<GlobalObject>().getOrCreateObjectPrototype(cx));
Handle<GlobalObject*> global = obj.as<GlobalObject>();
RootedObject proto(cx, GlobalObject::getOrCreateObjectPrototype(cx, global));
if (!proto)
return nullptr;

View File

@ -801,7 +801,7 @@ const JSFunctionSpec js::regexp_methods[] = {
name(JSContext* cx, unsigned argc, Value* vp) \
{ \
CallArgs args = CallArgsFromVp(argc, vp); \
RegExpStatics* res = cx->global()->getRegExpStatics(cx); \
RegExpStatics* res = GlobalObject::getRegExpStatics(cx, cx->global()); \
if (!res) \
return false; \
code; \
@ -827,7 +827,7 @@ DEFINE_STATIC_GETTER(static_paren9_getter, STATIC_PAREN_GETTER_CODE(9))
static bool \
name(JSContext* cx, unsigned argc, Value* vp) \
{ \
RegExpStatics* res = cx->global()->getRegExpStatics(cx); \
RegExpStatics* res = GlobalObject::getRegExpStatics(cx, cx->global()); \
if (!res) \
return false; \
code; \
@ -838,7 +838,7 @@ static bool
static_input_setter(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
RegExpStatics* res = cx->global()->getRegExpStatics(cx);
RegExpStatics* res = GlobalObject::getRegExpStatics(cx, cx->global());
if (!res)
return false;
@ -923,7 +923,7 @@ ExecuteRegExp(JSContext* cx, HandleObject regexp, HandleString string,
RegExpStatics* res;
if (staticsUpdate == UpdateRegExpStatics) {
res = cx->global()->getRegExpStatics(cx);
res = GlobalObject::getRegExpStatics(cx, cx->global());
if (!res)
return RegExpRunStatus_Error;
} else {

View File

@ -475,7 +475,7 @@ const Class SimdObject::class_ = {
&SimdObjectClassOps
};
bool
/* static */ bool
GlobalObject::initSimdObject(JSContext* cx, Handle<GlobalObject*> global)
{
// SIMD relies on the TypedObject module being initialized.
@ -483,11 +483,11 @@ GlobalObject::initSimdObject(JSContext* cx, Handle<GlobalObject*> global)
// to be able to call GetTypedObjectModule(). It is NOT necessary
// to install the TypedObjectModule global, but at the moment
// those two things are not separable.
if (!global->getOrCreateTypedObjectModule(cx))
if (!GlobalObject::getOrCreateTypedObjectModule(cx, global))
return false;
RootedObject globalSimdObject(cx);
RootedObject objProto(cx, global->getOrCreateObjectPrototype(cx));
RootedObject objProto(cx, GlobalObject::getOrCreateObjectPrototype(cx, global));
if (!objProto)
return false;
@ -510,7 +510,7 @@ static bool
CreateSimdType(JSContext* cx, Handle<GlobalObject*> global, HandlePropertyName stringRepr,
SimdType simdType, const JSFunctionSpec* methods)
{
RootedObject funcProto(cx, global->getOrCreateFunctionPrototype(cx));
RootedObject funcProto(cx, GlobalObject::getOrCreateFunctionPrototype(cx, global));
if (!funcProto)
return false;
@ -531,7 +531,7 @@ CreateSimdType(JSContext* cx, Handle<GlobalObject*> global, HandlePropertyName s
return false;
// Create prototype property, which inherits from Object.prototype.
RootedObject objProto(cx, global->getOrCreateObjectPrototype(cx));
RootedObject objProto(cx, GlobalObject::getOrCreateObjectPrototype(cx, global));
if (!objProto)
return false;
Rooted<TypedProto*> proto(cx);
@ -551,7 +551,7 @@ CreateSimdType(JSContext* cx, Handle<GlobalObject*> global, HandlePropertyName s
}
// Bind type descriptor to the global SIMD object
RootedObject globalSimdObject(cx, global->getOrCreateSimdGlobalObject(cx));
RootedObject globalSimdObject(cx, GlobalObject::getOrCreateSimdGlobalObject(cx, global));
MOZ_ASSERT(globalSimdObject);
RootedValue typeValue(cx, ObjectValue(*typeDescr));
@ -568,7 +568,7 @@ CreateSimdType(JSContext* cx, Handle<GlobalObject*> global, HandlePropertyName s
return !!typeDescr;
}
bool
/* static */ bool
GlobalObject::initSimdType(JSContext* cx, Handle<GlobalObject*> global, SimdType simdType)
{
#define CREATE_(Type) \
@ -584,13 +584,13 @@ GlobalObject::initSimdType(JSContext* cx, Handle<GlobalObject*> global, SimdType
#undef CREATE_
}
SimdTypeDescr*
/* static */ SimdTypeDescr*
GlobalObject::getOrCreateSimdTypeDescr(JSContext* cx, Handle<GlobalObject*> global,
SimdType simdType)
{
MOZ_ASSERT(unsigned(simdType) < unsigned(SimdType::Count), "Invalid SIMD type");
RootedObject globalSimdObject(cx, global->getOrCreateSimdGlobalObject(cx));
RootedObject globalSimdObject(cx, GlobalObject::getOrCreateSimdGlobalObject(cx, global));
if (!globalSimdObject)
return nullptr;
@ -628,8 +628,8 @@ SimdObject::resolve(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool*
JSObject*
js::InitSimdClass(JSContext* cx, HandleObject obj)
{
Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
return global->getOrCreateSimdGlobalObject(cx);
Handle<GlobalObject*> global = obj.as<GlobalObject>();
return GlobalObject::getOrCreateSimdGlobalObject(cx, global);
}
template<typename V>

View File

@ -52,17 +52,17 @@ const JSFunctionSpec SymbolObject::staticMethods[] = {
JSObject*
SymbolObject::initClass(JSContext* cx, HandleObject obj)
{
Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
Handle<GlobalObject*> global = obj.as<GlobalObject>();
// This uses &JSObject::class_ because: "The Symbol prototype object is an
// ordinary object. It is not a Symbol instance and does not have a
// [[SymbolData]] internal slot." (ES6 rev 24, 19.4.3)
RootedObject proto(cx, global->createBlankPrototype<PlainObject>(cx));
RootedObject proto(cx, GlobalObject::createBlankPrototype<PlainObject>(cx, global));
if (!proto)
return nullptr;
RootedFunction ctor(cx, global->createConstructor(cx, construct,
ClassName(JSProto_Symbol, cx), 0));
RootedFunction ctor(cx, GlobalObject::createConstructor(cx, construct,
ClassName(JSProto_Symbol, cx), 0));
if (!ctor)
return nullptr;

View File

@ -1124,11 +1124,11 @@ DefineSimpleTypeDescr(JSContext* cx,
typename T::Type type,
HandlePropertyName className)
{
RootedObject objProto(cx, global->getOrCreateObjectPrototype(cx));
RootedObject objProto(cx, GlobalObject::getOrCreateObjectPrototype(cx, global));
if (!objProto)
return false;
RootedObject funcProto(cx, global->getOrCreateFunctionPrototype(cx));
RootedObject funcProto(cx, GlobalObject::getOrCreateFunctionPrototype(cx, global));
if (!funcProto)
return false;
@ -1185,7 +1185,7 @@ DefineMetaTypeDescr(JSContext* cx,
if (!className)
return nullptr;
RootedObject funcProto(cx, global->getOrCreateFunctionPrototype(cx));
RootedObject funcProto(cx, GlobalObject::getOrCreateFunctionPrototype(cx, global));
if (!funcProto)
return nullptr;
@ -1197,7 +1197,7 @@ DefineMetaTypeDescr(JSContext* cx,
// Create ctor.prototype.prototype, which inherits from Object.__proto__
RootedObject objProto(cx, global->getOrCreateObjectPrototype(cx));
RootedObject objProto(cx, GlobalObject::getOrCreateObjectPrototype(cx, global));
if (!objProto)
return nullptr;
RootedObject protoProto(cx);
@ -1216,7 +1216,7 @@ DefineMetaTypeDescr(JSContext* cx,
const int constructorLength = 2;
RootedFunction ctor(cx);
ctor = global->createConstructor(cx, T::construct, className, constructorLength);
ctor = GlobalObject::createConstructor(cx, T::construct, className, constructorLength);
if (!ctor ||
!LinkConstructorAndPrototype(cx, ctor, proto) ||
!DefinePropertiesAndFunctions(cx, proto,
@ -1240,10 +1240,10 @@ DefineMetaTypeDescr(JSContext* cx,
* initializer for the `TypedObject` class populate the
* `TypedObject` global (which is referred to as "module" herein).
*/
bool
/* static */ bool
GlobalObject::initTypedObjectModule(JSContext* cx, Handle<GlobalObject*> global)
{
RootedObject objProto(cx, global->getOrCreateObjectPrototype(cx));
RootedObject objProto(cx, GlobalObject::getOrCreateObjectPrototype(cx, global));
if (!objProto)
return false;
@ -1317,9 +1317,8 @@ GlobalObject::initTypedObjectModule(JSContext* cx, Handle<GlobalObject*> global)
JSObject*
js::InitTypedObjectModuleObject(JSContext* cx, HandleObject obj)
{
MOZ_ASSERT(obj->is<GlobalObject>());
Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
return global->getOrCreateTypedObjectModule(cx);
Handle<GlobalObject*> global = obj.as<GlobalObject>();
return GlobalObject::getOrCreateTypedObjectModule(cx, global);
}
/******************************************************************************

View File

@ -350,14 +350,14 @@ InitWeakMapClass(JSContext* cx, HandleObject obj, bool defineMembers)
{
MOZ_ASSERT(obj->isNative());
Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
Handle<GlobalObject*> global = obj.as<GlobalObject>();
RootedPlainObject proto(cx, NewBuiltinClassInstance<PlainObject>(cx));
if (!proto)
return nullptr;
RootedFunction ctor(cx, global->createConstructor(cx, WeakMap_construct,
cx->names().WeakMap, 0));
RootedFunction ctor(cx, GlobalObject::createConstructor(cx, WeakMap_construct,
cx->names().WeakMap, 0));
if (!ctor)
return nullptr;

View File

@ -41,14 +41,15 @@ const JSFunctionSpec WeakSetObject::methods[] = {
};
JSObject*
WeakSetObject::initClass(JSContext* cx, JSObject* obj)
WeakSetObject::initClass(JSContext* cx, HandleObject obj)
{
Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
Handle<GlobalObject*> global = obj.as<GlobalObject>();
RootedPlainObject proto(cx, NewBuiltinClassInstance<PlainObject>(cx));
if (!proto)
return nullptr;
Rooted<JSFunction*> ctor(cx, global->createConstructor(cx, construct, ClassName(JSProto_WeakSet, cx), 0));
Rooted<JSFunction*> ctor(cx, GlobalObject::createConstructor(cx, construct,
ClassName(JSProto_WeakSet, cx), 0));
if (!ctor ||
!LinkConstructorAndPrototype(cx, ctor, proto) ||
!DefinePropertiesAndFunctions(cx, proto, properties, methods) ||

View File

@ -16,7 +16,7 @@ class WeakSetObject : public NativeObject
public:
static const unsigned RESERVED_SLOTS = 1;
static JSObject* initClass(JSContext* cx, JSObject* obj);
static JSObject* initClass(JSContext* cx, HandleObject obj);
static const Class class_;
private:

View File

@ -0,0 +1,14 @@
function f() {
var a = [];
for (var i=0; i<100; i++)
a.push({x: i});
var vals = [1, "", true, null];
for (var j=0; j<100; j++) {
var v = vals[j % vals.length];
a[95].y = v;
assertEq(a[95].y, v);
}
}
f();

View File

@ -0,0 +1,7 @@
// |jit-test| error: ReferenceError
symbols = [Symbol];
for (comparator of[, ])
for (a of symbols)
for (;;)
expect;

View File

@ -275,7 +275,7 @@ jit::BaselineCompile(JSContext* cx, JSScript* script, bool forceDebugInstrumenta
MOZ_ASSERT(script->canBaselineCompile());
MOZ_ASSERT(IsBaselineEnabled(cx));
script->ensureNonLazyCanonicalFunction(cx);
script->ensureNonLazyCanonicalFunction();
LifoAlloc alloc(TempAllocator::PreferredLifoChunkSize);
TempAllocator* temp = alloc.new_<TempAllocator>(&alloc);

View File

@ -499,8 +499,8 @@ GetPropIRGenerator::tryAttachNative(HandleObject obj, ObjOperandId objId, Handle
bool
GetPropIRGenerator::tryAttachWindowProxy(HandleObject obj, ObjOperandId objId, HandleId id)
{
// Attach a stub when the receiver is a WindowProxy and we are calling some
// kinds of JSNative getters on the Window object (the global object).
// Attach a stub when the receiver is a WindowProxy and we can do the lookup
// on the Window (the global object).
if (!IsWindowProxy(obj))
return false;
@ -511,34 +511,49 @@ GetPropIRGenerator::tryAttachWindowProxy(HandleObject obj, ObjOperandId objId, H
MOZ_ASSERT(obj->getClass() == cx_->maybeWindowProxyClass());
MOZ_ASSERT(ToWindowIfWindowProxy(obj) == cx_->global());
// Now try to do the lookup on the Window (the current global) and see if
// it's a native getter.
// Now try to do the lookup on the Window (the current global).
HandleObject windowObj = cx_->global();
RootedShape shape(cx_);
RootedNativeObject holder(cx_);
NativeGetPropCacheability type = CanAttachNativeGetProp(cx_, windowObj, id, &holder, &shape, pc_,
engine_, canAttachGetter_,
isTemporarilyUnoptimizable_);
if (type != CanAttachCallGetter ||
!IsCacheableGetPropCallNative(windowObj, holder, shape))
{
switch (type) {
case CanAttachNone:
return false;
case CanAttachReadSlot: {
maybeEmitIdGuard(id);
writer.guardClass(objId, GuardClassKind::WindowProxy);
ObjOperandId windowObjId = writer.loadObject(windowObj);
EmitReadSlotResult(writer, windowObj, holder, shape, windowObjId);
EmitReadSlotReturn(writer, windowObj, holder, shape);
return true;
}
case CanAttachCallGetter: {
if (!IsCacheableGetPropCallNative(windowObj, holder, shape))
return false;
// Make sure the native getter is okay with the IC passing the Window
// instead of the WindowProxy as |this| value.
JSFunction* callee = &shape->getterObject()->as<JSFunction>();
MOZ_ASSERT(callee->isNative());
if (!callee->jitInfo() || callee->jitInfo()->needsOuterizedThisObject())
return false;
// Guard the incoming object is a WindowProxy and inline a getter call based
// on the Window object.
maybeEmitIdGuard(id);
writer.guardClass(objId, GuardClassKind::WindowProxy);
ObjOperandId windowObjId = writer.loadObject(windowObj);
EmitCallGetterResult(writer, windowObj, holder, shape, windowObjId);
return true;
}
}
// Make sure the native getter is okay with the IC passing the Window
// instead of the WindowProxy as |this| value.
JSFunction* callee = &shape->getterObject()->as<JSFunction>();
MOZ_ASSERT(callee->isNative());
if (!callee->jitInfo() || callee->jitInfo()->needsOuterizedThisObject())
return false;
// Guard the incoming object is a WindowProxy and inline a getter call based
// on the Window object.
maybeEmitIdGuard(id);
writer.guardClass(objId, GuardClassKind::WindowProxy);
ObjOperandId windowObjId = writer.loadObject(windowObj);
EmitCallGetterResult(writer, windowObj, holder, shape, windowObjId);
return true;
MOZ_CRASH("Unreachable");
}
bool

View File

@ -1162,7 +1162,7 @@ PrepareAndExecuteRegExp(JSContext* cx, MacroAssembler& masm, Register regexp, Re
Address pairsVectorAddress(masm.getStackPointer(), pairsVectorStartOffset);
RegExpStatics* res = cx->global()->getRegExpStatics(cx);
RegExpStatics* res = GlobalObject::getRegExpStatics(cx, cx->global());
if (!res)
return false;
#ifdef JS_USE_LINK_REGISTER

View File

@ -2199,7 +2199,7 @@ IonCompile(JSContext* cx, JSScript* script,
// Make sure the script's canonical function isn't lazy. We can't de-lazify
// it in a helper thread.
script->ensureNonLazyCanonicalFunction(cx);
script->ensureNonLazyCanonicalFunction();
TrackPropertiesForSingletonScopes(cx, script, baselineFrame);

View File

@ -866,11 +866,16 @@ IonBuilder::processIterators()
// Find phis that must directly hold an iterator live.
Vector<MPhi*, 0, SystemAllocPolicy> worklist;
for (size_t i = 0; i < iterators_.length(); i++) {
MInstruction* ins = iterators_[i];
for (MUseDefIterator iter(ins); iter; iter++) {
if (iter.def()->isPhi()) {
if (!worklist.append(iter.def()->toPhi()))
return abort(AbortReason::Alloc);
MDefinition* def = iterators_[i];
if (def->isPhi()) {
if (!worklist.append(def->toPhi()))
return abort(AbortReason::Alloc);
} else {
for (MUseDefIterator iter(def); iter; iter++) {
if (iter.def()->isPhi()) {
if (!worklist.append(iter.def()->toPhi()))
return abort(AbortReason::Alloc);
}
}
}
}
@ -1999,7 +2004,12 @@ IonBuilder::inspectOpcode(JSOp op)
case JSOP_CALLITER:
case JSOP_NEW:
case JSOP_SUPERCALL:
return jsop_call(GET_ARGC(pc), (JSOp)*pc == JSOP_NEW || (JSOp)*pc == JSOP_SUPERCALL);
MOZ_TRY(jsop_call(GET_ARGC(pc), (JSOp)*pc == JSOP_NEW || (JSOp)*pc == JSOP_SUPERCALL));
if (op == JSOP_CALLITER) {
if (!outermostBuilder()->iterators_.append(current->peek(-1)))
return abort(AbortReason::Alloc);
}
return Ok();
case JSOP_EVAL:
case JSOP_STRICTEVAL:

View File

@ -1036,7 +1036,7 @@ class IonBuilder
{}
};
Vector<MInstruction*, 2, JitAllocPolicy> iterators_;
Vector<MDefinition*, 2, JitAllocPolicy> iterators_;
Vector<LoopHeader, 0, JitAllocPolicy> loopHeaders_;
Vector<MBasicBlock*, 0, JitAllocPolicy> loopHeaderStack_;
#ifdef DEBUG

View File

@ -557,12 +557,6 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
void mov(ImmPtr imm, Register dest) {
mov(ImmWord(uintptr_t(imm.value)), dest);
}
void mov(Register src, Address dest) {
MOZ_CRASH("NYI-IC");
}
void mov(Address src, Register dest) {
MOZ_CRASH("NYI-IC");
}
void branch(JitCode* c) {
BufferOffset bo = m_buffer.nextOffset();

View File

@ -359,22 +359,12 @@ EmitPreBarrier(MacroAssembler& masm, const AddrType& addr, MIRType type)
inline void
EmitStubGuardFailure(MacroAssembler& masm)
{
MOZ_ASSERT(R2 == ValueOperand(r1, r0));
// NOTE: This routine assumes that the stub guard code left the stack in the
// same state it was in when it was entered.
// BaselineStubEntry points to the current stub.
// Load next stub into ICStubReg.
masm.loadPtr(Address(ICStubReg, ICStub::offsetOfNext()), ICStubReg);
// Load stubcode pointer from BaselineStubEntry into scratch register.
masm.loadPtr(Address(ICStubReg, ICStub::offsetOfStubCode()), r0);
// Return address is already loaded, just jump to the next stubcode.
MOZ_ASSERT(ICTailCallReg == lr);
masm.branch(r0);
masm.jump(Address(ICStubReg, ICStub::offsetOfStubCode()));
}

View File

@ -316,19 +316,11 @@ EmitPreBarrier(MacroAssembler& masm, const AddrType& addr, MIRType type)
inline void
EmitStubGuardFailure(MacroAssembler& masm)
{
// NOTE: This routine assumes that the stub guard code left the stack in the
// same state it was in when it was entered.
// BaselineStubEntry points to the current stub.
// Load next stub into ICStubReg.
masm.loadPtr(Address(ICStubReg, ICStub::offsetOfNext()), ICStubReg);
// Load stubcode pointer from BaselineStubEntry into scratch register.
masm.loadPtr(Address(ICStubReg, ICStub::offsetOfStubCode()), r0);
// Return address is already loaded, just jump to the next stubcode.
masm.Br(x0);
masm.jump(Address(ICStubReg, ICStub::offsetOfStubCode()));
}
} // namespace jit

View File

@ -360,20 +360,12 @@ EmitPreBarrier(MacroAssembler& masm, const AddrType& addr, MIRType type)
inline void
EmitStubGuardFailure(MacroAssembler& masm)
{
// NOTE: This routine assumes that the stub guard code left the stack in
// the same state it was in when it was entered.
// BaselineStubEntry points to the current stub.
// Load next stub into ICStubReg
masm.loadPtr(Address(ICStubReg, ICStub::offsetOfNext()), ICStubReg);
// Load stubcode pointer from BaselineStubEntry into scratch register.
masm.loadPtr(Address(ICStubReg, ICStub::offsetOfStubCode()), R2.scratchReg());
// Return address is already loaded, just jump to the next stubcode.
MOZ_ASSERT(ICTailCallReg == ra);
masm.branch(R2.scratchReg());
masm.jump(Address(ICStubReg, ICStub::offsetOfStubCode()));
}
} // namespace jit

View File

@ -334,11 +334,6 @@ EmitPreBarrier(MacroAssembler& masm, const AddrType& addr, MIRType type)
inline void
EmitStubGuardFailure(MacroAssembler& masm)
{
// NOTE: This routine assumes that the stub guard code left the stack in the
// same state it was in when it was entered.
// BaselineStubEntry points to the current stub.
// Load next stub into ICStubReg
masm.loadPtr(Address(ICStubReg, ICStub::offsetOfNext()), ICStubReg);

View File

@ -334,19 +334,13 @@ EmitPreBarrier(MacroAssembler& masm, const AddrType& addr, MIRType type)
inline void
EmitStubGuardFailure(MacroAssembler& masm)
{
// NOTE: This routine assumes that the stub guard code left the stack in the
// same state it was in when it was entered.
// BaselineStubEntry points to the current stub.
// Load next stub into ICStubReg
masm.loadPtr(Address(ICStubReg, (int32_t) ICStub::offsetOfNext()), ICStubReg);
masm.loadPtr(Address(ICStubReg, ICStub::offsetOfNext()), ICStubReg);
// Return address is already loaded, just jump to the next stubcode.
masm.jmp(Operand(ICStubReg, (int32_t) ICStub::offsetOfStubCode()));
masm.jmp(Operand(ICStubReg, ICStub::offsetOfStubCode()));
}
} // namespace jit
} // namespace js

Some files were not shown because too many files have changed in this diff Show More