mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge m-c to inbound. a=merge
CLOSED TREE
This commit is contained in:
commit
6fc4fa1738
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="9f36b711af7597a6a32471c3305cf1e2d6947d39"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="b387bcad9bf8389580a8ae133b071053cfc9c30f"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
|
||||
<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="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="41efd945c841175f733ef764fe5f6a85c592970b"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="94516f787d477dc307e4566f415e0d2f0794f6b9"/>
|
||||
<!-- 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"/>
|
||||
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
|
||||
@ -122,7 +122,7 @@
|
||||
<project name="platform/system/media" path="system/media" revision="c1332c21c608f4932a6d7e83450411cde53315ef"/>
|
||||
<default remote="caf" revision="LNX.LA.3.5.2.1.1" sync-j="4"/>
|
||||
<!-- Platform common things -->
|
||||
<project name="device-shinano-common" path="device/sony/shinano-common" remote="b2g" revision="9934000e6d842b4c4d76fb56f52584e1a3819c9c"/>
|
||||
<project name="device-shinano-common" path="device/sony/shinano-common" remote="b2g" revision="ac45522bb3a14aff9facd74e2cd03430e1e0793f"/>
|
||||
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="1bb28abbc215f45220620af5cd60a8ac1be93722"/>
|
||||
<project name="device/qcom/common" path="device/qcom/common" revision="2501e5940ba69ece7654ff85611c76ae5bda299c"/>
|
||||
<project name="codeaurora_kernel_msm" path="kernel" remote="b2g" revision="5ada05ac150f643ef19e87015df7e106b88effe7"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="9f36b711af7597a6a32471c3305cf1e2d6947d39"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="b387bcad9bf8389580a8ae133b071053cfc9c30f"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
|
||||
<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="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="41efd945c841175f733ef764fe5f6a85c592970b"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="94516f787d477dc307e4566f415e0d2f0794f6b9"/>
|
||||
<!-- 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"/>
|
||||
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
|
||||
|
@ -19,7 +19,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="9f36b711af7597a6a32471c3305cf1e2d6947d39"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="b387bcad9bf8389580a8ae133b071053cfc9c30f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="87a2d8ab9248540910e56921654367b78a587095"/>
|
||||
|
@ -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="9f36b711af7597a6a32471c3305cf1e2d6947d39"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="b387bcad9bf8389580a8ae133b071053cfc9c30f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="41efd945c841175f733ef764fe5f6a85c592970b"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="94516f787d477dc307e4566f415e0d2f0794f6b9"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<!-- Stock Android things -->
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="9f36b711af7597a6a32471c3305cf1e2d6947d39"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="b387bcad9bf8389580a8ae133b071053cfc9c30f"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
|
||||
<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="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="41efd945c841175f733ef764fe5f6a85c592970b"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="94516f787d477dc307e4566f415e0d2f0794f6b9"/>
|
||||
<!-- 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"/>
|
||||
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="6e47ff2790f5656b5b074407829ceecf3e6188c4"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="9f36b711af7597a6a32471c3305cf1e2d6947d39"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="b387bcad9bf8389580a8ae133b071053cfc9c30f"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
|
||||
<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="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="41efd945c841175f733ef764fe5f6a85c592970b"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="94516f787d477dc307e4566f415e0d2f0794f6b9"/>
|
||||
<!-- 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"/>
|
||||
<project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" revision="337e0ef5e40f02a1ae59b90db0548976c70a7226"/>
|
||||
|
@ -19,7 +19,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="9f36b711af7597a6a32471c3305cf1e2d6947d39"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="b387bcad9bf8389580a8ae133b071053cfc9c30f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="87a2d8ab9248540910e56921654367b78a587095"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="9f36b711af7597a6a32471c3305cf1e2d6947d39"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="b387bcad9bf8389580a8ae133b071053cfc9c30f"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
|
||||
<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="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="41efd945c841175f733ef764fe5f6a85c592970b"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="94516f787d477dc307e4566f415e0d2f0794f6b9"/>
|
||||
<!-- 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"/>
|
||||
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
|
||||
|
@ -1,9 +1,9 @@
|
||||
{
|
||||
"git": {
|
||||
"git_revision": "9f36b711af7597a6a32471c3305cf1e2d6947d39",
|
||||
"git_revision": "b387bcad9bf8389580a8ae133b071053cfc9c30f",
|
||||
"remote": "https://git.mozilla.org/releases/gaia.git",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "8583025b84cda74c63e83bbbdfd7a4f33b917f20",
|
||||
"revision": "7dbfef98a254a3d56b8d38e003c988f9d19771a4",
|
||||
"repo_path": "integration/gaia-central"
|
||||
}
|
||||
|
@ -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="9f36b711af7597a6a32471c3305cf1e2d6947d39"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="b387bcad9bf8389580a8ae133b071053cfc9c30f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="41efd945c841175f733ef764fe5f6a85c592970b"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="94516f787d477dc307e4566f415e0d2f0794f6b9"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<!-- Stock Android things -->
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="9f36b711af7597a6a32471c3305cf1e2d6947d39"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="b387bcad9bf8389580a8ae133b071053cfc9c30f"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
|
||||
<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="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="41efd945c841175f733ef764fe5f6a85c592970b"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="94516f787d477dc307e4566f415e0d2f0794f6b9"/>
|
||||
<!-- 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"/>
|
||||
<project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" revision="337e0ef5e40f02a1ae59b90db0548976c70a7226"/>
|
||||
|
@ -522,38 +522,38 @@ let LoopUI;
|
||||
* has been fetched.
|
||||
*/
|
||||
getFavicon: function(callback) {
|
||||
let favicon = gBrowser.getIcon(gBrowser.selectedTab);
|
||||
// If the tab image's url starts with http(s), fetch icon from favicon
|
||||
// service via the moz-anno protocol.
|
||||
if (/^https?:/.test(favicon)) {
|
||||
let faviconURI = makeURI(favicon);
|
||||
favicon = this.favIconService.getFaviconLinkForIcon(faviconURI).spec;
|
||||
}
|
||||
if (!favicon) {
|
||||
callback(new Error("No favicon found"));
|
||||
let pageURI = gBrowser.selectedTab.linkedBrowser.currentURI.spec;
|
||||
// If the tab page’s url starts with http(s), fetch icon.
|
||||
if (!/^https?:/.test(pageURI)) {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
favicon = this.PlacesUtils.getImageURLForResolution(window, favicon);
|
||||
|
||||
// We XHR the favicon to get a File object, which we can pass to the FileReader
|
||||
// object. The FileReader turns the File object into a data-uri.
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open("get", favicon, true);
|
||||
xhr.responseType = "blob";
|
||||
xhr.overrideMimeType("image/x-icon");
|
||||
xhr.onload = () => {
|
||||
if (xhr.status != 200) {
|
||||
callback(new Error("Invalid status code received for favicon XHR: " + xhr.status));
|
||||
return;
|
||||
}
|
||||
this.PlacesUtils.promiseFaviconLinkUrl(pageURI).then(uri => {
|
||||
uri = this.PlacesUtils.getImageURLForResolution(window, uri.spec);
|
||||
|
||||
let reader = new FileReader();
|
||||
reader.onload = () => callback(null, reader.result);
|
||||
reader.onerror = callback;
|
||||
reader.readAsDataURL(xhr.response);
|
||||
};
|
||||
xhr.onerror = callback;
|
||||
xhr.send();
|
||||
// We XHR the favicon to get a File object, which we can pass to the FileReader
|
||||
// object. The FileReader turns the File object into a data-uri.
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open("get", uri, true);
|
||||
xhr.responseType = "blob";
|
||||
xhr.overrideMimeType("image/x-icon");
|
||||
xhr.onload = () => {
|
||||
if (xhr.status != 200) {
|
||||
callback(new Error("Invalid status code received for favicon XHR: " + xhr.status));
|
||||
return;
|
||||
}
|
||||
|
||||
let reader = new FileReader();
|
||||
reader.onload = reader.onload = () => callback(null, reader.result);
|
||||
reader.onerror = callback;
|
||||
reader.readAsDataURL(xhr.response);
|
||||
};
|
||||
xhr.onerror = callback;
|
||||
xhr.send();
|
||||
}).catch(err => {
|
||||
callback(err || new Error("No favicon found"));
|
||||
});
|
||||
}
|
||||
};
|
||||
})();
|
||||
@ -563,5 +563,3 @@ XPCOMUtils.defineLazyModuleGetter(LoopUI, "LoopRooms", "resource:///modules/loop
|
||||
XPCOMUtils.defineLazyModuleGetter(LoopUI, "MozLoopService", "resource:///modules/loop/MozLoopService.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(LoopUI, "PanelFrame", "resource:///modules/PanelFrame.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(LoopUI, "PlacesUtils", "resource://gre/modules/PlacesUtils.jsm");
|
||||
XPCOMUtils.defineLazyServiceGetter(LoopUI, "favIconService",
|
||||
"@mozilla.org/browser/favicon-service;1", "nsIFaviconService");
|
||||
|
@ -34,8 +34,8 @@
|
||||
* along any dimension beyond the point at which an overflow event would
|
||||
* occur". But none of -moz-{fit,max,min}-content do what we want here. So..
|
||||
*/
|
||||
min-width: 320px;
|
||||
min-height: 280px;
|
||||
min-width: 260px;
|
||||
min-height: 315px;
|
||||
}
|
||||
|
||||
#main-window[customize-entered] {
|
||||
@ -907,8 +907,32 @@ chatbox {
|
||||
width: 260px; /* CHAT_WIDTH_OPEN in socialchat.xml */
|
||||
}
|
||||
|
||||
chatbox[large="true"] {
|
||||
width: 300px;
|
||||
chatbox[customSize] {
|
||||
width: 300px; /* CHAT_WIDTH_OPEN_ALT in socialchat.xml */
|
||||
}
|
||||
|
||||
#chat-window[customSize] {
|
||||
min-width: 300px;
|
||||
}
|
||||
|
||||
chatbox[customSize="loopChatEnabled"] {
|
||||
/* 325px as defined per UX */
|
||||
height: 325px;
|
||||
}
|
||||
|
||||
#chat-window[customSize="loopChatEnabled"] {
|
||||
/* 325px + 30px top bar height. */
|
||||
min-height: calc(325px + 30px);
|
||||
}
|
||||
|
||||
chatbox[customSize="loopChatMessageAppended"] {
|
||||
/* 445px as defined per UX */
|
||||
height: 445px;
|
||||
}
|
||||
|
||||
#chat-window[customSize="loopChatMessageAppended"] {
|
||||
/* 445px + 30px top bar height. */
|
||||
min-height: calc(445px + 30px);
|
||||
}
|
||||
|
||||
chatbox[minimized="true"] {
|
||||
@ -922,6 +946,15 @@ chatbar {
|
||||
max-height: 0;
|
||||
}
|
||||
|
||||
.chatbar-innerbox {
|
||||
margin: -285px 0 0;
|
||||
}
|
||||
|
||||
chatbar[customSize] > .chatbar-innerbox {
|
||||
/* 425px to make room for the maximum custom-size chatbox; currently 'loopChatMessageAppended'. */
|
||||
margin-top: -425px;
|
||||
}
|
||||
|
||||
/* Apply crisp rendering for favicons at exactly 2dppx resolution */
|
||||
@media (resolution: 2dppx) {
|
||||
#social-sidebar-favico,
|
||||
|
@ -160,8 +160,7 @@
|
||||
<parameter name="aTarget"/>
|
||||
<body><![CDATA[
|
||||
aTarget.setAttribute("label", this.contentDocument.title);
|
||||
if (this.getAttribute("dark") == "true")
|
||||
aTarget.setAttribute("dark", "true");
|
||||
|
||||
aTarget.src = this.src;
|
||||
aTarget.content.setAttribute("origin", this.content.getAttribute("origin"));
|
||||
aTarget.content.popupnotificationanchor.className = this.content.popupnotificationanchor.className;
|
||||
@ -169,6 +168,16 @@
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<method name="setDecorationAttributes">
|
||||
<parameter name="aTarget"/>
|
||||
<body><![CDATA[
|
||||
for (let attr of ["dark", "customSize"]) {
|
||||
if (this.hasAttribute(attr))
|
||||
aTarget.setAttribute(attr, this.getAttribute(attr));
|
||||
}
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<method name="onTitlebarClick">
|
||||
<parameter name="aEvent"/>
|
||||
<body><![CDATA[
|
||||
@ -211,6 +220,8 @@
|
||||
let chatbar = win.document.getElementById("pinnedchats");
|
||||
let origin = this.content.getAttribute("origin");
|
||||
let cb = chatbar.openChat(origin, title, "about:blank");
|
||||
this.setDecorationAttributes(cb);
|
||||
|
||||
cb.promiseChatLoaded.then(
|
||||
() => {
|
||||
this.swapDocShells(cb);
|
||||
@ -225,6 +236,12 @@
|
||||
chatbar.chatboxForURL.delete("about:blank");
|
||||
chatbar.chatboxForURL.set(this.src, Cu.getWeakReference(cb));
|
||||
|
||||
let attachEvent = new cb.contentWindow.CustomEvent("socialFrameAttached", {
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
});
|
||||
cb.contentDocument.dispatchEvent(attachEvent);
|
||||
|
||||
deferred.resolve(cb);
|
||||
}
|
||||
);
|
||||
@ -457,8 +474,10 @@
|
||||
// These are from the CSS for the chatbox and must be kept in sync.
|
||||
// We can't use calcTotalWidthOf due to the transitions...
|
||||
const CHAT_WIDTH_OPEN = 260;
|
||||
const CHAT_WIDTH_OPEN_ALT = 300;
|
||||
const CHAT_WIDTH_MINIMIZED = 160;
|
||||
let openWidth = aChatbox.hasAttribute("large") ? 300 : CHAT_WIDTH_OPEN;
|
||||
let openWidth = aChatbox.hasAttribute("customSize") ?
|
||||
CHAT_WIDTH_OPEN_ALT : CHAT_WIDTH_OPEN;
|
||||
|
||||
return aChatbox.minimized ? CHAT_WIDTH_MINIMIZED : openWidth;
|
||||
]]></body>
|
||||
@ -684,18 +703,27 @@
|
||||
if (event.target != otherWin.document)
|
||||
return;
|
||||
|
||||
if (aChatbox.hasAttribute("customSize")) {
|
||||
otherWin.document.getElementById("chat-window").
|
||||
setAttribute("customSize", aChatbox.getAttribute("customSize"));
|
||||
}
|
||||
|
||||
let document = aChatbox.contentDocument;
|
||||
let detachEvent = new aChatbox.contentWindow.CustomEvent("socialFrameDetached", {
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
});
|
||||
aChatbox.contentDocument.dispatchEvent(detachEvent);
|
||||
|
||||
otherWin.removeEventListener("load", _chatLoad, true);
|
||||
let otherChatbox = otherWin.document.getElementById("chatter");
|
||||
aChatbox.setDecorationAttributes(otherChatbox);
|
||||
aChatbox.swapDocShells(otherChatbox);
|
||||
aChatbox.close();
|
||||
chatbar.chatboxForURL.set(aChatbox.src, Cu.getWeakReference(otherChatbox));
|
||||
|
||||
// All processing is done, now we can fire the event.
|
||||
document.dispatchEvent(detachEvent);
|
||||
|
||||
deferred.resolve(otherChatbox);
|
||||
}, true);
|
||||
return deferred.promise;
|
||||
|
@ -269,10 +269,6 @@ html[dir="rtl"] .new-room-view > .context > .context-content > .context-preview
|
||||
float: left;
|
||||
}
|
||||
|
||||
.new-room-view > .context > .context-content > .context-preview[src=""] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.new-room-view > .context > .context-content > .context-description {
|
||||
flex: 0 1 auto;
|
||||
display: block;
|
||||
|
@ -29,7 +29,7 @@ loop.conversationViews = (function(mozL10n) {
|
||||
if (!contact.email || contact.email.length === 0) {
|
||||
return { value: "" };
|
||||
}
|
||||
return contact.email.find(e => e.pref) || contact.email[0];
|
||||
return contact.email.find(function find(e) { return e.pref; }) || contact.email[0];
|
||||
}
|
||||
|
||||
function _getContactDisplayName(contact) {
|
||||
|
@ -29,7 +29,7 @@ loop.conversationViews = (function(mozL10n) {
|
||||
if (!contact.email || contact.email.length === 0) {
|
||||
return { value: "" };
|
||||
}
|
||||
return contact.email.find(e => e.pref) || contact.email[0];
|
||||
return contact.email.find(function find(e) { return e.pref; }) || contact.email[0];
|
||||
}
|
||||
|
||||
function _getContactDisplayName(contact) {
|
||||
|
@ -500,9 +500,8 @@ loop.panel = (function(_, mozL10n) {
|
||||
|
||||
return (
|
||||
React.createElement("div", {className: "room-entry-context-item"},
|
||||
React.createElement("a", {href: roomUrl.location, onClick: this.handleClick},
|
||||
React.createElement("img", {title: roomUrl.description,
|
||||
src: roomUrl.thumbnail})
|
||||
React.createElement("a", {href: roomUrl.location, title: roomUrl.description, onClick: this.handleClick},
|
||||
React.createElement("img", {src: roomUrl.thumbnail || "loop/shared/img/icons-16x16.svg#globe"})
|
||||
)
|
||||
)
|
||||
);
|
||||
@ -766,6 +765,7 @@ loop.panel = (function(_, mozL10n) {
|
||||
hide: !hostname ||
|
||||
!this.props.mozLoop.getLoopPref("contextInConversations.enabled")
|
||||
});
|
||||
var thumbnail = this.state.previewImage || "loop/shared/img/icons-16x16.svg#globe";
|
||||
|
||||
return (
|
||||
React.createElement("div", {className: "new-room-view"},
|
||||
@ -773,7 +773,7 @@ loop.panel = (function(_, mozL10n) {
|
||||
React.createElement(Checkbox, {label: mozL10n.get("context_inroom_label"),
|
||||
onChange: this.onCheckboxChange}),
|
||||
React.createElement("div", {className: "context-content"},
|
||||
React.createElement("img", {className: "context-preview", src: this.state.previewImage}),
|
||||
React.createElement("img", {className: "context-preview", src: thumbnail}),
|
||||
React.createElement("span", {className: "context-description"},
|
||||
this.state.description,
|
||||
React.createElement("span", {className: "context-url"}, hostname)
|
||||
|
@ -500,9 +500,8 @@ loop.panel = (function(_, mozL10n) {
|
||||
|
||||
return (
|
||||
<div className="room-entry-context-item">
|
||||
<a href={roomUrl.location} onClick={this.handleClick}>
|
||||
<img title={roomUrl.description}
|
||||
src={roomUrl.thumbnail} />
|
||||
<a href={roomUrl.location} title={roomUrl.description} onClick={this.handleClick}>
|
||||
<img src={roomUrl.thumbnail || "loop/shared/img/icons-16x16.svg#globe"} />
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
@ -766,6 +765,7 @@ loop.panel = (function(_, mozL10n) {
|
||||
hide: !hostname ||
|
||||
!this.props.mozLoop.getLoopPref("contextInConversations.enabled")
|
||||
});
|
||||
var thumbnail = this.state.previewImage || "loop/shared/img/icons-16x16.svg#globe";
|
||||
|
||||
return (
|
||||
<div className="new-room-view">
|
||||
@ -773,7 +773,7 @@ loop.panel = (function(_, mozL10n) {
|
||||
<Checkbox label={mozL10n.get("context_inroom_label")}
|
||||
onChange={this.onCheckboxChange} />
|
||||
<div className="context-content">
|
||||
<img className="context-preview" src={this.state.previewImage}/>
|
||||
<img className="context-preview" src={thumbnail} />
|
||||
<span className="context-description">
|
||||
{this.state.description}
|
||||
<span className="context-url">{hostname}</span>
|
||||
|
@ -480,7 +480,7 @@ loop.roomViews = (function(mozL10n) {
|
||||
}
|
||||
|
||||
var url = this._getURL();
|
||||
var thumbnail = url && url.thumbnail || "";
|
||||
var thumbnail = url && url.thumbnail || "loop/shared/img/icons-16x16.svg#globe";
|
||||
var urlDescription = url && url.description || "";
|
||||
var location = url && url.location || "";
|
||||
var locationData = null;
|
||||
@ -718,7 +718,6 @@ loop.roomViews = (function(mozL10n) {
|
||||
|
||||
return (
|
||||
React.createElement("div", {className: "room-conversation-wrapper"},
|
||||
React.createElement(sharedViews.TextChatView, {dispatcher: this.props.dispatcher}),
|
||||
React.createElement(DesktopRoomInvitationView, {
|
||||
dispatcher: this.props.dispatcher,
|
||||
error: this.state.error,
|
||||
@ -761,7 +760,8 @@ loop.roomViews = (function(mozL10n) {
|
||||
savingContext: this.state.savingContext,
|
||||
mozLoop: this.props.mozLoop,
|
||||
roomData: roomData,
|
||||
show: !shouldRenderInvitationOverlay && shouldRenderContextView})
|
||||
show: !shouldRenderInvitationOverlay && shouldRenderContextView}),
|
||||
React.createElement(sharedViews.TextChatView, {dispatcher: this.props.dispatcher})
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -480,7 +480,7 @@ loop.roomViews = (function(mozL10n) {
|
||||
}
|
||||
|
||||
var url = this._getURL();
|
||||
var thumbnail = url && url.thumbnail || "";
|
||||
var thumbnail = url && url.thumbnail || "loop/shared/img/icons-16x16.svg#globe";
|
||||
var urlDescription = url && url.description || "";
|
||||
var location = url && url.location || "";
|
||||
var locationData = null;
|
||||
@ -553,7 +553,7 @@ loop.roomViews = (function(mozL10n) {
|
||||
<div className="room-context-label">{mozL10n.get("context_inroom_label")}</div>
|
||||
<div className="room-context-content"
|
||||
onClick={this.handleContextClick}>
|
||||
<img className="room-context-thumbnail" src={thumbnail}/>
|
||||
<img className="room-context-thumbnail" src={thumbnail} />
|
||||
<div className="room-context-description"
|
||||
title={urlDescription}>
|
||||
{this._truncate(urlDescription)}
|
||||
@ -718,7 +718,6 @@ loop.roomViews = (function(mozL10n) {
|
||||
|
||||
return (
|
||||
<div className="room-conversation-wrapper">
|
||||
<sharedViews.TextChatView dispatcher={this.props.dispatcher} />
|
||||
<DesktopRoomInvitationView
|
||||
dispatcher={this.props.dispatcher}
|
||||
error={this.state.error}
|
||||
@ -762,6 +761,7 @@ loop.roomViews = (function(mozL10n) {
|
||||
mozLoop={this.props.mozLoop}
|
||||
roomData={roomData}
|
||||
show={!shouldRenderInvitationOverlay && shouldRenderContextView} />
|
||||
<sharedViews.TextChatView dispatcher={this.props.dispatcher} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -651,27 +651,6 @@ html, .fx-embedded, #main,
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/**
|
||||
* The .fx-embbeded .text-chat-* styles are very temporarily whilst we work on
|
||||
* text chat (bug 1108892 and dependencies).
|
||||
*/
|
||||
.fx-embedded .text-chat-view {
|
||||
height: 60px;
|
||||
color: white;
|
||||
background-color: black;
|
||||
}
|
||||
|
||||
.fx-embedded .text-chat-entries {
|
||||
/* XXX Should use flex, this is just for the initial implementation. */
|
||||
height: calc(100% - 2em);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.fx-embedded .text-chat-box {
|
||||
width: 100%;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
/* We use 641px rather than 640, as min-width and max-width are inclusive */
|
||||
@media screen and (min-width:641px) {
|
||||
.standalone .conversation-toolbar {
|
||||
@ -681,10 +660,6 @@ html, .fx-embedded, #main,
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.fx-embedded .local-stream {
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
.standalone .local-stream,
|
||||
.standalone .remote-inset-stream {
|
||||
position: absolute;
|
||||
@ -697,7 +672,7 @@ html, .fx-embedded, #main,
|
||||
}
|
||||
|
||||
/* Nested video elements */
|
||||
.conversation .media.nested {
|
||||
.standalone .conversation .media.nested {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
}
|
||||
@ -744,7 +719,7 @@ html, .fx-embedded, #main,
|
||||
}
|
||||
|
||||
/* Nested video elements */
|
||||
.conversation .media.nested {
|
||||
.standalone .conversation .media.nested {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
@ -969,10 +944,6 @@ body[platform="win"] .share-service-dropdown.overflow > .dropdown-menu-item {
|
||||
flex: 0 1 auto;
|
||||
}
|
||||
|
||||
.room-context-thumbnail[src=""] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.room-context > .error-display-area.error {
|
||||
display: block;
|
||||
background-color: rgba(215,67,69,.8);
|
||||
@ -1211,9 +1182,8 @@ html[dir="rtl"] .room-context-btn-edit {
|
||||
|
||||
.standalone-context-url > img {
|
||||
margin: 1em auto;
|
||||
max-width: 50%;
|
||||
/* allows 20% for the description wrapper plus the margins */
|
||||
max-height: calc(80% - 2em);
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.standalone-context-url-description-wrapper {
|
||||
@ -1244,18 +1214,64 @@ html[dir="rtl"] .room-context-btn-edit {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
/* Text chat in rooms styles */
|
||||
|
||||
.fx-embedded .room-conversation-wrapper {
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
}
|
||||
|
||||
.fx-embedded .video-layout-wrapper {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
.text-chat-view {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.fx-embedded .text-chat-view {
|
||||
flex: 1 0 auto;
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
}
|
||||
|
||||
.fx-embedded .text-chat-entries {
|
||||
flex: 1 1 auto;
|
||||
max-height: 120px;
|
||||
min-height: 60px;
|
||||
padding: .7em .5em 0;
|
||||
}
|
||||
|
||||
.fx-embedded .text-chat-box {
|
||||
flex: 0 0 auto;
|
||||
max-height: 40px;
|
||||
min-height: 40px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.text-chat-entries {
|
||||
margin: auto;
|
||||
overflow: scroll;
|
||||
border: 1px solid red;
|
||||
}
|
||||
|
||||
.text-chat-entry {
|
||||
text-align: left;
|
||||
text-align: end;
|
||||
margin-bottom: 1.5em;
|
||||
}
|
||||
|
||||
.text-chat-entry > span {
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: #0095dd;
|
||||
border-radius: 10000px;
|
||||
padding: .5em 1em;
|
||||
}
|
||||
|
||||
.text-chat-entry.received {
|
||||
text-align: right;
|
||||
text-align: start;
|
||||
}
|
||||
|
||||
.text-chat-entry.received > span {
|
||||
border-color: #d8d8d8;
|
||||
}
|
||||
|
||||
.text-chat-box {
|
||||
@ -1264,6 +1280,14 @@ html[dir="rtl"] .room-context-btn-edit {
|
||||
|
||||
.text-chat-box > form > input {
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
padding: 0 .5em .5em;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
.fx-embedded .text-chat-box > form > input {
|
||||
border: 0;
|
||||
border-top: 1px solid #999;
|
||||
}
|
||||
|
||||
@media screen and (max-width:640px) {
|
||||
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 73 KiB |
@ -255,6 +255,10 @@ loop.shared.mixins = (function() {
|
||||
*/
|
||||
var DocumentVisibilityMixin = {
|
||||
_onDocumentVisibilityChanged: function(event) {
|
||||
if (!this.isMounted()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var hidden = event.target.hidden;
|
||||
if (hidden && typeof this.onDocumentHidden === "function") {
|
||||
this.onDocumentHidden();
|
||||
@ -267,6 +271,9 @@ loop.shared.mixins = (function() {
|
||||
componentDidMount: function() {
|
||||
rootObject.document.addEventListener(
|
||||
"visibilitychange", this._onDocumentVisibilityChanged);
|
||||
// Assume that the consumer components is only mounted when the document
|
||||
// has become visible.
|
||||
this._onDocumentVisibilityChanged({ target: rootObject.document });
|
||||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
|
@ -68,6 +68,27 @@ loop.store.TextChatStore = (function() {
|
||||
*/
|
||||
dataChannelsAvailable: function() {
|
||||
this.setStoreState({ textChatEnabled: true });
|
||||
window.dispatchEvent(new CustomEvent("LoopChatEnabled"));
|
||||
},
|
||||
|
||||
/**
|
||||
* Appends a message to the store, which may be of type 'sent' or 'received'.
|
||||
*
|
||||
* @param {String} type
|
||||
* @param {sharedActions.ReceivedTextChatMessage|sharedActions.SendTextChatMessage} actionData
|
||||
*/
|
||||
_appendTextChatMessage: function(type, actionData) {
|
||||
// We create a new list to avoid updating the store's state directly,
|
||||
// which confuses the views.
|
||||
var message = {
|
||||
type: type,
|
||||
contentType: actionData.contentType,
|
||||
message: actionData.message
|
||||
};
|
||||
var newList = this._storeState.messageList.concat(message);
|
||||
this.setStoreState({ messageList: newList });
|
||||
|
||||
window.dispatchEvent(new CustomEvent("LoopChatMessageAppended"));
|
||||
},
|
||||
|
||||
/**
|
||||
@ -81,14 +102,8 @@ loop.store.TextChatStore = (function() {
|
||||
if (actionData.contentType != CHAT_CONTENT_TYPES.TEXT) {
|
||||
return;
|
||||
}
|
||||
// We create a new list to avoid updating the store's state directly,
|
||||
// which confuses the views.
|
||||
var newList = this._storeState.messageList.concat({
|
||||
type: CHAT_MESSAGE_TYPES.RECEIVED,
|
||||
contentType: actionData.contentType,
|
||||
message: actionData.message
|
||||
});
|
||||
this.setStoreState({ messageList: newList });
|
||||
|
||||
this._appendTextChatMessage(CHAT_MESSAGE_TYPES.RECEIVED, actionData);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -97,15 +112,8 @@ loop.store.TextChatStore = (function() {
|
||||
* @param {sharedActions.SendTextChatMessage} actionData
|
||||
*/
|
||||
sendTextChatMessage: function(actionData) {
|
||||
// We create a new list to avoid updating the store's state directly,
|
||||
// which confuses the views.
|
||||
var newList = this._storeState.messageList.concat({
|
||||
type: CHAT_MESSAGE_TYPES.SENT,
|
||||
contentType: actionData.contentType,
|
||||
message: actionData.message
|
||||
});
|
||||
this._appendTextChatMessage(CHAT_MESSAGE_TYPES.SENT, actionData);
|
||||
this._sdkDriver.sendTextChatMessage(actionData);
|
||||
this.setStoreState({ messageList: newList });
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -29,7 +29,7 @@ loop.shared.views.TextChatView = (function(mozl10n) {
|
||||
|
||||
return (
|
||||
React.createElement("div", {className: classes},
|
||||
this.props.message
|
||||
React.createElement("span", null, this.props.message)
|
||||
)
|
||||
);
|
||||
}
|
||||
@ -49,6 +49,9 @@ loop.shared.views.TextChatView = (function(mozl10n) {
|
||||
|
||||
componentWillUpdate: function() {
|
||||
var node = this.getDOMNode();
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
// Scroll only if we're right at the bottom of the display.
|
||||
this.shouldScroll = node.scrollHeight === node.scrollTop + node.clientHeight;
|
||||
},
|
||||
@ -64,17 +67,23 @@ loop.shared.views.TextChatView = (function(mozl10n) {
|
||||
},
|
||||
|
||||
render: function() {
|
||||
if (!this.props.messageList.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
React.createElement("div", {className: "text-chat-entries"},
|
||||
|
||||
this.props.messageList.map(function(entry, i) {
|
||||
return (
|
||||
React.createElement(TextChatEntry, {key: i,
|
||||
message: entry.message,
|
||||
type: entry.type})
|
||||
);
|
||||
}, this)
|
||||
|
||||
React.createElement("div", {className: "text-chat-scroller"},
|
||||
|
||||
this.props.messageList.map(function(entry, i) {
|
||||
return (
|
||||
React.createElement(TextChatEntry, {key: i,
|
||||
message: entry.message,
|
||||
type: entry.type})
|
||||
);
|
||||
}, this)
|
||||
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
@ -134,12 +143,15 @@ loop.shared.views.TextChatView = (function(mozl10n) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var messageList = this.state.messageList;
|
||||
|
||||
return (
|
||||
React.createElement("div", {className: "text-chat-view"},
|
||||
React.createElement(TextChatEntriesView, {messageList: this.state.messageList}),
|
||||
React.createElement(TextChatEntriesView, {messageList: messageList}),
|
||||
React.createElement("div", {className: "text-chat-box"},
|
||||
React.createElement("form", {onSubmit: this.handleFormSubmit},
|
||||
React.createElement("input", {type: "text",
|
||||
placeholder: messageList.length ? "" : mozl10n.get("chat_textbox_placeholder"),
|
||||
onKeyDown: this.handleKeyDown,
|
||||
valueLink: this.linkState("messageDetail")})
|
||||
)
|
||||
|
@ -29,7 +29,7 @@ loop.shared.views.TextChatView = (function(mozl10n) {
|
||||
|
||||
return (
|
||||
<div className={classes}>
|
||||
{this.props.message}
|
||||
<span>{this.props.message}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -49,6 +49,9 @@ loop.shared.views.TextChatView = (function(mozl10n) {
|
||||
|
||||
componentWillUpdate: function() {
|
||||
var node = this.getDOMNode();
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
// Scroll only if we're right at the bottom of the display.
|
||||
this.shouldScroll = node.scrollHeight === node.scrollTop + node.clientHeight;
|
||||
},
|
||||
@ -64,17 +67,23 @@ loop.shared.views.TextChatView = (function(mozl10n) {
|
||||
},
|
||||
|
||||
render: function() {
|
||||
if (!this.props.messageList.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="text-chat-entries">
|
||||
{
|
||||
this.props.messageList.map(function(entry, i) {
|
||||
return (
|
||||
<TextChatEntry key={i}
|
||||
message={entry.message}
|
||||
type={entry.type} />
|
||||
);
|
||||
}, this)
|
||||
}
|
||||
<div className="text-chat-scroller">
|
||||
{
|
||||
this.props.messageList.map(function(entry, i) {
|
||||
return (
|
||||
<TextChatEntry key={i}
|
||||
message={entry.message}
|
||||
type={entry.type} />
|
||||
);
|
||||
}, this)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -134,12 +143,15 @@ loop.shared.views.TextChatView = (function(mozl10n) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var messageList = this.state.messageList;
|
||||
|
||||
return (
|
||||
<div className="text-chat-view">
|
||||
<TextChatEntriesView messageList={this.state.messageList} />
|
||||
<TextChatEntriesView messageList={messageList} />
|
||||
<div className="text-chat-box">
|
||||
<form onSubmit={this.handleFormSubmit}>
|
||||
<input type="text"
|
||||
placeholder={messageList.length ? "" : mozl10n.get("chat_textbox_placeholder")}
|
||||
onKeyDown={this.handleKeyDown}
|
||||
valueLink={this.linkState("messageDetail")} />
|
||||
</form>
|
||||
|
@ -853,27 +853,51 @@ let MozLoopServiceInternal = {
|
||||
return;
|
||||
}
|
||||
|
||||
chatbox.setAttribute("dark", true);
|
||||
chatbox.setAttribute("large", true);
|
||||
|
||||
chatbox.addEventListener("DOMContentLoaded", function loaded(event) {
|
||||
if (event.target != chatbox.contentDocument) {
|
||||
return;
|
||||
}
|
||||
chatbox.removeEventListener("DOMContentLoaded", loaded, true);
|
||||
|
||||
let chatbar = chatbox.parentNode;
|
||||
let window = chatbox.contentWindow;
|
||||
|
||||
function socialFrameChanged(eventName) {
|
||||
UITour.availableTargetsCache.clear();
|
||||
UITour.notify(eventName);
|
||||
|
||||
if (eventName == "Loop:ChatWindowDetached" || eventName == "Loop:ChatWindowAttached") {
|
||||
// After detach, re-attach of the chatbox, refresh its reference so
|
||||
// we can keep using it here.
|
||||
let ref = chatbar.chatboxForURL.get(chatbox.src);
|
||||
chatbox = ref && ref.get() || chatbox;
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener("socialFrameHide", socialFrameChanged.bind(null, "Loop:ChatWindowHidden"));
|
||||
window.addEventListener("socialFrameShow", socialFrameChanged.bind(null, "Loop:ChatWindowShown"));
|
||||
window.addEventListener("socialFrameDetached", socialFrameChanged.bind(null, "Loop:ChatWindowDetached"));
|
||||
window.addEventListener("socialFrameAttached", socialFrameChanged.bind(null, "Loop:ChatWindowAttached"));
|
||||
window.addEventListener("unload", socialFrameChanged.bind(null, "Loop:ChatWindowClosed"));
|
||||
|
||||
const kSizeMap = {
|
||||
LoopChatEnabled: "loopChatEnabled",
|
||||
LoopChatMessageAppended: "loopChatMessageAppended"
|
||||
};
|
||||
|
||||
function onChatEvent(event) {
|
||||
// When the chat box or messages are shown, resize the panel or window
|
||||
// to be slightly higher to accomodate them.
|
||||
let customSize = kSizeMap[event.type];
|
||||
if (customSize) {
|
||||
chatbox.setAttribute("customSize", customSize);
|
||||
chatbox.parentNode.setAttribute("customSize", customSize);
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener("LoopChatEnabled", onChatEvent);
|
||||
window.addEventListener("LoopChatMessageAppended", onChatEvent);
|
||||
|
||||
injectLoopAPI(window);
|
||||
|
||||
let ourID = window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
@ -918,8 +942,16 @@ let MozLoopServiceInternal = {
|
||||
}.bind(this), true);
|
||||
};
|
||||
|
||||
if (!Chat.open(null, origin, "", url, undefined, undefined, callback)) {
|
||||
let chatbox = Chat.open(null, origin, "", url, undefined, undefined, callback);
|
||||
if (!chatbox) {
|
||||
return null;
|
||||
// It's common for unit tests to overload Chat.open.
|
||||
} else if (chatbox.setAttribute) {
|
||||
// Set properties that influence visual appeara nce of the chatbox right
|
||||
// away to circumvent glitches.
|
||||
chatbox.setAttribute("dark", true);
|
||||
chatbox.setAttribute("customSize", "loopDefault");
|
||||
chatbox.parentNode.setAttribute("customSize", "loopDefault");
|
||||
}
|
||||
return windowId;
|
||||
},
|
||||
|
@ -262,7 +262,7 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
||||
|
||||
return (
|
||||
React.createElement("div", {className: classes},
|
||||
React.createElement("img", {src: this.props.roomContextUrl.thumbnail}),
|
||||
React.createElement("img", {src: this.props.roomContextUrl.thumbnail || "shared/img/icons-16x16.svg#globe"}),
|
||||
React.createElement("div", {className: "standalone-context-url-description-wrapper"},
|
||||
this.props.roomContextUrl.description,
|
||||
React.createElement("br", null), React.createElement("a", {href: locationInfo.location,
|
||||
|
@ -262,7 +262,7 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
||||
|
||||
return (
|
||||
<div className={classes}>
|
||||
<img src={this.props.roomContextUrl.thumbnail} />
|
||||
<img src={this.props.roomContextUrl.thumbnail || "shared/img/icons-16x16.svg#globe"} />
|
||||
<div className="standalone-context-url-description-wrapper">
|
||||
{this.props.roomContextUrl.description}
|
||||
<br /><a href={locationInfo.location}
|
||||
|
@ -137,3 +137,7 @@ status_in_conversation=In conversation
|
||||
status_conversation_ended=Conversation ended
|
||||
status_error=Something went wrong
|
||||
support_link=Get Help
|
||||
|
||||
# Text chat strings
|
||||
|
||||
chat_textbox_placeholder=Type here…
|
||||
|
@ -850,6 +850,24 @@ describe("loop.panel", function() {
|
||||
expect(contextContent).to.not.equal(null);
|
||||
});
|
||||
|
||||
it("should show a default favicon when none is available", function() {
|
||||
fakeMozLoop.getSelectedTabMetadata = function (callback) {
|
||||
callback({
|
||||
url: "https://www.example.com",
|
||||
description: "fake description",
|
||||
previews: [""]
|
||||
});
|
||||
};
|
||||
|
||||
var view = createTestComponent();
|
||||
|
||||
// Simulate being visible
|
||||
view.onDocumentVisible();
|
||||
|
||||
var previewImage = view.getDOMNode().querySelector(".context-preview");
|
||||
expect(previewImage.src).to.match(/loop\/shared\/img\/icons-16x16.svg#globe$/);
|
||||
});
|
||||
|
||||
it("should not show context information when a URL is unavailable", function() {
|
||||
fakeMozLoop.getSelectedTabMetadata = function (callback) {
|
||||
callback({
|
||||
|
@ -305,6 +305,19 @@ describe("loop.roomViews", function () {
|
||||
expect(view.getDOMNode().querySelector(".room-context-url").textContent)
|
||||
.eql("hostname");
|
||||
});
|
||||
|
||||
it("should show a default favicon when none is available", function() {
|
||||
fakeContextURL.thumbnail = null;
|
||||
view = mountTestComponent({
|
||||
showContext: true,
|
||||
roomData: {
|
||||
roomContextUrls: [fakeContextURL]
|
||||
}
|
||||
});
|
||||
|
||||
expect(view.getDOMNode().querySelector(".room-context-thumbnail").src)
|
||||
.to.match(/loop\/shared\/img\/icons-16x16.svg#globe$/);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -28,10 +28,22 @@ add_task(function* test_mozLoop_getSelectedTabMetadata() {
|
||||
metadata = yield promiseGetMetadata();
|
||||
|
||||
Assert.strictEqual(metadata.url, null, "URL should be empty for about:home");
|
||||
Assert.ok(metadata.favicon.startsWith("data:image/x-icon;base64,"),
|
||||
"Favicon should be set for about:home");
|
||||
Assert.strictEqual(metadata.favicon, null, "Favicon should be empty for about:home");
|
||||
Assert.ok(metadata.title, "Title should be set for about:home");
|
||||
Assert.deepEqual(metadata.previews, [], "No previews available for about:home");
|
||||
|
||||
gBrowser.removeTab(tab);
|
||||
});
|
||||
|
||||
add_task(function* test_mozLoop_getSelectedTabMetadata_defaultIcon() {
|
||||
let tab = gBrowser.selectedTab = gBrowser.addTab();
|
||||
yield promiseTabLoadEvent(tab, "http://example.com/");
|
||||
let metadata = yield promiseGetMetadata();
|
||||
|
||||
Assert.strictEqual(metadata.url, "http://example.com/", "URL should match");
|
||||
Assert.strictEqual(metadata.favicon, null, "Favicon should be empty");
|
||||
Assert.ok(metadata.title, "Title should be set");
|
||||
Assert.deepEqual(metadata.previews, [], "No previews available");
|
||||
|
||||
gBrowser.removeTab(tab);
|
||||
});
|
||||
|
@ -177,7 +177,8 @@ describe("loop.shared.mixins", function() {
|
||||
|
||||
comp = TestUtils.renderIntoDocument(React.createElement(TestComp));
|
||||
|
||||
sinon.assert.calledOnce(onDocumentVisibleStub);
|
||||
// Twice, because it's also called when the component was mounted.
|
||||
sinon.assert.calledTwice(onDocumentVisibleStub);
|
||||
});
|
||||
|
||||
it("should call onDocumentVisible when document visibility changes to hidden",
|
||||
|
@ -25,6 +25,11 @@ describe("loop.store.TextChatStore", function () {
|
||||
store = new loop.store.TextChatStore(dispatcher, {
|
||||
sdkDriver: fakeSdkDriver
|
||||
});
|
||||
|
||||
sandbox.stub(window, "dispatchEvent");
|
||||
sandbox.stub(window, "CustomEvent", function(name) {
|
||||
this.name = name;
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
@ -37,6 +42,14 @@ describe("loop.store.TextChatStore", function () {
|
||||
|
||||
expect(store.getStoreState("textChatEnabled")).eql(true);
|
||||
});
|
||||
|
||||
it("should dispatch a LoopChatEnabled event", function() {
|
||||
store.dataChannelsAvailable();
|
||||
|
||||
sinon.assert.calledOnce(window.dispatchEvent);
|
||||
sinon.assert.calledWithExactly(window.dispatchEvent,
|
||||
new CustomEvent("LoopChatEnabled"));
|
||||
});
|
||||
});
|
||||
|
||||
describe("#receivedTextChatMessage", function() {
|
||||
@ -63,6 +76,17 @@ describe("loop.store.TextChatStore", function () {
|
||||
|
||||
expect(store.getStoreState("messageList").length).eql(0);
|
||||
});
|
||||
|
||||
it("should dispatch a LoopChatMessageAppended event", function() {
|
||||
store.receivedTextChatMessage({
|
||||
contentType: CHAT_CONTENT_TYPES.TEXT,
|
||||
message: "Hello!"
|
||||
});
|
||||
|
||||
sinon.assert.calledOnce(window.dispatchEvent);
|
||||
sinon.assert.calledWithExactly(window.dispatchEvent,
|
||||
new CustomEvent("LoopChatMessageAppended"));
|
||||
});
|
||||
});
|
||||
|
||||
describe("#sendTextChatMessage", function() {
|
||||
@ -92,5 +116,16 @@ describe("loop.store.TextChatStore", function () {
|
||||
message: messageData.message
|
||||
}]);
|
||||
});
|
||||
|
||||
it("should dipatch a LoopChatMessageAppended event", function() {
|
||||
store.sendTextChatMessage({
|
||||
contentType: CHAT_CONTENT_TYPES.TEXT,
|
||||
message: "Hello!"
|
||||
});
|
||||
|
||||
sinon.assert.calledOnce(window.dispatchEvent);
|
||||
sinon.assert.calledWithExactly(window.dispatchEvent,
|
||||
new CustomEvent("LoopChatMessageAppended"));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -80,5 +80,32 @@ describe("loop.shared.views.TextChatView", function () {
|
||||
message: "Hello!"
|
||||
}));
|
||||
});
|
||||
|
||||
it("should not render message entries when none are sent/ received yet", function() {
|
||||
view = mountTestComponent();
|
||||
|
||||
expect(view.getDOMNode().querySelector(".text-chat-entries")).to.eql(null);
|
||||
});
|
||||
|
||||
it("should render message entries when message were sent/ received", function() {
|
||||
view = mountTestComponent();
|
||||
|
||||
store.receivedTextChatMessage({
|
||||
contentType: CHAT_CONTENT_TYPES.TEXT,
|
||||
message: "Hello!"
|
||||
});
|
||||
store.sendTextChatMessage({
|
||||
contentType: CHAT_CONTENT_TYPES.TEXT,
|
||||
message: "Is it me you're looking for?"
|
||||
});
|
||||
|
||||
var node = view.getDOMNode();
|
||||
expect(node.querySelector(".text-chat-entries")).to.not.eql(null);
|
||||
|
||||
var entries = node.querySelectorAll(".text-chat-entry");
|
||||
expect(entries.length).to.eql(2);
|
||||
expect(entries[0].classList.contains("received")).to.eql(true);
|
||||
expect(entries[1].classList.contains("received")).to.not.eql(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -149,6 +149,20 @@ describe("loop.standaloneRoomViews", function() {
|
||||
linkInfo: "Shared URL"
|
||||
}));
|
||||
});
|
||||
|
||||
it("should display the default favicon when no thumbnail is available", function() {
|
||||
var view = mountTestComponent({
|
||||
roomName: "Mike's room",
|
||||
roomContextUrls: [{
|
||||
description: "Mark's super page",
|
||||
location: "http://invalid.com",
|
||||
thumbnail: ""
|
||||
}]
|
||||
});
|
||||
|
||||
expect(view.getDOMNode().querySelector(".standalone-context-url > img").src)
|
||||
.to.match(/shared\/img\/icons-16x16.svg#globe$/);
|
||||
});
|
||||
});
|
||||
|
||||
describe("StandaloneRoomHeader", function() {
|
||||
|
@ -148,10 +148,6 @@ body {
|
||||
|
||||
.svg-icon {
|
||||
display: inline-block;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-left: .5rem;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 16px 16px;
|
||||
background-position: center;
|
||||
border: 0;
|
||||
}
|
||||
|
@ -300,13 +300,12 @@
|
||||
|
||||
var SVGIcon = React.createClass({displayName: "SVGIcon",
|
||||
render: function() {
|
||||
var sizeUnit = this.props.size.split("x")[0] + "px";
|
||||
var sizeUnit = this.props.size.split("x");
|
||||
return (
|
||||
React.createElement("span", {className: "svg-icon", style: {
|
||||
"backgroundImage": "url(../content/shared/img/icons-" + this.props.size +
|
||||
".svg#" + this.props.shapeId + ")",
|
||||
"backgroundSize": sizeUnit + " " + sizeUnit
|
||||
}})
|
||||
React.createElement("img", {className: "svg-icon",
|
||||
src: "../content/shared/img/icons-" + this.props.size + ".svg#" + this.props.shapeId,
|
||||
width: sizeUnit[0],
|
||||
height: sizeUnit[1]})
|
||||
);
|
||||
}
|
||||
});
|
||||
@ -328,7 +327,7 @@
|
||||
],
|
||||
"16x16": ["add", "add-hover", "add-active", "audio", "audio-hover", "audio-active",
|
||||
"block", "block-red", "block-hover", "block-active", "contacts", "contacts-hover",
|
||||
"contacts-active", "copy", "checkmark", "delete", "google", "google-hover",
|
||||
"contacts-active", "copy", "checkmark", "delete", "globe", "google", "google-hover",
|
||||
"google-active", "history", "history-hover", "history-active", "leave",
|
||||
"precall", "precall-hover", "precall-active", "screen-white", "screenmute-white",
|
||||
"settings", "settings-hover", "settings-active", "share-darkgrey", "tag",
|
||||
|
@ -300,13 +300,12 @@
|
||||
|
||||
var SVGIcon = React.createClass({
|
||||
render: function() {
|
||||
var sizeUnit = this.props.size.split("x")[0] + "px";
|
||||
var sizeUnit = this.props.size.split("x");
|
||||
return (
|
||||
<span className="svg-icon" style={{
|
||||
"backgroundImage": "url(../content/shared/img/icons-" + this.props.size +
|
||||
".svg#" + this.props.shapeId + ")",
|
||||
"backgroundSize": sizeUnit + " " + sizeUnit
|
||||
}} />
|
||||
<img className="svg-icon"
|
||||
src={"../content/shared/img/icons-" + this.props.size + ".svg#" + this.props.shapeId}
|
||||
width={sizeUnit[0]}
|
||||
height={sizeUnit[1]} />
|
||||
);
|
||||
}
|
||||
});
|
||||
@ -328,7 +327,7 @@
|
||||
],
|
||||
"16x16": ["add", "add-hover", "add-active", "audio", "audio-hover", "audio-active",
|
||||
"block", "block-red", "block-hover", "block-active", "contacts", "contacts-hover",
|
||||
"contacts-active", "copy", "checkmark", "delete", "google", "google-hover",
|
||||
"contacts-active", "copy", "checkmark", "delete", "globe", "google", "google-hover",
|
||||
"google-active", "history", "history-hover", "history-active", "leave",
|
||||
"precall", "precall-hover", "precall-active", "screen-white", "screenmute-white",
|
||||
"settings", "settings-hover", "settings-active", "share-darkgrey", "tag",
|
||||
|
@ -193,6 +193,10 @@ let NetMonitorView = {
|
||||
* @return string (e.g, "network-inspector-view" or "network-statistics-view")
|
||||
*/
|
||||
get currentFrontendMode() {
|
||||
// The getter may be called from a timeout after the panel is destroyed.
|
||||
if (!this._body.selectedPanel) {
|
||||
return null;
|
||||
}
|
||||
return this._body.selectedPanel.id;
|
||||
},
|
||||
|
||||
|
@ -21,6 +21,7 @@ support-files =
|
||||
html_post-raw-test-page.html
|
||||
html_post-raw-with-headers-test-page.html
|
||||
html_simple-test-page.html
|
||||
html_send-beacon.html
|
||||
html_sorting-test-page.html
|
||||
html_statistics-test-page.html
|
||||
html_status-codes-test-page.html
|
||||
@ -99,6 +100,8 @@ skip-if = e10s # Bug 1091612
|
||||
[browser_net_security-tab-deselect.js]
|
||||
[browser_net_security-tab-visibility.js]
|
||||
[browser_net_security-warnings.js]
|
||||
[browser_net_send-beacon.js]
|
||||
[browser_net_send-beacon-other-tab.js]
|
||||
[browser_net_simple-init.js]
|
||||
[browser_net_simple-request-data.js]
|
||||
[browser_net_simple-request-details.js]
|
||||
|
@ -0,0 +1,31 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests if beacons from other tabs are properly ignored.
|
||||
*/
|
||||
|
||||
let test = Task.async(function*() {
|
||||
let [, debuggee, monitor] = yield initNetMonitor(SIMPLE_URL);
|
||||
let { RequestsMenu } = monitor.panelWin.NetMonitorView;
|
||||
RequestsMenu.lazyUpdate = false;
|
||||
|
||||
let tab = yield addTab(SEND_BEACON_URL);
|
||||
let beaconDebuggee = tab.linkedBrowser.contentWindow.wrappedJSObject;
|
||||
info("Beacon tab added successfully.");
|
||||
|
||||
is(RequestsMenu.itemCount, 0, "The requests menu should be empty.");
|
||||
|
||||
beaconDebuggee.performRequest();
|
||||
debuggee.location.reload();
|
||||
|
||||
yield waitForNetworkEvents(monitor, 1);
|
||||
is(RequestsMenu.itemCount, 1, "Only the reload should be recorded.");
|
||||
let request = RequestsMenu.getItemAtIndex(0);
|
||||
is(request.attachment.method, "GET", "The method is correct.");
|
||||
is(request.attachment.status, "200", "The status is correct.");
|
||||
|
||||
yield teardown(monitor);
|
||||
removeTab(tab);
|
||||
finish();
|
||||
});
|
27
browser/devtools/netmonitor/test/browser_net_send-beacon.js
Normal file
27
browser/devtools/netmonitor/test/browser_net_send-beacon.js
Normal file
@ -0,0 +1,27 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests if beacons are handled correctly.
|
||||
*/
|
||||
|
||||
let test = Task.async(function*() {
|
||||
let [, debuggee, monitor] = yield initNetMonitor(SEND_BEACON_URL);
|
||||
let { RequestsMenu } = monitor.panelWin.NetMonitorView;
|
||||
|
||||
RequestsMenu.lazyUpdate = false;
|
||||
|
||||
is(RequestsMenu.itemCount, 0, "The requests menu should be empty.");
|
||||
|
||||
debuggee.performRequest();
|
||||
|
||||
yield waitForNetworkEvents(monitor, 1);
|
||||
is(RequestsMenu.itemCount, 1, "The beacon should be recorded.");
|
||||
let request = RequestsMenu.getItemAtIndex(0);
|
||||
is(request.attachment.method, "POST", "The method is correct.");
|
||||
ok(request.attachment.url.endsWith("beacon_request"), "The URL is correct.");
|
||||
is(request.attachment.status, "404", "The status is correct.");
|
||||
|
||||
yield teardown(monitor);
|
||||
finish();
|
||||
});
|
@ -40,6 +40,7 @@ const SINGLE_GET_URL = EXAMPLE_URL + "html_single-get-page.html";
|
||||
const STATISTICS_URL = EXAMPLE_URL + "html_statistics-test-page.html";
|
||||
const CURL_URL = EXAMPLE_URL + "html_copy-as-curl.html";
|
||||
const CURL_UTILS_URL = EXAMPLE_URL + "html_curl-utils.html";
|
||||
const SEND_BEACON_URL = EXAMPLE_URL + "html_send-beacon.html";
|
||||
|
||||
const SIMPLE_SJS = EXAMPLE_URL + "sjs_simple-test-server.sjs";
|
||||
const CONTENT_TYPE_SJS = EXAMPLE_URL + "sjs_content-type-test-server.sjs";
|
||||
|
23
browser/devtools/netmonitor/test/html_send-beacon.html
Normal file
23
browser/devtools/netmonitor/test/html_send-beacon.html
Normal file
@ -0,0 +1,23 @@
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<!doctype html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
|
||||
<meta http-equiv="Pragma" content="no-cache" />
|
||||
<meta http-equiv="Expires" content="0" />
|
||||
<title>Network Monitor test page</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p>Send beacon test</p>
|
||||
|
||||
<script type="text/javascript">
|
||||
function performRequest() {
|
||||
navigator.sendBeacon("beacon_request");
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -116,6 +116,7 @@ support-files =
|
||||
[browser_perf_recordings-io-02.js]
|
||||
[browser_perf_recordings-io-03.js]
|
||||
[browser_perf_recordings-io-04.js]
|
||||
[browser_perf_recordings-io-05.js]
|
||||
[browser_perf-range-changed-render.js]
|
||||
[browser_perf-recording-selected-01.js]
|
||||
[browser_perf-recording-selected-02.js]
|
||||
|
@ -29,7 +29,6 @@ let test = Task.async(function*() {
|
||||
yield DetailsView.selectView("memory-calltree");
|
||||
yield DetailsView.selectView("memory-flamegraph");
|
||||
|
||||
|
||||
// Verify original recording.
|
||||
|
||||
let originalData = PerformanceController.getCurrentRecording().getAllData();
|
||||
@ -81,25 +80,6 @@ let test = Task.async(function*() {
|
||||
is(importedData.configuration.withMemory, originalData.configuration.withMemory,
|
||||
"The imported data is identical to the original data (9).");
|
||||
|
||||
yield teardown(panel);
|
||||
|
||||
// Test that when importing and no graphs rendered yet,
|
||||
// we do not get a getMappedSelection error
|
||||
// bug 1160828
|
||||
var { target, panel, toolbox } = yield initPerformance(SIMPLE_URL);
|
||||
var { EVENTS, PerformanceController, DetailsView, DetailsSubview, OverviewView, WaterfallView } = panel.panelWin;
|
||||
yield PerformanceController.clearRecordings();
|
||||
|
||||
rerendered = once(WaterfallView, EVENTS.WATERFALL_RENDERED);
|
||||
imported = once(PerformanceController, EVENTS.RECORDING_IMPORTED);
|
||||
yield PerformanceController.importRecording("", file);
|
||||
|
||||
yield imported;
|
||||
ok(true, "The recording data appears to have been successfully imported.");
|
||||
|
||||
yield rerendered;
|
||||
ok(true, "The imported data was re-rendered.");
|
||||
|
||||
yield teardown(panel);
|
||||
finish();
|
||||
});
|
||||
|
@ -0,0 +1,41 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test that when importing and no graphs rendered yet, we do not get a
|
||||
* `getMappedSelection` error.
|
||||
*/
|
||||
|
||||
let test = Task.async(function*() {
|
||||
var { target, panel, toolbox } = yield initPerformance(SIMPLE_URL);
|
||||
var { EVENTS, PerformanceController, WaterfallView } = panel.panelWin;
|
||||
|
||||
yield startRecording(panel);
|
||||
yield stopRecording(panel);
|
||||
|
||||
// Save recording.
|
||||
|
||||
let file = FileUtils.getFile("TmpD", ["tmpprofile.json"]);
|
||||
file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, parseInt("666", 8));
|
||||
|
||||
let exported = once(PerformanceController, EVENTS.RECORDING_EXPORTED);
|
||||
yield PerformanceController.exportRecording("", PerformanceController.getCurrentRecording(), file);
|
||||
|
||||
yield exported;
|
||||
ok(true, "The recording data appears to have been successfully saved.");
|
||||
|
||||
// Clear and re-import.
|
||||
|
||||
yield PerformanceController.clearRecordings();
|
||||
|
||||
let rendered = once(WaterfallView, EVENTS.WATERFALL_RENDERED);
|
||||
let imported = once(PerformanceController, EVENTS.RECORDING_IMPORTED);
|
||||
yield PerformanceController.importRecording("", file);
|
||||
yield imported;
|
||||
yield rendered;
|
||||
|
||||
ok(true, "No error was thrown.");
|
||||
|
||||
yield teardown(panel);
|
||||
finish();
|
||||
});
|
@ -65,10 +65,8 @@ function* spawnTest() {
|
||||
is(afterResizeBarsCount, beforeResizeBarsCount,
|
||||
"The same subset of the total markers remained visible.");
|
||||
|
||||
// Temporarily disable the following assertion; intermittent failures.
|
||||
// Bug 1169352.
|
||||
// is(Array.indexOf($$(".waterfall-tree-item"), $(".waterfall-tree-item:focus")), 2,
|
||||
// "The correct item is still focused in the tree.");
|
||||
is(Array.indexOf($$(".waterfall-tree-item"), $(".waterfall-tree-item:focus")), 2,
|
||||
"The correct item is still focused in the tree.");
|
||||
ok(!$("#waterfall-details").hidden,
|
||||
"The waterfall sidebar is still visible.");
|
||||
|
||||
|
@ -11,6 +11,7 @@ skip-if = buildapp == 'mulet'
|
||||
[browser_projecteditor_confirm_unsaved.js]
|
||||
[browser_projecteditor_contextmenu_01.js]
|
||||
[browser_projecteditor_contextmenu_02.js]
|
||||
skip-if = true # Bug 1173950
|
||||
[browser_projecteditor_delete_file.js]
|
||||
skip-if = e10s # Frequent failures in e10s - Bug 1020027
|
||||
[browser_projecteditor_rename_file.js]
|
||||
@ -23,6 +24,7 @@ skip-if = buildapp == 'mulet'
|
||||
[browser_projecteditor_init.js]
|
||||
[browser_projecteditor_menubar_01.js]
|
||||
[browser_projecteditor_menubar_02.js]
|
||||
skip-if = true # Bug 1173950
|
||||
[browser_projecteditor_new_file.js]
|
||||
[browser_projecteditor_stores.js]
|
||||
[browser_projecteditor_tree_selection_01.js]
|
||||
|
@ -63,10 +63,10 @@ share_email_subject5={{clientShortname2}} — Join the conversation
|
||||
share_email_subject_context={{clientShortname2}} conversation: {{title}}
|
||||
## LOCALIZATION NOTE (share_email_body4): In this item, don't translate the
|
||||
## part between {{..}} and leave the \n\n part alone
|
||||
share_email_body5=Hello!\n\nJoin me for a video conversation on {{clientShortname2}}.\n\nIt's the easiest way to connect by video with anyone anywhere. With {{clientSuperShortname}}, you don't have to download or install anything. Just click or paste this link into your {{brandShortname}}, Opera, or Chrome browser to join the conversation:\n\n{{callUrl}}\n\nIf you'd like to learn more about {{clientSuperShortname}} and how you can start your own free video conversations, visit {{learnMoreUrl}}\n\nTalk to you soon!
|
||||
share_email_body5=Hello!\n\nJoin me for a video conversation on {{clientShortname2}}.\n\nIt's the easiest way to connect by video with anyone anywhere. With {{clientSuperShortname}}, you don't have to download or install anything. Just click or paste this link into your {{brandShortname}}, Opera or Chrome browser to join the conversation:\n\n{{callUrl}}\n\nIf you'd like to learn more about {{clientSuperShortname}} and how you can start your own free video conversations, visit {{learnMoreUrl}}\n\nTalk to you soon!
|
||||
## LOCALIZATION NOTE (share_email_body_context): In this item, don't translate
|
||||
## the part between {{..}} and leave the \n\n part alone.
|
||||
share_email_body_context=Hello!\n\nJoin me for a video conversation on {{clientShortname2}} about:\n{{title}}.\n\nIt's the easiest way to connect by video with anyone anywhere. With {{clientSuperShortname}}, you don't have to download or install anything. Just click or paste this link into your {{brandShortname}}, Opera, or Chrome browser to join the conversation:\n\n{{callUrl}}\n\nIf you'd like to learn more about {{clientSuperShortname}} and how you can start your own free video conversations, visit {{learnMoreUrl}}\n\nTalk to you soon!
|
||||
share_email_body_context=Hello!\n\nJoin me for a video conversation on {{clientShortname2}} about:\n{{title}}.\n\nIt's the easiest way to connect by video with anyone anywhere. With {{clientSuperShortname}}, you don't have to download or install anything. Just click or paste this link into your {{brandShortname}}, Opera or Chrome browser to join the conversation:\n\n{{callUrl}}\n\nIf you'd like to learn more about {{clientSuperShortname}} and how you can start your own free video conversations, visit {{learnMoreUrl}}\n\nTalk to you soon!
|
||||
## LOCALIZATION NOTE (share_tweeet): In this item, don't translate the part
|
||||
## between {{..}}. Please keep the text below 117 characters to make sure it fits
|
||||
## in a tweet.
|
||||
@ -354,3 +354,7 @@ context_show_tooltip=Show Context
|
||||
context_save_label2=Save
|
||||
context_link_modified=This link was modified.
|
||||
context_learn_more_link_label=Learn more.
|
||||
|
||||
# Text chat strings
|
||||
|
||||
chat_textbox_placeholder=Type here…
|
||||
|
@ -195,7 +195,6 @@ chatbox[dark=true] > .chat-titlebar > hbox > .chat-title {
|
||||
|
||||
.chatbar-innerbox {
|
||||
background: transparent;
|
||||
margin: -285px 0 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
@ -1075,7 +1075,7 @@ toolbarbutton[constrain-size="true"][cui-areatype="toolbar"] > .toolbarbutton-ba
|
||||
list-style-image: url(chrome://browser/skin/undoCloseTab.png);
|
||||
}
|
||||
|
||||
@media (min-resolution: 1.25dppx) {
|
||||
@media (min-resolution: 1.1dppx) {
|
||||
#alltabs_undoCloseTab {
|
||||
list-style-image: url(chrome://browser/skin/undoCloseTab@2x.png);
|
||||
}
|
||||
@ -1508,16 +1508,19 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
|
||||
padding: 0 3px;
|
||||
}
|
||||
|
||||
@media (-moz-os-version: windows-xp),
|
||||
@media not all and (-moz-os-version: windows-vista),
|
||||
not all and (-moz-windows-default-theme) {
|
||||
richlistitem[type~="action"][actiontype="switchtab"][selected="true"] > .ac-url-box > .ac-action-icon {
|
||||
-moz-image-region: rect(11px, 16px, 22px, 0);
|
||||
}
|
||||
@media not all and (-moz-os-version: windows-win7),
|
||||
not all and (-moz-windows-default-theme) {
|
||||
richlistitem[type~="action"][actiontype="switchtab"][selected="true"] > .ac-url-box > .ac-action-icon {
|
||||
-moz-image-region: rect(11px, 16px, 22px, 0);
|
||||
}
|
||||
|
||||
.ac-comment[selected="true"],
|
||||
.ac-url-text[selected="true"],
|
||||
.ac-action-text[selected="true"] {
|
||||
color: inherit !important;
|
||||
.ac-comment[selected="true"],
|
||||
.ac-url-text[selected="true"],
|
||||
.ac-action-text[selected="true"] {
|
||||
color: inherit !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1892,7 +1895,7 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
|
||||
|
||||
%include ../shared/tabs.inc.css
|
||||
|
||||
@media (min-resolution: 1.25dppx) {
|
||||
@media (min-resolution: 1.1dppx) {
|
||||
/* image preloading hack from shared/tabs.inc.css */
|
||||
#tabbrowser-tabs::before {
|
||||
background-image:
|
||||
@ -1934,8 +1937,17 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
|
||||
}
|
||||
}
|
||||
|
||||
#TabsToolbar[brighttext] .tab-close-button:not(:hover):not([visuallyselected="true"]) {
|
||||
-moz-image-region: rect(0, 64px, 16px, 48px) !important;
|
||||
/* Invert the unhovered close tab icons on bright-text tabs */
|
||||
@media not all and (min-resolution: 1.1dppx) {
|
||||
#TabsToolbar[brighttext] .tab-close-button:not(:hover):not([visuallyselected="true"]) {
|
||||
-moz-image-region: rect(0, 64px, 16px, 48px) !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-resolution: 1.1dppx) {
|
||||
#TabsToolbar[brighttext] .tab-close-button:not(:hover):not([visuallyselected="true"]) {
|
||||
-moz-image-region: rect(0, 128px, 32px, 96px) !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* tabbrowser-tab focus ring */
|
||||
|
@ -1642,13 +1642,15 @@ BluetoothGattManager::GetCharacteristicNotification(
|
||||
aCharId,
|
||||
new DiscoverResultHandler(client));
|
||||
} else { // all characteristics of this service are discovered
|
||||
// Notify BluetoothGattService to create characteristics then proceed
|
||||
nsString path;
|
||||
GeneratePathFromGattId(aServiceId.mId, path);
|
||||
// Notify BluetoothGatt to make BluetoothGattService create characteristics
|
||||
// then proceed
|
||||
nsTArray<BluetoothNamedValue> values;
|
||||
BT_APPEND_NAMED_VALUE(values, "serviceId", aServiceId);
|
||||
BT_APPEND_NAMED_VALUE(values, "characteristics", client->mCharacteristics);
|
||||
|
||||
bs->DistributeSignal(NS_LITERAL_STRING("CharacteristicsDiscovered"),
|
||||
path,
|
||||
BluetoothValue(client->mCharacteristics));
|
||||
client->mAppUuid,
|
||||
BluetoothValue(values));
|
||||
|
||||
ProceedDiscoverProcess(client, aServiceId);
|
||||
}
|
||||
@ -1686,13 +1688,16 @@ BluetoothGattManager::GetDescriptorNotification(
|
||||
aDescriptorId,
|
||||
new DiscoverResultHandler(client));
|
||||
} else { // all descriptors of this characteristic are discovered
|
||||
// Notify BluetoothGattCharacteristic to create descriptors then proceed
|
||||
nsString path;
|
||||
GeneratePathFromGattId(aCharId, path);
|
||||
// Notify BluetoothGatt to make BluetoothGattCharacteristic create
|
||||
// descriptors then proceed
|
||||
nsTArray<BluetoothNamedValue> values;
|
||||
BT_APPEND_NAMED_VALUE(values, "serviceId", aServiceId);
|
||||
BT_APPEND_NAMED_VALUE(values, "characteristicId", aCharId);
|
||||
BT_APPEND_NAMED_VALUE(values, "descriptors", client->mDescriptors);
|
||||
|
||||
bs->DistributeSignal(NS_LITERAL_STRING("DescriptorsDiscovered"),
|
||||
path,
|
||||
BluetoothValue(client->mDescriptors));
|
||||
client->mAppUuid,
|
||||
BluetoothValue(values));
|
||||
client->mDescriptors.Clear();
|
||||
|
||||
ProceedDiscoverProcess(client, aServiceId);
|
||||
@ -1729,13 +1734,16 @@ BluetoothGattManager::GetIncludedServiceNotification(
|
||||
aIncludedServId,
|
||||
new DiscoverResultHandler(client));
|
||||
} else { // all included services of this service are discovered
|
||||
// Notify BluetoothGattService to create included services
|
||||
nsString path;
|
||||
GeneratePathFromGattId(aServiceId.mId, path);
|
||||
// Notify BluetoothGatt to make BluetoothGattService create included
|
||||
// services
|
||||
nsTArray<BluetoothNamedValue> values;
|
||||
BT_APPEND_NAMED_VALUE(values, "serviceId", aServiceId);
|
||||
BT_APPEND_NAMED_VALUE(values, "includedServices",
|
||||
client->mIncludedServices);
|
||||
|
||||
bs->DistributeSignal(NS_LITERAL_STRING("IncludedServicesDiscovered"),
|
||||
path,
|
||||
BluetoothValue(client->mIncludedServices));
|
||||
client->mAppUuid,
|
||||
BluetoothValue(values));
|
||||
client->mIncludedServices.Clear();
|
||||
|
||||
// Start to discover characteristics of this service
|
||||
|
@ -281,6 +281,77 @@ BluetoothGatt::HandleServicesDiscovered(const BluetoothValue& aValue)
|
||||
BluetoothGattBinding::ClearCachedServicesValue(this);
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothGatt::HandleIncludedServicesDiscovered(const BluetoothValue& aValue)
|
||||
{
|
||||
MOZ_ASSERT(aValue.type() == BluetoothValue::TArrayOfBluetoothNamedValue);
|
||||
|
||||
const InfallibleTArray<BluetoothNamedValue>& values =
|
||||
aValue.get_ArrayOfBluetoothNamedValue();
|
||||
MOZ_ASSERT(values.Length() == 2); // ServiceId, IncludedServices
|
||||
MOZ_ASSERT(values[0].name().EqualsLiteral("serviceId"));
|
||||
MOZ_ASSERT(values[0].value().type() ==
|
||||
BluetoothValue::TBluetoothGattServiceId);
|
||||
MOZ_ASSERT(values[1].name().EqualsLiteral("includedServices"));
|
||||
MOZ_ASSERT(values[1].value().type() ==
|
||||
BluetoothValue::TArrayOfBluetoothGattServiceId);
|
||||
|
||||
size_t index = mServices.IndexOf(
|
||||
values[0].value().get_BluetoothGattServiceId());
|
||||
NS_ENSURE_TRUE_VOID(index != mServices.NoIndex);
|
||||
|
||||
nsRefPtr<BluetoothGattService> service = mServices.ElementAt(index);
|
||||
service->AssignIncludedServices(
|
||||
values[1].value().get_ArrayOfBluetoothGattServiceId());
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothGatt::HandleCharacteristicsDiscovered(const BluetoothValue& aValue)
|
||||
{
|
||||
MOZ_ASSERT(aValue.type() == BluetoothValue::TArrayOfBluetoothNamedValue);
|
||||
|
||||
const InfallibleTArray<BluetoothNamedValue>& values =
|
||||
aValue.get_ArrayOfBluetoothNamedValue();
|
||||
MOZ_ASSERT(values.Length() == 2); // ServiceId, Characteristics
|
||||
MOZ_ASSERT(values[0].name().EqualsLiteral("serviceId"));
|
||||
MOZ_ASSERT(values[0].value().type() == BluetoothValue::TBluetoothGattServiceId);
|
||||
MOZ_ASSERT(values[1].name().EqualsLiteral("characteristics"));
|
||||
MOZ_ASSERT(values[1].value().type() ==
|
||||
BluetoothValue::TArrayOfBluetoothGattCharAttribute);
|
||||
|
||||
size_t index = mServices.IndexOf(
|
||||
values[0].value().get_BluetoothGattServiceId());
|
||||
NS_ENSURE_TRUE_VOID(index != mServices.NoIndex);
|
||||
|
||||
nsRefPtr<BluetoothGattService> service = mServices.ElementAt(index);
|
||||
service->AssignCharacteristics(
|
||||
values[1].value().get_ArrayOfBluetoothGattCharAttribute());
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothGatt::HandleDescriptorsDiscovered(const BluetoothValue& aValue)
|
||||
{
|
||||
MOZ_ASSERT(aValue.type() == BluetoothValue::TArrayOfBluetoothNamedValue);
|
||||
|
||||
const InfallibleTArray<BluetoothNamedValue>& values =
|
||||
aValue.get_ArrayOfBluetoothNamedValue();
|
||||
MOZ_ASSERT(values.Length() == 3); // ServiceId, CharacteristicId, Descriptors
|
||||
MOZ_ASSERT(values[0].name().EqualsLiteral("serviceId"));
|
||||
MOZ_ASSERT(values[0].value().type() == BluetoothValue::TBluetoothGattServiceId);
|
||||
MOZ_ASSERT(values[1].name().EqualsLiteral("characteristicId"));
|
||||
MOZ_ASSERT(values[1].value().type() == BluetoothValue::TBluetoothGattId);
|
||||
MOZ_ASSERT(values[2].name().EqualsLiteral("descriptors"));
|
||||
MOZ_ASSERT(values[2].value().type() == BluetoothValue::TArrayOfBluetoothGattId);
|
||||
|
||||
size_t index = mServices.IndexOf(
|
||||
values[0].value().get_BluetoothGattServiceId());
|
||||
NS_ENSURE_TRUE_VOID(index != mServices.NoIndex);
|
||||
|
||||
nsRefPtr<BluetoothGattService> service = mServices.ElementAt(index);
|
||||
service->AssignDescriptors(values[1].value().get_BluetoothGattId(),
|
||||
values[2].value().get_ArrayOfBluetoothGattId());
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothGatt::HandleCharacteristicChanged(const BluetoothValue& aValue)
|
||||
{
|
||||
@ -348,6 +419,12 @@ BluetoothGatt::Notify(const BluetoothSignal& aData)
|
||||
}
|
||||
|
||||
mDiscoveringServices = false;
|
||||
} else if (aData.name().EqualsLiteral("IncludedServicesDiscovered")) {
|
||||
HandleIncludedServicesDiscovered(v);
|
||||
} else if (aData.name().EqualsLiteral("CharacteristicsDiscovered")) {
|
||||
HandleCharacteristicsDiscovered(v);
|
||||
} else if (aData.name().EqualsLiteral("DescriptorsDiscovered")) {
|
||||
HandleDescriptorsDiscovered(v);
|
||||
} else if (aData.name().EqualsLiteral(GATT_CHARACTERISTIC_CHANGED_ID)) {
|
||||
HandleCharacteristicChanged(v);
|
||||
} else {
|
||||
|
@ -96,6 +96,50 @@ private:
|
||||
*/
|
||||
void HandleServicesDiscovered(const BluetoothValue& aValue);
|
||||
|
||||
/**
|
||||
* Add newly discovered GATT included services into mIncludedServices of
|
||||
* BluetoothGattService and update the cache value of mIncludedServices.
|
||||
*
|
||||
* @param aValue [in] BluetoothValue which contains an array of
|
||||
* BluetoothNamedValue. There are exact two elements in
|
||||
* the array. The first element uses 'serviceId' as the
|
||||
* name and uses BluetoothGattServiceId as the value. The
|
||||
* second element uses 'includedServices' as the name and
|
||||
* uses an array of BluetoothGattServiceId of all
|
||||
* discovered included services as the value.
|
||||
*/
|
||||
void HandleIncludedServicesDiscovered(const BluetoothValue& aValue);
|
||||
|
||||
/**
|
||||
* Add newly discovered GATT characteristics into mCharacteristics of
|
||||
* BluetoothGattService and update the cache value of mCharacteristics.
|
||||
*
|
||||
* @param aValue [in] BluetoothValue which contains an array of
|
||||
* BluetoothNamedValue. There are exact two elements in
|
||||
* the array. The first element uses 'serviceId' as the
|
||||
* name and uses BluetoothGattServiceId as the value. The
|
||||
* second element uses 'characteristics' as the name and
|
||||
* uses an array of BluetoothGattCharAttribute of all
|
||||
* discovered characteristics as the value.
|
||||
*/
|
||||
void HandleCharacteristicsDiscovered(const BluetoothValue& aValue);
|
||||
|
||||
/**
|
||||
* Add newly discovered GATT descriptors into mDescriptors of
|
||||
* BluetoothGattCharacteristic and update the cache value of mDescriptors.
|
||||
*
|
||||
* @param aValue [in] BluetoothValue which contains an array of
|
||||
* BluetoothNamedValue. There are exact three elements in
|
||||
* the array. The first element uses 'serviceId' as the
|
||||
* name and uses BluetoothGattServiceId as the value. The
|
||||
* second element uses 'characteristicId' as the name and
|
||||
* uses BluetoothGattId as the value. The third element
|
||||
* uses 'descriptors' as the name and uses an array of
|
||||
* BluetoothGattId of all discovered descriptors as the
|
||||
* value.
|
||||
*/
|
||||
void HandleDescriptorsDiscovered(const BluetoothValue& aValue);
|
||||
|
||||
/**
|
||||
* The value of a GATT characteristic has changed. In the mean time, the
|
||||
* cached value of this GATT characteristic has already been updated. An
|
||||
|
@ -142,18 +142,13 @@ BluetoothGattCharacteristic::StopNotifications(ErrorResult& aRv)
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothGattCharacteristic::HandleDescriptorsDiscovered(
|
||||
const BluetoothValue& aValue)
|
||||
BluetoothGattCharacteristic::AssignDescriptors(
|
||||
const nsTArray<BluetoothGattId>& aDescriptorIds)
|
||||
{
|
||||
MOZ_ASSERT(aValue.type() == BluetoothValue::TArrayOfBluetoothGattId);
|
||||
|
||||
const InfallibleTArray<BluetoothGattId>& descriptorIds =
|
||||
aValue.get_ArrayOfBluetoothGattId();
|
||||
|
||||
mDescriptors.Clear();
|
||||
for (uint32_t i = 0; i < descriptorIds.Length(); i++) {
|
||||
for (uint32_t i = 0; i < aDescriptorIds.Length(); i++) {
|
||||
mDescriptors.AppendElement(new BluetoothGattDescriptor(
|
||||
GetParentObject(), this, descriptorIds[i]));
|
||||
GetParentObject(), this, aDescriptorIds[i]));
|
||||
}
|
||||
|
||||
BluetoothGattCharacteristicBinding::ClearCachedDescriptorsValue(this);
|
||||
@ -175,9 +170,7 @@ BluetoothGattCharacteristic::Notify(const BluetoothSignal& aData)
|
||||
NS_ENSURE_TRUE_VOID(mSignalRegistered);
|
||||
|
||||
BluetoothValue v = aData.value();
|
||||
if (aData.name().EqualsLiteral("DescriptorsDiscovered")) {
|
||||
HandleDescriptorsDiscovered(v);
|
||||
} else if (aData.name().EqualsLiteral("CharacteristicValueUpdated")) {
|
||||
if (aData.name().EqualsLiteral("CharacteristicValueUpdated")) {
|
||||
HandleCharacteristicValueUpdated(v);
|
||||
} else {
|
||||
BT_WARNING("Not handling GATT Characteristic signal: %s",
|
||||
|
@ -32,6 +32,7 @@ class BluetoothGattCharacteristic final : public nsISupports
|
||||
, public nsWrapperCache
|
||||
, public BluetoothSignalObserver
|
||||
{
|
||||
friend class BluetoothGattService;
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(BluetoothGattCharacteristic)
|
||||
@ -106,10 +107,10 @@ private:
|
||||
* Add newly discovered GATT descriptors into mDescriptors and update the
|
||||
* cache value of mDescriptors.
|
||||
*
|
||||
* @param aValue [in] BluetoothValue which contains an array of
|
||||
* BluetoothGattId of all discovered descriptors.
|
||||
* @param aDescriptorIds [in] An array of BluetoothGattId for each descriptor
|
||||
* that belongs to this characteristic.
|
||||
*/
|
||||
void HandleDescriptorsDiscovered(const BluetoothValue& aValue);
|
||||
void AssignDescriptors(const nsTArray<BluetoothGattId>& aDescriptorIds);
|
||||
|
||||
/**
|
||||
* Update the value of this characteristic.
|
||||
|
@ -17,33 +17,10 @@ using namespace mozilla::dom;
|
||||
|
||||
USING_BLUETOOTH_NAMESPACE
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(BluetoothGattService)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(BluetoothGattService)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOwner)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mIncludedServices)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCharacteristics)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
|
||||
/**
|
||||
* Unregister the bluetooth signal handler after unlinked.
|
||||
*
|
||||
* This is needed to avoid ending up with exposing a deleted object to JS or
|
||||
* accessing deleted objects while receiving signals from parent process
|
||||
* after unlinked. Please see Bug 1138267 for detail informations.
|
||||
*/
|
||||
nsString path;
|
||||
GeneratePathFromGattId(tmp->mServiceId.mId, path);
|
||||
UnregisterBluetoothSignalHandler(path, tmp);
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(BluetoothGattService)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwner)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIncludedServices)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCharacteristics)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(BluetoothGattService)
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(BluetoothGattService,
|
||||
mOwner,
|
||||
mIncludedServices,
|
||||
mCharacteristics)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(BluetoothGattService)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(BluetoothGattService)
|
||||
@ -63,72 +40,49 @@ BluetoothGattService::BluetoothGattService(
|
||||
MOZ_ASSERT(!mAppUuid.IsEmpty());
|
||||
|
||||
UuidToString(mServiceId.mId.mUuid, mUuidStr);
|
||||
|
||||
// Generate bluetooth signal path of this service to applications
|
||||
nsString path;
|
||||
GeneratePathFromGattId(mServiceId.mId, path);
|
||||
RegisterBluetoothSignalHandler(path, this);
|
||||
}
|
||||
|
||||
BluetoothGattService::~BluetoothGattService()
|
||||
{
|
||||
nsString path;
|
||||
GeneratePathFromGattId(mServiceId.mId, path);
|
||||
UnregisterBluetoothSignalHandler(path, this);
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothGattService::HandleIncludedServicesDiscovered(
|
||||
const BluetoothValue& aValue)
|
||||
BluetoothGattService::AssignIncludedServices(
|
||||
const nsTArray<BluetoothGattServiceId>& aServiceIds)
|
||||
{
|
||||
MOZ_ASSERT(aValue.type() == BluetoothValue::TArrayOfBluetoothGattServiceId);
|
||||
|
||||
const InfallibleTArray<BluetoothGattServiceId>& includedServIds =
|
||||
aValue.get_ArrayOfBluetoothGattServiceId();
|
||||
|
||||
mIncludedServices.Clear();
|
||||
for (uint32_t i = 0; i < includedServIds.Length(); i++) {
|
||||
for (uint32_t i = 0; i < aServiceIds.Length(); i++) {
|
||||
mIncludedServices.AppendElement(new BluetoothGattService(
|
||||
GetParentObject(), mAppUuid, includedServIds[i]));
|
||||
GetParentObject(), mAppUuid, aServiceIds[i]));
|
||||
}
|
||||
|
||||
BluetoothGattServiceBinding::ClearCachedIncludedServicesValue(this);
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothGattService::HandleCharacteristicsDiscovered(
|
||||
const BluetoothValue& aValue)
|
||||
BluetoothGattService::AssignCharacteristics(
|
||||
const nsTArray<BluetoothGattCharAttribute>& aCharacteristics)
|
||||
{
|
||||
MOZ_ASSERT(aValue.type() ==
|
||||
BluetoothValue::TArrayOfBluetoothGattCharAttribute);
|
||||
|
||||
const InfallibleTArray<BluetoothGattCharAttribute>& characteristics =
|
||||
aValue.get_ArrayOfBluetoothGattCharAttribute();
|
||||
|
||||
mCharacteristics.Clear();
|
||||
for (uint32_t i = 0; i < characteristics.Length(); i++) {
|
||||
for (uint32_t i = 0; i < aCharacteristics.Length(); i++) {
|
||||
mCharacteristics.AppendElement(new BluetoothGattCharacteristic(
|
||||
GetParentObject(), this, characteristics[i]));
|
||||
GetParentObject(), this, aCharacteristics[i]));
|
||||
}
|
||||
|
||||
BluetoothGattServiceBinding::ClearCachedCharacteristicsValue(this);
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothGattService::Notify(const BluetoothSignal& aData)
|
||||
BluetoothGattService::AssignDescriptors(
|
||||
const BluetoothGattId& aCharacteristicId,
|
||||
const nsTArray<BluetoothGattId>& aDescriptorIds)
|
||||
{
|
||||
BT_LOGD("[D] %s", NS_ConvertUTF16toUTF8(aData.name()).get());
|
||||
NS_ENSURE_TRUE_VOID(mSignalRegistered);
|
||||
size_t index = mCharacteristics.IndexOf(aCharacteristicId);
|
||||
NS_ENSURE_TRUE_VOID(index != mCharacteristics.NoIndex);
|
||||
|
||||
BluetoothValue v = aData.value();
|
||||
if (aData.name().EqualsLiteral("IncludedServicesDiscovered")) {
|
||||
HandleIncludedServicesDiscovered(v);
|
||||
} else if (aData.name().EqualsLiteral("CharacteristicsDiscovered")) {
|
||||
HandleCharacteristicsDiscovered(v);
|
||||
} else {
|
||||
BT_WARNING("Not handling GATT Service signal: %s",
|
||||
NS_ConvertUTF16toUTF8(aData.name()).get());
|
||||
}
|
||||
nsRefPtr<BluetoothGattCharacteristic> characteristic =
|
||||
mCharacteristics.ElementAt(index);
|
||||
characteristic->AssignDescriptors(aDescriptorIds);
|
||||
}
|
||||
|
||||
JSObject*
|
||||
|
@ -17,13 +17,14 @@
|
||||
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
||||
class BluetoothGatt;
|
||||
class BluetoothSignal;
|
||||
class BluetoothValue;
|
||||
|
||||
class BluetoothGattService final : public nsISupports
|
||||
, public nsWrapperCache
|
||||
, public BluetoothSignalObserver
|
||||
{
|
||||
friend class BluetoothGatt;
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(BluetoothGattService)
|
||||
@ -71,8 +72,6 @@ public:
|
||||
return mServiceId;
|
||||
}
|
||||
|
||||
void Notify(const BluetoothSignal& aData); // BluetoothSignalObserver
|
||||
|
||||
nsPIDOMWindow* GetParentObject() const
|
||||
{
|
||||
return mOwner;
|
||||
@ -92,20 +91,36 @@ private:
|
||||
* Add newly discovered GATT included services into mIncludedServices and
|
||||
* update the cache value of mIncludedServices.
|
||||
*
|
||||
* @param aValue [in] BluetoothValue which contains an array of
|
||||
* BluetoothGattServiceId of all discovered included
|
||||
* services.
|
||||
* @param aServiceIds [in] An array of BluetoothGattServiceId for each
|
||||
* included service that belongs to this service.
|
||||
*/
|
||||
void HandleIncludedServicesDiscovered(const BluetoothValue& aValue);
|
||||
void AssignIncludedServices(
|
||||
const nsTArray<BluetoothGattServiceId>& aServiceIds);
|
||||
|
||||
/**
|
||||
* Add newly discovered GATT characteristics into mCharacteristics and
|
||||
* update the cache value of mCharacteristics.
|
||||
*
|
||||
* @param aValue [in] BluetoothValue which contains an array of
|
||||
* BluetoothGattId of all discovered characteristics.
|
||||
* @param aCharacteristics [in] An array of BluetoothGattCharAttribute for
|
||||
* each characteristic that belongs to this
|
||||
* service.
|
||||
*/
|
||||
void HandleCharacteristicsDiscovered(const BluetoothValue& aValue);
|
||||
void AssignCharacteristics(
|
||||
const nsTArray<BluetoothGattCharAttribute>& aCharacteristics);
|
||||
|
||||
/**
|
||||
* Add newly discovered GATT descriptors into mDescriptors of
|
||||
* BluetoothGattCharacteristic and update the cache value of mDescriptors.
|
||||
*
|
||||
* @param aCharacteristicId [in] BluetoothGattId of a characteristic that
|
||||
* belongs to this service.
|
||||
* @param aDescriptorIds [in] An array of BluetoothGattId for each descriptor
|
||||
* that belongs to the characteristic referred by
|
||||
* aCharacteristicId.
|
||||
*/
|
||||
void AssignDescriptors(
|
||||
const BluetoothGattId& aCharacteristicId,
|
||||
const nsTArray<BluetoothGattId>& aDescriptorIds);
|
||||
|
||||
/****************************************************************************
|
||||
* Variables
|
||||
|
@ -94,6 +94,7 @@ this.Keyboard = {
|
||||
Services.obs.addObserver(this, 'inprocess-browser-shown', false);
|
||||
Services.obs.addObserver(this, 'remote-browser-shown', false);
|
||||
Services.obs.addObserver(this, 'oop-frameloader-crashed', false);
|
||||
Services.obs.addObserver(this, 'message-manager-close', false);
|
||||
|
||||
for (let name of this._messageNames) {
|
||||
ppmm.addMessageListener('Keyboard:' + name, this);
|
||||
@ -107,10 +108,18 @@ this.Keyboard = {
|
||||
},
|
||||
|
||||
observe: function keyboardObserve(subject, topic, data) {
|
||||
let frameLoader = subject.QueryInterface(Ci.nsIFrameLoader);
|
||||
let mm = frameLoader.messageManager;
|
||||
let frameLoader = null;
|
||||
let mm = null;
|
||||
|
||||
if (topic == 'oop-frameloader-crashed') {
|
||||
if (topic == 'message-manager-close') {
|
||||
mm = subject;
|
||||
} else {
|
||||
frameLoader = subject.QueryInterface(Ci.nsIFrameLoader);
|
||||
mm = frameLoader.messageManager;
|
||||
}
|
||||
|
||||
if (topic == 'oop-frameloader-crashed' ||
|
||||
topic == 'message-manager-close') {
|
||||
if (this.formMM == mm) {
|
||||
// The application has been closed unexpectingly. Let's tell the
|
||||
// keyboard app that the focus has been lost.
|
||||
@ -290,6 +299,8 @@ this.Keyboard = {
|
||||
if (mm !== this.formMM) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.formMM = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,8 @@ const Cu = Components.utils;
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "AddonManager", "resource://gre/modules/AddonManager.jsm");
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Web Install Prompt service
|
||||
// -----------------------------------------------------------------------
|
||||
@ -27,7 +29,15 @@ WebInstallPrompt.prototype = {
|
||||
let button = bundle.GetStringFromName("addonsConfirmInstall.install");
|
||||
|
||||
aInstalls.forEach(function(install) {
|
||||
let result = (prompt.confirmEx(aBrowser.contentWindow, title, install.name, flags, button, null, null, null, {value: false}) == 0);
|
||||
let message;
|
||||
if (install.addon.signedState <= AddonManager.SIGNEDSTATE_MISSING) {
|
||||
title = bundle.GetStringFromName("addonsConfirmInstallUnsigned.title")
|
||||
message = bundle.GetStringFromName("addonsConfirmInstallUnsigned.message") + "\n\n" + install.name;
|
||||
} else {
|
||||
message = install.name;
|
||||
}
|
||||
|
||||
let result = (prompt.confirmEx(aBrowser.contentWindow, title, message, flags, button, null, null, null, {value: false}) == 0);
|
||||
if (result)
|
||||
install.install();
|
||||
else
|
||||
|
@ -5,6 +5,9 @@
|
||||
addonsConfirmInstall.title=Installing Add-on
|
||||
addonsConfirmInstall.install=Install
|
||||
|
||||
addonsConfirmInstallUnsigned.title=Unverified add-on
|
||||
addonsConfirmInstallUnsigned.message=This site would like to install an unverified add-on. Proceed at your own risk.
|
||||
|
||||
# Alerts
|
||||
alertAddonsDownloading=Downloading add-on
|
||||
alertAddonsInstalledNoRestart.message=Installation complete
|
||||
|
@ -13,7 +13,7 @@ task:
|
||||
phone:
|
||||
type: 'flame'
|
||||
memory: '319'
|
||||
sims: '1'
|
||||
sims: '2'
|
||||
build: '{{{img_url}}}'
|
||||
features:
|
||||
testdroidProxy: true
|
||||
|
@ -15,7 +15,18 @@ loader.lazyImporter(this, "NetUtil", "resource://gre/modules/NetUtil.jsm");
|
||||
loader.lazyServiceGetter(this, "gActivityDistributor",
|
||||
"@mozilla.org/network/http-activity-distributor;1",
|
||||
"nsIHttpActivityDistributor");
|
||||
loader.lazyImporter(this, "gDevTools", "resource:///modules/devtools/gDevTools.jsm");
|
||||
let _testing = false;
|
||||
Object.defineProperty(this, "gTesting", {
|
||||
get: function() {
|
||||
try {
|
||||
const { gDevTools } = require("resource:///modules/devtools/gDevTools.jsm");
|
||||
_testing = gDevTools.testing;
|
||||
} catch (e) {
|
||||
// gDevTools is not present on B2G.
|
||||
}
|
||||
return _testing;
|
||||
}
|
||||
});
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Network logging
|
||||
@ -747,7 +758,7 @@ NetworkMonitor.prototype = {
|
||||
// TODO: one particular test (browser_styleeditor_fetch-from-cache.js) needs
|
||||
// the gDevTools.testing check. We will move to a better way to serve its
|
||||
// needs in bug 1167188, where this check should be removed.
|
||||
if (!gDevTools.testing && aChannel.loadInfo &&
|
||||
if (!gTesting && aChannel.loadInfo &&
|
||||
aChannel.loadInfo.loadingDocument === null &&
|
||||
aChannel.loadInfo.loadingPrincipal === Services.scriptSecurityManager.getSystemPrincipal()) {
|
||||
return false;
|
||||
@ -768,12 +779,6 @@ NetworkMonitor.prototype = {
|
||||
}
|
||||
}
|
||||
|
||||
if (aChannel.loadInfo) {
|
||||
if (aChannel.loadInfo.contentPolicyType == Ci.nsIContentPolicy.TYPE_BEACON) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.topFrame) {
|
||||
let topFrame = NetworkHelper.getTopFrameForRequest(aChannel);
|
||||
if (topFrame && topFrame === this.topFrame) {
|
||||
@ -788,6 +793,24 @@ NetworkMonitor.prototype = {
|
||||
}
|
||||
}
|
||||
|
||||
// The following check is necessary because beacon channels don't come
|
||||
// associated with a load group. Bug 1160837 will hopefully introduce a
|
||||
// platform fix that will render the following code entirely useless.
|
||||
if (aChannel.loadInfo &&
|
||||
aChannel.loadInfo.contentPolicyType == Ci.nsIContentPolicy.TYPE_BEACON) {
|
||||
let nonE10sMatch = this.window &&
|
||||
aChannel.loadInfo.loadingDocument === this.window.document;
|
||||
let e10sMatch = this.topFrame &&
|
||||
this.topFrame.contentPrincipal &&
|
||||
this.topFrame.contentPrincipal.equals(aChannel.loadInfo.loadingPrincipal) &&
|
||||
this.topFrame.contentPrincipal.URI.spec == aChannel.referrer.spec;
|
||||
let b2gMatch = this.appId &&
|
||||
aChannel.loadInfo.loadingPrincipal.appId === this.appId;
|
||||
if (nonE10sMatch || e10sMatch || b2gMatch) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
|
@ -106,28 +106,23 @@ treechildren.autocomplete-treebody::-moz-tree-cell-text(selected) {
|
||||
}
|
||||
|
||||
%ifdef XP_WIN
|
||||
@media not all and (-moz-os-version: windows-xp) {
|
||||
@media (-moz-windows-default-theme) {
|
||||
/*
|
||||
-moz-appearance: menuitem is almost right, but the hover effect is not
|
||||
transparent and is lighter than desired.
|
||||
*/
|
||||
.autocomplete-richlistitem[selected="true"] {
|
||||
color: inherit;
|
||||
background-color: transparent;
|
||||
/* four gradients for the bevel highlights on each edge, one for blue background */
|
||||
background-image:
|
||||
linear-gradient(to bottom, rgba(255,255,255,0.9) 3px, transparent 3px),
|
||||
linear-gradient(to right, rgba(255,255,255,0.5) 3px, transparent 3px),
|
||||
linear-gradient(to left, rgba(255,255,255,0.5) 3px, transparent 3px),
|
||||
linear-gradient(to top, rgba(255,255,255,0.4) 3px, transparent 3px),
|
||||
linear-gradient(to bottom, rgba(163,196,247,0.3), rgba(122,180,246,0.3));
|
||||
background-clip: content-box;
|
||||
border-radius: 6px;
|
||||
outline: 1px solid rgb(124,163,206);
|
||||
-moz-outline-radius: 3px;
|
||||
outline-offset: -2px;
|
||||
}
|
||||
@media (-moz-os-version: windows-vista) and (-moz-windows-default-theme),
|
||||
(-moz-os-version: windows-win7) and (-moz-windows-default-theme) {
|
||||
.autocomplete-richlistitem[selected="true"] {
|
||||
color: inherit;
|
||||
background-color: transparent;
|
||||
/* four gradients for the bevel highlights on each edge, one for blue background */
|
||||
background-image:
|
||||
linear-gradient(to bottom, rgba(255,255,255,0.9) 3px, transparent 3px),
|
||||
linear-gradient(to right, rgba(255,255,255,0.5) 3px, transparent 3px),
|
||||
linear-gradient(to left, rgba(255,255,255,0.5) 3px, transparent 3px),
|
||||
linear-gradient(to top, rgba(255,255,255,0.4) 3px, transparent 3px),
|
||||
linear-gradient(to bottom, rgba(163,196,247,0.3), rgba(122,180,246,0.3));
|
||||
background-clip: content-box;
|
||||
border-radius: 6px;
|
||||
outline: 1px solid rgb(124,163,206);
|
||||
-moz-outline-radius: 3px;
|
||||
outline-offset: -2px;
|
||||
}
|
||||
}
|
||||
%endif
|
||||
|
Loading…
Reference in New Issue
Block a user