Merge mozilla-central to mozilla-inbound

This commit is contained in:
Carsten "Tomcat" Book 2015-11-26 16:56:09 +01:00
commit 7677a80971
219 changed files with 2429 additions and 734 deletions

View File

@ -38,6 +38,6 @@ exports.encode = function (data, charset) {
if (isUTF8(charset))
return btoa(unescape(encodeURIComponent(data)))
data = String.fromCharCode(...[(c.charCodeAt(0) & 0xff) for (c of data)]);
data = String.fromCharCode(...Array.from(data, c => (c.charCodeAt(0) & 0xff)));
return btoa(data);
}

View File

@ -307,7 +307,7 @@ function getItemWorkerForWindow(item, window) {
var RemoteItem = Class({
initialize: function(options, manager) {
this.id = options.id;
this.contexts = [instantiateContext(c) for (c of options.contexts)];
this.contexts = options.contexts.map(instantiateContext);
this.contentScript = options.contentScript;
this.contentScriptFile = options.contentScriptFile;

View File

@ -90,7 +90,7 @@ function makeChildOptions(options) {
function makeStringArray(arrayOrValue) {
if (!arrayOrValue)
return [];
return [String(v) for (v of [].concat(arrayOrValue))];
return [].concat(arrayOrValue).map(String);
}
return {

View File

@ -355,7 +355,7 @@ function itemActivated(item, clickedNode) {
function serializeItem(item) {
return {
id: internal(item).id,
contexts: [c.serialize() for (c of item.context)],
contexts: item.context.map(c => c.serialize()),
contentScript: item.contentScript,
contentScriptFile: item.contentScriptFile,
};

View File

@ -380,7 +380,7 @@ TestRunner.prototype = {
name: this.test.name,
passed: this.test.passed,
failed: this.test.failed,
errors: [error for (error in this.test.errors)].join(", ")
errors: Object.keys(this.test.errors).join(", ")
});
if (this.onDone !== null) {

View File

@ -193,7 +193,7 @@ function showResults() {
var data = ref.__url__ ? ref.__url__ : ref;
var warning = data == "[object Object]"
? "[object " + data.constructor.name + "(" +
[p for (p in data)].join(", ") + ")]"
Object.keys(data).join(", ") + ")]"
: data;
console.warn("LEAK", warning, info.bin);
}
@ -461,8 +461,7 @@ var consoleListener = {
testConsole.error(message);
return;
}
var pointless = [err for (err of POINTLESS_ERRORS)
if (message.indexOf(err) >= 0)];
var pointless = POINTLESS_ERRORS.filter(err => message.indexOf(err) >= 0);
if (pointless.length == 0 && message)
testConsole.log(message);
}

View File

@ -62,7 +62,7 @@ var dispatcher = _ => {
// starting a dispatch loop, in order to ignore timers registered
// in side effect to dispatch while also skipping immediates that
// were removed in side effect.
let ids = [id for ([id] of immediates)];
let ids = [...immediates.keys()];
for (let id of ids) {
let immediate = immediates.get(id);
if (immediate) {

View File

@ -65,12 +65,9 @@ exports.testBasename = function(assert) {
exports.testList = function(assert) {
let list = file.list(profilePath);
let found = [ true for (name of list)
if (name === fileNameInProfile) ];
let found = list.filter(name => name === fileNameInProfile);
if (found.length > 1)
assert.fail("a dir can't contain two files of the same name!");
assert.equal(found[0], true, "file.list() should work");
assert.equal(found.length, 1, "file.list() should work");
assert.throws(function() {
file.list(filePathInProfile);

View File

@ -35,7 +35,7 @@ function serializeServiceWorkerInfo(aServiceWorkerInfo) {
}
if (property === "principal") {
result.principal = {
origin: aServiceWorkerInfo.principal.origin,
origin: aServiceWorkerInfo.principal.originNoSuffix,
originAttributes: aServiceWorkerInfo.principal.originAttributes
};
return;

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9eca89f04628c99226e0d18c15d5ae11b71af0cf"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="86959c405348d27ba5686956ae3a8ffc274d3db8"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9a58f2e395da17c252f61f28900b5b09aeb813bd"/>
@ -24,7 +24,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
<project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ce651a7711042301cbc9c6866be0eeb9e1ceab66"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="5de6856fad82857028f9f059f50680a9bea5b75c"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9eca89f04628c99226e0d18c15d5ae11b71af0cf"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="86959c405348d27ba5686956ae3a8ffc274d3db8"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9a58f2e395da17c252f61f28900b5b09aeb813bd"/>
@ -24,7 +24,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
<project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ce651a7711042301cbc9c6866be0eeb9e1ceab66"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="5de6856fad82857028f9f059f50680a9bea5b75c"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>

View File

@ -15,7 +15,7 @@
<remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
<default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
<!-- Gecko and Gaia -->
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="9eca89f04628c99226e0d18c15d5ae11b71af0cf"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="86959c405348d27ba5686956ae3a8ffc274d3db8"/>
<!-- Gonk-specific things and forks -->
<project name="platform_bionic" path="bionic" remote="b2g" revision="e2b3733ba3fa5e3f404e983d2e4142b1f6b1b846"/>
<project name="platform_build" path="build" remote="b2g" revision="1b0db93fb6b870b03467aff50d6419771ba0d88c">

View File

@ -17,10 +17,10 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9eca89f04628c99226e0d18c15d5ae11b71af0cf"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="86959c405348d27ba5686956ae3a8ffc274d3db8"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9a58f2e395da17c252f61f28900b5b09aeb813bd"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="ac7e9ae8a24ab4a3f3da801ca53f95f39a32b89f"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ce651a7711042301cbc9c6866be0eeb9e1ceab66"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="5de6856fad82857028f9f059f50680a9bea5b75c"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
<project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9eca89f04628c99226e0d18c15d5ae11b71af0cf"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="86959c405348d27ba5686956ae3a8ffc274d3db8"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9a58f2e395da17c252f61f28900b5b09aeb813bd"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
<project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ce651a7711042301cbc9c6866be0eeb9e1ceab66"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="5de6856fad82857028f9f059f50680a9bea5b75c"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="f92a936f2aa97526d4593386754bdbf02db07a12"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9eca89f04628c99226e0d18c15d5ae11b71af0cf"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="86959c405348d27ba5686956ae3a8ffc274d3db8"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9a58f2e395da17c252f61f28900b5b09aeb813bd"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
<project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ce651a7711042301cbc9c6866be0eeb9e1ceab66"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="5de6856fad82857028f9f059f50680a9bea5b75c"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
<!-- Stock Android things -->
<project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="ffc05a232799fe8fcb3e47b7440b52b1fb4244c0"/>

View File

@ -15,7 +15,7 @@
<remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
<default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
<!-- Gecko and Gaia -->
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="9eca89f04628c99226e0d18c15d5ae11b71af0cf"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="86959c405348d27ba5686956ae3a8ffc274d3db8"/>
<!-- Gonk-specific things and forks -->
<project name="platform_bionic" path="bionic" remote="b2g" revision="e2b3733ba3fa5e3f404e983d2e4142b1f6b1b846"/>
<project name="platform_build" path="build" remote="b2g" revision="1b0db93fb6b870b03467aff50d6419771ba0d88c">

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9eca89f04628c99226e0d18c15d5ae11b71af0cf"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="86959c405348d27ba5686956ae3a8ffc274d3db8"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9a58f2e395da17c252f61f28900b5b09aeb813bd"/>
@ -24,7 +24,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
<project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ce651a7711042301cbc9c6866be0eeb9e1ceab66"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="5de6856fad82857028f9f059f50680a9bea5b75c"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>

View File

@ -1,9 +1,9 @@
{
"git": {
"git_revision": "9eca89f04628c99226e0d18c15d5ae11b71af0cf",
"git_revision": "86959c405348d27ba5686956ae3a8ffc274d3db8",
"remote": "https://git.mozilla.org/releases/gaia.git",
"branch": ""
},
"revision": "34a22433bbb6441d25de9f4dbb5f8c401e13c5cf",
"revision": "eae17e983597fd71c6a396ed63031bb552753f41",
"repo_path": "integration/gaia-central"
}

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9eca89f04628c99226e0d18c15d5ae11b71af0cf"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="86959c405348d27ba5686956ae3a8ffc274d3db8"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9a58f2e395da17c252f61f28900b5b09aeb813bd"/>
@ -24,7 +24,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
<project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ce651a7711042301cbc9c6866be0eeb9e1ceab66"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="5de6856fad82857028f9f059f50680a9bea5b75c"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="f92a936f2aa97526d4593386754bdbf02db07a12"/>

View File

@ -18,10 +18,10 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9eca89f04628c99226e0d18c15d5ae11b71af0cf"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="86959c405348d27ba5686956ae3a8ffc274d3db8"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9a58f2e395da17c252f61f28900b5b09aeb813bd"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="ac7e9ae8a24ab4a3f3da801ca53f95f39a32b89f"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ce651a7711042301cbc9c6866be0eeb9e1ceab66"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="5de6856fad82857028f9f059f50680a9bea5b75c"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
<project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9eca89f04628c99226e0d18c15d5ae11b71af0cf"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="86959c405348d27ba5686956ae3a8ffc274d3db8"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9a58f2e395da17c252f61f28900b5b09aeb813bd"/>
@ -24,7 +24,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
<project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ce651a7711042301cbc9c6866be0eeb9e1ceab66"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="5de6856fad82857028f9f059f50680a9bea5b75c"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
<!-- Stock Android things -->
<project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="ffc05a232799fe8fcb3e47b7440b52b1fb4244c0"/>

View File

@ -174,6 +174,7 @@
@RESPATH@/components/dom_audiochannel.xpt
@RESPATH@/components/dom_base.xpt
@RESPATH@/components/dom_system.xpt
@RESPATH@/components/dom_workers.xpt
#ifdef MOZ_WIDGET_GONK
@RESPATH@/components/dom_wifi.xpt
@RESPATH@/components/dom_system_gonk.xpt

View File

@ -1478,14 +1478,14 @@ pref("browser.uiCustomization.debug", false);
pref("browser.uiCustomization.state", "");
// The remote content URL shown for FxA signup. Must use HTTPS.
pref("identity.fxaccounts.remote.signup.uri", "https://accounts.firefox.com/signup?service=sync&context=fx_desktop_v1");
pref("identity.fxaccounts.remote.signup.uri", "https://accounts.firefox.com/signup?service=sync&context=fx_desktop_v2");
// The URL where remote content that forces re-authentication for Firefox Accounts
// should be fetched. Must use HTTPS.
pref("identity.fxaccounts.remote.force_auth.uri", "https://accounts.firefox.com/force_auth?service=sync&context=fx_desktop_v1");
pref("identity.fxaccounts.remote.force_auth.uri", "https://accounts.firefox.com/force_auth?service=sync&context=fx_desktop_v2");
// The remote content URL shown for signin in. Must use HTTPS.
pref("identity.fxaccounts.remote.signin.uri", "https://accounts.firefox.com/signin?service=sync&context=fx_desktop_v1");
pref("identity.fxaccounts.remote.signin.uri", "https://accounts.firefox.com/signin?service=sync&context=fx_desktop_v2");
// The remote content URL where FxAccountsWebChannel messages originate.
pref("identity.fxaccounts.remote.webchannel.uri", "https://accounts.firefox.com/");

View File

@ -472,18 +472,8 @@ var LoopUI;
return;
}
// Create the menu that is shown when the menu-button' dropmarker is clicked
// inside the notification bar.
let menuPopup = document.createElementNS(kNSXUL, "menupopup");
let menuItem = menuPopup.appendChild(document.createElementNS(kNSXUL, "menuitem"));
menuItem.setAttribute("label", this._getString("infobar_menuitem_dontshowagain_label"));
menuItem.setAttribute("accesskey", this._getString("infobar_menuitem_dontshowagain_accesskey"));
menuItem.addEventListener("command", () => {
// We're being told to hide the bar permanently.
this._hideBrowserSharingInfoBar(true);
});
let box = gBrowser.getNotificationBox();
let paused = false;
let bar = box.appendNotification(
this._getString("infobar_screenshare_browser_message"),
kBrowserSharingNotificationId,
@ -491,13 +481,28 @@ var LoopUI;
null,
box.PRIORITY_WARNING_LOW,
[{
label: this._getString("infobar_button_gotit_label"),
accessKey: this._getString("infobar_button_gotit_accesskey"),
type: "menu-button",
popup: menuPopup,
anchor: "dropmarker",
label: this._getString("infobar_button_pause_label"),
accessKey: this._getString("infobar_button_pause_accesskey"),
isDefault: false,
callback: (event, buttonInfo, buttonNode) => {
paused = !paused;
bar.label = paused ? this._getString("infobar_screenshare_paused_browser_message") :
this._getString("infobar_screenshare_browser_message");
bar.classList.toggle("paused", paused);
buttonNode.label = paused ? this._getString("infobar_button_resume_label") :
this._getString("infobar_button_pause_label");
buttonNode.accessKey = paused ? this._getString("infobar_button_resume_accesskey") :
this._getString("infobar_button_pause_accesskey");
return true;
}
},
{
label: this._getString("infobar_button_stop_label"),
accessKey: this._getString("infobar_button_stop_accesskey"),
isDefault: true,
callback: () => {
this._hideBrowserSharingInfoBar();
LoopUI.MozLoopService.hangupAllChatWindows();
}
}]
);

View File

@ -202,6 +202,31 @@ DistributionCustomizer.prototype = {
PlacesUtils.annotations.EXPIRE_NEVER);
}
if (item.icon && item.iconData) {
try {
let faviconURI = this._makeURI(item.icon);
PlacesUtils.favicons.replaceFaviconDataFromDataURL(
faviconURI, item.iconData, 0,
Services.scriptSecurityManager.getSystemPrincipal());
PlacesUtils.favicons.setAndFetchFaviconForPage(
this._makeURI(item.link), faviconURI, false,
PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE, null,
Services.scriptSecurityManager.getSystemPrincipal());
} catch(e) {
Cu.reportError(e);
}
}
if (item.keyword) {
try {
yield PlacesUtils.keywords.insert({ keyword: item.keyword,
url: item.link });
} catch(e) {
Cu.reportError(e);
}
}
break;
}
}

View File

@ -6,6 +6,10 @@ XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
"resource://gre/modules/PrivateBrowsingUtils.jsm");
Cu.import("resource://gre/modules/ExtensionUtils.jsm");
Cu.import("resource://gre/modules/AddonManager.jsm");
const INTEGER = /^[1-9]\d*$/;
var {
EventManager,
} = ExtensionUtils;
@ -18,38 +22,48 @@ var {
// Manages icon details for toolbar buttons in the |pageAction| and
// |browserAction| APIs.
global.IconDetails = {
// Accepted icon sizes.
SIZES: ["19", "38"],
// Normalizes the various acceptable input formats into an object
// with two properties, "19" and "38", containing icon URLs.
// with icon size as key and icon URL as value.
//
// If a context is specified (function is called from an extension):
// Throws an error if an invalid icon size was provided or the
// extension is not allowed to load the specified resources.
//
// If no context is specified, instead of throwing an error, this
// function simply logs a warning message.
normalize(details, extension, context=null, localize=false) {
let result = {};
if (details.imageData) {
let imageData = details.imageData;
try {
if (details.imageData) {
let imageData = details.imageData;
if (imageData instanceof Cu.getGlobalForObject(imageData).ImageData) {
imageData = {"19": imageData};
}
if (imageData instanceof Cu.getGlobalForObject(imageData).ImageData) {
imageData = {"19": imageData};
}
for (let size of Object.keys(imageData)) {
if (!INTEGER.test(size)) {
throw new Error(`Invalid icon size ${size}, must be an integer`);
}
for (let size of this.SIZES) {
if (size in imageData) {
result[size] = this.convertImageDataToPNG(imageData[size], context);
}
}
}
if (details.path) {
let path = details.path;
if (typeof path != "object") {
path = {"19": path};
}
if (details.path) {
let path = details.path;
if (typeof path != "object") {
path = {"19": path};
}
let baseURI = context ? context.uri : extension.baseURI;
let baseURI = context ? context.uri : extension.baseURI;
for (let size of Object.keys(path)) {
if (!INTEGER.test(size)) {
throw new Error(`Invalid icon size ${size}, must be an integer`);
}
for (let size of this.SIZES) {
if (size in path) {
let url = path[size];
if (localize) {
url = extension.localize(url);
@ -60,25 +74,23 @@ global.IconDetails = {
// The Chrome documentation specifies these parameters as
// relative paths. We currently accept absolute URLs as well,
// which means we need to check that the extension is allowed
// to load them.
try {
Services.scriptSecurityManager.checkLoadURIStrWithPrincipal(
extension.principal, url,
Services.scriptSecurityManager.DISALLOW_SCRIPT);
} catch (e) {
if (context) {
throw e;
}
// If there's no context, it's because we're handling this
// as a manifest directive. Log a warning rather than
// raising an error, but don't accept the URL in any case.
extension.manifestError(`Access to URL '${url}' denied`);
continue;
}
// to load them. This will throw an error if it's not allowed.
Services.scriptSecurityManager.checkLoadURIStrWithPrincipal(
extension.principal, url,
Services.scriptSecurityManager.DISALLOW_SCRIPT);
result[size] = url;
}
}
} catch (e) {
// Function is called from extension code, delegate error.
if (context) {
throw e;
}
// If there's no context, it's because we're handling this
// as a manifest directive. Log a warning rather than
// raising an error.
extension.manifestError(`Invalid icon data: ${e}`);
}
return result;
@ -89,12 +101,7 @@ global.IconDetails = {
getURL(icons, window, extension) {
const DEFAULT = "chrome://browser/content/extension.svg";
// Use the higher resolution image if we're doing any up-scaling
// for high resolution monitors.
let res = window.devicePixelRatio;
let size = res > 1 ? "38" : "19";
return icons[size] || icons["19"] || icons["38"] || DEFAULT;
return AddonManager.getPreferredIconURL({icons: icons}, 18, window) || DEFAULT;
},
convertImageDataToPNG(imageData, context) {

View File

@ -101,6 +101,29 @@ add_task(function* testDetailsObjects() {
resolutions: {
"1": imageData.red.url,
"2": browser.runtime.getURL("data/a.png"), } },
// Various resolutions
{ details: { "path": { "18": "a.png", "32": "a-x2.png" } },
resolutions: {
"1": browser.runtime.getURL("data/a.png"),
"2": browser.runtime.getURL("data/a-x2.png"), } },
{ details: { "path": { "16": "16.png", "100": "100.png" } },
resolutions: {
"1": browser.runtime.getURL("data/100.png"),
"2": browser.runtime.getURL("data/100.png"), } },
{ details: { "path": { "2": "2.png"} },
resolutions: {
"1": browser.runtime.getURL("data/2.png"),
"2": browser.runtime.getURL("data/2.png"), } },
{ details: { "path": {
"6": "6.png",
"18": "18.png",
"32": "32.png",
"48": "48.png",
"128": "128.png" } },
resolutions: {
"1": browser.runtime.getURL("data/18.png"),
"2": browser.runtime.getURL("data/48.png"), } },
];
// Allow serializing ImageData objects for logging.
@ -197,6 +220,62 @@ add_task(function* testDetailsObjects() {
yield extension.unload();
});
// Test that an error is thrown when providing invalid icon sizes
add_task(function *testInvalidIconSizes() {
let extension = ExtensionTestUtils.loadExtension({
manifest: {
"browser_action": {},
"page_action": {},
},
background: function () {
browser.tabs.query({ active: true, currentWindow: true }, tabs => {
var tabId = tabs[0].id;
for (var api of ["pageAction", "browserAction"]) {
// helper function to run setIcon and check if it fails
let assertSetIconThrows = function(detail, error, message) {
try {
detail.tabId = tabId;
browser[api].setIcon(detail);
browser.test.fail("Expected an error on invalid icon size.");
browser.test.notifyFail("setIcon with invalid icon size");
return;
} catch (e) {
browser.test.succeed("setIcon with invalid icon size");
}
}
// test invalid icon size inputs
for (var type of ["path", "imageData"]) {
assertSetIconThrows({ [type]: { "abcdef": "test.png" } });
assertSetIconThrows({ [type]: { "48px": "test.png" } });
assertSetIconThrows({ [type]: { "20.5": "test.png" } });
assertSetIconThrows({ [type]: { "5.0": "test.png" } });
assertSetIconThrows({ [type]: { "-300": "test.png" } });
assertSetIconThrows({ [type]: {
"abc": "test.png",
"5": "test.png"
}});
}
assertSetIconThrows({ imageData: { "abcdef": "test.png" }, path: {"5": "test.png"} });
assertSetIconThrows({ path: { "abcdef": "test.png" }, imageData: {"5": "test.png"} });
}
browser.test.notifyPass("setIcon with invalid icon size");
});
}
});
yield Promise.all([extension.startup(), extension.awaitFinish("setIcon with invalid icon size")]);
yield extension.unload();
});
// Test that default icon details in the manifest.json file are handled
// correctly.
add_task(function *testDefaultDetails() {
@ -294,7 +373,7 @@ add_task(function* testSecureURLsDenied() {
yield extension.startup();
yield extension.awaitFinish();
yield extension.awaitFinish("setIcon security tests");
yield extension.unload();
@ -304,12 +383,12 @@ add_task(function* testSecureURLsDenied() {
"javascript:true"];
let matchURLForbidden = url => ({
message: new RegExp(`Loading extension.*Access to.*'${url}' denied`),
message: new RegExp(`Loading extension.*Invalid icon data: NS_ERROR_DOM_BAD_URI`),
});
// Because the underlying method throws an error on invalid data,
// only the first invalid URL of each component will be logged.
let messages = [matchURLForbidden(urls[0]),
matchURLForbidden(urls[1]),
matchURLForbidden(urls[0]),
matchURLForbidden(urls[1])];
let waitForConsole = new Promise(resolve => {
@ -330,8 +409,8 @@ add_task(function* testSecureURLsDenied() {
},
"page_action": {
"default_icon": {
"19": urls[0],
"38": urls[1],
"19": urls[1],
"38": urls[0],
},
},
},

View File

@ -440,7 +440,16 @@ loop.panel = (function(_, mozL10n) {
this.props.dispatcher.dispatch(new sharedActions.OpenRoom({
roomToken: this.props.room.roomToken
}));
this.closeWindow();
// Open url if needed.
loop.request("getSelectedTabMetadata").then(function(metadata) {
var contextURL = this.props.room.decryptedContext.urls &&
this.props.room.decryptedContext.urls[0].location;
if (contextURL && metadata.url !== contextURL) {
loop.request("OpenURL", contextURL);
}
this.closeWindow();
}.bind(this));
},
handleClick: function(e) {

View File

@ -440,7 +440,16 @@ loop.panel = (function(_, mozL10n) {
this.props.dispatcher.dispatch(new sharedActions.OpenRoom({
roomToken: this.props.room.roomToken
}));
this.closeWindow();
// Open url if needed.
loop.request("getSelectedTabMetadata").then(function(metadata) {
var contextURL = this.props.room.decryptedContext.urls &&
this.props.room.decryptedContext.urls[0].location;
if (contextURL && metadata.url !== contextURL) {
loop.request("OpenURL", contextURL);
}
this.closeWindow();
}.bind(this));
},
handleClick: function(e) {

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 71 KiB

View File

@ -0,0 +1 @@
<svg width="12" height="12" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns"><title>FX_Hello-glyph-pause-12x12</title><desc>Created with Sketch.</desc><path d="M5 .5v11c0 .136-.05.253-.149.351-.099.099-.215.149-.351.149h-4c-.136 0-.253-.05-.352-.149-.099-.098-.148-.216-.148-.351v-11c0-.136.049-.253.148-.352.099-.098.217-.148.352-.148h4c.136 0 .252.05.351.148.099.099.149.217.149.352zm7 0v11c0 .136-.05.253-.149.351-.099.099-.216.149-.351.149h-4c-.136 0-.253-.05-.352-.149-.099-.098-.148-.216-.148-.351v-11c0-.136.049-.253.148-.352.099-.098.216-.148.352-.148h4c.136 0 .252.05.351.148.099.099.149.217.149.352z" sketch:type="MSShapeGroup" fill="#333"/></svg>

After

Width:  |  Height:  |  Size: 718 B

View File

@ -0,0 +1 @@
<svg width="11" height="12" viewBox="0 0 11 12" xmlns="http://www.w3.org/2000/svg" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns"><title>FX_Hello-glyph-play-12x12</title><desc>Created with Sketch.</desc><path d="M10.695 6.24l-10.263 5.704c-.118.066-.22.074-.305.023-.085-.052-.127-.144-.127-.278v-11.377c0-.134.043-.228.127-.278.085-.052.186-.044.305.022l10.263 5.704c.118.066.178.147.178.239 0 .094-.06.174-.178.241z" sketch:type="MSShapeGroup" fill="#fff"/></svg>

After

Width:  |  Height:  |  Size: 473 B

View File

@ -0,0 +1 @@
<svg width="12" height="12" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns"><title>FX_Hello-glyph-stop-12x12</title><desc>Created with Sketch.</desc><path d="M12 .5v11c0 .136-.05.253-.149.351-.099.099-.216.149-.351.149h-11c-.136 0-.253-.05-.352-.149-.099-.098-.148-.216-.148-.351v-11c0-.136.049-.253.148-.352.099-.098.217-.148.352-.148h11c.136 0 .252.05.351.148.099.099.149.217.149.352z" sketch:type="MSShapeGroup" fill="#D92215"/></svg>

After

Width:  |  Height:  |  Size: 499 B

View File

@ -89,6 +89,9 @@ browser.jar:
content/browser/loop/shared/img/animated-spinner.svg (content/shared/img/animated-spinner.svg)
content/browser/loop/shared/img/avatars.svg (content/shared/img/avatars.svg)
content/browser/loop/shared/img/firefox-avatar.svg (content/shared/img/firefox-avatar.svg)
content/browser/loop/shared/img/pause-12x12.svg (content/shared/img/pause-12x12.svg)
content/browser/loop/shared/img/play-12x12.svg (content/shared/img/play-12x12.svg)
content/browser/loop/shared/img/stop-12x12.svg (content/shared/img/stop-12x12.svg)
# Shared scripts
content/browser/loop/shared/js/actions.js (content/shared/js/actions.js)

View File

@ -875,10 +875,11 @@ var MozLoopServiceInternal = {
*/
hangupAllChatWindows() {
let isLoopURL = ({ src }) => /^about:loopconversation#/.test(src);
[...Chat.chatboxes].filter(isLoopURL).forEach(chatbox => {
let loopChatWindows = [...Chat.chatboxes].filter(isLoopURL);
for (let chatbox of loopChatWindows) {
let window = chatbox.content.contentWindow;
window.dispatchEvent(new window.CustomEvent("LoopHangupNow"));
});
}
},
/**

View File

@ -82,7 +82,10 @@ describe("loop.panel", function() {
roomToken: "QzBbvGmIZWU",
roomUrl: "http://sample/QzBbvGmIZWU",
decryptedContext: {
roomName: roomName
roomName: roomName,
urls: [{
location: "http://testurl.com"
}]
},
maxSize: 2,
participants: [{
@ -665,12 +668,23 @@ describe("loop.panel", function() {
});
describe("Copy button", function() {
var roomEntry;
var roomEntry, openURLStub;
beforeEach(function() {
// Stub to prevent warnings where no stores are set up to handle the
// actions we are testing.
sandbox.stub(dispatcher, "dispatch");
openURLStub = sinon.stub();
LoopMochaUtils.stubLoopRequest({
GetSelectedTabMetadata: function() {
return {
url: "http://invalid.com",
description: "fakeSite"
};
},
OpenURL: openURLStub
});
roomEntry = mountRoomEntry({
deleteRoom: sandbox.stub(),
@ -717,6 +731,32 @@ describe("loop.panel", function() {
sinon.assert.notCalled(dispatcher.dispatch);
});
it("should open a new tab with the room context if it is not the same as the currently open tab", function() {
TestUtils.Simulate.click(roomEntry.refs.roomEntry.getDOMNode());
sinon.assert.calledOnce(openURLStub);
sinon.assert.calledWithExactly(openURLStub, "http://testurl.com");
});
it("should not open a new tab if the context is the same as the currently open tab", function() {
LoopMochaUtils.stubLoopRequest({
GetSelectedTabMetadata: function() {
return {
url: "http://testurl.com",
description: "fakeSite"
};
}
});
roomEntry = mountRoomEntry({
deleteRoom: sandbox.stub(),
isOpenedRoom: false,
room: new loop.store.Room(roomData)
});
TestUtils.Simulate.click(roomEntry.refs.roomEntry.getDOMNode());
sinon.assert.notCalled(openURLStub);
});
});
});

View File

@ -156,11 +156,6 @@ add_task(function* test_infoBar() {
let button = bar.querySelector(".notification-button");
Assert.ok(button, "There should be a button present");
Assert.strictEqual(button.type, "menu-button", "We're expecting a menu-button");
Assert.strictEqual(button.getAttribute("anchor"), "dropmarker",
"The popup should be opening anchored to the dropmarker");
Assert.strictEqual(button.getElementsByTagNameNS(kNSXUL, "menupopup").length, 1,
"There should be a popup attached to the button");
};
testBarProps();
@ -175,11 +170,8 @@ add_task(function* test_infoBar() {
testBarProps();
// Test hiding the infoBar.
getInfoBar().querySelector(".notification-button")
.getElementsByTagNameNS(kNSXUL, "menuitem")[0].click();
getInfoBar().querySelector(".notification-button-default").click();
Assert.equal(getInfoBar(), null, "The notification should be hidden now");
Assert.strictEqual(Services.prefs.getBoolPref(kPrefBrowserSharingInfoBar), false,
"The pref should be set to false when the menu item is clicked");
gBrowser.selectedIndex = Array.indexOf(gBrowser.tabs, createdTabs[1]);

View File

@ -7,6 +7,7 @@ const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/AppConstants.jsm");
Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource:///modules/MigrationUtils.jsm");
Cu.import("resource:///modules/MSMigrationUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
@ -15,6 +16,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
const kEdgeRegistryRoot = "SOFTWARE\\Classes\\Local Settings\\Software\\" +
"Microsoft\\Windows\\CurrentVersion\\AppContainer\\Storage\\" +
"microsoft.microsoftedge_8wekyb3d8bbwe\\MicrosoftEdge";
const kEdgeReadingListPath = "AC\\MicrosoftEdge\\User\\Default\\DataStore\\Data\\";
function EdgeTypedURLMigrator() {
}
@ -79,6 +81,112 @@ EdgeTypedURLMigrator.prototype = {
},
}
function EdgeReadingListMigrator() {
}
EdgeReadingListMigrator.prototype = {
type: MigrationUtils.resourceTypes.BOOKMARKS,
get exists() {
return !!MSMigrationUtils.getEdgeLocalDataFolder();
},
migrate(callback) {
this._migrateReadingList(PlacesUtils.bookmarks.menuGuid).then(
() => callback(true),
ex => {
Cu.reportError(ex);
callback(false);
}
);
},
_migrateReadingList: Task.async(function*(parentGuid) {
let edgeDir = MSMigrationUtils.getEdgeLocalDataFolder();
if (!edgeDir) {
return;
}
this._readingListExtractor = Cc["@mozilla.org/profile/migrator/edgereadinglistextractor;1"].
createInstance(Ci.nsIEdgeReadingListExtractor);
edgeDir.appendRelativePath(kEdgeReadingListPath);
let errorProduced = null;
if (edgeDir.exists() && edgeDir.isReadable() && edgeDir.isDirectory()) {
let expectedDir = edgeDir.clone();
expectedDir.appendRelativePath("nouser1\\120712-0049");
if (expectedDir.exists() && expectedDir.isReadable() && expectedDir.isDirectory()) {
yield this._migrateReadingListDB(expectedDir, parentGuid).catch(ex => {
if (!errorProduced)
errorProduced = ex;
});
} else {
let getSubdirs = someDir => {
let subdirs = someDir.directoryEntries;
let rv = [];
while (subdirs.hasMoreElements()) {
let subdir = subdirs.getNext().QueryInterface(Ci.nsIFile);
if (subdir.isDirectory() && subdir.isReadable()) {
rv.push(subdir);
}
}
return rv;
};
let dirs = getSubdirs(edgeDir).map(getSubdirs);
for (let dir of dirs) {
yield this._migrateReadingListDB(dir, parentGuid).catch(ex => {
if (!errorProduced)
errorProduced = ex;
});
}
}
}
if (errorProduced) {
throw errorProduced;
}
}),
_migrateReadingListDB: Task.async(function*(dbFile, parentGuid) {
dbFile.appendRelativePath("DBStore\\spartan.edb");
if (!dbFile.exists() || !dbFile.isReadable() || !dbFile.isFile()) {
return;
}
let readingListItems;
try {
readingListItems = this._readingListExtractor.extract(dbFile.path);
} catch (ex) {
Cu.reportError("Failed to extract Edge reading list information from " +
"the database at " + dbFile.path + " due to the following error: " + ex);
// Deliberately make this fail so we expose failure in the UI:
throw ex;
return;
}
if (!readingListItems.length) {
return;
}
let destFolderGuid = yield this._ensureReadingListFolder(parentGuid);
for (let i = 0; i < readingListItems.length; i++) {
let readingListItem = readingListItems.queryElementAt(i, Ci.nsIPropertyBag2);
let url = readingListItem.get("uri");
let title = readingListItem.get("title");
let time = readingListItem.get("time");
// time is a PRTime, which is microseconds (since unix epoch), or null.
// We need milliseconds for the date constructor, so divide by 1000:
let dateAdded = time ? new Date(time / 1000) : new Date();
yield PlacesUtils.bookmarks.insert({
parentGuid: destFolderGuid, url: url, title, dateAdded
});
}
}),
_ensureReadingListFolder: Task.async(function*(parentGuid) {
if (!this.__readingListFolderGuid) {
let folderTitle = MigrationUtils.getLocalizedString("importedEdgeReadingList");
let folderSpec = {type: PlacesUtils.bookmarks.TYPE_FOLDER, parentGuid, title: folderTitle};
this.__readingListFolderGuid = (yield PlacesUtils.bookmarks.insert(folderSpec)).guid;
}
return this.__readingListFolderGuid;
}),
};
function EdgeProfileMigrator() {
}
@ -89,6 +197,7 @@ EdgeProfileMigrator.prototype.getResources = function() {
MSMigrationUtils.getBookmarksMigrator(MSMigrationUtils.MIGRATION_TYPE_EDGE),
MSMigrationUtils.getCookiesMigrator(MSMigrationUtils.MIGRATION_TYPE_EDGE),
new EdgeTypedURLMigrator(),
new EdgeReadingListMigrator(),
];
let windowsVaultFormPasswordsMigrator =
MSMigrationUtils.getWindowsVaultFormPasswordsMigrator();

View File

@ -26,7 +26,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "ctypes",
const EDGE_COOKIE_PATH_OPTIONS = ["", "#!001\\", "#!002\\"];
const EDGE_COOKIES_SUFFIX = "MicrosoftEdge\\Cookies";
const EDGE_FAVORITES = "AC\\MicrosoftEdge\\User\\Default\\Favorites";
const EDGE_READINGLIST = "AC\\MicrosoftEdge\\User\\Default\\DataStore\\Data\\";
const FREE_CLOSE_FAILED = 0;
const INTERNET_EXPLORER_EDGE_GUID = [0x3CCD5499,
0x4B1087A8,
@ -376,10 +375,6 @@ Bookmarks.prototype = {
yield MigrationUtils.createImportedBookmarksFolder(this.importedAppLabel, folderGuid);
}
yield this._migrateFolder(this._favoritesFolder, folderGuid);
if (this._migrationType == MSMigrationUtils.MIGRATION_TYPE_EDGE) {
yield this._migrateEdgeReadingList(PlacesUtils.bookmarks.menuGuid);
}
}.bind(this)).then(() => aCallback(true),
e => { Cu.reportError(e); aCallback(false) });
},
@ -390,6 +385,7 @@ Bookmarks.prototype = {
// for IE, and in a similar location for Edge.
// Until we support it, bookmarks are imported in alphabetical order.
let entries = aSourceFolder.directoryEntries;
let succeeded = true;
while (entries.hasMoreElements()) {
let entry = entries.getNext().QueryInterface(Ci.nsIFile);
try {
@ -439,82 +435,14 @@ Bookmarks.prototype = {
}
} catch (ex) {
Components.utils.reportError("Unable to import " + this.importedAppLabel + " favorite (" + entry.leafName + "): " + ex);
succeeded = false;
}
}
}),
_migrateEdgeReadingList: Task.async(function*(parentGuid) {
let edgeDir = getEdgeLocalDataFolder();
if (!edgeDir) {
return;
}
this._readingListExtractor = Cc["@mozilla.org/profile/migrator/edgereadinglistextractor;1"].
createInstance(Ci.nsIEdgeReadingListExtractor);
edgeDir.appendRelativePath(EDGE_READINGLIST);
if (edgeDir.exists() && edgeDir.isReadable() && edgeDir.isDirectory()) {
let expectedDir = edgeDir.clone();
expectedDir.appendRelativePath("nouser1\\120712-0049");
if (expectedDir.exists() && expectedDir.isReadable() && expectedDir.isDirectory()) {
yield this._migrateEdgeReadingListDB(expectedDir, parentGuid);
} else {
let getSubdirs = someDir => {
let subdirs = someDir.directoryEntries;
let rv = [];
while (subdirs.hasMoreElements()) {
let subdir = subdirs.getNext().QueryInterface(Ci.nsIFile);
if (subdir.isDirectory() && subdir.isReadable()) {
rv.push(subdir);
}
}
return rv;
};
let dirs = getSubdirs(edgeDir).map(getSubdirs);
for (let dir of dirs) {
yield this._migrateEdgeReadingListDB(dir, parentGuid);
}
}
}
}),
_migrateEdgeReadingListDB: Task.async(function*(dbFile, parentGuid) {
dbFile.appendRelativePath("DBStore\\spartan.edb");
if (!dbFile.exists() || !dbFile.isReadable() || !dbFile.isFile()) {
return;
}
let readingListItems;
try {
readingListItems = this._readingListExtractor.extract(dbFile.path);
} catch (ex) {
Cu.reportError("Failed to extract Edge reading list information from " +
"the database at " + dbPath + " due to the following error: " + ex);
return;
}
if (!readingListItems.length) {
return;
}
let destFolderGuid = yield this._ensureEdgeReadingListFolder(parentGuid);
for (let i = 0; i < readingListItems.length; i++) {
let readingListItem = readingListItems.queryElementAt(i, Ci.nsIPropertyBag2);
let url = readingListItem.get("uri");
let title = readingListItem.get("title");
let time = readingListItem.get("time");
// time is a PRTime, which is microseconds (since unix epoch), or null.
// We need milliseconds for the date constructor, so divide by 1000:
let dateAdded = time ? new Date(time / 1000) : new Date();
yield PlacesUtils.bookmarks.insert({
parentGuid: destFolderGuid, url: url, title, dateAdded
});
if (!succeeded) {
throw new Error("Failed to import all bookmarks correctly.");
}
}),
_ensureEdgeReadingListFolder: Task.async(function*(parentGuid) {
if (!this.__edgeReadingListFolderGuid) {
let folderTitle = MigrationUtils.getLocalizedString("importedEdgeReadingList");
let folderSpec = {type: PlacesUtils.bookmarks.TYPE_FOLDER, parentGuid, title: folderTitle};
this.__edgeReadingListFolderGuid = (yield PlacesUtils.bookmarks.insert(folderSpec)).guid;
}
return this.__edgeReadingListFolderGuid;
}),
};
function Cookies(migrationType) {
@ -948,4 +876,5 @@ var MSMigrationUtils = {
return new WindowsVaultFormPasswords();
},
getTypedURLs,
getEdgeLocalDataFolder,
};

View File

@ -197,7 +197,13 @@ nsEdgeReadingListExtractor::ConvertJETError(const JET_ERR &aError)
return NS_ERROR_FILE_INVALID_PATH;
case JET_errFileNotFound:
return NS_ERROR_FILE_NOT_FOUND;
case JET_errDatabaseDirtyShutdown:
return NS_ERROR_FILE_CORRUPTED;
default:
nsCOMPtr<nsIConsoleService> consoleService = do_GetService(NS_CONSOLESERVICE_CONTRACTID);
wchar_t* msg = new wchar_t[80];
swprintf(msg, 80, MOZ_UTF16("Unexpected JET error from ESE database: %ld"), aError);
consoleService->LogStringMessage(msg);
return NS_ERROR_FAILURE;
}
}

View File

@ -8,14 +8,20 @@ about=Test distribution file
[BookmarksToolbar]
item.1.title=Toolbar Link Before
item.1.link=http://mozilla.com/
item.1.link=https://example.org/toolbar/before/
item.1.keyword=e:t:b
item.1.icon=https://example.org/favicon.png
item.1.iconData=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAAAAAA6fptVAAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJggg==
item.2.type=default
item.3.title=Toolbar Link After
item.3.link=http://mozilla.com/
item.3.link=https://example.org/toolbar/after/
item.3.keyword=e:t:a
[BookmarksMenu]
item.1.title=Menu Link Before
item.1.link=http://mozilla.com/
item.1.link=https://example.org/menu/before/
item.1.icon=https://example.org/favicon.png
item.1.iconData=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAAAAAA6fptVAAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJggg==
item.2.type=default
item.3.title=Menu Link After
item.3.link=http://mozilla.com/
item.3.link=https://example.org/menu/after/

View File

@ -119,3 +119,34 @@ function rebuildSmartBookmarks() {
Services.console.unregisterListener(consoleListener);
});
}
const SINGLE_TRY_TIMEOUT = 100;
const NUMBER_OF_TRIES = 30;
/**
* Similar to waitForConditionPromise, but poll for an asynchronous value
* every SINGLE_TRY_TIMEOUT ms, for no more than tryCount times.
*
* @param promiseFn
* A function to generate a promise, which resolves to the expected
* asynchronous value.
* @param timeoutMsg
* The reason to reject the returned promise with.
* @param [optional] tryCount
* Maximum times to try before rejecting the returned promise with
* timeoutMsg, defaults to NUMBER_OF_TRIES.
* @return {Promise}
* @resolves to the asynchronous value being polled.
* @rejects if the asynchronous value is not available after tryCount attempts.
*/
var waitForResolvedPromise = Task.async(function* (promiseFn, timeoutMsg, tryCount=NUMBER_OF_TRIES) {
let tries = 0;
do {
try {
let value = yield promiseFn();
return value;
} catch (ex) {}
yield new Promise(resolve => do_timeout(SINGLE_TRY_TIMEOUT, resolve));
} while (++tries <= tryCount);
throw(timeoutMsg);
});

View File

@ -76,6 +76,16 @@ add_task(function* () {
});
Assert.equal(menuItem.title, "Menu Link After");
// Check no favicon or keyword exists for this bookmark
yield Assert.rejects(waitForResolvedPromise(() => {
return PlacesUtils.promiseFaviconData(menuItem.url.href);
}, "Favicon not found", 10), /Favicon\snot\sfound/, "Favicon not found");
let keywordItem = yield PlacesUtils.keywords.fetch({
url: menuItem.url.href
});
Assert.strictEqual(keywordItem, null);
// Check the custom bookmarks exist on toolbar.
let toolbarItem = yield PlacesUtils.bookmarks.fetch({
parentGuid: PlacesUtils.bookmarks.toolbarGuid,
@ -83,6 +93,24 @@ add_task(function* () {
});
Assert.equal(toolbarItem.title, "Toolbar Link Before");
// Check the custom favicon and keyword exist for this bookmark
let faviconItem = yield waitForResolvedPromise(() => {
return PlacesUtils.promiseFaviconData(toolbarItem.url.href);
}, "Favicon not found", 10);
Assert.equal(faviconItem.uri.spec, "https://example.org/favicon.png");
Assert.greater(faviconItem.dataLen, 0);
Assert.equal(faviconItem.mimeType, "image/png");
let base64Icon = "data:image/png;base64," +
base64EncodeString(String.fromCharCode.apply(String, faviconItem.data));
Assert.equal(base64Icon, SMALLPNG_DATA_URI.spec);
keywordItem = yield PlacesUtils.keywords.fetch({
url: toolbarItem.url.href
});
Assert.notStrictEqual(keywordItem, null);
Assert.equal(keywordItem.keyword, "e:t:b");
toolbarItem = yield PlacesUtils.bookmarks.fetch({
parentGuid: PlacesUtils.bookmarks.toolbarGuid,
index: 1 + DEFAULT_BOOKMARKS_ON_TOOLBAR

View File

@ -1250,6 +1250,19 @@ var SessionStoreInternal = {
// we don't want to save the busy state
delete winData.busy;
// When closing windows one after the other until Firefox quits, we
// will move those closed in series back to the "open windows" bucket
// before writing to disk. If however there is only a single window
// with tabs we deem not worth saving then we might end up with a
// random closed or even a pop-up window re-opened. To prevent that
// we explicitly allow saving an "empty" window state.
let isLastWindow =
Object.keys(this._windows).length == 1 &&
!this._closedWindows.some(win => win._shouldRestore || false);
// clear this window from the list, since it has definitely been closed.
delete this._windows[aWindow.__SSi];
// Now we have to figure out if this window is worth saving in the _closedWindows
// Object.
//
@ -1265,7 +1278,7 @@ var SessionStoreInternal = {
if (!winData.isPrivate) {
// Remove any open private tabs the window may contain.
PrivacyFilter.filterPrivateTabs(winData);
this.maybeSaveClosedWindow(winData);
this.maybeSaveClosedWindow(winData, isLastWindow);
}
// The tabbrowser binding will go away once the window is closed,
@ -1292,11 +1305,9 @@ var SessionStoreInternal = {
// It's possible that a tab switched its privacy state at some point
// before our flush, so we need to filter again.
PrivacyFilter.filterPrivateTabs(winData);
this.maybeSaveClosedWindow(winData);
this.maybeSaveClosedWindow(winData, isLastWindow);
}
// clear this window from the list
delete this._windows[aWindow.__SSi];
// Update the tabs data now that we've got the most
// recent information.
this.cleanUpWindow(aWindow, winData);
@ -1313,7 +1324,6 @@ var SessionStoreInternal = {
}
},
/**
* Clean up the message listeners on a window that has finally
* gone away. Call this once you're sure you don't want to hear
@ -1345,22 +1355,19 @@ var SessionStoreInternal = {
*
* @param winData
* The data for the closed window that we might save.
* @param isLastWindow
* Whether or not the window being closed is the last
* browser window. Callers of this function should pass
* in the value of SessionStoreInternal.atLastWindow for
* this argument, and pass in the same value if they happen
* to call this method again asynchronously (for example, after
* a window flush).
*/
maybeSaveClosedWindow(winData) {
maybeSaveClosedWindow(winData, isLastWindow) {
if (RunState.isRunning) {
// Determine whether the window has any tabs worth saving.
let hasSaveableTabs = winData.tabs.some(this._shouldSaveTabState);
// When closing windows one after the other until Firefox quits, we
// will move those closed in series back to the "open windows" bucket
// before writing to disk. If however there is only a single window
// with tabs we deem not worth saving then we might end up with a
// random closed or even a pop-up window re-opened. To prevent that
// we explicitly allow saving an "empty" window state.
let isLastWindow =
Object.keys(this._windows).length == 1 &&
!this._closedWindows.some(win => win._shouldRestore || false);
// Note that we might already have this window stored in
// _closedWindows from a previous call to this function.
let winIndex = this._closedWindows.indexOf(winData);

View File

@ -217,3 +217,4 @@ skip-if = os == "mac"
[browser_send_async_message_oom.js]
[browser_multiple_navigateAndRestore.js]
run-if = e10s
[browser_async_window_flushing.js]

View File

@ -0,0 +1,38 @@
/**
* Tests that when we close a window, it is immediately removed from the
* _windows array.
*/
add_task(function* test_synchronously_remove_window_state() {
// Depending on previous tests, we might already have some closed
// windows stored. We'll use its length to determine whether or not
// the window was added or not.
let state = JSON.parse(ss.getBrowserState());
ok(state, "Make sure we can get the state");
let initialWindows = state.windows.length;
// Open a new window and send the first tab somewhere
// interesting.
let newWin = yield BrowserTestUtils.openNewBrowserWindow();
let browser = newWin.gBrowser.selectedBrowser;
browser.loadURI("http://example.com");
yield BrowserTestUtils.browserLoaded(browser);
yield TabStateFlusher.flush(browser);
state = JSON.parse(ss.getBrowserState());
is(state.windows.length, initialWindows + 1,
"The new window to be in the state");
// Now close the window, and make sure that the window was removed
// from the windows list from the SessionState. We're specifically
// testing the case where the window is _not_ removed in between
// the close-initiated flush request and the flush response.
let windowClosed = BrowserTestUtils.windowClosed(newWin);
newWin.close();
state = JSON.parse(ss.getBrowserState());
is(state.windows.length, initialWindows,
"The new window should have been removed from the state");
// Wait for our window to go away
yield windowClosed;
});

View File

@ -198,11 +198,14 @@ room_name_untitled_page=Untitled Page
# Infobar strings
infobar_screenshare_browser_message=Users in your conversation will now be able to see the contents of any tab you click on.
infobar_button_gotit_label=Got it!
infobar_button_gotit_accesskey=G
infobar_menuitem_dontshowagain_label=Don't show this again
infobar_menuitem_dontshowagain_accesskey=D
infobar_screenshare_browser_message=You are sharing your tabs. Any tab you click on can be seen by your friends
infobar_screenshare_paused_browser_message=Tab sharing is paused
infobar_button_pause_label=Pause
infobar_button_resume_label=Resume
infobar_button_stop_label=Stop
infobar_button_pause_accesskey=P
infobar_button_stop_accesskey=S
infobar_button_resume_accesskey=R
# Context in conversation strings

View File

@ -1118,16 +1118,6 @@ notification[value="translation"] menulist > .menulist-dropmarker {
display: block;
}
/* Loop/ Hello browser styles */
notification[value="loop-sharing-notification"] .button-menubutton-button {
min-width: 0;
}
notification[value="loop-sharing-notification"] .messageImage {
list-style-image: url(chrome://browser/skin/webRTC-shareScreen-16.png);
}
#treecolAutoCompleteImage {
max-width : 36px;
}

View File

@ -3212,24 +3212,37 @@ menulist.translate-infobar-element > .menulist-dropmarker {
}
/* Loop/ Hello browser styles */
notification[value="loop-sharing-notification"] {
background: #00a9dc;
padding: 0;
border: 0;
}
notification[value="loop-sharing-notification"].paused {
background: #ebebeb;
}
notification[value="loop-sharing-notification"] .notification-button {
padding: 1px 5px;
background: #fff;
border-radius: 0;
}
notification[value="loop-sharing-notification"] .button-menubutton-button {
-moz-appearance: none;
min-width: 0;
margin: 0;
notification[value="loop-sharing-notification"].paused .notification-button {
background: #57bd35;
}
notification[value="loop-sharing-notification"] .messageImage {
list-style-image: url(chrome://browser/skin/webRTC-sharingScreen-menubar.png);
notification[value="loop-sharing-notification"].paused .notification-button:hover {
background: #39a017;
}
@media (min-resolution: 2dppx) {
notification[value="loop-sharing-notification"] .messageImage {
list-style-image: url(chrome://browser/skin/webRTC-sharingScreen-menubar@2x.png);
}
notification[value="loop-sharing-notification"] .notification-button:hover,
notification[value="loop-sharing-notification"].paused .notification-button-default:hover {
background: #ebebeb;
}
notification[value="loop-sharing-notification"] .notification-button-default,
notification[value="loop-sharing-notification"].paused .notification-button-default {
background: #fff;
}
.popup-notification-body[popupid="addon-progress"],

View File

@ -445,3 +445,83 @@
}
%endif
}
/* Loop notification */
notification[value="loop-sharing-notification"] {
-moz-appearance: none;
height: 40px;
background-color: #00a9dc;
box-shadow: 0 40px 1px rgba(0,0,0,.5) inset;
}
notification[value="loop-sharing-notification"].paused {
background-color: #ebebeb;
}
notification[value="loop-sharing-notification"] .notification-inner {
color: #fff;
padding: 0;
}
notification[value="loop-sharing-notification"].paused .notification-inner {
color: #00a9dc;
}
notification[value="loop-sharing-notification"] .notification-button {
-moz-appearance: none;
background-color: #fff;
border: 0;
border-right: solid 1px #ebebeb;
width: 100px;
height: 40px;
margin: 0;
list-style-image: url(chrome://browser/content/loop/shared/img/pause-12x12.svg);
box-shadow: 0 40px 1px rgba(0,0,0,.5) inset;
text-shadow: none;
}
notification[value="loop-sharing-notification"] .notification-button:-moz-locale-dir(rtl) {
border-right: 0;
border-left: solid 1px #ebebeb;
}
notification[value="loop-sharing-notification"].paused .notification-button {
background-color: #57bd35;
color: #fff;
list-style-image: url(chrome://browser/content/loop/shared/img/play-12x12.svg);
}
notification[value="loop-sharing-notification"].paused .notification-button:hover {
background-color: #39a017;
}
notification[value="loop-sharing-notification"] .notification-button:hover,
notification[value="loop-sharing-notification"].paused .notification-button-default:hover {
background-color: #ebebeb;
}
notification[value="loop-sharing-notification"] .notification-button-default,
notification[value="loop-sharing-notification"].paused .notification-button-default {
color: #d92215;
background-color: #fff;
border-right: 0;
list-style-image: url(chrome://browser/content/loop/shared/img/stop-12x12.svg);
}
notification[value="loop-sharing-notification"] .notification-button .button-icon {
display: block;
-moz-margin-end: 6px;
}
notification[value="loop-sharing-notification"] .button-menubutton-button {
min-width: 0;
}
notification[value="loop-sharing-notification"] .messageImage {
list-style-image: url(chrome://browser/content/loop/shared/img/icons-16x16.svg#loop-icon-white);
margin-inline-start: 14px;
}
notification[value="loop-sharing-notification"].paused .messageImage {
list-style-image: url(chrome://browser/content/loop/shared/img/icons-16x16.svg#loop-icon-still);
}

View File

@ -2316,19 +2316,6 @@ notification[value="translation"] {
-moz-appearance: none;
}
/* Loop/ Hello browser styles */
notification[value="loop-sharing-notification"] .button-menubutton-button {
-moz-appearance: none;
min-width: 0;
border: 0;
margin: 0;
}
notification[value="loop-sharing-notification"] .messageImage {
list-style-image: url(chrome://browser/skin/webRTC-shareScreen-16.png);
}
/* Bookmarks roots menu-items */
#subscribeToPageMenuitem:not([disabled]),
#subscribeToPageMenupopup,

View File

@ -28,26 +28,74 @@ namespace mozilla {
using dom::URLParams;
void OriginAttributes::InheritFromDocShellParent(const OriginAttributes& aParent)
void
PrincipalOriginAttributes::InheritFromDocShellToDoc(const DocShellOriginAttributes& aAttrs,
const nsIURI* aURI)
{
mAppId = aParent.mAppId;
mInBrowser = aParent.mInBrowser;
mUserContextId = aParent.mUserContextId;
mSignedPkg = aParent.mSignedPkg;
mAppId = aAttrs.mAppId;
mInBrowser = aAttrs.mInBrowser;
// addonId is computed from the principal URI and never propagated
mUserContextId = aAttrs.mUserContextId;
// TODO:
// Bug 1225349 - PrincipalOriginAttributes should inherit mSignedPkg
// accordingly by URI
mSignedPkg = aAttrs.mSignedPkg;
}
bool OriginAttributes::CopyFromLoadContext(nsILoadContext* aLoadContext)
void
PrincipalOriginAttributes::InheritFromNecko(const NeckoOriginAttributes& aAttrs)
{
OriginAttributes attrs;
bool result = aLoadContext->GetOriginAttributes(attrs);
NS_ENSURE_TRUE(result, false);
mAppId = aAttrs.mAppId;
mInBrowser = aAttrs.mInBrowser;
mAppId = attrs.mAppId;
mInBrowser = attrs.mInBrowser;
mAddonId = attrs.mAddonId;
mUserContextId = attrs.mUserContextId;
mSignedPkg = attrs.mSignedPkg;
return true;
// addonId is computed from the principal URI and never propagated
mUserContextId = aAttrs.mUserContextId;
mSignedPkg = aAttrs.mSignedPkg;
}
void
DocShellOriginAttributes::InheritFromDocToChildDocShell(const PrincipalOriginAttributes& aAttrs)
{
mAppId = aAttrs.mAppId;
mInBrowser = aAttrs.mInBrowser;
// addonId is computed from the principal URI and never propagated
mUserContextId = aAttrs.mUserContextId;
// TODO:
// Bug 1225353 - DocShell/NeckoOriginAttributes should inherit
// mSignedPkg accordingly by mSignedPkgInBrowser
mSignedPkg = aAttrs.mSignedPkg;
}
void
NeckoOriginAttributes::InheritFromDocToNecko(const PrincipalOriginAttributes& aAttrs)
{
mAppId = aAttrs.mAppId;
mInBrowser = aAttrs.mInBrowser;
// addonId is computed from the principal URI and never propagated
mUserContextId = aAttrs.mUserContextId;
// TODO:
// Bug 1225353 - DocShell/NeckoOriginAttributes should inherit
// mSignedPkg accordingly by mSignedPkgInBrowser
}
void
NeckoOriginAttributes::InheritFromDocShellToNecko(const DocShellOriginAttributes& aAttrs)
{
mAppId = aAttrs.mAppId;
mInBrowser = aAttrs.mInBrowser;
// addonId is computed from the principal URI and never propagated
mUserContextId = aAttrs.mUserContextId;
// TODO:
// Bug 1225353 - DocShell/NeckoOriginAttributes should inherit
// mSignedPkg accordingly by mSignedPkgInBrowser
}
void
@ -454,7 +502,7 @@ BasePrincipal::GetUnknownAppId(bool* aUnknownAppId)
}
already_AddRefed<BasePrincipal>
BasePrincipal::CreateCodebasePrincipal(nsIURI* aURI, const OriginAttributes& aAttrs)
BasePrincipal::CreateCodebasePrincipal(nsIURI* aURI, const PrincipalOriginAttributes& aAttrs)
{
// If the URI is supposed to inherit the security context of whoever loads it,
// we shouldn't make a codebase principal for it.
@ -495,7 +543,7 @@ BasePrincipal::CreateCodebasePrincipal(const nsACString& aOrigin)
"CreateCodebasePrincipal does not support nsNullPrincipal");
nsAutoCString originNoSuffix;
mozilla::OriginAttributes attrs;
mozilla::PrincipalOriginAttributes attrs;
if (!attrs.PopulateFromOrigin(aOrigin, originNoSuffix)) {
return nullptr;
}

View File

@ -14,26 +14,19 @@
#include "mozilla/dom/ChromeUtilsBinding.h"
class nsIContentSecurityPolicy;
class nsILoadContext;
class nsIObjectOutputStream;
class nsIObjectInputStream;
class nsIURI;
class nsExpandedPrincipal;
namespace mozilla {
// Base OriginAttributes class. This has several subclass flavors, and is not
// directly constructable itself.
class OriginAttributes : public dom::OriginAttributesDictionary
{
public:
OriginAttributes() {}
OriginAttributes(uint32_t aAppId, bool aInBrowser)
{
mAppId = aAppId;
mInBrowser = aInBrowser;
}
explicit OriginAttributes(const OriginAttributesDictionary& aOther)
: OriginAttributesDictionary(aOther) {}
bool operator==(const OriginAttributes& aOther) const
{
return mAppId == aOther.mAppId &&
@ -47,28 +40,6 @@ public:
return !(*this == aOther);
}
// The docshell often influences the origin attributes of content loaded
// inside of it, and in some cases also influences the origin attributes of
// content loaded in child docshells. We say that a given attribute "lives on
// the docshell" to indicate that this attribute is specified by the docshell
// (if any) associated with a given content document.
//
// In practice, this usually means that we need to store a copy of those
// attributes on each docshell, or provide methods on the docshell to compute
// them on-demand.
// We could track each of these attributes individually, but since the
// majority of the existing origin attributes currently live on the docshell,
// it's cleaner to simply store an entire OriginAttributes struct on each
// docshell, and selectively copy them to child docshells and content
// principals in a manner that implements our desired semantics.
//
// This method is used to propagate attributes from parent to child
// docshells.
void InheritFromDocShellParent(const OriginAttributes& aParent);
// Copy from the origin attributes of the nsILoadContext.
bool CopyFromLoadContext(nsILoadContext* aLoadContext);
// Serializes/Deserializes non-default values into the suffix format, i.e.
// |!key1=value1&key2=value2|. If there are no non-default attributes, this
// returns an empty string.
@ -79,6 +50,92 @@ public:
// |uri!key1=value1&key2=value2| and returns the uri without the suffix.
bool PopulateFromOrigin(const nsACString& aOrigin,
nsACString& aOriginNoSuffix);
protected:
OriginAttributes() {}
explicit OriginAttributes(const OriginAttributesDictionary& aOther)
: OriginAttributesDictionary(aOther) {}
};
class PrincipalOriginAttributes;
class DocShellOriginAttributes;
class NeckoOriginAttributes;
// Various classes in Gecko contain OriginAttributes members, and those
// OriginAttributes get propagated to other classes according to certain rules.
// For example, the OriginAttributes on the docshell affect the OriginAttributes
// for the principal of a document loaded inside it, whose OriginAttributes in
// turn affect those of network loads and child docshells. To codify and
// centralize these rules, we introduce separate subclasses for the different
// flavors, and a variety of InheritFrom* methods to implement the transfer
// behavior.
// For OriginAttributes stored on principals.
class PrincipalOriginAttributes : public OriginAttributes
{
public:
PrincipalOriginAttributes() {}
PrincipalOriginAttributes(uint32_t aAppId, bool aInBrowser)
{
mAppId = aAppId;
mInBrowser = aInBrowser;
}
// Inheriting OriginAttributes from docshell to document when user navigates.
//
// @param aAttrs Origin Attributes of the docshell.
// @param aURI The URI of the document.
void InheritFromDocShellToDoc(const DocShellOriginAttributes& aAttrs,
const nsIURI* aURI);
// Inherit OriginAttributes from Necko.
void InheritFromNecko(const NeckoOriginAttributes& aAttrs);
};
// For OriginAttributes stored on docshells / loadcontexts / browsing contexts.
class DocShellOriginAttributes : public OriginAttributes
{
public:
DocShellOriginAttributes() {}
DocShellOriginAttributes(uint32_t aAppId, bool aInBrowser)
{
mAppId = aAppId;
mInBrowser = aInBrowser;
}
// Inheriting OriginAttributes from document to child docshell when an
// <iframe> is created.
//
// @param aAttrs Origin Attributes of the document.
void
InheritFromDocToChildDocShell(const PrincipalOriginAttributes& aAttrs);
};
// For OriginAttributes stored on Necko.
class NeckoOriginAttributes : public OriginAttributes
{
public:
NeckoOriginAttributes() {}
NeckoOriginAttributes(uint32_t aAppId, bool aInBrowser)
{
mAppId = aAppId;
mInBrowser = aInBrowser;
}
// Inheriting OriginAttributes from document to necko when a network request
// is made.
void InheritFromDocToNecko(const PrincipalOriginAttributes& aAttrs);
void InheritFromDocShellToNecko(const DocShellOriginAttributes& aAttrs);
};
// For operating on OriginAttributes not associated with any data structure.
class GenericOriginAttributes : public OriginAttributes
{
public:
GenericOriginAttributes() {}
explicit GenericOriginAttributes(const OriginAttributesDictionary& aOther)
: OriginAttributes(aOther) {}
};
class OriginAttributesPattern : public dom::OriginAttributesPatternDictionary
@ -168,10 +225,10 @@ public:
static BasePrincipal* Cast(nsIPrincipal* aPrin) { return static_cast<BasePrincipal*>(aPrin); }
static already_AddRefed<BasePrincipal>
CreateCodebasePrincipal(nsIURI* aURI, const OriginAttributes& aAttrs);
CreateCodebasePrincipal(nsIURI* aURI, const PrincipalOriginAttributes& aAttrs);
static already_AddRefed<BasePrincipal> CreateCodebasePrincipal(const nsACString& aOrigin);
const OriginAttributes& OriginAttributesRef() { return mOriginAttributes; }
const PrincipalOriginAttributes& OriginAttributesRef() { return mOriginAttributes; }
uint32_t AppId() const { return mOriginAttributes.mAppId; }
uint32_t UserContextId() const { return mOriginAttributes.mUserContextId; }
bool IsInBrowserElement() const { return mOriginAttributes.mInBrowser; }
@ -203,7 +260,7 @@ protected:
nsCOMPtr<nsIContentSecurityPolicy> mCSP;
nsCOMPtr<nsIContentSecurityPolicy> mPreloadCSP;
OriginAttributes mOriginAttributes;
PrincipalOriginAttributes mOriginAttributes;
};
} // namespace mozilla

View File

@ -160,7 +160,7 @@ nsJSPrincipals::ReadKnownPrincipalType(JSContext* aCx,
return false;
}
OriginAttributes attrs;
PrincipalOriginAttributes attrs;
attrs.PopulateFromSuffix(suffix);
info = ContentPrincipalInfo(attrs, spec);
}

View File

@ -44,7 +44,7 @@ nsNullPrincipal::CreateWithInheritedAttributes(nsIPrincipal* aInheritFrom)
}
/* static */ already_AddRefed<nsNullPrincipal>
nsNullPrincipal::Create(const OriginAttributes& aOriginAttributes)
nsNullPrincipal::Create(const PrincipalOriginAttributes& aOriginAttributes)
{
RefPtr<nsNullPrincipal> nullPrin = new nsNullPrincipal();
nsresult rv = nullPrin->Init(aOriginAttributes);
@ -54,7 +54,7 @@ nsNullPrincipal::Create(const OriginAttributes& aOriginAttributes)
}
nsresult
nsNullPrincipal::Init(const OriginAttributes& aOriginAttributes)
nsNullPrincipal::Init(const PrincipalOriginAttributes& aOriginAttributes)
{
mOriginAttributes = aOriginAttributes;

View File

@ -52,9 +52,9 @@ public:
// Returns null on failure.
static already_AddRefed<nsNullPrincipal>
Create(const mozilla::OriginAttributes& aOriginAttributes = mozilla::OriginAttributes());
Create(const mozilla::PrincipalOriginAttributes& aOriginAttributes = mozilla::PrincipalOriginAttributes());
nsresult Init(const mozilla::OriginAttributes& aOriginAttributes = mozilla::OriginAttributes());
nsresult Init(const mozilla::PrincipalOriginAttributes& aOriginAttributes = mozilla::PrincipalOriginAttributes());
virtual void GetScriptLocation(nsACString &aStr) override;

View File

@ -85,7 +85,7 @@ nsPrincipal::~nsPrincipal()
}
nsresult
nsPrincipal::Init(nsIURI *aCodebase, const OriginAttributes& aOriginAttributes)
nsPrincipal::Init(nsIURI *aCodebase, const PrincipalOriginAttributes& aOriginAttributes)
{
NS_ENSURE_STATE(!mInitialized);
NS_ENSURE_ARG(aCodebase);
@ -391,7 +391,7 @@ nsPrincipal::Read(nsIObjectInputStream* aStream)
rv = aStream->ReadCString(suffix);
NS_ENSURE_SUCCESS(rv, rv);
OriginAttributes attrs;
PrincipalOriginAttributes attrs;
bool ok = attrs.PopulateFromSuffix(suffix);
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);

View File

@ -34,7 +34,7 @@ public:
nsPrincipal();
// Init() must be called before the principal is in a usable state.
nsresult Init(nsIURI* aCodebase, const mozilla::OriginAttributes& aOriginAttributes);
nsresult Init(nsIURI* aCodebase, const mozilla::PrincipalOriginAttributes& aOriginAttributes);
virtual void GetScriptLocation(nsACString& aStr) override;
void SetURI(nsIURI* aURI);

View File

@ -291,7 +291,7 @@ nsScriptSecurityManager::AppStatusForPrincipal(nsIPrincipal *aPrin)
// The app could contain a cross-origin iframe - make sure that the content
// is actually same-origin with the app.
MOZ_ASSERT(inMozBrowser == false, "Checked this above");
OriginAttributes attrs(appId, false);
PrincipalOriginAttributes attrs(appId, false);
nsCOMPtr<nsIPrincipal> appPrin = BasePrincipal::CreateCodebasePrincipal(appURI, attrs);
NS_ENSURE_TRUE(appPrin, nsIPrincipal::APP_STATUS_NOT_INSTALLED);
return aPrin->Equals(appPrin) ? status
@ -362,7 +362,7 @@ nsScriptSecurityManager::GetChannelResultPrincipal(nsIChannel* aChannel,
}
nsresult
nsScriptSecurityManager::MaybeSetAddonIdFromURI(OriginAttributes& aAttrs, nsIURI* aURI)
nsScriptSecurityManager::MaybeSetAddonIdFromURI(PrincipalOriginAttributes& aAttrs, nsIURI* aURI)
{
nsAutoCString scheme;
nsresult rv = aURI->GetScheme(scheme);
@ -405,7 +405,8 @@ nsScriptSecurityManager::GetChannelURIPrincipal(nsIChannel* aChannel,
return GetLoadContextCodebasePrincipal(uri, loadContext, aPrincipal);
}
OriginAttributes attrs(UNKNOWN_APP_ID, false);
//TODO: Bug 1211590. inherit Origin Attributes from LoadInfo.
PrincipalOriginAttributes attrs(UNKNOWN_APP_ID, false);
rv = MaybeSetAddonIdFromURI(attrs, uri);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPrincipal> prin = BasePrincipal::CreateCodebasePrincipal(uri, attrs);
@ -1008,7 +1009,7 @@ NS_IMETHODIMP
nsScriptSecurityManager::GetSimpleCodebasePrincipal(nsIURI* aURI,
nsIPrincipal** aPrincipal)
{
OriginAttributes attrs(UNKNOWN_APP_ID, false);
PrincipalOriginAttributes attrs(UNKNOWN_APP_ID, false);
nsCOMPtr<nsIPrincipal> prin = BasePrincipal::CreateCodebasePrincipal(aURI, attrs);
prin.forget(aPrincipal);
return *aPrincipal ? NS_OK : NS_ERROR_FAILURE;
@ -1018,7 +1019,7 @@ NS_IMETHODIMP
nsScriptSecurityManager::GetNoAppCodebasePrincipal(nsIURI* aURI,
nsIPrincipal** aPrincipal)
{
OriginAttributes attrs(NO_APP_ID, false);
PrincipalOriginAttributes attrs(NO_APP_ID, false);
nsCOMPtr<nsIPrincipal> prin = BasePrincipal::CreateCodebasePrincipal(aURI, attrs);
prin.forget(aPrincipal);
return *aPrincipal ? NS_OK : NS_ERROR_FAILURE;
@ -1035,7 +1036,7 @@ NS_IMETHODIMP
nsScriptSecurityManager::CreateCodebasePrincipal(nsIURI* aURI, JS::Handle<JS::Value> aOriginAttributes,
JSContext* aCx, nsIPrincipal** aPrincipal)
{
OriginAttributes attrs;
PrincipalOriginAttributes attrs;
if (!aOriginAttributes.isObject() || !attrs.Init(aCx, aOriginAttributes)) {
return NS_ERROR_INVALID_ARG;
}
@ -1065,7 +1066,7 @@ NS_IMETHODIMP
nsScriptSecurityManager::CreateNullPrincipal(JS::Handle<JS::Value> aOriginAttributes,
JSContext* aCx, nsIPrincipal** aPrincipal)
{
OriginAttributes attrs;
PrincipalOriginAttributes attrs;
if (!aOriginAttributes.isObject() || !attrs.Init(aCx, aOriginAttributes)) {
return NS_ERROR_INVALID_ARG;
}
@ -1099,7 +1100,7 @@ nsScriptSecurityManager::GetAppCodebasePrincipal(nsIURI* aURI,
NS_ENSURE_TRUE(aAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID,
NS_ERROR_INVALID_ARG);
OriginAttributes attrs(aAppId, aInMozBrowser);
PrincipalOriginAttributes attrs(aAppId, aInMozBrowser);
nsCOMPtr<nsIPrincipal> prin = BasePrincipal::CreateCodebasePrincipal(aURI, attrs);
prin.forget(aPrincipal);
return *aPrincipal ? NS_OK : NS_ERROR_FAILURE;
@ -1111,10 +1112,13 @@ nsScriptSecurityManager::
nsILoadContext* aLoadContext,
nsIPrincipal** aPrincipal)
{
OriginAttributes attrs;
bool result = attrs.CopyFromLoadContext(aLoadContext);
DocShellOriginAttributes docShellAttrs;
bool result = aLoadContext->GetOriginAttributes(docShellAttrs);;
NS_ENSURE_TRUE(result, NS_ERROR_FAILURE);
PrincipalOriginAttributes attrs;
attrs.InheritFromDocShellToDoc(docShellAttrs, aURI);
nsresult rv = MaybeSetAddonIdFromURI(attrs, aURI);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPrincipal> prin = BasePrincipal::CreateCodebasePrincipal(aURI, attrs);
@ -1127,10 +1131,8 @@ nsScriptSecurityManager::GetDocShellCodebasePrincipal(nsIURI* aURI,
nsIDocShell* aDocShell,
nsIPrincipal** aPrincipal)
{
OriginAttributes attrs;
nsDocShell* docShell= nsDocShell::Cast(aDocShell);
bool result = attrs.CopyFromLoadContext(docShell);
NS_ENSURE_TRUE(result, NS_ERROR_FAILURE);
PrincipalOriginAttributes attrs;
attrs.InheritFromDocShellToDoc(nsDocShell::Cast(aDocShell)->GetOriginAttributes(), aURI);
nsresult rv = MaybeSetAddonIdFromURI(attrs, aURI);
NS_ENSURE_SUCCESS(rv, rv);

View File

@ -28,7 +28,7 @@ class nsIStringBundle;
class nsSystemPrincipal;
namespace mozilla {
class OriginAttributes;
class PrincipalOriginAttributes;
} // namespace mozilla
/////////////////////////////
@ -121,7 +121,7 @@ private:
AddSitesToFileURIWhitelist(const nsCString& aSiteList);
// If aURI is a moz-extension:// URI, set mAddonId to the associated addon.
nsresult MaybeSetAddonIdFromURI(mozilla::OriginAttributes& aAttrs, nsIURI* aURI);
nsresult MaybeSetAddonIdFromURI(mozilla::PrincipalOriginAttributes& aAttrs, nsIURI* aURI);
nsCOMPtr<nsIPrincipal> mSystemPrincipal;
bool mPrefInitialized;

View File

@ -4,34 +4,34 @@
#include "gtest/gtest.h"
#include "mozilla/BasePrincipal.h"
using mozilla::OriginAttributes;
using mozilla::PrincipalOriginAttributes;
static void
TestSuffix(const OriginAttributes& attrs)
TestSuffix(const PrincipalOriginAttributes& attrs)
{
nsAutoCString suffix;
attrs.CreateSuffix(suffix);
OriginAttributes attrsFromSuffix;
PrincipalOriginAttributes attrsFromSuffix;
attrsFromSuffix.PopulateFromSuffix(suffix);
EXPECT_EQ(attrs, attrsFromSuffix);
}
TEST(OriginAttributes, Suffix_default)
TEST(PrincipalOriginAttributes, Suffix_default)
{
OriginAttributes attrs;
PrincipalOriginAttributes attrs;
TestSuffix(attrs);
}
TEST(OriginAttributes, Suffix_appId_inBrowser)
TEST(PrincipalOriginAttributes, Suffix_appId_inBrowser)
{
OriginAttributes attrs(1, true);
PrincipalOriginAttributes attrs(1, true);
TestSuffix(attrs);
}
TEST(OriginAttributes, Suffix_maxAppId_inBrowser)
TEST(PrincipalOriginAttributes, Suffix_maxAppId_inBrowser)
{
OriginAttributes attrs(4294967295, true);
PrincipalOriginAttributes attrs(4294967295, true);
TestSuffix(attrs);
}

View File

@ -12,7 +12,8 @@ h2, h3, h4 {
}
button {
width: 100px;
padding-left: 20px;
padding-right: 20px;
}
#body {
@ -80,3 +81,12 @@ label {
.target-details {
flex: 1;
}
.addon-controls {
display: flex;
flex-direction: row;
}
.addon-options {
flex: 1;
}

View File

@ -8,6 +8,7 @@
"use strict";
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
const { loader } = Components.utils.import(
"resource://devtools/shared/Loader.jsm", {});
@ -23,7 +24,15 @@ loader.lazyRequireGetter(this, "WorkersComponent",
"devtools/client/aboutdebugging/components/workers", true);
loader.lazyRequireGetter(this, "Services");
loader.lazyImporter(this, "AddonManager",
"resource://gre/modules/AddonManager.jsm");
const Strings = Services.strings.createBundle(
"chrome://devtools/locale/aboutdebugging.properties");
var AboutDebugging = {
_prefListeners: [],
_categories: null,
get categories() {
// If needed, initialize the list of available categories.
@ -72,14 +81,19 @@ var AboutDebugging = {
let updatePref = () => {
Services.prefs.setBoolPref(pref, element.checked);
};
element.addEventListener("change", updatePref, false);
let updateCheckbox = () => {
element.checked = Services.prefs.getBoolPref(pref);
};
element.addEventListener("change", updatePref, false);
Services.prefs.addObserver(pref, updateCheckbox, false);
this._prefListeners.push([pref, updateCheckbox]);
updateCheckbox();
});
// Link buttons to their associated actions.
let loadAddonButton = document.getElementById("load-addon-from-file");
loadAddonButton.addEventListener("click", this.loadAddonFromFile);
if (!DebuggerServer.initialized) {
DebuggerServer.init();
DebuggerServer.addBrowserActors();
@ -95,10 +109,41 @@ var AboutDebugging = {
});
},
loadAddonFromFile() {
let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
fp.init(window,
Strings.GetStringFromName("selectAddonFromFile"),
Ci.nsIFilePicker.modeOpen);
let res = fp.show();
if (res == Ci.nsIFilePicker.returnCancel || !fp.file) {
return;
}
let file = fp.file;
// AddonManager.installTemporaryAddon accepts either
// addon directory or final xpi file.
if (!file.isDirectory() && !file.leafName.endsWith(".xpi")) {
file = file.parent;
}
try {
AddonManager.installTemporaryAddon(file);
} catch(e) {
alert("Error while installing the addon:\n" + e.message + "\n");
throw e;
}
},
destroy() {
let telemetry = this._telemetry;
telemetry.toolClosed("aboutdebugging");
telemetry.destroy();
this._prefListeners.forEach(([pref, listener]) => {
Services.prefs.removeObserver(pref, listener);
});
this._prefListeners = [];
React.unmountComponentAtNode(document.querySelector("#addons"));
React.unmountComponentAtNode(document.querySelector("#workers"));
},
};

View File

@ -34,8 +34,13 @@
<div class="header">
<h1 class="header-name">&aboutDebugging.addons;</h1>
</div>
<input id="enable-addon-debugging" type="checkbox" data-pref="devtools.chrome.enabled"/>
<label for="enable-addon-debugging" title="&aboutDebugging.addonDebugging.tooltip;">&aboutDebugging.addonDebugging.label;</label>
<div class="addon-controls">
<div class="addon-options">
<input id="enable-addon-debugging" type="checkbox" data-pref="devtools.chrome.enabled"/>
<label for="enable-addon-debugging" title="&aboutDebugging.addonDebugging.tooltip;">&aboutDebugging.addonDebugging.label;</label>
</div>
<button id="load-addon-from-file">&aboutDebugging.loadTemporaryAddon;</button>
</div>
<div id="addons"></div>
</div>
<div id="tab-workers" class="tab">

View File

@ -0,0 +1,13 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DIRS += [
'components',
]
BROWSER_CHROME_MANIFESTS += [
'test/browser.ini'
]

View File

@ -0,0 +1,7 @@
Components.utils.import("resource://gre/modules/Services.jsm");
function startup() {
Services.obs.notifyObservers(null, "test-devtools", null);
}
function shutdown() {}
function install() {}
function uninstall() {}

View File

@ -0,0 +1,26 @@
<?xml version="1.0"?>
<!--
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-->
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest"
em:id="test-devtools@mozilla.org"
em:name="test-devtools"
em:version="1.0"
em:type="2"
em:creator="Mozilla">
<em:bootstrap>true</em:bootstrap>
<em:targetApplication>
<Description>
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
<em:minVersion>44.0a1</em:minVersion>
<em:maxVersion>*</em:maxVersion>
</Description>
</em:targetApplication>
</Description>
</RDF>

View File

@ -0,0 +1,9 @@
[DEFAULT]
tags = devtools
subsuite = devtools
support-files =
head.js
addons/unpacked/bootstrap.js
addons/unpacked/install.rdf
[browser_addons_install.js]

View File

@ -0,0 +1,61 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
var {AddonManager} = Cu.import("resource://gre/modules/AddonManager.jsm", {});
const ADDON_ID = "test-devtools@mozilla.org";
const ADDON_NAME = "test-devtools";
add_task(function *() {
let { tab, document } = yield openAboutDebugging("addons");
// Mock the file picker to select a test addon
let MockFilePicker = SpecialPowers.MockFilePicker;
MockFilePicker.init(null);
let file = get_supports_file("addons/unpacked/install.rdf");
MockFilePicker.returnFiles = [file.file];
// Wait for a message sent by the addon's bootstrap.js file
let promise = new Promise(done => {
Services.obs.addObserver(function listener() {
Services.obs.removeObserver(listener, "test-devtools", false);
ok(true, "Addon installed and running its bootstrap.js file");
done();
}, "test-devtools", false);
});
// Trigger the file picker by clicking on the button
document.getElementById("load-addon-from-file").click();
// Wait for the addon execution
yield promise;
// Check that the addon appears in the UI
let names = [...document.querySelectorAll("#addons .target-name")];
names = names.map(element => element.textContent);
ok(names.includes(ADDON_NAME), "The addon name appears in the list of addons: " + names);
// Now uninstall this addon
yield new Promise(done => {
AddonManager.getAddonByID(ADDON_ID, addon => {
let listener = {
onUninstalled: function(aUninstalledAddon) {
if (aUninstalledAddon != addon) {
return;
}
AddonManager.removeAddonListener(listener);
done();
}
};
AddonManager.addAddonListener(listener);
addon.uninstall();
});
});
// Ensure that the UI removes the addon from the list
names = [...document.querySelectorAll("#addons .target-name")];
names = names.map(element => element.textContent);
ok(!names.includes(ADDON_NAME), "After uninstall, the addon name disappears from the list of addons: " + names);
yield closeAboutDebugging(tab);
});

View File

@ -0,0 +1,78 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
var {utils: Cu, classes: Cc, interfaces: Ci} = Components;
const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
const Services = require("Services");
const DevToolsUtils = require("devtools/shared/DevToolsUtils");
DevToolsUtils.testing = true;
const CHROME_ROOT = gTestPath.substr(0, gTestPath.lastIndexOf("/") + 1);
registerCleanupFunction(() => {
DevToolsUtils.testing = false;
});
function openAboutDebugging() {
info("opening about:debugging");
return addTab("about:debugging").then(tab => {
let browser = tab.linkedBrowser;
return {
tab,
document: browser.contentDocument,
window: browser.contentWindow
};
});
}
function closeAboutDebugging(tab) {
info("Closing about:debugging");
return removeTab(tab);
}
function addTab(aUrl, aWindow) {
info("Adding tab: " + aUrl);
return new Promise(done => {
let targetWindow = aWindow || window;
let targetBrowser = targetWindow.gBrowser;
targetWindow.focus();
let tab = targetBrowser.selectedTab = targetBrowser.addTab(aUrl);
let linkedBrowser = tab.linkedBrowser;
linkedBrowser.addEventListener("load", function onLoad() {
linkedBrowser.removeEventListener("load", onLoad, true);
info("Tab added and finished loading: " + aUrl);
done(tab);
}, true);
});
}
function removeTab(aTab, aWindow) {
info("Removing tab.");
return new Promise(done => {
let targetWindow = aWindow || window;
let targetBrowser = targetWindow.gBrowser;
let tabContainer = targetBrowser.tabContainer;
tabContainer.addEventListener("TabClose", function onClose(aEvent) {
tabContainer.removeEventListener("TabClose", onClose, false);
info("Tab removed and finished closing.");
done();
}, false);
targetBrowser.removeTab(aTab);
});
}
function get_supports_file(path) {
let cr = Cc["@mozilla.org/chrome/chrome-registry;1"].
getService(Ci.nsIChromeRegistry);
let fileurl = cr.convertChromeURL(Services.io.newURI(CHROME_ROOT + path, null, null));
return fileurl.QueryInterface(Ci.nsIFileURL);
}

View File

@ -565,6 +565,7 @@ function AnimationsTimeline(inspector) {
this.onScrubberMouseUp = this.onScrubberMouseUp.bind(this);
this.onScrubberMouseOut = this.onScrubberMouseOut.bind(this);
this.onScrubberMouseMove = this.onScrubberMouseMove.bind(this);
this.onAnimationSelected = this.onAnimationSelected.bind(this);
EventEmitter.decorate(this);
}
@ -633,14 +634,17 @@ AnimationsTimeline.prototype = {
this.win = null;
this.inspector = null;
},
destroyTargetNodes: function() {
for (let targetNode of this.targetNodes) {
targetNode.destroy();
}
this.targetNodes = [];
},
destroyTimeBlocks: function() {
for (let timeBlock of this.timeBlocks) {
timeBlock.off("selected", this.onAnimationSelected);
timeBlock.destroy();
}
this.timeBlocks = [];
@ -656,6 +660,24 @@ AnimationsTimeline.prototype = {
this.animationsEl.innerHTML = "";
},
onAnimationSelected: function(e, animation) {
// Unselect the previously selected animation if any.
[...this.rootWrapperEl.querySelectorAll(".animation.selected")].forEach(el => {
el.classList.remove("selected");
});
// Select the new animation.
let index = this.animations.indexOf(animation);
if (index === -1) {
return;
}
this.rootWrapperEl.querySelectorAll(".animation")[index]
.classList.toggle("selected");
// Relay the event to the parent component.
this.emit("selected", animation);
},
onScrubberMouseDown: function(e) {
this.moveScrubberTo(e.pageX);
this.win.addEventListener("mouseup", this.onScrubberMouseUp);
@ -764,6 +786,8 @@ AnimationsTimeline.prototype = {
timeBlock.init(timeBlockEl);
timeBlock.render(animation);
this.timeBlocks.push(timeBlock);
timeBlock.on("selected", this.onAnimationSelected);
}
// Use the document's current time to position the scrubber (if the server
// doesn't provide it, hide the scrubber entirely).
@ -872,15 +896,21 @@ AnimationsTimeline.prototype = {
* UI component responsible for displaying a single animation timeline, which
* basically looks like a rectangle that shows the delay and iterations.
*/
function AnimationTimeBlock() {}
function AnimationTimeBlock() {
EventEmitter.decorate(this);
this.onClick = this.onClick.bind(this);
}
exports.AnimationTimeBlock = AnimationTimeBlock;
AnimationTimeBlock.prototype = {
init: function(containerEl) {
this.containerEl = containerEl;
this.containerEl.addEventListener("click", this.onClick);
},
destroy: function() {
this.containerEl.removeEventListener("click", this.onClick);
while (this.containerEl.firstChild) {
this.containerEl.firstChild.remove();
}
@ -999,6 +1029,10 @@ AnimationTimeBlock.prototype = {
}
return text;
},
onClick: function() {
this.emit("selected", this.animation);
}
};

View File

@ -9,6 +9,7 @@ support-files =
doc_simple_animation.html
head.js
[browser_animation_click_selects_animation.js]
[browser_animation_controller_exposes_document_currentTime.js]
[browser_animation_empty_on_invalid_nodes.js]
[browser_animation_mutations_with_same_names.js]

View File

@ -0,0 +1,47 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Check that animations displayed in the timeline can be selected by clicking
// them, and that this emits the right events and adds the right classes.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {panel} = yield openAnimationInspector();
let timeline = panel.animationsTimelineComponent;
let selected = timeline.rootWrapperEl.querySelectorAll(".animation.selected");
ok(!selected.length, "There are no animations selected by default");
info("Click on the first animation, expect the right event and right class");
let animation0 = yield clickToSelect(timeline, 0);
is(animation0, timeline.animations[0],
"The selected event was emitted with the right animation");
ok(isTimeBlockSelected(timeline, 0),
"The time block has the right selected class");
info("Click on the second animation, expect the first one to be unselected");
let animation1 = yield clickToSelect(timeline, 1);
is(animation1, timeline.animations[1],
"The selected event was emitted with the right animation");
ok(isTimeBlockSelected(timeline, 1),
"The second time block has the right selected class");
ok(!isTimeBlockSelected(timeline, 0),
"The first time block has been unselected");
});
function* clickToSelect(timeline, index) {
info("Click on animation " + index + " in the timeline");
let onSelected = timeline.once("selected");
let timeBlock = timeline.rootWrapperEl.querySelectorAll(".time-block")[index];
EventUtils.sendMouseEvent({type: "click"}, timeBlock,
timeBlock.ownerDocument.defaultView);
return yield onSelected;
}
function isTimeBlockSelected(timeline, index) {
let animation = timeline.rootWrapperEl.querySelectorAll(".animation")[index];
return animation.classList.contains("selected");
}

View File

@ -2,6 +2,7 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/content/shared/widgets/widgets.css" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/skin/common.css" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/skin/widgets.css" type="text/css"?>

View File

@ -75,6 +75,7 @@ support-files =
[browser_cmd_pref1.js]
[browser_cmd_pref2.js]
[browser_cmd_pref3.js]
[browser_cmd_qsa.js]
[browser_cmd_restart.js]
[browser_cmd_rulers.js]
[browser_cmd_screenshot.js]

View File

@ -0,0 +1,33 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Tests that the qsa commands work as they should.
const TEST_URI = "data:text/html;charset=utf-8,<body></body>";
function test() {
helpers.addTabWithToolbar(TEST_URI, function(options) {
return helpers.audit(options, [
{
setup: 'qsa',
check: {
input: 'qsa',
hints: ' [query]',
markup: 'VVV',
status: 'VALID'
}
},
{
setup: 'qsa body',
check: {
input: 'qsa body',
hints: '',
markup: 'VVVVVVVV',
status: 'VALID'
}
}
]);
}).then(finish, helpers.handleError);
}

View File

@ -2,6 +2,7 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/content/shared/widgets/widgets.css" type="text/css"?>
<?xml-stylesheet href="debugger.css" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/skin/common.css" type="text/css"?>

View File

@ -6,6 +6,7 @@
<!ENTITY % toolboxDTD SYSTEM "chrome://devtools/locale/toolbox.dtd" >
%toolboxDTD;
]>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet rel="stylesheet" href="chrome://devtools/content/framework/dev-edition-promo/dev-edition-promo.css" type="text/css"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" id="dev-edition-promo">

View File

@ -2,6 +2,7 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/content/shared/widgets/widgets.css" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/skin/common.css" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/skin/widgets.css" type="text/css"?>

View File

@ -7,6 +7,8 @@
%toolboxDTD;
]>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
id="devtools-toolbox-window"
macanimationtype="document"

View File

@ -7,6 +7,8 @@
%toolboxDTD;
]>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
id="devtools-toolbox-window"
macanimationtype="document"

View File

@ -2,6 +2,7 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/content/shared/widgets/widgets.css" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/content/inspector/inspector.css" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/skin/common.css" type="text/css"?>

View File

@ -6,4 +6,5 @@
<!ENTITY aboutDebugging.addons "Add-ons">
<!ENTITY aboutDebugging.addonDebugging.label "Enable add-on debugging">
<!ENTITY aboutDebugging.addonDebugging.tooltip "Turning this on will allow you to debug add-ons and various other parts of the browser chrome">
<!ENTITY aboutDebugging.loadTemporaryAddon "Load Temporary Add-on">
<!ENTITY aboutDebugging.workers "Workers">

View File

@ -5,6 +5,7 @@
debug = Debug
extensions = Extensions
selectAddonFromFile = Select Add-on Directory or XPI File
serviceWorkers = Service Workers
sharedWorkers = Shared Workers
otherWorkers = Other Workers

View File

@ -18,7 +18,7 @@ add_task(function*() {
markup.isDragging = true;
info("Simulate a mousemove on the view, at the bottom, and expect scrolling");
let onScrolled = waitForViewScroll(markup);
let onScrolled = waitForScrollStop(markup);
markup._onMouseMove({
preventDefault: () => {},
@ -30,7 +30,7 @@ add_task(function*() {
ok(bottomScrollPos > 0, "The view was scrolled down");
info("Simulate a mousemove at the top and expect more scrolling");
onScrolled = waitForViewScroll(markup);
onScrolled = waitForScrollStop(markup);
markup._onMouseMove({
preventDefault: () => {},
@ -46,22 +46,28 @@ add_task(function*() {
markup._onMouseUp();
});
function waitForViewScroll(markup) {
/**
* Waits until the element has not scrolled for 30 consecutive frames.
*/
function* waitForScrollStop(markup) {
let el = markup.doc.documentElement;
let startPos = el.scrollTop;
let win = markup.doc.defaultView;
let lastScrollTop = el.scrollTop;
let stopFrameCount = 0;
while (stopFrameCount < 30) {
// Wait for a frame.
yield new Promise(resolve => win.requestAnimationFrame(resolve));
return new Promise(resolve => {
let isDone = () => {
if (el.scrollTop === startPos) {
resolve(el.scrollTop);
} else {
startPos = el.scrollTop;
// Continue checking every 50ms.
setTimeout(isDone, 50);
}
};
// Check if the element has scrolled.
if (lastScrollTop == el.scrollTop) {
// No scrolling since the last frame.
stopFrameCount++;
} else {
// The element has scrolled. Reset the frame counter.
stopFrameCount = 0;
lastScrollTop = el.scrollTop;
}
}
// Start checking if the view scrolled after a while.
setTimeout(isDone, 50);
});
return lastScrollTop;
}

View File

@ -7,7 +7,7 @@
include('../templates.mozbuild')
DIRS += [
'aboutdebugging/components',
'aboutdebugging',
'animationinspector',
'canvasdebugger',
'commandline',

View File

@ -2,6 +2,7 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/content/shared/widgets/widgets.css" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/content/netmonitor/netmonitor.css" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/skin/common.css" type="text/css"?>

View File

@ -2,6 +2,7 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/content/shared/widgets/widgets.css" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/skin/common.css" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/skin/widgets.css" type="text/css"?>

View File

@ -2,6 +2,7 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/skin/common.css" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/skin/widgets.css" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/skin/shadereditor.css" type="text/css"?>

View File

@ -2,6 +2,7 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/skin/common.css" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/skin/widgets.css" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/content/shared/widgets/widgets.css" type="text/css"?>

View File

@ -2,6 +2,7 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/content/shared/widgets/widgets.css" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/skin/common.css" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/skin/widgets.css" type="text/css"?>

View File

@ -238,6 +238,10 @@ body {
background-color: var(--even-animation-timeline-background-color);
}
.animation-timeline .animation.selected {
background-color: var(--theme-selection-background-semitransparent);
}
.animation-timeline .animation .target {
width: var(--timeline-sidebar-width);
overflow: hidden;
@ -254,6 +258,7 @@ body {
left: var(--timeline-sidebar-width);
right: 0;
height: var(--timeline-animation-height);
cursor: pointer;
}
/* Animation iterations */

View File

@ -2,6 +2,7 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/content/shared/widgets/widgets.css" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/skin/common.css" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/skin/widgets.css" type="text/css"?>

View File

@ -158,8 +158,12 @@ WebConsoleActor.prototype =
},
/**
* The window we work with.
* @type nsIDOMWindow
* The window or sandbox we work with.
* Note that even if it is named `window` it refers to the current
* global we are debugging, which can be a Sandbox for addons
* or browser content toolbox.
*
* @type nsIDOMWindow or Sandbox
*/
get window() {
if (this.parentActor.isRootActor) {
@ -736,7 +740,8 @@ WebConsoleActor.prototype =
break;
}
let requestStartTime = this.window ?
// See `window` definition. It isn't always a DOM Window.
let requestStartTime = this.window && this.window.performance ?
this.window.performance.timing.requestStart : 0;
let cache = this.consoleAPIListener

View File

@ -69,6 +69,7 @@ exports.devtoolsModules = [
"devtools/shared/gcli/commands/media",
"devtools/shared/gcli/commands/pagemod",
"devtools/shared/gcli/commands/paintflashing",
"devtools/shared/gcli/commands/qsa",
"devtools/shared/gcli/commands/restart",
"devtools/shared/gcli/commands/rulers",
"devtools/shared/gcli/commands/screenshot",

View File

@ -21,6 +21,7 @@ DevToolsModules(
'media.js',
'pagemod.js',
'paintflashing.js',
'qsa.js',
'restart.js',
'rulers.js',
'screenshot.js',

View File

@ -0,0 +1,24 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const l10n = require("gcli/l10n");
exports.items = [
{
item: "command",
runAt: "server",
name: "qsa",
description: l10n.lookup("qsaDesc"),
params: [{
name: "query",
type: "nodelist",
description: l10n.lookup("qsaQueryDesc")
}],
exec: function(args, context) {
return args.query.length;
}
}
];

View File

@ -57,20 +57,7 @@ using JS::ubi::AtomOrTwoByteChars;
/*** Cycle Collection Boilerplate *****************************************************************/
NS_IMPL_CYCLE_COLLECTION_CLASS(HeapSnapshot)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(HeapSnapshot)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(HeapSnapshot)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(HeapSnapshot)
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(HeapSnapshot, mParent)
NS_IMPL_CYCLE_COLLECTING_ADDREF(HeapSnapshot)
NS_IMPL_CYCLE_COLLECTING_RELEASE(HeapSnapshot)

View File

@ -1557,6 +1557,11 @@ mediaEmulateManual=View the document as if rendered on a device supporting the g
mediaEmulateType=The media type to emulate
mediaResetDesc=Stop emulating a CSS media type
# LOCALIZATION NOTE (qsaDesc, qsaQueryDesc)
# These strings describe the 'qsa' commands and all available parameters.
qsaDesc=Perform querySelectorAll on the current document and return number of matches
qsaQueryDesc=CSS selectors separated by comma
# LOCALIZATION NOTE (injectDesc, injectManual, injectLibraryDesc, injectLoaded,
# injectFailed) These strings describe the 'inject' commands and all available
# parameters.

View File

@ -23,7 +23,8 @@ LoadContext::LoadContext(nsIPrincipal* aPrincipal,
, mIsNotNull(true)
#endif
{
mOriginAttributes = BasePrincipal::Cast(aPrincipal)->OriginAttributesRef();
PrincipalOriginAttributes poa = BasePrincipal::Cast(aPrincipal)->OriginAttributesRef();
mOriginAttributes = DocShellOriginAttributes(poa.mAppId, poa.mInBrowser);
if (!aOptionalBase) {
return;

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