This commit is contained in:
Ryan VanderMeulen 2014-04-29 17:07:34 -04:00
Родитель 9b997f94bd f40e4ae854
Коммит f1311f346a
228 изменённых файлов: 5691 добавлений и 2360 удалений

Просмотреть файл

@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Bug 995411 moves some files around in gfx/layers and widget/xpwidget
Bug 958889 moves files into the new mobile/android/base/tabspanel/ package.

Просмотреть файл

@ -31,6 +31,7 @@
gestures.forEach(AccessFuTest.addSequence);
AccessFuTest.addFunc(stopGestureTracker);
AccessFuTest.waitForExplicitFinish();
Logger.logLevel = Logger.DEBUG;
AccessFuTest.runTests();
});
}

Просмотреть файл

@ -156,11 +156,6 @@ pref("browser.search.suggest.enabled", true);
// tell the search service that we don't really expose the "current engine"
pref("browser.search.noCurrentEngine", true);
// Enable sparse localization by setting a few package locale overrides
pref("chrome.override_package.global", "b2g-l10n");
pref("chrome.override_package.mozapps", "b2g-l10n");
pref("chrome.override_package.passwordmgr", "b2g-l10n");
// enable xul error pages
pref("browser.xul.error_pages.enabled", true);
@ -899,9 +894,9 @@ pref("osfile.reset_worker_delay", 5000);
pref("apz.asyncscroll.throttle", 40);
pref("apz.pan_repaint_interval", 16);
// Maximum fling velocity in inches/ms. Slower devices may need to reduce this
// to avoid checkerboarding. Note, float value must be set as a string.
pref("apz.max_velocity_inches_per_ms", "0.0375");
// APZ physics settings, tuned by UX designers
pref("apz.max_velocity_inches_per_ms", "0.07");
pref("apz.fling_friction", "0.003");
// Tweak default displayport values to reduce the risk of running out of
// memory when zooming in

Просмотреть файл

@ -5,3 +5,8 @@
#filter substitution
pref("general.useragent.locale", "@AB_CD@");
// Enable sparse localization by setting a few package locale overrides
pref("chrome.override_package.global", "b2g-l10n");
pref("chrome.override_package.mozapps", "b2g-l10n");
pref("chrome.override_package.passwordmgr", "b2g-l10n");

Просмотреть файл

@ -1428,7 +1428,7 @@ pref("browser.newtabpage.rows", 3);
// number of columns of newtab grid
pref("browser.newtabpage.columns", 3);
pref("browser.newtabpage.directorySource", "chrome://global/content/directoryLinks.json");
pref("browser.newtabpage.directorySource", "data:application/json,{}");
// Enable the DOM fullscreen API.
pref("full-screen-api.enabled", true);

Просмотреть файл

@ -5180,7 +5180,8 @@ function UpdateCurrentCharset(target) {
}
function charsetLoadListener() {
var charset = CharsetMenu.foldCharset(window.content.document.characterSet);
let currCharset = gBrowser.selectedBrowser.characterSet;
let charset = CharsetMenu.foldCharset(currCharset);
if (charset.length > 0 && (charset != gLastBrowserCharset)) {
gPrevCharset = gLastBrowserCharset;

Просмотреть файл

@ -639,7 +639,7 @@
<hbox id="nav-bar-customization-target" flex="1">
<toolbaritem id="urlbar-container" flex="400" persist="width"
forwarddisabled="true" title="&locationItem.title;" removable="false"
title="&locationItem.title;" removable="false"
cui-areatype="toolbar"
class="chromeclass-location" overflows="false">
<toolbarbutton id="back-button" class="toolbarbutton-1 chromeclass-toolbar-additional"

Просмотреть файл

@ -9,6 +9,7 @@
const TEST_CONTENT_HELPER = "chrome://mochitests/content/browser/browser/base/content/test/social/social_crash_content_helper.js";
let {getFrameWorkerHandle} = Cu.import("resource://gre/modules/FrameWorker.jsm", {});
let {Promise} = Cu.import("resource://gre/modules/Promise.jsm", {}).Promise;
function test() {
waitForExplicitFinish();
@ -16,6 +17,9 @@ function test() {
// We need to ensure all our workers are in the same content process.
Services.prefs.setIntPref("dom.ipc.processCount", 1);
// This test generates many uncaught promises that should not cause failures.
Promise.Debugging.clearUncaughtErrorObservers();
runSocialTestWithProvider(gProviders, function (finishcb) {
runSocialTests(tests, undefined, undefined, function() {
Services.prefs.clearUserPref("dom.ipc.processCount");

Просмотреть файл

@ -26,11 +26,9 @@ pref("app.update.url.details", "https://www.mozilla.org/firefox/aurora/");
// app.update.checkInstallTime is true.
pref("app.update.checkInstallTime.days", 2);
// Search codes belong only in builds with official branding
pref("browser.search.param.yahoo-fr", "");
pref("browser.search.param.yahoo-fr-cjkt", ""); // now unused
pref("browser.search.param.yahoo-fr-ja", "");
pref("browser.search.param.yahoo-f-CN", "");
// code usage depends on contracts, please contact the Firefox module owner if you have questions
pref("browser.search.param.yahoo-fr", "moz35");
pref("browser.search.param.yahoo-fr-ja", "mozff");
#ifdef MOZ_METRO
pref("browser.search.param.yahoo-fr-metro", "");
#endif

Просмотреть файл

@ -23,11 +23,9 @@ pref("app.update.url.details", "https://nightly.mozilla.org");
// app.update.checkInstallTime is true.
pref("app.update.checkInstallTime.days", 2);
// Search codes belong only in builds with official branding
pref("browser.search.param.yahoo-fr", "");
pref("browser.search.param.yahoo-fr-cjkt", ""); // now unused
pref("browser.search.param.yahoo-fr-ja", "");
pref("browser.search.param.yahoo-f-CN", "");
// code usage depends on contracts, please contact the Firefox module owner if you have questions
pref("browser.search.param.yahoo-fr", "moz35");
pref("browser.search.param.yahoo-fr-ja", "mozff");
#ifdef MOZ_METRO
pref("browser.search.param.yahoo-fr-metro", "");
#endif

Просмотреть файл

@ -23,9 +23,8 @@ pref("app.update.url.details", "https://www.mozilla.org/%LOCALE%/firefox/notes")
// app.update.checkInstallTime is true.
pref("app.update.checkInstallTime.days", 63);
pref("browser.search.param.ms-pc", "MOZI");
// code usage depends on contracts, please contact the Firefox module owner if you have questions
pref("browser.search.param.yahoo-fr", "moz35");
pref("browser.search.param.yahoo-fr-cjkt", "moz35"); // now unused
pref("browser.search.param.yahoo-fr-ja", "mozff");
#ifdef MOZ_METRO
pref("browser.search.param.ms-pc-metro", "MOZW");

Просмотреть файл

@ -23,11 +23,9 @@ pref("app.update.url.details", "https://nightly.mozilla.org");
// app.update.checkInstallTime is true.
pref("app.update.checkInstallTime.days", 2);
// Search codes belong only in builds with official branding
pref("browser.search.param.yahoo-fr", "");
pref("browser.search.param.yahoo-fr-cjkt", ""); // now unused
pref("browser.search.param.yahoo-fr-ja", "");
pref("browser.search.param.yahoo-f-CN", "");
// code usage depends on contracts, please contact the Firefox module owner if you have questions
pref("browser.search.param.yahoo-fr", "moz35");
pref("browser.search.param.yahoo-fr-ja", "mozff");
#ifdef MOZ_METRO
pref("browser.search.param.yahoo-fr-metro", "");
#endif

Просмотреть файл

@ -14,14 +14,23 @@ support-files =
skip-if = e10s # Bug ?????? - Test uses load event and checks event.target.
[browser_483086.js]
[browser_addEngine.js]
[browser_amazon.js]
[browser_amazon_behavior.js]
skip-if = e10s # Bug ?????? - some issue with progress listeners [JavaScript Error: "req.originalURI is null" {file: "chrome://mochitests/content/browser/browser/components/search/test/browser_bing_behavior.js" line: 127}]
[browser_bing.js]
[browser_bing_behavior.js]
skip-if = e10s # Bug ?????? - some issue with progress listeners [JavaScript Error: "req.originalURI is null" {file: "chrome://mochitests/content/browser/browser/components/search/test/browser_bing_behavior.js" line: 127}]
[browser_contextmenu.js]
skip-if = e10s # Bug ?????? - Test touches content (content.window.getSelection().QueryInterface(Ci.nsISelectionPrivate)....)
[browser_eBay.js]
[browser_eBay_behavior.js]
skip-if = e10s # Bug ?????? - some issue with progress listeners [JavaScript Error: "req.originalURI is null" {file: "chrome://mochitests/content/browser/browser/components/search/test/browser_bing_behavior.js" line: 127}]
[browser_google.js]
[browser_google_behavior.js]
skip-if = e10s # Bug ?????? - some issue with progress listeners [JavaScript Error: "req.originalURI is null" {file: "chrome://mochitests/content/browser/browser/components/search/test/browser_bing_behavior.js" line: 127}]
[browser_healthreport.js]
[browser_private_search_perwindowpb.js]
skip-if = e10s # Bug ?????? - Test uses load event and checks event.target.
[browser_yahoo.js]
[browser_yahoo_behavior.js]
skip-if = e10s # Bug ?????? - some issue with progress listeners [JavaScript Error: "req.originalURI is null" {file: "chrome://mochitests/content/browser/browser/components/search/test/browser_bing_behavior.js" line: 127}]

Просмотреть файл

@ -0,0 +1,68 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/*
* Test Amazon search plugin URLs
*/
"use strict";
const BROWSER_SEARCH_PREF = "browser.search.";
function test() {
let engine = Services.search.getEngineByName("Amazon.com");
ok(engine, "Amazon.com");
let base = "http://www.amazon.com/exec/obidos/external-search/?field-keywords=foo&mode=blended&tag=mozilla-20&sourceid=Mozilla-search";
let url;
// Test search URLs (including purposes).
url = engine.getSubmission("foo").uri.spec;
is(url, base, "Check search URL for 'foo'");
// Check all other engine properties.
const EXPECTED_ENGINE = {
name: "Amazon.com",
alias: null,
description: "Amazon.com Search",
searchForm: "http://www.amazon.com/",
type: Ci.nsISearchEngine.TYPE_MOZSEARCH,
hidden: false,
wrappedJSObject: {
queryCharset: "UTF-8",
"_iconURL": "data:image/x-icon;base64,AAABAAIAEBAAAAAAAAC0AQAAJgAAACAgAAAAAAAA6QIAANoBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAF7SURBVDjLlZPLasJAFIaFRF+iVV+h6hO0GF+gVB9AaHwDt64qCG03tQgtdCFIuyhUelmGli66MXThSt24kNiFBUlAYi6ezjnNxSuawB/ITP7v/HNmJgQAEaZzpgHs/gwcTyTEXuXl2U6nA8ViEbK5HKler28CVRAwnB9ptVrAh8MrQuCaZ4iA8fzIqSgCxwzpTIaSuN/RWGwdYLwCUBQFZFkGSZLgqdmEE7YEN8VOAKyaSKUW4nNBAFmnYiKZpDRX1WqwBBzP089n5f/NEQsFL4WqqtsBWJlzDAJr5PwSMM1awEzzdxIbGI3Hvc6jCZeVFgRQRwpY7Qcw3ktgfpR8wLRxCPaot/X4GS95MppfF6DX9n2A3f+kAZycaT8bAZjU6r6B/duD6d3BYg9wQq/tkYzHY1blEiz5lmQyGc95mrO6r2CxgpjCBXgNsJVviolpXJiraeOIjJRE10juUa4sR8V+mO17VvmGqtuOcdNlwut8zTQJcJ0njifyB2bgTdKh6w4BAAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACsElEQVRYw71XQWsTURBe2LQgeNKLB+tVemt6txcteNSD/QGC6VEIGDx5s+eKPQqFgJhLNdFLBWMP7cU0oSAWjB70koC9WHbVQ5SO8+XtS14mr7svyaYDH9m87Jv55puZt1nPi4yIzjMeMj7T9OwjI88455nGC1cZX+nsDESumJmPFDwIAqrX6z00Gg1qt9vjkJgFgUeuO16Vy3RjeZkyMzM9+MY1fsM9I9h9zyV7ZAznZrA4FAoFVwJ1z+WuOysrg1lnMolkHJX4k0igzI5sARYWF7vEZEk0rvO6iyUSuJfLJUqM7zYSqRDIra4OOUZPmNZsNrsl8UVTpkJAjh1GzmaSpJ8mAWmYeZB5urHRhW5SNOfUCCDo47W1bvPZsp2qAhipy3Nz1kaLG8dUCEBqM5AvpgElqFar01NgIZsdco7Zb7VasU2YigIYL5tjqCL7Q5YkFQXKlcqQ7DbHthIALk/IWAKor82xPIhshxWABCYioDMz51sexcVi0XoG4DPLIyvJjkTArK3scDQnRvO0MdTrUHGiKZCP4tNgO6BAEI08EQH9Z2Qow0hyPypJGIa9p6JWKCn4SA8jSKmJIDgyRvPJkcRxjfUwNGr/i8+Mo32iHzWiThBD4NM60bet9P77/ubA728RlTjMiwiH6zEEfvIrwdZFtQmMJ7W/ofIDBZD5m3mVZGwJcOP2kmILIlCkE45HoPWurwCSg0+UQRD4ZyXxId+T7gQb9+4q9sioY5ltrOG3L5vqXiiJffDx/aUi83ZJ7jr2ohcEu8Hh6/m+I7OWGiVxbWKHsz+O3vSOakqFQdsFgQeJUiKD7Wv9YKXBgCeSUC3v2kM5EJhlHDh3NcgcPlG1BXZu98sDmTuBa4fsMnz9fniJUaGzs+eMC540XuR0aDO2L8Y3qPyMcdOM+R/8XcqRA3qp9gAAAABJRU5ErkJggg==",
_urls : [
{
type: "text/html",
method: "GET",
template: "http://www.amazon.com/exec/obidos/external-search/",
params: [
{
name: "field-keywords",
value: "{searchTerms}",
purpose: undefined,
},
{
name: "mode",
value: "blended",
purpose: undefined,
},
{
name: "tag",
value: "mozilla-20",
purpose: undefined,
},
{
name: "sourceid",
value: "Mozilla-search",
purpose: undefined,
},
],
mozparams: {},
},
],
},
};
isSubObjectOf(EXPECTED_ENGINE, engine, "Amazon");
}

Просмотреть файл

@ -0,0 +1,191 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/*
* Test Amazon search plugin URLs
*/
"use strict";
const BROWSER_SEARCH_PREF = "browser.search.";
function test() {
let engine = Services.search.getEngineByName("Amazon.com");
ok(engine, "Amazon is installed");
let previouslySelectedEngine = Services.search.currentEngine;
Services.search.currentEngine = engine;
let base = "http://www.amazon.com/exec/obidos/external-search/?field-keywords=foo&mode=blended&tag=mozilla-20&sourceid=Mozilla-search";
let url;
// Test search URLs (including purposes).
url = engine.getSubmission("foo").uri.spec;
is(url, base, "Check search URL for 'foo'");
waitForExplicitFinish();
var gCurrTest;
var gTests = [
{
name: "context menu search",
searchURL: base,
run: function () {
// Simulate a contextmenu search
// FIXME: This is a bit "low-level"...
BrowserSearch.loadSearch("foo", false, "contextmenu");
}
},
{
name: "keyword search",
searchURL: base,
run: function () {
gURLBar.value = "? foo";
gURLBar.focus();
EventUtils.synthesizeKey("VK_RETURN", {});
}
},
{
name: "search bar search",
searchURL: base,
run: function () {
let sb = BrowserSearch.searchBar;
sb.focus();
sb.value = "foo";
registerCleanupFunction(function () {
sb.value = "";
});
EventUtils.synthesizeKey("VK_RETURN", {});
}
},
{
name: "new tab search",
searchURL: base,
run: function () {
function doSearch(doc) {
// Re-add the listener, and perform a search
gBrowser.addProgressListener(listener);
doc.getElementById("newtab-search-text").value = "foo";
doc.getElementById("newtab-search-submit").click();
}
// load about:newtab, but remove the listener first so it doesn't
// get in the way
gBrowser.removeProgressListener(listener);
gBrowser.loadURI("about:newtab");
info("Waiting for about:newtab load");
tab.linkedBrowser.addEventListener("load", function load(event) {
if (event.originalTarget != tab.linkedBrowser.contentDocument ||
event.target.location.href == "about:blank") {
info("skipping spurious load event");
return;
}
tab.linkedBrowser.removeEventListener("load", load, true);
// Observe page setup
let win = gBrowser.contentWindow;
if (win.gSearch.currentEngineName ==
Services.search.currentEngine.name) {
doSearch(win.document);
}
else {
info("Waiting for newtab search init");
win.addEventListener("ContentSearchService", function done(event) {
info("Got newtab search event " + event.detail.type);
if (event.detail.type == "State") {
win.removeEventListener("ContentSearchService", done);
// Let gSearch respond to the event before continuing.
executeSoon(() => doSearch(win.document));
}
});
}
}, true);
}
},
{
name: "home page search",
searchURL: base,
run: function () {
// Bug 992270: Ignore uncaught about:home exceptions (related to snippets from IndexedDB)
ignoreAllUncaughtExceptions(true);
// load about:home, but remove the listener first so it doesn't
// get in the way
gBrowser.removeProgressListener(listener);
gBrowser.loadURI("about:home");
info("Waiting for about:home load");
tab.linkedBrowser.addEventListener("load", function load(event) {
if (event.originalTarget != tab.linkedBrowser.contentDocument ||
event.target.location.href == "about:blank") {
info("skipping spurious load event");
return;
}
tab.linkedBrowser.removeEventListener("load", load, true);
// Observe page setup
let doc = gBrowser.contentDocument;
let mutationObserver = new MutationObserver(function (mutations) {
for (let mutation of mutations) {
if (mutation.attributeName == "searchEngineName") {
// Re-add the listener, and perform a search
gBrowser.addProgressListener(listener);
doc.getElementById("searchText").value = "foo";
doc.getElementById("searchSubmit").click();
}
}
});
mutationObserver.observe(doc.documentElement, { attributes: true });
}, true);
}
}
];
function nextTest() {
// Make sure we listen again for uncaught exceptions in the next test or cleanup.
ignoreAllUncaughtExceptions(false);
if (gTests.length) {
gCurrTest = gTests.shift();
info("Running : " + gCurrTest.name);
executeSoon(gCurrTest.run);
} else {
finish();
}
}
let tab = gBrowser.selectedTab = gBrowser.addTab();
let listener = {
onStateChange: function onStateChange(webProgress, req, flags, status) {
info("onStateChange");
// Only care about top-level document starts
let docStart = Ci.nsIWebProgressListener.STATE_IS_DOCUMENT |
Ci.nsIWebProgressListener.STATE_START;
if (!(flags & docStart) || !webProgress.isTopLevel)
return;
info("received document start");
ok(req instanceof Ci.nsIChannel, "req is a channel");
is(req.originalURI.spec, gCurrTest.searchURL, "search URL was loaded");
info("Actual URI: " + req.URI.spec);
req.cancel(Components.results.NS_ERROR_FAILURE);
executeSoon(nextTest);
}
}
registerCleanupFunction(function () {
gBrowser.removeProgressListener(listener);
gBrowser.removeTab(tab);
Services.search.currentEngine = previouslySelectedEngine;
});
tab.linkedBrowser.addEventListener("load", function load() {
tab.linkedBrowser.removeEventListener("load", load, true);
gBrowser.addProgressListener(listener);
nextTest();
}, true);
}

Просмотреть файл

@ -9,18 +9,11 @@
const BROWSER_SEARCH_PREF = "browser.search.";
let runtime = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime);
// Custom search parameters
const PC_PARAM_VALUE = runtime.isOfficialBranding ? "MOZI" : null;
function test() {
let engine = Services.search.getEngineByName("Bing");
ok(engine, "Bing");
let base = "http://www.bing.com/search?q=foo";
if (typeof(PC_PARAM_VALUE) == "string")
base += "&pc=" + PC_PARAM_VALUE;
let base = "http://www.bing.com/search?q=foo&pc=MOZI";
let url;
// Test search URLs (including purposes).
@ -85,6 +78,11 @@ function test() {
value: "{searchTerms}",
purpose: undefined,
},
{
name: "pc",
value: "MOZI",
purpose: undefined,
},
{
name: "form",
value: "MOZCON",

Просмотреть файл

@ -9,9 +9,6 @@
const BROWSER_SEARCH_PREF = "browser.search.";
let runtime = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime);
// Custom search parameters
const PC_PARAM_VALUE = runtime.isOfficialBranding ? "MOZI" : null;
function test() {
let engine = Services.search.getEngineByName("Bing");
@ -20,10 +17,7 @@ function test() {
let previouslySelectedEngine = Services.search.currentEngine;
Services.search.currentEngine = engine;
let base = "http://www.bing.com/search?q=foo";
if (typeof(PC_PARAM_VALUE) == "string")
base += "&pc=" + PC_PARAM_VALUE;
let base = "http://www.bing.com/search?q=foo&pc=MOZI";
let url;
// Test search URLs (including purposes).

Просмотреть файл

@ -0,0 +1,84 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/*
* Test eBay search plugin URLs
*/
"use strict";
const BROWSER_SEARCH_PREF = "browser.search.";
function test() {
let engine = Services.search.getEngineByName("eBay");
ok(engine, "eBay");
let base = "http://rover.ebay.com/rover/1/711-47294-18009-3/4?mfe=search&mpre=http://www.ebay.com/sch/i.html?_nkw=foo";
let url;
// Test search URLs (including purposes).
url = engine.getSubmission("foo").uri.spec;
is(url, base, "Check search URL for 'foo'");
// Check search suggestion URL.
url = engine.getSubmission("foo", "application/x-suggestions+json").uri.spec;
is(url, "http://autosug.ebay.com/autosug?sId=0&kwd=foo&fmt=osr", "Check search suggestion URL for 'foo'");
// Check all other engine properties.
const EXPECTED_ENGINE = {
name: "eBay",
alias: null,
description: "eBay - Online auctions",
searchForm: "http://search.ebay.com/",
type: Ci.nsISearchEngine.TYPE_MOZSEARCH,
hidden: false,
wrappedJSObject: {
queryCharset: "ISO-8859-1",
"_iconURL": "data:image/x-icon;base64,AAABAAIAEBAAAAAAAAB6AQAAJgAAACAgAAAAAAAAQgMAAKABAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAFBSURBVDjLtZPdK0MBGIf3J5Babhx3rinFBWuipaUskX9DYvkopqgV90q5UJpyp0OKrUWM2VrRsS9D0zZKHGaOnW1nj4vtypVtPPe/533r9746QAAOAJXfo5Yzgg44pHrcugon/6Sgo0b+XuAOZ2iZiVQmyPoDpIwmUkYTzqM7GsdDdC7F6Lbf8pzOkfWOouzqeZem2b+2AqAV8zjD8yVBqqcf2b7C66yNiMGMfixIQSvi8Mp0LEbR5ADq1QSKWM+Gx0RC9nOZ2GLzwlIWdPWiuNzk4w/EpThNkyEAXKEP2ud8KGId2sspilhPMrmNwzfCuqePr/xbSfC5I/I0MMSj2YJ3z49gDdO2cEOrLUowJpE9G0QRG1ClKbR0EIdvmOPYcnUtnN+vsnZiQC1k/qnGagQ1n3LNzySUJZVskitnmr8BlQG7T2hvgxsAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAMJSURBVFjD7ZddSFNhGMeHXXQTZFFCWfR1pRhUECQlBdWVToo+6KYu1KigtDASG5qUfZgFZvahEDosECPDktKZS1FL+1DRnEvdUptjug91X2dnZzv/3vO6OZbWnR4v9sADL+fs7P97/s/znu2VAJD4UkpSSdKG+QubTyPBr+sXz8XCR64fIAHihVTis0SsUAoAVhEBrBKIHCGAEMB/ARi3F5LkbpS2WMRzYEEBXC2tsD6T03R9agsCGLNyqPw6CXmrBT06JvhbPHZwmkdwtR0B138PPKOHgzXD5jLAy3tmibo4K9weZwDAazJj/FQKRnfugfHMeRiTz0K3Ixam1HQKcPC+Fisu9NK1P08Uj4DleHgMdXC+WQ7nu3UEOhFMfTQcVUvQ1H4IN2sj8H2k7K+2TqCc3GseyA8AmDOzMBq7D9bS8sAr6nEJdNt3UbHVF1XQGtmZew8bTPT6tWoD3KpsUvlR8NxUoEICMvl6KQo+xqCwcRs4T8Ax5c8bFExjbAgAjO7aS8VsLypgq3g5nWStjztAhWRVhqAqeB6IuKTClkw1eNYEbrCQQBwD8yGGOsAooogLYejQPKBi7UPF9DkH+ezd+o141ZkUPAOC+L9SAMivNc7q46YMNSLTe4n1kaQF4XD3ZIDTPgU3XEYciKcAHrsGJS1xKFBGgyVzouiT4VbdGhjt/cEA5isyKsaz7jl3we7bg7Rqf6j0LoSldON4wWcqJDgQNGTN++l13vELA+MK6kKd6iryFOvxtidt9i5gO7owdjKJQliflNAU1pas6xQgnAzg1ux+lJEdILixNr0Pq9JUUA8NwVG9DM73G0jlcnh+V4BpjIWzJmIGQIjnXw5TiDuKSEwxurm3ITc8DNO51BnrLbIcsrW0dNA6RxgUKU1UdGVqLy5X6qGzTLvlnewiBZyGs3Yz6X8UeaYI3olvZDhzwLumZ+eHvooCCC0Q5VUsb4unwycM4YIDqA01tPqmgbzQr2EIYPECiPm33LYoDiZSsY9moh9O/Znoa4d9HkXtPg2pX/cPKCoRQ+ocZa4AAAAASUVORK5CYII=",
_urls : [
{
type: "application/x-suggestions+json",
method: "GET",
template: "http://autosug.ebay.com/autosug",
params: [
{
name: "sId",
value: "0",
purpose: undefined,
},
{
name: "kwd",
value: "{searchTerms}",
purpose: undefined,
},
{
name: "fmt",
value: "osr",
purpose: undefined,
},
],
},
{
type: "text/html",
method: "GET",
template: "http://rover.ebay.com/rover/1/711-47294-18009-3/4",
params: [
{
name: "mfe",
value: "search",
purpose: undefined,
},
{
name: "mpre",
value: "http://www.ebay.com/sch/i.html?_nkw={searchTerms}",
purpose: undefined,
},
],
mozparams: {},
},
],
},
};
isSubObjectOf(EXPECTED_ENGINE, engine, "eBay");
}

Просмотреть файл

@ -0,0 +1,191 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/*
* Test eBay search plugin URLs
*/
"use strict";
const BROWSER_SEARCH_PREF = "browser.search.";
function test() {
let engine = Services.search.getEngineByName("eBay");
ok(engine, "eBay is installed");
let previouslySelectedEngine = Services.search.currentEngine;
Services.search.currentEngine = engine;
let base = "http://rover.ebay.com/rover/1/711-47294-18009-3/4?mfe=search&mpre=http://www.ebay.com/sch/i.html?_nkw=foo";
let url;
// Test search URLs (including purposes).
url = engine.getSubmission("foo").uri.spec;
is(url, base, "Check search URL for 'foo'");
waitForExplicitFinish();
var gCurrTest;
var gTests = [
{
name: "context menu search",
searchURL: base,
run: function () {
// Simulate a contextmenu search
// FIXME: This is a bit "low-level"...
BrowserSearch.loadSearch("foo", false, "contextmenu");
}
},
{
name: "keyword search",
searchURL: base,
run: function () {
gURLBar.value = "? foo";
gURLBar.focus();
EventUtils.synthesizeKey("VK_RETURN", {});
}
},
{
name: "search bar search",
searchURL: base,
run: function () {
let sb = BrowserSearch.searchBar;
sb.focus();
sb.value = "foo";
registerCleanupFunction(function () {
sb.value = "";
});
EventUtils.synthesizeKey("VK_RETURN", {});
}
},
{
name: "new tab search",
searchURL: base,
run: function () {
function doSearch(doc) {
// Re-add the listener, and perform a search
gBrowser.addProgressListener(listener);
doc.getElementById("newtab-search-text").value = "foo";
doc.getElementById("newtab-search-submit").click();
}
// load about:newtab, but remove the listener first so it doesn't
// get in the way
gBrowser.removeProgressListener(listener);
gBrowser.loadURI("about:newtab");
info("Waiting for about:newtab load");
tab.linkedBrowser.addEventListener("load", function load(event) {
if (event.originalTarget != tab.linkedBrowser.contentDocument ||
event.target.location.href == "about:blank") {
info("skipping spurious load event");
return;
}
tab.linkedBrowser.removeEventListener("load", load, true);
// Observe page setup
let win = gBrowser.contentWindow;
if (win.gSearch.currentEngineName ==
Services.search.currentEngine.name) {
doSearch(win.document);
}
else {
info("Waiting for newtab search init");
win.addEventListener("ContentSearchService", function done(event) {
info("Got newtab search event " + event.detail.type);
if (event.detail.type == "State") {
win.removeEventListener("ContentSearchService", done);
// Let gSearch respond to the event before continuing.
executeSoon(() => doSearch(win.document));
}
});
}
}, true);
}
},
{
name: "home page search",
searchURL: base,
run: function () {
// Bug 992270: Ignore uncaught about:home exceptions (related to snippets from IndexedDB)
ignoreAllUncaughtExceptions(true);
// load about:home, but remove the listener first so it doesn't
// get in the way
gBrowser.removeProgressListener(listener);
gBrowser.loadURI("about:home");
info("Waiting for about:home load");
tab.linkedBrowser.addEventListener("load", function load(event) {
if (event.originalTarget != tab.linkedBrowser.contentDocument ||
event.target.location.href == "about:blank") {
info("skipping spurious load event");
return;
}
tab.linkedBrowser.removeEventListener("load", load, true);
// Observe page setup
let doc = gBrowser.contentDocument;
let mutationObserver = new MutationObserver(function (mutations) {
for (let mutation of mutations) {
if (mutation.attributeName == "searchEngineName") {
// Re-add the listener, and perform a search
gBrowser.addProgressListener(listener);
doc.getElementById("searchText").value = "foo";
doc.getElementById("searchSubmit").click();
}
}
});
mutationObserver.observe(doc.documentElement, { attributes: true });
}, true);
}
}
];
function nextTest() {
// Make sure we listen again for uncaught exceptions in the next test or cleanup.
ignoreAllUncaughtExceptions(false);
if (gTests.length) {
gCurrTest = gTests.shift();
info("Running : " + gCurrTest.name);
executeSoon(gCurrTest.run);
} else {
finish();
}
}
let tab = gBrowser.selectedTab = gBrowser.addTab();
let listener = {
onStateChange: function onStateChange(webProgress, req, flags, status) {
info("onStateChange");
// Only care about top-level document starts
let docStart = Ci.nsIWebProgressListener.STATE_IS_DOCUMENT |
Ci.nsIWebProgressListener.STATE_START;
if (!(flags & docStart) || !webProgress.isTopLevel)
return;
info("received document start");
ok(req instanceof Ci.nsIChannel, "req is a channel");
is(req.originalURI.spec, gCurrTest.searchURL, "search URL was loaded");
info("Actual URI: " + req.URI.spec);
req.cancel(Components.results.NS_ERROR_FAILURE);
executeSoon(nextTest);
}
}
registerCleanupFunction(function () {
gBrowser.removeProgressListener(listener);
gBrowser.removeTab(tab);
Services.search.currentEngine = previouslySelectedEngine;
});
tab.linkedBrowser.addEventListener("load", function load() {
tab.linkedBrowser.removeEventListener("load", load, true);
gBrowser.addProgressListener(listener);
nextTest();
}, true);
}

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -0,0 +1,191 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/*
* Test Yahoo search plugin URLs
*/
"use strict";
const BROWSER_SEARCH_PREF = "browser.search.";
function test() {
let engine = Services.search.getEngineByName("Yahoo");
ok(engine, "Yahoo is installed");
let previouslySelectedEngine = Services.search.currentEngine;
Services.search.currentEngine = engine;
let base = "https://search.yahoo.com/search?p=foo&ei=UTF-8&fr=moz35";
let url;
// Test search URLs (including purposes).
url = engine.getSubmission("foo").uri.spec;
is(url, base, "Check search URL for 'foo'");
waitForExplicitFinish();
var gCurrTest;
var gTests = [
{
name: "context menu search",
searchURL: base,
run: function () {
// Simulate a contextmenu search
// FIXME: This is a bit "low-level"...
BrowserSearch.loadSearch("foo", false, "contextmenu");
}
},
{
name: "keyword search",
searchURL: base,
run: function () {
gURLBar.value = "? foo";
gURLBar.focus();
EventUtils.synthesizeKey("VK_RETURN", {});
}
},
{
name: "search bar search",
searchURL: base,
run: function () {
let sb = BrowserSearch.searchBar;
sb.focus();
sb.value = "foo";
registerCleanupFunction(function () {
sb.value = "";
});
EventUtils.synthesizeKey("VK_RETURN", {});
}
},
{
name: "new tab search",
searchURL: base,
run: function () {
function doSearch(doc) {
// Re-add the listener, and perform a search
gBrowser.addProgressListener(listener);
doc.getElementById("newtab-search-text").value = "foo";
doc.getElementById("newtab-search-submit").click();
}
// load about:newtab, but remove the listener first so it doesn't
// get in the way
gBrowser.removeProgressListener(listener);
gBrowser.loadURI("about:newtab");
info("Waiting for about:newtab load");
tab.linkedBrowser.addEventListener("load", function load(event) {
if (event.originalTarget != tab.linkedBrowser.contentDocument ||
event.target.location.href == "about:blank") {
info("skipping spurious load event");
return;
}
tab.linkedBrowser.removeEventListener("load", load, true);
// Observe page setup
let win = gBrowser.contentWindow;
if (win.gSearch.currentEngineName ==
Services.search.currentEngine.name) {
doSearch(win.document);
}
else {
info("Waiting for newtab search init");
win.addEventListener("ContentSearchService", function done(event) {
info("Got newtab search event " + event.detail.type);
if (event.detail.type == "State") {
win.removeEventListener("ContentSearchService", done);
// Let gSearch respond to the event before continuing.
executeSoon(() => doSearch(win.document));
}
});
}
}, true);
}
},
{
name: "home page search",
searchURL: base,
run: function () {
// Bug 992270: Ignore uncaught about:home exceptions (related to snippets from IndexedDB)
ignoreAllUncaughtExceptions(true);
// load about:home, but remove the listener first so it doesn't
// get in the way
gBrowser.removeProgressListener(listener);
gBrowser.loadURI("about:home");
info("Waiting for about:home load");
tab.linkedBrowser.addEventListener("load", function load(event) {
if (event.originalTarget != tab.linkedBrowser.contentDocument ||
event.target.location.href == "about:blank") {
info("skipping spurious load event");
return;
}
tab.linkedBrowser.removeEventListener("load", load, true);
// Observe page setup
let doc = gBrowser.contentDocument;
let mutationObserver = new MutationObserver(function (mutations) {
for (let mutation of mutations) {
if (mutation.attributeName == "searchEngineName") {
// Re-add the listener, and perform a search
gBrowser.addProgressListener(listener);
doc.getElementById("searchText").value = "foo";
doc.getElementById("searchSubmit").click();
}
}
});
mutationObserver.observe(doc.documentElement, { attributes: true });
}, true);
}
}
];
function nextTest() {
// Make sure we listen again for uncaught exceptions in the next test or cleanup.
ignoreAllUncaughtExceptions(false);
if (gTests.length) {
gCurrTest = gTests.shift();
info("Running : " + gCurrTest.name);
executeSoon(gCurrTest.run);
} else {
finish();
}
}
let tab = gBrowser.selectedTab = gBrowser.addTab();
let listener = {
onStateChange: function onStateChange(webProgress, req, flags, status) {
info("onStateChange");
// Only care about top-level document starts
let docStart = Ci.nsIWebProgressListener.STATE_IS_DOCUMENT |
Ci.nsIWebProgressListener.STATE_START;
if (!(flags & docStart) || !webProgress.isTopLevel)
return;
info("received document start");
ok(req instanceof Ci.nsIChannel, "req is a channel");
is(req.originalURI.spec, gCurrTest.searchURL, "search URL was loaded");
info("Actual URI: " + req.URI.spec);
req.cancel(Components.results.NS_ERROR_FAILURE);
executeSoon(nextTest);
}
}
registerCleanupFunction(function () {
gBrowser.removeProgressListener(listener);
gBrowser.removeTab(tab);
Services.search.currentEngine = previouslySelectedEngine;
});
tab.linkedBrowser.addEventListener("load", function load() {
tab.linkedBrowser.removeEventListener("load", load, true);
gBrowser.addProgressListener(listener);
nextTest();
}, true);
}

Просмотреть файл

@ -126,15 +126,16 @@ SessionStartup.prototype = {
return;
}
this._initialState = this._parseStateString(stateString);
this._initialState = this._parseStateString(stateString);
let shouldResumeSessionOnce = Services.prefs.getBoolPref("browser.sessionstore.resume_session_once");
let shouldResumeSession = shouldResumeSessionOnce ||
Services.prefs.getIntPref("browser.startup.page") == BROWSER_STARTUP_RESUME_SESSION;
// If this is a normal restore then throw away any previous session
if (!shouldResumeSessionOnce)
if (!shouldResumeSessionOnce && this._initialState) {
delete this._initialState.lastSessionState;
}
let resumeFromCrash = Services.prefs.getBoolPref("browser.sessionstore.resume_from_crash");

Просмотреть файл

@ -246,7 +246,7 @@ function test() {
test_existingSHEnd_noClear, test_existingSHMiddle_noClear,
test_getBrowserState_lotsOfTabsOpening,
test_getBrowserState_userTypedValue, test_userTypedClearLoadURI];
let originalState = ss.getBrowserState();
let originalState = JSON.parse(ss.getBrowserState());
let state = {
windows: [{
tabs: [{ entries: [{ url: "about:blank" }] }]
@ -256,8 +256,7 @@ function test() {
if (tests.length) {
waitForBrowserState(state, tests.shift());
} else {
ss.setBrowserState(originalState);
executeSoon(finish);
waitForBrowserState(originalState, finish);
}
}

Просмотреть файл

@ -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/. */
let stateBackup = ss.getBrowserState();
let stateBackup = JSON.parse(ss.getBrowserState());
function test() {
/** Test for Bug 600545 **/
@ -72,8 +72,7 @@ function done() {
currentWindow.close();
}
ss.setBrowserState(stateBackup);
executeSoon(finish);
waitForBrowserState(stateBackup, finish);
}
// Count up the number of tabs in the state data

Просмотреть файл

@ -46,7 +46,7 @@ function testBug601955_3() {
}
function done() {
gBrowser.removeTab(window.gBrowser.tabs[0]);
gBrowser.removeTab(window.gBrowser.tabs[1]);
Services.prefs.clearUserPref("browser.sessionstore.interval");

Просмотреть файл

@ -165,6 +165,9 @@ function waitForBrowserState(aState, aSetStateCallback) {
listening = true;
gBrowser.tabContainer.addEventListener("SSTabRestored", onSSTabRestored, true);
// Ensure setBrowserState() doesn't remove the initial tab.
gBrowser.selectedTab = gBrowser.tabs[0];
// Finally, call setBrowserState
ss.setBrowserState(JSON.stringify(aState));
}
@ -520,6 +523,7 @@ let TestRunner = {
*/
finish: function () {
closeAllButPrimaryWindow();
gBrowser.selectedTab = gBrowser.tabs[0];
waitForBrowserState(this.backupState, finish);
}
};

Просмотреть файл

@ -0,0 +1,3 @@
{
"windows": // invalid json
}

Просмотреть файл

@ -0,0 +1,21 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function run_test() {
let profd = do_get_profile();
let sourceSession = do_get_file("data/sessionstore_invalid.js");
sourceSession.copyTo(profd, "sessionstore.js");
let sourceCheckpoints = do_get_file("data/sessionCheckpoints_all.json");
sourceCheckpoints.copyTo(profd, "sessionCheckpoints.json");
do_test_pending();
let startup = Cc["@mozilla.org/browser/sessionstartup;1"].
getService(Ci.nsISessionStartup);
afterSessionStartupInitialization(function cb() {
do_check_eq(startup.sessionType, Ci.nsISessionStartup.NO_SESSION);
do_test_finished();
});
}

Просмотреть файл

@ -4,9 +4,11 @@ tail =
firefox-appdir = browser
support-files =
data/sessionCheckpoints_all.json
data/sessionstore_invalid.js
data/sessionstore_valid.js
[test_backup.js]
[test_backup_once.js]
[test_startup_nosession_async.js]
[test_startup_session_async.js]
[test_startup_invalid_session.js]

Просмотреть файл

@ -37,6 +37,7 @@ function test() {
Services.prefs.clearUserPref("browser.sessionstore.restore_hidden_tabs");
gBrowser.selectedTab = gBrowser.tabs[0];
ss.setBrowserState(stateBackup);
});

Просмотреть файл

@ -9,6 +9,10 @@ function test() {
registerCleanupFunction(function() {
gBrowser.unpinTab(pinnedTab);
// Don't remove the initial tab.
gBrowser.moveTabTo(gBrowser.tabs[1], 0);
while (gBrowser.tabs[1])
gBrowser.removeTab(gBrowser.tabs[1]);
hideTabView();

Просмотреть файл

@ -3,34 +3,26 @@
function test() {
waitForExplicitFinish();
window.addEventListener("tabviewshown", onTabViewWindowLoaded, false);
TabView.toggle();
newWindowWithTabView(onTabViewWindowLoaded);
}
function onTabViewWindowLoaded() {
window.removeEventListener("tabviewshown", onTabViewWindowLoaded, false);
let contentWindow = document.getElementById("tab-view").contentWindow;
function onTabViewWindowLoaded(win) {
let contentWindow = win.TabView.getContentWindow();
is(contentWindow.GroupItems.groupItems.length, 1,
"There is one group item on startup");
is(gBrowser.tabs.length, 1, "There is one tab on startup");
is(win.gBrowser.tabs.length, 1, "There is one tab on startup");
let groupItem = contentWindow.GroupItems.groupItems[0];
hideGroupItem(groupItem, function () {
let onTabViewHidden = function() {
window.removeEventListener("tabviewhidden", onTabViewHidden, false);
hideTabView(() => {
is(contentWindow.GroupItems.groupItems.length, 1,
"There is still one group item");
isnot(groupItem, contentWindow.GroupItems.groupItems[0],
"The initial group item is not the same as the final group item");
is(gBrowser.tabs.length, 1, "There is only one tab");
ok(!TabView.isVisible(), "Tab View is hidden");
finish();
};
window.addEventListener("tabviewhidden", onTabViewHidden, false);
TabView.hide();
is(win.gBrowser.tabs.length, 1, "There is only one tab");
ok(!win.TabView.isVisible(), "Tab View is hidden");
promiseWindowClosed(win).then(finish);
}, win);
});
}

Просмотреть файл

@ -40,7 +40,7 @@ function test() {
is(targetGroup.getChildren().length, 2, 'target group has now two children');
// cleanup and finish
tabItem.close();
targetGroup.getChild(0).close();
hideTabView(finishTest);
});
}

Просмотреть файл

@ -3,6 +3,7 @@
function test() {
let cw;
let win;
let currentTest;
let getGroupItem = function (index) {
@ -15,7 +16,7 @@ function test() {
cw.UI.setActive(groupItem);
for (let i=0; i<numTabs || 0; i++)
gBrowser.loadOneTab('about:blank', {inBackground: true});
win.gBrowser.loadOneTab('about:blank', {inBackground: true});
return groupItem;
}
@ -35,13 +36,13 @@ function test() {
}
currentTest = test.name;
showTabView(test.func);
showTabView(test.func, win);
} else
hideTabView(finish);
promiseWindowClosed(win).then(finish);
}
let assertTabViewIsHidden = function () {
ok(!TabView.isVisible(), currentTest + ': tabview is hidden');
ok(!win.TabView.isVisible(), currentTest + ': tabview is hidden');
}
let assertNumberOfGroupItems = function (num) {
@ -49,7 +50,7 @@ function test() {
}
let assertNumberOfTabs = function (num) {
is(gBrowser.tabs.length, num, currentTest + ': number of tabs is equal to ' + num);
is(win.gBrowser.tabs.length, num, currentTest + ': number of tabs is equal to ' + num);
}
let assertGroupItemRemoved = function (groupItem) {
@ -68,7 +69,7 @@ function test() {
closeGroupItem(groupItem, function () {
assertNumberOfGroupItems(1);
assertGroupItemRemoved(groupItem);
whenTabViewIsHidden(next);
whenTabViewIsHidden(next, win);
});
}
@ -82,7 +83,7 @@ function test() {
assertNumberOfGroupItems(1);
assertGroupItemRemoved(groupItem);
next();
});
}, win);
});
}
@ -97,7 +98,7 @@ function test() {
closeGroupItem(groupItem, function () {
assertNumberOfGroupItems(1);
assertGroupItemExists(newGroupItem);
hideTabView(next);
hideTabView(next, win);
});
}
@ -115,7 +116,7 @@ function test() {
assertGroupItemRemoved(groupItem);
assertGroupItemExists(newGroupItem);
next();
});
}, win);
});
}
@ -123,37 +124,37 @@ function test() {
// action: exit panorama
// expected: nothing should happen
let testPinnedTab1 = function () {
gBrowser.pinTab(gBrowser.selectedTab);
win.gBrowser.pinTab(win.gBrowser.selectedTab);
let groupItem = getGroupItem(0);
hideTabView(function () {
assertNumberOfGroupItems(1);
assertGroupItemExists(groupItem);
gBrowser.unpinTab(gBrowser.selectedTab);
win.gBrowser.unpinTab(win.gBrowser.selectedTab);
next();
});
}, win);
}
// setup: 1 pinned tab
// action: exit panorama
// expected: new blank group is created
let testPinnedTab2 = function () {
gBrowser.pinTab(gBrowser.selectedTab);
win.gBrowser.pinTab(win.gBrowser.selectedTab);
getGroupItem(0).close();
hideTabView(function () {
assertNumberOfTabs(1);
assertNumberOfGroupItems(1);
gBrowser.unpinTab(gBrowser.selectedTab);
win.gBrowser.unpinTab(win.gBrowser.selectedTab);
next();
});
}, win);
}
// setup: 1 pinned tab, 1 empty group, 1 non-empty group
// action: close non-empty group
// expected: nothing should happen
let testPinnedTab3 = function () {
gBrowser.pinTab(gBrowser.selectedTab);
win.gBrowser.pinTab(win.gBrowser.selectedTab);
let groupItem = getGroupItem(0);
let newGroupItem = createGroupItem(1);
@ -163,8 +164,8 @@ function test() {
assertNumberOfGroupItems(1);
assertGroupItemExists(groupItem);
gBrowser.unpinTab(gBrowser.selectedTab);
hideTabView(next);
win.gBrowser.unpinTab(win.gBrowser.selectedTab);
hideTabView(next, win);
});
}
@ -172,7 +173,7 @@ function test() {
// action: hide non-empty group, exit panorama
// expected: nothing should happen
let testPinnedTab4 = function () {
gBrowser.pinTab(gBrowser.selectedTab);
win.gBrowser.pinTab(win.gBrowser.selectedTab);
let groupItem = getGroupItem(0);
let newGroupItem = createGroupItem(1);
@ -183,9 +184,9 @@ function test() {
assertNumberOfGroupItems(1);
assertGroupItemExists(groupItem);
assertGroupItemRemoved(newGroupItem);
gBrowser.unpinTab(gBrowser.selectedTab);
win.gBrowser.unpinTab(win.gBrowser.selectedTab);
next();
});
}, win);
});
}
@ -200,7 +201,7 @@ function test() {
closeGroupItem(groupItem, function () {
assertNumberOfGroupItems(1);
assertGroupItemExists(newGroupItem);
whenTabViewIsHidden(next);
whenTabViewIsHidden(next, win);
});
}
@ -218,7 +219,7 @@ function test() {
assertGroupItemRemoved(groupItem);
assertGroupItemExists(newGroupItem);
next();
});
}, win);
});
}
@ -235,7 +236,7 @@ function test() {
assertNumberOfGroupItems(1);
assertGroupItemRemoved(groupItem);
assertGroupItemExists(hiddenGroupItem);
hideTabView(next);
hideTabView(next, win);
});
});
}
@ -255,7 +256,7 @@ function test() {
assertGroupItemRemoved(groupItem);
assertGroupItemRemoved(hiddenGroupItem);
next();
});
}, win);
});
});
}
@ -279,8 +280,9 @@ function test() {
waitForExplicitFinish();
showTabView(function () {
cw = TabView.getContentWindow();
newWindowWithTabView(window => {
win = window;
cw = win.TabView.getContentWindow();
next();
});
}

Просмотреть файл

@ -3,11 +3,12 @@
function test() {
let cw;
let win;
let groupItemId;
let prefix = 'start';
let assertTabViewIsHidden = function () {
ok(!TabView.isVisible(), prefix + ': tabview is hidden');
ok(!win.TabView.isVisible(), prefix + ': tabview is hidden');
}
let assertNumberOfGroups = function (num) {
@ -15,11 +16,11 @@ function test() {
}
let assertNumberOfTabs = function (num) {
is(gBrowser.visibleTabs.length, num, prefix + ': there should be ' + num + ' tabs');
is(win.gBrowser.visibleTabs.length, num, prefix + ': there should be ' + num + ' tabs');
}
let assertNumberOfPinnedTabs = function (num) {
is(gBrowser._numPinnedTabs, num, prefix + ': there should be ' + num + ' pinned tabs');
is(win.gBrowser._numPinnedTabs, num, prefix + ': there should be ' + num + ' pinned tabs');
}
let assertGroupItemPreserved = function () {
@ -34,7 +35,7 @@ function test() {
}
let createTab = function (url) {
return gBrowser.loadOneTab(url || 'http://mochi.test:8888/', {inBackground: true});
return win.gBrowser.loadOneTab(url || 'http://mochi.test:8888/', {inBackground: true});
}
let createBlankTab = function () {
@ -44,7 +45,7 @@ function test() {
let finishTest = function () {
prefix = 'finish';
assertValidPrerequisites();
finish();
promiseWindowClosed(win).then(finish);
}
let testUndoCloseWithSelectedBlankTab = function () {
@ -53,7 +54,7 @@ function test() {
assertNumberOfTabs(2);
afterAllTabsLoaded(function () {
gBrowser.removeTab(tab);
win.gBrowser.removeTab(tab);
assertNumberOfTabs(1);
assertNumberOfPinnedTabs(0);
@ -63,9 +64,9 @@ function test() {
assertGroupItemPreserved();
createBlankTab();
afterAllTabsLoaded(testUndoCloseWithSelectedBlankPinnedTab);
});
});
afterAllTabsLoaded(testUndoCloseWithSelectedBlankPinnedTab, win);
}, 0, win);
}, win);
}
let testUndoCloseWithSelectedBlankPinnedTab = function () {
@ -73,14 +74,8 @@ function test() {
assertNumberOfTabs(2);
afterAllTabsLoaded(function () {
gBrowser.removeTab(gBrowser.tabs[0]);
gBrowser.pinTab(gBrowser.tabs[0]);
registerCleanupFunction(function () {
let tab = gBrowser.tabs[0];
if (tab.pinned)
gBrowser.unpinTab(tab);
});
win.gBrowser.removeTab(win.gBrowser.tabs[0]);
win.gBrowser.pinTab(win.gBrowser.tabs[0]);
assertNumberOfTabs(1);
assertNumberOfPinnedTabs(1);
@ -91,23 +86,24 @@ function test() {
assertGroupItemPreserved();
createBlankTab();
gBrowser.removeTab(gBrowser.tabs[0]);
win.gBrowser.removeTab(win.gBrowser.tabs[0]);
afterAllTabsLoaded(finishTest);
});
});
afterAllTabsLoaded(finishTest, win);
}, 0, win);
}, win);
}
waitForExplicitFinish();
registerCleanupFunction(function () TabView.hide());
showTabView(function () {
newWindowWithTabView(window => {
win = window;
hideTabView(function () {
cw = TabView.getContentWindow();
cw = win.TabView.getContentWindow();
groupItemId = cw.GroupItems.groupItems[0].id;
assertValidPrerequisites();
testUndoCloseWithSelectedBlankTab();
});
}, win);
});
}

Просмотреть файл

@ -18,18 +18,18 @@ let activeGroup;
function test() {
waitForExplicitFinish();
showTabView(function () {
contentWindow = TabView.getContentWindow();
newWindowWithTabView(win => {
contentWindow = win.TabView.getContentWindow();
activeGroup = contentWindow.GroupItems.getActiveGroupItem();
gBrowser.browsers[0].loadURI("data:text/html,<p>test for bug 626455, tab1");
win.gBrowser.browsers[0].loadURI("data:text/html,<p>test for bug 626455, tab1");
let tab = gBrowser.addTab(TEST_URL);
afterAllTabsLoaded(() => testStayOnPage(tab));
let tab = win.gBrowser.addTab(TEST_URL);
afterAllTabsLoaded(() => testStayOnPage(win, tab));
});
}
function testStayOnPage(blockingTab) {
function testStayOnPage(win, blockingTab) {
let browser = blockingTab.linkedBrowser;
waitForOnBeforeUnloadDialog(browser, function (btnLeave, btnStay) {
// stay on page
@ -37,12 +37,12 @@ function testStayOnPage(blockingTab) {
executeSoon(function () {
showTabView(function () {
is(gBrowser.tabs.length, 1,
is(win.gBrowser.tabs.length, 1,
"The total number of tab is 1 when staying on the page");
// The other initial tab has been closed when trying to close the tab
// group. The only tab left is the one with the onbeforeunload dialog.
let url = gBrowser.browsers[0].currentURI.spec;
let url = win.gBrowser.browsers[0].currentURI.spec;
ok(url.contains("onbeforeunload"), "The open tab is the expected one");
is(contentWindow.GroupItems.getActiveGroupItem(), activeGroup,
@ -52,32 +52,32 @@ function testStayOnPage(blockingTab) {
"Only one group is open");
// start the next test
testLeavePage(gBrowser.tabs[0]);
});
testLeavePage(win, win.gBrowser.tabs[0]);
}, win);
});
});
closeGroupItem(activeGroup);
}
function testLeavePage(blockingTab) {
function testLeavePage(win, blockingTab) {
let browser = blockingTab.linkedBrowser;
waitForOnBeforeUnloadDialog(browser, function (btnLeave, btnStay) {
// Leave page
btnLeave.click();
});
whenGroupClosed(activeGroup, finishTest);
whenGroupClosed(activeGroup, () => finishTest(win));
closeGroupItem(activeGroup);
}
function finishTest() {
is(gBrowser.tabs.length, 1,
function finishTest(win) {
is(win.gBrowser.tabs.length, 1,
"The total number of tab is 1 after leaving the page");
is(contentWindow.TabItems.getItems().length, 1,
"The total number of tab items is 1 after leaving the page");
let location = gBrowser.browsers[0].currentURI.spec;
let location = win.gBrowser.browsers[0].currentURI.spec;
is(location, BROWSER_NEW_TAB_URL, "The open tab is the expected one");
isnot(contentWindow.GroupItems.getActiveGroupItem(), activeGroup,
@ -88,7 +88,7 @@ function finishTest() {
contentWindow = null;
activeGroup = null;
finish();
promiseWindowClosed(win).then(finish);
}
// ----------

Просмотреть файл

@ -4,10 +4,10 @@
function test() {
waitForExplicitFinish();
showTabView(function () {
is(gBrowser.tabs.length, 1, "There is only one tab");
newWindowWithTabView(win => {
is(win.gBrowser.tabs.length, 1, "There is only one tab");
let tab = gBrowser.tabs[0];
let tab = win.gBrowser.tabs[0];
let tabItem = tab._tabViewTabItem;
ok(tabItem.parent, "The tab item belongs to a group");
let groupId = tabItem.parent.id;
@ -16,16 +16,16 @@ function test() {
whenTabViewIsHidden(function() {
// a new tab with group should be opened
is(gBrowser.tabs.length, 1, "There is still one tab");
isnot(gBrowser.selectedTab, tab, "The tab is different");
is(win.gBrowser.tabs.length, 1, "There is still one tab");
isnot(win.gBrowser.selectedTab, tab, "The tab is different");
tab = gBrowser.tabs[0];
tab = win.gBrowser.tabs[0];
tabItem = tab._tabViewTabItem;
ok(tabItem.parent, "This new tab item belongs to a group");
is(tabItem.parent.id, groupId, "The group is different");
finish();
});
promiseWindowClosed(win).then(finish);
}, win);
});
}

Просмотреть файл

@ -4,44 +4,38 @@
function test() {
waitForExplicitFinish();
gBrowser.addTab("http://example.com/");
gBrowser.addTab("http://example.com/");
newWindowWithTabView(win => {
win.gBrowser.addTab("http://example.com/");
win.gBrowser.addTab("http://example.com/");
registerCleanupFunction(function () {
while (gBrowser.tabs.length > 1)
gBrowser.removeTab(gBrowser.tabs[1]);
hideTabView();
})
afterAllTabsLoaded(function() {
showTabView(function() {
let cw = TabView.getContentWindow();
afterAllTabsLoaded(function() {
let cw = win.TabView.getContentWindow();
let groupItemOne = cw.GroupItems.groupItems[0];
is(groupItemOne.getChildren().length, 3, "The number of tabs in group one is 3");
// create a group with a blank tab
let groupItemTwo = createGroupItemWithBlankTabs(window, 400, 400, 40, 1);
let groupItemTwo = createGroupItemWithBlankTabs(win, 400, 400, 40, 1);
is(groupItemTwo.getChildren().length, 1, "The number of tabs in group two is 1");
cw.UI.setActive(groupItemOne);
moveTabToAnotherGroup(groupItemOne.getChild(2).tab, groupItemOne, groupItemTwo, function() {
moveTabToAnotherGroup(groupItemOne.getChild(1).tab, groupItemOne, groupItemTwo, function() {
moveTabToAnotherGroup(win, groupItemOne.getChild(2).tab, groupItemOne, groupItemTwo, function() {
moveTabToAnotherGroup(win, groupItemOne.getChild(1).tab, groupItemOne, groupItemTwo, function() {
groupItemOne.close();
hideTabView(finish);
promiseWindowClosed(win).then(finish);
});
});
});
});
}
function moveTabToAnotherGroup(targetTab, groupItemOne, groupItemTwo, callback) {
function moveTabToAnotherGroup(win, targetTab, groupItemOne, groupItemTwo, callback) {
hideTabView(function() {
let tabCountInGroupItemOne = groupItemOne.getChildren().length;
let tabCountInGroupItemTwo = groupItemTwo.getChildren().length;
TabView.moveTabTo(targetTab, groupItemTwo.id);
win.TabView.moveTabTo(targetTab, groupItemTwo.id);
showTabView(function() {
is(groupItemOne.getChildren().length, --tabCountInGroupItemOne, "The number of tab items in group one is decreased");
@ -49,6 +43,6 @@ function moveTabToAnotherGroup(targetTab, groupItemOne, groupItemTwo, callback)
is(groupItemTwo.getChild(tabCountInGroupItemTwo-1).tab, targetTab, "The last tab is the moved tab");
callback();
});
});
}, win);
}, win);
}

Просмотреть файл

@ -509,12 +509,13 @@ StackFramesView.prototype = Heritage.extend(WidgetMethods, {
if (stackframeItem) {
// The container is not empty and an actual item was selected.
let depth = stackframeItem.attachment.depth;
DebuggerController.StackFrames.selectFrame(depth);
// Mirror the selected item in the classic list.
this.suppressSelectionEvents = true;
this._mirror.selectedItem = e => e.attachment.depth == depth;
this.suppressSelectionEvents = false;
DebuggerController.StackFrames.selectFrame(depth);
}
},

Просмотреть файл

@ -749,10 +749,11 @@ function openVarPopup(aPanel, aCoords, aWaitForFetchedProperties) {
let fetchedProperties = aWaitForFetchedProperties
? waitForDebuggerEvents(aPanel, events.FETCHED_BUBBLE_PROPERTIES)
: promise.resolve(null);
let updatedFrame = waitForDebuggerEvents(aPanel, events.FETCHED_SCOPES);
let { left, top } = editor.getCoordsFromPosition(aCoords);
bubble._findIdentifier(left, top);
return promise.all([popupShown, fetchedProperties]).then(waitForTick);
return promise.all([popupShown, fetchedProperties, updatedFrame]).then(waitForTick);
}
// Simulates the mouse hovering a variable in the debugger

Просмотреть файл

@ -1702,13 +1702,17 @@ Experiments.ExperimentEntry.prototype = {
}
this._enabled = false;
let changes = yield this.reconcileAddonState();
let now = this._policy.now();
this._lastChangedDate = now;
this._endDate = now;
let changes = yield this.reconcileAddonState();
this._logTermination(terminationKind, terminationReason);
if (terminationKind == TELEMETRY_LOG.TERMINATION.ADDON_UNINSTALLED) {
changes |= this.ADDON_CHANGE_UNINSTALL;
}
return changes;
}),

Просмотреть файл

@ -11,6 +11,7 @@ Cu.import("resource://gre/modules/osfile.jsm");
Cu.import("resource://services-sync/healthreport.jsm", this);
Cu.import("resource://testing-common/services/healthreport/utils.jsm", this);
Cu.import("resource://gre/modules/services/healthreport/providers.jsm");
Cu.import("resource://testing-common/AddonManagerTesting.jsm");
const PREF_EXPERIMENTS_ENABLED = "experiments.enabled";
const PREF_LOGGING_LEVEL = "experiments.logging.level";

Просмотреть файл

@ -25,6 +25,24 @@ let gManifestObject = null;
let gManifestHandlerURI = null;
let gTimerScheduleOffset = -1;
function uninstallExperimentAddons() {
return Task.spawn(function* () {
let addons = yield getExperimentAddons();
for (let a of addons) {
yield AddonTestUtils.uninstallAddonByID(a.id);
}
});
}
function testCleanup(experimentsInstance) {
return Task.spawn(function* () {
yield experimentsInstance.uninit();
yield removeCacheFile();
yield uninstallExperimentAddons();
restartManager();
});
}
function run_test() {
run_next_test();
}
@ -256,8 +274,7 @@ add_task(function* test_getExperiments() {
// Cleanup.
Services.obs.removeObserver(observer, OBSERVER_TOPIC);
yield experiments.uninit();
yield removeCacheFile();
yield testCleanup(experiments);
});
// Test that we handle the experiments addon already being
@ -337,8 +354,7 @@ add_task(function* test_addonAlreadyInstalled() {
// Cleanup.
Services.obs.removeObserver(observer, OBSERVER_TOPIC);
yield experiments.uninit();
yield removeCacheFile();
yield testCleanup(experiments);
});
add_task(function* test_lastActiveToday() {
@ -364,8 +380,7 @@ add_task(function* test_lastActiveToday() {
Assert.ok(lastActive, "Have a last active experiment");
Assert.equal(lastActive, e[0], "Last active object is expected.");
yield experiments.uninit();
yield removeCacheFile();
yield testCleanup(experiments);
});
// Test explicitly disabling experiments.
@ -450,10 +465,7 @@ add_task(function* test_disableExperiment() {
"Property " + k + " should match reference data.");
}
// Cleanup.
yield experiments.uninit();
yield removeCacheFile();
yield testCleanup(experiments);
});
add_task(function* test_disableExperimentsFeature() {
@ -541,10 +553,7 @@ add_task(function* test_disableExperimentsFeature() {
"Property " + k + " should match reference data.");
}
// Cleanup.
yield experiments.uninit();
yield removeCacheFile();
yield testCleanup(experiments);
});
// Test that after a failed experiment install:
@ -676,11 +685,7 @@ add_task(function* test_installFailure() {
}
}
// Cleanup.
Services.obs.removeObserver(observer, OBSERVER_TOPIC);
yield experiments.uninit();
yield removeCacheFile();
yield testCleanup(experiments);
});
// Test that after an experiment was disabled by user action,
@ -779,8 +784,7 @@ add_task(function* test_userDisabledAndUpdated() {
// Cleanup.
Services.obs.removeObserver(observer, OBSERVER_TOPIC);
yield experiments.uninit();
yield removeCacheFile();
yield testCleanup(experiments);
});
// Test that changing the hash for an active experiments triggers an
@ -871,8 +875,7 @@ add_task(function* test_updateActiveExperiment() {
// Cleanup.
Services.obs.removeObserver(observer, OBSERVER_TOPIC);
yield experiments.uninit();
yield removeCacheFile();
yield testCleanup(experiments);
});
// Tests that setting the disable flag for an active experiment
@ -963,8 +966,7 @@ add_task(function* test_disableActiveExperiment() {
// Cleanup.
Services.obs.removeObserver(observer, OBSERVER_TOPIC);
yield experiments.uninit();
yield removeCacheFile();
yield testCleanup(experiments);
});
// Test that:
@ -1044,8 +1046,7 @@ add_task(function* test_freezePendingExperiment() {
// Cleanup.
Services.obs.removeObserver(observer, OBSERVER_TOPIC);
yield experiments.uninit();
yield removeCacheFile();
yield testCleanup(experiments);
});
// Test that setting the frozen flag for an active experiment doesn't
@ -1125,8 +1126,7 @@ add_task(function* test_freezeActiveExperiment() {
// Cleanup.
Services.obs.removeObserver(observer, OBSERVER_TOPIC);
yield experiments.uninit();
yield removeCacheFile();
yield testCleanup(experiments);
});
// Test that removing an active experiment from the manifest doesn't
@ -1218,8 +1218,7 @@ add_task(function* test_removeActiveExperiment() {
// Cleanup.
Services.obs.removeObserver(observer, OBSERVER_TOPIC);
yield experiments.uninit();
yield removeCacheFile();
yield testCleanup(experiments);
});
// Test that we correctly handle experiment start & install failures.
@ -1274,8 +1273,7 @@ add_task(function* test_invalidUrl() {
// Cleanup.
Services.obs.removeObserver(observer, OBSERVER_TOPIC);
yield experiments.uninit();
yield removeCacheFile();
yield testCleanup(experiments);
});
// Test that we handle it properly when active experiment addons are being
@ -1353,8 +1351,7 @@ add_task(function* test_unexpectedUninstall() {
// Cleanup.
Services.obs.removeObserver(observer, OBSERVER_TOPIC);
yield experiments.uninit();
yield removeCacheFile();
yield testCleanup(experiments);
});
// If the Addon Manager knows of an experiment that we don't, it should get
@ -1387,8 +1384,7 @@ add_task(function* testUnknownExperimentsUninstalled() {
addons = yield getExperimentAddons();
Assert.equal(addons.length, 0, "Experiment 1 was uninstalled.");
yield experiments.uninit();
yield removeCacheFile();
yield testCleanup(experiments);
});
// If someone else installs an experiment add-on, we detect and stop that.
@ -1415,8 +1411,7 @@ add_task(function* testForeignExperimentInstall() {
addons = yield getExperimentAddons();
Assert.equal(addons.length, 0, "Add-on install should have been cancelled.");
yield experiments.uninit();
yield removeCacheFile();
yield testCleanup(experiments);
});
// Experiment add-ons will be disabled after Addon Manager restarts. Ensure
@ -1441,7 +1436,7 @@ add_task(function* testEnabledAfterRestart() {
};
let addons = yield getExperimentAddons();
Assert.equal(addons.length, 0, "Precondition: No experimenta add-ons installed.");
Assert.equal(addons.length, 0, "Precondition: No experiment add-ons installed.");
yield experiments.updateManifest();
let fromManifest = yield experiments.getExperiments();
@ -1464,6 +1459,65 @@ add_task(function* testEnabledAfterRestart() {
yield experiments.updateManifest();
Assert.ok(addons[0].isActive, "It activates when the manifest is evaluated.");
yield experiments.uninit();
yield removeCacheFile();
yield testCleanup(experiments);
});
// Test coverage for an add-on uninstall disabling the experiment and that it stays
// disabled over restarts.
add_task(function* test_foreignUninstallAndRestart() {
let experiments = new Experiments.Experiments(gPolicy);
gManifestObject = {
"version": 1,
experiments: [
{
id: EXPERIMENT1_ID,
xpiURL: gDataRoot + EXPERIMENT1_XPI_NAME,
xpiHash: EXPERIMENT1_XPI_SHA1,
startTime: gPolicy.now().getTime() / 1000 - 60,
endTime: gPolicy.now().getTime() / 1000 + 60,
maxActiveSeconds: 10 * SEC_IN_ONE_DAY,
appName: ["XPCShell"],
channel: ["nightly"],
},
],
};
let addons = yield getExperimentAddons();
Assert.equal(addons.length, 0, "Precondition: No experiment add-ons installed.");
yield experiments.updateManifest();
let experimentList = yield experiments.getExperiments();
Assert.equal(experimentList.length, 1, "A single experiment is known.");
addons = yield getExperimentAddons();
Assert.equal(addons.length, 1, "A single experiment add-on is installed.");
Assert.ok(addons[0].isActive, "That experiment is active.");
yield AddonTestUtils.uninstallAddonByID(EXPERIMENT1_ID);
yield experiments._mainTask;
let addons = yield getExperimentAddons();
Assert.equal(addons.length, 0, "Experiment add-on should have been removed.");
experimentList = yield experiments.getExperiments();
Assert.equal(experimentList.length, 1, "A single experiment is known.");
Assert.equal(experimentList[0].id, EXPERIMENT1_ID, "Experiment 1 should be the sole entry.");
Assert.ok(!experimentList[0].active, "Experiment 1 should not be active anymore.");
// Fake restart behaviour.
experiments.uninit();
restartManager();
experiments = new Experiments.Experiments(gPolicy);
yield experiments.updateManifest();
let addons = yield getExperimentAddons();
Assert.equal(addons.length, 0, "No experiment add-ons installed.");
experimentList = yield experiments.getExperiments();
Assert.equal(experimentList.length, 1, "A single experiment is known.");
Assert.equal(experimentList[0].id, EXPERIMENT1_ID, "Experiment 1 should be the sole entry.");
Assert.ok(!experimentList[0].active, "Experiment 1 should not be active.");
yield testCleanup(experiments);
});

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -16,7 +16,7 @@
</Url>
<Url type="text/html" method="GET" template="http://www.bing.com/search">
<Param name="q" value="{searchTerms}"/>
<MozParam name="pc" condition="pref" pref="ms-pc"/>
<Param name="pc" value="MOZI"/>
<MozParam name="form" condition="purpose" purpose="contextmenu" value="MOZCON"/>
<MozParam name="form" condition="purpose" purpose="searchbar" value="MOZSBR"/>
<MozParam name="form" condition="purpose" purpose="homepage" value="MOZSPG"/>

Просмотреть файл

@ -7,13 +7,14 @@
<Description>eBay - Online auctions</Description>
<InputEncoding>ISO-8859-1</InputEncoding>
<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAB6AQAAJgAAACAgAAAAAAAAQgMAAKABAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAFBSURBVDjLtZPdK0MBGIf3J5Babhx3rinFBWuipaUskX9DYvkopqgV90q5UJpyp0OKrUWM2VrRsS9D0zZKHGaOnW1nj4vtypVtPPe/533r9746QAAOAJXfo5Yzgg44pHrcugon/6Sgo0b+XuAOZ2iZiVQmyPoDpIwmUkYTzqM7GsdDdC7F6Lbf8pzOkfWOouzqeZem2b+2AqAV8zjD8yVBqqcf2b7C66yNiMGMfixIQSvi8Mp0LEbR5ADq1QSKWM+Gx0RC9nOZ2GLzwlIWdPWiuNzk4w/EpThNkyEAXKEP2ud8KGId2sspilhPMrmNwzfCuqePr/xbSfC5I/I0MMSj2YJ3z49gDdO2cEOrLUowJpE9G0QRG1ClKbR0EIdvmOPYcnUtnN+vsnZiQC1k/qnGagQ1n3LNzySUJZVskitnmr8BlQG7T2hvgxsAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAMJSURBVFjD7ZddSFNhGMeHXXQTZFFCWfR1pRhUECQlBdWVToo+6KYu1KigtDASG5qUfZgFZvahEDosECPDktKZS1FL+1DRnEvdUptjug91X2dnZzv/3vO6OZbWnR4v9sADL+fs7P97/s/znu2VAJD4UkpSSdKG+QubTyPBr+sXz8XCR64fIAHihVTis0SsUAoAVhEBrBKIHCGAEMB/ARi3F5LkbpS2WMRzYEEBXC2tsD6T03R9agsCGLNyqPw6CXmrBT06JvhbPHZwmkdwtR0B138PPKOHgzXD5jLAy3tmibo4K9weZwDAazJj/FQKRnfugfHMeRiTz0K3Ixam1HQKcPC+Fisu9NK1P08Uj4DleHgMdXC+WQ7nu3UEOhFMfTQcVUvQ1H4IN2sj8H2k7K+2TqCc3GseyA8AmDOzMBq7D9bS8sAr6nEJdNt3UbHVF1XQGtmZew8bTPT6tWoD3KpsUvlR8NxUoEICMvl6KQo+xqCwcRs4T8Ax5c8bFExjbAgAjO7aS8VsLypgq3g5nWStjztAhWRVhqAqeB6IuKTClkw1eNYEbrCQQBwD8yGGOsAooogLYejQPKBi7UPF9DkH+ezd+o141ZkUPAOC+L9SAMivNc7q46YMNSLTe4n1kaQF4XD3ZIDTPgU3XEYciKcAHrsGJS1xKFBGgyVzouiT4VbdGhjt/cEA5isyKsaz7jl3we7bg7Rqf6j0LoSldON4wWcqJDgQNGTN++l13vELA+MK6kKd6iryFOvxtidt9i5gO7owdjKJQliflNAU1pas6xQgnAzg1ux+lJEdILixNr0Pq9JUUA8NwVG9DM73G0jlcnh+V4BpjIWzJmIGQIjnXw5TiDuKSEwxurm3ITc8DNO51BnrLbIcsrW0dNA6RxgUKU1UdGVqLy5X6qGzTLvlnewiBZyGs3Yz6X8UeaYI3olvZDhzwLumZ+eHvooCCC0Q5VUsb4unwycM4YIDqA01tPqmgbzQr2EIYPECiPm33LYoDiZSsY9moh9O/Znoa4d9HkXtPg2pX/cPKCoRQ+ocZa4AAAAASUVORK5CYII=</Image>
<Url type="application/x-suggestions+json" method="GET" template="http://anywhere.ebay.com/services/suggest/">
<Param name="s" value="0"/>
<Param name="q" value="{searchTerms}"/>
<Url type="application/x-suggestions+json" method="GET" template="http://autosug.ebay.com/autosug">
<Param name="sId" value="0" />
<Param name="kwd" value="{searchTerms}" />
<Param name="fmt" value="osr" />
</Url>
<Url type="text/html" method="GET" template="http://rover.ebay.com/rover/1/711-47294-18009-3/4" resultdomain="ebay.com">
<Param name="mpre" value="http://shop.ebay.com/?_nkw={searchTerms}"/>
<Param name="mfe" value="search" />
<Param name="mpre" value="http://www.ebay.com/sch/i.html?_nkw={searchTerms}" />
</Url>
<SearchForm>http://search.ebay.com/</SearchForm>
</SearchPlugin>

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -1265,7 +1265,7 @@ toolbarbutton[sdk-button="true"][cui-areatype="toolbar"] > .toolbarbutton-icon {
position: relative;
background-color: #fff;
background-clip: padding-box;
padding-left: 4px;
padding-left: 3px;
border-radius: 2.5px 0 0 2.5px;
border-width: 0 8px 0 0;
border-style: solid;
@ -1275,6 +1275,10 @@ toolbarbutton[sdk-button="true"][cui-areatype="toolbar"] > .toolbarbutton-icon {
margin-bottom: -1px;
}
@conditionalForwardWithUrlbar@ > #forward-button[disabled] + #urlbar > #notification-popup-box {
padding-left: 7px;
}
#notification-popup-box:not([hidden]) + #identity-box {
-moz-padding-start: 10px;
border-radius: 0;

Просмотреть файл

@ -3384,7 +3384,7 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
}
}
@conditionalForwardWithUrlbar@[forwarddisabled] > #urlbar > #notification-popup-box {
@conditionalForwardWithUrlbar@ > #forward-button[disabled] + #urlbar > #notification-popup-box {
padding-left: 7px;
}

Просмотреть файл

@ -2274,8 +2274,8 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] {
-moz-margin-end: -8px;
}
@conditionalForwardWithUrlbar@[forwarddisabled] > #urlbar-wrapper > #urlbar > #notification-popup-box {
padding-left: 5px;
@conditionalForwardWithUrlbar@ > #forward-button[disabled] + #urlbar > #notification-popup-box {
padding-left: 7px;
}
#notification-popup-box:-moz-locale-dir(rtl),

Двоичные данные
build/pgo/certs/cert8.db

Двоичный файл не отображается.

Двоичные данные
build/pgo/certs/key3.db

Двоичный файл не отображается.

Просмотреть файл

@ -212,3 +212,5 @@ http://example.cn:80 privileged
http://example.co.jp:80 privileged
http://example.fi:80 privileged
# Hosts for testing marketplace apps installations
https://marketplace.firefox.com:443 privileged

Просмотреть файл

@ -5964,18 +5964,6 @@ if test "$MOZ_GAMEPAD"; then
MOZ_GAMEPAD_BACKEND=cocoa
;;
WINNT)
if test -z "$MOZ_HAS_WINSDK_WITH_D3D"; then
if test -n "$MOZ_DIRECTX_SDK_PATH" ; then
if ! test -f "$MOZ_DIRECTX_SDK_PATH"/lib/$MOZ_DIRECTX_SDK_CPU_SUFFIX/dxguid.lib ; then
MOZ_GAMEPAD=
fi
elif test "$GCC" != "yes"; then
MOZ_GAMEPAD=
fi
fi
if test -z "$MOZ_GAMEPAD"; then
AC_MSG_ERROR([Couldn't find the DirectX SDK, needed for gamepad support. Please install it or, reconfigure with --disable-gamepad to disable gamepad support.])
fi
MOZ_GAMEPAD_BACKEND=windows
;;
Linux)

Просмотреть файл

@ -3209,7 +3209,7 @@ nsObjectLoadingContent::LegacyCall(JSContext* aCx,
}
for (size_t i = 0; i < args.length(); i++) {
if (!JS_WrapValue(aCx, args.handleAt(i))) {
if (!JS_WrapValue(aCx, args[i])) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return JS::UndefinedValue();
}

Просмотреть файл

@ -32,7 +32,7 @@ public:
virtual ReentrantMonitor& GetReentrantMonitor() MOZ_OVERRIDE;
virtual bool IsShutdown() const MOZ_FINAL MOZ_OVERRIDE;
virtual bool IsShutdown() const MOZ_OVERRIDE;
virtual bool OnStateMachineThread() const MOZ_OVERRIDE;
@ -40,11 +40,11 @@ public:
virtual MediaResource* GetResource() const MOZ_OVERRIDE;
virtual void NotifyBytesConsumed(int64_t aBytes, int64_t aOffset) MOZ_FINAL MOZ_OVERRIDE;
virtual void NotifyBytesConsumed(int64_t aBytes, int64_t aOffset) MOZ_OVERRIDE;
virtual void NotifyDecodedFrames(uint32_t aParsed, uint32_t aDecoded) MOZ_FINAL MOZ_OVERRIDE;
virtual void NotifyDecodedFrames(uint32_t aParsed, uint32_t aDecoded) MOZ_OVERRIDE;
virtual int64_t GetEndMediaTime() const MOZ_FINAL MOZ_OVERRIDE;
virtual int64_t GetEndMediaTime() const MOZ_OVERRIDE;
virtual int64_t GetMediaDuration() MOZ_OVERRIDE;
@ -56,25 +56,25 @@ public:
virtual void SetTransportSeekable(bool aTransportSeekable) MOZ_OVERRIDE;
virtual VideoFrameContainer* GetVideoFrameContainer() MOZ_FINAL MOZ_OVERRIDE;
virtual VideoFrameContainer* GetVideoFrameContainer() MOZ_OVERRIDE;
virtual layers::ImageContainer* GetImageContainer() MOZ_OVERRIDE;
virtual bool IsTransportSeekable() MOZ_FINAL MOZ_OVERRIDE;
virtual bool IsTransportSeekable() MOZ_OVERRIDE;
virtual bool IsMediaSeekable() MOZ_FINAL MOZ_OVERRIDE;
virtual bool IsMediaSeekable() MOZ_OVERRIDE;
virtual void MetadataLoaded(int aChannels, int aRate, bool aHasAudio, bool aHasVideo, MetadataTags* aTags) MOZ_FINAL MOZ_OVERRIDE;
virtual void QueueMetadata(int64_t aTime, int aChannels, int aRate, bool aHasAudio, bool aHasVideo, MetadataTags* aTags) MOZ_FINAL MOZ_OVERRIDE;
virtual void MetadataLoaded(int aChannels, int aRate, bool aHasAudio, bool aHasVideo, MetadataTags* aTags) MOZ_OVERRIDE;
virtual void QueueMetadata(int64_t aTime, int aChannels, int aRate, bool aHasAudio, bool aHasVideo, MetadataTags* aTags) MOZ_OVERRIDE;
virtual void SetMediaEndTime(int64_t aTime) MOZ_FINAL MOZ_OVERRIDE;
virtual void SetMediaEndTime(int64_t aTime) MOZ_OVERRIDE;
virtual void UpdatePlaybackPosition(int64_t aTime) MOZ_FINAL MOZ_OVERRIDE;
virtual void UpdatePlaybackPosition(int64_t aTime) MOZ_OVERRIDE;
virtual void OnReadMetadataCompleted() MOZ_FINAL MOZ_OVERRIDE;
virtual void OnReadMetadataCompleted() MOZ_OVERRIDE;
virtual MediaDecoderOwner* GetOwner() MOZ_OVERRIDE;
virtual void NotifyWaitingForResourcesStatusChanged() MOZ_FINAL MOZ_OVERRIDE;
virtual void NotifyWaitingForResourcesStatusChanged() MOZ_OVERRIDE;
protected:
// This monitor object is not really used to synchronize access to anything.

Просмотреть файл

@ -164,6 +164,14 @@ VideoTrackEncoder::NotifyQueuedTrackChanges(MediaStreamGraph* aGraph,
if (!chunk.IsNull()) {
gfx::IntSize imgsize = chunk.mFrame.GetImage()->GetSize();
gfxIntSize intrinsicSize = chunk.mFrame.GetIntrinsicSize();
#ifdef MOZ_WIDGET_GONK
// Block the video frames come from video source.
if (chunk.mFrame.GetImage()->GetFormat() != ImageFormat::PLANAR_YCBCR) {
LOG("Can't encode this ImageFormat %x", chunk.mFrame.GetImage()->GetFormat());
NotifyCancel();
break;
}
#endif
nsresult rv = Init(imgsize.width, imgsize.height,
intrinsicSize.width, intrinsicSize.height,
aTrackRate);

Просмотреть файл

@ -89,7 +89,9 @@ public:
return false;
}
MaybeSwitchVideoReaders(aTimeThreshold);
if (MaybeSwitchVideoReaders(aTimeThreshold)) {
GetVideoReader()->DecodeToTarget(aTimeThreshold);
}
bool rv = GetVideoReader()->DecodeVideoFrame(aKeyFrameSkip, aTimeThreshold);
@ -129,7 +131,7 @@ public:
void CallDecoderInitialization();
private:
void MaybeSwitchVideoReaders(int64_t aTimeThreshold) {
bool MaybeSwitchVideoReaders(int64_t aTimeThreshold) {
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
MOZ_ASSERT(mActiveVideoDecoder != -1);
@ -146,10 +148,11 @@ private:
MSE_DEBUG("%p MSR::DecodeVF switching to %d", this, mActiveVideoDecoder);
GetVideoReader()->SetActive();
GetVideoReader()->DecodeToTarget(aTimeThreshold);
break;
return true;
}
}
return false;
}
MediaDecoderReader* GetAudioReader() {

Просмотреть файл

@ -66,6 +66,12 @@ SubBufferDecoder::GetResource() const
return static_cast<SourceBufferResource*>(mResource.get());
}
void
SubBufferDecoder::NotifyDecodedFrames(uint32_t aParsed, uint32_t aDecoded)
{
return mParentDecoder->NotifyDecodedFrames(aParsed, aDecoded);
}
void
SubBufferDecoder::SetMediaDuration(int64_t aDuration)
{
@ -192,12 +198,8 @@ SourceBuffer::GetBuffered(ErrorResult& aRv)
return nullptr;
}
nsRefPtr<TimeRanges> ranges = new TimeRanges();
for (uint32_t i = 0; i < mDecoders.Length(); ++i) {
nsRefPtr<TimeRanges> r = new TimeRanges();
mDecoders[i]->GetBuffered(r);
if (r->Length() > 0) {
ranges->Add(r->GetStartTime(), r->GetEndTime());
}
if (mDecoder) {
mDecoder->GetBuffered(ranges);
}
ranges->Normalize();
return ranges.forget();
@ -264,10 +266,10 @@ SourceBuffer::Abort(ErrorResult& aRv)
mAppendWindowStart = 0;
mAppendWindowEnd = PositiveInfinity<double>();
MSE_DEBUG("%p Abort: Discarding decoders.", this);
if (mCurrentDecoder) {
mCurrentDecoder->GetResource()->Ended();
mCurrentDecoder = nullptr;
MSE_DEBUG("%p Abort: Discarding decoder.", this);
if (mDecoder) {
mDecoder->GetResource()->Ended();
mDecoder = nullptr;
}
}
@ -294,16 +296,15 @@ void
SourceBuffer::Detach()
{
Ended();
mDecoders.Clear();
mCurrentDecoder = nullptr;
mDecoder = nullptr;
mMediaSource = nullptr;
}
void
SourceBuffer::Ended()
{
for (uint32_t i = 0; i < mDecoders.Length(); ++i) {
mDecoders[i]->GetResource()->Ended();
if (mDecoder) {
mDecoder->GetResource()->Ended();
}
}
@ -316,6 +317,7 @@ SourceBuffer::SourceBuffer(MediaSource* aMediaSource, const nsACString& aType)
, mTimestampOffset(0)
, mAppendMode(SourceBufferAppendMode::Segments)
, mUpdating(false)
, mDecoderInit(false)
{
MOZ_ASSERT(aMediaSource);
if (mType.EqualsIgnoreCase("video/webm") || mType.EqualsIgnoreCase("audio/webm")) {
@ -324,6 +326,8 @@ SourceBuffer::SourceBuffer(MediaSource* aMediaSource, const nsACString& aType)
// XXX: Plug in parsers for MPEG4, etc. here.
mParser = new ContainerParser();
}
MSE_DEBUG("%p SourceBuffer: Creating initial decoder.", this);
InitNewDecoder();
}
already_AddRefed<SourceBuffer>
@ -335,8 +339,8 @@ SourceBuffer::Create(MediaSource* aMediaSource, const nsACString& aType)
SourceBuffer::~SourceBuffer()
{
for (uint32_t i = 0; i < mDecoders.Length(); ++i) {
mDecoders[i]->GetResource()->Ended();
if (mDecoder) {
mDecoder->GetResource()->Ended();
}
}
@ -375,11 +379,7 @@ SourceBuffer::InitNewDecoder()
if (!decoder) {
return false;
}
mDecoders.AppendElement(decoder);
// XXX: At this point, we really want to push through any remaining
// processing for the old decoder and discard it, rather than hanging on
// to all of them in mDecoders.
mCurrentDecoder = decoder;
mDecoder = decoder;
return true;
}
@ -424,21 +424,24 @@ SourceBuffer::AppendData(const uint8_t* aData, uint32_t aLength, ErrorResult& aR
// TODO: Test buffer full flag.
StartUpdating();
// TODO: Run buffer append algorithm asynchronously (would call StopUpdating()).
if (mParser->IsInitSegmentPresent(aData, aLength) || !mCurrentDecoder) {
MSE_DEBUG("%p AppendBuffer: New initialization segment, switching decoders.", this);
if (mCurrentDecoder) {
mCurrentDecoder->GetResource()->Ended();
}
if (!InitNewDecoder()) {
aRv.Throw(NS_ERROR_FAILURE); // XXX: Review error handling.
return;
if (!mDecoder || mParser->IsInitSegmentPresent(aData, aLength)) {
if (!mDecoder || mDecoderInit) {
MSE_DEBUG("%p AppendBuffer: New initialization segment, creating decoder.", this);
mDecoder->GetResource()->Ended();
if (!InitNewDecoder()) {
aRv.Throw(NS_ERROR_FAILURE); // XXX: Review error handling.
return;
}
}
MSE_DEBUG("%p AppendBuffer: Decoder marked as initialized.", this);
mDecoderInit = true;
}
// XXX: For future reference: NDA call must run on the main thread.
mCurrentDecoder->NotifyDataArrived(reinterpret_cast<const char*>(aData),
aLength,
mCurrentDecoder->GetResource()->GetLength());
mCurrentDecoder->GetResource()->AppendData(aData, aLength);
mDecoder->NotifyDataArrived(reinterpret_cast<const char*>(aData),
aLength,
mDecoder->GetResource()->GetLength());
mDecoder->GetResource()->AppendData(aData, aLength);
// Eviction uses a byte threshold. If the buffer is greater than the
// number of bytes then data is evicted. The time range for this
@ -446,7 +449,7 @@ SourceBuffer::AppendData(const uint8_t* aData, uint32_t aLength, ErrorResult& aR
// evict data before that range across all SourceBuffer's it knows
// about.
const int evict_threshold = 1000000;
bool evicted = mCurrentDecoder->GetResource()->EvictData(evict_threshold);
bool evicted = mDecoder->GetResource()->EvictData(evict_threshold);
if (evicted) {
double start = 0.0;
double end = 0.0;
@ -479,14 +482,15 @@ SourceBuffer::GetBufferedStartEndTime(double* aStart, double* aEnd)
void
SourceBuffer::Evict(double aStart, double aEnd)
{
for (uint32_t i = 0; i < mDecoders.Length(); ++i) {
// Need to map time to byte offset then evict
int64_t end = mDecoders[i]->ConvertToByteOffset(aEnd);
if (end <= 0) {
NS_WARNING("SourceBuffer::Evict failed");
continue;
}
mDecoders[i]->GetResource()->EvictBefore(end);
if (!mDecoder) {
return;
}
// Need to map time to byte offset then evict
int64_t end = mDecoder->ConvertToByteOffset(aEnd);
if (end > 0) {
mDecoder->GetResource()->EvictBefore(end);
} else {
NS_WARNING("SourceBuffer::Evict failed");
}
}

Просмотреть файл

@ -140,10 +140,7 @@ private:
nsAutoPtr<ContainerParser> mParser;
// XXX: We only want to keep the current decoder alive, but need a way to
// query @buffered for everything this SourceBuffer is responsible for.
nsTArray<nsRefPtr<SubBufferDecoder>> mDecoders;
nsRefPtr<SubBufferDecoder> mCurrentDecoder;
nsRefPtr<SubBufferDecoder> mDecoder;
double mAppendWindowStart;
double mAppendWindowEnd;
@ -152,6 +149,8 @@ private:
SourceBufferAppendMode mAppendMode;
bool mUpdating;
bool mDecoderInit;
};
} // namespace dom

Просмотреть файл

@ -40,6 +40,7 @@ public:
virtual bool OnStateMachineThread() const MOZ_OVERRIDE;
virtual bool OnDecodeThread() const MOZ_OVERRIDE;
virtual SourceBufferResource* GetResource() const MOZ_OVERRIDE;
virtual void NotifyDecodedFrames(uint32_t aParsed, uint32_t aDecoded) MOZ_OVERRIDE;
virtual void SetMediaDuration(int64_t aDuration) MOZ_OVERRIDE;
virtual void UpdateEstimatedMediaDuration(int64_t aDuration) MOZ_OVERRIDE;
virtual void SetMediaSeekable(bool aMediaSeekable) MOZ_OVERRIDE;

Просмотреть файл

@ -678,6 +678,7 @@ MediaEngineWebRTCVideoSource::Shutdown()
void
MediaEngineWebRTCVideoSource::AllocImpl() {
MOZ_ASSERT(NS_IsMainThread());
ReentrantMonitorAutoEnter sync(mCallbackMonitor);
mCameraControl = ICameraControl::Create(mCaptureIndex);
if (mCameraControl) {
@ -818,6 +819,7 @@ MediaEngineWebRTCVideoSource::OnUserError(UserContext aContext, nsresult aError)
void
MediaEngineWebRTCVideoSource::OnTakePictureComplete(uint8_t* aData, uint32_t aLength, const nsAString& aMimeType)
{
ReentrantMonitorAutoEnter sync(mCallbackMonitor);
mLastCapture =
static_cast<nsIDOMFile*>(new nsDOMMemoryFile(static_cast<void*>(aData),
static_cast<uint64_t>(aLength),

Просмотреть файл

@ -2244,8 +2244,7 @@ this.DOMApplicationRegistry = {
queuedDownload: {},
queuedPackageDownload: {},
onInstallSuccessAck: function onInstallSuccessAck(aManifestURL,
aDontNeedNetwork) {
onInstallSuccessAck: function(aManifestURL, aDontNeedNetwork) {
// If we are offline, register to run when we'll be online.
if ((Services.io.offline) && !aDontNeedNetwork) {
let onlineWrapper = {
@ -2345,7 +2344,7 @@ onInstallSuccessAck: function onInstallSuccessAck(aManifestURL,
let dir = this._getAppDir(aId).path;
let manFile = OS.Path.join(dir, manifestName);
this._writeFile(manFile, JSON.stringify(aJsonManifest));
return this._writeFile(manFile, JSON.stringify(aJsonManifest));
},
// Add an app that is already installed to the registry.
@ -2418,7 +2417,7 @@ onInstallSuccessAck: function onInstallSuccessAck(aManifestURL,
});
}),
confirmInstall: function(aData, aProfileDir, aInstallSuccessCallback) {
confirmInstall: Task.async(function*(aData, aProfileDir, aInstallSuccessCallback) {
debug("confirmInstall");
let origin = Services.io.newURI(aData.app.origin, null, null);
@ -2443,7 +2442,7 @@ onInstallSuccessAck: function onInstallSuccessAck(aManifestURL,
let app = this._setupApp(aData, id);
let jsonManifest = aData.isPackage ? app.updateManifest : app.manifest;
this._writeManifestFile(id, aData.isPackage, jsonManifest);
yield this._writeManifestFile(id, aData.isPackage, jsonManifest);
debug("app.origin: " + app.origin);
let manifest = new ManifestHelper(jsonManifest, app.origin);
@ -2477,42 +2476,15 @@ onInstallSuccessAck: function onInstallSuccessAck(aManifestURL,
aData.app[prop] = appObject[prop];
}
let dontNeedNetwork = false;
if (manifest.appcache_path) {
this.queuedDownload[app.manifestURL] = {
manifest: manifest,
app: appObject,
profileDir: aProfileDir
}
}
// We notify about the successful installation via mgmt.oninstall and the
// corresponging DOMRequest.onsuccess event as soon as the app is properly
// saved in the registry.
this._saveApps().then(() => {
this.broadcastMessage("Webapps:AddApp", { id: id, app: appObject });
if (aData.isPackage && aData.autoInstall) {
// Skip directly to onInstallSuccessAck, since there isn't
// a WebappsRegistry to receive Webapps:Install:Return:OK and respond
// Webapps:Install:Return:Ack when an app is being auto-installed.
this.onInstallSuccessAck(app.manifestURL);
} else {
// Broadcast Webapps:Install:Return:OK so the WebappsRegistry can notify
// the installing page about the successful install, after which it'll
// respond Webapps:Install:Return:Ack, which calls onInstallSuccessAck.
this.broadcastMessage("Webapps:Install:Return:OK", aData);
}
if (!aData.isPackage) {
this.updateAppHandlers(null, app.manifest, app);
if (aInstallSuccessCallback) {
aInstallSuccessCallback(app.manifest);
}
}
Services.obs.notifyObservers(null, "webapps-installed",
JSON.stringify({ manifestURL: app.manifestURL }));
});
let dontNeedNetwork = false;
if (manifest.package_path) {
} else if (manifest.package_path) {
// If it is a local app then it must been installed from a local file
// instead of web.
#ifdef MOZ_ANDROID_SYNTHAPKS
@ -2537,12 +2509,40 @@ onInstallSuccessAck: function onInstallSuccessAck(aManifestURL,
};
}
// We notify about the successful installation via mgmt.oninstall and the
// corresponding DOMRequest.onsuccess event as soon as the app is properly
// saved in the registry.
yield this._saveApps();
this.broadcastMessage("Webapps:AddApp", { id: id, app: appObject });
if (aData.isPackage && aData.autoInstall) {
// Skip directly to onInstallSuccessAck, since there isn't
// a WebappsRegistry to receive Webapps:Install:Return:OK and respond
// Webapps:Install:Return:Ack when an app is being auto-installed.
this.onInstallSuccessAck(app.manifestURL);
} else {
// Broadcast Webapps:Install:Return:OK so the WebappsRegistry can notify
// the installing page about the successful install, after which it'll
// respond Webapps:Install:Return:Ack, which calls onInstallSuccessAck.
this.broadcastMessage("Webapps:Install:Return:OK", aData);
}
if (!aData.isPackage) {
this.updateAppHandlers(null, app.manifest, app);
if (aInstallSuccessCallback) {
aInstallSuccessCallback(app.manifest);
}
}
Services.obs.notifyObservers(null, "webapps-installed",
JSON.stringify({ manifestURL: app.manifestURL }));
if (aData.forceSuccessAck) {
// If it's a local install, there's no content process so just
// ack the install.
this.onInstallSuccessAck(app.manifestURL, dontNeedNetwork);
}
},
}),
/**
* Install the package after successfully downloading it
@ -3104,7 +3104,10 @@ onInstallSuccessAck: function onInstallSuccessAck(aManifestURL,
throw "CERTDB_ERROR";
}
let [result, zipReader] = yield this._openSignedPackage(aZipFile, certDb);
let [result, zipReader] = yield this._openSignedPackage(aApp.installOrigin,
aApp.manifestURL,
aZipFile,
certDb);
// We cannot really know if the system date is correct or
// not. What we can know is if it's after the build date or not,
@ -3147,11 +3150,39 @@ onInstallSuccessAck: function onInstallSuccessAck(aManifestURL,
}).bind(this));
},
_openSignedPackage: function(aZipFile, aCertDb) {
_openSignedPackage: function(aInstallOrigin, aManifestURL, aZipFile, aCertDb) {
let deferred = Promise.defer();
let root = TrustedRootCertificate.index;
let useReviewerCerts = false;
try {
useReviewerCerts = Services.prefs.
getBoolPref("dom.mozApps.use_reviewer_certs");
} catch (ex) { }
// We'll use the reviewer and dev certificates only if the pref is set to
// true.
if (useReviewerCerts) {
let manifestPath = Services.io.newURI(aManifestURL, null, null).path;
switch (aInstallOrigin) {
case "https://marketplace.firefox.com":
root = manifestPath.startsWith("/reviewers/")
? Ci.nsIX509CertDB.AppMarketplaceProdReviewersRoot
: Ci.nsIX509CertDB.AppMarketplaceProdPublicRoot;
break;
case "https://marketplace-dev.allizom.org":
root = manifestPath.startsWith("/reviewers/")
? Ci.nsIX509CertDB.AppMarketplaceDevReviewersRoot
: Ci.nsIX509CertDB.AppMarketplaceDevPublicRoot;
break;
}
}
aCertDb.openSignedAppFileAsync(
TrustedRootCertificate.index, aZipFile,
root, aZipFile,
function(aRv, aZipReader) {
deferred.resolve([aRv, aZipReader]);
}

Просмотреть файл

@ -0,0 +1,28 @@
{
"version" : "2.0",
"name" : "Flashlight (Linterna)",
"description" : "Simple Flashlight that you can use everywhere without internet connection and also with cool modes: * Flashlight mode - * Disco mode - * Colors mode",
"launch_path" : "/index.html",
"icons": {
"16": "/img/icons/mortar-16.png",
"48": "/img/icons/mortar-48.png",
"60": "/img/icons/mortar-60.png",
"128": "/img/icons/mortar-128.png"
},
"developer": {
"name": "William Vargas",
"url" : "https://twitter.com/tecnowilliam"
},
"installs_allowed_from": ["*"],
"locales": {
"es": {
"description": "Una simple linterna que puedes utilizar en cualquier lugar sin conexión a internet y con opciones geniales: * Modo Linterna - * Modo Disco - * Modo Colores",
"developer": {
"name": "William Vargas",
"url" : "https://twitter.com/tecnowilliam"
}
}
},
"default_locale": "en",
"package_path": "marketplace_app.zip"
}

Просмотреть файл

@ -0,0 +1 @@
Content-Type: application/x-web-app-manifest+json

Двоичные данные
dom/apps/tests/marketplace/marketplace_app.zip Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -0,0 +1,50 @@
{
"version": "0.2.2",
"name": "KitchenSink",
"description": "Tests and report APIs available on the device",
"launch_path": "/index.html",
"developer": {
"name": "Piotr Zalewa",
"url": "http://www.mozillalabs.com"
},
"icons": {
"16": "/img/icons/logo-16.png",
"32": "/img/icons/logo-32.png",
"64": "/img/icons/logo-64.png",
"128": "/img/icons/logo-128.png",
"256": "/img/icons/logo-256.png"
},
"type": "privileged",
"permissions": {
"alarms": {
"description": "Testing"
},
"browser": {
"description": "Testing"
},
"geolocation": {
"description": "Testing"
},
"contacts": {
"access": "readwrite",
"description": "Testing"
},
"device-storage:sdcard": {
"access": "readwrite",
"description": "Testing"
},
"fmradio": {
"description": "Testing"
},
"storage": {
"description": "Testing"
},
"systemXHR": {
"description": "Testing"
},
"tcp-socket": {
"description": "Testing"
}
},
"package_path": "marketplace_privileged_app.zip"
}

Просмотреть файл

@ -0,0 +1 @@
Content-Type: application/x-web-app-manifest+json

Двоичные данные
dom/apps/tests/marketplace/marketplace_privileged_app.zip Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -0,0 +1,20 @@
{
"name": "Stopwatch",
"description": "Simple stopwatch",
"launch_path": "/index.html",
"icons": {
"128": "/static/img/icon.png"
},
"developer": {
"name": "Andy McKay",
"url": "http://www.agmweb.ca/blog/andy/"
},
"locales": {
"fr": {
"description": "Simple chronomètre"
}
},
"installs_allowed_from": ["*"],
"default_locale": "en",
"package_path": "marketplace_reviewers_app.zip"
}

Просмотреть файл

@ -0,0 +1 @@
Content-Type: application/x-web-app-manifest+json

Двоичные данные
dom/apps/tests/marketplace/marketplace_reviewers_app.zip Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -14,10 +14,14 @@ support-files =
signed_app_template.webapp
signed/*
test_packaged_app_common.js
marketplace/*
pkg_install_iframe.html
[test_app_update.html]
[test_bug_795164.html]
[test_install_receipts.html]
[test_marketplace_pkg_install.html]
skip-if = buildapp == "b2g" || toolkit == "android" # see bug 989806
[test_packaged_app_install.html]
[test_packaged_app_update.html]
[test_receipt_operations.html]

Просмотреть файл

@ -0,0 +1,26 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Cross Origin Helper</title>
</head>
<body>
<script type="application/javascript">
window.addEventListener("message", function onMessage(event) {
window.removeEventListener("message", onMessage, false);
var request = navigator.mozApps.installPackage(event.data);
request.onerror = function() {
parent.postMessage("Error: " + this.error.name, "*");
};
request.onsuccess = function() {
parent.postMessage("Application installed", "*");
};
}, false);
</script>
</body>
</html>

Просмотреть файл

@ -102,7 +102,7 @@ function readFile(path) {
function makeResource(templatePath, version, packagePath, packageSize,
appName, developerName, developerUrl) {
var res = readFile(templatePath, false).
var res = readFile(templatePath).
replace(/VERSIONTOKEN/g, version).
replace(/PACKAGEPATHTOKEN/g, packagePath).
replace(/PACKAGESIZETOKEN/g, packageSize).

Просмотреть файл

@ -0,0 +1,198 @@
<!DOCTYPE html>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=989806
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 989806</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="test_packaged_app_common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=989806">Mozilla Bug 989806</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="application/javascript;version=1.7">
"use strict";
let gApp = null;
let gExternalInstallOrigin = "http://mochi.test:8888/";
let gExternalAppsPath = gExternalInstallOrigin + "tests/dom/apps/tests/marketplace/";
let gMarketplaceInstallOrigin = "https://marketplace.firefox.com/";
let gMarketplaceAppsPath = gMarketplaceInstallOrigin + "tests/dom/apps/tests/marketplace/";
SimpleTest.waitForExplicitFinish();
function checkAppOnInstallSuccess(aExpected) {
navigator.mozApps.mgmt.oninstall = function(evt) {
info("Got oninstall event");
gApp = evt.application;
gApp.ondownloaderror = function() {
ok(false, "Download should succeed (got error: " +
gApp.downloadError.name + ")");
PackagedTestHelper.finish();
};
gApp.ondownloadsuccess = function() {
info("App downloaded");
PackagedTestHelper.checkAppState(gApp, aExpected.version, aExpected,
true, true, PackagedTestHelper.next);
};
};
}
function checkAppOnInstallError(aExpectedError) {
navigator.mozApps.mgmt.oninstall = function(evt) {
info("Got oninstall event");
gApp = evt.application;
gApp.ondownloaderror = function() {
is(gApp.downloadError.name, aExpectedError,
"Download fails with expected error: " + aExpectedError);
if (gApp.downloadError.name != aExpectedError) {
PackagedTestHelper.finish();
} else {
PackagedTestHelper.next();
}
};
gApp.ondownloadsuccess = function() {
ok(false, "App download should fail");
PackagedTestHelper.finish();
};
};
}
function checkUninstallApp(aApp) {
let req = navigator.mozApps.mgmt.uninstall(aApp);
req.onsuccess = function() {
info("App uninstalled");
aApp.ondownloadsuccess = null;
aApp.ondownloaderror = null;
aApp.onprogress = null;
PackagedTestHelper.next();
};
req.onerror = function(evt) {
ok(false, "App uninstallation should succeed (got unexpected " +
evt.target.error.name + ")");
PackagedTestHelper.finish();
};
}
function installApp(installOrigin, manifestURL) {
let domParent = document.getElementById('container');
let ifr = document.createElement('iframe');
ifr.setAttribute('mozbrowser', 'true');
ifr.setAttribute("src", installOrigin + "tests/dom/apps/tests/pkg_install_iframe.html");
ifr.addEventListener("load", function onIFrameLoad() {
ifr.removeEventListener("load", onIFrameLoad, false);
ifr.contentWindow.postMessage(manifestURL, "*");
}, false);
ifr.addEventListener("mozbrowsererror", function onCertError(e) {
ifr.removeEventListener("mozbrowsererror", onCertError);
ok(false, "mozbrowsererror: " + e.detail.type);
domParent.removeChild(ifr);
PackagedTestHelper.finish();
});
window.addEventListener("message", function onMessage(event) {
window.removeEventListener("message", onMessage);
is(event.data, "Application installed", "Application installed");
domParent.removeChild(ifr);
});
domParent.appendChild(ifr);
}
PackagedTestHelper.setSteps([
function() {
SpecialPowers.setAllAppsLaunchable(true);
SpecialPowers.addPermission("webapps-manage", true, document);
SpecialPowers.addPermission("browser", true, document);
SpecialPowers.autoConfirmAppInstall(() =>
SpecialPowers.pushPrefEnv({set: [["dom.mozBrowserFramesEnabled", true]]},
PackagedTestHelper.next));
},
function() {
info("== TEST == Marketplace packaged app from https://marketplace.firefox.com/");
let miniManifestURL = gMarketplaceAppsPath + "marketplace_app.webapp"
let expected = {
name: "Flashlight (Linterna)",
manifestURL: miniManifestURL,
installOrigin: gMarketplaceInstallOrigin.slice(0, -1),
progress: 0,
installState: "installed",
downloadAvailable: false,
downloading: false,
readyToApplyDownload: false,
launch_path: "/index.html",
version: "2.0",
};
checkAppOnInstallSuccess(expected);
installApp(gMarketplaceInstallOrigin, miniManifestURL);
},
function() {
info("== TEST == Marketplace privileged app from https://marketplace.firefox.com/");
let miniManifestURL = gMarketplaceAppsPath + "marketplace_privileged_app.webapp"
let expected = {
name: "KitchenSink",
manifestURL: miniManifestURL,
installOrigin: gMarketplaceInstallOrigin.slice(0, -1),
progress: 0,
installState: "installed",
downloadAvailable: false,
downloading: false,
readyToApplyDownload: false,
launch_path: "/index.html",
version: "0.2.2",
};
checkAppOnInstallSuccess(expected);
installApp(gMarketplaceInstallOrigin, miniManifestURL);
},
function() {
info("== TEST == Marketplace reviewers packaged app from https://marketplace.firefox.com/");
checkAppOnInstallError("INVALID_SIGNATURE");
installApp(gMarketplaceInstallOrigin, gMarketplaceAppsPath + "marketplace_reviewers_app.webapp");
},
function() {
info("== TEST == Marketplace packaged app not from https://marketplace.firefox.com/");
checkAppOnInstallError("INSTALL_FROM_DENIED");
installApp(gExternalInstallOrigin, gExternalAppsPath + "marketplace_app.webapp");
},
function() {
info("== TEST == Marketplace privileged app not from https://marketplace.firefox.com/");
checkAppOnInstallError("INSTALL_FROM_DENIED");
installApp(gExternalInstallOrigin, gExternalAppsPath + "marketplace_privileged_app.webapp");
},
function() {
info("== TEST == Marketplace reviewers packaged app not from https://marketplace.firefox.com/");
checkAppOnInstallError("INVALID_SIGNATURE");
installApp(gExternalInstallOrigin, gExternalAppsPath + "marketplace_reviewers_app.webapp");
},
function() {
PackagedTestHelper.finish();
}
]);
addLoadEvent(PackagedTestHelper.start);
</script>
</pre>
<div id="container"></div>
</body>
</html>

Просмотреть файл

@ -12,31 +12,18 @@ var PackagedTestHelper = (function PackagedTestHelper() {
var gAppName = "appname";
var gApp = null;
var gInstallOrigin = "http://mochi.test:8888";
var timeoutID;
function timeoutError() {
ok(false, "Timeout! Probably waiting on a app installation event");
info("Finishing this test suite!");
finish();
}
function debug(aMsg) {
//dump("== PackageTestHelper debug == " + aMsg + "\n");
}
function next() {
if (timeoutID) {
clearTimeout(timeoutID);
}
index += 1;
if (index >= steps.length) {
ok(false, "Shouldn't get here!");
return;
}
try {
// There's nothing here that should take more than 30 seconds, even on
// heavy loads. So there's no need to stop further tests for five minutes.
timeoutID = setTimeout(timeoutError, 30000);
steps[index]();
} catch(ex) {
ok(false, "Caught exception", ex);
@ -48,10 +35,8 @@ var PackagedTestHelper = (function PackagedTestHelper() {
}
function finish() {
if (timeoutID) {
clearTimeout(timeoutID);
}
SpecialPowers.removePermission("webapps-manage", document);
SpecialPowers.removePermission("browser", document);
SimpleTest.finish();
}
@ -165,7 +150,7 @@ var PackagedTestHelper = (function PackagedTestHelper() {
is(aApp.manifest.size, aExpectedApp.size, "Check size");
}
if (aApp.manifest) {
is(aApp.manifest.launch_path, gSJSPath, "Check launch path");
is(aApp.manifest.launch_path, aExpectedApp.launch_path || gSJSPath, "Check launch path");
}
if (aExpectedApp.manifestURL) {
is(aApp.manifestURL, aExpectedApp.manifestURL, "Check manifestURL");

Просмотреть файл

@ -476,10 +476,7 @@ private:
arguments.AppendElement(value);
}
console->ProfileMethod(cx, mAction, arguments, error);
if (error.Failed()) {
NS_WARNING("Failed to call call profile() method to the ConsoleAPI.");
}
console->ProfileMethod(cx, mAction, arguments);
}
private:
@ -662,23 +659,20 @@ Console::TimeEnd(JSContext* aCx, const JS::Handle<JS::Value> aTime)
}
void
Console::Profile(JSContext* aCx, const Sequence<JS::Value>& aData,
ErrorResult& aRv)
Console::Profile(JSContext* aCx, const Sequence<JS::Value>& aData)
{
ProfileMethod(aCx, NS_LITERAL_STRING("profile"), aData, aRv);
ProfileMethod(aCx, NS_LITERAL_STRING("profile"), aData);
}
void
Console::ProfileEnd(JSContext* aCx, const Sequence<JS::Value>& aData,
ErrorResult& aRv)
Console::ProfileEnd(JSContext* aCx, const Sequence<JS::Value>& aData)
{
ProfileMethod(aCx, NS_LITERAL_STRING("profileEnd"), aData, aRv);
ProfileMethod(aCx, NS_LITERAL_STRING("profileEnd"), aData);
}
void
Console::ProfileMethod(JSContext* aCx, const nsAString& aAction,
const Sequence<JS::Value>& aData,
ErrorResult& aRv)
const Sequence<JS::Value>& aData)
{
if (!NS_IsMainThread()) {
// Here we are in a worker thread.
@ -688,6 +682,8 @@ Console::ProfileMethod(JSContext* aCx, const nsAString& aAction,
return;
}
ClearException ce(aCx);
RootedDictionary<ConsoleProfileEvent> event(aCx);
event.mAction = aAction;
@ -700,15 +696,14 @@ Console::ProfileMethod(JSContext* aCx, const nsAString& aAction,
JS::Rooted<JS::Value> eventValue(aCx);
if (!event.ToObject(aCx, &eventValue)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
JS::Rooted<JSObject*> eventObj(aCx, &eventValue.toObject());
MOZ_ASSERT(eventObj);
if (!JS_DefineProperty(aCx, eventObj, "wrappedJSObject", eventValue, JSPROP_ENUMERATE)) {
aRv.Throw(NS_ERROR_FAILURE);
if (!JS_DefineProperty(aCx, eventObj, "wrappedJSObject", eventValue,
JSPROP_ENUMERATE)) {
return;
}
@ -717,7 +712,6 @@ Console::ProfileMethod(JSContext* aCx, const nsAString& aAction,
const nsIID& iid = NS_GET_IID(nsISupports);
if (NS_FAILED(xpc->WrapJS(aCx, eventObj, iid, getter_AddRefs(wrapper)))) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
@ -836,13 +830,14 @@ Console::Method(JSContext* aCx, MethodName aMethodName,
ConsoleCallData* callData = new ConsoleCallData();
mQueuedCalls.insertBack(callData);
ClearException ce(aCx);
callData->Initialize(aCx, aMethodName, aMethodString, aData);
RAII raii(mQueuedCalls);
if (mWindow) {
nsCOMPtr<nsIWebNavigation> webNav = do_GetInterface(mWindow);
if (!webNav) {
Throw(aCx, NS_ERROR_FAILURE);
return;
}
@ -857,7 +852,6 @@ Console::Method(JSContext* aCx, MethodName aMethodName,
nsCOMPtr<nsIStackFrame> stack = CreateStack(aCx, maxDepth);
if (!stack) {
Throw(aCx, NS_ERROR_FAILURE);
return;
}
@ -866,7 +860,6 @@ Console::Method(JSContext* aCx, MethodName aMethodName,
uint32_t language;
nsresult rv = stack->GetLanguage(&language);
if (NS_FAILED(rv)) {
Throw(aCx, rv);
return;
}
@ -877,7 +870,6 @@ Console::Method(JSContext* aCx, MethodName aMethodName,
callData->mTopStackFrame.ref(),
language);
if (NS_FAILED(rv)) {
Throw(aCx, rv);
return;
}
@ -887,7 +879,6 @@ Console::Method(JSContext* aCx, MethodName aMethodName,
nsCOMPtr<nsIStackFrame> caller;
rv = stack->GetCaller(getter_AddRefs(caller));
if (NS_FAILED(rv)) {
Throw(aCx, rv);
return;
}
@ -902,7 +893,6 @@ Console::Method(JSContext* aCx, MethodName aMethodName,
callData->mReifiedStack.construct();
nsresult rv = ReifyStack(stack, callData->mReifiedStack.ref());
if (NS_WARN_IF(NS_FAILED(rv))) {
Throw(aCx, rv);
return;
}
}
@ -915,7 +905,6 @@ Console::Method(JSContext* aCx, MethodName aMethodName,
ErrorResult rv;
nsRefPtr<nsPerformance> performance = win->GetPerformance(rv);
if (rv.Failed()) {
Throw(aCx, rv.ErrorCode());
return;
}
@ -1111,7 +1100,6 @@ Console::ProcessCallData(ConsoleCallData* aData)
JS::Rooted<JS::Value> eventValue(cx);
if (!event.ToObject(cx, &eventValue)) {
Throw(cx, NS_ERROR_FAILURE);
return;
}

Просмотреть файл

@ -87,12 +87,10 @@ public:
TimeEnd(JSContext* aCx, const JS::Handle<JS::Value> aTime);
void
Profile(JSContext* aCx, const Sequence<JS::Value>& aData,
ErrorResult& aRv);
Profile(JSContext* aCx, const Sequence<JS::Value>& aData);
void
ProfileEnd(JSContext* aCx, const Sequence<JS::Value>& aData,
ErrorResult& aRv);
ProfileEnd(JSContext* aCx, const Sequence<JS::Value>& aData);
void
Assert(JSContext* aCx, bool aCondition, const Sequence<JS::Value>& aData);
@ -181,8 +179,7 @@ private:
void
ProfileMethod(JSContext* aCx, const nsAString& aAction,
const Sequence<JS::Value>& aData,
ErrorResult& aRv);
const Sequence<JS::Value>& aData);
JS::Value
IncreaseCounter(JSContext* aCx, const ConsoleStackEntry& aFrame,

Просмотреть файл

@ -1975,11 +1975,11 @@ BaseStubConstructor(nsIWeakReference* aWeakOwner,
nsCOMPtr<nsIDOMWindow> currentWin(do_GetInterface(currentInner));
rv = WrapNative(cx, currentWin, &NS_GET_IID(nsIDOMWindow),
true, argv.handleAt(0));
true, argv[0]);
for (size_t i = 1; i < argc; ++i) {
argv[i] = args[i - 1];
if (!JS_WrapValue(cx, argv.handleAt(i)))
argv[i].set(args[i - 1]);
if (!JS_WrapValue(cx, argv[i]))
return NS_ERROR_FAILURE;
}

Просмотреть файл

@ -1002,7 +1002,7 @@ nsJSContext::SetProperty(JS::Handle<JSObject*> aTarget, const char* aPropName, n
// got the arguments, now attach them.
for (uint32_t i = 0; i < args.length(); ++i) {
if (!JS_WrapValue(mContext, args.handleAt(i))) {
if (!JS_WrapValue(mContext, args[i])) {
return NS_ERROR_FAILURE;
}
}
@ -1066,7 +1066,7 @@ nsJSContext::ConvertSupportsTojsvals(nsISupports* aArgs,
if (argsArray) {
for (uint32_t argCtr = 0; argCtr < argCount && NS_SUCCEEDED(rv); argCtr++) {
nsCOMPtr<nsISupports> arg;
JS::MutableHandle<JS::Value> thisVal = aArgsOut.handleAt(argCtr);
JS::MutableHandle<JS::Value> thisVal = aArgsOut[argCtr];
argsArray->QueryElementAt(argCtr, NS_GET_IID(nsISupports),
getter_AddRefs(arg));
if (!arg) {
@ -1099,7 +1099,7 @@ nsJSContext::ConvertSupportsTojsvals(nsISupports* aArgs,
} else {
nsCOMPtr<nsIVariant> variant = do_QueryInterface(aArgs);
if (variant) {
rv = xpc->VariantToJS(cx, aScope, variant, aArgsOut.handleAt(0));
rv = xpc->VariantToJS(cx, aScope, variant, aArgsOut[0]);
} else {
NS_ERROR("Not an array, not an interface?");
rv = NS_ERROR_UNEXPECTED;

Просмотреть файл

@ -2054,7 +2054,7 @@ inline bool
AddStringToIDVector(JSContext* cx, JS::AutoIdVector& vector, const char* name)
{
return vector.growBy(1) &&
InternJSString(cx, vector[vector.length() - 1], name);
InternJSString(cx, *(vector[vector.length() - 1]).address(), name);
}
// Implementation of the bits that XrayWrapper needs

Просмотреть файл

@ -12525,8 +12525,8 @@ class CallbackMember(CGNativeMember):
{
'result': result,
'successCode': "continue;\n" if arg.variadic else "break;\n",
'jsvalRef': "argv.handleAt(%s)" % jsvalIndex,
'jsvalHandle': "argv.handleAt(%s)" % jsvalIndex,
'jsvalRef': "argv[%s]" % jsvalIndex,
'jsvalHandle': "argv[%s]" % jsvalIndex,
# XXXbz we don't have anything better to use for 'obj',
# really... It's OK to use CallbackPreserveColor because
# CallSetup already handled the unmark-gray bits for us.
@ -12558,7 +12558,7 @@ class CallbackMember(CGNativeMember):
// This is our current trailing argument; reduce argc
--argc;
} else {
argv[${i}] = JS::UndefinedValue();
argv[${i}].setUndefined();
}
""",
argName=arg.identifier.name,
@ -12816,7 +12816,7 @@ class CallbackSetter(CallbackAccessor):
return fill(
"""
MOZ_ASSERT(argv.length() == 1);
if (!JS_SetProperty(cx, CallbackPreserveColor(), "${attrName}", argv.handleAt(0))) {
if (!JS_SetProperty(cx, CallbackPreserveColor(), "${attrName}", argv[0])) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return${errorReturn};
}

Просмотреть файл

@ -244,7 +244,7 @@ ToJSValue(JSContext* aCx,
return false;
}
for (size_t i = 0; i < aLength; ++i) {
if (!ToJSValue(aCx, aArguments[i], v.handleAt(i))) {
if (!ToJSValue(aCx, aArguments[i], v[i])) {
return false;
}
}

Просмотреть файл

@ -22,6 +22,19 @@ enum GamepadMappingType
StandardMapping = 1
};
// Per spec:
// https://dvcs.w3.org/hg/gamepad/raw-file/default/gamepad.html#remapping
const int kStandardGamepadButtons = 17;
const int kStandardGamepadAxes = 4;
const int kButtonLeftTrigger = 6;
const int kButtonRightTrigger = 7;
const int kLeftStickXAxis = 0;
const int kLeftStickYAxis = 1;
const int kRightStickXAxis = 2;
const int kRightStickYAxis = 3;
class Gamepad : public nsISupports,
public nsWrapperCache
{

Просмотреть файл

@ -97,7 +97,9 @@ function createMediaElement(type, label) {
* The error callback if the stream fails to be retrieved
*/
function getUserMedia(constraints, onSuccess, onError) {
constraints["fake"] = FAKE_ENABLED;
if (!("fake" in constraints)) {
constraints["fake"] = FAKE_ENABLED;
}
info("Call getUserMedia for " + JSON.stringify(constraints));
navigator.mozGetUserMedia(constraints, onSuccess, onError);

Просмотреть файл

@ -131,7 +131,7 @@ MobileMessageManager::Send(JSContext* aCx, JS::Handle<JSObject*> aGlobal,
uint32_t aServiceId,
JS::Handle<JSString*> aNumber,
const nsAString& aMessage,
JS::Value* aRequest)
JS::MutableHandle<JS::Value> aRequest)
{
nsCOMPtr<nsISmsService> smsService = do_GetService(SMS_SERVICE_CONTRACTID);
NS_ENSURE_TRUE(smsService, NS_ERROR_FAILURE);
@ -149,16 +149,14 @@ MobileMessageManager::Send(JSContext* aCx, JS::Handle<JSObject*> aGlobal,
NS_ENSURE_SUCCESS(rv, rv);
js::AssertSameCompartment(aCx, aGlobal);
JS::Rooted<JS::Value> rval(aCx);
rv = nsContentUtils::WrapNative(aCx,
static_cast<nsIDOMDOMRequest*>(request.get()),
&rval);
aRequest);
if (NS_FAILED(rv)) {
NS_ERROR("Failed to create the js value!");
return rv;
}
*aRequest = rval;
return NS_OK;
}
@ -208,7 +206,7 @@ MobileMessageManager::Send(JS::Handle<JS::Value> aNumber,
if (aNumber.isString()) {
JS::Rooted<JSString*> str(aCx, aNumber.toString());
return Send(aCx, global, serviceId, str, aMessage, aReturn.address());
return Send(aCx, global, serviceId, str, aMessage, aReturn);
}
// Must be an array then.
@ -236,7 +234,7 @@ MobileMessageManager::Send(JS::Handle<JS::Value> aNumber,
return NS_ERROR_FAILURE;
}
nsresult rv = Send(aCx, global, serviceId, str, aMessage, &requests[i]);
nsresult rv = Send(aCx, global, serviceId, str, aMessage, requests[i]);
NS_ENSURE_SUCCESS(rv, rv);
}

Просмотреть файл

@ -38,7 +38,7 @@ private:
uint32_t aServiceId,
JS::Handle<JSString*> aNumber,
const nsAString& aMessage,
JS::Value* aRequest);
JS::MutableHandle<JS::Value> aRequest);
nsresult DispatchTrustedSmsEventToSelf(const char* aTopic,
const nsAString& aEventName,

Просмотреть файл

@ -57,7 +57,7 @@ PersistenceTypeFromText(const nsACString& aText)
inline nsresult
NullablePersistenceTypeFromText(const nsACString& aText,
Nullable<PersistenceType> *aPersistenceType)
Nullable<PersistenceType>* aPersistenceType)
{
if (aText.IsVoid()) {
*aPersistenceType = Nullable<PersistenceType>();
@ -74,7 +74,7 @@ NullablePersistenceTypeFromText(const nsACString& aText,
return NS_OK;
}
return NS_ERROR_UNEXPECTED;
return NS_ERROR_FAILURE;
}
inline mozilla::dom::StorageType

Просмотреть файл

@ -2290,6 +2290,13 @@ QuotaManager::ClearStoragesForURI(nsIURI* aURI,
NS_ENSURE_ARG_POINTER(aURI);
Nullable<PersistenceType> persistenceType;
nsresult rv =
NullablePersistenceTypeFromText(aPersistenceType, &persistenceType);
if (NS_WARN_IF(NS_FAILED(rv))) {
return NS_ERROR_INVALID_ARG;
}
// This only works from the main process.
NS_ENSURE_TRUE(IsMainProcess(), NS_ERROR_NOT_AVAILABLE);
@ -2299,17 +2306,13 @@ QuotaManager::ClearStoragesForURI(nsIURI* aURI,
// Figure out which origin we're dealing with.
nsCString origin;
nsresult rv = GetInfoFromURI(aURI, aAppId, aInMozBrowserOnly, nullptr, &origin,
nullptr, nullptr);
rv = GetInfoFromURI(aURI, aAppId, aInMozBrowserOnly, nullptr, &origin,
nullptr, nullptr);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoCString pattern;
GetOriginPatternString(aAppId, aInMozBrowserOnly, origin, pattern);
Nullable<PersistenceType> persistenceType;
rv = NullablePersistenceTypeFromText(aPersistenceType, &persistenceType);
NS_ENSURE_SUCCESS(rv, rv);
// If there is a pending or running clear operation for this origin, return
// immediately.
if (IsClearOriginPending(pattern, persistenceType)) {
@ -2687,7 +2690,9 @@ QuotaManager::AcquireExclusiveAccess(const nsACString& aPattern,
nsIOfflineStorage*& storage = matches[index];
if (!storage->IsClosed() &&
storage != aStorage &&
storage->Id() == aStorage->Id()) {
storage->Id() == aStorage->Id() &&
(aPersistenceType.IsNull() ||
aPersistenceType.Value() == storage->Type())) {
liveStorages.AppendElement(storage);
}
}
@ -2708,14 +2713,23 @@ QuotaManager::AcquireExclusiveAccess(const nsACString& aPattern,
matches.Find(mLiveStorages, aPattern);
}
if (!matches.IsEmpty()) {
// We want *all* storages, even those that are closed, when we're going to
// clear the origin.
matches.AppendElementsTo(liveStorages);
NS_ASSERTION(op->mStorages.IsEmpty(),
"How do we already have storages here?");
NS_ASSERTION(op->mStorages.IsEmpty(),
"How do we already have storages here?");
matches.SwapElements(op->mStorages);
// We want *all* storages that match the given persistence type, even those
// that are closed, when we're going to clear the origin.
if (!matches.IsEmpty()) {
for (uint32_t i = 0; i < Client::TYPE_MAX; i++) {
nsTArray<nsIOfflineStorage*>& storages = matches.ArrayAt(i);
for (uint32_t j = 0; j < storages.Length(); j++) {
nsIOfflineStorage* storage = storages[j];
if (aPersistenceType.IsNull() ||
aPersistenceType.Value() == storage->Type()) {
liveStorages.AppendElement(storage);
op->mStorages[i].AppendElement(storage);
}
}
}
}
}

Просмотреть файл

@ -272,6 +272,7 @@ let NotificationDB = {
var id = data.id;
if (!this.notifications[origin]) {
if (DEBUG) { debug("No notifications found for origin: " + origin); }
callback();
return;
}
@ -279,6 +280,7 @@ let NotificationDB = {
var oldNotification = this.notifications[origin][id];
if (!oldNotification) {
if (DEBUG) { debug("No notification found with id: " + id); }
callback();
return;
}

Просмотреть файл

@ -34,3 +34,4 @@ LOCAL_INCLUDES += [
'/dom/ipc',
]
XPCSHELL_TESTS_MANIFESTS += ['test/unit/xpcshell.ini']

Просмотреть файл

@ -0,0 +1,338 @@
const Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
"@mozilla.org/childprocessmessagemanager;1",
"nsIMessageSender");
let systemNotification = {
origin: "app://system.gaiamobile.org/manifest.webapp",
id: "{2bc883bf-2809-4432-b0f4-f54e10372764}",
title: "SystemNotification:" + Date.now(),
dir: "auto",
lang: "",
body: "System notification body",
tag: "",
icon: "icon.png"
};
let calendarNotification = {
origin: "app://calendar.gaiamobile.org/manifest.webapp",
id: "{d8d11299-a58e-429b-9a9a-57c562982fbf}",
title: "CalendarNotification:" + Date.now(),
dir: "auto",
lang: "",
body: "Calendar notification body",
tag: "",
icon: "icon.png"
};
function run_test() {
do_get_profile();
Cu.import("resource://gre/modules/NotificationDB.jsm");
run_next_test();
}
// Helper function to add a listener, send message and treat the reply
function addAndSend(msg, reply, callback, payload, runNext = true) {
let handler = {
receiveMessage: function(message) {
if (message.name === reply) {
cpmm.removeMessageListener(reply, handler);
callback(message);
if (runNext) {
run_next_test();
}
}
}
};
cpmm.addMessageListener(reply, handler);
cpmm.sendAsyncMessage(msg, payload);
}
// helper fonction, comparing two notifications
function compareNotification(notif1, notif2) {
// retrieved notification should be the second one sent
for (let prop in notif1) {
// compare each property
do_check_eq(notif1[prop], notif2[prop]);
}
}
// Get one notification, none exists
add_test(function test_get_none() {
let requestID = 0;
let msgReply = "Notification:GetAll:Return:OK";
let msgHandler = function(message) {
do_check_eq(requestID, message.data.requestID);
do_check_eq(0, message.data.notifications.length);
};
addAndSend("Notification:GetAll", msgReply, msgHandler, {
origin: systemNotification.origin,
requestID: requestID
});
});
// Store one notification
add_test(function test_send_one() {
let requestID = 1;
let msgReply = "Notification:Save:Return:OK";
let msgHandler = function(message) {
do_check_eq(requestID, message.data.requestID);
};
addAndSend("Notification:Save", msgReply, msgHandler, {
origin: systemNotification.origin,
notification: systemNotification,
requestID: requestID
});
});
// Get one notification, one exists
add_test(function test_get_one() {
let requestID = 2;
let msgReply = "Notification:GetAll:Return:OK";
let msgHandler = function(message) {
do_check_eq(requestID, message.data.requestID);
do_check_eq(1, message.data.notifications.length);
// compare the content
compareNotification(systemNotification, message.data.notifications[0]);
};
addAndSend("Notification:GetAll", msgReply, msgHandler, {
origin: systemNotification.origin,
requestID: requestID
});
});
// Delete one notification
add_test(function test_delete_one() {
let requestID = 3;
let msgReply = "Notification:Delete:Return:OK";
let msgHandler = function(message) {
do_check_eq(requestID, message.data.requestID);
};
addAndSend("Notification:Delete", msgReply, msgHandler, {
origin: systemNotification.origin,
id: systemNotification.id,
requestID: requestID
});
});
// Get one notification, none exists
add_test(function test_get_none_again() {
let requestID = 4;
let msgReply = "Notification:GetAll:Return:OK";
let msgHandler = function(message) {
do_check_eq(requestID, message.data.requestID);
do_check_eq(0, message.data.notifications.length);
};
addAndSend("Notification:GetAll", msgReply, msgHandler, {
origin: systemNotification.origin,
requestID: requestID
});
});
// Delete one notification that do not exists anymore
add_test(function test_delete_one_nonexistent() {
let requestID = 5;
let msgReply = "Notification:Delete:Return:OK";
let msgHandler = function(message) {
do_check_eq(requestID, message.data.requestID);
};
addAndSend("Notification:Delete", msgReply, msgHandler, {
origin: systemNotification.origin,
id: systemNotification.id,
requestID: requestID
});
});
// Store two notifications with the same id
add_test(function test_send_two_get_one() {
let requestID = 6;
let calls = 0;
let msgGetReply = "Notification:GetAll:Return:OK";
let msgGetHandler = function(message) {
do_check_eq(requestID + 2, message.data.requestID);
do_check_eq(1, message.data.notifications.length);
// compare the content
compareNotification(systemNotification, message.data.notifications[0]);
};
let msgSaveReply = "Notification:Save:Return:OK";
let msgSaveHandler = function(message) {
calls += 1;
if (calls === 2) {
addAndSend("Notification:GetAll", msgGetReply, msgGetHandler, {
origin: systemNotification.origin,
requestID: (requestID + 2)
});
}
};
addAndSend("Notification:Save", msgSaveReply, msgSaveHandler, {
origin: systemNotification.origin,
notification: systemNotification,
requestID: requestID
}, false);
addAndSend("Notification:Save", msgSaveReply, msgSaveHandler, {
origin: systemNotification.origin,
notification: systemNotification,
requestID: (requestID + 1)
}, false);
});
// Delete previous notification
add_test(function test_delete_previous() {
let requestID = 8;
let msgReply = "Notification:Delete:Return:OK";
let msgHandler = function(message) {
do_check_eq(requestID, message.data.requestID);
};
addAndSend("Notification:Delete", msgReply, msgHandler, {
origin: systemNotification.origin,
id: systemNotification.id,
requestID: requestID
});
});
// Store two notifications from same origin with the same tag
add_test(function test_send_two_get_one() {
let requestID = 10;
let tag = "voicemail";
let systemNotification1 = systemNotification;
systemNotification1.id = "{f271f9ee-3955-4c10-b1f2-af552fb270ee}";
systemNotification1.tag = tag;
let systemNotification2 = systemNotification;
systemNotification2.id = "{8ef9a628-f0f4-44b4-820d-c117573c33e3}";
systemNotification2.tag = tag;
let msgGetReply = "Notification:GetAll:Return:OK";
let msgGetNotifHandler = {
receiveMessage: function(message) {
if (message.name === msgGetReply) {
cpmm.removeMessageListener(msgGetReply, msgGetNotifHandler);
let notifications = message.data.notifications;
// same tag, so replaced
do_check_eq(1, notifications.length);
// compare the content
compareNotification(systemNotification2, notifications[0]);
run_next_test();
}
}
};
cpmm.addMessageListener(msgGetReply, msgGetNotifHandler);
let msgSaveReply = "Notification:Save:Return:OK";
let msgSaveCalls = 0;
let msgSaveHandler = function(message) {
msgSaveCalls++;
// Once both request have been sent, trigger getall
if (msgSaveCalls === 2) {
cpmm.sendAsyncMessage("Notification:GetAll", {
origin: systemNotification1.origin,
requestID: message.data.requestID + 2 // 12, 13
});
}
};
addAndSend("Notification:Save", msgSaveReply, msgSaveHandler, {
origin: systemNotification1.origin,
notification: systemNotification1,
requestID: requestID // 10
}, false);
addAndSend("Notification:Save", msgSaveReply, msgSaveHandler, {
origin: systemNotification2.origin,
notification: systemNotification2,
requestID: (requestID + 1) // 11
}, false);
});
// Store two notifications from two origins with the same tag
add_test(function test_send_two_get_two() {
let requestID = 20;
let tag = "voicemail";
let systemNotification1 = systemNotification;
systemNotification1.tag = tag;
let calendarNotification2 = calendarNotification;
calendarNotification2.tag = tag;
let msgGetReply = "Notification:GetAll:Return:OK";
let msgGetCalls = 0;
let msgGetHandler = {
receiveMessage: function(message) {
if (message.name === msgGetReply) {
msgGetCalls++;
let notifications = message.data.notifications;
// one notification per origin
do_check_eq(1, notifications.length);
// first call should be system notification
if (msgGetCalls === 1) {
compareNotification(systemNotification1, notifications[0]);
}
// second and last call should be calendar notification
if (msgGetCalls === 2) {
cpmm.removeMessageListener(msgGetReply, msgGetHandler);
compareNotification(calendarNotification2, notifications[0]);
run_next_test();
}
}
}
};
cpmm.addMessageListener(msgGetReply, msgGetHandler);
let msgSaveReply = "Notification:Save:Return:OK";
let msgSaveCalls = 0;
let msgSaveHandler = {
receiveMessage: function(message) {
if (message.name === msgSaveReply) {
msgSaveCalls++;
if (msgSaveCalls === 2) {
cpmm.removeMessageListener(msgSaveReply, msgSaveHandler);
// Trigger getall for each origin
cpmm.sendAsyncMessage("Notification:GetAll", {
origin: systemNotification1.origin,
requestID: message.data.requestID + 1 // 22
});
cpmm.sendAsyncMessage("Notification:GetAll", {
origin: calendarNotification2.origin,
requestID: message.data.requestID + 2 // 23
});
}
}
}
};
cpmm.addMessageListener(msgSaveReply, msgSaveHandler);
cpmm.sendAsyncMessage("Notification:Save", {
origin: systemNotification1.origin,
notification: systemNotification1,
requestID: requestID // 20
});
cpmm.sendAsyncMessage("Notification:Save", {
origin: calendarNotification2.origin,
notification: calendarNotification2,
requestID: (requestID + 1) // 21
});
});

Просмотреть файл

@ -0,0 +1,5 @@
[DEFAULT]
head =
tail =
[test_notificationdb.js]

Просмотреть файл

@ -20,10 +20,7 @@ interface Console {
void time(optional any time);
void timeEnd(optional any time);
[Throws]
void profile(any... data);
[Throws]
void profileEnd(any... data);
void assert(boolean condition, any... data);

Просмотреть файл

@ -728,7 +728,7 @@ APZCTreeManager::HandOffFling(AsyncPanZoomController* aPrev, ScreenPoint aVeloci
// otherwise built on touch-start and cleared on touch-end, and a fling
// happens after touch-end. Note that, unlike DispatchScroll() which is
// called on every touch-move during overscroll panning,
// HandleFlingOverscroll() is only called once during a fling handoff,
// HandOffFling() is only called once during a fling handoff,
// so it's not worth trying to avoid building the handoff chain here.
BuildOverscrollHandoffChain(aPrev);

Просмотреть файл

@ -66,7 +66,7 @@
#define APZC_LOG_FM(fm, prefix, ...) \
APZC_LOG(prefix ":" \
" i=(%ld %lld) cb=(%d %d %d %d) rcs=(%.3f %.3f) dp=(%.3f %.3f %.3f %.3f) dpm=(%.3f %.3f %.3f %.3f) um=%d " \
"v=(%.3f %.3f %.3f %.3f) s=(%.3f %.3f) sr=(%.3f %.3f %.3f %.3f) z=(%.3f %.3f %.3f %.3f) u=(%d %lu)\n", \
"v=(%.3f %.3f %.3f %.3f) s=(%.3f %.3f) sr=(%.3f %.3f %.3f %.3f) z(ld=%.3f r=%.3f cr=%.3f z=%.3f ts=%.3f) u=(%d %lu)\n", \
__VA_ARGS__, \
fm.mPresShellId, fm.GetScrollId(), \
fm.mCompositionBounds.x, fm.mCompositionBounds.y, fm.mCompositionBounds.width, fm.mCompositionBounds.height, \
@ -77,7 +77,7 @@
fm.mViewport.x, fm.mViewport.y, fm.mViewport.width, fm.mViewport.height, \
fm.GetScrollOffset().x, fm.GetScrollOffset().y, \
fm.mScrollableRect.x, fm.mScrollableRect.y, fm.mScrollableRect.width, fm.mScrollableRect.height, \
fm.mDevPixelsPerCSSPixel.scale, fm.mResolution.scale, fm.mCumulativeResolution.scale, fm.GetZoom().scale, \
fm.mDevPixelsPerCSSPixel.scale, fm.mResolution.scale, fm.mCumulativeResolution.scale, fm.GetZoom().scale, fm.mTransformScale.scale, \
fm.GetScrollOffsetUpdated(), fm.GetScrollGeneration()); \
// Static helper functions
@ -163,6 +163,20 @@ typedef GeckoContentController::APZStateChange APZStateChange;
* generated displayport's size is beyond that of the scrollable rect on the
* opposite axis.
*
* "apz.fling_accel_interval_ms"
* The time in milliseconds that determines whether a second fling will be
* treated as accelerated. If two flings are started within this interval,
* the second one will be accelerated. Setting an interval of 0 means that
* acceleration will be disabled.
*
* "apz.fling_accel_base_mult"
* "apz.fling_accel_supplemental_mult"
* When applying an acceleration on a fling, the new computed velocity is
* (new_fling_velocity * base_mult) + (old_velocity * supplemental_mult).
* The base_mult and supplemental_mult multiplier values are controlled by
* these prefs. Note that "old_velocity" here is the initial velocity of the
* previous fling _after_ acceleration was applied to it (if applicable).
*
* "apz.fling_friction"
* Amount of friction applied during flings.
*
@ -330,10 +344,40 @@ GetFrameTime() {
class FlingAnimation: public AsyncPanZoomAnimation {
public:
FlingAnimation(AsyncPanZoomController& aApzc)
FlingAnimation(AsyncPanZoomController& aApzc, bool aApplyAcceleration)
: AsyncPanZoomAnimation(TimeDuration::FromMilliseconds(gfxPrefs::APZFlingRepaintInterval()))
, mApzc(aApzc)
{}
{
TimeStamp now = GetFrameTime();
ScreenPoint velocity(mApzc.mX.GetVelocity(), mApzc.mY.GetVelocity());
// If the last fling was very recent and in the same direction as this one,
// boost the velocity to be the sum of the two. Check separate axes separately
// because we could have two vertical flings with small horizontal components
// on the opposite side of zero, and we still want the y-fling to get accelerated.
// Note that the acceleration code is only applied on the APZC that receives the
// actual touch event; the accelerated velocities are then handed off using the
// normal HandOffFling codepath.
if (aApplyAcceleration && !mApzc.mLastFlingTime.IsNull()
&& (now - mApzc.mLastFlingTime).ToMilliseconds() < gfxPrefs::APZFlingAccelInterval()) {
if (SameDirection(velocity.x, mApzc.mLastFlingVelocity.x)) {
velocity.x = Accelerate(velocity.x, mApzc.mLastFlingVelocity.x);
APZC_LOG("%p Applying fling x-acceleration from %f to %f (delta %f)\n",
&mApzc, mApzc.mX.GetVelocity(), velocity.x, mApzc.mLastFlingVelocity.x);
mApzc.mX.SetVelocity(velocity.x);
}
if (SameDirection(velocity.y, mApzc.mLastFlingVelocity.y)) {
velocity.y = Accelerate(velocity.y, mApzc.mLastFlingVelocity.y);
APZC_LOG("%p Applying fling y-acceleration from %f to %f (delta %f)\n",
&mApzc, mApzc.mY.GetVelocity(), velocity.y, mApzc.mLastFlingVelocity.y);
mApzc.mY.SetVelocity(velocity.y);
}
}
mApzc.mLastFlingTime = now;
mApzc.mLastFlingVelocity = velocity;
}
/**
* Advances a fling by an interpolated amount based on the passed in |aDelta|.
* This should be called whenever sampling the content transform for this
@ -344,6 +388,19 @@ public:
const TimeDuration& aDelta);
private:
static bool SameDirection(float aVelocity1, float aVelocity2)
{
return (aVelocity1 == 0.0f)
|| (aVelocity2 == 0.0f)
|| (IsNegative(aVelocity1) == IsNegative(aVelocity2));
}
static float Accelerate(float aBase, float aSupplemental)
{
return (aBase * gfxPrefs::APZFlingAccelBaseMultiplier())
+ (aSupplemental * gfxPrefs::APZFlingAccelSupplementalMultiplier());
}
AsyncPanZoomController& mApzc;
};
@ -755,7 +812,7 @@ nsEventStatus AsyncPanZoomController::OnTouchEnd(const MultiTouchInput& aEvent)
mX.EndTouch();
mY.EndTouch();
SetState(FLING);
StartAnimation(new FlingAnimation(*this));
StartAnimation(new FlingAnimation(*this, true));
return nsEventStatus_eConsumeNoDefault;
case PINCHING:
@ -1183,7 +1240,7 @@ void AsyncPanZoomController::TakeOverFling(ScreenPoint aVelocity) {
mX.SetVelocity(mX.GetVelocity() + aVelocity.x);
mY.SetVelocity(mY.GetVelocity() + aVelocity.y);
SetState(FLING);
StartAnimation(new FlingAnimation(*this));
StartAnimation(new FlingAnimation(*this, false));
}
void AsyncPanZoomController::CallDispatchScroll(const ScreenPoint& aStartPoint, const ScreenPoint& aEndPoint,
@ -1294,20 +1351,20 @@ bool FlingAnimation::Sample(FrameMetrics& aFrameMetrics,
velocity.y = 0;
}
// To hand off the fling, we call APZCTreeManager::HandleFlingOverscroll()
// To hand off the fling, we call APZCTreeManager::HandOffFling()
// which starts a new fling in the next APZC in the handoff chain with
// the same velocity. For simplicity, the actual overscroll of the current
// sample is discarded rather than being handed off. The compositor should
// sample animations sufficiently frequently that this is not noticeable.
// Make a local copy of the tree manager pointer and check if it's not
// null before calling HandleFlingOverscroll(). This is necessary because
// null before calling HandOffFling(). This is necessary because
// Destroy(), which nulls out mTreeManager, could be called concurrently.
APZCTreeManager* treeManagerLocal = mApzc.mTreeManager;
if (treeManagerLocal) {
// APZC is holding mMonitor, so directly calling HandleFlingOverscroll()
// APZC is holding mMonitor, so directly calling HandOffFling()
// (which acquires the tree lock) would violate the lock ordering. Instead
// we schedule HandleFlingOverscroll() to be called after mMonitor is
// we schedule HandOffFling() to be called after mMonitor is
// released.
mDeferredTasks.append(NewRunnableMethod(treeManagerLocal,
&APZCTreeManager::HandOffFling,
@ -1718,11 +1775,11 @@ gfx3DMatrix AsyncPanZoomController::GetTransformToLastDispatchedPaint() {
void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aLayerMetrics, bool aIsFirstPaint) {
ReentrantMonitorAutoEnter lock(mMonitor);
bool isDefault = mFrameMetrics.IsDefault();
mLastContentPaintMetrics = aLayerMetrics;
UpdateTransformScale();
bool isDefault = mFrameMetrics.IsDefault();
mFrameMetrics.mMayHaveTouchListeners = aLayerMetrics.mMayHaveTouchListeners;
APZC_LOG_FM(aLayerMetrics, "%p got a NotifyLayersUpdated with aIsFirstPaint=%d", this, aIsFirstPaint);

Просмотреть файл

@ -294,12 +294,6 @@ public:
*/
void CancelAnimation();
/**
* Take over a fling with the given velocity from another APZC. Used for
* during overscroll handoff for a fling.
*/
void TakeOverFling(ScreenPoint aVelocity);
/**
* Returns allowed touch behavior for the given point on the scrollable layer.
* Internally performs a kind of hit testing based on the regions constructed
@ -501,14 +495,6 @@ protected:
*/
void DispatchRepaintRequest(const FrameMetrics& aFrameMetrics);
/**
* Advances a fling by an interpolated amount based on the passed in |aDelta|.
* This should be called whenever sampling the content transform for this
* frame. Returns true if the fling animation should be advanced by one frame,
* or false if there is no fling or the fling has ended.
*/
bool DoFling(const TimeDuration& aDelta);
/**
* Gets the current frame metrics. This is *not* the Gecko copy stored in the
* layers code.
@ -777,7 +763,25 @@ private:
RefPtr<AsyncPanZoomAnimation> mAnimation;
friend class Axis;
/* ===================================================================
* The functions and members in this section are used to manage
* fling animations.
*/
public:
/**
* Take over a fling with the given velocity from another APZC. Used for
* during overscroll handoff for a fling.
*/
void TakeOverFling(ScreenPoint aVelocity);
private:
friend class FlingAnimation;
// The initial velocity of the most recent fling.
ScreenPoint mLastFlingVelocity;
// The time at which the most recent fling started.
TimeStamp mLastFlingTime;
/* ===================================================================

Просмотреть файл

@ -111,6 +111,9 @@ private:
DECL_GFX_PREF(Live, "apz.content_response_timeout", APZContentResponseTimeout, int32_t, 300);
DECL_GFX_PREF(Live, "apz.cross_slide.enabled", APZCrossSlideEnabled, bool, false);
DECL_GFX_PREF(Live, "apz.enlarge_displayport_when_clipped", APZEnlargeDisplayPortWhenClipped, bool, false);
DECL_GFX_PREF(Live, "apz.fling_accel_interval_ms", APZFlingAccelInterval, int32_t, 500);
DECL_GFX_PREF(Live, "apz.fling_accel_base_mult", APZFlingAccelBaseMultiplier, float, 1.0f);
DECL_GFX_PREF(Live, "apz.fling_accel_supplemental_mult", APZFlingAccelSupplementalMultiplier, float, 1.0f);
DECL_GFX_PREF(Once, "apz.fling_friction", APZFlingFriction, float, 0.002f);
DECL_GFX_PREF(Live, "apz.fling_repaint_interval", APZFlingRepaintInterval, int32_t, 75);
DECL_GFX_PREF(Once, "apz.fling_stopped_threshold", APZFlingStoppedThreshold, float, 0.01f);

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше