Merge mozilla-central to b2g-inbound

This commit is contained in:
Carsten "Tomcat" Book 2015-06-16 17:01:53 +02:00
Родитель 3a1059fafd 56a152e92c
Коммит d53814a451
258 изменённых файлов: 3689 добавлений и 5841 удалений

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

@ -1378,6 +1378,7 @@ pref("devtools.webide.enabled", true);
pref("devtools.toolbox.footer.height", 250);
pref("devtools.toolbox.sidebar.width", 500);
pref("devtools.toolbox.host", "bottom");
pref("devtools.toolbox.previousHost", "side");
pref("devtools.toolbox.selectedTool", "webconsole");
pref("devtools.toolbox.toolbarSpec", '["splitconsole", "paintflashing toggle","tilt toggle","scratchpad","resize toggle","eyedropper","screenshot --fullpage", "rulers"]');
pref("devtools.toolbox.sideEnabled", true);

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

@ -1241,14 +1241,9 @@
<svg:svg height="0">
#include tab-shape.inc.svg
#if defined(XP_UNIX) && !defined(XP_MACOSX)
<svg:clipPath id="urlbar-clip-path" clipPathUnits="userSpaceOnUse">
<svg:path d="m 1,-5 l 0,50 l 10000,0 l 0,-50 z"/>
</svg:clipPath>
#endif
<svg:clipPath id="urlbar-back-button-clip-path" clipPathUnits="userSpaceOnUse">
#ifndef XP_MACOSX
<svg:path d="m 1,-5 l 0,7.8 c 2.5,3.2 4,6.2 4,10.2 c 0,4 -1.5,7 -4,10 l 0,22 l 10000,0 l 0,-50 l -10000,0 z"/>
<svg:path d="m 1,-5 l 0,7.8 c 2.5,3.2 4,6.2 4,10.2 c 0,4 -1.5,7 -4,10 l 0,22l10000,0 l 0,-50 l -10000,0 z"/>
#else
<svg:path d="M -11,-5 a 16 16 0 0 1 0,34 l 10000,0 l 0,-34 l -10000,0 z"/>
#endif

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

@ -102,12 +102,15 @@ let handleContentContextMenu = function (event) {
.getInterface(Ci.nsIDOMWindowUtils)
.outerWindowID;
let disableSetDesktopBg = null;
// Media related cache info parent needs for saving
let contentType = null;
let contentDisposition = null;
if (event.target.nodeType == Ci.nsIDOMNode.ELEMENT_NODE &&
event.target instanceof Ci.nsIImageLoadingContent &&
event.target.currentURI) {
disableSetDesktopBg = disableSetDesktopBackground(event.target);
try {
let imageCache =
Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
@ -148,7 +151,7 @@ let handleContentContextMenu = function (event) {
{ editFlags, spellInfo, customMenuItems, addonInfo,
principal, docLocation, charSet, baseURI, referrer,
referrerPolicy, contentType, contentDisposition,
frameOuterWindowID, selectionInfo },
frameOuterWindowID, selectionInfo, disableSetDesktopBg },
{ event, popupNode: event.target });
}
else {
@ -169,6 +172,7 @@ let handleContentContextMenu = function (event) {
contentType: contentType,
contentDisposition: contentDisposition,
selectionInfo: selectionInfo,
disableSetDesktopBackground: disableSetDesktopBg,
};
}
}
@ -753,3 +757,52 @@ addMessageListener("ContextMenu:SearchFieldBookmarkData", (message) => {
sendAsyncMessage("ContextMenu:SearchFieldBookmarkData:Result",
{ spec, title, description, postData, charset });
});
function disableSetDesktopBackground(aTarget) {
// Disable the Set as Desktop Background menu item if we're still trying
// to load the image or the load failed.
if (!(aTarget instanceof Ci.nsIImageLoadingContent))
return true;
if (("complete" in aTarget) && !aTarget.complete)
return true;
if (aTarget.currentURI.schemeIs("javascript"))
return true;
let request = aTarget.QueryInterface(Ci.nsIImageLoadingContent)
.getRequest(Ci.nsIImageLoadingContent.CURRENT_REQUEST);
if (!request)
return true;
return false;
}
addMessageListener("ContextMenu:SetAsDesktopBackground", (message) => {
let target = message.objects.target;
// Paranoia: check disableSetDesktopBackground again, in case the
// image changed since the context menu was initiated.
let disable = disableSetDesktopBackground(target);
if (!disable) {
try {
BrowserUtils.urlSecurityCheck(target.currentURI.spec, target.ownerDocument.nodePrincipal);
let canvas = content.document.createElement("canvas");
canvas.width = target.naturalWidth;
canvas.height = target.naturalHeight;
let ctx = canvas.getContext("2d");
ctx.drawImage(target, 0, 0);
let dataUrl = canvas.toDataURL();
sendAsyncMessage("ContextMenu:SetAsDesktopBackground:Result",
{ dataUrl });
}
catch (e) {
Cu.reportError(e);
disable = true;
}
}
if (disable)
sendAsyncMessage("ContextMenu:SetAsDesktopBackground:Result", { disable });
});

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

@ -241,7 +241,7 @@ nsContextMenu.prototype = {
if (haveSetDesktopBackground && this.onLoadedImage) {
document.getElementById("context-setDesktopBackground")
.disabled = this.disableSetDesktopBackground();
.disabled = gContextMenuContentData.disableSetDesktopBackground;
}
// Reload image depends on an image that's not fully loaded
@ -1134,60 +1134,49 @@ nsContextMenu.prototype = {
referrerURI: gContextMenuContentData.documentURIObject });
},
disableSetDesktopBackground: function() {
// Disable the Set as Desktop Background menu item if we're still trying
// to load the image or the load failed.
if (!(this.target instanceof Ci.nsIImageLoadingContent))
return true;
if (("complete" in this.target) && !this.target.complete)
return true;
if (this.target.currentURI.schemeIs("javascript"))
return true;
var request = this.target
.QueryInterface(Ci.nsIImageLoadingContent)
.getRequest(Ci.nsIImageLoadingContent.CURRENT_REQUEST);
if (!request)
return true;
return false;
},
setDesktopBackground: function() {
// Paranoia: check disableSetDesktopBackground again, in case the
// image changed since the context menu was initiated.
if (this.disableSetDesktopBackground())
return;
let mm = this.browser.messageManager;
var doc = this.target.ownerDocument;
urlSecurityCheck(this.target.currentURI.spec, this.principal);
mm.sendAsyncMessage("ContextMenu:SetAsDesktopBackground", null,
{ target: this.target });
// Confirm since it's annoying if you hit this accidentally.
const kDesktopBackgroundURL =
"chrome://browser/content/setDesktopBackground.xul";
let onMessage = (message) => {
mm.removeMessageListener("ContextMenu:SetAsDesktopBackground:Result",
onMessage);
if (message.data.disable)
return;
let image = document.createElementNS('http://www.w3.org/1999/xhtml', 'img');
image.src = message.data.dataUrl;
// Confirm since it's annoying if you hit this accidentally.
const kDesktopBackgroundURL =
"chrome://browser/content/setDesktopBackground.xul";
#ifdef XP_MACOSX
// On Mac, the Set Desktop Background window is not modal.
// Don't open more than one Set Desktop Background window.
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
.getService(Components.interfaces.nsIWindowMediator);
var dbWin = wm.getMostRecentWindow("Shell:SetDesktopBackground");
if (dbWin) {
dbWin.gSetBackground.init(this.target);
dbWin.focus();
}
else {
openDialog(kDesktopBackgroundURL, "",
"centerscreen,chrome,dialog=no,dependent,resizable=no",
this.target);
}
// On Mac, the Set Desktop Background window is not modal.
// Don't open more than one Set Desktop Background window.
const wm = Cc["@mozilla.org/appshell/window-mediator;1"].
getService(Ci.nsIWindowMediator);
let dbWin = wm.getMostRecentWindow("Shell:SetDesktopBackground");
if (dbWin) {
dbWin.gSetBackground.init(image);
dbWin.focus();
}
else {
openDialog(kDesktopBackgroundURL, "",
"centerscreen,chrome,dialog=no,dependent,resizable=no",
image);
}
#else
// On non-Mac platforms, the Set Wallpaper dialog is modal.
openDialog(kDesktopBackgroundURL, "",
"centerscreen,chrome,dialog,modal,dependent",
this.target);
// On non-Mac platforms, the Set Wallpaper dialog is modal.
openDialog(kDesktopBackgroundURL, "",
"centerscreen,chrome,dialog,modal,dependent",
image);
#endif
};
mm.addMessageListener("ContextMenu:SetAsDesktopBackground:Result", onMessage);
},
// Save URL of clicked-on frame.
@ -1298,7 +1287,9 @@ nsContextMenu.prototype = {
}
}
// set up a channel to do the saving
// setting up a new channel for 'right click - save link as ...'
// which should be treated the same way as a toplevel load, hence
// we use TYPE_DOCUMENT, see also bug: 1136055
var ioService = Cc["@mozilla.org/network/io-service;1"].
getService(Ci.nsIIOService);
var channel = ioService.newChannelFromURI2(makeURI(linkURL),
@ -1306,7 +1297,7 @@ nsContextMenu.prototype = {
this.principal, // aLoadingPrincipal
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER);
Ci.nsIContentPolicy.TYPE_DOCUMENT);
if (linkDownload)
channel.contentDispositionFilename = linkDownload;
if (channel instanceof Ci.nsIPrivateBrowsingChannel) {

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

@ -3890,6 +3890,7 @@
contentDisposition: aMessage.data.contentDisposition,
frameOuterWindowID: aMessage.data.frameOuterWindowID,
selectionInfo: aMessage.data.selectionInfo,
disableSetDesktopBackground: aMessage.data.disableSetDesktopBg,
};
let popup = browser.ownerDocument.getElementById("contentAreaContextMenu");
let event = gContextMenuContentData.event;

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

@ -137,7 +137,7 @@ skip-if = e10s # Bug 1101993 - times out for unknown reasons when run in the dir
[browser_autocomplete_oldschool_wrap.js]
[browser_autocomplete_tag_star_visibility.js]
[browser_backButtonFitts.js]
skip-if = os != "win" # The Fitts Law back button is only supported on Windows (bug 571454)
skip-if = os == "mac" # The Fitt's Law back button is not supported on OS X
[browser_beforeunload_duplicate_dialogs.js]
skip-if = e10s # bug 967873 means permitUnload doesn't work in e10s mode
[browser_blob-channelname.js]

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

@ -36,10 +36,19 @@ add_task(function* test_reader_button() {
is_element_hidden(readerButton, "Reader mode button is not present on a new tab");
// Point tab to a test page that is not reader-able due to hidden nodes.
let url = TEST_PATH + "readerModeArticleHiddenNodes.html";
yield promiseTabLoadEvent(tab, url);
yield ContentTask.spawn(tab.linkedBrowser, "", function() {
return ContentTaskUtils.waitForEvent(content, "MozAfterPaint");
let paintPromise = ContentTask.spawn(tab.linkedBrowser, "", function() {
return new Promise(resolve => {
addEventListener("DOMContentLoaded", function onDCL() {
removeEventListener("DOMContentLoaded", onDCL);
addEventListener("MozAfterPaint", function onPaint() {
removeEventListener("MozAfterPaint", onPaint);
resolve();
});
});
});
});
tab.linkedBrowser.loadURI(url);
yield paintPromise;
is_element_hidden(readerButton, "Reader mode button is still not present on tab with unreadable content.");
});

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

@ -1,267 +1,272 @@
<html>
<head>
<meta charset="utf-8">
<script type="application/javascript;version=1.7"
src="healthreport_pingData.js">
</script>
<script type="application/javascript;version=1.7">
function init() {
window.addEventListener("message", function process(e) {
// The init function of abouthealth.js schedules an initial payload event,
// which will be sent after the payload data has been collected. This extra
// event can cause unexpected successes/failures in this test, so we wait
// for the extra event to arrive here before progressing with the actual
// test.
if (e.data.type == "payload") {
window.removeEventListener("message", process, false);
window.addEventListener("message", doTest, false);
doTest();
}
}, false);
}
function checkSubmissionValue(payload, expectedValue) {
return payload.enabled == expectedValue;
}
function validatePayload(payload) {
payload = JSON.parse(payload);
// xxxmpc - this is some pretty low-bar validation, but we have plenty of tests of that API elsewhere
if (!payload.thisPingDate)
return false;
return true;
}
function isArray(arg) {
return Object.prototype.toString.call(arg) === '[object Array]';
}
function writeDiagnostic(text) {
let node = document.createTextNode(text);
let br = document.createElement("br");
document.body.appendChild(node);
document.body.appendChild(br);
}
function validateCurrentTelemetryEnvironment(data) {
// Simple check for now: check that the received object has the expected
// top-level properties.
const expectedKeys = ["profile", "settings", "system", "build", "partner", "addons"];
return expectedKeys.every(key => (key in data));
}
function validateCurrentTelemetryPingData(ping) {
// Simple check for now: check that the received object has the expected
// top-level properties and that the type and reason match.
const expectedKeys = ["environment", "clientId", "payload", "application",
"version", "type", "id"];
return expectedKeys.every(key => (key in ping)) &&
(ping.type == "main") &&
("info" in ping.payload) &&
("reason" in ping.payload.info) &&
(ping.payload.info.reason == "gather-subsession-payload");
}
function validateTelemetryPingList(list) {
if (!isArray(list)) {
console.log("Telemetry ping list is not an array.");
return false;
}
if (list.length != TEST_PINGS.length) {
console.log("Telemetry ping length is not correct.");
return false;
}
let valid = true;
for (let i=0; i<list.length; ++i) {
let received = list[i];
let expected = TEST_PINGS[i];
if (received.type != expected.type ||
received.timestampCreated != expected.date.getTime()) {
writeDiagnostic("Telemetry ping " + i + " does not match.");
writeDiagnostic("Expected: " + JSON.stringify(expected));
writeDiagnostic("Received: " + JSON.stringify(received));
valid = false;
} else {
writeDiagnostic("Telemetry ping " + i + " matches.");
}
}
return true;
}
function validateTelemetryPingData(expected, received) {
const receivedDate = new Date(received.creationDate);
if (received.id != expected.id ||
received.type != expected.type ||
receivedDate.getTime() != expected.date.getTime()) {
writeDiagnostic("Telemetry ping data for " + expected.id + " doesn't match.");
writeDiagnostic("Expected: " + JSON.stringify(expected));
writeDiagnostic("Received: " + JSON.stringify(received));
return false;
}
writeDiagnostic("Telemetry ping data for " + expected.id + " matched.");
return true;
}
var tests = [
{
info: "Checking initial value is enabled",
event: "RequestCurrentPrefs",
payloadType: "prefs",
validateResponse: function(payload) {
return checkSubmissionValue(payload, true);
},
},
{
info: "Verifying disabling works",
event: "DisableDataSubmission",
payloadType: "prefs",
validateResponse: function(payload) {
return checkSubmissionValue(payload, false);
},
},
{
info: "Verifying we're still disabled",
event: "RequestCurrentPrefs",
payloadType: "prefs",
validateResponse: function(payload) {
return checkSubmissionValue(payload, false);
},
},
{
info: "Verifying we can get a payload while submission is disabled",
event: "RequestCurrentPayload",
payloadType: "payload",
validateResponse: function(payload) {
return validatePayload(payload);
},
},
{
info: "Verifying enabling works",
event: "EnableDataSubmission",
payloadType: "prefs",
validateResponse: function(payload) {
return checkSubmissionValue(payload, true);
},
},
{
info: "Verifying we're still re-enabled",
event: "RequestCurrentPrefs",
payloadType: "prefs",
validateResponse: function(payload) {
return checkSubmissionValue(payload, true);
},
},
{
info: "Verifying we can get a payload after re-enabling",
event: "RequestCurrentPayload",
payloadType: "payload",
validateResponse: function(payload) {
return validatePayload(payload);
},
},
{
info: "Verifying that we can get the current Telemetry environment data",
event: "RequestCurrentEnvironment",
payloadType: "telemetry-current-environment-data",
validateResponse: function(payload) {
return validateCurrentTelemetryEnvironment(payload);
},
},
{
info: "Verifying that we can get the current Telemetry ping data",
event: "RequestCurrentPingData",
payloadType: "telemetry-current-ping-data",
validateResponse: function(payload) {
return validateCurrentTelemetryPingData(payload);
},
},
{
info: "Verifying that we get the proper Telemetry ping list",
event: "RequestTelemetryPingList",
payloadType: "telemetry-ping-list",
validateResponse: function(payload) {
// Validate the ping list
if (!validateTelemetryPingList(payload)) {
return false;
}
// Now that we received the ping ids, set up additional test tasks
// that check loading the individual pings.
for (let i=0; i<TEST_PINGS.length; ++i) {
TEST_PINGS[i].id = payload[i].id;
tests.push({
info: "Verifying that we can get the proper Telemetry ping data #" + (i + 1),
event: "RequestTelemetryPingData",
eventData: { id: TEST_PINGS[i].id },
payloadType: "telemetry-ping-data",
validateResponse: function(payload) {
return validateTelemetryPingData(TEST_PINGS[i], payload.pingData);
},
});
}
return true;
},
},
];
var currentTest = -1;
function doTest(evt) {
if (evt) {
if (currentTest < 0 || !evt.data.content)
return; // not yet testing
var test = tests[currentTest];
if (evt.data.type != test.payloadType)
return; // skip unrequested events
var error = JSON.stringify(evt.data.content);
var pass = false;
try {
pass = test.validateResponse(evt.data.content)
} catch (e) {}
reportResult(test.info, pass, error);
}
// start the next test if there are any left
if (tests[++currentTest])
sendToBrowser(tests[currentTest].event, tests[currentTest].eventData);
else
reportFinished();
}
function reportResult(info, pass, error) {
var data = {type: "testResult", info: info, pass: pass, error: error};
var event = new CustomEvent("FirefoxHealthReportTestResponse", {detail: {data: data}, bubbles: true});
document.dispatchEvent(event);
}
function reportFinished(cmd) {
var data = {type: "testsComplete", count: tests.length};
var event = new CustomEvent("FirefoxHealthReportTestResponse", {detail: {data: data}, bubbles: true});
document.dispatchEvent(event);
}
function sendToBrowser(type, eventData) {
eventData = eventData || {};
let detail = {command: type};
for (let key of Object.keys(eventData)) {
detail[key] = eventData[key];
}
var event = new CustomEvent("RemoteHealthReportCommand", {detail: detail, bubbles: true});
document.dispatchEvent(event);
}
</script>
</head>
<body onload="init()">
</body>
</html>
<html>
<head>
<meta charset="utf-8">
<script type="application/javascript;version=1.7"
src="healthreport_pingData.js">
</script>
<script type="application/javascript;version=1.7">
function init() {
window.addEventListener("message", function process(e) {
// The init function of abouthealth.js schedules an initial payload event,
// which will be sent after the payload data has been collected. This extra
// event can cause unexpected successes/failures in this test, so we wait
// for the extra event to arrive here before progressing with the actual
// test.
if (e.data.type == "payload") {
window.removeEventListener("message", process, false);
window.addEventListener("message", doTest, false);
doTest();
}
}, false);
}
function checkSubmissionValue(payload, expectedValue) {
return payload.enabled == expectedValue;
}
function validatePayload(payload) {
payload = JSON.parse(payload);
// xxxmpc - this is some pretty low-bar validation, but we have plenty of tests of that API elsewhere
if (!payload.thisPingDate)
return false;
return true;
}
function isArray(arg) {
return Object.prototype.toString.call(arg) === '[object Array]';
}
function writeDiagnostic(text) {
let node = document.createTextNode(text);
let br = document.createElement("br");
document.body.appendChild(node);
document.body.appendChild(br);
}
function validateCurrentTelemetryEnvironment(data) {
// Simple check for now: check that the received object has the expected
// top-level properties.
const expectedKeys = ["profile", "settings", "system", "build", "partner", "addons"];
return expectedKeys.every(key => (key in data));
}
function validateCurrentTelemetryPingData(ping) {
// Simple check for now: check that the received object has the expected
// top-level properties and that the type and reason match.
const expectedKeys = ["environment", "clientId", "payload", "application",
"version", "type", "id"];
return expectedKeys.every(key => (key in ping)) &&
(ping.type == "main") &&
("info" in ping.payload) &&
("reason" in ping.payload.info) &&
(ping.payload.info.reason == "gather-subsession-payload");
}
function validateTelemetryPingList(list) {
if (!isArray(list)) {
console.log("Telemetry ping list is not an array.");
return false;
}
// Telemetry may generate other pings (e.g. "deletion" pings), so filter those
// out.
const TEST_TYPES_REGEX = /^test-telemetryArchive/;
list = list.filter(p => TEST_TYPES_REGEX.test(p.type));
if (list.length != TEST_PINGS.length) {
console.log("Telemetry ping length is not correct.");
return false;
}
let valid = true;
for (let i=0; i<list.length; ++i) {
let received = list[i];
let expected = TEST_PINGS[i];
if (received.type != expected.type ||
received.timestampCreated != expected.date.getTime()) {
writeDiagnostic("Telemetry ping " + i + " does not match.");
writeDiagnostic("Expected: " + JSON.stringify(expected));
writeDiagnostic("Received: " + JSON.stringify(received));
valid = false;
} else {
writeDiagnostic("Telemetry ping " + i + " matches.");
}
}
return true;
}
function validateTelemetryPingData(expected, received) {
const receivedDate = new Date(received.creationDate);
if (received.id != expected.id ||
received.type != expected.type ||
receivedDate.getTime() != expected.date.getTime()) {
writeDiagnostic("Telemetry ping data for " + expected.id + " doesn't match.");
writeDiagnostic("Expected: " + JSON.stringify(expected));
writeDiagnostic("Received: " + JSON.stringify(received));
return false;
}
writeDiagnostic("Telemetry ping data for " + expected.id + " matched.");
return true;
}
var tests = [
{
info: "Checking initial value is enabled",
event: "RequestCurrentPrefs",
payloadType: "prefs",
validateResponse: function(payload) {
return checkSubmissionValue(payload, true);
},
},
{
info: "Verifying disabling works",
event: "DisableDataSubmission",
payloadType: "prefs",
validateResponse: function(payload) {
return checkSubmissionValue(payload, false);
},
},
{
info: "Verifying we're still disabled",
event: "RequestCurrentPrefs",
payloadType: "prefs",
validateResponse: function(payload) {
return checkSubmissionValue(payload, false);
},
},
{
info: "Verifying we can get a payload while submission is disabled",
event: "RequestCurrentPayload",
payloadType: "payload",
validateResponse: function(payload) {
return validatePayload(payload);
},
},
{
info: "Verifying enabling works",
event: "EnableDataSubmission",
payloadType: "prefs",
validateResponse: function(payload) {
return checkSubmissionValue(payload, true);
},
},
{
info: "Verifying we're still re-enabled",
event: "RequestCurrentPrefs",
payloadType: "prefs",
validateResponse: function(payload) {
return checkSubmissionValue(payload, true);
},
},
{
info: "Verifying we can get a payload after re-enabling",
event: "RequestCurrentPayload",
payloadType: "payload",
validateResponse: function(payload) {
return validatePayload(payload);
},
},
{
info: "Verifying that we can get the current Telemetry environment data",
event: "RequestCurrentEnvironment",
payloadType: "telemetry-current-environment-data",
validateResponse: function(payload) {
return validateCurrentTelemetryEnvironment(payload);
},
},
{
info: "Verifying that we can get the current Telemetry ping data",
event: "RequestCurrentPingData",
payloadType: "telemetry-current-ping-data",
validateResponse: function(payload) {
return validateCurrentTelemetryPingData(payload);
},
},
{
info: "Verifying that we get the proper Telemetry ping list",
event: "RequestTelemetryPingList",
payloadType: "telemetry-ping-list",
validateResponse: function(payload) {
// Validate the ping list
if (!validateTelemetryPingList(payload)) {
return false;
}
// Now that we received the ping ids, set up additional test tasks
// that check loading the individual pings.
for (let i=0; i<TEST_PINGS.length; ++i) {
TEST_PINGS[i].id = payload[i].id;
tests.push({
info: "Verifying that we can get the proper Telemetry ping data #" + (i + 1),
event: "RequestTelemetryPingData",
eventData: { id: TEST_PINGS[i].id },
payloadType: "telemetry-ping-data",
validateResponse: function(payload) {
return validateTelemetryPingData(TEST_PINGS[i], payload.pingData);
},
});
}
return true;
},
},
];
var currentTest = -1;
function doTest(evt) {
if (evt) {
if (currentTest < 0 || !evt.data.content)
return; // not yet testing
var test = tests[currentTest];
if (evt.data.type != test.payloadType)
return; // skip unrequested events
var error = JSON.stringify(evt.data.content);
var pass = false;
try {
pass = test.validateResponse(evt.data.content)
} catch (e) {}
reportResult(test.info, pass, error);
}
// start the next test if there are any left
if (tests[++currentTest])
sendToBrowser(tests[currentTest].event, tests[currentTest].eventData);
else
reportFinished();
}
function reportResult(info, pass, error) {
var data = {type: "testResult", info: info, pass: pass, error: error};
var event = new CustomEvent("FirefoxHealthReportTestResponse", {detail: {data: data}, bubbles: true});
document.dispatchEvent(event);
}
function reportFinished(cmd) {
var data = {type: "testsComplete", count: tests.length};
var event = new CustomEvent("FirefoxHealthReportTestResponse", {detail: {data: data}, bubbles: true});
document.dispatchEvent(event);
}
function sendToBrowser(type, eventData) {
eventData = eventData || {};
let detail = {command: type};
for (let key of Object.keys(eventData)) {
detail[key] = eventData[key];
}
var event = new CustomEvent("RemoteHealthReportCommand", {detail: detail, bubbles: true});
document.dispatchEvent(event);
}
</script>
</head>
<body onload="init()">
</body>
</html>

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

@ -3071,6 +3071,17 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
let viewsLeft = this._viewsLeft;
if (viewsLeft) {
let notification = this._panel.firstElementChild.notification;
if (this._notificationType == "passwords" && notification && notification.options &&
notification.options.origin) {
let fxAOrigin = new URL(Services.prefs.getCharPref("identity.fxaccounts.remote.signup.uri")).origin
if (notification.options.origin == fxAOrigin) {
// Somewhat gross hack - we don't want to show the sync promo while
// the user may be logging into Sync.
return;
}
}
if (Services.prefs.prefHasUserValue("services.sync.username") &&
this._notificationType != "addons-sync-disabled") {
// If the user has already setup Sync, don't show the notification.

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

@ -12,6 +12,7 @@ Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Promise.jsm");
Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://gre/modules/TelemetryController.jsm");
Cu.importGlobalProperties(["URL"]);
@ -1978,6 +1979,16 @@ const DAILY_DISCRETE_TEXT_FIELD = Metrics.Storage.FIELD_DAILY_DISCRETE_TEXT;
*/
const UITourHealthReport = {
recordTreatmentTag: function(tag, value) {
TelemetryController.submitExternalPing("uitour-tag",
{
version: 1,
tagName: tag,
tagValue: value,
},
{
addClientId: true,
addEnvironment: true,
});
#ifdef MOZ_SERVICES_HEALTHREPORT
Task.spawn(function*() {
let reporter = Cc["@mozilla.org/datareporting/service;1"]

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

@ -8,6 +8,7 @@ let gContentAPI;
let gContentWindow;
Components.utils.import("resource:///modules/UITour.jsm");
Components.utils.import("resource://testing-common/TelemetryArchiveTesting.jsm", this);
function test() {
UITourTest();
@ -400,13 +401,24 @@ let tests = [
});
});
},
function test_treatment_tag(done) {
taskify(function* test_treatment_tag(done) {
let ac = new TelemetryArchiveTesting.Checker();
yield ac.promiseInit();
gContentAPI.setTreatmentTag("foobar", "baz");
gContentAPI.getTreatmentTag("foobar", (data) => {
is(data.value, "baz", "set and retrieved treatmentTag");
done();
ac.promiseFindPing("uitour-tag", [
[["payload", "tagName"], "foobar"],
[["payload", "tagValue"], "baz"],
]).then((found) => {
ok(found, "Telemetry ping submitted for setTreatmentTag");
done();
}, (err) => {
ok(false, "Exeption finding uitour telemetry ping: " + err);
done();
});
});
},
}),
// Make sure this test is last in the file so the appMenu gets left open and done will confirm it got tore down.
taskify(function* cleanupMenus() {

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

@ -1,3 +1 @@
41.0a1
# Version to display in the about box:
41.0a1

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

@ -0,0 +1 @@
41.0a1

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

@ -22,6 +22,7 @@ support-files =
[browser_ignore_toolbox_network_requests.js]
[browser_keybindings_01.js]
[browser_keybindings_02.js]
[browser_keybindings_03.js]
[browser_new_activation_workflow.js]
[browser_target_events.js]
[browser_target_remote.js]

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

@ -0,0 +1,43 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test that the toolbox 'switch to previous host' feature works.
// Pressing ctrl/cmd+shift+d should switch to the last used host.
const URL = "data:text/html;charset=utf8,test page for toolbox switching";
add_task(function*() {
info("Create a test tab and open the toolbox");
let tab = yield addTab(URL);
let target = TargetFactory.forTab(tab);
let toolbox = yield gDevTools.showToolbox(target, "webconsole");
let keyElement = toolbox.doc.getElementById("toolbox-toggle-host-key");
let {SIDE, BOTTOM, WINDOW} = devtools.Toolbox.HostType;
checkHostType(toolbox, BOTTOM, SIDE);
info ("Switching from bottom to side");
synthesizeKeyElement(keyElement);
yield toolbox.once("host-changed");
checkHostType(toolbox, SIDE, BOTTOM);
info ("Switching from side to bottom");
synthesizeKeyElement(keyElement);
yield toolbox.once("host-changed");
checkHostType(toolbox, BOTTOM, SIDE);
info ("Switching to window");
yield toolbox.switchHost(WINDOW);
checkHostType(toolbox, WINDOW, BOTTOM);
info ("Switching from window to bottom");
synthesizeKeyElement(keyElement);
yield toolbox.once("host-changed");
checkHostType(toolbox, BOTTOM, WINDOW);
yield toolbox.destroy();
gBrowser.removeCurrentTab();
});

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

@ -2,37 +2,35 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
let temp = {}
Cu.import("resource:///modules/devtools/gDevTools.jsm", temp);
let DevTools = temp.DevTools;
Cu.import("resource://gre/modules/devtools/Loader.jsm", temp);
let devtools = temp.devtools;
let Toolbox = devtools.Toolbox;
"use strict";
let {SIDE, BOTTOM, WINDOW} = devtools.Toolbox.HostType;
let toolbox, target;
function test()
{
gBrowser.selectedTab = gBrowser.addTab();
target = TargetFactory.forTab(gBrowser.selectedTab);
const URL = "data:text/html;charset=utf8,test for opening toolbox in different hosts";
gBrowser.selectedBrowser.addEventListener("load", function onLoad(evt) {
gBrowser.selectedBrowser.removeEventListener(evt.type, onLoad, true);
gDevTools.showToolbox(target)
.then(testBottomHost, console.error)
.then(null, console.error);
}, true);
add_task(function* runTest() {
info("Create a test tab and open the toolbox");
let tab = yield addTab(URL);
target = TargetFactory.forTab(tab);
toolbox = yield gDevTools.showToolbox(target, "webconsole");
content.location = "data:text/html,test for opening toolbox in different hosts";
}
yield testBottomHost();
yield testSidebarHost();
yield testWindowHost();
yield testToolSelect();
yield testDestroy();
yield testRememberHost();
yield testPreviousHost();
function testBottomHost(aToolbox)
{
toolbox = aToolbox;
yield toolbox.destroy();
checkHostType(Toolbox.HostType.BOTTOM);
toolbox = target = null;
gBrowser.removeCurrentTab();
});
function* testBottomHost() {
checkHostType(toolbox, BOTTOM);
// test UI presence
let nbox = gBrowser.getNotificationBox();
@ -40,13 +38,11 @@ function testBottomHost(aToolbox)
ok(iframe, "toolbox bottom iframe exists");
checkToolboxLoaded(iframe);
toolbox.switchHost(Toolbox.HostType.SIDE).then(testSidebarHost);
}
function testSidebarHost()
{
checkHostType(Toolbox.HostType.SIDE);
function* testSidebarHost() {
yield toolbox.switchHost(SIDE);
checkHostType(toolbox, SIDE);
// test UI presence
let nbox = gBrowser.getNotificationBox();
@ -57,13 +53,11 @@ function testSidebarHost()
ok(iframe, "toolbox side iframe exists");
checkToolboxLoaded(iframe);
toolbox.switchHost(Toolbox.HostType.WINDOW).then(testWindowHost);
}
function testWindowHost()
{
checkHostType(Toolbox.HostType.WINDOW);
function* testWindowHost() {
yield toolbox.switchHost(WINDOW);
checkHostType(toolbox, WINDOW);
let nbox = gBrowser.getNotificationBox();
let sidebar = document.getAnonymousElementByAttribute(nbox, "class", "devtools-toolbox-side-iframe");
@ -74,57 +68,70 @@ function testWindowHost()
let iframe = win.document.getElementById("toolbox-iframe");
checkToolboxLoaded(iframe);
testToolSelect();
}
function testToolSelect()
{
function* testToolSelect() {
// make sure we can load a tool after switching hosts
toolbox.selectTool("inspector").then(testDestroy);
yield toolbox.selectTool("inspector");
}
function testDestroy()
{
toolbox.destroy().then(function() {
target = TargetFactory.forTab(gBrowser.selectedTab);
gDevTools.showToolbox(target).then(testRememberHost);
});
function* testDestroy() {
yield toolbox.destroy();
target = TargetFactory.forTab(gBrowser.selectedTab);
toolbox = yield gDevTools.showToolbox(target);
}
function testRememberHost(aToolbox)
{
toolbox = aToolbox;
function* testRememberHost() {
// last host was the window - make sure it's the same when re-opening
is(toolbox.hostType, Toolbox.HostType.WINDOW, "host remembered");
is(toolbox.hostType, WINDOW, "host remembered");
let win = Services.wm.getMostRecentWindow("devtools:toolbox");
ok(win, "toolbox separate window exists");
cleanup();
}
function checkHostType(hostType)
{
is(toolbox.hostType, hostType, "host type is " + hostType);
function* testPreviousHost() {
// last host was the window - make sure it's the same when re-opening
is(toolbox.hostType, WINDOW, "host remembered");
let pref = Services.prefs.getCharPref("devtools.toolbox.host");
is(pref, hostType, "host pref is " + hostType);
info("Switching to side");
yield toolbox.switchHost(SIDE);
checkHostType(toolbox, SIDE, WINDOW);
info("Switching to bottom");
yield toolbox.switchHost(BOTTOM);
checkHostType(toolbox, BOTTOM, SIDE);
info("Switching from bottom to side");
yield toolbox.switchToPreviousHost();
checkHostType(toolbox, SIDE, BOTTOM);
info("Switching from side to bottom");
yield toolbox.switchToPreviousHost();
checkHostType(toolbox, BOTTOM, SIDE);
info("Switching to window");
yield toolbox.switchHost(WINDOW);
checkHostType(toolbox, WINDOW, BOTTOM);
info("Switching from window to bottom");
yield toolbox.switchToPreviousHost();
checkHostType(toolbox, BOTTOM, WINDOW);
info("Forcing the previous host to match the current (bottom)")
Services.prefs.setCharPref("devtools.toolbox.previousHost", BOTTOM);
info("Switching from bottom to side (since previous=current=bottom");
yield toolbox.switchToPreviousHost();
checkHostType(toolbox, SIDE, BOTTOM);
info("Forcing the previous host to match the current (side)")
Services.prefs.setCharPref("devtools.toolbox.previousHost", SIDE);
info("Switching from side to bottom (since previous=current=side");
yield toolbox.switchToPreviousHost();
checkHostType(toolbox, BOTTOM, SIDE);
}
function checkToolboxLoaded(iframe)
{
function checkToolboxLoaded(iframe) {
let tabs = iframe.contentDocument.getElementById("toolbox-tabs");
ok(tabs, "toolbox UI has been loaded into iframe");
}
function cleanup()
{
Services.prefs.setCharPref("devtools.toolbox.host", Toolbox.HostType.BOTTOM);
toolbox.destroy().then(function() {
DevTools = Toolbox = toolbox = target = null;
gBrowser.removeCurrentTab();
finish();
});
}

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

@ -68,15 +68,6 @@ function testAllTheTools(docked, callback, toolNum=0) {
});
}
function synthesizeKeyForToolbox(keyId) {
let el = toolbox.doc.getElementById(keyId);
let key = el.getAttribute("key") || el.getAttribute("keycode");
let mod = {};
el.getAttribute("modifiers").split(" ").forEach((m) => mod[m+"Key"] = true);
info("Synthesizing: key="+key+", mod="+JSON.stringify(mod));
EventUtils.synthesizeKey(key, mod, toolbox.doc.defaultView);
}
function testReload(key, docked, toolID, callback) {
let complete = () => {
gBrowser.selectedBrowser.messageManager.removeMessageListener("devtools:test:load", complete);
@ -86,7 +77,8 @@ function testReload(key, docked, toolID, callback) {
description = docked+" devtools with tool "+toolID+", key #" + key;
info("Testing reload in "+description);
synthesizeKeyForToolbox(key);
let el = toolbox.doc.getElementById(key);
synthesizeKeyElement(el);
reloadsSent++;
}

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

@ -109,3 +109,36 @@ function executeInContent(name, data={}, objects={}, expectResponse=true) {
return promise.resolve();
}
}
/**
* Synthesize a keypress from a <key> element, taking into account
* any modifiers.
* @param {Element} el the <key> element to synthesize
*/
function synthesizeKeyElement(el) {
let key = el.getAttribute("key") || el.getAttribute("keycode");
let mod = {};
el.getAttribute("modifiers").split(" ").forEach((m) => mod[m+"Key"] = true);
info(`Synthesizing: key=${key}, mod=${JSON.stringify(mod)}`);
EventUtils.synthesizeKey(key, mod, el.ownerDocument.defaultView);
}
/* Check the toolbox host type and prefs to make sure they match the
* expected values
* @param {Toolbox}
* @param {HostType} hostType
* One of {SIDE, BOTTOM, WINDOW} from devtools.Toolbox.HostType
* @param {HostType} Optional previousHostType
* The host that will be switched to when calling switchToPreviousHost
*/
function checkHostType(toolbox, hostType, previousHostType) {
is(toolbox.hostType, hostType, "host type is " + hostType);
let pref = Services.prefs.getCharPref("devtools.toolbox.host");
is(pref, hostType, "host pref is " + hostType);
if (previousHostType) {
is (Services.prefs.getCharPref("devtools.toolbox.previousHost"),
previousHostType, "The previous host is correct");
}
}

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

@ -30,9 +30,11 @@ function getFrameScript() {
}
gDevTools.testing = true;
SimpleTest.registerCleanupFunction(() => {
registerCleanupFunction(() => {
gDevTools.testing = false;
Services.prefs.clearUserPref("devtools.dump.emit");
Services.prefs.clearUserPref("devtools.toolbox.host");
Services.prefs.clearUserPref("devtools.toolbox.previousHost");
});
registerCleanupFunction(function cleanup() {

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

@ -188,7 +188,8 @@ Toolbox.prototype = {
_prefs: {
LAST_HOST: "devtools.toolbox.host",
LAST_TOOL: "devtools.toolbox.selectedTool",
SIDE_ENABLED: "devtools.toolbox.sideEnabled"
SIDE_ENABLED: "devtools.toolbox.sideEnabled",
PREVIOUS_HOST: "devtools.toolbox.previousHost"
},
currentToolId: null,
@ -497,12 +498,16 @@ Toolbox.prototype = {
_addHostListeners: function() {
let nextKey = this.doc.getElementById("toolbox-next-tool-key");
nextKey.addEventListener("command", this.selectNextTool.bind(this), true);
let prevKey = this.doc.getElementById("toolbox-previous-tool-key");
prevKey.addEventListener("command", this.selectPreviousTool.bind(this), true);
let minimizeKey = this.doc.getElementById("toolbox-minimize-key");
minimizeKey.addEventListener("command", this._toggleMinimizeMode, true);
let toggleKey = this.doc.getElementById("toolbox-toggle-host-key");
toggleKey.addEventListener("command", this.switchToPreviousHost.bind(this), true);
// Split console uses keypress instead of command so the event can be
// cancelled with stopPropagation on the keypress, and not preventDefault.
this.doc.addEventListener("keypress", this._splitConsoleOnKeypress, false);
@ -1579,6 +1584,26 @@ Toolbox.prototype = {
return newHost;
},
/**
* Switch to the last used host for the toolbox UI.
* This is determined by the devtools.toolbox.previousHost pref.
*/
switchToPreviousHost: function() {
let hostType = Services.prefs.getCharPref(this._prefs.PREVIOUS_HOST);
// Handle the case where the previous host happens to match the current
// host. If so, switch to bottom if it's not already used, and side if not.
if (hostType === this._host.type) {
if (hostType === Toolbox.HostType.BOTTOM) {
hostType = Toolbox.HostType.SIDE;
} else {
hostType = Toolbox.HostType.BOTTOM;
}
}
return this.switchHost(hostType);
},
/**
* Switch to a new host for the toolbox UI. E.g. bottom, sidebar, window,
* and focus the window when done.
@ -1607,10 +1632,12 @@ Toolbox.prototype = {
this._host.off("window-closed", this.destroy);
this.destroyHost();
let prevHostType = this._host.type;
this._host = newHost;
if (this.hostType != Toolbox.HostType.CUSTOM) {
Services.prefs.setCharPref(this._prefs.LAST_HOST, this._host.type);
Services.prefs.setCharPref(this._prefs.PREVIOUS_HOST, prevHostType);
}
this._buildDockButtons();

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

@ -74,6 +74,10 @@
key="&toolboxToggleMinimize.key;"
oncommand="void(0);"
modifiers="shift, accel"/>
<key id="toolbox-toggle-host-key"
key="&toolboxToggle.key;"
oncommand="void(0);"
modifiers="accel shift"/>
</keyset>
<popupset>

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

@ -264,8 +264,13 @@ var Scratchpad = {
this._updateViewMenuItem(SHOW_LINE_NUMBERS, "sp-menu-line-numbers");
this._updateViewMenuItem(WRAP_TEXT, "sp-menu-word-wrap");
this._updateViewMenuItem(SHOW_TRAILING_SPACE, "sp-menu-highlight-trailing-space");
this._updateViewFontMenuItem(MINIMUM_FONT_SIZE, "sp-cmd-smaller-font");
this._updateViewFontMenuItem(MAXIMUM_FONT_SIZE, "sp-cmd-larger-font");
},
/**
* Check or uncheck view menu item according to stored preferences.
*/
_updateViewMenuItem: function SP_updateViewMenuItem(preferenceName, menuId) {
let checked = Services.prefs.getBoolPref(preferenceName);
if (checked) {
@ -275,6 +280,16 @@ var Scratchpad = {
}
},
/**
* Disable view menu item if the stored font size is equals to the given one.
*/
_updateViewFontMenuItem: function SP_updateViewFontMenuItem(fontSize, commandId) {
let prefFontSize = Services.prefs.getIntPref(EDITOR_FONT_SIZE);
if (prefFontSize === fontSize) {
document.getElementById(commandId).setAttribute('disabled', true);
}
},
/**
* The script execution context. This tells Scratchpad in which context the
* script shall execute.
@ -1939,6 +1954,12 @@ var Scratchpad = {
let newFontSize = size + 1;
this.editor.setFontSize(newFontSize);
Services.prefs.setIntPref(EDITOR_FONT_SIZE, newFontSize);
if (newFontSize === MAXIMUM_FONT_SIZE) {
document.getElementById("sp-cmd-larger-font").setAttribute('disabled', true);
}
document.getElementById("sp-cmd-smaller-font").removeAttribute('disabled');
}
},
@ -1953,7 +1974,13 @@ var Scratchpad = {
let newFontSize = size - 1;
this.editor.setFontSize(newFontSize);
Services.prefs.setIntPref(EDITOR_FONT_SIZE, newFontSize);
if (newFontSize === MINIMUM_FONT_SIZE) {
document.getElementById("sp-cmd-smaller-font").setAttribute('disabled', true);
}
}
document.getElementById("sp-cmd-larger-font").removeAttribute('disabled');
},
/**
@ -1963,6 +1990,9 @@ var Scratchpad = {
{
this.editor.setFontSize(NORMAL_FONT_SIZE);
Services.prefs.setIntPref(EDITOR_FONT_SIZE, NORMAL_FONT_SIZE);
document.getElementById("sp-cmd-larger-font").removeAttribute('disabled');
document.getElementById("sp-cmd-smaller-font").removeAttribute('disabled');
},
_observers: [],

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

@ -44,3 +44,4 @@ support-files = NS_ERROR_ILLEGAL_INPUT.txt
[browser_scratchpad_ui.js]
[browser_scratchpad_close_toolbox.js]
[browser_scratchpad_remember_view_options.js]
[browser_scratchpad_disable_view_menu_items.js]

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

@ -0,0 +1,66 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Test if the view menu items "Larger Font" and "Smaller Font" are disabled
// when the font size reaches the maximum/minimum values.
let {Task} = Cu.import("resource://gre/modules/Task.jsm", {});
function test() {
const options = {
tabContent: 'test if view menu items "Larger Font" and "Smaller Font" are enabled/disabled.'
};
openTabAndScratchpad(options)
.then(Task.async(runTests))
.then(finish, console.error);
}
function* runTests([win, sp]) {
yield testMaximumFontSize(win, sp);
yield testMinimumFontSize(win, sp);
}
const MAXIMUM_FONT_SIZE = 96;
const MINIMUM_FONT_SIZE = 6;
const NORMAL_FONT_SIZE = 12;
let testMaximumFontSize = Task.async(function* (win, sp) {
let doc = win.document;
Services.prefs.clearUserPref('devtools.scratchpad.editorFontSize');
let menu = doc.getElementById('sp-menu-larger-font');
for (let i = NORMAL_FONT_SIZE; i <= MAXIMUM_FONT_SIZE; i++) {
menu.doCommand();
}
let cmd = doc.getElementById('sp-cmd-larger-font');
ok(cmd.getAttribute('disabled') === 'true', 'Command "sp-cmd-larger-font" is disabled.');
menu = doc.getElementById('sp-menu-smaller-font');
menu.doCommand();
ok(cmd.hasAttribute('disabled') === false, 'Command "sp-cmd-larger-font" is enabled.');
});
let testMinimumFontSize = Task.async(function* (win, sp) {
let doc = win.document;
let menu = doc.getElementById('sp-menu-smaller-font');
for (let i = MAXIMUM_FONT_SIZE; i >= MINIMUM_FONT_SIZE; i--) {
menu.doCommand();
}
let cmd = doc.getElementById('sp-cmd-smaller-font');
ok(cmd.getAttribute('disabled') === 'true', 'Command "sp-cmd-smaller-font" is disabled.');
menu = doc.getElementById('sp-menu-larger-font');
menu.doCommand();
ok(cmd.hasAttribute('disabled') === false, 'Command "sp-cmd-smaller-font" is enabled.');
Services.prefs.clearUserPref('devtools.scratchpad.editorFontSize');
});

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

@ -24,6 +24,7 @@
<!-- This key is used with the accel+shift modifiers to minimize the toolbox -->
<!ENTITY toolboxToggleMinimize.key "U">
<!ENTITY toolboxToggle.key "d">
<!-- LOCALIZATION NOTE (toolboxFramesButton): This is the label for
- the iframes menu list that appears only when the document has some.
- It allows you to switch the context of the whole toolbox. -->

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

@ -680,17 +680,17 @@ toolbarbutton[constrain-size="true"][cui-areatype="toolbar"] > .toolbarbutton-ba
}
#back-button {
margin-top: 3px;
margin-bottom: 3px;
-moz-margin-start: 5px;
padding: 0;
padding-top: 3px;
padding-bottom: 3px;
-moz-padding-start: 5px;
-moz-padding-end: 0;
position: relative;
z-index: 1;
border-radius: 10000px;
border-radius: 0 10000px 10000px 0;
}
#back-button:not(:-moz-lwtheme) {
background-color: -moz-dialog;
#back-button:-moz-locale-dir(rtl) {
border-radius: 10000px 0 0 10000px;
}
#back-button > menupopup {
@ -894,17 +894,13 @@ toolbarbutton[constrain-size="true"][cui-areatype="toolbar"] > .toolbarbutton-ba
}
@conditionalForwardWithUrlbar@ {
clip-path: url("chrome://browser/content/browser.xul#urlbar-clip-path");
-moz-margin-start: -5px;
}
@conditionalForwardWithUrlbar@:-moz-lwtheme {
clip-path: url("chrome://browser/content/browser.xul#urlbar-back-button-clip-path");
-moz-margin-start: -5px;
}
@conditionalForwardWithUrlbar@:-moz-locale-dir(rtl),
@conditionalForwardWithUrlbar@ > #urlbar:-moz-locale-dir(rtl) {
/* Let clip-path clip the urlbar-wrapper's right side for RTL. */
/* let urlbar-back-button-clip-path clip the urlbar's right side for RTL */
transform: scaleX(-1);
}

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

@ -117,15 +117,24 @@ browser.jar:
skin/classic/browser/readinglist/icons.svg (../shared/readinglist/icons.svg)
skin/classic/browser/readinglist/readinglist-icon.svg (../shared/readinglist/readinglist-icon.svg)
* skin/classic/browser/readinglist/sidebar.css (readinglist/sidebar.css)
skin/classic/browser/webRTC-shareDevice-16.png
skin/classic/browser/webRTC-shareDevice-64.png
skin/classic/browser/webRTC-shareDevice-16.png (../shared/webrtc/webRTC-shareDevice-16.png)
skin/classic/browser/webRTC-shareDevice-16@2x.png (../shared/webrtc/webRTC-shareDevice-16@2x.png)
skin/classic/browser/webRTC-shareDevice-64.png (../shared/webrtc/webRTC-shareDevice-64.png)
skin/classic/browser/webRTC-shareDevice-64@2x.png (../shared/webrtc/webRTC-shareDevice-64@2x.png)
skin/classic/browser/webRTC-sharingDevice-16.png (../shared/webrtc/webRTC-sharingDevice-16.png)
skin/classic/browser/webRTC-shareMicrophone-16.png
skin/classic/browser/webRTC-shareMicrophone-64.png
skin/classic/browser/webRTC-sharingDevice-16@2x.png (../shared/webrtc/webRTC-sharingDevice-16@2x.png)
skin/classic/browser/webRTC-shareMicrophone-16.png (../shared/webrtc/webRTC-shareMicrophone-16.png)
skin/classic/browser/webRTC-shareMicrophone-16@2x.png (../shared/webrtc/webRTC-shareMicrophone-16@2x.png)
skin/classic/browser/webRTC-shareMicrophone-64.png (../shared/webrtc/webRTC-shareMicrophone-64.png)
skin/classic/browser/webRTC-shareMicrophone-64@2x.png (../shared/webrtc/webRTC-shareMicrophone-64@2x.png)
skin/classic/browser/webRTC-sharingMicrophone-16.png (../shared/webrtc/webRTC-sharingMicrophone-16.png)
skin/classic/browser/webRTC-sharingMicrophone-16@2x.png (../shared/webrtc/webRTC-sharingMicrophone-16@2x.png)
skin/classic/browser/webRTC-shareScreen-16.png (../shared/webrtc/webRTC-shareScreen-16.png)
skin/classic/browser/webRTC-shareScreen-16@2x.png (../shared/webrtc/webRTC-shareScreen-16@2x.png)
skin/classic/browser/webRTC-shareScreen-64.png (../shared/webrtc/webRTC-shareScreen-64.png)
skin/classic/browser/webRTC-shareScreen-64@2x.png (../shared/webrtc/webRTC-shareScreen-64@2x.png)
skin/classic/browser/webRTC-sharingScreen-16.png (../shared/webrtc/webRTC-sharingScreen-16.png)
skin/classic/browser/webRTC-sharingScreen-16@2x.png (../shared/webrtc/webRTC-sharingScreen-16@2x.png)
skin/classic/browser/webRTC-indicator.css (../shared/webrtc/indicator.css)
skin/classic/browser/webRTC-camera-white-16.png (../shared/webrtc/camera-white-16.png)
skin/classic/browser/webRTC-microphone-white-16.png (../shared/webrtc/microphone-white-16.png)

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

До

Ширина:  |  Высота:  |  Размер: 1.1 KiB

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

До

Ширина:  |  Высота:  |  Размер: 2.8 KiB

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

@ -155,16 +155,16 @@ browser.jar:
skin/classic/browser/readinglist/icons.svg (../shared/readinglist/icons.svg)
skin/classic/browser/readinglist/readinglist-icon.svg (../shared/readinglist/readinglist-icon.svg)
* skin/classic/browser/readinglist/sidebar.css (readinglist/sidebar.css)
skin/classic/browser/webRTC-shareDevice-16.png
skin/classic/browser/webRTC-shareDevice-16@2x.png
skin/classic/browser/webRTC-shareDevice-64.png
skin/classic/browser/webRTC-shareDevice-64@2x.png
skin/classic/browser/webRTC-shareDevice-16.png (../shared/webrtc/webRTC-shareDevice-16.png)
skin/classic/browser/webRTC-shareDevice-16@2x.png (../shared/webrtc/webRTC-shareDevice-16@2x.png)
skin/classic/browser/webRTC-shareDevice-64.png (../shared/webrtc/webRTC-shareDevice-64.png)
skin/classic/browser/webRTC-shareDevice-64@2x.png (../shared/webrtc/webRTC-shareDevice-64@2x.png)
skin/classic/browser/webRTC-sharingDevice-16.png (../shared/webrtc/webRTC-sharingDevice-16.png)
skin/classic/browser/webRTC-sharingDevice-16@2x.png (../shared/webrtc/webRTC-sharingDevice-16@2x.png)
skin/classic/browser/webRTC-shareMicrophone-16.png
skin/classic/browser/webRTC-shareMicrophone-16@2x.png
skin/classic/browser/webRTC-shareMicrophone-64.png
skin/classic/browser/webRTC-shareMicrophone-64@2x.png
skin/classic/browser/webRTC-shareMicrophone-16.png (../shared/webrtc/webRTC-shareMicrophone-16.png)
skin/classic/browser/webRTC-shareMicrophone-16@2x.png (../shared/webrtc/webRTC-shareMicrophone-16@2x.png)
skin/classic/browser/webRTC-shareMicrophone-64.png (../shared/webrtc/webRTC-shareMicrophone-64.png)
skin/classic/browser/webRTC-shareMicrophone-64@2x.png (../shared/webrtc/webRTC-shareMicrophone-64@2x.png)
skin/classic/browser/webRTC-sharingMicrophone-16.png (../shared/webrtc/webRTC-sharingMicrophone-16.png)
skin/classic/browser/webRTC-sharingMicrophone-16@2x.png (../shared/webrtc/webRTC-sharingMicrophone-16@2x.png)
skin/classic/browser/webRTC-shareScreen-16.png (../shared/webrtc/webRTC-shareScreen-16.png)

Двоичные данные
browser/themes/osx/webRTC-shareDevice-16.png

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

До

Ширина:  |  Высота:  |  Размер: 224 B

Двоичные данные
browser/themes/osx/webRTC-shareDevice-64.png

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

До

Ширина:  |  Высота:  |  Размер: 1.1 KiB

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

@ -318,6 +318,51 @@
border-image: url("chrome://browser/skin/urlbar-arrow@2x.png") 0 16 0 0 fill;
}
.webRTC-shareDevices-notification-icon,
#webRTC-shareDevices-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-shareDevice-16@2x.png);
}
.webRTC-sharingDevices-notification-icon,
#webRTC-sharingDevices-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-sharingDevice-16@2x.png);
}
.webRTC-shareMicrophone-notification-icon,
#webRTC-shareMicrophone-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-shareMicrophone-16@2x.png);
}
.webRTC-sharingMicrophone-notification-icon,
#webRTC-sharingMicrophone-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-sharingMicrophone-16@2x.png);
}
.webRTC-shareScreen-notification-icon,
#webRTC-shareScreen-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-shareScreen-16@2x.png);
}
.webRTC-sharingScreen-notification-icon,
#webRTC-sharingScreen-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-sharingScreen-16@2x.png);
}
.popup-notification-icon[popupid="webRTC-sharingDevices"],
.popup-notification-icon[popupid="webRTC-shareDevices"] {
list-style-image: url(chrome://browser/skin/webRTC-shareDevice-64@2x.png);
}
.popup-notification-icon[popupid="webRTC-sharingMicrophone"],
.popup-notification-icon[popupid="webRTC-shareMicrophone"] {
list-style-image: url(chrome://browser/skin/webRTC-shareMicrophone-64@2x.png);
}
.popup-notification-icon[popupid="webRTC-sharingScreen"],
.popup-notification-icon[popupid="webRTC-shareScreen"] {
list-style-image: url(chrome://browser/skin/webRTC-shareScreen-64@2x.png);
}
%ifdef XP_MACOSX
/* OSX only until we have icons for Windows and Linux */
.default-notification-icon,
@ -381,36 +426,6 @@
list-style-image: url(chrome://browser/skin/bad-content-unblocked-16@2x.png);
}
.webRTC-shareDevices-notification-icon,
#webRTC-shareDevices-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-shareDevice-16@2x.png);
}
.webRTC-sharingDevices-notification-icon,
#webRTC-sharingDevices-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-sharingDevice-16@2x.png);
}
.webRTC-shareMicrophone-notification-icon,
#webRTC-shareMicrophone-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-shareMicrophone-16@2x.png);
}
.webRTC-sharingMicrophone-notification-icon,
#webRTC-sharingMicrophone-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-sharingMicrophone-16@2x.png);
}
.webRTC-shareScreen-notification-icon,
#webRTC-shareScreen-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-shareScreen-16@2x.png);
}
.webRTC-sharingScreen-notification-icon,
#webRTC-sharingScreen-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-sharingScreen-16@2x.png);
}
.web-notifications-notification-icon,
#web-notifications-notification-icon {
list-style-image: url(chrome://browser/skin/notification-16@2x.png);
@ -458,21 +473,6 @@
list-style-image: url(chrome://browser/skin/pointerLock-64@2x.png);
}
.popup-notification-icon[popupid="webRTC-sharingDevices"],
.popup-notification-icon[popupid="webRTC-shareDevices"] {
list-style-image: url(chrome://browser/skin/webRTC-shareDevice-64@2x.png);
}
.popup-notification-icon[popupid="webRTC-sharingMicrophone"],
.popup-notification-icon[popupid="webRTC-shareMicrophone"] {
list-style-image: url(chrome://browser/skin/webRTC-shareMicrophone-64@2x.png);
}
.popup-notification-icon[popupid="webRTC-sharingScreen"],
.popup-notification-icon[popupid="webRTC-shareScreen"] {
list-style-image: url(chrome://browser/skin/webRTC-shareScreen-64@2x.png);
}
.popup-notification-icon[popupid="servicesInstall"] {
list-style-image: url(chrome://browser/skin/social/services-64@2x.png);
}

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

До

Ширина:  |  Высота:  |  Размер: 224 B

После

Ширина:  |  Высота:  |  Размер: 224 B

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

До

Ширина:  |  Высота:  |  Размер: 367 B

После

Ширина:  |  Высота:  |  Размер: 367 B

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

До

Ширина:  |  Высота:  |  Размер: 1.1 KiB

После

Ширина:  |  Высота:  |  Размер: 1.1 KiB

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

До

Ширина:  |  Высота:  |  Размер: 1.6 KiB

После

Ширина:  |  Высота:  |  Размер: 1.6 KiB

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

До

Ширина:  |  Высота:  |  Размер: 1.1 KiB

После

Ширина:  |  Высота:  |  Размер: 1.1 KiB

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

До

Ширина:  |  Высота:  |  Размер: 1.3 KiB

После

Ширина:  |  Высота:  |  Размер: 1.3 KiB

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

До

Ширина:  |  Высота:  |  Размер: 2.5 KiB

После

Ширина:  |  Высота:  |  Размер: 2.5 KiB

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

До

Ширина:  |  Высота:  |  Размер: 5.6 KiB

После

Ширина:  |  Высота:  |  Размер: 5.6 KiB

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

@ -155,15 +155,24 @@ browser.jar:
skin/classic/browser/notification-pluginNormal.png (../shared/plugins/notification-pluginNormal.png)
skin/classic/browser/notification-pluginAlert.png (../shared/plugins/notification-pluginAlert.png)
skin/classic/browser/notification-pluginBlocked.png (../shared/plugins/notification-pluginBlocked.png)
skin/classic/browser/webRTC-shareDevice-16.png
skin/classic/browser/webRTC-shareDevice-64.png
skin/classic/browser/webRTC-shareDevice-16.png (../shared/webrtc/webRTC-shareDevice-16.png)
skin/classic/browser/webRTC-shareDevice-16@2x.png (../shared/webrtc/webRTC-shareDevice-16@2x.png)
skin/classic/browser/webRTC-shareDevice-64.png (../shared/webrtc/webRTC-shareDevice-64.png)
skin/classic/browser/webRTC-shareDevice-64@2x.png (../shared/webrtc/webRTC-shareDevice-64@2x.png)
skin/classic/browser/webRTC-sharingDevice-16.png (../shared/webrtc/webRTC-sharingDevice-16.png)
skin/classic/browser/webRTC-shareMicrophone-16.png
skin/classic/browser/webRTC-shareMicrophone-64.png
skin/classic/browser/webRTC-sharingDevice-16@2x.png (../shared/webrtc/webRTC-sharingDevice-16@2x.png)
skin/classic/browser/webRTC-shareMicrophone-16.png (../shared/webrtc/webRTC-shareMicrophone-16.png)
skin/classic/browser/webRTC-shareMicrophone-16@2x.png (../shared/webrtc/webRTC-shareMicrophone-16@2x.png)
skin/classic/browser/webRTC-shareMicrophone-64.png (../shared/webrtc/webRTC-shareMicrophone-64.png)
skin/classic/browser/webRTC-shareMicrophone-64@2x.png (../shared/webrtc/webRTC-shareMicrophone-64@2x.png)
skin/classic/browser/webRTC-sharingMicrophone-16.png (../shared/webrtc/webRTC-sharingMicrophone-16.png)
skin/classic/browser/webRTC-sharingMicrophone-16@2x.png (../shared/webrtc/webRTC-sharingMicrophone-16@2x.png)
skin/classic/browser/webRTC-shareScreen-16.png (../shared/webrtc/webRTC-shareScreen-16.png)
skin/classic/browser/webRTC-shareScreen-16@2x.png (../shared/webrtc/webRTC-shareScreen-16@2x.png)
skin/classic/browser/webRTC-shareScreen-64.png (../shared/webrtc/webRTC-shareScreen-64.png)
skin/classic/browser/webRTC-shareScreen-64@2x.png (../shared/webrtc/webRTC-shareScreen-64@2x.png)
skin/classic/browser/webRTC-sharingScreen-16.png (../shared/webrtc/webRTC-sharingScreen-16.png)
skin/classic/browser/webRTC-sharingScreen-16@2x.png (../shared/webrtc/webRTC-sharingScreen-16@2x.png)
skin/classic/browser/webRTC-indicator.css (../shared/webrtc/indicator.css)
skin/classic/browser/webRTC-camera-white-16.png (../shared/webrtc/camera-white-16.png)
skin/classic/browser/webRTC-microphone-white-16.png (../shared/webrtc/microphone-white-16.png)

Двоичные данные
browser/themes/windows/webRTC-shareDevice-16.png

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

До

Ширина:  |  Высота:  |  Размер: 233 B

Двоичные данные
browser/themes/windows/webRTC-shareDevice-64.png

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

До

Ширина:  |  Высота:  |  Размер: 1.1 KiB

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

До

Ширина:  |  Высота:  |  Размер: 347 B

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

До

Ширина:  |  Высота:  |  Размер: 1.6 KiB

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

@ -127,19 +127,20 @@ bool isInIgnoredNamespaceForImplicitCtor(const Decl *decl) {
return false;
}
return name == "std" || // standard C++ lib
name == "__gnu_cxx" || // gnu C++ lib
name == "boost" || // boost
name == "webrtc" || // upstream webrtc
name == "icu_52" || // icu
name == "google" || // protobuf
name == "google_breakpad" || // breakpad
name == "soundtouch" || // libsoundtouch
name == "stagefright" || // libstagefright
name == "MacFileUtilities" || // MacFileUtilities
name == "dwarf2reader" || // dwarf2reader
name == "arm_ex_to_module" || // arm_ex_to_module
name == "testing"; // gtest
return name == "std" || // standard C++ lib
name == "__gnu_cxx" || // gnu C++ lib
name == "boost" || // boost
name == "webrtc" || // upstream webrtc
name.substr(0, 4) == "icu_" || // icu
name == "google" || // protobuf
name == "google_breakpad" || // breakpad
name == "soundtouch" || // libsoundtouch
name == "stagefright" || // libstagefright
name == "MacFileUtilities" || // MacFileUtilities
name == "dwarf2reader" || // dwarf2reader
name == "arm_ex_to_module" || // arm_ex_to_module
name == "testing"; // gtest
}
bool isInIgnoredNamespaceForImplicitConversion(const Decl *decl) {

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

@ -1958,8 +1958,8 @@ MOZILLA_UAVERSION=`$PYTHON $srcdir/python/mozbuild/mozbuild/milestone.py --topsr
MOZILLA_SYMBOLVERSION=`$PYTHON $srcdir/python/mozbuild/mozbuild/milestone.py --topsrcdir $srcdir --symbolversion`
dnl Get version of various core apps from the version files.
FIREFOX_VERSION=`cat $_topsrcdir/browser/config/version.txt|head -1`
FIREFOX_VERSION_ABOUT=`cat $_topsrcdir/browser/config/version.txt|tail -1`
FIREFOX_VERSION=`cat $_topsrcdir/browser/config/version.txt`
FIREFOX_VERSION_ABOUT=`cat $_topsrcdir/browser/config/version_about.txt`
if test -z "$FIREFOX_VERSION"; then
AC_MSG_ERROR([FIREFOX_VERSION is unexpectedly blank.])

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

@ -203,6 +203,7 @@ this.DOMApplicationRegistry = {
dirKey: DIRECTORY_NAME,
init: function() {
// Keep the messages in sync with the lazy-loading in browser.js (bug 1171013).
this.messages = ["Webapps:Install",
"Webapps:Uninstall",
"Webapps:GetSelf",

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

@ -531,13 +531,13 @@ File::GetLastModified(ErrorResult& aRv)
}
void
File::GetMozFullPath(nsAString& aFilename, ErrorResult& aRv)
File::GetMozFullPath(nsAString& aFilename, ErrorResult& aRv) const
{
mImpl->GetMozFullPath(aFilename, aRv);
}
void
File::GetMozFullPathInternal(nsAString& aFileName, ErrorResult& aRv)
File::GetMozFullPathInternal(nsAString& aFileName, ErrorResult& aRv) const
{
mImpl->GetMozFullPathInternal(aFileName, aRv);
}
@ -735,7 +735,7 @@ BlobImplBase::GetPath(nsAString& aPath, ErrorResult& aRv)
}
void
BlobImplBase::GetMozFullPath(nsAString& aFileName, ErrorResult& aRv)
BlobImplBase::GetMozFullPath(nsAString& aFileName, ErrorResult& aRv) const
{
NS_ASSERTION(mIsFile, "Should only be called on files");
@ -759,7 +759,7 @@ BlobImplBase::GetMozFullPath(nsAString& aFileName, ErrorResult& aRv)
}
void
BlobImplBase::GetMozFullPathInternal(nsAString& aFileName, ErrorResult& aRv)
BlobImplBase::GetMozFullPathInternal(nsAString& aFileName, ErrorResult& aRv) const
{
if (!mIsFile) {
aRv.Throw(NS_ERROR_FAILURE);
@ -950,7 +950,7 @@ BlobImplFile::CreateSlice(uint64_t aStart, uint64_t aLength,
}
void
BlobImplFile::GetMozFullPathInternal(nsAString& aFilename, ErrorResult& aRv)
BlobImplFile::GetMozFullPathInternal(nsAString& aFilename, ErrorResult& aRv) const
{
NS_ASSERTION(mIsFile, "Should only be called on files");
aRv = mFile->GetPath(aFilename);

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

@ -261,9 +261,9 @@ public:
void GetPath(nsAString& aName, ErrorResult& aRv);
void GetMozFullPath(nsAString& aFilename, ErrorResult& aRv);
void GetMozFullPath(nsAString& aFilename, ErrorResult& aRv) const;
void GetMozFullPathInternal(nsAString& aName, ErrorResult& aRv);
void GetMozFullPathInternal(nsAString& aName, ErrorResult& aRv) const;
protected:
virtual bool HasFileInterface() const override { return true; }
@ -293,9 +293,9 @@ public:
virtual void SetLastModified(int64_t aLastModified) = 0;
virtual void GetMozFullPath(nsAString& aName, ErrorResult& aRv) = 0;
virtual void GetMozFullPath(nsAString& aName, ErrorResult& aRv) const = 0;
virtual void GetMozFullPathInternal(nsAString& aFileName, ErrorResult& aRv) = 0;
virtual void GetMozFullPathInternal(nsAString& aFileName, ErrorResult& aRv) const = 0;
virtual uint64_t GetSize(ErrorResult& aRv) = 0;
@ -434,10 +434,10 @@ public:
virtual void SetLastModified(int64_t aLastModified) override;
virtual void GetMozFullPath(nsAString& aName, ErrorResult& aRv) override;
virtual void GetMozFullPath(nsAString& aName, ErrorResult& aRv) const override;
virtual void GetMozFullPathInternal(nsAString& aFileName,
ErrorResult& aRv) override;
ErrorResult& aRv) const override;
virtual uint64_t GetSize(ErrorResult& aRv) override
{
@ -822,7 +822,7 @@ public:
virtual int64_t GetLastModified(ErrorResult& aRv) override;
virtual void SetLastModified(int64_t aLastModified) override;
virtual void GetMozFullPathInternal(nsAString& aFullPath,
ErrorResult& aRv) override;
ErrorResult& aRv) const override;
virtual void GetInternalStream(nsIInputStream** aInputStream,
ErrorResult& aRv) override;

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

@ -240,7 +240,7 @@ MultipartBlobImpl::SetLengthAndModifiedDate()
void
MultipartBlobImpl::GetMozFullPathInternal(nsAString& aFilename,
ErrorResult& aRv)
ErrorResult& aRv) const
{
if (!mIsFromNsIFile || mBlobImpls.Length() == 0) {
BlobImplBase::GetMozFullPathInternal(aFilename, aRv);

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

@ -101,7 +101,7 @@ public:
}
virtual void GetMozFullPathInternal(nsAString& aFullPath,
ErrorResult& aRv) override;
ErrorResult& aRv) const override;
virtual nsresult
SetMutable(bool aMutable) override;

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

@ -313,34 +313,7 @@ AutoJSAPI::~AutoJSAPI()
if (mOwnErrorReporting) {
MOZ_ASSERT(NS_IsMainThread(), "See corresponding assertion in TakeOwnershipOfErrorReporting()");
if (HasException()) {
// AutoJSAPI uses a JSAutoNullableCompartment, and may be in a null
// compartment when the destructor is called. However, the JS engine
// requires us to be in a compartment when we fetch the pending exception.
// In this case, we enter the privileged junk scope and don't dispatch any
// error events.
JS::Rooted<JSObject*> errorGlobal(cx(), JS::CurrentGlobalOrNull(cx()));
if (!errorGlobal)
errorGlobal = xpc::PrivilegedJunkScope();
JSAutoCompartment ac(cx(), errorGlobal);
nsCOMPtr<nsPIDOMWindow> win = xpc::WindowGlobalOrNull(errorGlobal);
JS::Rooted<JS::Value> exn(cx());
js::ErrorReport jsReport(cx());
if (StealException(&exn) && jsReport.init(cx(), exn)) {
nsRefPtr<xpc::ErrorReport> xpcReport = new xpc::ErrorReport();
xpcReport->Init(jsReport.report(), jsReport.message(),
nsContentUtils::IsCallerChrome(),
win ? win->WindowID() : 0);
if (win) {
DispatchScriptErrorEvent(win, JS_GetRuntime(cx()), xpcReport, exn);
} else {
xpcReport->LogToConsole();
}
} else {
NS_WARNING("OOMed while acquiring uncaught exception from JSAPI");
}
}
ReportException();
// We need to do this _after_ processing the existing exception, because the
// JS engine can throw while doing that, and uses this bit to determine what
@ -508,6 +481,41 @@ AutoJSAPI::TakeOwnershipOfErrorReporting()
JS_SetErrorReporter(rt, WarningOnlyErrorReporter);
}
void
AutoJSAPI::ReportException()
{
MOZ_ASSERT(OwnsErrorReporting(), "This is not our exception to report!");
if (!HasException()) {
return;
}
// AutoJSAPI uses a JSAutoNullableCompartment, and may be in a null
// compartment when the destructor is called. However, the JS engine
// requires us to be in a compartment when we fetch the pending exception.
// In this case, we enter the privileged junk scope and don't dispatch any
// error events.
JS::Rooted<JSObject*> errorGlobal(cx(), JS::CurrentGlobalOrNull(cx()));
if (!errorGlobal)
errorGlobal = xpc::PrivilegedJunkScope();
JSAutoCompartment ac(cx(), errorGlobal);
nsCOMPtr<nsPIDOMWindow> win = xpc::WindowGlobalOrNull(errorGlobal);
JS::Rooted<JS::Value> exn(cx());
js::ErrorReport jsReport(cx());
if (StealException(&exn) && jsReport.init(cx(), exn)) {
nsRefPtr<xpc::ErrorReport> xpcReport = new xpc::ErrorReport();
xpcReport->Init(jsReport.report(), jsReport.message(),
nsContentUtils::IsCallerChrome(),
win ? win->WindowID() : 0);
if (win) {
DispatchScriptErrorEvent(win, JS_GetRuntime(cx()), xpcReport, exn);
} else {
xpcReport->LogToConsole();
}
} else {
NS_WARNING("OOMed while acquiring uncaught exception from JSAPI");
}
}
bool
AutoJSAPI::StealException(JS::MutableHandle<JS::Value> aVal)
{

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

@ -274,6 +274,9 @@ public:
// while keeping the old behavior as the default.
void TakeOwnershipOfErrorReporting();
bool OwnsErrorReporting() { return mOwnErrorReporting; }
// If HasException, report it. Otherwise, a no-op. This must be
// called only if OwnsErrorReporting().
void ReportException();
bool HasException() const {
MOZ_ASSERT(CxPusherIsStackTop());

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

@ -68,7 +68,7 @@ nsContentPolicy::~nsContentPolicy()
inline nsresult
nsContentPolicy::CheckPolicy(CPMethod policyMethod,
SCPMethod simplePolicyMethod,
uint32_t contentType,
nsContentPolicyType contentType,
nsIURI *contentLocation,
nsIURI *requestingLocation,
nsISupports *requestingContext,
@ -110,6 +110,9 @@ nsContentPolicy::CheckPolicy(CPMethod policyMethod,
}
}
nsContentPolicyType externalType =
nsContentUtils::InternalContentPolicyTypeToExternal(contentType);
/*
* Enumerate mPolicies and ask each of them, taking the logical AND of
* their permissions.
@ -120,7 +123,7 @@ nsContentPolicy::CheckPolicy(CPMethod policyMethod,
int32_t count = entries.Count();
for (int32_t i = 0; i < count; i++) {
/* check the appropriate policy */
rv = (entries[i]->*policyMethod)(contentType, contentLocation,
rv = (entries[i]->*policyMethod)(externalType, contentLocation,
requestingLocation, requestingContext,
mimeType, extra, requestPrincipal,
decision);
@ -166,7 +169,7 @@ nsContentPolicy::CheckPolicy(CPMethod policyMethod,
count = simpleEntries.Count();
for (int32_t i = 0; i < count; i++) {
/* check the appropriate policy */
rv = (simpleEntries[i]->*simplePolicyMethod)(contentType, contentLocation,
rv = (simpleEntries[i]->*simplePolicyMethod)(externalType, contentLocation,
requestingLocation,
topFrameElement, isTopLevel,
mimeType, extra, requestPrincipal,

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

@ -49,7 +49,7 @@ class nsContentPolicy : public nsIContentPolicy
//Helper method that applies policyMethod across all policies in mPolicies
// with the given parameters
nsresult CheckPolicy(CPMethod policyMethod, SCPMethod simplePolicyMethod,
uint32_t contentType,
nsContentPolicyType contentType,
nsIURI *aURI, nsIURI *origURI,
nsISupports *requestingContext,
const nsACString &mimeGuess, nsISupports *extra,

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

@ -92,28 +92,38 @@ inline const char *
NS_CP_ContentTypeName(uint32_t contentType)
{
switch (contentType) {
CASE_RETURN( TYPE_OTHER );
CASE_RETURN( TYPE_SCRIPT );
CASE_RETURN( TYPE_IMAGE );
CASE_RETURN( TYPE_STYLESHEET );
CASE_RETURN( TYPE_OBJECT );
CASE_RETURN( TYPE_DOCUMENT );
CASE_RETURN( TYPE_SUBDOCUMENT );
CASE_RETURN( TYPE_REFRESH );
CASE_RETURN( TYPE_XBL );
CASE_RETURN( TYPE_PING );
CASE_RETURN( TYPE_XMLHTTPREQUEST );
CASE_RETURN( TYPE_OBJECT_SUBREQUEST );
CASE_RETURN( TYPE_DTD );
CASE_RETURN( TYPE_FONT );
CASE_RETURN( TYPE_MEDIA );
CASE_RETURN( TYPE_WEBSOCKET );
CASE_RETURN( TYPE_CSP_REPORT );
CASE_RETURN( TYPE_XSLT );
CASE_RETURN( TYPE_BEACON );
CASE_RETURN( TYPE_FETCH );
CASE_RETURN( TYPE_IMAGESET );
CASE_RETURN( TYPE_WEB_MANIFEST );
CASE_RETURN( TYPE_OTHER );
CASE_RETURN( TYPE_SCRIPT );
CASE_RETURN( TYPE_IMAGE );
CASE_RETURN( TYPE_STYLESHEET );
CASE_RETURN( TYPE_OBJECT );
CASE_RETURN( TYPE_DOCUMENT );
CASE_RETURN( TYPE_SUBDOCUMENT );
CASE_RETURN( TYPE_REFRESH );
CASE_RETURN( TYPE_XBL );
CASE_RETURN( TYPE_PING );
CASE_RETURN( TYPE_XMLHTTPREQUEST );
CASE_RETURN( TYPE_OBJECT_SUBREQUEST );
CASE_RETURN( TYPE_DTD );
CASE_RETURN( TYPE_FONT );
CASE_RETURN( TYPE_MEDIA );
CASE_RETURN( TYPE_WEBSOCKET );
CASE_RETURN( TYPE_CSP_REPORT );
CASE_RETURN( TYPE_XSLT );
CASE_RETURN( TYPE_BEACON );
CASE_RETURN( TYPE_FETCH );
CASE_RETURN( TYPE_IMAGESET );
CASE_RETURN( TYPE_WEB_MANIFEST );
CASE_RETURN( TYPE_INTERNAL_SCRIPT );
CASE_RETURN( TYPE_INTERNAL_WORKER );
CASE_RETURN( TYPE_INTERNAL_SHARED_WORKER );
CASE_RETURN( TYPE_INTERNAL_EMBED );
CASE_RETURN( TYPE_INTERNAL_OBJECT );
CASE_RETURN( TYPE_INTERNAL_FRAME );
CASE_RETURN( TYPE_INTERNAL_IFRAME );
CASE_RETURN( TYPE_INTERNAL_AUDIO );
CASE_RETURN( TYPE_INTERNAL_VIDEO );
CASE_RETURN( TYPE_INTERNAL_TRACK );
default:
return "<Unknown Type>";
}

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

@ -7812,3 +7812,31 @@ nsContentUtils::GetWindowRoot(nsIDocument* aDoc)
}
return nullptr;
}
/* static */
nsContentPolicyType
nsContentUtils::InternalContentPolicyTypeToExternal(nsContentPolicyType aType)
{
switch (aType) {
case nsIContentPolicy::TYPE_INTERNAL_SCRIPT:
case nsIContentPolicy::TYPE_INTERNAL_WORKER:
case nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER:
return nsIContentPolicy::TYPE_SCRIPT;
case nsIContentPolicy::TYPE_INTERNAL_EMBED:
case nsIContentPolicy::TYPE_INTERNAL_OBJECT:
return nsIContentPolicy::TYPE_OBJECT;
case nsIContentPolicy::TYPE_INTERNAL_FRAME:
case nsIContentPolicy::TYPE_INTERNAL_IFRAME:
return nsIContentPolicy::TYPE_SUBDOCUMENT;
case nsIContentPolicy::TYPE_INTERNAL_AUDIO:
case nsIContentPolicy::TYPE_INTERNAL_VIDEO:
case nsIContentPolicy::TYPE_INTERNAL_TRACK:
return nsIContentPolicy::TYPE_MEDIA;
default:
return aType;
}
}

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

@ -916,6 +916,11 @@ public:
*/
static nsIContentPolicy *GetContentPolicy();
/**
* Map internal content policy types to external ones.
*/
static nsContentPolicyType InternalContentPolicyTypeToExternal(nsContentPolicyType aType);
/**
* Quick helper to determine whether there are any mutation listeners
* of a given type that apply to this content or any of its ancestors.

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

@ -43,6 +43,9 @@ nsDataDocumentContentPolicy::ShouldLoad(uint32_t aContentType,
nsIPrincipal *aRequestPrincipal,
int16_t *aDecision)
{
MOZ_ASSERT(aContentType == nsContentUtils::InternalContentPolicyTypeToExternal(aContentType),
"We should only see external content policy types here.");
*aDecision = nsIContentPolicy::ACCEPT;
// Look for the document. In most cases, aRequestingContext is a node.
nsCOMPtr<nsIDocument> doc;

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

@ -12463,6 +12463,7 @@ nsGlobalWindow::RunTimeoutHandler(nsTimeout* aTimeout,
// New script entry point required, due to the "Create a script" sub-step of
// http://www.whatwg.org/specs/web-apps/current-work/#timer-initialisation-steps
AutoEntryScript entryScript(this, reason, true, aScx->GetNativeContext());
entryScript.TakeOwnershipOfErrorReporting();
JS::CompileOptions options(entryScript.cx());
options.setFileAndLine(filename, lineNo)
.setVersion(JSVERSION_DEFAULT);

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

@ -20,7 +20,7 @@ interface nsIPrincipal;
* by launching a dialog to prompt the user for something).
*/
[scriptable,uuid(cb978019-0c5b-4067-abb6-c914461208c1)]
[scriptable,uuid(b545899e-42bd-434c-8fec-a0af3448ea15)]
interface nsIContentPolicy : nsIContentPolicyBase
{
/**

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

@ -24,7 +24,7 @@ typedef unsigned long nsContentPolicyType;
* by launching a dialog to prompt the user for something).
*/
[scriptable,uuid(4f2655e8-6365-4583-8510-732bff2186c5)]
[scriptable,uuid(11b8d725-7c2b-429e-b51f-8b5b542d5009)]
interface nsIContentPolicyBase : nsISupports
{
/**
@ -57,6 +57,10 @@ interface nsIContentPolicyBase : nsISupports
* Implementations of nsIContentPolicy should treat this the same way they
* treat unknown types, because existing users of TYPE_OTHER may be converted
* to use new content types.
*
* Note that the TYPE_INTERNAL_* constants are never passed to content
* policy implementations. They are mapped to other TYPE_* constants, and
* are only intended for internal usage inside Gecko.
*/
const nsContentPolicyType TYPE_OTHER = 1;
@ -177,6 +181,82 @@ interface nsIContentPolicyBase : nsISupports
*/
const nsContentPolicyType TYPE_WEB_MANIFEST = 22;
/**
* Indicates an internal constant for scripts loaded through script
* elements.
*
* This will be mapped to TYPE_SCRIPT before being passed to content policy
* implementations.
*/
const nsContentPolicyType TYPE_INTERNAL_SCRIPT = 23;
/**
* Indicates an internal constant for scripts loaded through a dedicated
* worker.
*
* This will be mapped to TYPE_SCRIPT before being passed to content policy
* implementations.
*/
const nsContentPolicyType TYPE_INTERNAL_WORKER = 24;
/**
* Indicates an internal constant for scripts loaded through a shared
* worker.
*
* This will be mapped to TYPE_SCRIPT before being passed to content policy
* implementations.
*/
const nsContentPolicyType TYPE_INTERNAL_SHARED_WORKER = 25;
/**
* Indicates an internal constant for content loaded from embed elements.
*
* This will be mapped to TYPE_OBJECT.
*/
const nsContentPolicyType TYPE_INTERNAL_EMBED = 26;
/**
* Indicates an internal constant for content loaded from object elements.
*
* This will be mapped to TYPE_OBJECT.
*/
const nsContentPolicyType TYPE_INTERNAL_OBJECT = 27;
/**
* Indicates an internal constant for content loaded from frame elements.
*
* This will be mapped to TYPE_SUBDOCUMENT.
*/
const nsContentPolicyType TYPE_INTERNAL_FRAME = 28;
/**
* Indicates an internal constant for content loaded from iframe elements.
*
* This will be mapped to TYPE_SUBDOCUMENT.
*/
const nsContentPolicyType TYPE_INTERNAL_IFRAME = 29;
/**
* Indicates an internal constant for content loaded from audio elements.
*
* This will be mapped to TYPE_MEDIA.
*/
const nsContentPolicyType TYPE_INTERNAL_AUDIO = 30;
/**
* Indicates an internal constant for content loaded from video elements.
*
* This will be mapped to TYPE_MEDIA.
*/
const nsContentPolicyType TYPE_INTERNAL_VIDEO = 31;
/**
* Indicates an internal constant for content loaded from track elements.
*
* This will be mapped to TYPE_MEDIA.
*/
const nsContentPolicyType TYPE_INTERNAL_TRACK = 32;
/* When adding new content types, please update nsContentBlocker,
* NS_CP_ContentTypeName, nsCSPContext, all nsIContentPolicy
* implementations, and other things that are not listed here that are

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

@ -28,7 +28,7 @@ interface nsIDOMElement;
* by launching a dialog to prompt the user for something).
*/
[scriptable,uuid(704b4b8e-2287-498a-9c0a-d1bde547a2d4)]
[scriptable,uuid(b181c97c-9d67-4da1-95a0-e0a202e1807c)]
interface nsISimpleContentPolicy : nsIContentPolicyBase
{
/**

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

@ -98,41 +98,6 @@ nsJSUtils::GetCurrentlyRunningCodeInnerWindowID(JSContext *aContext)
return innerWindowID;
}
void
nsJSUtils::ReportPendingException(JSContext *aContext)
{
if (JS_IsExceptionPending(aContext)) {
bool saved = JS_SaveFrameChain(aContext);
{
// JS_SaveFrameChain set the compartment of aContext to null, so we need
// to enter a compartment. The question is, which one? We don't want to
// enter the original compartment of aContext (or the compartment of the
// current exception on aContext, for that matter) because when we
// JS_ReportPendingException the JS engine can try to duck-type the
// exception and produce a JSErrorReport. It will then pass that
// JSErrorReport to the error reporter on aContext, which might expose
// information from it to script via onerror handlers. So it's very
// important that the duck typing happen in the same compartment as the
// onerror handler. In practice, that's the compartment of the window (or
// otherwise default global) of aContext, so use that here.
nsIScriptContext* scx = GetScriptContextFromJSContext(aContext);
JS::Rooted<JSObject*> scope(aContext);
scope = scx ? scx->GetWindowProxy() : nullptr;
if (!scope) {
// The SafeJSContext has no default object associated with it.
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aContext == nsContentUtils::GetSafeJSContext());
scope = xpc::UnprivilegedJunkScope(); // Usage approved by bholley
}
JSAutoCompartment ac(aContext, scope);
JS_ReportPendingException(aContext);
}
if (saved) {
JS_RestoreFrameChain(aContext);
}
}
}
nsresult
nsJSUtils::CompileFunction(AutoJSAPI& jsapi,
JS::AutoObjectVector& aScopeChain,
@ -199,12 +164,11 @@ nsJSUtils::EvaluateString(JSContext* aCx,
PROFILER_LABEL("nsJSUtils", "EvaluateString",
js::ProfileEntry::Category::JS);
MOZ_ASSERT(JS::ContextOptionsRef(aCx).autoJSAPIOwnsErrorReporting(),
"Caller must own error reporting");
MOZ_ASSERT_IF(aCompileOptions.versionSet,
aCompileOptions.version != JSVERSION_UNKNOWN);
MOZ_ASSERT_IF(aEvaluateOptions.coerceToString, !aCompileOptions.noScriptRval);
MOZ_ASSERT_IF(!aEvaluateOptions.reportUncaught, !aCompileOptions.noScriptRval);
// Note that the above assert means that if aCompileOptions.noScriptRval then
// also aEvaluateOptions.reportUncaught.
MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
MOZ_ASSERT(aSrcBuf.get());
MOZ_ASSERT(js::GetGlobalForObjectCrossCompartment(aEvaluationGlobal) ==
@ -225,13 +189,6 @@ nsJSUtils::EvaluateString(JSContext* aCx,
nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
NS_ENSURE_TRUE(ssm->ScriptAllowed(aEvaluationGlobal), NS_OK);
mozilla::Maybe<AutoDontReportUncaught> dontReport;
if (!aEvaluateOptions.reportUncaught) {
// We need to prevent AutoLastFrameCheck from reporting and clearing
// any pending exceptions.
dontReport.emplace(aCx);
}
bool ok = true;
// Scope the JSAutoCompartment so that we can later wrap the return value
// into the caller's cx.
@ -275,24 +232,14 @@ nsJSUtils::EvaluateString(JSContext* aCx,
}
if (!ok) {
if (aEvaluateOptions.reportUncaught) {
ReportPendingException(aCx);
if (!aCompileOptions.noScriptRval) {
aRetValue.setUndefined();
}
} else {
rv = JS_IsExceptionPending(aCx) ? NS_ERROR_FAILURE
: NS_ERROR_OUT_OF_MEMORY;
JS::Rooted<JS::Value> exn(aCx);
JS_GetPendingException(aCx, &exn);
MOZ_ASSERT(!aCompileOptions.noScriptRval); // we asserted this on entry
aRetValue.set(exn);
JS_ClearPendingException(aCx);
rv = NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW;
if (!aCompileOptions.noScriptRval) {
aRetValue.setUndefined();
}
}
// Wrap the return value into whatever compartment aCx was in.
if (!aCompileOptions.noScriptRval) {
if (ok && !aCompileOptions.noScriptRval) {
if (!JS_WrapValue(aCx, aRetValue)) {
return NS_ERROR_OUT_OF_MEMORY;
}

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

@ -53,13 +53,6 @@ public:
*/
static uint64_t GetCurrentlyRunningCodeInnerWindowID(JSContext *aContext);
/**
* Report a pending exception on aContext, if any. Note that this
* can be called when the context has a JS stack. If that's the
* case, the stack will be set aside before reporting the exception.
*/
static void ReportPendingException(JSContext *aContext);
static nsresult CompileFunction(mozilla::dom::AutoJSAPI& jsapi,
JS::AutoObjectVector& aScopeChain,
JS::CompileOptions& aOptions,
@ -71,12 +64,10 @@ public:
struct MOZ_STACK_CLASS EvaluateOptions {
bool coerceToString;
bool reportUncaught;
JS::AutoObjectVector scopeChain;
explicit EvaluateOptions(JSContext* cx)
: coerceToString(false)
, reportUncaught(true)
, scopeChain(cx)
{}
@ -84,16 +75,13 @@ public:
coerceToString = aCoerce;
return *this;
}
EvaluateOptions& setReportUncaught(bool aReport) {
reportUncaught = aReport;
return *this;
}
};
// aEvaluationGlobal is the global to evaluate in. The return value
// will then be wrapped back into the compartment aCx is in when
// this function is called.
// this function is called. For all the EvaluateString overloads,
// the JSContext must come from an AutoJSAPI that has had
// TakeOwnershipOfErrorReporting() called on it.
static nsresult EvaluateString(JSContext* aCx,
const nsAString& aScript,
JS::Handle<JSObject*> aEvaluationGlobal,

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

@ -1120,6 +1120,7 @@ nsScriptLoader::EvaluateScript(nsScriptLoadRequest* aRequest,
// http://www.whatwg.org/specs/web-apps/current-work/#execute-the-script-block
AutoEntryScript entryScript(globalObject, "<script> element", true,
context->GetNativeContext());
entryScript.TakeOwnershipOfErrorReporting();
JS::Rooted<JSObject*> global(entryScript.cx(),
globalObject->GetGlobalJSObject());

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

@ -34,8 +34,6 @@
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/DOMError.h"
#include "mozilla/dom/DOMErrorBinding.h"
#include "mozilla/dom/DOMException.h"
#include "mozilla/dom/DOMExceptionBinding.h"
#include "mozilla/dom/ElementBinding.h"
#include "mozilla/dom/HTMLObjectElement.h"
#include "mozilla/dom/HTMLObjectElementBinding.h"
@ -284,26 +282,16 @@ ErrorResult::ReportJSExceptionFromJSImplementation(JSContext* aCx)
MOZ_ASSERT(!mMightHaveUnreportedJSException,
"Why didn't you tell us you planned to handle JS exceptions?");
dom::DOMException* domException;
nsresult rv =
UNWRAP_OBJECT(DOMException, &mJSException.toObject(), domException);
if (NS_SUCCEEDED(rv)) {
// Check for a DOMError, since we convert that into an Error in the content
// compartment. We can probably remove that now; see bug 1174954.
dom::DOMError* domError;
nsresult rv = UNWRAP_OBJECT(DOMError, &mJSException.toObject(), domError);
if (NS_FAILED(rv)) {
// Just report it.
ReportJSException(aCx);
return;
}
dom::DOMError* domError;
rv = UNWRAP_OBJECT(DOMError, &mJSException.toObject(), domError);
if (NS_FAILED(rv)) {
// Unwrapping really shouldn't fail here: if mExceptionHandling is set to
// eRethrowContentExceptions then the CallSetup destructor only stores an
// exception if it unwraps to DOMError or DOMException. If we reach this
// then either mExceptionHandling wasn't set to eRethrowContentExceptions
// and we shouldn't be calling ReportJSExceptionFromJSImplementation or
// something went really wrong.
NS_RUNTIMEABORT("We stored a non-DOMError exception!");
}
nsString message;
domError->GetMessage(message);

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

@ -6,10 +6,6 @@
#include "mozilla/dom/CallbackObject.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/DOMError.h"
#include "mozilla/dom/DOMErrorBinding.h"
#include "mozilla/dom/DOMException.h"
#include "mozilla/dom/DOMExceptionBinding.h"
#include "jsfriendapi.h"
#include "nsIScriptGlobalObject.h"
#include "nsIXPConnect.h"
@ -224,8 +220,7 @@ CallbackObject::CallSetup::ShouldRethrowException(JS::Handle<JS::Value> aExcepti
MOZ_ASSERT(mCompartment);
// Now we only want to throw an exception to the caller if the object that was
// thrown is a DOMError or DOMException object in the caller compartment
// (which we stored in mCompartment).
// thrown is in the caller compartment (which we stored in mCompartment).
if (!aException.isObject()) {
return false;
@ -233,14 +228,7 @@ CallbackObject::CallSetup::ShouldRethrowException(JS::Handle<JS::Value> aExcepti
JS::Rooted<JSObject*> obj(mCx, &aException.toObject());
obj = js::UncheckedUnwrap(obj, /* stopAtOuter = */ false);
if (js::GetObjectCompartment(obj) != mCompartment) {
return false;
}
DOMError* domError;
DOMException* domException;
return NS_SUCCEEDED(UNWRAP_OBJECT(DOMError, obj, domError)) ||
NS_SUCCEEDED(UNWRAP_OBJECT(DOMException, obj, domException));
return js::GetObjectCompartment(obj) == mCompartment;
}
CallbackObject::CallSetup::~CallSetup()

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

@ -142,9 +142,9 @@ ThrowAndReport(nsPIDOMWindow* aWindow, nsresult aRv, const char* aMessage)
if (NS_WARN_IF(!jsapi.InitWithLegacyErrorReporting(aWindow))) {
return;
}
jsapi.TakeOwnershipOfErrorReporting();
Throw(jsapi.cx(), aRv, aMessage);
(void) JS_ReportPendingException(jsapi.cx());
}
already_AddRefed<Exception>

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

@ -73,6 +73,22 @@ TestInterfaceJS.prototype = {
"NotSupportedError");
},
testThrowTypeError: function() {
throw new this._win.TypeError("We are a TypeError");
},
testThrowCallbackError: function(callback) {
callback();
},
testThrowXraySelfHosted: function() {
this._win.Array.indexOf();
},
testThrowSelfHosted: function() {
Array.indexOf();
},
testPromiseWithThrowingChromePromiseInit: function() {
return new this._win.Promise(function() {
noSuchMethodExistsYo1();

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

@ -51,9 +51,86 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1107592
"http://mochi.test:8888/tests/dom/bindings/test/test_exception_options_from_jsimplemented.html",
"Should still have the right file name");
is(e.lineNumber, 38, "Should still have the right line number");
todo_is(e.columnNumber, 7,
"No column number support for DOMException yet");
todo_isnot(e.columnNumber, 0,
"No column number support for DOMException yet");
}
try {
t.testThrowTypeError();
} catch (e) {
ok(e instanceof TypeError, "Should have a TypeError here");
ok(!(e instanceof DOMException), "Should not have DOMException here (2)");
ok(!("code" in e), "Should not have a 'code' property (2)");
is(e.name, "TypeError", "Should be named TypeError");
is(e.message, "We are a TypeError",
"Should also have the right message (2)");
is(e.stack,
"doTest@http://mochi.test:8888/tests/dom/bindings/test/test_exception_options_from_jsimplemented.html:59:7\n",
"Exception stack for TypeError should only show our code");
is(e.fileName,
"http://mochi.test:8888/tests/dom/bindings/test/test_exception_options_from_jsimplemented.html",
"Should still have the right file name for TypeError");
is(e.lineNumber, 59, "Should still have the right line number for TypeError");
is(e.columnNumber, 7, "Should have the right column number for TypeError");
}
try {
t.testThrowCallbackError(function() { Array.indexOf() });
} catch (e) {
ok(e instanceof TypeError, "Should have a TypeError here (3)");
ok(!(e instanceof DOMException), "Should not have DOMException here (3)");
ok(!("code" in e), "Should not have a 'code' property (3)");
is(e.name, "TypeError", "Should be named TypeError (3)");
is(e.message, "missing argument 0 when calling function Array.indexOf",
"Should also have the right message (3)");
is(e.stack,
"doTest/<@http://mochi.test:8888/tests/dom/bindings/test/test_exception_options_from_jsimplemented.html:78:45\n" +
"doTest@http://mochi.test:8888/tests/dom/bindings/test/test_exception_options_from_jsimplemented.html:78:7\n"
,
"Exception stack for TypeError should only show our code (3)");
is(e.fileName,
"http://mochi.test:8888/tests/dom/bindings/test/test_exception_options_from_jsimplemented.html",
"Should still have the right file name for TypeError (3)");
is(e.lineNumber, 78, "Should still have the right line number for TypeError (3)");
is(e.columnNumber, 45, "Should have the right column number for TypeError (3)");
}
try {
t.testThrowXraySelfHosted();
} catch (e) {
ok(!(e instanceof Error), "Should have an Exception here (4)");
ok(!(e instanceof DOMException), "Should not have DOMException here (4)");
ok(!("code" in e), "Should not have a 'code' property (4)");
is(e.name, "NS_ERROR_UNEXPECTED", "Name should be sanitized (4)");
is(e.message, "", "Message should be sanitized (5)");
is(e.stack,
"doTest@http://mochi.test:8888/tests/dom/bindings/test/test_exception_options_from_jsimplemented.html:99:7\n",
"Exception stack for sanitized exception should only show our code (4)");
is(e.filename,
"http://mochi.test:8888/tests/dom/bindings/test/test_exception_options_from_jsimplemented.html",
"Should still have the right file name for sanitized exception (4)");
is(e.lineNumber, 99, "Should still have the right line number for sanitized exception (4)");
todo_isnot(e.columnNumber, 0, "Should have the right column number for sanitized exception (4)");
}
try {
t.testThrowSelfHosted();
} catch (e) {
ok(!(e instanceof Error), "Should have an Exception here (5)");
ok(!(e instanceof DOMException), "Should not have DOMException here (5)");
ok(!("code" in e), "Should not have a 'code' property (5)");
is(e.name, "NS_ERROR_UNEXPECTED", "Name should be sanitized (5)");
is(e.message, "", "Message should be sanitized (5)");
is(e.stack,
"doTest@http://mochi.test:8888/tests/dom/bindings/test/test_exception_options_from_jsimplemented.html:117:7\n",
"Exception stack for sanitized exception should only show our code (5)");
is(e.filename,
"http://mochi.test:8888/tests/dom/bindings/test/test_exception_options_from_jsimplemented.html",
"Should still have the right file name for sanitized exception (5)");
is(e.lineNumber, 117, "Should still have the right line number for sanitized exception (5)");
todo_isnot(e.columnNumber, 0, "Should have the right column number for sanitized exception (5)");
}
SimpleTest.finish();
}

2
dom/cache/CacheTypes.ipdlh поставляемый
Просмотреть файл

@ -12,7 +12,6 @@ using HeadersGuardEnum from "mozilla/dom/cache/IPCUtils.h";
using RequestCredentials from "mozilla/dom/cache/IPCUtils.h";
using RequestMode from "mozilla/dom/cache/IPCUtils.h";
using RequestCache from "mozilla/dom/cache/IPCUtils.h";
using RequestContext from "mozilla/dom/cache/IPCUtils.h";
using ResponseType from "mozilla/dom/cache/IPCUtils.h";
using mozilla::void_t from "ipc/IPCMessageUtils.h";
using struct nsID from "nsID.h";
@ -63,7 +62,6 @@ struct CacheRequest
RequestCredentials credentials;
CacheReadStreamOrVoid body;
uint32_t contentPolicyType;
RequestContext context;
RequestCache requestCache;
};

58
dom/cache/DBSchema.cpp поставляемый
Просмотреть файл

@ -29,11 +29,11 @@ namespace dom {
namespace cache {
namespace db {
const int32_t kMaxWipeSchemaVersion = 11;
const int32_t kMaxWipeSchemaVersion = 13;
namespace {
const int32_t kLatestSchemaVersion = 11;
const int32_t kLatestSchemaVersion = 13;
const int32_t kMaxEntriesPerStatement = 255;
const uint32_t kPageSize = 4 * 1024;
@ -77,40 +77,6 @@ static_assert(int(RequestCredentials::Omit) == 0 &&
int(RequestCredentials::Include) == 2 &&
int(RequestCredentials::EndGuard_) == 3,
"RequestCredentials values are as expected");
static_assert(int(RequestContext::Audio) == 0 &&
int(RequestContext::Beacon) == 1 &&
int(RequestContext::Cspreport) == 2 &&
int(RequestContext::Download) == 3 &&
int(RequestContext::Embed) == 4 &&
int(RequestContext::Eventsource) == 5 &&
int(RequestContext::Favicon) == 6 &&
int(RequestContext::Fetch) == 7 &&
int(RequestContext::Font) == 8 &&
int(RequestContext::Form) == 9 &&
int(RequestContext::Frame) == 10 &&
int(RequestContext::Hyperlink) == 11 &&
int(RequestContext::Iframe) == 12 &&
int(RequestContext::Image) == 13 &&
int(RequestContext::Imageset) == 14 &&
int(RequestContext::Import) == 15 &&
int(RequestContext::Internal) == 16 &&
int(RequestContext::Location) == 17 &&
int(RequestContext::Manifest) == 18 &&
int(RequestContext::Object) == 19 &&
int(RequestContext::Ping) == 20 &&
int(RequestContext::Plugin) == 21 &&
int(RequestContext::Prefetch) == 22 &&
int(RequestContext::Script) == 23 &&
int(RequestContext::Serviceworker) == 24 &&
int(RequestContext::Sharedworker) == 25 &&
int(RequestContext::Subresource) == 26 &&
int(RequestContext::Style) == 27 &&
int(RequestContext::Track) == 28 &&
int(RequestContext::Video) == 29 &&
int(RequestContext::Worker) == 30 &&
int(RequestContext::Xmlhttprequest) == 31 &&
int(RequestContext::Xslt) == 32,
"RequestContext values are as expected");
static_assert(int(RequestCache::Default) == 0 &&
int(RequestCache::No_store) == 1 &&
int(RequestCache::Reload) == 2 &&
@ -291,7 +257,6 @@ CreateSchema(mozIStorageConnection* aConn)
"request_mode INTEGER NOT NULL, "
"request_credentials INTEGER NOT NULL, "
"request_contentpolicytype INTEGER NOT NULL, "
"request_context INTEGER NOT NULL, "
"request_cache INTEGER NOT NULL, "
"request_body_id TEXT NULL, "
"response_type INTEGER NOT NULL, "
@ -1462,7 +1427,6 @@ InsertEntry(mozIStorageConnection* aConn, CacheId aCacheId,
"request_mode, "
"request_credentials, "
"request_contentpolicytype, "
"request_context, "
"request_cache, "
"request_body_id, "
"response_type, "
@ -1484,7 +1448,6 @@ InsertEntry(mozIStorageConnection* aConn, CacheId aCacheId,
":request_mode, "
":request_credentials, "
":request_contentpolicytype, "
":request_context, "
":request_cache, "
":request_body_id, "
":response_type, "
@ -1533,10 +1496,6 @@ InsertEntry(mozIStorageConnection* aConn, CacheId aCacheId,
static_cast<int32_t>(aRequest.contentPolicyType()));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("request_context"),
static_cast<int32_t>(aRequest.context()));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("request_cache"),
static_cast<int32_t>(aRequest.requestCache()));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
@ -1780,7 +1739,6 @@ ReadRequest(mozIStorageConnection* aConn, EntryId aEntryId,
"request_mode, "
"request_credentials, "
"request_contentpolicytype, "
"request_context, "
"request_cache, "
"request_body_id "
"FROM entries "
@ -1830,25 +1788,19 @@ ReadRequest(mozIStorageConnection* aConn, EntryId aEntryId,
aSavedRequestOut->mValue.contentPolicyType() =
static_cast<nsContentPolicyType>(requestContentPolicyType);
int32_t requestContext;
rv = state->GetInt32(8, &requestContext);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
aSavedRequestOut->mValue.context() =
static_cast<RequestContext>(requestContext);
int32_t requestCache;
rv = state->GetInt32(9, &requestCache);
rv = state->GetInt32(8, &requestCache);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
aSavedRequestOut->mValue.requestCache() =
static_cast<RequestCache>(requestCache);
bool nullBody = false;
rv = state->GetIsNull(10, &nullBody);
rv = state->GetIsNull(9, &nullBody);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
aSavedRequestOut->mHasBodyId = !nullBody;
if (aSavedRequestOut->mHasBodyId) {
rv = ExtractId(state, 10, &aSavedRequestOut->mBodyId);
rv = ExtractId(state, 9, &aSavedRequestOut->mBodyId);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
}

5
dom/cache/IPCUtils.h поставляемый
Просмотреть файл

@ -39,11 +39,6 @@ namespace IPC {
mozilla::dom::RequestCache::Default,
mozilla::dom::RequestCache::EndGuard_> {};
template<>
struct ParamTraits<mozilla::dom::RequestContext> :
public ContiguousEnumSerializer<mozilla::dom::RequestContext,
mozilla::dom::RequestContext::Audio,
mozilla::dom::RequestContext::EndGuard_> {};
template<>
struct ParamTraits<mozilla::dom::ResponseType> :
public ContiguousEnumSerializer<mozilla::dom::ResponseType,
mozilla::dom::ResponseType::Basic,

5
dom/cache/TypeUtils.cpp поставляемый
Просмотреть файл

@ -177,7 +177,6 @@ TypeUtils::ToCacheRequest(CacheRequest& aOut, InternalRequest* aIn,
aOut.mode() = aIn->Mode();
aOut.credentials() = aIn->GetCredentialsMode();
aOut.contentPolicyType() = aIn->ContentPolicyType();
aOut.context() = aIn->Context();
aOut.requestCache() = aIn->GetCacheMode();
if (aBodyAction == IgnoreBody) {
@ -328,10 +327,6 @@ TypeUtils::ToInternalRequest(const CacheRequest& aIn)
internalRequest->SetMode(aIn.mode());
internalRequest->SetCredentialsMode(aIn.credentials());
internalRequest->SetContentPolicyType(aIn.contentPolicyType());
DebugOnly<RequestContext> contextAfterSetContentPolicyType = internalRequest->Context();
internalRequest->SetContext(aIn.context());
MOZ_ASSERT(contextAfterSetContentPolicyType.value == internalRequest->Context(),
"The RequestContext and nsContentPolicyType values should not get out of sync");
internalRequest->SetCacheMode(aIn.requestCache());
nsRefPtr<InternalHeaders> internalHeaders =

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

@ -894,6 +894,10 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
NS_ENSURE_TRUE(Preferences::GetRootBranch(), NS_ERROR_FAILURE);
bool disabled = Preferences::GetBool("webgl.disabled", false);
// TODO: When we have software webgl support we should use that instead.
disabled |= gfxPlatform::InSafeMode();
if (disabled) {
GenerateWarning("WebGL creation is disabled, and so disallowed here.");
return NS_ERROR_FAILURE;

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

@ -492,7 +492,16 @@ WebGLContext::GenerateWarning(const char* fmt, va_list ap)
// no need to print to stderr, as JS_ReportWarning takes care of this for us.
AutoJSContext cx;
if (!mCanvasElement) {
return;
}
AutoJSAPI api;
if (!api.Init(mCanvasElement->OwnerDoc()->GetScopeObject())) {
return;
}
JSContext* cx = api.cx();
JS_ReportWarning(cx, "WebGL: %s", buf);
if (!ShouldGenerateWarnings()) {
JS_ReportWarning(cx,

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

@ -39,7 +39,6 @@ InternalRequest::GetRequestConstructorCopy(nsIGlobalObject* aGlobal, ErrorResult
// The default referrer is already about:client.
copy->mContentPolicyType = nsIContentPolicy::TYPE_FETCH;
copy->mContext = RequestContext::Fetch;
copy->mMode = mMode;
copy->mCredentialsMode = mCredentialsMode;
copy->mCacheMode = mCacheMode;
@ -76,7 +75,6 @@ InternalRequest::InternalRequest(const InternalRequest& aOther)
, mURL(aOther.mURL)
, mHeaders(new InternalHeaders(*aOther.mHeaders))
, mContentPolicyType(aOther.mContentPolicyType)
, mContext(aOther.mContext)
, mReferrer(aOther.mReferrer)
, mMode(aOther.mMode)
, mCredentialsMode(aOther.mCredentialsMode)
@ -104,78 +102,85 @@ void
InternalRequest::SetContentPolicyType(nsContentPolicyType aContentPolicyType)
{
mContentPolicyType = aContentPolicyType;
}
/* static */
RequestContext
InternalRequest::MapContentPolicyTypeToRequestContext(nsContentPolicyType aContentPolicyType)
{
RequestContext context = RequestContext::Internal;
switch (aContentPolicyType) {
case nsIContentPolicy::TYPE_OTHER:
mContext = RequestContext::Internal;
context = RequestContext::Internal;
break;
case nsIContentPolicy::TYPE_SCRIPT:
mContext = RequestContext::Script;
context = RequestContext::Script;
break;
case nsIContentPolicy::TYPE_IMAGE:
mContext = RequestContext::Image;
context = RequestContext::Image;
break;
case nsIContentPolicy::TYPE_STYLESHEET:
mContext = RequestContext::Style;
context = RequestContext::Style;
break;
case nsIContentPolicy::TYPE_OBJECT:
mContext = RequestContext::Object;
context = RequestContext::Object;
break;
case nsIContentPolicy::TYPE_DOCUMENT:
mContext = RequestContext::Internal;
context = RequestContext::Internal;
break;
case nsIContentPolicy::TYPE_SUBDOCUMENT:
mContext = RequestContext::Iframe;
context = RequestContext::Iframe;
break;
case nsIContentPolicy::TYPE_REFRESH:
mContext = RequestContext::Internal;
context = RequestContext::Internal;
break;
case nsIContentPolicy::TYPE_XBL:
mContext = RequestContext::Internal;
context = RequestContext::Internal;
break;
case nsIContentPolicy::TYPE_PING:
mContext = RequestContext::Ping;
context = RequestContext::Ping;
break;
case nsIContentPolicy::TYPE_XMLHTTPREQUEST:
mContext = RequestContext::Xmlhttprequest;
context = RequestContext::Xmlhttprequest;
break;
case nsIContentPolicy::TYPE_OBJECT_SUBREQUEST:
mContext = RequestContext::Plugin;
context = RequestContext::Plugin;
break;
case nsIContentPolicy::TYPE_DTD:
mContext = RequestContext::Internal;
context = RequestContext::Internal;
break;
case nsIContentPolicy::TYPE_FONT:
mContext = RequestContext::Font;
context = RequestContext::Font;
break;
case nsIContentPolicy::TYPE_MEDIA:
mContext = RequestContext::Audio;
context = RequestContext::Audio;
break;
case nsIContentPolicy::TYPE_WEBSOCKET:
mContext = RequestContext::Internal;
context = RequestContext::Internal;
break;
case nsIContentPolicy::TYPE_CSP_REPORT:
mContext = RequestContext::Cspreport;
context = RequestContext::Cspreport;
break;
case nsIContentPolicy::TYPE_XSLT:
mContext = RequestContext::Xslt;
context = RequestContext::Xslt;
break;
case nsIContentPolicy::TYPE_BEACON:
mContext = RequestContext::Beacon;
context = RequestContext::Beacon;
break;
case nsIContentPolicy::TYPE_FETCH:
mContext = RequestContext::Fetch;
context = RequestContext::Fetch;
break;
case nsIContentPolicy::TYPE_IMAGESET:
mContext = RequestContext::Imageset;
context = RequestContext::Imageset;
break;
case nsIContentPolicy::TYPE_WEB_MANIFEST:
mContext = RequestContext::Manifest;
context = RequestContext::Manifest;
break;
default:
MOZ_ASSERT(false, "Unhandled nsContentPolicyType value");
mContext = RequestContext::Internal;
break;
}
return context;
}
} // namespace dom

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

@ -26,8 +26,7 @@ namespace dom {
/*
* The mapping of RequestContext and nsContentPolicyType is currently as the
* following. Note that this mapping is not perfect yet (see the TODO comments
* below for examples), so for now we'll have to keep both an mContext and an
* mContentPolicyType, because we cannot have a two way conversion.
* below for examples).
*
* RequestContext | nsContentPolicyType
* ------------------+--------------------
@ -55,7 +54,6 @@ namespace dom {
* plugin | TYPE_OBJECT_SUBREQUEST
* prefetch |
* script | TYPE_SCRIPT
* serviceworker |
* sharedworker |
* subresource | Not supported by Gecko
* style | TYPE_STYLESHEET
@ -282,13 +280,7 @@ public:
RequestContext
Context() const
{
return mContext;
}
void
SetContext(RequestContext aContext)
{
mContext = aContext;
return MapContentPolicyTypeToRequestContext(mContentPolicyType);
}
bool
@ -372,13 +364,15 @@ private:
~InternalRequest();
static RequestContext
MapContentPolicyTypeToRequestContext(nsContentPolicyType aContentPolicyType);
nsCString mMethod;
nsCString mURL;
nsRefPtr<InternalHeaders> mHeaders;
nsCOMPtr<nsIInputStream> mBodyStream;
nsContentPolicyType mContentPolicyType;
RequestContext mContext;
// Empty string: no-referrer
// "about:client": client (default)

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

@ -79,13 +79,6 @@ public:
return mRequest->Context();
}
// [ChromeOnly]
void
SetContext(RequestContext aContext)
{
mRequest->SetContext(aContext);
}
void
SetContentPolicyType(nsContentPolicyType aContentPolicyType)
{

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

@ -81,7 +81,7 @@ Directory::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
}
void
Directory::GetName(nsString& aRetval) const
Directory::GetName(nsAString& aRetval) const
{
aRetval.Truncate();

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

@ -59,7 +59,7 @@ public:
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
void
GetName(nsString& aRetval) const;
GetName(nsAString& aRetval) const;
already_AddRefed<Promise>
CreateFile(const nsAString& aPath, const CreateFileOptions& aOptions,

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

@ -113,6 +113,7 @@
#include "nsFocusManager.h"
#include "nsIFrame.h"
#include "nsIContent.h"
#include "nsLayoutStylesheetCache.h"
using namespace mozilla;
using namespace mozilla::dom;
@ -146,26 +147,6 @@ static bool ConvertToMidasInternalCommand(const nsAString & inCommandID,
// ==================================================================
// =
// ==================================================================
static nsresult
RemoveFromAgentSheets(nsCOMArray<nsIStyleSheet> &aAgentSheets, const nsAString& url)
{
nsCOMPtr<nsIURI> uri;
nsresult rv = NS_NewURI(getter_AddRefs(uri), url);
NS_ENSURE_SUCCESS(rv, rv);
for (int32_t i = aAgentSheets.Count() - 1; i >= 0; --i) {
nsIStyleSheet* sheet = aAgentSheets[i];
nsIURI* sheetURI = sheet->GetSheetURI();
bool equals = false;
uri->Equals(sheetURI, &equals);
if (equals) {
aAgentSheets.RemoveObjectAt(i);
}
}
return NS_OK;
}
nsresult
NS_NewHTMLDocument(nsIDocument** aInstancePtrResult, bool aLoadedAsData)
@ -2660,9 +2641,9 @@ nsHTMLDocument::TearingDownEditor(nsIEditor *aEditor)
nsCOMArray<nsIStyleSheet> agentSheets;
presShell->GetAgentStyleSheets(agentSheets);
RemoveFromAgentSheets(agentSheets, NS_LITERAL_STRING("resource://gre/res/contenteditable.css"));
agentSheets.RemoveObject(nsLayoutStylesheetCache::ContentEditableSheet());
if (oldState == eDesignMode)
RemoveFromAgentSheets(agentSheets, NS_LITERAL_STRING("resource://gre/res/designmode.css"));
agentSheets.RemoveObject(nsLayoutStylesheetCache::DesignModeSheet());
presShell->SetAgentStyleSheets(agentSheets);
@ -2800,41 +2781,34 @@ nsHTMLDocument::EditingStateChanged()
rv = presShell->GetAgentStyleSheets(agentSheets);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIURI> uri;
rv = NS_NewURI(getter_AddRefs(uri),
NS_LITERAL_STRING("resource://gre/res/contenteditable.css"));
NS_ENSURE_SUCCESS(rv, rv);
CSSStyleSheet* contentEditableSheet =
nsLayoutStylesheetCache::ContentEditableSheet();
nsRefPtr<CSSStyleSheet> sheet;
rv = LoadChromeSheetSync(uri, true, getter_AddRefs(sheet));
NS_ENSURE_TRUE(sheet, rv);
bool result;
bool result = agentSheets.AppendObject(sheet);
NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY);
if (!agentSheets.Contains(contentEditableSheet)) {
bool result = agentSheets.AppendObject(contentEditableSheet);
NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY);
}
// Should we update the editable state of all the nodes in the document? We
// need to do this when the designMode value changes, as that overrides
// specific states on the elements.
if (designMode) {
// designMode is being turned on (overrides contentEditable).
rv = NS_NewURI(getter_AddRefs(uri),
NS_LITERAL_STRING("resource://gre/res/designmode.css"));
NS_ENSURE_SUCCESS(rv, rv);
rv = LoadChromeSheetSync(uri, true, getter_AddRefs(sheet));
NS_ENSURE_TRUE(sheet, rv);
result = agentSheets.AppendObject(sheet);
NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY);
CSSStyleSheet* designModeSheet =
nsLayoutStylesheetCache::DesignModeSheet();
if (!agentSheets.Contains(designModeSheet)) {
result = agentSheets.AppendObject(designModeSheet);
NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY);
}
updateState = true;
spellRecheckAll = oldState == eContentEditable;
}
else if (oldState == eDesignMode) {
// designMode is being turned off (contentEditable is still on).
RemoveFromAgentSheets(agentSheets,
NS_LITERAL_STRING("resource://gre/res/designmode.css"));
agentSheets.RemoveObject(nsLayoutStylesheetCache::DesignModeSheet());
updateState = true;
}

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

@ -125,7 +125,7 @@ BlobImplSnapshot::CreateSlice(uint64_t aStart,
void
BlobImplSnapshot::GetMozFullPathInternal(nsAString& aFilename,
ErrorResult& aRv)
ErrorResult& aRv) const
{
AssertSanity();
MOZ_ASSERT(mIsFile);

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

@ -74,7 +74,7 @@ private:
#endif
virtual void
GetMozFullPathInternal(nsAString& aFullPath, ErrorResult& aRv) override;
GetMozFullPathInternal(nsAString& aFullPath, ErrorResult& aRv) const override;
virtual void
GetInternalStream(nsIInputStream** aStream, ErrorResult& aRv) override;

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

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

@ -63,6 +63,18 @@ function testSteps()
// This one lives in storage/default/file++++c++
{ url: "file:///c:/", dbName: "dbQ", dbVersion: 1 },
// This one lives in storage/default/file++++Users+joe+c+++index.html
{ url: "file:///Users/joe/c++/index.html", dbName: "dbR", dbVersion: 1 },
// This one lives in storage/default/file++++Users+joe+c+++index.html
{ url: "file:///Users/joe/c///index.html", dbName: "dbR", dbVersion: 1 },
// This one lives in storage/default/file++++++index.html
{ url: "file:///+/index.html", dbName: "dbS", dbVersion: 1 },
// This one lives in storage/default/file++++++index.html
{ url: "file://///index.html", dbName: "dbS", dbVersion: 1 },
// This one lives in storage/temporary/http+++localhost
{ url: "http://localhost", dbName: "dbZ",
dbOptions: { version: 1, storage: "temporary" } }

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

@ -1918,7 +1918,7 @@ public:
NS_DECL_ISUPPORTS_INHERITED
virtual void
GetMozFullPathInternal(nsAString& aFileName, ErrorResult& aRv) override;
GetMozFullPathInternal(nsAString& aFileName, ErrorResult& aRv) const override;
virtual already_AddRefed<BlobImpl>
CreateSlice(uint64_t aStart,
@ -2078,10 +2078,10 @@ public:
SetLastModified(int64_t aLastModified) override;
virtual void
GetMozFullPath(nsAString& aName, ErrorResult& aRv) override;
GetMozFullPath(nsAString& aName, ErrorResult& aRv) const override;
virtual void
GetMozFullPathInternal(nsAString& aFileName, ErrorResult& aRv) override;
GetMozFullPathInternal(nsAString& aFileName, ErrorResult& aRv) const override;
virtual uint64_t
GetSize(ErrorResult& aRv) override;
@ -2319,7 +2319,7 @@ NS_IMPL_QUERY_INTERFACE_INHERITED(BlobChild::RemoteBlobImpl,
void
BlobChild::
RemoteBlobImpl::GetMozFullPathInternal(nsAString& aFilePath,
ErrorResult& aRv)
ErrorResult& aRv) const
{
if (!EventTargetIsOnCurrentThread(mActorTarget)) {
MOZ_CRASH("Not implemented!");
@ -2774,14 +2774,14 @@ RemoteBlobImpl::SetLastModified(int64_t aLastModified)
void
BlobParent::
RemoteBlobImpl::GetMozFullPath(nsAString& aName, ErrorResult& aRv)
RemoteBlobImpl::GetMozFullPath(nsAString& aName, ErrorResult& aRv) const
{
mBlobImpl->GetMozFullPath(aName, aRv);
}
void
BlobParent::
RemoteBlobImpl::GetMozFullPathInternal(nsAString& aFileName, ErrorResult& aRv)
RemoteBlobImpl::GetMozFullPathInternal(nsAString& aFileName, ErrorResult& aRv) const
{
mBlobImpl->GetMozFullPathInternal(aFileName, aRv);
}

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

@ -423,6 +423,7 @@ TabChildBase::HandlePossibleViewportChange(const ScreenIntSize& aOldScreenSize)
defaultZoom <= viewportInfo.GetMaxZoom());
metrics.SetZoom(CSSToParentLayerScale2D(ConvertScaleForRoot(defaultZoom)));
metrics.SetPresShellId(presShellId);
metrics.SetScrollId(viewId);
}
@ -561,13 +562,9 @@ TabChildBase::UpdateFrameHandler(const FrameMetrics& aFrameMetrics)
} else {
// aFrameMetrics.mIsRoot is false, so we are trying to update a subframe.
// This requires special handling.
nsCOMPtr<nsIContent> content = nsLayoutUtils::FindContentFor(
aFrameMetrics.GetScrollId());
if (content) {
FrameMetrics newSubFrameMetrics(aFrameMetrics);
APZCCallbackHelper::UpdateSubFrame(content, newSubFrameMetrics);
return true;
}
FrameMetrics newSubFrameMetrics(aFrameMetrics);
APZCCallbackHelper::UpdateSubFrame(newSubFrameMetrics);
return true;
}
return true;
}
@ -580,9 +577,7 @@ TabChildBase::ProcessUpdateFrame(const FrameMetrics& aFrameMetrics)
}
FrameMetrics newMetrics = aFrameMetrics;
if (nsCOMPtr<nsIPresShell> presShell = GetPresShell()) {
APZCCallbackHelper::UpdateRootFrame(presShell, newMetrics);
}
APZCCallbackHelper::UpdateRootFrame(newMetrics);
CSSSize cssCompositedSize = newMetrics.CalculateCompositedSizeInCssPixels();
// The BrowserElementScrolling helper must know about these updated metrics

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

@ -79,7 +79,7 @@ function fetchManifest() {
reqInit.credentials = 'include';
}
const req = new content.Request(manifestURL, reqInit);
req.setContext('manifest');
req.setContentPolicyType(Ci.nsIContentPolicy.TYPE_WEB_MANIFEST);
const response = yield content.fetch(req);
const manifest = yield processResponse(response, content);
return manifest;

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

@ -251,6 +251,10 @@ nsresult nsJSThunk::EvaluateScript(nsIChannel *aChannel,
// http://www.whatwg.org/specs/web-apps/current-work/#javascript-protocol
AutoEntryScript entryScript(innerGlobal, "javascript: URI", true,
scriptContext->GetNativeContext());
// We want to make sure we report any exceptions that happen before we
// return, since whatever happens inside our execution shouldn't affect any
// other scripts that might happen to be running.
entryScript.TakeOwnershipOfErrorReporting();
JSContext* cx = entryScript.cx();
JS::Rooted<JSObject*> globalJSObject(cx, innerGlobal->GetGlobalJSObject());
NS_ENSURE_TRUE(globalJSObject, NS_ERROR_UNEXPECTED);
@ -278,20 +282,13 @@ nsresult nsJSThunk::EvaluateScript(nsIChannel *aChannel,
rv = nsJSUtils::EvaluateString(cx, NS_ConvertUTF8toUTF16(script),
globalJSObject, options, evalOptions, &v);
// If there's an error on cx as a result of that call, report
// it now -- either we're just running under the event loop,
// so we shouldn't propagate JS exceptions out of here, or we
// can't be sure that our caller is JS (and if it's not we'll
// lose the error), or it might be JS that then proceeds to
// cause an error of its own (which will also make us lose
// this error).
::JS_ReportPendingException(cx);
if (NS_FAILED(rv) || !(v.isString() || v.isUndefined())) {
return NS_ERROR_MALFORMED_URI;
} else if (v.isUndefined()) {
return NS_ERROR_DOM_RETVAL_UNDEFINED;
} else {
MOZ_ASSERT(rv != NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW,
"How did we get a non-undefined return value?");
nsAutoJSString result;
if (!result.init(cx, v)) {
return NS_ERROR_OUT_OF_MEMORY;

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

@ -104,12 +104,13 @@ void InitPreferredSampleRate()
cubeb* GetCubebContextUnlocked()
{
sMutex.AssertCurrentThreadOwns();
if (sCubebContext ||
cubeb_init(&sCubebContext, "CubebUtils") == CUBEB_OK) {
return sCubebContext;
if (!sCubebContext) {
MOZ_ASSERT(NS_IsMainThread());
if (cubeb_init(&sCubebContext, "CubebUtils") != CUBEB_OK) {
NS_WARNING("cubeb_init failed");
}
}
NS_WARNING("cubeb_init failed");
return nullptr;
return sCubebContext;
}
uint32_t GetCubebLatency()

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

@ -56,10 +56,6 @@
#include "RtspOmxDecoder.h"
#include "RtspOmxReader.h"
#endif
#ifdef MOZ_WMF
#include "WMFDecoder.h"
#include "WMFReader.h"
#endif
#ifdef MOZ_DIRECTSHOW
#include "DirectShowDecoder.h"
#include "DirectShowReader.h"
@ -334,14 +330,6 @@ IsAndroidMediaType(const nsACString& aType)
}
#endif
#ifdef MOZ_WMF
static bool
IsWMFSupportedType(const nsACString& aType)
{
return WMFDecoder::CanPlayType(aType, NS_LITERAL_STRING(""));
}
#endif
#ifdef MOZ_DIRECTSHOW
static bool
IsDirectShowSupportedType(const nsACString& aType)
@ -481,23 +469,10 @@ DecoderTraits::CanHandleMediaType(const char* aMIMEType,
}
#endif
#ifdef MOZ_DIRECTSHOW
// Note: DirectShow should come before WMF, so that we prefer DirectShow's
// MP3 support over WMF's.
if (DirectShowDecoder::GetSupportedCodecs(nsDependentCString(aMIMEType), &codecList)) {
result = CANPLAY_MAYBE;
}
#endif
#ifdef MOZ_WMF
if (!Preferences::GetBool("media.fragmented-mp4.exposed", false) &&
IsWMFSupportedType(nsDependentCString(aMIMEType))) {
if (!aHaveRequestedCodecs) {
return CANPLAY_MAYBE;
}
return WMFDecoder::CanPlayType(nsDependentCString(aMIMEType),
aRequestedCodecs)
? CANPLAY_YES : CANPLAY_NO;
}
#endif
#ifdef MOZ_APPLEMEDIA
if (IsAppleMediaSupportedType(nsDependentCString(aMIMEType), &codecList)) {
result = CANPLAY_MAYBE;
@ -637,12 +612,6 @@ InstantiateDecoder(const nsACString& aType, MediaDecoderOwner* aOwner)
return decoder.forget();
}
#endif
#ifdef MOZ_WMF
if (IsWMFSupportedType(aType)) {
decoder = new WMFDecoder();
return decoder.forget();
}
#endif
#ifdef MOZ_APPLEMEDIA
if (IsAppleMediaSupportedType(aType)) {
decoder = new AppleDecoder();
@ -727,17 +696,10 @@ MediaDecoderReader* DecoderTraits::CreateReader(const nsACString& aType, Abstrac
} else
#endif
#ifdef MOZ_DIRECTSHOW
// Note: DirectShowReader is preferred for MP3, but if it's disabled we
// fallback to the WMFReader.
if (IsDirectShowSupportedType(aType)) {
decoderReader = new DirectShowReader(aDecoder);
} else
#endif
#ifdef MOZ_WMF
if (IsWMFSupportedType(aType)) {
decoderReader = new WMFReader(aDecoder);
} else
#endif
#ifdef MOZ_APPLEMEDIA
if (IsAppleMediaSupportedType(aType)) {
decoderReader = new AppleMP3Reader(aDecoder);
@ -781,9 +743,6 @@ bool DecoderTraits::IsSupportedInVideoDocument(const nsACString& aType)
IsMP4SupportedType(aType) ||
#endif
IsMP3SupportedType(aType) ||
#ifdef MOZ_WMF
IsWMFSupportedType(aType) ||
#endif
#ifdef MOZ_DIRECTSHOW
IsDirectShowSupportedType(aType) ||
#endif

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

@ -10,6 +10,7 @@
#include <limits>
#include "nsIObserver.h"
#include "nsTArray.h"
#include "CubebUtils.h"
#include "VideoUtils.h"
#include "MediaDecoderStateMachine.h"
#include "ImageContainer.h"
@ -28,10 +29,6 @@
#include "mozilla/dom/VideoTrack.h"
#include "mozilla/dom/VideoTrackList.h"
#ifdef MOZ_WMF
#include "WMFDecoder.h"
#endif
using namespace mozilla::dom;
using namespace mozilla::layers;
using namespace mozilla::media;
@ -404,6 +401,11 @@ bool MediaDecoder::Init(MediaDecoderOwner* aOwner)
mOwner = aOwner;
mVideoFrameContainer = aOwner->GetVideoFrameContainer();
MediaShutdownManager::Instance().Register(this);
// We don't use the cubeb context yet, but need to ensure it is created on
// the main thread.
if (!CubebUtils::GetCubebContext()) {
NS_WARNING("Audio backend initialization failed.");
}
return true;
}
@ -1509,14 +1511,6 @@ MediaDecoder::IsAndroidMediaEnabled()
}
#endif
#ifdef MOZ_WMF
bool
MediaDecoder::IsWMFEnabled()
{
return WMFDecoder::IsEnabled();
}
#endif
#ifdef MOZ_APPLEMEDIA
bool
MediaDecoder::IsAppleMP3Enabled()

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

@ -159,10 +159,11 @@ MediaTaskQueue::AwaitShutdownAndIdle()
nsRefPtr<ShutdownPromise>
MediaTaskQueue::BeginShutdown()
{
// Make sure there are no tasks for this queue waiting in the caller's tail
// dispatcher.
MOZ_ASSERT_IF(AbstractThread::GetCurrent(),
!AbstractThread::GetCurrent()->TailDispatcher().HasTasksFor(this));
// Dispatch any tasks for this queue waiting in the caller's tail dispatcher,
// since this is the last opportunity to do so.
if (AbstractThread* currentThread = AbstractThread::GetCurrent()) {
currentThread->TailDispatcher().DispatchTasksFor(this);
}
MonitorAutoLock mon(mQueueMonitor);
mIsShutdown = true;

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

@ -56,6 +56,7 @@ public:
already_AddRefed<nsIRunnable> aRunnable,
AbstractThread::DispatchFailureHandling aFailureHandling = AbstractThread::AssertDispatchSuccess) = 0;
virtual void DispatchTasksFor(AbstractThread* aThread) = 0;
virtual bool HasTasksFor(AbstractThread* aThread) = 0;
virtual void DrainDirectTasks() = 0;
};
@ -82,14 +83,7 @@ public:
MOZ_ASSERT(mDirectTasks.empty());
for (size_t i = 0; i < mTaskGroups.Length(); ++i) {
UniquePtr<PerThreadTaskGroup> group(Move(mTaskGroups[i]));
nsRefPtr<AbstractThread> thread = group->mThread;
AbstractThread::DispatchFailureHandling failureHandling = group->mFailureHandling;
AbstractThread::DispatchReason reason = mIsTailDispatcher ? AbstractThread::TailDispatch
: AbstractThread::NormalDispatch;
nsCOMPtr<nsIRunnable> r = new TaskGroupRunnable(Move(group));
thread->Dispatch(r.forget(), failureHandling, reason);
DispatchTaskGroup(Move(mTaskGroups[i]));
}
}
@ -132,6 +126,17 @@ public:
return !!GetTaskGroup(aThread) || (aThread == AbstractThread::GetCurrent() && !mDirectTasks.empty());
}
void DispatchTasksFor(AbstractThread* aThread) override
{
for (size_t i = 0; i < mTaskGroups.Length(); ++i) {
if (mTaskGroups[i]->mThread == aThread) {
DispatchTaskGroup(Move(mTaskGroups[i]));
mTaskGroups.RemoveElementAt(i);
return;
}
}
}
private:
struct PerThreadTaskGroup
@ -215,6 +220,17 @@ private:
return nullptr;
}
void DispatchTaskGroup(UniquePtr<PerThreadTaskGroup> aGroup)
{
nsRefPtr<AbstractThread> thread = aGroup->mThread;
AbstractThread::DispatchFailureHandling failureHandling = aGroup->mFailureHandling;
AbstractThread::DispatchReason reason = mIsTailDispatcher ? AbstractThread::TailDispatch
: AbstractThread::NormalDispatch;
nsCOMPtr<nsIRunnable> r = new TaskGroupRunnable(Move(aGroup));
thread->Dispatch(r.forget(), failureHandling, reason);
}
// Direct tasks.
std::queue<nsCOMPtr<nsIRunnable>> mDirectTasks;

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

@ -54,9 +54,6 @@ if CONFIG['MOZ_DIRECTSHOW']:
if CONFIG['MOZ_ANDROID_OMX']:
DIRS += ['android']
if CONFIG['MOZ_WMF']:
DIRS += ['wmf']
if CONFIG['MOZ_FMP4']:
DIRS += ['fmp4']

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