зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to inbound. a=merge CLOSED TREE
This commit is contained in:
Коммит
0b0d5bd64a
|
@ -80,9 +80,8 @@ browser/components/sessionstore/test/unit/data/sessionstore_invalid.js
|
|||
browser/components/enterprisepolicies/schemas/schema.jsm
|
||||
# generated & special files in cld2
|
||||
browser/components/translation/cld2/**
|
||||
# Screenshots and Follow-on search are imported as a system add-on and have
|
||||
# Screenshots is imported as a system add-on and has
|
||||
# their own lint rules currently.
|
||||
browser/extensions/followonsearch/**
|
||||
browser/extensions/screenshots/**
|
||||
browser/extensions/pdfjs/content/build**
|
||||
browser/extensions/pdfjs/content/web**
|
||||
|
|
|
@ -1051,7 +1051,7 @@ pref("security.sandbox.content.level", 3);
|
|||
// 2 - "read access triggered by file dialog activity, limited read/write"
|
||||
// "access for Flash functionality"
|
||||
// 3 - "limited read/write access for Flash functionality"
|
||||
pref("dom.ipc.plugins.sandbox-level.flash", 2);
|
||||
pref("dom.ipc.plugins.sandbox-level.flash", 1);
|
||||
// Controls the level used on older OS X versions. Is overriden when the
|
||||
// "dom.ipc.plugins.sandbox-level.flash" is set to 0.
|
||||
pref("dom.ipc.plugins.sandbox-level.flash.legacy", 1);
|
||||
|
@ -1060,7 +1060,7 @@ pref("dom.ipc.plugins.sandbox-level.flash.max-legacy-os-minor", 10);
|
|||
// Controls the sandbox level used by plugins other than Flash. On Mac,
|
||||
// no other plugins are supported and this pref is only used for test
|
||||
// plugins used in automated tests.
|
||||
pref("dom.ipc.plugins.sandbox-level.default", 2);
|
||||
pref("dom.ipc.plugins.sandbox-level.default", 1);
|
||||
#endif
|
||||
|
||||
#if defined(XP_LINUX) && defined(MOZ_SANDBOX) && defined(MOZ_CONTENT_SANDBOX)
|
||||
|
|
|
@ -36,6 +36,7 @@ const startupPhases = {
|
|||
modules: new Set([
|
||||
"resource://gre/modules/AppConstants.jsm",
|
||||
"resource://gre/modules/ActorManagerParent.jsm",
|
||||
"resource://gre/modules/CustomElementsListener.jsm",
|
||||
"resource://gre/modules/ExtensionUtils.jsm",
|
||||
"resource://gre/modules/XPCOMUtils.jsm",
|
||||
"resource://gre/modules/Services.jsm",
|
||||
|
|
|
@ -580,6 +580,7 @@ MenuItem.prototype = {
|
|||
checked: false,
|
||||
contexts: ["all"],
|
||||
enabled: true,
|
||||
visible: true,
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -708,6 +709,9 @@ MenuItem.prototype = {
|
|||
},
|
||||
|
||||
enabledForContext(contextData) {
|
||||
if (!this.visible) {
|
||||
return false;
|
||||
}
|
||||
let contexts = getMenuContexts(contextData);
|
||||
if (!this.contexts.some(n => contexts.has(n))) {
|
||||
return false;
|
||||
|
|
|
@ -197,6 +197,11 @@
|
|||
"optional": true,
|
||||
"description": "List of contexts this menu item will appear in. Defaults to ['page'] if not specified."
|
||||
},
|
||||
"visible": {
|
||||
"type": "boolean",
|
||||
"optional": true,
|
||||
"description": "Whether the item is visible in the menu."
|
||||
},
|
||||
"onclick": {
|
||||
"type": "function",
|
||||
"optional": true,
|
||||
|
@ -294,6 +299,11 @@
|
|||
"minItems": 1,
|
||||
"optional": true
|
||||
},
|
||||
"visible": {
|
||||
"type": "boolean",
|
||||
"optional": true,
|
||||
"description": "Whether the item is visible in the menu."
|
||||
},
|
||||
"onclick": {
|
||||
"type": "function",
|
||||
"optional": "omit-key-if-missing",
|
||||
|
|
|
@ -115,6 +115,7 @@ skip-if = (verify && (os == 'linux' || os == 'mac'))
|
|||
[browser_ext_menus_targetElement.js]
|
||||
[browser_ext_menus_targetElement_extension.js]
|
||||
[browser_ext_menus_targetElement_shadow.js]
|
||||
[browser_ext_menus_visible.js]
|
||||
[browser_ext_omnibox.js]
|
||||
[browser_ext_openPanel.js]
|
||||
skip-if = (verify && !debug && (os == 'linux' || os == 'mac'))
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
const PAGE = "http://mochi.test:8888/browser/browser/components/extensions/test/browser/context.html";
|
||||
|
||||
add_task(async function visible_false() {
|
||||
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, PAGE);
|
||||
|
||||
async function background() {
|
||||
browser.menus.onShown.addListener(info => {
|
||||
browser.test.assertEq("[]", JSON.stringify(info.menuIds), "Expected no menu items");
|
||||
browser.test.sendMessage("done");
|
||||
});
|
||||
browser.menus.create({
|
||||
id: "create-visible-false",
|
||||
title: "invisible menu item",
|
||||
visible: false,
|
||||
});
|
||||
browser.menus.create({
|
||||
id: "update-without-params",
|
||||
title: "invisible menu item",
|
||||
visible: false,
|
||||
});
|
||||
await browser.menus.update("update-without-params", {});
|
||||
browser.menus.create({
|
||||
id: "update-visible-to-false",
|
||||
title: "initially visible menu item",
|
||||
});
|
||||
await browser.menus.update("update-visible-to-false", {visible: false});
|
||||
browser.test.sendMessage("ready");
|
||||
}
|
||||
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
permissions: ["menus"],
|
||||
},
|
||||
background,
|
||||
});
|
||||
|
||||
await extension.startup();
|
||||
await extension.awaitMessage("ready");
|
||||
await openContextMenu();
|
||||
await extension.awaitMessage("done");
|
||||
await closeContextMenu();
|
||||
|
||||
await extension.unload();
|
||||
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
});
|
||||
|
||||
add_task(async function visible_true() {
|
||||
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, PAGE);
|
||||
|
||||
async function background() {
|
||||
browser.menus.onShown.addListener(info => {
|
||||
browser.test.assertEq(`["update-to-true"]`, JSON.stringify(info.menuIds), "Expected no menu items");
|
||||
browser.test.sendMessage("done");
|
||||
});
|
||||
browser.menus.create({
|
||||
id: "update-to-true",
|
||||
title: "invisible menu item",
|
||||
visible: false,
|
||||
});
|
||||
await browser.menus.update("update-to-true", {visible: true});
|
||||
browser.test.sendMessage("ready");
|
||||
}
|
||||
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
permissions: ["menus"],
|
||||
},
|
||||
background,
|
||||
});
|
||||
|
||||
await extension.startup();
|
||||
await extension.awaitMessage("ready");
|
||||
await openContextMenu();
|
||||
await extension.awaitMessage("done");
|
||||
await closeContextMenu();
|
||||
|
||||
await extension.unload();
|
||||
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
});
|
|
@ -103,6 +103,7 @@ async function testSearchEngine(engineDetails) {
|
|||
// Test search URLs (including purposes).
|
||||
let url = engine.getSubmission("foo").uri.spec;
|
||||
Assert.equal(url, base + engineDetails.codes.submission, "Check search URL for 'foo'");
|
||||
let sb = BrowserSearch.searchBar;
|
||||
|
||||
let engineTests = [
|
||||
{
|
||||
|
@ -136,12 +137,8 @@ async function testSearchEngine(engineDetails) {
|
|||
name: "search bar search",
|
||||
searchURL: base + engineDetails.codes.submission,
|
||||
run() {
|
||||
let sb = BrowserSearch.searchBar;
|
||||
sb.focus();
|
||||
sb.value = "foo";
|
||||
registerCleanupFunction(function() {
|
||||
sb.value = "";
|
||||
});
|
||||
EventUtils.synthesizeKey("KEY_Enter");
|
||||
}
|
||||
},
|
||||
|
@ -185,5 +182,6 @@ async function testSearchEngine(engineDetails) {
|
|||
}
|
||||
|
||||
engine.alias = undefined;
|
||||
sb.value = "";
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
}
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
"env": {
|
||||
"browser": true,
|
||||
"node": false
|
||||
}
|
||||
};
|
|
@ -1,192 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* global APP_SHUTDOWN:false */
|
||||
|
||||
"use strict";
|
||||
|
||||
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
ChromeUtils.import("resource://gre/modules/Timer.jsm");
|
||||
|
||||
// Preferences this add-on uses.
|
||||
const kPrefPrefix = "extensions.followonsearch.";
|
||||
const PREF_LOGGING = `${kPrefPrefix}logging`;
|
||||
|
||||
const kExtensionID = "followonsearch@mozilla.com";
|
||||
const kSaveTelemetryMsg = `${kExtensionID}:save-telemetry`;
|
||||
const kShutdownMsg = `${kExtensionID}:shutdown`;
|
||||
|
||||
const frameScript = `chrome://followonsearch/content/followonsearch-fs.js?q=${Math.random()}`;
|
||||
|
||||
const validSearchTypes = [
|
||||
// A search is a follow-on search from an SAP.
|
||||
"follow-on",
|
||||
// The search is a "search access point".
|
||||
"sap",
|
||||
];
|
||||
|
||||
var gLoggingEnabled = false;
|
||||
var gTelemetryActivated = false;
|
||||
|
||||
/**
|
||||
* Logs a message to the console if logging is enabled.
|
||||
*
|
||||
* @param {String} message The message to log.
|
||||
*/
|
||||
function log(message) {
|
||||
if (gLoggingEnabled) {
|
||||
console.log("Follow-On Search", message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles receiving a message from the content process to save telemetry.
|
||||
*
|
||||
* @param {Object} message The message received.
|
||||
*/
|
||||
function handleSaveTelemetryMsg(message) {
|
||||
if (message.name != kSaveTelemetryMsg) {
|
||||
throw new Error(`Unexpected message received: ${message.name}`);
|
||||
}
|
||||
|
||||
let info = message.data;
|
||||
|
||||
if (!validSearchTypes.includes(info.type)) {
|
||||
throw new Error("Unexpected type!");
|
||||
}
|
||||
|
||||
log(info);
|
||||
|
||||
let histogram = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS");
|
||||
let payload = `${info.sap}.${info.type}:unknown:${info.code}`;
|
||||
if (info.extra) {
|
||||
payload += `:${info.extra}`
|
||||
}
|
||||
histogram.add(payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Activates recording of telemetry if it isn't already activated.
|
||||
*/
|
||||
function activateTelemetry() {
|
||||
if (gTelemetryActivated) {
|
||||
return;
|
||||
}
|
||||
|
||||
gTelemetryActivated = true;
|
||||
|
||||
Services.mm.addMessageListener(kSaveTelemetryMsg, handleSaveTelemetryMsg);
|
||||
Services.mm.loadFrameScript(frameScript, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deactivites recording of telemetry if it isn't already deactivated.
|
||||
*/
|
||||
function deactivateTelemetry() {
|
||||
if (!gTelemetryActivated) {
|
||||
return;
|
||||
}
|
||||
|
||||
Services.mm.removeMessageListener(kSaveTelemetryMsg, handleSaveTelemetryMsg);
|
||||
Services.mm.removeDelayedFrameScript(frameScript);
|
||||
Services.mm.broadcastAsyncMessage(kShutdownMsg);
|
||||
|
||||
gTelemetryActivated = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* cohortManager is used to decide which users to enable the add-on for.
|
||||
*/
|
||||
var cohortManager = {
|
||||
// Indicates whether the telemetry should be enabled.
|
||||
enableForUser: false,
|
||||
|
||||
// Records if we've already run init.
|
||||
_definedThisSession: false,
|
||||
|
||||
/**
|
||||
* Initialises the manager, working out if telemetry should be enabled
|
||||
* for the user.
|
||||
*/
|
||||
init() {
|
||||
if (this._definedThisSession) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._definedThisSession = true;
|
||||
this.enableForUser = false;
|
||||
|
||||
try {
|
||||
let distId = Services.prefs.getCharPref("distribution.id", "");
|
||||
if (distId) {
|
||||
log("It is a distribution, not setting up nor enabling telemetry.");
|
||||
return;
|
||||
}
|
||||
} catch (e) {}
|
||||
|
||||
log("Enabling telemetry for user");
|
||||
this.enableForUser = true;
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Called when the add-on is installed.
|
||||
*
|
||||
* @param {Object} data Data about the add-on.
|
||||
* @param {Number} reason Indicates why the extension is being installed.
|
||||
*/
|
||||
function install(data, reason) {
|
||||
// Nothing specifically to do, startup will set everything up for us.
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the add-on is uninstalled.
|
||||
*
|
||||
* @param {Object} data Data about the add-on.
|
||||
* @param {Number} reason Indicates why the extension is being uninstalled.
|
||||
*/
|
||||
function uninstall(data, reason) {
|
||||
// Nothing specifically to do, shutdown does what we need.
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the add-on starts up.
|
||||
*
|
||||
* @param {Object} data Data about the add-on.
|
||||
* @param {Number} reason Indicates why the extension is being started.
|
||||
*/
|
||||
function startup(data, reason) {
|
||||
try {
|
||||
gLoggingEnabled = Services.prefs.getBoolPref(PREF_LOGGING, false);
|
||||
} catch (e) {
|
||||
// Needed until Firefox 54
|
||||
}
|
||||
|
||||
cohortManager.init();
|
||||
|
||||
if (cohortManager.enableForUser) {
|
||||
// Workaround for bug 1202125
|
||||
// We need to delay our loading so that when we are upgraded,
|
||||
// our new script doesn't get the shutdown message.
|
||||
setTimeout(() => {
|
||||
activateTelemetry();
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the add-on shuts down.
|
||||
*
|
||||
* @param {Object} data Data about the add-on.
|
||||
* @param {Number} reason Indicates why the extension is being shut down.
|
||||
*/
|
||||
function shutdown(data, reason) {
|
||||
// If we're shutting down, skip the cleanup to save time.
|
||||
if (reason === APP_SHUTDOWN) {
|
||||
return;
|
||||
}
|
||||
|
||||
deactivateTelemetry();
|
||||
}
|
|
@ -1,308 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* eslint-env mozilla/frame-script */
|
||||
|
||||
"use strict";
|
||||
|
||||
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
XPCOMUtils.defineLazyGlobalGetters(this, ["URLSearchParams"]);
|
||||
|
||||
const kExtensionID = "followonsearch@mozilla.com";
|
||||
const kSaveTelemetryMsg = `${kExtensionID}:save-telemetry`;
|
||||
const kShutdownMsg = `${kExtensionID}:shutdown`;
|
||||
const kLastSearchQueueDepth = 10;
|
||||
|
||||
/**
|
||||
* A map of search domains with their expected codes.
|
||||
*/
|
||||
let searchDomains = [{
|
||||
"domains": [ "search.yahoo.co.jp" ],
|
||||
"search": "p",
|
||||
"followOnSearch": "ai",
|
||||
"prefix": ["fr"],
|
||||
"codes": ["mozff"],
|
||||
"sap": "yahoo",
|
||||
}, {
|
||||
"domains": [ "www.bing.com" ],
|
||||
"search": "q",
|
||||
"prefix": ["pc"],
|
||||
"reportPrefix": "form",
|
||||
"codes": ["MOZI", "MOZD", "MZSL01", "MZSL02", "MZSL03", "MOZ2"],
|
||||
"sap": "bing",
|
||||
}, {
|
||||
// The Google domains.
|
||||
"domains": [
|
||||
"www.google.com", "www.google.ac", "www.google.ad", "www.google.ae",
|
||||
"www.google.com.af", "www.google.com.ag", "www.google.com.ai",
|
||||
"www.google.al", "www.google.am", "www.google.co.ao", "www.google.com.ar",
|
||||
"www.google.as", "www.google.at", "www.google.com.au", "www.google.az",
|
||||
"www.google.ba", "www.google.com.bd", "www.google.be", "www.google.bf",
|
||||
"www.google.bg", "www.google.com.bh", "www.google.bi", "www.google.bj",
|
||||
"www.google.com.bn", "www.google.com.bo", "www.google.com.br",
|
||||
"www.google.bs", "www.google.bt", "www.google.co.bw", "www.google.by",
|
||||
"www.google.com.bz", "www.google.ca", "www.google.com.kh", "www.google.cc",
|
||||
"www.google.cd", "www.google.cf", "www.google.cat", "www.google.cg",
|
||||
"www.google.ch", "www.google.ci", "www.google.co.ck", "www.google.cl",
|
||||
"www.google.cm", "www.google.cn", "www.google.com.co", "www.google.co.cr",
|
||||
"www.google.com.cu", "www.google.cv", "www.google.cx", "www.google.com.cy",
|
||||
"www.google.cz", "www.google.de", "www.google.dj", "www.google.dk",
|
||||
"www.google.dm", "www.google.com.do", "www.google.dz", "www.google.com.ec",
|
||||
"www.google.ee", "www.google.com.eg", "www.google.es", "www.google.com.et",
|
||||
"www.google.eu", "www.google.fi", "www.google.com.fj", "www.google.fm",
|
||||
"www.google.fr", "www.google.ga", "www.google.ge", "www.google.gf",
|
||||
"www.google.gg", "www.google.com.gh", "www.google.com.gi", "www.google.gl",
|
||||
"www.google.gm", "www.google.gp", "www.google.gr", "www.google.com.gt",
|
||||
"www.google.gy", "www.google.com.hk", "www.google.hn", "www.google.hr",
|
||||
"www.google.ht", "www.google.hu", "www.google.co.id", "www.google.iq",
|
||||
"www.google.ie", "www.google.co.il", "www.google.im", "www.google.co.in",
|
||||
"www.google.io", "www.google.is", "www.google.it", "www.google.je",
|
||||
"www.google.com.jm", "www.google.jo", "www.google.co.jp", "www.google.co.ke",
|
||||
"www.google.ki", "www.google.kg", "www.google.co.kr", "www.google.com.kw",
|
||||
"www.google.kz", "www.google.la", "www.google.com.lb", "www.google.com.lc",
|
||||
"www.google.li", "www.google.lk", "www.google.co.ls", "www.google.lt",
|
||||
"www.google.lu", "www.google.lv", "www.google.com.ly", "www.google.co.ma",
|
||||
"www.google.md", "www.google.me", "www.google.mg", "www.google.mk",
|
||||
"www.google.ml", "www.google.com.mm", "www.google.mn", "www.google.ms",
|
||||
"www.google.com.mt", "www.google.mu", "www.google.mv", "www.google.mw",
|
||||
"www.google.com.mx", "www.google.com.my", "www.google.co.mz",
|
||||
"www.google.com.na", "www.google.ne", "www.google.nf", "www.google.com.ng",
|
||||
"www.google.com.ni", "www.google.nl", "www.google.no", "www.google.com.np",
|
||||
"www.google.nr", "www.google.nu", "www.google.co.nz", "www.google.com.om",
|
||||
"www.google.com.pk", "www.google.com.pa", "www.google.com.pe",
|
||||
"www.google.com.ph", "www.google.pl", "www.google.com.pg", "www.google.pn",
|
||||
"www.google.com.pr", "www.google.ps", "www.google.pt", "www.google.com.py",
|
||||
"www.google.com.qa", "www.google.ro", "www.google.rs", "www.google.ru",
|
||||
"www.google.rw", "www.google.com.sa", "www.google.com.sb", "www.google.sc",
|
||||
"www.google.se", "www.google.com.sg", "www.google.sh", "www.google.si",
|
||||
"www.google.sk", "www.google.com.sl", "www.google.sn", "www.google.sm",
|
||||
"www.google.so", "www.google.st", "www.google.sr", "www.google.com.sv",
|
||||
"www.google.td", "www.google.tg", "www.google.co.th", "www.google.com.tj",
|
||||
"www.google.tk", "www.google.tl", "www.google.tm", "www.google.to",
|
||||
"www.google.tn", "www.google.com.tr", "www.google.tt", "www.google.com.tw",
|
||||
"www.google.co.tz", "www.google.com.ua", "www.google.co.ug",
|
||||
"www.google.co.uk", "www.google.us", "www.google.com.uy", "www.google.co.uz",
|
||||
"www.google.com.vc", "www.google.co.ve", "www.google.vg", "www.google.co.vi",
|
||||
"www.google.com.vn", "www.google.vu", "www.google.ws", "www.google.co.za",
|
||||
"www.google.co.zm", "www.google.co.zw",
|
||||
],
|
||||
"search": "q",
|
||||
"prefix": ["client"],
|
||||
"followOnSearch": "oq",
|
||||
"codes": ["firefox-b-ab", "firefox-b", "firefox-b-1-ab", "firefox-b-1"],
|
||||
"sap": "google",
|
||||
}, {
|
||||
// This is intended only for tests.
|
||||
"domains": [ "mochi.test" ],
|
||||
"search": "m",
|
||||
"prefix": ["mt"],
|
||||
"followOnSearch": "mtfo",
|
||||
"reportPrefix": "form",
|
||||
"codes": ["TEST"],
|
||||
"sap": "mochitest"
|
||||
}];
|
||||
|
||||
function getSearchDomainCodes(host) {
|
||||
for (let domainInfo of searchDomains) {
|
||||
if (domainInfo.domains.includes(host)) {
|
||||
return domainInfo;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for debugging to log messages.
|
||||
*
|
||||
* @param {String} message The message to log.
|
||||
*/
|
||||
function log(message) {
|
||||
// console.log(message);
|
||||
}
|
||||
|
||||
// Hack to handle the most common reload/back/forward case.
|
||||
// If gLastSearchQueue includes the current URL, ignore the search.
|
||||
// This also prevents us from handling reloads with hashes twice
|
||||
let gLastSearchQueue = [];
|
||||
gLastSearchQueue.push = function(...args) {
|
||||
if (this.length >= kLastSearchQueueDepth) {
|
||||
this.shift();
|
||||
}
|
||||
return Array.prototype.push.apply(this, args);
|
||||
};
|
||||
|
||||
// Track if we are in the middle of a Google session
|
||||
// that started from Firefox
|
||||
let searchingGoogle = false;
|
||||
|
||||
/**
|
||||
* Since most codes are in the URL, we can handle them via
|
||||
* a progress listener.
|
||||
*/
|
||||
var webProgressListener = {
|
||||
QueryInterface: ChromeUtils.generateQI([Ci.nsIWebProgressListener, Ci.nsISupportsWeakReference]),
|
||||
onLocationChange(aWebProgress, aRequest, aLocation, aFlags)
|
||||
{
|
||||
if (aWebProgress.DOMWindow && (aWebProgress.DOMWindow != content)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (!aWebProgress.isTopLevel ||
|
||||
// Not a URL
|
||||
(!aLocation.schemeIs("http") && !aLocation.schemeIs("https")) ||
|
||||
// Doesn't have a query string or a ref
|
||||
(!aLocation.query && !aLocation.ref)) {
|
||||
searchingGoogle = false;
|
||||
return;
|
||||
}
|
||||
if (gLastSearchQueue.includes(aLocation.spec)) {
|
||||
// If it's a recent search, just return. We
|
||||
// don't reset searchingGoogle though because
|
||||
// we might still be doing that.
|
||||
return;
|
||||
}
|
||||
let domainInfo = getSearchDomainCodes(aLocation.host);
|
||||
if (!domainInfo) {
|
||||
searchingGoogle = false;
|
||||
return;
|
||||
}
|
||||
|
||||
let queries = new URLSearchParams(aLocation.query);
|
||||
// Yahoo has switched to Unified search so we can get
|
||||
// different codes on the same domain. Hack for now
|
||||
// to allow two different prefixes for codes
|
||||
let code = queries.get(domainInfo.prefix[0]);
|
||||
if (!code && domainInfo.prefix.length > 1) {
|
||||
code = queries.get(domainInfo.prefix[1]);
|
||||
}
|
||||
// Special case Google so we can track searches
|
||||
// without codes from the browser.
|
||||
if (domainInfo.sap == "google") {
|
||||
if (aLocation.filePath == "/search") {
|
||||
gLastSearchQueue.push(aLocation.spec);
|
||||
// Our engine currently sends oe and ie - no one else does
|
||||
if (queries.get("oe") && queries.get("ie")) {
|
||||
sendSaveTelemetryMsg(code ? code : "none", code, "sap");
|
||||
searchingGoogle = true;
|
||||
} else {
|
||||
// The tbm value is the specific type of search (Books, Images, News, etc).
|
||||
// These are referred to as vertical searches.
|
||||
let tbm = queries.get("tbm");
|
||||
if (searchingGoogle) {
|
||||
sendSaveTelemetryMsg(code ? code : "none", code, "follow-on", tbm ? `vertical-${tbm}` : null);
|
||||
} else if (code) {
|
||||
// Trying to do the right thing for back button to existing entries
|
||||
sendSaveTelemetryMsg(code, domainInfo.sap, "follow-on", tbm ? `vertical-${tbm}` : null);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Special case all Google. Otherwise our code can
|
||||
// show up in maps
|
||||
return;
|
||||
}
|
||||
searchingGoogle = false;
|
||||
if (queries.get(domainInfo.search)) {
|
||||
if (domainInfo.codes.includes(code)) {
|
||||
if (domainInfo.reportPrefix &&
|
||||
queries.get(domainInfo.reportPrefix)) {
|
||||
code = queries.get(domainInfo.reportPrefix);
|
||||
}
|
||||
if (queries.get(domainInfo.followOnSearch)) {
|
||||
log(`${aLocation.host} search with code ${code} - Follow on`);
|
||||
sendSaveTelemetryMsg(code, domainInfo.sap, "follow-on");
|
||||
} else {
|
||||
log(`${aLocation.host} search with code ${code} - First search via Firefox`);
|
||||
sendSaveTelemetryMsg(code, domainInfo.sap, "sap");
|
||||
}
|
||||
gLastSearchQueue.push(aLocation.spec);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Parses a cookie string into separate parts.
|
||||
*
|
||||
* @param {String} cookieString The string to parse.
|
||||
* @param {Object} [params] An optional object to append the parameters to.
|
||||
* @return {Object} An object containing the query keys and values.
|
||||
*/
|
||||
function parseCookies(cookieString, params = {}) {
|
||||
var cookies = cookieString.split(/;\s*/);
|
||||
|
||||
for (var i in cookies) {
|
||||
var kvp = cookies[i].split(/=(.+)/);
|
||||
params[kvp[0]] = kvp[1];
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Page load listener to handle loads www.bing.com only.
|
||||
* We have to use a page load listener because we need
|
||||
* to check cookies.
|
||||
* @param {Object} event The page load event.
|
||||
*/
|
||||
function onPageLoad(event) {
|
||||
var doc = event.target;
|
||||
var win = doc.defaultView;
|
||||
if (win != win.top) {
|
||||
return;
|
||||
}
|
||||
var uri = doc.documentURIObject;
|
||||
if (!(uri instanceof Ci.nsIStandardURL) ||
|
||||
(!uri.schemeIs("http") && !uri.schemeIs("https")) ||
|
||||
uri.host != "www.bing.com" ||
|
||||
!doc.location.search ||
|
||||
gLastSearchQueue.includes(uri.spec)) {
|
||||
return;
|
||||
}
|
||||
var queries = new URLSearchParams(doc.location.search.toLowerCase());
|
||||
// For Bing, QBRE form code is used for all follow-on search
|
||||
if (queries.get("form") != "qbre") {
|
||||
return;
|
||||
}
|
||||
if (parseCookies(doc.cookie).SRCHS == "PC=MOZI") {
|
||||
log(`${uri.host} search with code MOZI - Follow on`);
|
||||
sendSaveTelemetryMsg("MOZI", "bing", "follow-on");
|
||||
gLastSearchQueue.push(uri.spec);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a message to the process that added this script to tell it to save
|
||||
* telemetry.
|
||||
*
|
||||
* @param {String} code The codes used for the search engine.
|
||||
* @param {String} sap The SAP code.
|
||||
* @param {String} type The type of search (sap/follow-on).
|
||||
* @param {String} extra Any additional parameters (Optional)
|
||||
*/
|
||||
function sendSaveTelemetryMsg(code, sap, type, extra) {
|
||||
sendAsyncMessage(kSaveTelemetryMsg, {
|
||||
code,
|
||||
sap,
|
||||
type,
|
||||
extra,
|
||||
});
|
||||
}
|
||||
|
||||
addEventListener("DOMContentLoaded", onPageLoad, false);
|
||||
docShell.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebProgress)
|
||||
.addProgressListener(webProgressListener, Ci.nsIWebProgress.NOTIFY_LOCATION);
|
||||
|
||||
let gDisabled = false;
|
||||
|
||||
addMessageListener(kShutdownMsg, () => {
|
||||
if (!gDisabled) {
|
||||
removeEventListener("DOMContentLoaded", onPageLoad, false);
|
||||
docShell.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebProgress)
|
||||
.removeProgressListener(webProgressListener);
|
||||
gDisabled = true;
|
||||
}
|
||||
});
|
|
@ -1,22 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
|
||||
<Description about="urn:mozilla:install-manifest">
|
||||
<em:id>followonsearch@mozilla.com</em:id>
|
||||
<em:name>Follow-on Search Telemetry</em:name>
|
||||
<em:version>0.9.7</em:version>
|
||||
<em:type>2</em:type>
|
||||
<em:bootstrap>true</em:bootstrap>
|
||||
<em:multiprocessCompatible>true</em:multiprocessCompatible>
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
|
||||
<em:minVersion>52.0</em:minVersion>
|
||||
<em:maxVersion>66.*</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
</Description>
|
||||
</RDF>
|
|
@ -1,7 +0,0 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
[features/followonsearch@mozilla.com] chrome.jar:
|
||||
% content followonsearch %content/
|
||||
content/ (content/*)
|
|
@ -1,17 +0,0 @@
|
|||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
with Files("**"):
|
||||
BUG_COMPONENT = ("Firefox", "Search")
|
||||
|
||||
FINAL_TARGET_FILES.features['followonsearch@mozilla.com'] += [
|
||||
'bootstrap.js',
|
||||
'install.rdf',
|
||||
]
|
||||
|
||||
BROWSER_CHROME_MANIFESTS += ['test/browser/browser.ini']
|
||||
|
||||
JAR_MANIFESTS += ['jar.mn']
|
|
@ -1,7 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
"extends": [
|
||||
"plugin:mozilla/browser-test",
|
||||
],
|
||||
};
|
|
@ -1,7 +0,0 @@
|
|||
[DEFAULT]
|
||||
|
||||
[browser_followOnTelemetry.js]
|
||||
support-files =
|
||||
test.html
|
||||
test2.html
|
||||
testEngine.xml
|
|
@ -1,66 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
ChromeUtils.defineModuleGetter(this, "SearchTestUtils",
|
||||
"resource://testing-common/SearchTestUtils.jsm");
|
||||
|
||||
SearchTestUtils.init(Assert, registerCleanupFunction);
|
||||
|
||||
const BASE_URL = "http://mochi.test:8888/browser/browser/extensions/followonsearch/test/browser/";
|
||||
const TEST_ENGINE_BASENAME = "testEngine.xml";
|
||||
|
||||
add_task(async function test_followOnSearchTelemetry() {
|
||||
let engine = await SearchTestUtils.promiseNewSearchEngine(
|
||||
getRootDirectory(gTestPath) + TEST_ENGINE_BASENAME,
|
||||
registerCleanupFunction);
|
||||
let oldCurrentEngine = Services.search.currentEngine;
|
||||
Services.search.currentEngine = engine;
|
||||
|
||||
let histogram = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS");
|
||||
histogram.clear();
|
||||
|
||||
registerCleanupFunction(() => Services.search.currentEngine = oldCurrentEngine);
|
||||
|
||||
await BrowserTestUtils.withNewTab({gBrowser}, async browser => {
|
||||
// Open the initial search page via entering a search on the URL bar.
|
||||
let loadPromise = BrowserTestUtils.waitForLocationChange(gBrowser,
|
||||
`${BASE_URL}test.html?searchm=test&mt=TEST`);
|
||||
|
||||
gURLBar.focus();
|
||||
EventUtils.sendString("test");
|
||||
EventUtils.sendKey("return");
|
||||
|
||||
await loadPromise;
|
||||
|
||||
// Perform a follow-on search, selecting the form in the page.
|
||||
loadPromise = BrowserTestUtils.waitForLocationChange(gBrowser,
|
||||
`${BASE_URL}test2.html?mtfo=followonsearchtest&mt=TEST&m=test`);
|
||||
|
||||
await ContentTask.spawn(browser, null, function() {
|
||||
content.document.getElementById("submit").click();
|
||||
});
|
||||
|
||||
await loadPromise;
|
||||
|
||||
let snapshot;
|
||||
|
||||
// We have to wait for the snapshot to come in, as there's async functionality
|
||||
// in the extension.
|
||||
await TestUtils.waitForCondition(() => {
|
||||
snapshot = histogram.snapshot();
|
||||
return "mochitest.follow-on:unknown:TEST" in snapshot;
|
||||
});
|
||||
Assert.ok("mochitest.follow-on:unknown:TEST" in snapshot,
|
||||
"Histogram should have an entry for the follow-on search.");
|
||||
Assert.deepEqual(snapshot["mochitest.follow-on:unknown:TEST"], {
|
||||
counts: [ 1, 0, 0 ],
|
||||
histogram_type: 4,
|
||||
max: 2,
|
||||
min: 1,
|
||||
ranges: [ 0, 1, 2 ],
|
||||
sum: 1,
|
||||
}, "Histogram should have the correct snapshot data");
|
||||
});
|
||||
});
|
|
@ -1,15 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Follow-on Search Test</title>
|
||||
</head>
|
||||
<body>
|
||||
<form method="get" action="test2.html">
|
||||
<input type="text" name="mtfo" value="followonsearchtest"/>
|
||||
<input type="text" name="mt" value="TEST"/>
|
||||
<input type="text" name="m" value="test"/>
|
||||
<input type="submit" id="submit" value="submit"/>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
|
@ -1,8 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Follow-on Search Test Final Page</title>
|
||||
</head>
|
||||
<body></body>
|
||||
</html>
|
|
@ -1,15 +0,0 @@
|
|||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/"
|
||||
xmlns:moz="http://www.mozilla.org/2006/browser/search/">
|
||||
<ShortName>Mochitest</ShortName>
|
||||
<Description>Mochitest Engine</Description>
|
||||
<InputEncoding>UTF-8</InputEncoding>
|
||||
<Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAABGklEQVQoz2NgGB6AnZ1dUlJSXl4eSDIyMhLW4Ovr%2B%2Fr168uXL69Zs4YoG%2BLi4i5dusTExMTGxsbNzd3f37937976%2BnpmZmagbHR09J49e5YvX66kpATVEBYW9ubNm2nTphkbG7e2tp44cQLIuHfvXm5urpaWFlDKysqqu7v73LlzECMYIiIiHj58mJCQoKKicvXq1bS0NKBgW1vbjh074uPjgeqAXE1NzSdPnvDz84M0AEUvXLgAsW379u1z5swBen3jxo2zZ892cHB4%2BvQp0KlAfwI1cHJyghQFBwfv2rULokFXV%2FfixYu7d%2B8GGqGgoMDKyrpu3br9%2B%2FcDuXl5eVA%2FAEWBfoWHAdAYoNuAYQ0XAeoUERFhGDYAAPoUaT2dfWJuAAAAAElFTkSuQmCC</Image>
|
||||
<Url type="text/html" method="GET" template="http://mochi.test:8888/browser/browser/extensions/followonsearch/test/browser/test.html?search" rel="searchform">
|
||||
<Param name="m" value="{searchTerms}"/>
|
||||
<Param name="mt" value="TEST"/>
|
||||
</Url>
|
||||
</OpenSearchDescription>
|
|
@ -289,6 +289,28 @@ cbindgen = check_prog('CBINDGEN', add_rustup_path('cbindgen'), paths=toolchain_s
|
|||
when=depends(build_project)
|
||||
(lambda build_project: build_project != 'js'))
|
||||
|
||||
|
||||
@depends_if(cbindgen)
|
||||
@checking('cbindgen version')
|
||||
@imports(_from='textwrap', _import='dedent')
|
||||
def cbindgen_version(cbindgen):
|
||||
cbindgen_min_version = Version('0.6.1')
|
||||
|
||||
# cbindgen x.y.z
|
||||
version = Version(check_cmd_output(cbindgen, '--version').strip().split(" ")[1])
|
||||
|
||||
if version < cbindgen_min_version:
|
||||
die(dedent('''\
|
||||
cbindgen version {} is too old. At least version {} is required.
|
||||
|
||||
Please update using 'cargo install cbindgen --force' or running
|
||||
'./mach bootstrap', after removing the existing executable located at
|
||||
{}.
|
||||
'''.format(version, cbindgen_min_version, cbindgen)))
|
||||
|
||||
return version
|
||||
|
||||
|
||||
# Bindgen can use rustfmt to format Rust file, but it's not required.
|
||||
js_option(env='RUSTFMT', nargs=1, help='Path to the rustfmt program')
|
||||
|
||||
|
|
|
@ -747,10 +747,12 @@ CreateTrackInfoWithMIMETypeAndContainerTypeExtraParameters(
|
|||
Maybe<int32_t> maybeWidth = aContainerType.ExtendedType().GetWidth();
|
||||
if (maybeWidth && *maybeWidth > 0) {
|
||||
videoInfo->mImage.width = *maybeWidth;
|
||||
videoInfo->mDisplay.width = *maybeWidth;
|
||||
}
|
||||
Maybe<int32_t> maybeHeight = aContainerType.ExtendedType().GetHeight();
|
||||
if (maybeHeight && *maybeHeight > 0) {
|
||||
videoInfo->mImage.height = *maybeHeight;
|
||||
videoInfo->mDisplay.height = *maybeHeight;
|
||||
}
|
||||
} else if (trackInfo->GetAsAudioInfo()) {
|
||||
AudioInfo* audioInfo = trackInfo->GetAsAudioInfo();
|
||||
|
|
|
@ -208,6 +208,8 @@ public:
|
|||
}
|
||||
mIsCodecSupportAdaptivePlayback =
|
||||
mJavaDecoder->IsAdaptivePlaybackSupported();
|
||||
mIsHardwareAccelerated =
|
||||
mJavaDecoder->IsHardwareAccelerated();
|
||||
return InitPromise::CreateAndResolve(TrackInfo::kVideoTrack, __func__);
|
||||
}
|
||||
|
||||
|
@ -272,12 +274,19 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
bool IsHardwareAccelerated(nsACString& aFailureReason) const override
|
||||
{
|
||||
return mIsHardwareAccelerated;
|
||||
}
|
||||
|
||||
private:
|
||||
const VideoInfo mConfig;
|
||||
GeckoSurface::GlobalRef mSurface;
|
||||
AndroidSurfaceTextureHandle mSurfaceHandle;
|
||||
// Only accessed on reader's task queue.
|
||||
bool mIsCodecSupportAdaptivePlayback = false;
|
||||
// Can be accessed on any thread, but only written on during init.
|
||||
bool mIsHardwareAccelerated = false;
|
||||
// Accessed on mTaskQueue, reader's TaskQueue and Java callback tread.
|
||||
// SimpleMap however is thread-safe, so it's okay to do so.
|
||||
SimpleMap<InputInfo> mInputInfos;
|
||||
|
@ -457,8 +466,8 @@ RemoteDataDecoder::CreateVideoDecoder(const CreateDecoderParams& aParams,
|
|||
MediaFormat::LocalRef format;
|
||||
NS_ENSURE_SUCCESS(
|
||||
MediaFormat::CreateVideoFormat(TranslateMimeType(config.mMimeType),
|
||||
config.mDisplay.width,
|
||||
config.mDisplay.height,
|
||||
config.mImage.width,
|
||||
config.mImage.height,
|
||||
&format),
|
||||
nullptr);
|
||||
|
||||
|
|
|
@ -2530,6 +2530,43 @@ DrawBackgroundColor(nsCSSRendering::ImageLayerClipState& aClipState,
|
|||
aCtx->Restore();
|
||||
}
|
||||
|
||||
static Maybe<nscolor>
|
||||
CalcScrollbarColor(nsIFrame* aFrame, StyleComplexColor nsStyleUI::* aColor)
|
||||
{
|
||||
ComputedStyle* scrollbarStyle = nsLayoutUtils::StyleForScrollbar(aFrame);
|
||||
auto color = scrollbarStyle->StyleUI()->*aColor;
|
||||
if (color.IsAuto()) {
|
||||
return Nothing();
|
||||
}
|
||||
return Some(color.CalcColor(scrollbarStyle));
|
||||
}
|
||||
|
||||
static nscolor
|
||||
GetBackgroundColor(nsIFrame* aFrame, ComputedStyle* aComputedStyle)
|
||||
{
|
||||
Maybe<nscolor> overrideColor = Nothing();
|
||||
switch (aComputedStyle->StyleDisplay()->mAppearance) {
|
||||
case StyleAppearance::ScrollbarthumbVertical:
|
||||
case StyleAppearance::ScrollbarthumbHorizontal:
|
||||
overrideColor =
|
||||
CalcScrollbarColor(aFrame, &nsStyleUI::mScrollbarFaceColor);
|
||||
break;
|
||||
case StyleAppearance::ScrollbarVertical:
|
||||
case StyleAppearance::ScrollbarHorizontal:
|
||||
case StyleAppearance::Scrollcorner:
|
||||
overrideColor =
|
||||
CalcScrollbarColor(aFrame, &nsStyleUI::mScrollbarTrackColor);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (overrideColor.isSome()) {
|
||||
return *overrideColor;
|
||||
}
|
||||
return aComputedStyle->
|
||||
GetVisitedDependentColor(&nsStyleBackground::mBackgroundColor);
|
||||
}
|
||||
|
||||
nscolor
|
||||
nsCSSRendering::DetermineBackgroundColor(nsPresContext* aPresContext,
|
||||
ComputedStyle* aComputedStyle,
|
||||
|
@ -2551,8 +2588,7 @@ nsCSSRendering::DetermineBackgroundColor(nsPresContext* aPresContext,
|
|||
const nsStyleBackground *bg = aComputedStyle->StyleBackground();
|
||||
nscolor bgColor;
|
||||
if (aDrawBackgroundColor) {
|
||||
bgColor = aComputedStyle->
|
||||
GetVisitedDependentColor(&nsStyleBackground::mBackgroundColor);
|
||||
bgColor = GetBackgroundColor(aFrame, aComputedStyle);
|
||||
if (NS_GET_A(bgColor) == 0) {
|
||||
aDrawBackgroundColor = false;
|
||||
}
|
||||
|
|
|
@ -522,6 +522,23 @@ nsIFrame::AddXULPrefSize(nsIFrame* aBox, nsSize& aSize, bool &aWidthSet, bool &a
|
|||
return (aWidthSet && aHeightSet);
|
||||
}
|
||||
|
||||
// This returns the scrollbar width we want to use when either native
|
||||
// theme is disabled, or the native theme claims that it doesn't support
|
||||
// scrollbar.
|
||||
static nscoord
|
||||
GetScrollbarWidthNoTheme(nsIFrame* aBox)
|
||||
{
|
||||
ComputedStyle* scrollbarStyle = nsLayoutUtils::StyleForScrollbar(aBox);
|
||||
switch (scrollbarStyle->StyleUIReset()->mScrollbarWidth) {
|
||||
default:
|
||||
case StyleScrollbarWidth::Auto:
|
||||
return 16 * AppUnitsPerCSSPixel();
|
||||
case StyleScrollbarWidth::Thin:
|
||||
return 8 * AppUnitsPerCSSPixel();
|
||||
case StyleScrollbarWidth::None:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
nsIFrame::AddXULMinSize(nsBoxLayoutState& aState, nsIFrame* aBox, nsSize& aSize,
|
||||
|
@ -548,6 +565,19 @@ nsIFrame::AddXULMinSize(nsBoxLayoutState& aState, nsIFrame* aBox, nsSize& aSize,
|
|||
aSize.height = aState.PresContext()->DevPixelsToAppUnits(size.height);
|
||||
aHeightSet = true;
|
||||
}
|
||||
} else {
|
||||
switch (display->mAppearance) {
|
||||
case StyleAppearance::ScrollbarVertical:
|
||||
aSize.width = GetScrollbarWidthNoTheme(aBox);
|
||||
aWidthSet = true;
|
||||
break;
|
||||
case StyleAppearance::ScrollbarHorizontal:
|
||||
aSize.height = GetScrollbarWidthNoTheme(aBox);
|
||||
aHeightSet = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ interface ICodec {
|
|||
void setCallbacks(in ICodecCallbacks callbacks);
|
||||
boolean configure(in FormatParam format, in GeckoSurface surface, in int flags, in String drmStubId);
|
||||
boolean isAdaptivePlaybackSupported();
|
||||
boolean isHardwareAccelerated();
|
||||
boolean isTunneledPlaybackSupported();
|
||||
void start();
|
||||
void stop();
|
||||
|
|
|
@ -1046,16 +1046,6 @@ public class GeckoAppShell
|
|||
return sScreenDepth;
|
||||
}
|
||||
|
||||
@WrapForJNI(calledFrom = "gecko")
|
||||
private static synchronized void setScreenDepthOverride(int aScreenDepth) {
|
||||
if (sScreenDepth != 0) {
|
||||
Log.e(LOGTAG, "Tried to override screen depth after it's already been set");
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
sScreenDepth = aScreenDepth;
|
||||
}
|
||||
|
||||
@WrapForJNI(calledFrom = "gecko")
|
||||
private static void performHapticFeedback(boolean aIsLongPress) {
|
||||
// Don't perform haptic feedback if a vibration is currently playing,
|
||||
|
|
|
@ -350,6 +350,7 @@ import org.mozilla.gecko.gfx.GeckoSurface;
|
|||
private SamplePool mSamplePool;
|
||||
// Values will be updated after configure called.
|
||||
private volatile boolean mIsAdaptivePlaybackSupported = false;
|
||||
private volatile boolean mIsHardwareAccelerated = false;
|
||||
private boolean mIsTunneledPlaybackSupported = false;
|
||||
|
||||
public synchronized void setCallbacks(ICodecCallbacks callbacks) throws RemoteException {
|
||||
|
@ -399,6 +400,7 @@ import org.mozilla.gecko.gfx.GeckoSurface;
|
|||
Log.w(LOGTAG, "unable to configure " + name + ". Try next.");
|
||||
continue;
|
||||
}
|
||||
mIsHardwareAccelerated = !name.startsWith("OMX.google.");
|
||||
mCodec = codec;
|
||||
mInputProcessor = new InputProcessor();
|
||||
final boolean renderToSurface = surface != null;
|
||||
|
@ -477,6 +479,11 @@ import org.mozilla.gecko.gfx.GeckoSurface;
|
|||
return mIsAdaptivePlaybackSupported;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isHardwareAccelerated() {
|
||||
return mIsHardwareAccelerated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isTunneledPlaybackSupported() {
|
||||
return mIsTunneledPlaybackSupported;
|
||||
|
|
|
@ -191,6 +191,21 @@ public final class CodecProxy {
|
|||
}
|
||||
}
|
||||
|
||||
@WrapForJNI
|
||||
public synchronized boolean isHardwareAccelerated()
|
||||
{
|
||||
if (mRemote == null) {
|
||||
Log.e(LOGTAG, "cannot check isHardwareAccelerated with an ended codec");
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
return mRemote.isHardwareAccelerated();
|
||||
} catch (RemoteException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@WrapForJNI
|
||||
public synchronized boolean isTunneledPlaybackSupported()
|
||||
{
|
||||
|
|
|
@ -490,10 +490,16 @@ BackgroundFileSaver::ProcessStateChange()
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// Now we can update the actual target file name.
|
||||
mActualTarget = renamedTarget;
|
||||
mActualTargetKeepPartial = renamedTargetKeepPartial;
|
||||
// We should not only update the mActualTarget with renameTarget when
|
||||
// they point to the different files.
|
||||
// In this way, if mActualTarget and renamedTarget point to the same file
|
||||
// with different addresses, "CheckCompletion()" will return false forever.
|
||||
}
|
||||
|
||||
// Update mActualTarget with renameTarget,
|
||||
// even if they point to the same file.
|
||||
mActualTarget = renamedTarget;
|
||||
mActualTargetKeepPartial = renamedTargetKeepPartial;
|
||||
}
|
||||
|
||||
// Notify if the target file name actually changed.
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
job-defaults:
|
||||
max-run-time: 1800
|
||||
suite: raptor
|
||||
workdir: /home/cltbld
|
||||
tier:
|
||||
by-test-platform:
|
||||
windows10-64-ccov/.*: 3
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#!/bin/bash
|
||||
set -x -e -v
|
||||
|
||||
# If you update this, make sure to update the minimum version in rust.configure
|
||||
# as well.
|
||||
CBINDGEN_VERSION=v0.6.1
|
||||
TARGET="$1"
|
||||
|
||||
|
|
|
@ -19,6 +19,8 @@ from .taskgraph import TaskGraph
|
|||
from .try_option_syntax import parse_message
|
||||
from .actions import render_actions_json
|
||||
from taskgraph.util.partials import populate_release_history
|
||||
from taskgraph.util.yaml import load_yaml
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
@ -320,8 +322,7 @@ def write_artifact(filename, data):
|
|||
def read_artifact(filename):
|
||||
path = os.path.join(ARTIFACTS_DIR, filename)
|
||||
if filename.endswith('.yml'):
|
||||
with open(path, 'r') as f:
|
||||
return yaml.load(f)
|
||||
return load_yaml(path, filename)
|
||||
elif filename.endswith('.json'):
|
||||
with open(path, 'r') as f:
|
||||
return json.load(f)
|
||||
|
|
|
@ -69,7 +69,7 @@ def make_task_description(config, jobs):
|
|||
'treeherder', {}).get('machine', {}).get('platform', '')
|
||||
treeherder.setdefault('platform',
|
||||
'{}/opt'.format(dep_th_platform))
|
||||
treeherder.setdefault('tier', 3)
|
||||
treeherder.setdefault('tier', 2)
|
||||
treeherder.setdefault('kind', 'build')
|
||||
label = job['label']
|
||||
description = (
|
||||
|
|
|
@ -337,7 +337,8 @@ def mozharness_test_on_native_engine(config, job, taskdesc):
|
|||
if test['max-run-time']:
|
||||
worker['max-run-time'] = test['max-run-time']
|
||||
|
||||
worker['env'] = env = {
|
||||
env = worker.setdefault('env', {})
|
||||
env.update({
|
||||
'GECKO_HEAD_REPOSITORY': config.params['head_repository'],
|
||||
'GECKO_HEAD_REV': config.params['head_rev'],
|
||||
'MOZHARNESS_CONFIG': ' '.join(mozharness['config']),
|
||||
|
@ -351,7 +352,7 @@ def mozharness_test_on_native_engine(config, job, taskdesc):
|
|||
"MOZ_HIDE_RESULTS_TABLE": '1',
|
||||
"MOZ_NODE_PATH": "/usr/local/bin/node",
|
||||
'MOZ_AUTOMATION': '1',
|
||||
}
|
||||
})
|
||||
# talos tests don't need Xvfb
|
||||
if is_talos:
|
||||
env['NEED_XVFB'] = 'false'
|
||||
|
|
|
@ -146,6 +146,9 @@ test_description_schema = Schema({
|
|||
'test-platform',
|
||||
basestring),
|
||||
|
||||
# base work directory used to set up the task.
|
||||
Optional('workdir'): basestring,
|
||||
|
||||
# the name by which this test suite is addressed in try syntax; defaults to
|
||||
# the test-name. This will translate to the `unittest_try_name` or
|
||||
# `talos_try_name` attribute.
|
||||
|
@ -1097,6 +1100,9 @@ def make_job_description(config, tests):
|
|||
run['using'] = 'mozharness-test'
|
||||
run['test'] = test
|
||||
|
||||
if 'workdir' in test:
|
||||
run['workdir'] = test.pop('workdir')
|
||||
|
||||
jobdesc['worker-type'] = test.pop('worker-type')
|
||||
if test.get('fetches'):
|
||||
jobdesc['fetches'] = test.pop('fetches')
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
import os
|
||||
from distutils.spawn import find_executable
|
||||
|
||||
import mozfile
|
||||
|
||||
ARTIFACT_URL = 'https://queue.taskcluster.net/v1/task/{task}/artifacts/{artifact}'
|
||||
|
||||
|
||||
class FetchesMixin(object):
|
||||
"""Utility class to download artifacts via `MOZ_FETCHES` and the
|
||||
`fetch-content` script."""
|
||||
|
||||
@property
|
||||
def fetch_script(self):
|
||||
if getattr(self, '_fetch_script', None):
|
||||
return self._fetch_script
|
||||
|
||||
self._fetch_script = find_executable('fetch-content')
|
||||
if not self._fetch_script and 'GECKO_PATH' in os.environ:
|
||||
self._fetch_script = os.path.join(os.environ['GECKO_PATH'],
|
||||
'taskcluster', 'script', 'misc', 'fetch-content')
|
||||
return self._fetch_script
|
||||
|
||||
def fetch_content(self):
|
||||
if not os.environ.get('MOZ_FETCHES'):
|
||||
self.warning('no fetches to download')
|
||||
return
|
||||
|
||||
fetches = os.environ['MOZ_FETCHES'].split()
|
||||
|
||||
if not self.fetch_script or not os.path.isfile(self.fetch_script):
|
||||
self.warning("fetch-content script not found, downloading manually")
|
||||
self._download_fetches(fetches)
|
||||
return
|
||||
|
||||
cmd = [self.fetch_script, 'task-artifacts'] + fetches
|
||||
self.run_command(cmd, env=os.environ, throw_exception=True)
|
||||
|
||||
def _download_fetches(self, fetches):
|
||||
# TODO: make sure fetch-content script is available everywhere
|
||||
# so this isn't needed
|
||||
for word in fetches:
|
||||
artifact, task = word.split('@', 1)
|
||||
extdir = os.environ['MOZ_FETCHES_DIR']
|
||||
|
||||
if '>' in artifact:
|
||||
artifact, subdir = artifact.rsplit('>', 1)
|
||||
extdir = os.path.join(extdir, subdir)
|
||||
|
||||
url = ARTIFACT_URL.format(artifact=artifact, task=task)
|
||||
self.download_file(url)
|
||||
|
||||
filename = os.path.basename(artifact)
|
||||
mozfile.extract(filename, extdir)
|
||||
os.remove(filename)
|
|
@ -8,7 +8,6 @@ import os
|
|||
import posixpath
|
||||
import shutil
|
||||
import sys
|
||||
import tarfile
|
||||
import tempfile
|
||||
import zipfile
|
||||
import uuid
|
||||
|
@ -144,31 +143,14 @@ class CodeCoverageMixin(SingleTestMixin):
|
|||
self.java_coverage_output_path = os.path.join(tempfile.mkdtemp(),
|
||||
'junit-coverage.ec')
|
||||
|
||||
def _download_grcov(self):
|
||||
fetches_dir = os.environ.get('MOZ_FETCHES_DIR')
|
||||
if fetches_dir and os.path.isfile(os.path.join(fetches_dir, 'grcov')):
|
||||
self.grcov_dir = fetches_dir
|
||||
else:
|
||||
# Create the grcov directory, then download it.
|
||||
# TODO: use the fetch-content script to download artifacts.
|
||||
self.grcov_dir = tempfile.mkdtemp()
|
||||
ARTIFACT_URL = 'https://queue.taskcluster.net/v1/task/{task}/artifacts/{artifact}'
|
||||
for word in os.getenv('MOZ_FETCHES').split():
|
||||
artifact, task = word.split('@', 1)
|
||||
filename = os.path.basename(artifact)
|
||||
url = ARTIFACT_URL.format(artifact=artifact, task=task)
|
||||
self.download_file(url, parent_dir=self.grcov_dir)
|
||||
|
||||
with tarfile.open(os.path.join(self.grcov_dir, filename), 'r') as tar:
|
||||
tar.extractall(self.grcov_dir)
|
||||
os.remove(os.path.join(self.grcov_dir, filename))
|
||||
|
||||
@PostScriptAction('download-and-extract')
|
||||
def setup_coverage_tools(self, action, success=None):
|
||||
if not self.code_coverage_enabled and not self.java_code_coverage_enabled:
|
||||
return
|
||||
|
||||
self._download_grcov()
|
||||
self.grcov_dir = os.environ['MOZ_FETCHES_DIR']
|
||||
if not os.path.isfile(os.path.join(self.grcov_dir, 'grcov')):
|
||||
self.fetch_content()
|
||||
|
||||
if self.code_coverage_enabled:
|
||||
self._setup_cpp_js_coverage_tools()
|
||||
|
|
|
@ -13,8 +13,10 @@ import sys
|
|||
import mozinfo
|
||||
from manifestparser import TestManifest
|
||||
|
||||
from mozharness.mozilla.fetches import FetchesMixin
|
||||
|
||||
class SingleTestMixin(object):
|
||||
|
||||
class SingleTestMixin(FetchesMixin):
|
||||
"""Utility functions for per-test testing like test verification and per-test coverage."""
|
||||
|
||||
def __init__(self):
|
||||
|
|
|
@ -299,6 +299,8 @@ class Raptor(TestingMixin, MercurialScript, CodeCoverageMixin):
|
|||
# clobber defined in BaseScript
|
||||
|
||||
def download_and_extract(self, extract_dirs=None, suite_categories=None):
|
||||
if 'MOZ_FETCHES' in os.environ:
|
||||
self.fetch_content()
|
||||
return super(Raptor, self).download_and_extract(
|
||||
suite_categories=['common', 'raptor']
|
||||
)
|
||||
|
|
|
@ -20,6 +20,7 @@ from mozharness.base.python import (
|
|||
virtualenv_config_options,
|
||||
)
|
||||
from mozharness.mozilla.automation import AutomationMixin, TBPL_WARNING
|
||||
from mozharness.mozilla.fetches import FetchesMixin
|
||||
from mozharness.mozilla.structuredlog import StructuredOutputParser
|
||||
from mozharness.mozilla.testing.unittest import DesktopUnittestOutputParser
|
||||
from mozharness.mozilla.testing.try_tools import TryToolsMixin, try_config_options
|
||||
|
@ -102,7 +103,7 @@ testing_config_options = [
|
|||
|
||||
# TestingMixin {{{1
|
||||
class TestingMixin(VirtualenvMixin, AutomationMixin, ResourceMonitoringMixin,
|
||||
TooltoolMixin, TryToolsMixin, VerifyToolsMixin):
|
||||
TooltoolMixin, TryToolsMixin, VerifyToolsMixin, FetchesMixin):
|
||||
"""
|
||||
The steps to identify + download the proper bits for [browser] unit
|
||||
tests and Talos.
|
||||
|
|
|
@ -11,6 +11,9 @@ ChromeUtils.import("resource://gre/modules/ActorManagerParent.jsm");
|
|||
ChromeUtils.import("resource://gre/modules/ExtensionUtils.jsm");
|
||||
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
// Windowless browsers can create documents that rely on XUL Custom Elements:
|
||||
ChromeUtils.import("resource://gre/modules/CustomElementsListener.jsm", null);
|
||||
|
||||
ChromeUtils.defineModuleGetter(this, "AddonManager",
|
||||
"resource://gre/modules/AddonManager.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "AddonTestUtils",
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
// Set up Custom Elements for XUL and XHTML documents before anything else
|
||||
// happens. Anything loaded here should be considered part of core XUL functionality.
|
||||
// Any window-specific elements can be registered via <script> tags at the
|
||||
// top of individual documents.
|
||||
Services.obs.addObserver({
|
||||
observe(doc) {
|
||||
if (doc.nodePrincipal.isSystemPrincipal && (
|
||||
doc.contentType == "application/vnd.mozilla.xul+xml" ||
|
||||
doc.contentType == "application/xhtml+xml"
|
||||
)) {
|
||||
Services.scriptloader.loadSubScript(
|
||||
"chrome://global/content/customElements.js", doc.ownerGlobal);
|
||||
}
|
||||
}
|
||||
}, "document-element-inserted");
|
|
@ -60,8 +60,8 @@ MainProcessSingleton.prototype = {
|
|||
observe(subject, topic, data) {
|
||||
switch (topic) {
|
||||
case "app-startup": {
|
||||
ChromeUtils.import("resource://gre/modules/CustomElementsListener.jsm", null);
|
||||
Services.obs.addObserver(this, "xpcom-shutdown");
|
||||
Services.obs.addObserver(this, "document-element-inserted");
|
||||
|
||||
// Load this script early so that console.* is initialized
|
||||
// before other frame scripts.
|
||||
|
@ -72,24 +72,8 @@ MainProcessSingleton.prototype = {
|
|||
break;
|
||||
}
|
||||
|
||||
case "document-element-inserted":
|
||||
// Set up Custom Elements for XUL and XHTML documents before anything else
|
||||
// happens. Anything loaded here should be considered part of core XUL functionality.
|
||||
// Any window-specific elements can be registered via <script> tags at the
|
||||
// top of individual documents.
|
||||
const doc = subject;
|
||||
if (doc.nodePrincipal.isSystemPrincipal && (
|
||||
doc.contentType == "application/vnd.mozilla.xul+xml" ||
|
||||
doc.contentType == "application/xhtml+xml"
|
||||
)) {
|
||||
Services.scriptloader.loadSubScript(
|
||||
"chrome://global/content/customElements.js", doc.ownerGlobal);
|
||||
}
|
||||
break;
|
||||
|
||||
case "xpcom-shutdown":
|
||||
Services.mm.removeMessageListener("Search:AddEngine", this.addSearchEngine);
|
||||
Services.obs.removeObserver(this, "document-element-inserted");
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
|
|
@ -12,3 +12,7 @@ EXTRA_COMPONENTS += [
|
|||
'MainProcessSingleton.js',
|
||||
'ProcessSingleton.manifest',
|
||||
]
|
||||
|
||||
EXTRA_JS_MODULES += [
|
||||
'CustomElementsListener.jsm',
|
||||
]
|
||||
|
|
|
@ -4,43 +4,52 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
// <video> is used for top-level audio documents as well
|
||||
let videoElement = document.getElementsByTagName("video")[0];
|
||||
// Hide our variables from the web content, even though the spec allows them
|
||||
// (and the DOM) to be accessible (see bug 1474832)
|
||||
{
|
||||
// <video> is used for top-level audio documents as well
|
||||
let videoElement = document.getElementsByTagName("video")[0];
|
||||
|
||||
// Redirect focus to the video element whenever the document receives
|
||||
// focus.
|
||||
document.addEventListener("focus", (e) => {
|
||||
// We don't want to retarget focus if it goes to the controls in
|
||||
// the video element. Because they're anonymous content, the target
|
||||
// will be the video element in that case. Avoid calling .focus()
|
||||
// for those events:
|
||||
if (e.target == videoElement) {
|
||||
return;
|
||||
}
|
||||
videoElement.focus();
|
||||
}, true);
|
||||
|
||||
// Handle fullscreen mode
|
||||
document.addEventListener("keypress", ev => {
|
||||
// Maximize the standalone video when pressing F11,
|
||||
// but ignore audio elements
|
||||
if (ev.key == "F11" && videoElement.videoWidth != 0 && videoElement.videoHeight != 0) {
|
||||
// If we're in browser fullscreen mode, it means the user pressed F11
|
||||
// while browser chrome or another tab had focus.
|
||||
// Don't break leaving that mode, so do nothing here.
|
||||
if (window.fullScreen) {
|
||||
let setFocusToVideoElement = function(e) {
|
||||
// We don't want to retarget focus if it goes to the controls in
|
||||
// the video element. Because they're anonymous content, the target
|
||||
// will be the video element in that case. Avoid calling .focus()
|
||||
// for those events:
|
||||
if (e && e.target == videoElement) {
|
||||
return;
|
||||
}
|
||||
videoElement.focus();
|
||||
};
|
||||
|
||||
// If we're not in browser fullscreen mode, prevent entering into that,
|
||||
// so we don't end up there after pressing Esc.
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
// Redirect focus to the video element whenever the document receives
|
||||
// focus.
|
||||
document.addEventListener("focus", setFocusToVideoElement, true);
|
||||
|
||||
if (!document.mozFullScreenElement) {
|
||||
videoElement.mozRequestFullScreen();
|
||||
} else {
|
||||
document.mozCancelFullScreen();
|
||||
// Focus on the video in the newly created document.
|
||||
setFocusToVideoElement();
|
||||
|
||||
// Handle fullscreen mode
|
||||
document.addEventListener("keypress", ev => {
|
||||
// Maximize the standalone video when pressing F11,
|
||||
// but ignore audio elements
|
||||
if (ev.key == "F11" && videoElement.videoWidth != 0 && videoElement.videoHeight != 0) {
|
||||
// If we're in browser fullscreen mode, it means the user pressed F11
|
||||
// while browser chrome or another tab had focus.
|
||||
// Don't break leaving that mode, so do nothing here.
|
||||
if (window.fullScreen) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If we're not in browser fullscreen mode, prevent entering into that,
|
||||
// so we don't end up there after pressing Esc.
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
|
||||
if (!document.mozFullScreenElement) {
|
||||
videoElement.mozRequestFullScreen();
|
||||
} else {
|
||||
document.mozCancelFullScreen();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -24,6 +24,9 @@ function getMediaElement(aWindow) {
|
|||
var popup = window.open("seek_with_sound.ogg");
|
||||
popup.addEventListener("load", function() {
|
||||
var video = getMediaElement(popup);
|
||||
|
||||
is(popup.document.activeElement, video, "Document should load with focus moved to the video element.");
|
||||
|
||||
if (!video.paused)
|
||||
runTestVideo(video);
|
||||
else {
|
||||
|
@ -52,6 +55,9 @@ function runTestAudioPre() {
|
|||
popup = window.open("audio.ogg");
|
||||
popup.addEventListener("load", function() {
|
||||
var audio = getMediaElement(popup);
|
||||
|
||||
is(popup.document.activeElement, audio, "Document should load with focus moved to the video element.");
|
||||
|
||||
if (!audio.paused)
|
||||
runTestAudio(audio);
|
||||
else {
|
||||
|
|
|
@ -1878,7 +1878,10 @@ var gHeader = {
|
|||
|
||||
let browser = getBrowserElement();
|
||||
let chromewin = browser.ownerGlobal;
|
||||
chromewin.openLinkIn(url, "tab", {fromChrome: true});
|
||||
chromewin.openLinkIn(url, "tab", {
|
||||
fromChrome: true,
|
||||
triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal({}),
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -587,11 +587,6 @@ nsAppShell::Observe(nsISupports* aSubject,
|
|||
|
||||
} else if (!strcmp(aTopic, "profile-after-change")) {
|
||||
if (jni::IsAvailable()) {
|
||||
// See if we want to force 16-bit color before doing anything
|
||||
if (Preferences::GetBool("gfx.android.rgb16.force", false)) {
|
||||
java::GeckoAppShell::SetScreenDepthOverride(16);
|
||||
}
|
||||
|
||||
java::GeckoThread::SetState(
|
||||
java::GeckoThread::State::PROFILE_READY());
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче