зеркало из https://github.com/mozilla/gecko-dev.git
Merge b2g-inbound to m-c.
This commit is contained in:
Коммит
f1311f346a
2
CLOBBER
2
CLOBBER
|
@ -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/cert8.db
Двоичный файл не отображается.
Двоичные данные
build/pgo/certs/key3.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
|
||||
|
|
12
configure.in
12
configure.in
|
@ -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
|
Двоичный файл не отображается.
|
@ -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
|
Двоичный файл не отображается.
|
@ -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
|
Двоичный файл не отображается.
|
@ -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);
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче