Merge m-c to inbound. a=merge
CLOSED TREE
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="d22dfece04fc00457e8369c660c11f945b088d2f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="7a865bd6163e9a0372861d27450b3434875ef5c1"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
@ -23,7 +23,7 @@
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<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="2b761dbeebac9126947315659419a0fb1f80b230"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f0e6d8bde961683b7862b4eb0bb04c49d9699f3c"/>
|
||||
<!-- 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"/>
|
||||
@ -129,7 +129,7 @@
|
||||
<!-- Stock Android things -->
|
||||
<project name="platform/external/icu4c" path="external/icu4c" revision="2bb01561780583cc37bc667f0ea79f48a122d8a2"/>
|
||||
<!-- dolphin specific things -->
|
||||
<project name="device/sprd" path="device/sprd" revision="ea8680ba32e41e5f7a2ff12d692f2a159cb19501"/>
|
||||
<project name="device/sprd" path="device/sprd" revision="b007fe5fb2c214bd71133378248113e6e74ce4d9"/>
|
||||
<project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="4e58336019b5cbcfd134caf55b142236cf986618"/>
|
||||
<project name="platform/frameworks/av" path="frameworks/av" revision="4387fe988e5a1001f29ce05fcfda03ed2d32137b"/>
|
||||
<project name="platform/hardware/akm" path="hardware/akm" revision="6d3be412647b0eab0adff8a2768736cf4eb68039"/>
|
||||
|
@ -19,13 +19,13 @@
|
||||
<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="d22dfece04fc00457e8369c660c11f945b088d2f"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="7a865bd6163e9a0372861d27450b3434875ef5c1"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="6fa7a4936414ceb4055fd27f7a30e76790f834fb"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="2b761dbeebac9126947315659419a0fb1f80b230"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f0e6d8bde961683b7862b4eb0bb04c49d9699f3c"/>
|
||||
<!-- Stock Android things -->
|
||||
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
|
||||
<project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>
|
||||
|
@ -17,10 +17,10 @@
|
||||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="d22dfece04fc00457e8369c660c11f945b088d2f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="7a865bd6163e9a0372861d27450b3434875ef5c1"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="2b761dbeebac9126947315659419a0fb1f80b230"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f0e6d8bde961683b7862b4eb0bb04c49d9699f3c"/>
|
||||
<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="3ab0d9c70f0b2e1ededc679112c392303f037361">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="d22dfece04fc00457e8369c660c11f945b088d2f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="7a865bd6163e9a0372861d27450b3434875ef5c1"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
@ -23,7 +23,7 @@
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<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="2b761dbeebac9126947315659419a0fb1f80b230"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f0e6d8bde961683b7862b4eb0bb04c49d9699f3c"/>
|
||||
<!-- 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"/>
|
||||
|
@ -19,13 +19,13 @@
|
||||
<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="d22dfece04fc00457e8369c660c11f945b088d2f"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="7a865bd6163e9a0372861d27450b3434875ef5c1"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="6fa7a4936414ceb4055fd27f7a30e76790f834fb"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="2b761dbeebac9126947315659419a0fb1f80b230"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f0e6d8bde961683b7862b4eb0bb04c49d9699f3c"/>
|
||||
<!-- Stock Android things -->
|
||||
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
|
||||
<project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="d22dfece04fc00457e8369c660c11f945b088d2f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="7a865bd6163e9a0372861d27450b3434875ef5c1"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
@ -23,7 +23,7 @@
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<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="2b761dbeebac9126947315659419a0fb1f80b230"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f0e6d8bde961683b7862b4eb0bb04c49d9699f3c"/>
|
||||
<!-- 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"/>
|
||||
|
@ -17,10 +17,10 @@
|
||||
</project>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="d22dfece04fc00457e8369c660c11f945b088d2f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="7a865bd6163e9a0372861d27450b3434875ef5c1"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="2b761dbeebac9126947315659419a0fb1f80b230"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f0e6d8bde961683b7862b4eb0bb04c49d9699f3c"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<!-- Stock Android things -->
|
||||
|
@ -4,6 +4,6 @@
|
||||
"remote": "",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "8175c3383310bf79cbfd01d36273620dede2a111",
|
||||
"revision": "fbcff6610f8b99726ef14b0c6d894b4a7053eecf",
|
||||
"repo_path": "integration/gaia-central"
|
||||
}
|
||||
|
@ -17,11 +17,11 @@
|
||||
<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="d22dfece04fc00457e8369c660c11f945b088d2f"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="7a865bd6163e9a0372861d27450b3434875ef5c1"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="2b761dbeebac9126947315659419a0fb1f80b230"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f0e6d8bde961683b7862b4eb0bb04c49d9699f3c"/>
|
||||
<!-- Stock Android things -->
|
||||
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
|
||||
<project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
|
||||
|
@ -15,7 +15,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="d22dfece04fc00457e8369c660c11f945b088d2f"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="7a865bd6163e9a0372861d27450b3434875ef5c1"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
|
@ -17,10 +17,10 @@
|
||||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="d22dfece04fc00457e8369c660c11f945b088d2f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="7a865bd6163e9a0372861d27450b3434875ef5c1"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="2b761dbeebac9126947315659419a0fb1f80b230"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f0e6d8bde961683b7862b4eb0bb04c49d9699f3c"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<!-- Stock Android things -->
|
||||
|
@ -17,12 +17,12 @@
|
||||
<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="d22dfece04fc00457e8369c660c11f945b088d2f"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="7a865bd6163e9a0372861d27450b3434875ef5c1"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="2b761dbeebac9126947315659419a0fb1f80b230"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f0e6d8bde961683b7862b4eb0bb04c49d9699f3c"/>
|
||||
<project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
|
||||
<!-- Stock Android things -->
|
||||
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
|
||||
|
@ -14,6 +14,30 @@
|
||||
%endif
|
||||
}
|
||||
|
||||
/* These values are chosen to keep the Loop detached chat window from
|
||||
* getting too small. When it's too small, three bad things happen:
|
||||
*
|
||||
* - It looks terrible
|
||||
* - It's not really usable
|
||||
* - It's possible for the user to be transmitting video that's cropped by the
|
||||
* the edge of the window, so that they're not aware of it, which is a
|
||||
* privacy problem
|
||||
*
|
||||
* Note that if the chat window grows more users than Loop who want this
|
||||
* ability, we'll need to generalize. A partial patch for this is in
|
||||
* bug 1112264.
|
||||
*/
|
||||
|
||||
#chat-window {
|
||||
/*
|
||||
* In some ideal world, we'd have a simple way to express "block resizing
|
||||
* 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;
|
||||
}
|
||||
|
||||
#main-window[customize-entered] {
|
||||
min-width: -moz-fit-content;
|
||||
}
|
||||
@ -849,7 +873,7 @@ toolbarbutton[type="socialmark"] {
|
||||
|
||||
toolbarbutton.badged-button > .toolbarbutton-badge-container > .toolbarbutton-icon,
|
||||
toolbarbutton[type="socialmark"] > .toolbarbutton-icon {
|
||||
max-width: 16px;
|
||||
max-width: 18px;
|
||||
}
|
||||
toolbarpaletteitem[place="palette"] > toolbarbutton.badged-button > .toolbarbutton-badge-container > .toolbarbutton-icon {
|
||||
max-width: 32px;
|
||||
|
@ -95,8 +95,8 @@ addMessageListener("MixedContent:ReenableProtection", function() {
|
||||
addMessageListener("SecondScreen:tab-mirror", function(message) {
|
||||
let app = SimpleServiceDiscovery.findAppForService(message.data.service);
|
||||
if (app) {
|
||||
let width = content.scrollWidth;
|
||||
let height = content.scrollHeight;
|
||||
let width = content.innerWidth;
|
||||
let height = content.innerHeight;
|
||||
let viewport = {cssWidth: width, cssHeight: height, width: width, height: height};
|
||||
app.mirror(function() {}, content, viewport, function() {}, content);
|
||||
}
|
||||
|
@ -1190,6 +1190,10 @@
|
||||
// We need to explicitly focus the new tab, because
|
||||
// tabbox.xml does this only in some cases.
|
||||
this.mCurrentTab.focus();
|
||||
} else if (gMultiProcessBrowser) {
|
||||
// Clear focus so that _adjustFocusAfterTabSwitch can detect if
|
||||
// some element has been focused and respect that.
|
||||
document.activeElement.blur();
|
||||
}
|
||||
|
||||
if (!gMultiProcessBrowser)
|
||||
@ -1207,12 +1211,12 @@
|
||||
<method name="_adjustFocusAfterTabSwitch">
|
||||
<parameter name="newTab"/>
|
||||
<body><![CDATA[
|
||||
let newBrowser = this.getBrowserForTab(newTab);
|
||||
|
||||
// Don't steal focus from the tab bar.
|
||||
if (document.activeElement == newTab)
|
||||
return;
|
||||
|
||||
let newBrowser = this.getBrowserForTab(newTab);
|
||||
|
||||
// If there's a tabmodal prompt showing, focus it.
|
||||
if (newBrowser.hasAttribute("tabmodalPromptShowing")) {
|
||||
let XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
@ -1226,7 +1230,6 @@
|
||||
// In full screen mode, only bother making the location bar visible
|
||||
// if the tab is a blank one.
|
||||
if (newBrowser._urlbarFocused && gURLBar) {
|
||||
|
||||
// Explicitly close the popup if the URL bar retains focus
|
||||
gURLBar.closePopup();
|
||||
|
||||
@ -1248,20 +1251,13 @@
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, focus the content area. If we're not using remote tabs, we
|
||||
// can focus the content area right away, since tab switching is synchronous.
|
||||
// If we're using remote tabs, we have to wait until after we've finalized
|
||||
// switching the tabs.
|
||||
|
||||
if (newTab._skipContentFocus) {
|
||||
// It's possible the tab we're switching to is ready to focus asynchronously,
|
||||
// when we've already focused something else. In that case, this
|
||||
// _skipContentFocus property can be set so that we skip focusing the
|
||||
// content after we switch tabs.
|
||||
delete newTab._skipContentFocus;
|
||||
// Don't focus the content area if something has been focused after the
|
||||
// tab switch was initiated.
|
||||
if (gMultiProcessBrowser &&
|
||||
document.activeElement != document.documentElement)
|
||||
return;
|
||||
}
|
||||
|
||||
// We're now committed to focusing the content area.
|
||||
let fm = Services.focus;
|
||||
let focusFlags = fm.FLAG_NOSCROLL;
|
||||
|
||||
|
@ -1035,17 +1035,17 @@
|
||||
"searchbar-oneoffheader-searchtext");
|
||||
let textbox = searchbar.textbox;
|
||||
let self = this;
|
||||
let keyPressHandler = function() {
|
||||
let inputHandler = function() {
|
||||
headerSearchText.setAttribute("value", textbox.value);
|
||||
if (textbox.value)
|
||||
self.removeAttribute("showonlysettings");
|
||||
};
|
||||
textbox.addEventListener("keyup", keyPressHandler);
|
||||
textbox.addEventListener("input", inputHandler);
|
||||
this.addEventListener("popuphiding", function hiding() {
|
||||
textbox.removeEventListener("keyup", keyPressHandler);
|
||||
textbox.removeEventListener("input", inputHandler);
|
||||
this.removeEventListener("popuphiding", hiding);
|
||||
});
|
||||
keyPressHandler();
|
||||
inputHandler();
|
||||
|
||||
// Handle opensearch items. This needs to be done before building the
|
||||
// list of one off providers, as that code will return early if all the
|
||||
@ -1060,8 +1060,6 @@
|
||||
|
||||
let addEngines = gBrowser.selectedBrowser.engines;
|
||||
if (addEngines && addEngines.length > 0) {
|
||||
const kBundleURI = "chrome://browser/locale/search.properties";
|
||||
let bundle = Services.strings.createBundle(kBundleURI);
|
||||
for (let engine of addEngines) {
|
||||
let button = document.createElementNS(kXULNS, "button");
|
||||
let label = bundle.formatStringFromName("cmd_addFoundEngine",
|
||||
|
@ -309,8 +309,6 @@ function openLinkIn(url, where, params) {
|
||||
// result in a new frontmost window (e.g. "javascript:window.open('');").
|
||||
w.focus();
|
||||
|
||||
let newTab;
|
||||
|
||||
switch (where) {
|
||||
case "current":
|
||||
let flags = Ci.nsIWebNavigation.LOAD_FLAGS_NONE;
|
||||
@ -333,7 +331,7 @@ function openLinkIn(url, where, params) {
|
||||
loadInBackground = !loadInBackground;
|
||||
// fall through
|
||||
case "tab":
|
||||
newTab = w.gBrowser.loadOneTab(url, {
|
||||
w.gBrowser.loadOneTab(url, {
|
||||
referrerURI: aReferrerURI,
|
||||
charset: aCharset,
|
||||
postData: aPostData,
|
||||
@ -349,12 +347,6 @@ function openLinkIn(url, where, params) {
|
||||
w.gBrowser.selectedBrowser.focus();
|
||||
|
||||
if (!loadInBackground && w.isBlankPageURL(url)) {
|
||||
if (newTab && gMultiProcessBrowser) {
|
||||
// Remote browsers are switched to asynchronously, and we need to
|
||||
// ensure that the location bar remains focused in that case rather
|
||||
// than the content area being focused.
|
||||
newTab._skipContentFocus = true;
|
||||
}
|
||||
w.focusAndSelectUrlBar();
|
||||
}
|
||||
}
|
||||
|
@ -570,6 +570,27 @@ this.LoopRooms = {
|
||||
return LoopRoomsInternal.maybeRefresh(user);
|
||||
},
|
||||
|
||||
/**
|
||||
* This method is only useful for unit tests to set the rooms cache to contain
|
||||
* a list of fake room data that can be asserted in tests.
|
||||
*
|
||||
* @param {Map} stub Stub cache containing fake rooms data
|
||||
*/
|
||||
stubCache: function(stub) {
|
||||
LoopRoomsInternal.rooms.clear();
|
||||
if (stub) {
|
||||
// Fill up the rooms cache with room objects provided in the `stub` Map.
|
||||
for (let [key, value] of stub.entries()) {
|
||||
LoopRoomsInternal.rooms.set(key, value);
|
||||
}
|
||||
gDirty = false;
|
||||
} else {
|
||||
// Restore the cache to not be stubbed anymore, but it'll need a refresh
|
||||
// from the server for sure.
|
||||
gDirty = true;
|
||||
}
|
||||
},
|
||||
|
||||
promise: function(method, ...params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this[method](...params, (error, result) => {
|
||||
|
@ -23,6 +23,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "hookWindowCloseForPanelClose",
|
||||
"resource://gre/modules/MozSocialAPI.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
|
||||
"resource://gre/modules/PluralForm.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "UITour",
|
||||
"resource:///modules/UITour.jsm");
|
||||
XPCOMUtils.defineLazyGetter(this, "appInfo", function() {
|
||||
return Cc["@mozilla.org/xre/app-info;1"]
|
||||
.getService(Ci.nsIXULAppInfo)
|
||||
@ -735,7 +737,21 @@ function injectLoopAPI(targetWindow) {
|
||||
callId: callid
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Notifies the UITour module that an event occurred that it might be
|
||||
* interested in.
|
||||
*
|
||||
* @param {String} subject Subject of the notification
|
||||
*/
|
||||
notifyUITour: {
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
value: function(subject) {
|
||||
UITour.notify(subject);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
function onStatusChanged(aSubject, aTopic, aData) {
|
||||
|
@ -81,6 +81,16 @@ loop.roomViews = (function(mozL10n) {
|
||||
this.stopListening(this.props.roomStore);
|
||||
},
|
||||
|
||||
handleTextareaKeyDown: function(event) {
|
||||
// Submit the form as soon as the user press Enter in that field
|
||||
// Note: We're using a textarea instead of a simple text input to display
|
||||
// placeholder and entered text on two lines, to circumvent l10n
|
||||
// rendering/UX issues for some locales.
|
||||
if (event.which === 13) {
|
||||
this.handleFormSubmit(event);
|
||||
}
|
||||
},
|
||||
|
||||
handleFormSubmit: function(event) {
|
||||
event.preventDefault();
|
||||
|
||||
@ -129,9 +139,10 @@ loop.roomViews = (function(mozL10n) {
|
||||
mozL10n.get("rooms_name_change_failed_label")
|
||||
),
|
||||
React.DOM.form({onSubmit: this.handleFormSubmit},
|
||||
React.DOM.input({type: "text", className: "input-room-name",
|
||||
React.DOM.textarea({rows: "2", type: "text", className: "input-room-name",
|
||||
valueLink: this.linkState("newRoomName"),
|
||||
onBlur: this.handleFormSubmit,
|
||||
onKeyDown: this.handleTextareaKeyDown,
|
||||
placeholder: mozL10n.get("rooms_name_this_room_label")})
|
||||
),
|
||||
React.DOM.p(null, mozL10n.get("invite_header_text")),
|
||||
|
@ -81,6 +81,16 @@ loop.roomViews = (function(mozL10n) {
|
||||
this.stopListening(this.props.roomStore);
|
||||
},
|
||||
|
||||
handleTextareaKeyDown: function(event) {
|
||||
// Submit the form as soon as the user press Enter in that field
|
||||
// Note: We're using a textarea instead of a simple text input to display
|
||||
// placeholder and entered text on two lines, to circumvent l10n
|
||||
// rendering/UX issues for some locales.
|
||||
if (event.which === 13) {
|
||||
this.handleFormSubmit(event);
|
||||
}
|
||||
},
|
||||
|
||||
handleFormSubmit: function(event) {
|
||||
event.preventDefault();
|
||||
|
||||
@ -129,9 +139,10 @@ loop.roomViews = (function(mozL10n) {
|
||||
{mozL10n.get("rooms_name_change_failed_label")}
|
||||
</p>
|
||||
<form onSubmit={this.handleFormSubmit}>
|
||||
<input type="text" className="input-room-name"
|
||||
<textarea rows="2" type="text" className="input-room-name"
|
||||
valueLink={this.linkState("newRoomName")}
|
||||
onBlur={this.handleFormSubmit}
|
||||
onKeyDown={this.handleTextareaKeyDown}
|
||||
placeholder={mozL10n.get("rooms_name_this_room_label")} />
|
||||
</form>
|
||||
<p>{mozL10n.get("invite_header_text")}</p>
|
||||
|
@ -810,15 +810,20 @@ html, .fx-embedded, #main,
|
||||
}
|
||||
|
||||
.room-invitation-overlay form {
|
||||
padding: 8em 0 2.5em 0;
|
||||
padding: 6em 0 2em 0;
|
||||
}
|
||||
|
||||
.room-invitation-overlay input[type="text"] {
|
||||
.room-invitation-overlay textarea {
|
||||
display: block;
|
||||
background: rgba(0, 0, 0, .5);
|
||||
color: #fff;
|
||||
font-family: "Helvetica Neue", Arial, sans;
|
||||
font-size: 1.2em;
|
||||
border: none;
|
||||
width: 200px;
|
||||
margin: 0 auto;
|
||||
padding: .2em .4em;
|
||||
border-radius: .5em;
|
||||
}
|
||||
|
||||
.room-invitation-overlay .btn-group {
|
||||
|
@ -298,6 +298,7 @@ loop.store = loop.store || {};
|
||||
*/
|
||||
copyRoomUrl: function(actionData) {
|
||||
this._mozLoop.copyString(actionData.roomUrl);
|
||||
this._mozLoop.notifyUITour("Loop:RoomURLCopied");
|
||||
},
|
||||
|
||||
/**
|
||||
@ -307,6 +308,7 @@ loop.store = loop.store || {};
|
||||
*/
|
||||
emailRoomUrl: function(actionData) {
|
||||
loop.shared.utils.composeCallUrlEmail(actionData.roomUrl);
|
||||
this._mozLoop.notifyUITour("Loop:RoomURLEmailed");
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -146,9 +146,9 @@ describe("loop.roomViews", function () {
|
||||
}));
|
||||
});
|
||||
|
||||
it("should dispatch a RenameRoom action when enter is pressed",
|
||||
it("should dispatch a RenameRoom action when Enter key is pressed",
|
||||
function() {
|
||||
React.addons.TestUtils.Simulate.submit(roomNameBox);
|
||||
TestUtils.Simulate.keyDown(roomNameBox, {key: "Enter", which: 13});
|
||||
|
||||
sinon.assert.calledOnce(dispatcher.dispatch);
|
||||
sinon.assert.calledWithExactly(dispatcher.dispatch,
|
||||
|
@ -77,6 +77,7 @@ describe("loop.store.RoomStore", function () {
|
||||
beforeEach(function() {
|
||||
fakeMozLoop = {
|
||||
copyString: function() {},
|
||||
notifyUITour: function() {},
|
||||
rooms: {
|
||||
create: function() {},
|
||||
getAll: function() {},
|
||||
|
@ -704,7 +704,11 @@
|
||||
}
|
||||
|
||||
window.addEventListener("DOMContentLoaded", function() {
|
||||
React.renderComponent(App(null), document.body);
|
||||
try {
|
||||
React.renderComponent(App(null), document.body);
|
||||
} catch(err) {
|
||||
console.log(err);
|
||||
}
|
||||
|
||||
_renderComponentsInIframes();
|
||||
|
||||
|
@ -704,7 +704,11 @@
|
||||
}
|
||||
|
||||
window.addEventListener("DOMContentLoaded", function() {
|
||||
React.renderComponent(<App />, document.body);
|
||||
try {
|
||||
React.renderComponent(<App />, document.body);
|
||||
} catch(err) {
|
||||
console.log(err);
|
||||
}
|
||||
|
||||
_renderComponentsInIframes();
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
<?xml-stylesheet
|
||||
href="chrome://browser/content/preferences/handlers.css"?>
|
||||
<?xml-stylesheet href="chrome://browser/skin/preferences/applications.css"?>
|
||||
<?xml-stylesheet href="chrome://browser/content/preferences/in-content/search.css"?>
|
||||
<?xml-stylesheet href="chrome://browser/skin/preferences/in-content/search.css"?>
|
||||
|
||||
<!DOCTYPE page [
|
||||
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
|
||||
|
@ -4,6 +4,10 @@
|
||||
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
const ENGINE_FLAVOR = "text/x-moz-search-engine";
|
||||
|
||||
var gEngineView = null;
|
||||
|
||||
var gSearchPane = {
|
||||
|
||||
init: function ()
|
||||
@ -15,9 +19,37 @@ var gSearchPane = {
|
||||
return;
|
||||
}
|
||||
|
||||
gEngineView = new EngineView(new EngineStore());
|
||||
document.getElementById("engineList").view = gEngineView;
|
||||
this.buildDefaultEngineDropDown();
|
||||
|
||||
Services.obs.addObserver(this, "browser-search-engine-modified", false);
|
||||
window.addEventListener("unload", () => {
|
||||
Services.obs.removeObserver(this, "browser-search-engine-modified", false);
|
||||
});
|
||||
},
|
||||
|
||||
buildDefaultEngineDropDown: function() {
|
||||
// This is called each time something affects the list of engines.
|
||||
let list = document.getElementById("defaultEngine");
|
||||
let currentEngine = Services.search.currentEngine.name;
|
||||
Services.search.getVisibleEngines().forEach(e => {
|
||||
let currentEngine;
|
||||
|
||||
// First, try to preserve the current selection.
|
||||
if (list.selectedItem)
|
||||
currentEngine = list.selectedItem.label;
|
||||
|
||||
// If there's no current selection, use the current default engine.
|
||||
if (!currentEngine)
|
||||
currentEngine = Services.search.currentEngine.name;
|
||||
|
||||
// If the current engine isn't in the list any more, select the first item.
|
||||
let engines = gEngineView._engineStore._engines;
|
||||
if (!engines.some(e => e.name == currentEngine))
|
||||
currentEngine = engines[0].name;
|
||||
|
||||
// Now clean-up and rebuild the list.
|
||||
list.removeAllItems();
|
||||
gEngineView._engineStore._engines.forEach(e => {
|
||||
let item = list.appendItem(e.name);
|
||||
item.setAttribute("class", "menuitem-iconic searchengine-menuitem menuitem-with-favicon");
|
||||
if (e.iconURI)
|
||||
@ -26,42 +58,119 @@ var gSearchPane = {
|
||||
if (e.name == currentEngine)
|
||||
list.selectedItem = item;
|
||||
});
|
||||
|
||||
this.displayOneClickEnginesList();
|
||||
|
||||
document.getElementById("oneClickProvidersList")
|
||||
.addEventListener("CheckboxStateChange", gSearchPane.saveOneClickEnginesList);
|
||||
},
|
||||
|
||||
displayOneClickEnginesList: function () {
|
||||
let richlistbox = document.getElementById("oneClickProvidersList");
|
||||
let pref = document.getElementById("browser.search.hiddenOneOffs").value;
|
||||
let hiddenList = pref ? pref.split(",") : [];
|
||||
observe: function(aEngine, aTopic, aVerb) {
|
||||
if (aTopic == "browser-search-engine-modified") {
|
||||
aEngine.QueryInterface(Components.interfaces.nsISearchEngine);
|
||||
switch (aVerb) {
|
||||
case "engine-added":
|
||||
gEngineView._engineStore.addEngine(aEngine);
|
||||
gEngineView.rowCountChanged(gEngineView.lastIndex, 1);
|
||||
gSearchPane.buildDefaultEngineDropDown();
|
||||
break;
|
||||
case "engine-changed":
|
||||
gEngineView._engineStore.reloadIcons();
|
||||
gEngineView.invalidate();
|
||||
break;
|
||||
case "engine-removed":
|
||||
case "engine-current":
|
||||
case "engine-default":
|
||||
// Not relevant
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
while (richlistbox.firstChild)
|
||||
richlistbox.firstChild.remove();
|
||||
onTreeSelect: function() {
|
||||
document.getElementById("removeEngineButton").disabled =
|
||||
gEngineView.selectedIndex == -1 || gEngineView.lastIndex == 0;
|
||||
},
|
||||
|
||||
let currentEngine = Services.search.currentEngine.name;
|
||||
Services.search.getVisibleEngines().forEach(e => {
|
||||
if (e.name == currentEngine)
|
||||
return;
|
||||
onTreeKeyPress: function(aEvent) {
|
||||
let index = gEngineView.selectedIndex;
|
||||
let tree = document.getElementById("engineList");
|
||||
if (aEvent.charCode == KeyEvent.DOM_VK_SPACE) {
|
||||
// Space toggles the checkbox.
|
||||
let newValue = !gEngineView._engineStore.engines[index].shown;
|
||||
gEngineView.setCellValue(index, tree.columns.getFirstColumn(),
|
||||
newValue.toString());
|
||||
}
|
||||
else {
|
||||
let isMac = Services.appinfo.OS == "Darwin";
|
||||
if ((isMac && aEvent.keyCode == KeyEvent.DOM_VK_RETURN) ||
|
||||
(!isMac && aEvent.keyCode == KeyEvent.DOM_VK_F2))
|
||||
tree.startEditing(index, tree.columns.getLastColumn());
|
||||
}
|
||||
},
|
||||
|
||||
let item = document.createElement("richlistitem");
|
||||
item.setAttribute("label", e.name);
|
||||
if (hiddenList.indexOf(e.name) == -1)
|
||||
item.setAttribute("checked", "true");
|
||||
if (e.iconURI)
|
||||
item.setAttribute("src", e.iconURI.spec);
|
||||
richlistbox.appendChild(item);
|
||||
});
|
||||
onRestoreDefaults: function() {
|
||||
let num = gEngineView._engineStore.restoreDefaultEngines();
|
||||
gEngineView.rowCountChanged(0, num);
|
||||
gEngineView.invalidate();
|
||||
},
|
||||
|
||||
showRestoreDefaults: function(aEnable) {
|
||||
document.getElementById("restoreDefaultSearchEngines").disabled = !aEnable;
|
||||
},
|
||||
|
||||
remove: function() {
|
||||
gEngineView._engineStore.removeEngine(gEngineView.selectedEngine);
|
||||
let index = gEngineView.selectedIndex;
|
||||
gEngineView.rowCountChanged(index, -1);
|
||||
gEngineView.invalidate();
|
||||
gEngineView.selection.select(Math.min(index, gEngineView.lastIndex));
|
||||
gEngineView.ensureRowIsVisible(gEngineView.currentIndex);
|
||||
document.getElementById("engineList").focus();
|
||||
},
|
||||
|
||||
editKeyword: function(aEngine, aNewKeyword) {
|
||||
if (aNewKeyword) {
|
||||
let bduplicate = false;
|
||||
let eduplicate = false;
|
||||
let dupName = "";
|
||||
|
||||
try {
|
||||
let bmserv =
|
||||
Components.classes["@mozilla.org/browser/nav-bookmarks-service;1"]
|
||||
.getService(Components.interfaces.nsINavBookmarksService);
|
||||
if (bmserv.getURIForKeyword(aNewKeyword))
|
||||
bduplicate = true;
|
||||
} catch(ex) {}
|
||||
|
||||
// Check for duplicates in changes we haven't committed yet
|
||||
let engines = gEngineView._engineStore.engines;
|
||||
for each (let engine in engines) {
|
||||
if (engine.alias == aNewKeyword &&
|
||||
engine.name != aEngine.name) {
|
||||
eduplicate = true;
|
||||
dupName = engine.name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Notify the user if they have chosen an existing engine/bookmark keyword
|
||||
if (eduplicate || bduplicate) {
|
||||
let strings = document.getElementById("engineManagerBundle");
|
||||
let dtitle = strings.getString("duplicateTitle");
|
||||
let bmsg = strings.getString("duplicateBookmarkMsg");
|
||||
let emsg = strings.getFormattedString("duplicateEngineMsg", [dupName]);
|
||||
|
||||
Services.prompt.alert(window, dtitle, eduplicate ? emsg : bmsg);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
gEngineView._engineStore.changeEngine(aEngine, "alias", aNewKeyword);
|
||||
gEngineView.invalidate();
|
||||
return true;
|
||||
},
|
||||
|
||||
saveOneClickEnginesList: function () {
|
||||
let richlistbox = document.getElementById("oneClickProvidersList");
|
||||
let hiddenList = [];
|
||||
for (let child of richlistbox.childNodes) {
|
||||
if (!child.checked)
|
||||
hiddenList.push(child.getAttribute("label"));
|
||||
for (let engine of gEngineView._engineStore.engines) {
|
||||
if (!engine.shown)
|
||||
hiddenList.push(engine.name);
|
||||
}
|
||||
document.getElementById("browser.search.hiddenOneOffs").value =
|
||||
hiddenList.join(",");
|
||||
@ -70,6 +179,273 @@ var gSearchPane = {
|
||||
setDefaultEngine: function () {
|
||||
Services.search.currentEngine =
|
||||
document.getElementById("defaultEngine").selectedItem.engine;
|
||||
this.displayOneClickEnginesList();
|
||||
}
|
||||
};
|
||||
|
||||
function onDragEngineStart(event) {
|
||||
var selectedIndex = gEngineView.selectedIndex;
|
||||
if (selectedIndex >= 0) {
|
||||
event.dataTransfer.setData(ENGINE_FLAVOR, selectedIndex.toString());
|
||||
event.dataTransfer.effectAllowed = "move";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function EngineStore() {
|
||||
let pref = document.getElementById("browser.search.hiddenOneOffs").value;
|
||||
this.hiddenList = pref ? pref.split(",") : [];
|
||||
|
||||
this._engines = Services.search.getVisibleEngines().map(this._cloneEngine, this);
|
||||
this._defaultEngines = Services.search.getDefaultEngines().map(this._cloneEngine, this);
|
||||
|
||||
// check if we need to disable the restore defaults button
|
||||
var someHidden = this._defaultEngines.some(function (e) e.hidden);
|
||||
gSearchPane.showRestoreDefaults(someHidden);
|
||||
}
|
||||
EngineStore.prototype = {
|
||||
_engines: null,
|
||||
_defaultEngines: null,
|
||||
|
||||
get engines() {
|
||||
return this._engines;
|
||||
},
|
||||
set engines(val) {
|
||||
this._engines = val;
|
||||
return val;
|
||||
},
|
||||
|
||||
_getIndexForEngine: function ES_getIndexForEngine(aEngine) {
|
||||
return this._engines.indexOf(aEngine);
|
||||
},
|
||||
|
||||
_getEngineByName: function ES_getEngineByName(aName) {
|
||||
for each (var engine in this._engines)
|
||||
if (engine.name == aName)
|
||||
return engine;
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
_cloneEngine: function ES_cloneEngine(aEngine) {
|
||||
var clonedObj={};
|
||||
for (var i in aEngine)
|
||||
clonedObj[i] = aEngine[i];
|
||||
clonedObj.originalEngine = aEngine;
|
||||
clonedObj.shown = this.hiddenList.indexOf(clonedObj.name) == -1;
|
||||
return clonedObj;
|
||||
},
|
||||
|
||||
// Callback for Array's some(). A thisObj must be passed to some()
|
||||
_isSameEngine: function ES_isSameEngine(aEngineClone) {
|
||||
return aEngineClone.originalEngine == this.originalEngine;
|
||||
},
|
||||
|
||||
addEngine: function ES_addEngine(aEngine) {
|
||||
this._engines.push(this._cloneEngine(aEngine));
|
||||
},
|
||||
|
||||
moveEngine: function ES_moveEngine(aEngine, aNewIndex) {
|
||||
if (aNewIndex < 0 || aNewIndex > this._engines.length - 1)
|
||||
throw new Error("ES_moveEngine: invalid aNewIndex!");
|
||||
var index = this._getIndexForEngine(aEngine);
|
||||
if (index == -1)
|
||||
throw new Error("ES_moveEngine: invalid engine?");
|
||||
|
||||
if (index == aNewIndex)
|
||||
return; // nothing to do
|
||||
|
||||
// Move the engine in our internal store
|
||||
var removedEngine = this._engines.splice(index, 1)[0];
|
||||
this._engines.splice(aNewIndex, 0, removedEngine);
|
||||
|
||||
Services.search.moveEngine(aEngine.originalEngine, aNewIndex);
|
||||
},
|
||||
|
||||
removeEngine: function ES_removeEngine(aEngine) {
|
||||
var index = this._getIndexForEngine(aEngine);
|
||||
if (index == -1)
|
||||
throw new Error("invalid engine?");
|
||||
|
||||
this._engines.splice(index, 1);
|
||||
Services.search.removeEngine(aEngine.originalEngine);
|
||||
|
||||
if (this._defaultEngines.some(this._isSameEngine, aEngine))
|
||||
gSearchPane.showRestoreDefaults(true);
|
||||
gSearchPane.buildDefaultEngineDropDown();
|
||||
},
|
||||
|
||||
restoreDefaultEngines: function ES_restoreDefaultEngines() {
|
||||
var added = 0;
|
||||
|
||||
for (var i = 0; i < this._defaultEngines.length; ++i) {
|
||||
var e = this._defaultEngines[i];
|
||||
|
||||
// If the engine is already in the list, just move it.
|
||||
if (this._engines.some(this._isSameEngine, e)) {
|
||||
this.moveEngine(this._getEngineByName(e.name), i);
|
||||
} else {
|
||||
// Otherwise, add it back to our internal store
|
||||
this._engines.splice(i, 0, e);
|
||||
let engine = e.originalEngine;
|
||||
engine.hidden = false;
|
||||
Services.search.moveEngine(engine, i);
|
||||
added++;
|
||||
}
|
||||
}
|
||||
gSearchPane.showRestoreDefaults(false);
|
||||
gSearchPane.buildDefaultEngineDropDown();
|
||||
return added;
|
||||
},
|
||||
|
||||
changeEngine: function ES_changeEngine(aEngine, aProp, aNewValue) {
|
||||
var index = this._getIndexForEngine(aEngine);
|
||||
if (index == -1)
|
||||
throw new Error("invalid engine?");
|
||||
|
||||
this._engines[index][aProp] = aNewValue;
|
||||
aEngine.originalEngine[aProp] = aNewValue;
|
||||
},
|
||||
|
||||
reloadIcons: function ES_reloadIcons() {
|
||||
this._engines.forEach(function (e) {
|
||||
e.uri = e.originalEngine.uri;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function EngineView(aEngineStore) {
|
||||
this._engineStore = aEngineStore;
|
||||
}
|
||||
EngineView.prototype = {
|
||||
_engineStore: null,
|
||||
tree: null,
|
||||
|
||||
get lastIndex() {
|
||||
return this.rowCount - 1;
|
||||
},
|
||||
get selectedIndex() {
|
||||
var seln = this.selection;
|
||||
if (seln.getRangeCount() > 0) {
|
||||
var min = {};
|
||||
seln.getRangeAt(0, min, {});
|
||||
return min.value;
|
||||
}
|
||||
return -1;
|
||||
},
|
||||
get selectedEngine() {
|
||||
return this._engineStore.engines[this.selectedIndex];
|
||||
},
|
||||
|
||||
// Helpers
|
||||
rowCountChanged: function (index, count) {
|
||||
this.tree.rowCountChanged(index, count);
|
||||
},
|
||||
|
||||
invalidate: function () {
|
||||
this.tree.invalidate();
|
||||
},
|
||||
|
||||
ensureRowIsVisible: function (index) {
|
||||
this.tree.ensureRowIsVisible(index);
|
||||
},
|
||||
|
||||
getSourceIndexFromDrag: function (dataTransfer) {
|
||||
return parseInt(dataTransfer.getData(ENGINE_FLAVOR));
|
||||
},
|
||||
|
||||
// nsITreeView
|
||||
get rowCount() {
|
||||
return this._engineStore.engines.length;
|
||||
},
|
||||
|
||||
getImageSrc: function(index, column) {
|
||||
if (column.id == "engineName" && this._engineStore.engines[index].iconURI)
|
||||
return this._engineStore.engines[index].iconURI.spec;
|
||||
return "";
|
||||
},
|
||||
|
||||
getCellText: function(index, column) {
|
||||
if (column.id == "engineName")
|
||||
return this._engineStore.engines[index].name;
|
||||
else if (column.id == "engineKeyword")
|
||||
return this._engineStore.engines[index].alias;
|
||||
return "";
|
||||
},
|
||||
|
||||
setTree: function(tree) {
|
||||
this.tree = tree;
|
||||
},
|
||||
|
||||
canDrop: function(targetIndex, orientation, dataTransfer) {
|
||||
var sourceIndex = this.getSourceIndexFromDrag(dataTransfer);
|
||||
return (sourceIndex != -1 &&
|
||||
sourceIndex != targetIndex &&
|
||||
sourceIndex != targetIndex + orientation);
|
||||
},
|
||||
|
||||
drop: function(dropIndex, orientation, dataTransfer) {
|
||||
var sourceIndex = this.getSourceIndexFromDrag(dataTransfer);
|
||||
var sourceEngine = this._engineStore.engines[sourceIndex];
|
||||
|
||||
const nsITreeView = Components.interfaces.nsITreeView;
|
||||
if (dropIndex > sourceIndex) {
|
||||
if (orientation == nsITreeView.DROP_BEFORE)
|
||||
dropIndex--;
|
||||
} else {
|
||||
if (orientation == nsITreeView.DROP_AFTER)
|
||||
dropIndex++;
|
||||
}
|
||||
|
||||
this._engineStore.moveEngine(sourceEngine, dropIndex);
|
||||
gSearchPane.showRestoreDefaults(true);
|
||||
gSearchPane.buildDefaultEngineDropDown();
|
||||
|
||||
// Redraw, and adjust selection
|
||||
this.invalidate();
|
||||
this.selection.select(dropIndex);
|
||||
},
|
||||
|
||||
selection: null,
|
||||
getRowProperties: function(index) { return ""; },
|
||||
getCellProperties: function(index, column) { return ""; },
|
||||
getColumnProperties: function(column) { return ""; },
|
||||
isContainer: function(index) { return false; },
|
||||
isContainerOpen: function(index) { return false; },
|
||||
isContainerEmpty: function(index) { return false; },
|
||||
isSeparator: function(index) { return false; },
|
||||
isSorted: function(index) { return false; },
|
||||
getParentIndex: function(index) { return -1; },
|
||||
hasNextSibling: function(parentIndex, index) { return false; },
|
||||
getLevel: function(index) { return 0; },
|
||||
getProgressMode: function(index, column) { },
|
||||
getCellValue: function(index, column) {
|
||||
if (column.id == "engineShown")
|
||||
return this._engineStore.engines[index].shown;
|
||||
return undefined;
|
||||
},
|
||||
toggleOpenState: function(index) { },
|
||||
cycleHeader: function(column) { },
|
||||
selectionChanged: function() { },
|
||||
cycleCell: function(row, column) { },
|
||||
isEditable: function(index, column) { return column.id != "engineName"; },
|
||||
isSelectable: function(index, column) { return false; },
|
||||
setCellValue: function(index, column, value) {
|
||||
if (column.id == "engineShown") {
|
||||
this._engineStore.engines[index].shown = value == "true";
|
||||
gEngineView.invalidate();
|
||||
gSearchPane.saveOneClickEnginesList();
|
||||
}
|
||||
},
|
||||
setCellText: function(index, column, value) {
|
||||
if (column.id == "engineKeyword") {
|
||||
if (!gSearchPane.editKeyword(this._engineStore.engines[index], value)) {
|
||||
setTimeout(() => {
|
||||
document.getElementById("engineList").startEditing(index, column);
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
},
|
||||
performAction: function(action) { },
|
||||
performActionOnRow: function(action, index) { },
|
||||
performActionOnCell: function(action, index, column) { }
|
||||
};
|
||||
|
@ -39,8 +39,34 @@
|
||||
<caption label="&oneClickSearchEngines.label;"/>
|
||||
<label>&chooseWhichOneToDisplay.label;</label>
|
||||
|
||||
<richlistbox id="oneClickProvidersList"/>
|
||||
<hbox pack="end">
|
||||
<tree id="engineList" flex="1" rows="8" hidecolumnpicker="true" editable="true"
|
||||
seltype="single" onselect="gSearchPane.onTreeSelect();"
|
||||
onkeypress="gSearchPane.onTreeKeyPress(event);">
|
||||
<treechildren id="engineChildren" flex="1"
|
||||
ondragstart="onDragEngineStart(event);"/>
|
||||
<treecols>
|
||||
<treecol id="engineShown" type="checkbox" style="min-width: 26px;" editable="true"/>
|
||||
<treecol id="engineName" flex="4" label="&engineNameColumn.label;"/>
|
||||
<treecol id="engineKeyword" flex="1" label="&engineKeywordColumn.label;" editable="true"/>
|
||||
</treecols>
|
||||
</tree>
|
||||
|
||||
<hbox>
|
||||
<button id="restoreDefaultSearchEngines"
|
||||
label="&restoreDefaultSearchEngines.label;"
|
||||
accesskey="&restoreDefaultSearchEngines.accesskey;"
|
||||
oncommand="gSearchPane.onRestoreDefaults();"/>
|
||||
<spacer flex="1"/>
|
||||
<button id="removeEngineButton"
|
||||
label="&removeEngine.label;"
|
||||
accesskey="&removeEngine.accesskey;"
|
||||
disabled="true"
|
||||
oncommand="gSearchPane.remove();"/>
|
||||
</hbox>
|
||||
|
||||
<separator class="thin"/>
|
||||
|
||||
<hbox pack="start" style="margin-bottom: 1em">
|
||||
<label id="addEngines" class="text-link" value="&addMoreSearchEngines.label;"
|
||||
onclick="if (event.button == 0) { Services.wm.getMostRecentWindow('navigator:browser').BrowserSearch.loadAddEngines(); }"/>
|
||||
</hbox>
|
||||
|
@ -45,7 +45,6 @@ browser.jar:
|
||||
content/browser/preferences/sync.js
|
||||
#endif
|
||||
content/browser/preferences/search.xul
|
||||
content/browser/preferences/search.css
|
||||
content/browser/preferences/search.js
|
||||
* content/browser/preferences/tabs.xul
|
||||
* content/browser/preferences/tabs.js
|
||||
|
@ -16,7 +16,7 @@
|
||||
-->
|
||||
<?xml-stylesheet href="chrome://browser/content/preferences/handlers.css"?>
|
||||
<?xml-stylesheet href="chrome://browser/skin/preferences/applications.css"?>
|
||||
<?xml-stylesheet href="chrome://browser/content/preferences/search.css"?>
|
||||
<?xml-stylesheet href="chrome://browser/skin/preferences/search.css"?>
|
||||
|
||||
<!DOCTYPE prefwindow [
|
||||
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
|
||||
|
@ -1,29 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#oneClickProvidersList richlistitem {
|
||||
-moz-binding: url("chrome://global/content/bindings/checkbox.xml#checkbox");
|
||||
-moz-padding-start: 5px;
|
||||
height: 22px; /* setting the height of checkboxes is required to let the
|
||||
window auto-sizing code work. */
|
||||
}
|
||||
|
||||
#oneClickProvidersList {
|
||||
height: 178px;
|
||||
}
|
||||
|
||||
.searchengine-menuitem > .menu-iconic-left {
|
||||
display: -moz-box
|
||||
}
|
||||
|
||||
.checkbox-label-box {
|
||||
-moz-box-align: center;
|
||||
-moz-appearance: none;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.checkbox-icon {
|
||||
margin: 3px 3px;
|
||||
max-width: 16px;
|
||||
}
|
@ -4,13 +4,45 @@
|
||||
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
const ENGINE_FLAVOR = "text/x-moz-search-engine";
|
||||
|
||||
var gEngineView = null;
|
||||
|
||||
var gSearchPane = {
|
||||
|
||||
init: function ()
|
||||
{
|
||||
gEngineView = new EngineView(new EngineStore());
|
||||
document.getElementById("engineList").view = gEngineView;
|
||||
this.buildDefaultEngineDropDown();
|
||||
|
||||
Services.obs.addObserver(this, "browser-search-engine-modified", false);
|
||||
window.addEventListener("unload", () => {
|
||||
Services.obs.removeObserver(this, "browser-search-engine-modified", false);
|
||||
});
|
||||
},
|
||||
|
||||
buildDefaultEngineDropDown: function() {
|
||||
// This is called each time something affects the list of engines.
|
||||
let list = document.getElementById("defaultEngine");
|
||||
let currentEngine = Services.search.currentEngine.name;
|
||||
Services.search.getVisibleEngines().forEach(e => {
|
||||
let currentEngine;
|
||||
|
||||
// First, try to preserve the current selection.
|
||||
if (list.selectedItem)
|
||||
currentEngine = list.selectedItem.label;
|
||||
|
||||
// If there's no current selection, use the current default engine.
|
||||
if (!currentEngine)
|
||||
currentEngine = Services.search.currentEngine.name;
|
||||
|
||||
// If the current engine isn't in the list any more, select the first item.
|
||||
let engines = gEngineView._engineStore._engines;
|
||||
if (!engines.some(e => e.name == currentEngine))
|
||||
currentEngine = engines[0].name;
|
||||
|
||||
// Now clean-up and rebuild the list.
|
||||
list.removeAllItems();
|
||||
gEngineView._engineStore._engines.forEach(e => {
|
||||
let item = list.appendItem(e.name);
|
||||
item.setAttribute("class", "menuitem-iconic searchengine-menuitem menuitem-with-favicon");
|
||||
if (e.iconURI)
|
||||
@ -19,50 +51,472 @@ var gSearchPane = {
|
||||
if (e.name == currentEngine)
|
||||
list.selectedItem = item;
|
||||
});
|
||||
|
||||
this.displayOneClickEnginesList();
|
||||
|
||||
document.getElementById("oneClickProvidersList")
|
||||
.addEventListener("CheckboxStateChange", gSearchPane.saveOneClickEnginesList);
|
||||
},
|
||||
|
||||
displayOneClickEnginesList: function () {
|
||||
let richlistbox = document.getElementById("oneClickProvidersList");
|
||||
let pref = document.getElementById("browser.search.hiddenOneOffs").value;
|
||||
let hiddenList = pref ? pref.split(",") : [];
|
||||
observe: function(aEngine, aTopic, aVerb) {
|
||||
if (aTopic == "browser-search-engine-modified") {
|
||||
aEngine.QueryInterface(Components.interfaces.nsISearchEngine);
|
||||
switch (aVerb) {
|
||||
case "engine-added":
|
||||
gEngineView._engineStore.addEngine(aEngine);
|
||||
gEngineView.rowCountChanged(gEngineView.lastIndex, 1);
|
||||
gSearchPane.buildDefaultEngineDropDown();
|
||||
break;
|
||||
case "engine-changed":
|
||||
gEngineView._engineStore.reloadIcons();
|
||||
gEngineView.invalidate();
|
||||
break;
|
||||
case "engine-removed":
|
||||
case "engine-current":
|
||||
case "engine-default":
|
||||
// Not relevant
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
while (richlistbox.firstChild)
|
||||
richlistbox.firstChild.remove();
|
||||
onTreeSelect: function() {
|
||||
document.getElementById("removeEngineButton").disabled =
|
||||
gEngineView.selectedIndex == -1 || gEngineView.lastIndex == 0;
|
||||
},
|
||||
|
||||
let currentEngine = Services.search.currentEngine.name;
|
||||
Services.search.getVisibleEngines().forEach(e => {
|
||||
if (e.name == currentEngine)
|
||||
return;
|
||||
onTreeKeyPress: function(aEvent) {
|
||||
let index = gEngineView.selectedIndex;
|
||||
let tree = document.getElementById("engineList");
|
||||
if (aEvent.charCode == KeyEvent.DOM_VK_SPACE) {
|
||||
// Space toggles the checkbox.
|
||||
let newValue = !gEngineView._engineStore.engines[index].shown;
|
||||
gEngineView.setCellValue(index, tree.columns.getFirstColumn(),
|
||||
newValue.toString());
|
||||
}
|
||||
else {
|
||||
let isMac = Services.appinfo.OS == "Darwin";
|
||||
if ((isMac && aEvent.keyCode == KeyEvent.DOM_VK_RETURN) ||
|
||||
(!isMac && aEvent.keyCode == KeyEvent.DOM_VK_F2))
|
||||
tree.startEditing(index, tree.columns.getLastColumn());
|
||||
}
|
||||
},
|
||||
|
||||
let item = document.createElement("richlistitem");
|
||||
item.setAttribute("label", e.name);
|
||||
if (hiddenList.indexOf(e.name) == -1)
|
||||
item.setAttribute("checked", "true");
|
||||
if (e.iconURI)
|
||||
item.setAttribute("src", e.iconURI.spec);
|
||||
richlistbox.appendChild(item);
|
||||
});
|
||||
onRestoreDefaults: function() {
|
||||
let num = gEngineView._engineStore.restoreDefaultEngines();
|
||||
gEngineView.rowCountChanged(0, num);
|
||||
gEngineView.invalidate();
|
||||
},
|
||||
|
||||
showRestoreDefaults: function(aEnable) {
|
||||
document.getElementById("restoreDefaultSearchEngines").disabled = !aEnable;
|
||||
},
|
||||
|
||||
remove: function() {
|
||||
gEngineView._engineStore.removeEngine(gEngineView.selectedEngine);
|
||||
let index = gEngineView.selectedIndex;
|
||||
gEngineView.rowCountChanged(index, -1);
|
||||
gEngineView.invalidate();
|
||||
gEngineView.selection.select(Math.min(index, gEngineView.lastIndex));
|
||||
gEngineView.ensureRowIsVisible(gEngineView.currentIndex);
|
||||
document.getElementById("engineList").focus();
|
||||
},
|
||||
|
||||
editKeyword: function(aEngine, aNewKeyword) {
|
||||
if (aNewKeyword) {
|
||||
let bduplicate = false;
|
||||
let eduplicate = false;
|
||||
let dupName = "";
|
||||
|
||||
try {
|
||||
let bmserv =
|
||||
Components.classes["@mozilla.org/browser/nav-bookmarks-service;1"]
|
||||
.getService(Components.interfaces.nsINavBookmarksService);
|
||||
if (bmserv.getURIForKeyword(aNewKeyword))
|
||||
bduplicate = true;
|
||||
} catch(ex) {}
|
||||
|
||||
// Check for duplicates in changes we haven't committed yet
|
||||
let engines = gEngineView._engineStore.engines;
|
||||
for each (let engine in engines) {
|
||||
if (engine.alias == aNewKeyword &&
|
||||
engine.name != aEngine.name) {
|
||||
eduplicate = true;
|
||||
dupName = engine.name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Notify the user if they have chosen an existing engine/bookmark keyword
|
||||
if (eduplicate || bduplicate) {
|
||||
let strings = document.getElementById("engineManagerBundle");
|
||||
let dtitle = strings.getString("duplicateTitle");
|
||||
let bmsg = strings.getString("duplicateBookmarkMsg");
|
||||
let emsg = strings.getFormattedString("duplicateEngineMsg", [dupName]);
|
||||
|
||||
Services.prompt.alert(window, dtitle, eduplicate ? emsg : bmsg);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
gEngineView._engineStore.changeEngine(aEngine, "alias", aNewKeyword);
|
||||
gEngineView.invalidate();
|
||||
return true;
|
||||
},
|
||||
|
||||
saveOneClickEnginesList: function () {
|
||||
let richlistbox = document.getElementById("oneClickProvidersList");
|
||||
let hiddenList = [];
|
||||
for (let child of richlistbox.childNodes) {
|
||||
if (!child.checked)
|
||||
hiddenList.push(child.getAttribute("label"));
|
||||
for (let engine of gEngineView._engineStore.engines) {
|
||||
if (!engine.shown)
|
||||
hiddenList.push(engine.name);
|
||||
}
|
||||
document.getElementById("browser.search.hiddenOneOffs").value =
|
||||
hiddenList.join(",");
|
||||
},
|
||||
|
||||
setDefaultEngine: function () {
|
||||
Services.search.currentEngine =
|
||||
document.getElementById("defaultEngine").selectedItem.engine;
|
||||
this.displayOneClickEnginesList();
|
||||
if (document.documentElement.instantApply) {
|
||||
Services.search.currentEngine =
|
||||
document.getElementById("defaultEngine").selectedItem.engine;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function onDragEngineStart(event) {
|
||||
var selectedIndex = gEngineView.selectedIndex;
|
||||
if (selectedIndex >= 0) {
|
||||
event.dataTransfer.setData(ENGINE_FLAVOR, selectedIndex.toString());
|
||||
event.dataTransfer.effectAllowed = "move";
|
||||
}
|
||||
}
|
||||
|
||||
// "Operation" objects
|
||||
function EngineMoveOp(aEngineClone, aNewIndex) {
|
||||
if (!aEngineClone)
|
||||
throw new Error("bad args to new EngineMoveOp!");
|
||||
this._engine = aEngineClone.originalEngine;
|
||||
this._newIndex = aNewIndex;
|
||||
}
|
||||
EngineMoveOp.prototype = {
|
||||
_engine: null,
|
||||
_newIndex: null,
|
||||
commit: function EMO_commit() {
|
||||
Services.search.moveEngine(this._engine, this._newIndex);
|
||||
}
|
||||
};
|
||||
|
||||
function EngineRemoveOp(aEngineClone) {
|
||||
if (!aEngineClone)
|
||||
throw new Error("bad args to new EngineRemoveOp!");
|
||||
this._engine = aEngineClone.originalEngine;
|
||||
}
|
||||
EngineRemoveOp.prototype = {
|
||||
_engine: null,
|
||||
commit: function ERO_commit() {
|
||||
Services.search.removeEngine(this._engine);
|
||||
}
|
||||
};
|
||||
|
||||
function EngineUnhideOp(aEngineClone, aNewIndex) {
|
||||
if (!aEngineClone)
|
||||
throw new Error("bad args to new EngineUnhideOp!");
|
||||
this._engine = aEngineClone.originalEngine;
|
||||
this._newIndex = aNewIndex;
|
||||
}
|
||||
EngineUnhideOp.prototype = {
|
||||
_engine: null,
|
||||
_newIndex: null,
|
||||
commit: function EUO_commit() {
|
||||
this._engine.hidden = false;
|
||||
Services.search.moveEngine(this._engine, this._newIndex);
|
||||
}
|
||||
};
|
||||
|
||||
function EngineChangeOp(aEngineClone, aProp, aValue) {
|
||||
if (!aEngineClone)
|
||||
throw new Error("bad args to new EngineChangeOp!");
|
||||
|
||||
this._engine = aEngineClone.originalEngine;
|
||||
this._prop = aProp;
|
||||
this._newValue = aValue;
|
||||
}
|
||||
EngineChangeOp.prototype = {
|
||||
_engine: null,
|
||||
_prop: null,
|
||||
_newValue: null,
|
||||
commit: function ECO_commit() {
|
||||
this._engine[this._prop] = this._newValue;
|
||||
}
|
||||
};
|
||||
|
||||
function EngineStore() {
|
||||
let pref = document.getElementById("browser.search.hiddenOneOffs").value;
|
||||
this.hiddenList = pref ? pref.split(",") : [];
|
||||
|
||||
this._engines = Services.search.getVisibleEngines().map(this._cloneEngine, this);
|
||||
this._defaultEngines = Services.search.getDefaultEngines().map(this._cloneEngine, this);
|
||||
|
||||
if (document.documentElement.instantApply) {
|
||||
this._ops = {
|
||||
push: function(op) { op.commit(); }
|
||||
};
|
||||
}
|
||||
else {
|
||||
this._ops = [];
|
||||
document.documentElement.addEventListener("beforeaccept", () => {
|
||||
gEngineView._engineStore.commit();
|
||||
});
|
||||
}
|
||||
|
||||
// check if we need to disable the restore defaults button
|
||||
var someHidden = this._defaultEngines.some(function (e) e.hidden);
|
||||
gSearchPane.showRestoreDefaults(someHidden);
|
||||
}
|
||||
EngineStore.prototype = {
|
||||
_engines: null,
|
||||
_defaultEngines: null,
|
||||
_ops: null,
|
||||
|
||||
get engines() {
|
||||
return this._engines;
|
||||
},
|
||||
set engines(val) {
|
||||
this._engines = val;
|
||||
return val;
|
||||
},
|
||||
|
||||
_getIndexForEngine: function ES_getIndexForEngine(aEngine) {
|
||||
return this._engines.indexOf(aEngine);
|
||||
},
|
||||
|
||||
_getEngineByName: function ES_getEngineByName(aName) {
|
||||
for each (var engine in this._engines)
|
||||
if (engine.name == aName)
|
||||
return engine;
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
_cloneEngine: function ES_cloneEngine(aEngine) {
|
||||
var clonedObj={};
|
||||
for (var i in aEngine)
|
||||
clonedObj[i] = aEngine[i];
|
||||
clonedObj.originalEngine = aEngine;
|
||||
clonedObj.shown = this.hiddenList.indexOf(clonedObj.name) == -1;
|
||||
return clonedObj;
|
||||
},
|
||||
|
||||
// Callback for Array's some(). A thisObj must be passed to some()
|
||||
_isSameEngine: function ES_isSameEngine(aEngineClone) {
|
||||
return aEngineClone.originalEngine == this.originalEngine;
|
||||
},
|
||||
|
||||
commit: function ES_commit() {
|
||||
for (op of this._ops)
|
||||
op.commit();
|
||||
|
||||
Services.search.currentEngine =
|
||||
document.getElementById("defaultEngine").selectedItem.engine;
|
||||
},
|
||||
|
||||
addEngine: function ES_addEngine(aEngine) {
|
||||
this._engines.push(this._cloneEngine(aEngine));
|
||||
},
|
||||
|
||||
moveEngine: function ES_moveEngine(aEngine, aNewIndex) {
|
||||
if (aNewIndex < 0 || aNewIndex > this._engines.length - 1)
|
||||
throw new Error("ES_moveEngine: invalid aNewIndex!");
|
||||
var index = this._getIndexForEngine(aEngine);
|
||||
if (index == -1)
|
||||
throw new Error("ES_moveEngine: invalid engine?");
|
||||
|
||||
if (index == aNewIndex)
|
||||
return; // nothing to do
|
||||
|
||||
// Move the engine in our internal store
|
||||
var removedEngine = this._engines.splice(index, 1)[0];
|
||||
this._engines.splice(aNewIndex, 0, removedEngine);
|
||||
|
||||
this._ops.push(new EngineMoveOp(aEngine, aNewIndex));
|
||||
},
|
||||
|
||||
removeEngine: function ES_removeEngine(aEngine) {
|
||||
var index = this._getIndexForEngine(aEngine);
|
||||
if (index == -1)
|
||||
throw new Error("invalid engine?");
|
||||
|
||||
this._engines.splice(index, 1);
|
||||
this._ops.push(new EngineRemoveOp(aEngine));
|
||||
if (this._defaultEngines.some(this._isSameEngine, aEngine))
|
||||
gSearchPane.showRestoreDefaults(true);
|
||||
gSearchPane.buildDefaultEngineDropDown();
|
||||
},
|
||||
|
||||
restoreDefaultEngines: function ES_restoreDefaultEngines() {
|
||||
var added = 0;
|
||||
|
||||
for (var i = 0; i < this._defaultEngines.length; ++i) {
|
||||
var e = this._defaultEngines[i];
|
||||
|
||||
// If the engine is already in the list, just move it.
|
||||
if (this._engines.some(this._isSameEngine, e)) {
|
||||
this.moveEngine(this._getEngineByName(e.name), i);
|
||||
} else {
|
||||
// Otherwise, add it back to our internal store
|
||||
this._engines.splice(i, 0, e);
|
||||
this._ops.push(new EngineUnhideOp(e, i));
|
||||
added++;
|
||||
}
|
||||
}
|
||||
gSearchPane.showRestoreDefaults(false);
|
||||
gSearchPane.buildDefaultEngineDropDown();
|
||||
return added;
|
||||
},
|
||||
|
||||
changeEngine: function ES_changeEngine(aEngine, aProp, aNewValue) {
|
||||
var index = this._getIndexForEngine(aEngine);
|
||||
if (index == -1)
|
||||
throw new Error("invalid engine?");
|
||||
|
||||
this._engines[index][aProp] = aNewValue;
|
||||
this._ops.push(new EngineChangeOp(aEngine, aProp, aNewValue));
|
||||
},
|
||||
|
||||
reloadIcons: function ES_reloadIcons() {
|
||||
this._engines.forEach(function (e) {
|
||||
e.uri = e.originalEngine.uri;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function EngineView(aEngineStore) {
|
||||
this._engineStore = aEngineStore;
|
||||
}
|
||||
EngineView.prototype = {
|
||||
_engineStore: null,
|
||||
tree: null,
|
||||
|
||||
get lastIndex() {
|
||||
return this.rowCount - 1;
|
||||
},
|
||||
get selectedIndex() {
|
||||
var seln = this.selection;
|
||||
if (seln.getRangeCount() > 0) {
|
||||
var min = {};
|
||||
seln.getRangeAt(0, min, {});
|
||||
return min.value;
|
||||
}
|
||||
return -1;
|
||||
},
|
||||
get selectedEngine() {
|
||||
return this._engineStore.engines[this.selectedIndex];
|
||||
},
|
||||
|
||||
// Helpers
|
||||
rowCountChanged: function (index, count) {
|
||||
this.tree.rowCountChanged(index, count);
|
||||
},
|
||||
|
||||
invalidate: function () {
|
||||
this.tree.invalidate();
|
||||
},
|
||||
|
||||
ensureRowIsVisible: function (index) {
|
||||
this.tree.ensureRowIsVisible(index);
|
||||
},
|
||||
|
||||
getSourceIndexFromDrag: function (dataTransfer) {
|
||||
return parseInt(dataTransfer.getData(ENGINE_FLAVOR));
|
||||
},
|
||||
|
||||
// nsITreeView
|
||||
get rowCount() {
|
||||
return this._engineStore.engines.length;
|
||||
},
|
||||
|
||||
getImageSrc: function(index, column) {
|
||||
if (column.id == "engineName" && this._engineStore.engines[index].iconURI)
|
||||
return this._engineStore.engines[index].iconURI.spec;
|
||||
return "";
|
||||
},
|
||||
|
||||
getCellText: function(index, column) {
|
||||
if (column.id == "engineName")
|
||||
return this._engineStore.engines[index].name;
|
||||
else if (column.id == "engineKeyword")
|
||||
return this._engineStore.engines[index].alias;
|
||||
return "";
|
||||
},
|
||||
|
||||
setTree: function(tree) {
|
||||
this.tree = tree;
|
||||
},
|
||||
|
||||
canDrop: function(targetIndex, orientation, dataTransfer) {
|
||||
var sourceIndex = this.getSourceIndexFromDrag(dataTransfer);
|
||||
return (sourceIndex != -1 &&
|
||||
sourceIndex != targetIndex &&
|
||||
sourceIndex != targetIndex + orientation);
|
||||
},
|
||||
|
||||
drop: function(dropIndex, orientation, dataTransfer) {
|
||||
var sourceIndex = this.getSourceIndexFromDrag(dataTransfer);
|
||||
var sourceEngine = this._engineStore.engines[sourceIndex];
|
||||
|
||||
const nsITreeView = Components.interfaces.nsITreeView;
|
||||
if (dropIndex > sourceIndex) {
|
||||
if (orientation == nsITreeView.DROP_BEFORE)
|
||||
dropIndex--;
|
||||
} else {
|
||||
if (orientation == nsITreeView.DROP_AFTER)
|
||||
dropIndex++;
|
||||
}
|
||||
|
||||
this._engineStore.moveEngine(sourceEngine, dropIndex);
|
||||
gSearchPane.showRestoreDefaults(true);
|
||||
gSearchPane.buildDefaultEngineDropDown();
|
||||
|
||||
// Redraw, and adjust selection
|
||||
this.invalidate();
|
||||
this.selection.select(dropIndex);
|
||||
},
|
||||
|
||||
selection: null,
|
||||
getRowProperties: function(index) { return ""; },
|
||||
getCellProperties: function(index, column) { return ""; },
|
||||
getColumnProperties: function(column) { return ""; },
|
||||
isContainer: function(index) { return false; },
|
||||
isContainerOpen: function(index) { return false; },
|
||||
isContainerEmpty: function(index) { return false; },
|
||||
isSeparator: function(index) { return false; },
|
||||
isSorted: function(index) { return false; },
|
||||
getParentIndex: function(index) { return -1; },
|
||||
hasNextSibling: function(parentIndex, index) { return false; },
|
||||
getLevel: function(index) { return 0; },
|
||||
getProgressMode: function(index, column) { },
|
||||
getCellValue: function(index, column) {
|
||||
if (column.id == "engineShown")
|
||||
return this._engineStore.engines[index].shown;
|
||||
return undefined;
|
||||
},
|
||||
toggleOpenState: function(index) { },
|
||||
cycleHeader: function(column) { },
|
||||
selectionChanged: function() { },
|
||||
cycleCell: function(row, column) { },
|
||||
isEditable: function(index, column) { return column.id != "engineName"; },
|
||||
isSelectable: function(index, column) { return false; },
|
||||
setCellValue: function(index, column, value) {
|
||||
if (column.id == "engineShown") {
|
||||
this._engineStore.engines[index].shown = value == "true";
|
||||
gEngineView.invalidate();
|
||||
gSearchPane.saveOneClickEnginesList();
|
||||
}
|
||||
},
|
||||
setCellText: function(index, column, value) {
|
||||
if (column.id == "engineKeyword") {
|
||||
if (!gSearchPane.editKeyword(this._engineStore.engines[index], value)) {
|
||||
setTimeout(() => {
|
||||
document.getElementById("engineList").startEditing(index, column);
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
},
|
||||
performAction: function(action) { },
|
||||
performActionOnRow: function(action, index) { },
|
||||
performActionOnCell: function(action, index, column) { }
|
||||
};
|
||||
|
@ -34,6 +34,8 @@
|
||||
|
||||
<script type="application/javascript" src="chrome://browser/content/preferences/search.js"/>
|
||||
|
||||
<stringbundle id="engineManagerBundle" src="chrome://browser/locale/engineManager.properties"/>
|
||||
|
||||
<!-- Default Search Engine -->
|
||||
<groupbox id="defaultEngineGroup" align="start">
|
||||
<caption label="&defaultSearchEngine.label;"/>
|
||||
@ -51,8 +53,34 @@
|
||||
<caption label="&oneClickSearchEngines.label;"/>
|
||||
<label>&chooseWhichOneToDisplay.label;</label>
|
||||
|
||||
<richlistbox id="oneClickProvidersList"/>
|
||||
<hbox pack="end" style="margin-bottom: 1em">
|
||||
<tree id="engineList" flex="1" rows="8" hidecolumnpicker="true" editable="true"
|
||||
seltype="single" onselect="gSearchPane.onTreeSelect();"
|
||||
onkeypress="gSearchPane.onTreeKeyPress(event);">
|
||||
<treechildren id="engineChildren" flex="1"
|
||||
ondragstart="onDragEngineStart(event);"/>
|
||||
<treecols>
|
||||
<treecol id="engineShown" type="checkbox" style="min-width: 26px;" editable="true"/>
|
||||
<treecol id="engineName" flex="4" label="&engineNameColumn.label;"/>
|
||||
<treecol id="engineKeyword" flex="1" label="&engineKeywordColumn.label;" editable="true"/>
|
||||
</treecols>
|
||||
</tree>
|
||||
|
||||
<hbox>
|
||||
<button id="restoreDefaultSearchEngines"
|
||||
label="&restoreDefaultSearchEngines.label;"
|
||||
accesskey="&restoreDefaultSearchEngines.accesskey;"
|
||||
oncommand="gSearchPane.onRestoreDefaults();"/>
|
||||
<spacer flex="1"/>
|
||||
<button id="removeEngineButton"
|
||||
label="&removeEngine.label;"
|
||||
accesskey="&removeEngine.accesskey;"
|
||||
disabled="true"
|
||||
oncommand="gSearchPane.remove();"/>
|
||||
</hbox>
|
||||
|
||||
<separator class="thin"/>
|
||||
|
||||
<hbox pack="start" style="margin-bottom: 1em">
|
||||
<label id="addEngines" class="text-link" value="&addMoreSearchEngines.label;"
|
||||
onclick="if (event.button == 0) { Services.wm.getMostRecentWindow('navigator:browser').BrowserSearch.loadAddEngines(); }"/>
|
||||
</hbox>
|
||||
|
@ -6,6 +6,7 @@ const {Cc, Ci, Cu} = require("chrome");
|
||||
const {rgbToHsl} = require("devtools/css-color").colorUtils;
|
||||
const {EventEmitter} = Cu.import("resource://gre/modules/devtools/event-emitter.js");
|
||||
const promise = Cu.import("resource://gre/modules/Promise.jsm", {}).Promise;
|
||||
const {setTimeout, clearTimeout} = Cu.import("resource://gre/modules/Timer.jsm", {});
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
@ -546,7 +547,7 @@ Eyedropper.prototype = {
|
||||
* Callback to be called when the color is in the clipboard.
|
||||
*/
|
||||
copyColor: function(callback) {
|
||||
Services.appShell.hiddenDOMWindow.clearTimeout(this._copyTimeout);
|
||||
clearTimeout(this._copyTimeout);
|
||||
|
||||
let color = this._colorValue.value;
|
||||
clipboardHelper.copyString(color);
|
||||
@ -554,7 +555,7 @@ Eyedropper.prototype = {
|
||||
this._colorValue.classList.add("highlight");
|
||||
this._colorValue.value = "✓ " + l10n.GetStringFromName("colorValue.copied");
|
||||
|
||||
this._copyTimeout = Services.appShell.hiddenDOMWindow.setTimeout(() => {
|
||||
this._copyTimeout = setTimeout(() => {
|
||||
this._colorValue.classList.remove("highlight");
|
||||
this._colorValue.value = color;
|
||||
|
||||
|
@ -14,6 +14,7 @@ const promise = require("projecteditor/helpers/promise");
|
||||
const { on, forget } = require("projecteditor/helpers/event");
|
||||
const { FileResource } = require("projecteditor/stores/resource");
|
||||
const {Services} = Cu.import("resource://gre/modules/Services.jsm");
|
||||
const {setTimeout, clearTimeout} = Cu.import("resource://gre/modules/Timer.jsm", {});
|
||||
|
||||
const CHECK_LINKED_DIRECTORY_DELAY = 5000;
|
||||
const SHOULD_LIVE_REFRESH = true;
|
||||
@ -35,7 +36,6 @@ var LocalStore = Class({
|
||||
|
||||
initialize: function(path) {
|
||||
this.initStore();
|
||||
this.window = Services.appShell.hiddenDOMWindow;
|
||||
this.path = OS.Path.normalize(path);
|
||||
this.rootPath = this.path;
|
||||
this.displayName = this.path;
|
||||
@ -46,9 +46,8 @@ var LocalStore = Class({
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
if (this.window) {
|
||||
this.window.clearTimeout(this._refreshTimeout);
|
||||
}
|
||||
clearTimeout(this._refreshTimeout);
|
||||
|
||||
if (this._refreshDeferred) {
|
||||
this._refreshDeferred.reject("destroy");
|
||||
}
|
||||
@ -58,7 +57,6 @@ var LocalStore = Class({
|
||||
|
||||
this._refreshTimeout = null;
|
||||
this._refreshDeferred = null;
|
||||
this.window = null;
|
||||
this.worker = null;
|
||||
|
||||
if (this.root) {
|
||||
@ -132,7 +130,7 @@ var LocalStore = Class({
|
||||
// XXX: Once Bug 958280 adds a watch function, will not need to forever loop here.
|
||||
this.refresh().then(() => {
|
||||
if (SHOULD_LIVE_REFRESH) {
|
||||
this._refreshTimeout = this.window.setTimeout(this.refreshLoop,
|
||||
this._refreshTimeout = setTimeout(this.refreshLoop,
|
||||
CHECK_LINKED_DIRECTORY_DELAY);
|
||||
}
|
||||
});
|
||||
|
@ -17,7 +17,7 @@ function test() {
|
||||
waitForFocus(init, content);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,browser_css_color.js";
|
||||
content.location = "data:text/html;charset=utf-8,browser_css_color.js";
|
||||
}
|
||||
|
||||
function init() {
|
||||
|
@ -2822,32 +2822,10 @@ TextPropertyEditor.prototype = {
|
||||
* Validate this property. Does it make sense for this value to be assigned
|
||||
* to this property name? This does not apply the property value
|
||||
*
|
||||
* @param {string} [aValue]
|
||||
* The property value used for validation.
|
||||
* Defaults to the current value for this.prop
|
||||
*
|
||||
* @return {bool} true if the property value is valid, false otherwise.
|
||||
*/
|
||||
isValid: function(aValue) {
|
||||
let name = this.prop.name;
|
||||
let value = typeof aValue == "undefined" ? this.prop.value : aValue;
|
||||
let val = parseSingleValue(value);
|
||||
|
||||
let style = this.doc.createElementNS(HTML_NS, "div").style;
|
||||
let prefs = Services.prefs;
|
||||
|
||||
// We toggle output of errors whilst the user is typing a property value.
|
||||
let prefVal = prefs.getBoolPref("layout.css.report_errors");
|
||||
prefs.setBoolPref("layout.css.report_errors", false);
|
||||
|
||||
let validValue = false;
|
||||
try {
|
||||
style.setProperty(name, val.value, val.priority);
|
||||
validValue = style.getPropertyValue(name) !== "" || val.value === "";
|
||||
} finally {
|
||||
prefs.setBoolPref("layout.css.report_errors", prefVal);
|
||||
}
|
||||
return validValue;
|
||||
isValid: function() {
|
||||
return domUtils.cssPropertyIsValid(this.prop.name, this.prop.value);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1159,6 +1159,7 @@ this.UITour = {
|
||||
let tooltipTitle = document.getElementById("UITourTooltipTitle");
|
||||
let tooltipDesc = document.getElementById("UITourTooltipDescription");
|
||||
let tooltipIcon = document.getElementById("UITourTooltipIcon");
|
||||
let tooltipIconContainer = document.getElementById("UITourTooltipIconContainer");
|
||||
let tooltipButtons = document.getElementById("UITourTooltipButtons");
|
||||
|
||||
if (tooltip.state == "showing" || tooltip.state == "open") {
|
||||
@ -1168,7 +1169,7 @@ this.UITour = {
|
||||
tooltipTitle.textContent = aTitle || "";
|
||||
tooltipDesc.textContent = aDescription || "";
|
||||
tooltipIcon.src = aIconURL || "";
|
||||
tooltipIcon.hidden = !aIconURL;
|
||||
tooltipIconContainer.hidden = !aIconURL;
|
||||
|
||||
while (tooltipButtons.firstChild)
|
||||
tooltipButtons.firstChild.remove();
|
||||
|
@ -1,160 +1,221 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
let gTestTab;
|
||||
let gContentAPI;
|
||||
let gContentWindow;
|
||||
let loopButton;
|
||||
let loopPanel = document.getElementById("loop-notification-panel");
|
||||
|
||||
Components.utils.import("resource:///modules/UITour.jsm");
|
||||
const { LoopRooms } = Components.utils.import("resource:///modules/loop/LoopRooms.jsm", {});
|
||||
|
||||
function test() {
|
||||
UITourTest();
|
||||
}
|
||||
|
||||
let tests = [
|
||||
taskify(function* test_menu_show_hide() {
|
||||
ise(loopButton.open, false, "Menu should initially be closed");
|
||||
gContentAPI.showMenu("loop");
|
||||
|
||||
yield waitForConditionPromise(() => {
|
||||
return loopButton.open;
|
||||
}, "Menu should be visible after showMenu()");
|
||||
|
||||
ok(loopPanel.hasAttribute("noautohide"), "@noautohide should be on the loop panel");
|
||||
ok(loopPanel.hasAttribute("panelopen"), "The panel should have @panelopen");
|
||||
is(loopPanel.state, "open", "The panel should be open");
|
||||
ok(loopButton.hasAttribute("open"), "Loop button should know that the menu is open");
|
||||
|
||||
gContentAPI.hideMenu("loop");
|
||||
yield waitForConditionPromise(() => {
|
||||
return !loopButton.open;
|
||||
}, "Menu should be hidden after hideMenu()");
|
||||
|
||||
checkLoopPanelIsHidden();
|
||||
}),
|
||||
// Test the menu was cleaned up in teardown.
|
||||
taskify(function* setup_menu_cleanup() {
|
||||
gContentAPI.showMenu("loop");
|
||||
|
||||
yield waitForConditionPromise(() => {
|
||||
return loopButton.open;
|
||||
}, "Menu should be visible after showMenu()");
|
||||
|
||||
// Leave it open so it gets torn down and we can test below that teardown was succesful.
|
||||
}),
|
||||
taskify(function* test_menu_cleanup() {
|
||||
// Test that the open menu from above was torn down fully.
|
||||
checkLoopPanelIsHidden();
|
||||
}),
|
||||
function test_availableTargets(done) {
|
||||
gContentAPI.showMenu("loop");
|
||||
gContentAPI.getConfiguration("availableTargets", (data) => {
|
||||
for (let targetName of ["loop-newRoom", "loop-roomList", "loop-signInUpLink"]) {
|
||||
isnot(data.targets.indexOf(targetName), -1, targetName + " should exist");
|
||||
}
|
||||
done();
|
||||
});
|
||||
},
|
||||
function test_hideMenuHidesAnnotations(done) {
|
||||
let infoPanel = document.getElementById("UITourTooltip");
|
||||
let highlightPanel = document.getElementById("UITourHighlightContainer");
|
||||
|
||||
gContentAPI.showMenu("loop", function menuCallback() {
|
||||
gContentAPI.showHighlight("loop-roomList");
|
||||
gContentAPI.showInfo("loop-newRoom", "Make a new room", "AKA. conversation");
|
||||
UITour.getTarget(window, "loop-newRoom").then((target) => {
|
||||
waitForPopupAtAnchor(infoPanel, target.node, Task.async(function* checkPanelIsOpen() {
|
||||
isnot(loopPanel.state, "closed", "Loop panel should still be open");
|
||||
ok(loopPanel.hasAttribute("noautohide"), "@noautohide should still be on the loop panel");
|
||||
is(highlightPanel.getAttribute("targetName"), "loop-roomList", "Check highlight @targetname");
|
||||
is(infoPanel.getAttribute("targetName"), "loop-newRoom", "Check info panel @targetname");
|
||||
|
||||
info("Close the loop menu and make sure the annotations inside disappear");
|
||||
let hiddenPromises = [promisePanelElementHidden(window, infoPanel),
|
||||
promisePanelElementHidden(window, highlightPanel)];
|
||||
gContentAPI.hideMenu("loop");
|
||||
yield Promise.all(hiddenPromises);
|
||||
isnot(infoPanel.state, "open", "Info panel should have automatically hid");
|
||||
isnot(highlightPanel.state, "open", "Highlight panel should have automatically hid");
|
||||
done();
|
||||
}), "Info panel should be anchored to the new room button");
|
||||
});
|
||||
});
|
||||
},
|
||||
function test_notifyLoopChatWindowOpenedClosed(done) {
|
||||
gContentAPI.observe((event, params) => {
|
||||
is(event, "Loop:ChatWindowOpened", "Check Loop:ChatWindowOpened notification");
|
||||
gContentAPI.observe((event, params) => {
|
||||
is(event, "Loop:ChatWindowShown", "Check Loop:ChatWindowShown notification");
|
||||
gContentAPI.observe((event, params) => {
|
||||
is(event, "Loop:ChatWindowClosed", "Check Loop:ChatWindowClosed notification");
|
||||
gContentAPI.observe((event, params) => {
|
||||
ok(false, "No more notifications should have arrived");
|
||||
});
|
||||
});
|
||||
done();
|
||||
});
|
||||
document.querySelector("#pinnedchats > chatbox").close();
|
||||
});
|
||||
LoopRooms.open("fakeTourRoom");
|
||||
},
|
||||
taskify(function* test_arrow_panel_position() {
|
||||
ise(loopButton.open, false, "Menu should initially be closed");
|
||||
let popup = document.getElementById("UITourTooltip");
|
||||
|
||||
yield showMenuPromise("loop");
|
||||
|
||||
let currentTarget = "loop-newRoom";
|
||||
yield showInfoPromise(currentTarget, "This is " + currentTarget, "My arrow should be on the side");
|
||||
is(popup.popupBoxObject.alignmentPosition, "start_before", "Check " + currentTarget + " position");
|
||||
|
||||
currentTarget = "loop-roomList";
|
||||
yield showInfoPromise(currentTarget, "This is " + currentTarget, "My arrow should be on the side");
|
||||
is(popup.popupBoxObject.alignmentPosition, "start_before", "Check " + currentTarget + " position");
|
||||
|
||||
currentTarget = "loop-signInUpLink";
|
||||
yield showInfoPromise(currentTarget, "This is " + currentTarget, "My arrow should be underneath");
|
||||
is(popup.popupBoxObject.alignmentPosition, "after_end", "Check " + currentTarget + " position");
|
||||
}),
|
||||
];
|
||||
|
||||
// End tests
|
||||
|
||||
function checkLoopPanelIsHidden() {
|
||||
ok(!loopPanel.hasAttribute("noautohide"), "@noautohide on the loop panel should have been cleaned up");
|
||||
ok(!loopPanel.hasAttribute("panelopen"), "The panel shouldn't have @panelopen");
|
||||
isnot(loopPanel.state, "open", "The panel shouldn't be open");
|
||||
is(loopButton.hasAttribute("open"), false, "Loop button should know that the panel is closed");
|
||||
}
|
||||
|
||||
if (Services.prefs.getBoolPref("loop.enabled")) {
|
||||
loopButton = window.LoopUI.toolbarButton.node;
|
||||
// The targets to highlight only appear after getting started is launched.
|
||||
Services.prefs.setBoolPref("loop.gettingStarted.seen", true);
|
||||
Services.prefs.setCharPref("loop.server", "http://localhost");
|
||||
Services.prefs.setCharPref("services.push.serverURL", "ws://localhost/");
|
||||
|
||||
registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref("loop.gettingStarted.seen");
|
||||
Services.prefs.clearUserPref("loop.server");
|
||||
Services.prefs.clearUserPref("services.push.serverURL");
|
||||
|
||||
// Copied from browser/components/loop/test/mochitest/head.js
|
||||
// Remove the iframe after each test. This also avoids mochitest complaining
|
||||
// about leaks on shutdown as we intentionally hold the iframe open for the
|
||||
// life of the application.
|
||||
let frameId = loopButton.getAttribute("notificationFrameId");
|
||||
let frame = document.getElementById(frameId);
|
||||
if (frame) {
|
||||
frame.remove();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
ok(true, "Loop is disabled so skip the UITour Loop tests");
|
||||
tests = [];
|
||||
}
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
let gTestTab;
|
||||
let gContentAPI;
|
||||
let gContentWindow;
|
||||
let loopButton;
|
||||
let loopPanel = document.getElementById("loop-notification-panel");
|
||||
|
||||
Components.utils.import("resource:///modules/UITour.jsm");
|
||||
const { LoopRooms } = Components.utils.import("resource:///modules/loop/LoopRooms.jsm", {});
|
||||
|
||||
function test() {
|
||||
UITourTest();
|
||||
}
|
||||
|
||||
let tests = [
|
||||
taskify(function* test_menu_show_hide() {
|
||||
ise(loopButton.open, false, "Menu should initially be closed");
|
||||
gContentAPI.showMenu("loop");
|
||||
|
||||
yield waitForConditionPromise(() => {
|
||||
return loopButton.open;
|
||||
}, "Menu should be visible after showMenu()");
|
||||
|
||||
ok(loopPanel.hasAttribute("noautohide"), "@noautohide should be on the loop panel");
|
||||
ok(loopPanel.hasAttribute("panelopen"), "The panel should have @panelopen");
|
||||
is(loopPanel.state, "open", "The panel should be open");
|
||||
ok(loopButton.hasAttribute("open"), "Loop button should know that the menu is open");
|
||||
|
||||
gContentAPI.hideMenu("loop");
|
||||
yield waitForConditionPromise(() => {
|
||||
return !loopButton.open;
|
||||
}, "Menu should be hidden after hideMenu()");
|
||||
|
||||
checkLoopPanelIsHidden();
|
||||
}),
|
||||
// Test the menu was cleaned up in teardown.
|
||||
taskify(function* setup_menu_cleanup() {
|
||||
gContentAPI.showMenu("loop");
|
||||
|
||||
yield waitForConditionPromise(() => {
|
||||
return loopButton.open;
|
||||
}, "Menu should be visible after showMenu()");
|
||||
|
||||
// Leave it open so it gets torn down and we can test below that teardown was succesful.
|
||||
}),
|
||||
taskify(function* test_menu_cleanup() {
|
||||
// Test that the open menu from above was torn down fully.
|
||||
checkLoopPanelIsHidden();
|
||||
}),
|
||||
function test_availableTargets(done) {
|
||||
gContentAPI.showMenu("loop");
|
||||
gContentAPI.getConfiguration("availableTargets", (data) => {
|
||||
for (let targetName of ["loop-newRoom", "loop-roomList", "loop-signInUpLink"]) {
|
||||
isnot(data.targets.indexOf(targetName), -1, targetName + " should exist");
|
||||
}
|
||||
done();
|
||||
});
|
||||
},
|
||||
function test_hideMenuHidesAnnotations(done) {
|
||||
let infoPanel = document.getElementById("UITourTooltip");
|
||||
let highlightPanel = document.getElementById("UITourHighlightContainer");
|
||||
|
||||
gContentAPI.showMenu("loop", function menuCallback() {
|
||||
gContentAPI.showHighlight("loop-roomList");
|
||||
gContentAPI.showInfo("loop-newRoom", "Make a new room", "AKA. conversation");
|
||||
UITour.getTarget(window, "loop-newRoom").then((target) => {
|
||||
waitForPopupAtAnchor(infoPanel, target.node, Task.async(function* checkPanelIsOpen() {
|
||||
isnot(loopPanel.state, "closed", "Loop panel should still be open");
|
||||
ok(loopPanel.hasAttribute("noautohide"), "@noautohide should still be on the loop panel");
|
||||
is(highlightPanel.getAttribute("targetName"), "loop-roomList", "Check highlight @targetname");
|
||||
is(infoPanel.getAttribute("targetName"), "loop-newRoom", "Check info panel @targetname");
|
||||
|
||||
info("Close the loop menu and make sure the annotations inside disappear");
|
||||
let hiddenPromises = [promisePanelElementHidden(window, infoPanel),
|
||||
promisePanelElementHidden(window, highlightPanel)];
|
||||
gContentAPI.hideMenu("loop");
|
||||
yield Promise.all(hiddenPromises);
|
||||
isnot(infoPanel.state, "open", "Info panel should have automatically hid");
|
||||
isnot(highlightPanel.state, "open", "Highlight panel should have automatically hid");
|
||||
done();
|
||||
}), "Info panel should be anchored to the new room button");
|
||||
});
|
||||
});
|
||||
},
|
||||
function test_notifyLoopChatWindowOpenedClosed(done) {
|
||||
gContentAPI.observe((event, params) => {
|
||||
is(event, "Loop:ChatWindowOpened", "Check Loop:ChatWindowOpened notification");
|
||||
gContentAPI.observe((event, params) => {
|
||||
is(event, "Loop:ChatWindowShown", "Check Loop:ChatWindowShown notification");
|
||||
gContentAPI.observe((event, params) => {
|
||||
is(event, "Loop:ChatWindowClosed", "Check Loop:ChatWindowClosed notification");
|
||||
gContentAPI.observe((event, params) => {
|
||||
ok(false, "No more notifications should have arrived");
|
||||
});
|
||||
});
|
||||
done();
|
||||
});
|
||||
document.querySelector("#pinnedchats > chatbox").close();
|
||||
});
|
||||
LoopRooms.open("fakeTourRoom");
|
||||
},
|
||||
function test_notifyLoopRoomURLCopied(done) {
|
||||
gContentAPI.observe((event, params) => {
|
||||
is(event, "Loop:ChatWindowOpened", "Loop chat window should've opened");
|
||||
gContentAPI.observe((event, params) => {
|
||||
is(event, "Loop:ChatWindowShown", "Check Loop:ChatWindowShown notification");
|
||||
|
||||
let chat = document.querySelector("#pinnedchats > chatbox");
|
||||
gContentAPI.observe((event, params) => {
|
||||
is(event, "Loop:RoomURLCopied", "Check Loop:RoomURLCopied notification");
|
||||
gContentAPI.observe((event, params) => {
|
||||
is(event, "Loop:ChatWindowClosed", "Check Loop:ChatWindowClosed notification");
|
||||
});
|
||||
chat.close();
|
||||
done();
|
||||
});
|
||||
chat.content.contentDocument.querySelector(".btn-copy").click();
|
||||
});
|
||||
});
|
||||
setupFakeRoom();
|
||||
LoopRooms.open("fakeTourRoom");
|
||||
},
|
||||
function test_notifyLoopRoomURLEmailed(done) {
|
||||
gContentAPI.observe((event, params) => {
|
||||
is(event, "Loop:ChatWindowOpened", "Loop chat window should've opened");
|
||||
gContentAPI.observe((event, params) => {
|
||||
is(event, "Loop:ChatWindowShown", "Check Loop:ChatWindowShown notification");
|
||||
|
||||
let chat = document.querySelector("#pinnedchats > chatbox");
|
||||
let composeEmailCalled = false;
|
||||
|
||||
gContentAPI.observe((event, params) => {
|
||||
is(event, "Loop:RoomURLEmailed", "Check Loop:RoomURLEmailed notification");
|
||||
ok(composeEmailCalled, "mozLoop.composeEmail should be called");
|
||||
gContentAPI.observe((event, params) => {
|
||||
is(event, "Loop:ChatWindowClosed", "Check Loop:ChatWindowClosed notification");
|
||||
});
|
||||
chat.close();
|
||||
done();
|
||||
});
|
||||
|
||||
let chatWin = chat.content.contentWindow;
|
||||
let oldComposeEmail = chatWin.navigator.wrappedJSObject.mozLoop.composeEmail;
|
||||
chatWin.navigator.wrappedJSObject.mozLoop.composeEmail = function(recipient, subject, body) {
|
||||
ok(recipient, "composeEmail should be invoked with at least a recipient value");
|
||||
composeEmailCalled = true;
|
||||
chatWin.navigator.wrappedJSObject.mozLoop.composeEmail = oldComposeEmail;
|
||||
};
|
||||
chatWin.document.querySelector(".btn-email").click();
|
||||
});
|
||||
});
|
||||
LoopRooms.open("fakeTourRoom");
|
||||
},
|
||||
taskify(function* test_arrow_panel_position() {
|
||||
ise(loopButton.open, false, "Menu should initially be closed");
|
||||
let popup = document.getElementById("UITourTooltip");
|
||||
|
||||
yield showMenuPromise("loop");
|
||||
|
||||
let currentTarget = "loop-newRoom";
|
||||
yield showInfoPromise(currentTarget, "This is " + currentTarget, "My arrow should be on the side");
|
||||
is(popup.popupBoxObject.alignmentPosition, "start_before", "Check " + currentTarget + " position");
|
||||
|
||||
currentTarget = "loop-roomList";
|
||||
yield showInfoPromise(currentTarget, "This is " + currentTarget, "My arrow should be on the side");
|
||||
is(popup.popupBoxObject.alignmentPosition, "start_before", "Check " + currentTarget + " position");
|
||||
|
||||
currentTarget = "loop-signInUpLink";
|
||||
yield showInfoPromise(currentTarget, "This is " + currentTarget, "My arrow should be underneath");
|
||||
is(popup.popupBoxObject.alignmentPosition, "after_end", "Check " + currentTarget + " position");
|
||||
}),
|
||||
];
|
||||
|
||||
// End tests
|
||||
|
||||
function checkLoopPanelIsHidden() {
|
||||
ok(!loopPanel.hasAttribute("noautohide"), "@noautohide on the loop panel should have been cleaned up");
|
||||
ok(!loopPanel.hasAttribute("panelopen"), "The panel shouldn't have @panelopen");
|
||||
isnot(loopPanel.state, "open", "The panel shouldn't be open");
|
||||
is(loopButton.hasAttribute("open"), false, "Loop button should know that the panel is closed");
|
||||
}
|
||||
|
||||
function setupFakeRoom() {
|
||||
let room = {};
|
||||
for (let prop of ["roomToken", "roomName", "roomOwner", "roomUrl", "participants"])
|
||||
room[prop] = "fakeTourRoom";
|
||||
LoopRooms.stubCache(new Map([
|
||||
[room.roomToken, room]
|
||||
]));
|
||||
}
|
||||
|
||||
if (Services.prefs.getBoolPref("loop.enabled")) {
|
||||
loopButton = window.LoopUI.toolbarButton.node;
|
||||
// The targets to highlight only appear after getting started is launched.
|
||||
Services.prefs.setBoolPref("loop.gettingStarted.seen", true);
|
||||
Services.prefs.setCharPref("loop.server", "http://localhost");
|
||||
Services.prefs.setCharPref("services.push.serverURL", "ws://localhost/");
|
||||
|
||||
registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref("loop.gettingStarted.seen");
|
||||
Services.prefs.clearUserPref("loop.server");
|
||||
Services.prefs.clearUserPref("services.push.serverURL");
|
||||
|
||||
// Copied from browser/components/loop/test/mochitest/head.js
|
||||
// Remove the iframe after each test. This also avoids mochitest complaining
|
||||
// about leaks on shutdown as we intentionally hold the iframe open for the
|
||||
// life of the application.
|
||||
let frameId = loopButton.getAttribute("notificationFrameId");
|
||||
let frame = document.getElementById(frameId);
|
||||
if (frame) {
|
||||
frame.remove();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
ok(true, "Loop is disabled so skip the UITour Loop tests");
|
||||
tests = [];
|
||||
}
|
||||
|
@ -167,8 +167,12 @@ browser.jar:
|
||||
skin/classic/browser/preferences/in-content/favicon.ico (../shared/incontentprefs/favicon.ico)
|
||||
skin/classic/browser/preferences/in-content/icons.png (../shared/incontentprefs/icons.png)
|
||||
skin/classic/browser/preferences/in-content/icons@2x.png (../shared/incontentprefs/icons@2x.png)
|
||||
skin/classic/browser/preferences/in-content/search.css (../shared/incontentprefs/search.css)
|
||||
skin/classic/browser/preferences/in-content/check.png (../shared/incontentprefs/check.png)
|
||||
skin/classic/browser/preferences/in-content/check@2x.png (../shared/incontentprefs/check@2x.png)
|
||||
skin/classic/browser/preferences/applications.css (preferences/applications.css)
|
||||
skin/classic/browser/preferences/aboutPermissions.css (preferences/aboutPermissions.css)
|
||||
skin/classic/browser/preferences/search.css (preferences/search.css)
|
||||
skin/classic/browser/social/services-16.png (social/services-16.png)
|
||||
skin/classic/browser/social/services-64.png (social/services-64.png)
|
||||
skin/classic/browser/social/share-button.png (social/share-button.png)
|
||||
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.3 KiB |
39
browser/themes/linux/preferences/search.css
Normal file
@ -0,0 +1,39 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#defaultEngine > .menulist-label-box > .menulist-icon {
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
/* work around a display: none in Linux's menu.css, see bug 1112310 */
|
||||
.searchengine-menuitem > .menu-iconic-left {
|
||||
display: -moz-box;
|
||||
}
|
||||
|
||||
#engineList {
|
||||
margin: .5em 6px;
|
||||
}
|
||||
|
||||
#engineList treechildren::-moz-tree-checkbox(checked) {
|
||||
list-style-image: url("chrome://global/skin/checkbox/cbox-check.gif");
|
||||
}
|
||||
|
||||
#engineList treechildren::-moz-tree-image(engineName) {
|
||||
-moz-margin-end: 4px;
|
||||
-moz-margin-start: 0;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
#engineList treechildren::-moz-tree-row {
|
||||
min-height: 20px;
|
||||
}
|
||||
|
||||
#engineList treechildren::-moz-tree-drop-feedback {
|
||||
background-color: Highlight;
|
||||
width: 10000px; /* 100% doesn't work; 10k is hopefully larger than any window
|
||||
we may have, overflow isn't visible. */
|
||||
height: 2px;
|
||||
-moz-margin-start: 0;
|
||||
}
|
@ -271,8 +271,16 @@ browser.jar:
|
||||
skin/classic/browser/preferences/in-content/favicon.ico (../shared/incontentprefs/favicon.ico)
|
||||
skin/classic/browser/preferences/in-content/icons.png (../shared/incontentprefs/icons.png)
|
||||
skin/classic/browser/preferences/in-content/icons@2x.png (../shared/incontentprefs/icons@2x.png)
|
||||
skin/classic/browser/preferences/in-content/search.css (../shared/incontentprefs/search.css)
|
||||
skin/classic/browser/preferences/in-content/check.png (../shared/incontentprefs/check.png)
|
||||
skin/classic/browser/preferences/in-content/check@2x.png (../shared/incontentprefs/check@2x.png)
|
||||
skin/classic/browser/preferences/applications.css (preferences/applications.css)
|
||||
skin/classic/browser/preferences/aboutPermissions.css (preferences/aboutPermissions.css)
|
||||
skin/classic/browser/preferences/search.css (preferences/search.css)
|
||||
skin/classic/browser/preferences/checkbox.png (preferences/checkbox.png)
|
||||
skin/classic/browser/preferences/checkbox@2x.png (preferences/checkbox@2x.png)
|
||||
skin/classic/browser/yosemite/preferences/checkbox.png (preferences/checkbox-yosemite.png)
|
||||
skin/classic/browser/yosemite/preferences/checkbox@2x.png (preferences/checkbox-yosemite@2x.png)
|
||||
skin/classic/browser/social/services-16.png (social/services-16.png)
|
||||
skin/classic/browser/social/services-16@2x.png (social/services-16@2x.png)
|
||||
skin/classic/browser/social/services-64.png (social/services-64.png)
|
||||
@ -588,6 +596,8 @@ browser.jar:
|
||||
% override chrome://browser/skin/menuPanel-help@2x.png chrome://browser/skin/yosemite/menuPanel-help@2x.png os=Darwin osversion>=10.10
|
||||
% override chrome://browser/skin/menuPanel-small.png chrome://browser/skin/yosemite/menuPanel-small.png os=Darwin osversion>=10.10
|
||||
% override chrome://browser/skin/menuPanel-small@2x.png chrome://browser/skin/yosemite/menuPanel-small@2x.png os=Darwin osversion>=10.10
|
||||
% override chrome://browser/skin/preferences/checkbox.png chrome://browser/skin/yosemite/preferences/checkbox.png os=Darwin osversion>=10.10
|
||||
% override chrome://browser/skin/preferences/checkbox@2x.png chrome://browser/skin/yosemite/preferences/checkbox@2x.png os=Darwin osversion>=10.10
|
||||
% override chrome://browser/skin/reload-stop-go.png chrome://browser/skin/yosemite/reload-stop-go.png os=Darwin osversion>=10.10
|
||||
% override chrome://browser/skin/reload-stop-go@2x.png chrome://browser/skin/yosemite/reload-stop-go@2x.png os=Darwin osversion>=10.10
|
||||
% override chrome://browser/skin/sync-horizontalbar.png chrome://browser/skin/yosemite/sync-horizontalbar.png os=Darwin osversion>=10.10
|
||||
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 9.5 KiB |
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.0 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 5.9 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
BIN
browser/themes/osx/preferences/checkbox-yosemite.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
browser/themes/osx/preferences/checkbox-yosemite@2x.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
browser/themes/osx/preferences/checkbox.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
browser/themes/osx/preferences/checkbox@2x.png
Normal file
After Width: | Height: | Size: 3.6 KiB |
54
browser/themes/osx/preferences/search.css
Normal file
@ -0,0 +1,54 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#defaultEngine > .menulist-label-box > .menulist-icon {
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
#engineList {
|
||||
margin: .5em 6px;
|
||||
}
|
||||
|
||||
#engineList treechildren::-moz-tree-image(engineShown) {
|
||||
list-style-image: url("chrome://browser/skin/preferences/checkbox.png");
|
||||
-moz-image-region: rect(0, 16px, 16px, 0);
|
||||
-moz-margin-start: 4px;
|
||||
-moz-margin-end: 1px;
|
||||
}
|
||||
|
||||
#engineList treechildren::-moz-tree-image(engineShown, checked) {
|
||||
-moz-image-region: rect(0, 48px, 16px, 32px);
|
||||
}
|
||||
|
||||
@media (min-resolution: 2dppx) {
|
||||
#engineList treechildren::-moz-tree-image(engineShown) {
|
||||
list-style-image: url("chrome://browser/skin/preferences/checkbox@2x.png");
|
||||
-moz-image-region: rect(0, 32px, 32px, 0);
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
#engineList treechildren::-moz-tree-image(engineShown, checked) {
|
||||
-moz-image-region: rect(0, 96px, 32px, 64px);
|
||||
}
|
||||
}
|
||||
|
||||
#engineList treechildren::-moz-tree-image(engineName) {
|
||||
-moz-margin-end: 4px;
|
||||
-moz-margin-start: 1px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
#engineList treechildren::-moz-tree-row {
|
||||
min-height: 20px;
|
||||
}
|
||||
|
||||
#engineList treechildren::-moz-tree-drop-feedback {
|
||||
background-color: Highlight;
|
||||
width: 10000px; /* 100% doesn't work; 10k is hopefully larger than any window
|
||||
we may have, overflow isn't visible. */
|
||||
height: 2px;
|
||||
-moz-margin-start: 0;
|
||||
}
|
BIN
browser/themes/shared/incontentprefs/check.png
Normal file
After Width: | Height: | Size: 288 B |
BIN
browser/themes/shared/incontentprefs/check@2x.png
Normal file
After Width: | Height: | Size: 471 B |
54
browser/themes/shared/incontentprefs/search.css
Normal file
@ -0,0 +1,54 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#defaultEngine > .menulist-label-box > .menulist-icon {
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
/* work around a display: none in Linux's menu.css, see bug 1112310 */
|
||||
.searchengine-menuitem > .menu-iconic-left {
|
||||
display: -moz-box;
|
||||
}
|
||||
|
||||
#engineList {
|
||||
margin: .5em 6px;
|
||||
}
|
||||
|
||||
#engineList treechildren::-moz-tree-image(engineShown, checked) {
|
||||
/* Unfortunately check.svg can't be used in XUL trees. */
|
||||
list-style-image: url("check.png");
|
||||
-moz-margin-start: 5px;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
}
|
||||
|
||||
@media (min-resolution: 2dppx) {
|
||||
#engineList treechildren::-moz-tree-image(engineShown, checked) {
|
||||
list-style-image: url("check@2x.png");
|
||||
}
|
||||
}
|
||||
|
||||
#engineList treechildren::-moz-tree-image(engineName) {
|
||||
-moz-margin-end: 10px;
|
||||
-moz-margin-start: 1px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
#engineList treechildren::-moz-tree-row {
|
||||
min-height: 36px;
|
||||
}
|
||||
|
||||
#engineList treechildren::-moz-tree-cell-text {
|
||||
/* Override to avoid text in the selected row being white on light gray. */
|
||||
color: -moz-FieldText;
|
||||
}
|
||||
|
||||
#engineList treechildren::-moz-tree-drop-feedback {
|
||||
background-color: Highlight;
|
||||
width: 10000px; /* 100% doesn't work; 10k is hopefully larger than any window
|
||||
we may have, overflow isn't visible. */
|
||||
height: 2px;
|
||||
-moz-margin-start: 0;
|
||||
}
|
@ -118,9 +118,9 @@ browser.jar:
|
||||
skin/classic/browser/webRTC-microphone-white-16.png (../shared/webrtc/microphone-white-16.png)
|
||||
skin/classic/browser/webRTC-screen-white-16.png (../shared/webrtc/screen-white-16.png)
|
||||
skin/classic/browser/loop/menuPanel.png (loop/menuPanel.png)
|
||||
skin/classic/browser/loop/toolbar.png (loop/toolbar-XPVista7.png)
|
||||
skin/classic/browser/loop/toolbar-lunaSilver.png (loop/toolbar-lunaSilver.png)
|
||||
skin/classic/browser/loop/toolbar.png (loop/toolbar-XP.png)
|
||||
skin/classic/browser/loop/toolbar-inverted.png (loop/toolbar-inverted.png)
|
||||
skin/classic/browser/loop/toolbar-lunaSilver.png (loop/toolbar-lunaSilver.png)
|
||||
skin/classic/browser/customizableui/background-noise-toolbar.png (customizableui/background-noise-toolbar.png)
|
||||
skin/classic/browser/customizableui/customizeFavicon.ico (../shared/customizableui/customizeFavicon.ico)
|
||||
skin/classic/browser/customizableui/customize-illustration.png (../shared/customizableui/customize-illustration.png)
|
||||
@ -195,8 +195,14 @@ browser.jar:
|
||||
skin/classic/browser/preferences/in-content/favicon.ico (../shared/incontentprefs/favicon.ico)
|
||||
skin/classic/browser/preferences/in-content/icons.png (../shared/incontentprefs/icons.png)
|
||||
skin/classic/browser/preferences/in-content/icons@2x.png (../shared/incontentprefs/icons@2x.png)
|
||||
skin/classic/browser/preferences/in-content/search.css (../shared/incontentprefs/search.css)
|
||||
skin/classic/browser/preferences/in-content/check.png (../shared/incontentprefs/check.png)
|
||||
skin/classic/browser/preferences/in-content/check@2x.png (../shared/incontentprefs/check@2x.png)
|
||||
skin/classic/browser/preferences/applications.css (preferences/applications.css)
|
||||
skin/classic/browser/preferences/aboutPermissions.css (preferences/aboutPermissions.css)
|
||||
skin/classic/browser/preferences/search.css (preferences/search.css)
|
||||
skin/classic/browser/preferences/checkbox.png (preferences/checkbox-xp.png)
|
||||
skin/classic/browser/preferences/checkbox-classic.png (preferences/checkbox-classic.png)
|
||||
skin/classic/browser/social/services-16.png (social/services-16.png)
|
||||
skin/classic/browser/social/services-64.png (social/services-64.png)
|
||||
skin/classic/browser/social/chat-icons.svg (../shared/social/chat-icons.svg)
|
||||
@ -564,9 +570,10 @@ browser.jar:
|
||||
skin/classic/aero/browser/webRTC-camera-white-16.png (../shared/webrtc/camera-white-16.png)
|
||||
skin/classic/aero/browser/webRTC-microphone-white-16.png (../shared/webrtc/microphone-white-16.png)
|
||||
skin/classic/aero/browser/webRTC-screen-white-16.png (../shared/webrtc/screen-white-16.png)
|
||||
skin/classic/aero/browser/loop/menuPanel.png (loop/menuPanel-aero.png)
|
||||
skin/classic/aero/browser/loop/menuPanel.png (loop/menuPanel.png)
|
||||
skin/classic/aero/browser/loop/menuPanel-aero.png (loop/menuPanel-aero.png)
|
||||
skin/classic/aero/browser/loop/toolbar.png (loop/toolbar.png)
|
||||
skin/classic/aero/browser/loop/toolbar-XPVista7.png (loop/toolbar-XPVista7.png)
|
||||
skin/classic/aero/browser/loop/toolbar-aero.png (loop/toolbar-aero.png)
|
||||
skin/classic/aero/browser/loop/toolbar-inverted.png (loop/toolbar-inverted.png)
|
||||
skin/classic/aero/browser/customizableui/background-noise-toolbar.png (customizableui/background-noise-toolbar.png)
|
||||
skin/classic/aero/browser/customizableui/customize-illustration.png (../shared/customizableui/customize-illustration.png)
|
||||
@ -643,8 +650,15 @@ browser.jar:
|
||||
skin/classic/aero/browser/preferences/in-content/favicon.ico (../shared/incontentprefs/favicon.ico)
|
||||
skin/classic/aero/browser/preferences/in-content/icons.png (../shared/incontentprefs/icons.png)
|
||||
skin/classic/aero/browser/preferences/in-content/icons@2x.png (../shared/incontentprefs/icons@2x.png)
|
||||
skin/classic/aero/browser/preferences/in-content/search.css (../shared/incontentprefs/search.css)
|
||||
skin/classic/aero/browser/preferences/in-content/check.png (../shared/incontentprefs/check.png)
|
||||
skin/classic/aero/browser/preferences/in-content/check@2x.png (../shared/incontentprefs/check@2x.png)
|
||||
skin/classic/aero/browser/preferences/applications.css (preferences/applications.css)
|
||||
skin/classic/aero/browser/preferences/aboutPermissions.css (preferences/aboutPermissions.css)
|
||||
skin/classic/aero/browser/preferences/search.css (preferences/search.css)
|
||||
skin/classic/aero/browser/preferences/checkbox.png (preferences/checkbox-8.png)
|
||||
skin/classic/aero/browser/preferences/checkbox-aero.png (preferences/checkbox-aero.png)
|
||||
skin/classic/aero/browser/preferences/checkbox-classic.png (preferences/checkbox-classic.png)
|
||||
skin/classic/aero/browser/social/services-16.png (social/services-16.png)
|
||||
skin/classic/aero/browser/social/services-64.png (social/services-64.png)
|
||||
skin/classic/aero/browser/social/chat-icons.svg (../shared/social/chat-icons.svg)
|
||||
@ -902,6 +916,9 @@ browser.jar:
|
||||
% override chrome://browser/skin/menuPanel-small.png chrome://browser/skin/menuPanel-small-aero.png os=WINNT osversion=6
|
||||
% override chrome://browser/skin/menuPanel-small.png chrome://browser/skin/menuPanel-small-aero.png os=WINNT osversion=6.1
|
||||
|
||||
% override chrome://browser/skin/preferences/checkbox.png chrome://browser/skin/preferences/checkbox-aero.png os=WINNT osversion=6
|
||||
% override chrome://browser/skin/preferences/checkbox.png chrome://browser/skin/preferences/checkbox-aero.png os=WINNT osversion=6.1
|
||||
|
||||
% override chrome://browser/skin/theme-switcher-icon.png chrome://browser/skin/theme-switcher-icon-aero.png os=WINNT osversion=6
|
||||
% override chrome://browser/skin/theme-switcher-icon.png chrome://browser/skin/theme-switcher-icon-aero.png os=WINNT osversion=6.1
|
||||
|
||||
@ -917,5 +934,8 @@ browser.jar:
|
||||
% override chrome://browser/skin/tabbrowser/tab-arrow-left.png chrome://browser/skin/tabbrowser/tab-arrow-left-XPVista7.png os=WINNT osversion=6
|
||||
% override chrome://browser/skin/tabbrowser/tab-arrow-left.png chrome://browser/skin/tabbrowser/tab-arrow-left-XPVista7.png os=WINNT osversion=6.1
|
||||
|
||||
% override chrome://browser/skin/loop/toolbar.png chrome://browser/skin/loop/toolbar-XPVista7.png os=WINNT osversion=6
|
||||
% override chrome://browser/skin/loop/toolbar.png chrome://browser/skin/loop/toolbar-XPVista7.png os=WINNT osversion=6.1
|
||||
% override chrome://browser/skin/loop/toolbar.png chrome://browser/skin/loop/toolbar-aero.png os=WINNT osversion=6
|
||||
% override chrome://browser/skin/loop/toolbar.png chrome://browser/skin/loop/toolbar-aero.png os=WINNT osversion=6.1
|
||||
|
||||
% override chrome://browser/skin/loop/menuPanel.png chrome://browser/skin/loop/menuPanel-aero.png os=WINNT osversion=6
|
||||
% override chrome://browser/skin/loop/menuPanel.png chrome://browser/skin/loop/menuPanel-aero.png os=WINNT osversion=6.1
|
||||
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 8.7 KiB After Width: | Height: | Size: 2.8 KiB |
BIN
browser/themes/windows/loop/toolbar-XP.png
Normal file
After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 4.6 KiB |
BIN
browser/themes/windows/loop/toolbar-aero.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.1 KiB |
BIN
browser/themes/windows/preferences/checkbox-8.png
Normal file
After Width: | Height: | Size: 705 B |
BIN
browser/themes/windows/preferences/checkbox-aero.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
browser/themes/windows/preferences/checkbox-classic.png
Normal file
After Width: | Height: | Size: 284 B |
BIN
browser/themes/windows/preferences/checkbox-xp.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
59
browser/themes/windows/preferences/search.css
Normal file
@ -0,0 +1,59 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#defaultEngine > .menulist-label-box > .menulist-icon {
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
#engineList {
|
||||
margin: .5em 6px;
|
||||
}
|
||||
|
||||
#engineList treechildren::-moz-tree-checkbox {
|
||||
list-style-image: url("chrome://browser/skin/preferences/checkbox.png");
|
||||
-moz-image-region: rect(0, 16px, 16px, 0);
|
||||
}
|
||||
|
||||
#engineList treechildren::-moz-tree-checkbox(checked) {
|
||||
-moz-image-region: rect(0, 64px, 16px, 48px);
|
||||
}
|
||||
|
||||
@media (-moz-windows-classic) {
|
||||
#engineList treechildren::-moz-tree-checkbox {
|
||||
list-style-image: url("chrome://browser/skin/preferences/checkbox-classic.png");
|
||||
}
|
||||
|
||||
#engineList treechildren::-moz-tree-checkbox(checked) {
|
||||
-moz-image-region: rect(0, 48px, 16px, 32px);
|
||||
}
|
||||
}
|
||||
|
||||
@media not all and (-moz-windows-classic) {
|
||||
#engineList treechildren::-moz-tree-checkbox(hover) {
|
||||
-moz-image-region: rect(0, 48px, 16px, 32px);
|
||||
}
|
||||
|
||||
#engineList treechildren::-moz-tree-checkbox(checked, hover) {
|
||||
-moz-image-region: rect(0, 80px, 16px, 64px);
|
||||
}
|
||||
}
|
||||
|
||||
#engineList treechildren::-moz-tree-image(engineName) {
|
||||
-moz-margin-end: 4px;
|
||||
-moz-margin-start: 0;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
#engineList treechildren::-moz-tree-row {
|
||||
min-height: 20px;
|
||||
}
|
||||
|
||||
#engineList treechildren::-moz-tree-drop-feedback {
|
||||
background-color: Highlight;
|
||||
width: 10000px; /* 100% doesn't work; 10k is hopefully larger than any window
|
||||
we may have, overflow isn't visible. */
|
||||
height: 2px;
|
||||
-moz-margin-start: 0;
|
||||
}
|
@ -82,6 +82,18 @@ ASSERT_ICC_LOCK_TYPE_EQUALITY(Fdn, CARD_LOCK_TYPE_FDN);
|
||||
|
||||
#undef ASSERT_ICC_LOCK_TYPE_EQUALITY
|
||||
|
||||
/**
|
||||
* Enum IccContactType
|
||||
*/
|
||||
#define ASSERT_ICC_CONTACT_TYPE_EQUALITY(webidlState, xpidlState) \
|
||||
ASSERT_EQUALITY(IccContactType, webidlState, xpidlState)
|
||||
|
||||
ASSERT_ICC_CONTACT_TYPE_EQUALITY(Adn, CARD_CONTACT_TYPE_ADN);
|
||||
ASSERT_ICC_CONTACT_TYPE_EQUALITY(Fdn, CARD_CONTACT_TYPE_FDN);
|
||||
ASSERT_ICC_CONTACT_TYPE_EQUALITY(Sdn, CARD_CONTACT_TYPE_SDN);
|
||||
|
||||
#undef ASSERT_ICC_CONTACT_TYPE_EQUALITY
|
||||
|
||||
#undef ASSERT_EQUALITY
|
||||
|
||||
} // namespace icc
|
||||
|
@ -341,7 +341,7 @@ Icc::GetCardLockRetryCount(IccLockType aLockType, ErrorResult& aRv)
|
||||
}
|
||||
|
||||
already_AddRefed<DOMRequest>
|
||||
Icc::ReadContacts(const nsAString& aContactType, ErrorResult& aRv)
|
||||
Icc::ReadContacts(IccContactType aContactType, ErrorResult& aRv)
|
||||
{
|
||||
if (!mProvider) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
@ -349,7 +349,8 @@ Icc::ReadContacts(const nsAString& aContactType, ErrorResult& aRv)
|
||||
}
|
||||
|
||||
nsRefPtr<nsIDOMDOMRequest> request;
|
||||
nsresult rv = mProvider->ReadContacts(mClientId, GetOwner(), aContactType,
|
||||
nsresult rv = mProvider->ReadContacts(mClientId, GetOwner(),
|
||||
static_cast<uint32_t>(aContactType),
|
||||
getter_AddRefs(request));
|
||||
if (NS_FAILED(rv)) {
|
||||
aRv.Throw(rv);
|
||||
@ -360,7 +361,7 @@ Icc::ReadContacts(const nsAString& aContactType, ErrorResult& aRv)
|
||||
}
|
||||
|
||||
already_AddRefed<DOMRequest>
|
||||
Icc::UpdateContact(const JSContext* aCx, const nsAString& aContactType,
|
||||
Icc::UpdateContact(const JSContext* aCx, IccContactType aContactType,
|
||||
JS::Handle<JS::Value> aContact, const nsAString& aPin2,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
@ -370,7 +371,8 @@ Icc::UpdateContact(const JSContext* aCx, const nsAString& aContactType,
|
||||
}
|
||||
|
||||
nsRefPtr<nsIDOMDOMRequest> request;
|
||||
nsresult rv = mProvider->UpdateContact(mClientId, GetOwner(), aContactType,
|
||||
nsresult rv = mProvider->UpdateContact(mClientId, GetOwner(),
|
||||
static_cast<uint32_t>(aContactType),
|
||||
aContact, aPin2,
|
||||
getter_AddRefs(request));
|
||||
if (NS_FAILED(rv)) {
|
||||
|
@ -90,10 +90,10 @@ public:
|
||||
GetCardLockRetryCount(IccLockType aLockType, ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<DOMRequest>
|
||||
ReadContacts(const nsAString& aContactType, ErrorResult& aRv);
|
||||
ReadContacts(IccContactType aContactType, ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<DOMRequest>
|
||||
UpdateContact(const JSContext* aCx, const nsAString& aContactType,
|
||||
UpdateContact(const JSContext* aCx, IccContactType aContactType,
|
||||
JS::Handle<JS::Value> aContact, const nsAString& aPin2,
|
||||
ErrorResult& aRv);
|
||||
|
||||
|
@ -20,7 +20,7 @@ interface nsIIccListener : nsISupports
|
||||
/**
|
||||
* XPCOM component (in the content process) that provides the ICC information.
|
||||
*/
|
||||
[scriptable, uuid(38bbc600-76ac-11e4-82f8-0800200c9a66)]
|
||||
[scriptable, uuid(937213c3-f64e-4f58-b4e0-3010f219d0c3)]
|
||||
interface nsIIccProvider : nsISupports
|
||||
{
|
||||
// MUST match enum IccCardState in MozIcc.webidl!
|
||||
@ -80,6 +80,11 @@ interface nsIIccProvider : nsISupports
|
||||
const unsigned long CARD_LOCK_TYPE_RSPCK_PUK = 19;
|
||||
const unsigned long CARD_LOCK_TYPE_FDN = 20;
|
||||
|
||||
// MUST match with enum IccContactType in MozIcc.webidl
|
||||
const unsigned long CARD_CONTACT_TYPE_ADN = 0;
|
||||
const unsigned long CARD_CONTACT_TYPE_FDN = 1;
|
||||
const unsigned long CARD_CONTACT_TYPE_SDN = 2;
|
||||
|
||||
/**
|
||||
* Called when a content process registers receiving unsolicited messages from
|
||||
* RadioInterfaceLayer in the chrome process. Only a content process that has
|
||||
@ -148,11 +153,11 @@ interface nsIIccProvider : nsISupports
|
||||
*/
|
||||
nsIDOMDOMRequest readContacts(in unsigned long clientId,
|
||||
in nsIDOMWindow window,
|
||||
in DOMString contactType);
|
||||
in unsigned long contactType);
|
||||
|
||||
nsIDOMDOMRequest updateContact(in unsigned long clientId,
|
||||
in nsIDOMWindow window,
|
||||
in DOMString contactType,
|
||||
in unsigned long contactType,
|
||||
in jsval contact,
|
||||
in DOMString pin2);
|
||||
|
||||
|
@ -3411,6 +3411,8 @@ TabChild::RecvRequestNotifyAfterRemotePaint()
|
||||
bool
|
||||
TabChild::RecvUIResolutionChanged()
|
||||
{
|
||||
mDPI = 0;
|
||||
mDefaultScale = 0;
|
||||
static_cast<PuppetWidget*>(mWidget.get())->ClearBackingScaleCache();
|
||||
nsCOMPtr<nsIDocument> document(GetDocument());
|
||||
nsCOMPtr<nsIPresShell> presShell = document->GetShell();
|
||||
|
@ -219,7 +219,6 @@ MediaEngineTabVideoSource::Draw() {
|
||||
IntSize size(mBufW, mBufH);
|
||||
|
||||
nsresult rv;
|
||||
float scale = 1.0;
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(mWindow);
|
||||
|
||||
@ -240,25 +239,14 @@ MediaEngineTabVideoSource::Draw() {
|
||||
return;
|
||||
}
|
||||
|
||||
float left, top, width, height;
|
||||
rect->GetLeft(&left);
|
||||
rect->GetTop(&top);
|
||||
float width, height;
|
||||
rect->GetWidth(&width);
|
||||
rect->GetHeight(&height);
|
||||
|
||||
if (mScrollWithPage) {
|
||||
nsPoint point;
|
||||
utils->GetScrollXY(false, &point.x, &point.y);
|
||||
left += point.x;
|
||||
top += point.y;
|
||||
}
|
||||
|
||||
if (width == 0 || height == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t srcX = left;
|
||||
int32_t srcY = top;
|
||||
int32_t srcW;
|
||||
int32_t srcH;
|
||||
|
||||
@ -279,14 +267,15 @@ MediaEngineTabVideoSource::Draw() {
|
||||
if (!presContext) {
|
||||
return;
|
||||
}
|
||||
|
||||
nscolor bgColor = NS_RGB(255, 255, 255);
|
||||
nsCOMPtr<nsIPresShell> presShell = presContext->PresShell();
|
||||
uint32_t renderDocFlags = (nsIPresShell::RENDER_IGNORE_VIEWPORT_SCROLLING |
|
||||
nsIPresShell::RENDER_DOCUMENT_RELATIVE);
|
||||
nsRect r(nsPresContext::CSSPixelsToAppUnits(srcX / scale),
|
||||
nsPresContext::CSSPixelsToAppUnits(srcY / scale),
|
||||
nsPresContext::CSSPixelsToAppUnits(srcW / scale),
|
||||
nsPresContext::CSSPixelsToAppUnits(srcH / scale));
|
||||
uint32_t renderDocFlags = nsIPresShell::RENDER_DOCUMENT_RELATIVE;
|
||||
if (!mScrollWithPage) {
|
||||
renderDocFlags |= nsIPresShell::RENDER_IGNORE_VIEWPORT_SCROLLING;
|
||||
}
|
||||
nsRect r(0, 0, nsPresContext::CSSPixelsToAppUnits((float)srcW),
|
||||
nsPresContext::CSSPixelsToAppUnits((float)srcH));
|
||||
|
||||
gfxImageFormat format = gfxImageFormat::RGB24;
|
||||
uint32_t stride = gfxASurface::FormatStrideForWidth(format, size.width);
|
||||
@ -302,9 +291,9 @@ MediaEngineTabVideoSource::Draw() {
|
||||
return;
|
||||
}
|
||||
nsRefPtr<gfxContext> context = new gfxContext(dt);
|
||||
context->SetMatrix(
|
||||
context->CurrentMatrix().Scale(scale * size.width / srcW,
|
||||
scale * size.height / srcH));
|
||||
context->SetMatrix(context->CurrentMatrix().Scale((float)size.width/srcW,
|
||||
(float)size.height/srcH));
|
||||
|
||||
rv = presShell->RenderDocument(r, renderDocFlags, bgColor, context);
|
||||
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
|
@ -471,14 +471,18 @@ Nfc.prototype = {
|
||||
delete message.sessionId;
|
||||
|
||||
if (SessionHelper.isP2PSession(sessionId)) {
|
||||
gMessageManager.onPeerEvent(NFC.PEER_EVENT_FOUND, message.sessionToken);
|
||||
if (message.records) {
|
||||
// TODO: Bug 1082493.
|
||||
} else {
|
||||
gMessageManager.onPeerEvent(NFC.PEER_EVENT_FOUND, message.sessionToken);
|
||||
}
|
||||
} else {
|
||||
gMessageManager.onTagFound(message);
|
||||
}
|
||||
|
||||
let sysMsg = new NfcTechDiscoveredSysMsg(message.sessionToken,
|
||||
message.isP2P,
|
||||
message.records);
|
||||
message.records || null);
|
||||
gSystemMessenger.broadcastMessage("nfc-manager-tech-discovered", sysMsg);
|
||||
break;
|
||||
case "TechLostNotification":
|
||||
|
@ -573,6 +573,10 @@ NFCTechDiscoveredWrapper.prototype = {
|
||||
let peer = aWindow.MozNFCPeer._create(aWindow, peerImpl);
|
||||
aMessage.peer = peer;
|
||||
}
|
||||
|
||||
delete aMessage.isP2P;
|
||||
delete aMessage.sessionToken;
|
||||
|
||||
return aMessage;
|
||||
},
|
||||
|
||||
|
@ -40,7 +40,7 @@ interface nsIRilSendWorkerMessageCallback : nsISupports
|
||||
boolean handleResponse(in jsval response);
|
||||
};
|
||||
|
||||
[scriptable, uuid(dc874da3-5f74-49d4-8e1c-a58ed9a1c0ef)]
|
||||
[scriptable, uuid(864a47d6-a576-4a5c-b8b8-9ca312345f52)]
|
||||
interface nsIRadioInterface : nsISupports
|
||||
{
|
||||
readonly attribute nsIRilContext rilContext;
|
||||
|
@ -2591,6 +2591,11 @@ GECKO_CARDLOCK_TO_SEL_CODE[GECKO_CARDLOCK_NCK] = ICC_SEL_CODE_PH_NET_PIN;
|
||||
GECKO_CARDLOCK_TO_SEL_CODE[GECKO_CARDLOCK_CCK] = ICC_SEL_CODE_PH_CORP_PIN;
|
||||
GECKO_CARDLOCK_TO_SEL_CODE[GECKO_CARDLOCK_SPCK] = ICC_SEL_CODE_PH_SP_PIN;
|
||||
|
||||
// See nsIIccProvider::CARD_CONTACT_TYPE_*
|
||||
this.GECKO_CARDCONTACT_TYPE_ADN = 0;
|
||||
this.GECKO_CARDCONTACT_TYPE_FDN = 1;
|
||||
this.GECKO_CARDCONTACT_TYPE_SDN = 2;
|
||||
|
||||
// See ril.h RIL_PersoSubstate
|
||||
this.PERSONSUBSTATE = {};
|
||||
PERSONSUBSTATE[CARD_PERSOSUBSTATE_UNKNOWN] = GECKO_CARDSTATE_UNKNOWN;
|
||||
|
@ -1023,7 +1023,7 @@ RilObject.prototype = {
|
||||
* Read UICC Phonebook contacts.
|
||||
*
|
||||
* @param contactType
|
||||
* "adn" or "fdn".
|
||||
* One of GECKO_CARDCONTACT_TYPE_*.
|
||||
* @param requestId
|
||||
* Request id from RadioInterfaceLayer.
|
||||
*/
|
||||
@ -1057,7 +1057,7 @@ RilObject.prototype = {
|
||||
/**
|
||||
* Update UICC Phonebook.
|
||||
*
|
||||
* @param contactType "adn" or "fdn".
|
||||
* @param contactType One of GECKO_CARDCONTACT_TYPE_*.
|
||||
* @param contact The contact will be updated.
|
||||
* @param pin2 PIN2 is required for updating FDN.
|
||||
* @param requestId Request id from RadioInterfaceLayer.
|
||||
@ -15138,7 +15138,7 @@ ICCContactHelperObject.prototype = {
|
||||
* Helper function to read ICC contacts.
|
||||
*
|
||||
* @param appType One of CARD_APPTYPE_*.
|
||||
* @param contactType "adn" or "fdn".
|
||||
* @param contactType One of GECKO_CARDCONTACT_TYPE_*.
|
||||
* @param onsuccess Callback to be called when success.
|
||||
* @param onerror Callback to be called when error.
|
||||
*/
|
||||
@ -15146,17 +15146,17 @@ ICCContactHelperObject.prototype = {
|
||||
let ICCRecordHelper = this.context.ICCRecordHelper;
|
||||
|
||||
switch (contactType) {
|
||||
case "adn":
|
||||
case GECKO_CARDCONTACT_TYPE_ADN:
|
||||
if (!this.hasDfPhoneBook(appType)) {
|
||||
ICCRecordHelper.readADNLike(ICC_EF_ADN, onsuccess, onerror);
|
||||
} else {
|
||||
this.readUSimContacts(onsuccess, onerror);
|
||||
}
|
||||
break;
|
||||
case "fdn":
|
||||
case GECKO_CARDCONTACT_TYPE_FDN:
|
||||
ICCRecordHelper.readADNLike(ICC_EF_FDN, onsuccess, onerror);
|
||||
break;
|
||||
case "sdn":
|
||||
case GECKO_CARDCONTACT_TYPE_SDN:
|
||||
let ICCUtilsHelper = this.context.ICCUtilsHelper;
|
||||
if (!ICCUtilsHelper.isICCServiceAvailable("SDN")) {
|
||||
onerror(CONTACT_ERR_CONTACT_TYPE_NOT_SUPPORTED);
|
||||
@ -15178,7 +15178,7 @@ ICCContactHelperObject.prototype = {
|
||||
* Helper function to find free contact record.
|
||||
*
|
||||
* @param appType One of CARD_APPTYPE_*.
|
||||
* @param contactType "adn" or "fdn".
|
||||
* @param contactType One of GECKO_CARDCONTACT_TYPE_*.
|
||||
* @param onsuccess Callback to be called when success.
|
||||
* @param onerror Callback to be called when error.
|
||||
*/
|
||||
@ -15186,7 +15186,7 @@ ICCContactHelperObject.prototype = {
|
||||
let ICCRecordHelper = this.context.ICCRecordHelper;
|
||||
|
||||
switch (contactType) {
|
||||
case "adn":
|
||||
case GECKO_CARDCONTACT_TYPE_ADN:
|
||||
if (!this.hasDfPhoneBook(appType)) {
|
||||
ICCRecordHelper.findFreeRecordId(ICC_EF_ADN, onsuccess.bind(null, 0), onerror);
|
||||
} else {
|
||||
@ -15197,7 +15197,7 @@ ICCContactHelperObject.prototype = {
|
||||
ICCRecordHelper.readPBR(gotPbrCb, onerror);
|
||||
}
|
||||
break;
|
||||
case "fdn":
|
||||
case GECKO_CARDCONTACT_TYPE_FDN:
|
||||
ICCRecordHelper.findFreeRecordId(ICC_EF_FDN, onsuccess.bind(null, 0), onerror);
|
||||
break;
|
||||
default:
|
||||
@ -15255,7 +15255,7 @@ ICCContactHelperObject.prototype = {
|
||||
* Helper function to add a new ICC contact.
|
||||
*
|
||||
* @param appType One of CARD_APPTYPE_*.
|
||||
* @param contactType "adn" or "fdn".
|
||||
* @param contactType One of GECKO_CARDCONTACT_TYPE_*.
|
||||
* @param contact The contact will be added.
|
||||
* @param pin2 PIN2 is required for FDN.
|
||||
* @param onsuccess Callback to be called when success.
|
||||
@ -15276,7 +15276,7 @@ ICCContactHelperObject.prototype = {
|
||||
* Helper function to update ICC contact.
|
||||
*
|
||||
* @param appType One of CARD_APPTYPE_*.
|
||||
* @param contactType "adn" or "fdn".
|
||||
* @param contactType One of GECKO_CARDCONTACT_TYPE_*.
|
||||
* @param contact The contact will be updated.
|
||||
* @param pin2 PIN2 is required for FDN.
|
||||
* @param onsuccess Callback to be called when success.
|
||||
@ -15286,14 +15286,14 @@ ICCContactHelperObject.prototype = {
|
||||
let ICCRecordHelper = this.context.ICCRecordHelper;
|
||||
|
||||
switch (contactType) {
|
||||
case "adn":
|
||||
case GECKO_CARDCONTACT_TYPE_ADN:
|
||||
if (!this.hasDfPhoneBook(appType)) {
|
||||
ICCRecordHelper.updateADNLike(ICC_EF_ADN, contact, null, onsuccess, onerror);
|
||||
} else {
|
||||
this.updateUSimContact(contact, onsuccess, onerror);
|
||||
}
|
||||
break;
|
||||
case "fdn":
|
||||
case GECKO_CARDCONTACT_TYPE_FDN:
|
||||
if (!pin2) {
|
||||
onerror(GECKO_ERROR_SIM_PIN2);
|
||||
return;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
|
||||
|
||||
@ -32,7 +32,8 @@ add_test(function test_error_message_read_icc_contact () {
|
||||
// Error 3, suppose we update the supported PBR fields in USIM_PBR_FIELDS,
|
||||
// but forget to add implemenetations for it.
|
||||
USIM_PBR_FIELDS.push("pbc");
|
||||
do_test({contactType: "adn"}, CONTACT_ERR_FIELD_NOT_SUPPORTED);
|
||||
do_test({contactType: GECKO_CARDCONTACT_TYPE_ADN},
|
||||
CONTACT_ERR_FIELD_NOT_SUPPORTED);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
@ -59,14 +60,18 @@ add_test(function test_error_message_update_icc_contact() {
|
||||
do_test({}, CONTACT_ERR_REQUEST_NOT_SUPPORTED);
|
||||
|
||||
// Error 2, specifying a correct contactType, but without providing 'contact'.
|
||||
do_test({contactType: "adn"}, CONTACT_ERR_REQUEST_NOT_SUPPORTED);
|
||||
do_test({contactType: GECKO_CARDCONTACT_TYPE_ADN},
|
||||
CONTACT_ERR_REQUEST_NOT_SUPPORTED);
|
||||
|
||||
// Error 3, specifying a non-supported contactType.
|
||||
ril.appType = CARD_APPTYPE_USIM;
|
||||
do_test({contactType: "sdn", contact: {}}, CONTACT_ERR_CONTACT_TYPE_NOT_SUPPORTED);
|
||||
do_test({contactType: GECKO_CARDCONTACT_TYPE_SDN, contact: {}},
|
||||
CONTACT_ERR_CONTACT_TYPE_NOT_SUPPORTED);
|
||||
|
||||
// Error 4, without supplying pin2.
|
||||
do_test({contactType: "fdn", contact: {contactId: ICCID + "1"}}, GECKO_ERROR_SIM_PIN2);
|
||||
do_test({contactType: GECKO_CARDCONTACT_TYPE_FDN,
|
||||
contact: {contactId: ICCID + "1"}},
|
||||
GECKO_ERROR_SIM_PIN2);
|
||||
|
||||
// Error 5, No free record found in EF_ADN.
|
||||
let record = context.ICCRecordHelper;
|
||||
@ -81,19 +86,22 @@ add_test(function test_error_message_update_icc_contact() {
|
||||
options.callback(options);
|
||||
};
|
||||
|
||||
do_test({contactType: "adn", contact: {}}, CONTACT_ERR_NO_FREE_RECORD_FOUND);
|
||||
do_test({contactType: GECKO_CARDCONTACT_TYPE_ADN, contact: {}},
|
||||
CONTACT_ERR_NO_FREE_RECORD_FOUND);
|
||||
|
||||
// Error 6, ICC IO Error.
|
||||
io.loadLinearFixedEF = function(options) {
|
||||
ril[REQUEST_SIM_IO](0, {rilRequestError: ERROR_GENERIC_FAILURE});
|
||||
};
|
||||
do_test({contactType: "adn", contact: {contactId: ICCID + "1"}},
|
||||
do_test({contactType: GECKO_CARDCONTACT_TYPE_ADN,
|
||||
contact: {contactId: ICCID + "1"}},
|
||||
GECKO_ERROR_GENERIC_FAILURE);
|
||||
|
||||
// Error 7, suppose we update the supported PBR fields in USIM_PBR_FIELDS,
|
||||
// but forget to add implemenetations for it.
|
||||
USIM_PBR_FIELDS.push("pbc");
|
||||
do_test({contactType: "adn", contact: {contactId: ICCID + "1"}},
|
||||
do_test({contactType: GECKO_CARDCONTACT_TYPE_ADN,
|
||||
contact: {contactId: ICCID + "1"}},
|
||||
CONTACT_ERR_FIELD_NOT_SUPPORTED);
|
||||
|
||||
// Error 8, EF_PBR doesn't exist.
|
||||
@ -101,7 +109,8 @@ add_test(function test_error_message_update_icc_contact() {
|
||||
onsuccess([]);
|
||||
};
|
||||
|
||||
do_test({contactType: "adn", contact: {contactId: ICCID + "1"}},
|
||||
do_test({contactType: GECKO_CARDCONTACT_TYPE_ADN,
|
||||
contact: {contactId: ICCID + "1"}},
|
||||
CONTACT_ERR_CANNOT_ACCESS_PHONEBOOK);
|
||||
|
||||
run_next_test();
|
||||
@ -183,31 +192,31 @@ add_test(function test_read_icc_contacts() {
|
||||
|
||||
// SIM
|
||||
do_print("Test read SIM adn contacts");
|
||||
do_test(CARD_APPTYPE_SIM, "adn", expectedContact1);
|
||||
do_test(CARD_APPTYPE_SIM, GECKO_CARDCONTACT_TYPE_ADN, expectedContact1);
|
||||
|
||||
do_print("Test read SIM fdn contacts");
|
||||
do_test(CARD_APPTYPE_SIM, "fdn", expectedContact1);
|
||||
do_test(CARD_APPTYPE_SIM, GECKO_CARDCONTACT_TYPE_FDN, expectedContact1);
|
||||
|
||||
// USIM
|
||||
do_print("Test read USIM adn contacts");
|
||||
do_test(CARD_APPTYPE_USIM, "adn", expectedContact2);
|
||||
do_test(CARD_APPTYPE_USIM, GECKO_CARDCONTACT_TYPE_ADN, expectedContact2);
|
||||
|
||||
do_print("Test read USIM fdn contacts");
|
||||
do_test(CARD_APPTYPE_USIM, "fdn", expectedContact1);
|
||||
do_test(CARD_APPTYPE_USIM, GECKO_CARDCONTACT_TYPE_FDN, expectedContact1);
|
||||
|
||||
// RUIM
|
||||
do_print("Test read RUIM adn contacts");
|
||||
do_test(CARD_APPTYPE_RUIM, "adn", expectedContact1);
|
||||
do_test(CARD_APPTYPE_RUIM, GECKO_CARDCONTACT_TYPE_ADN, expectedContact1);
|
||||
|
||||
do_print("Test read RUIM fdn contacts");
|
||||
do_test(CARD_APPTYPE_RUIM, "fdn", expectedContact1);
|
||||
do_test(CARD_APPTYPE_RUIM, GECKO_CARDCONTACT_TYPE_FDN, expectedContact1);
|
||||
|
||||
// RUIM with enhanced phone book
|
||||
do_print("Test read RUIM adn contacts with enhanced phone book");
|
||||
do_test(CARD_APPTYPE_RUIM, "adn", expectedContact2, true);
|
||||
do_test(CARD_APPTYPE_RUIM, GECKO_CARDCONTACT_TYPE_ADN, expectedContact2, true);
|
||||
|
||||
do_print("Test read RUIM fdn contacts with enhanced phone book");
|
||||
do_test(CARD_APPTYPE_RUIM, "fdn", expectedContact1, true);
|
||||
do_test(CARD_APPTYPE_RUIM, GECKO_CARDCONTACT_TYPE_FDN, expectedContact1, true);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
@ -261,9 +270,9 @@ add_test(function test_update_icc_contact() {
|
||||
};
|
||||
|
||||
recordHelper.updateADNLike = function(fileId, contact, pin2, onsuccess, onerror) {
|
||||
if (aContactType === "fdn") {
|
||||
if (aContactType === GECKO_CARDCONTACT_TYPE_FDN) {
|
||||
do_check_eq(fileId, ICC_EF_FDN);
|
||||
} else if (aContactType === "adn") {
|
||||
} else if (aContactType === GECKO_CARDCONTACT_TYPE_ADN) {
|
||||
do_check_eq(fileId, ICC_EF_ADN);
|
||||
}
|
||||
do_check_eq(pin2, aPin2);
|
||||
@ -370,35 +379,42 @@ add_test(function test_update_icc_contact() {
|
||||
let contact = contacts[i];
|
||||
// SIM
|
||||
do_print("Test update SIM adn contacts");
|
||||
do_test(CARD_APPTYPE_SIM, "adn", contact);
|
||||
do_test(CARD_APPTYPE_SIM, GECKO_CARDCONTACT_TYPE_ADN, contact);
|
||||
|
||||
do_print("Test update SIM fdn contacts");
|
||||
do_test(CARD_APPTYPE_SIM, "fdn", contact, "1234");
|
||||
do_test(CARD_APPTYPE_SIM, GECKO_CARDCONTACT_TYPE_FDN, contact, "1234");
|
||||
|
||||
// USIM
|
||||
do_print("Test update USIM adn contacts");
|
||||
do_test(CARD_APPTYPE_USIM, "adn", contact, null, ICC_USIM_TYPE1_TAG);
|
||||
do_test(CARD_APPTYPE_USIM, "adn", contact, null, ICC_USIM_TYPE2_TAG, true);
|
||||
do_test(CARD_APPTYPE_USIM, "adn", contact, null, ICC_USIM_TYPE2_TAG, false);
|
||||
do_test(CARD_APPTYPE_USIM, GECKO_CARDCONTACT_TYPE_ADN, contact, null,
|
||||
ICC_USIM_TYPE1_TAG);
|
||||
do_test(CARD_APPTYPE_USIM, GECKO_CARDCONTACT_TYPE_ADN, contact, null,
|
||||
ICC_USIM_TYPE2_TAG, true);
|
||||
do_test(CARD_APPTYPE_USIM, GECKO_CARDCONTACT_TYPE_ADN, contact, null,
|
||||
ICC_USIM_TYPE2_TAG, false);
|
||||
|
||||
do_print("Test update USIM fdn contacts");
|
||||
do_test(CARD_APPTYPE_USIM, "fdn", contact, "1234");
|
||||
do_test(CARD_APPTYPE_USIM, GECKO_CARDCONTACT_TYPE_FDN, contact, "1234");
|
||||
|
||||
// RUIM
|
||||
do_print("Test update RUIM adn contacts");
|
||||
do_test(CARD_APPTYPE_RUIM, "adn", contact);
|
||||
do_test(CARD_APPTYPE_RUIM, GECKO_CARDCONTACT_TYPE_ADN, contact);
|
||||
|
||||
do_print("Test update RUIM fdn contacts");
|
||||
do_test(CARD_APPTYPE_RUIM, "fdn", contact, "1234");
|
||||
do_test(CARD_APPTYPE_RUIM, GECKO_CARDCONTACT_TYPE_FDN, contact, "1234");
|
||||
|
||||
// RUIM with enhanced phone book
|
||||
do_print("Test update RUIM adn contacts with enhanced phone book");
|
||||
do_test(CARD_APPTYPE_RUIM, "adn", contact, null, ICC_USIM_TYPE1_TAG, null, true);
|
||||
do_test(CARD_APPTYPE_RUIM, "adn", contact, null, ICC_USIM_TYPE2_TAG, true, true);
|
||||
do_test(CARD_APPTYPE_RUIM, "adn", contact, null, ICC_USIM_TYPE2_TAG, false, true);
|
||||
do_test(CARD_APPTYPE_RUIM, GECKO_CARDCONTACT_TYPE_ADN, contact, null,
|
||||
ICC_USIM_TYPE1_TAG, null,true);
|
||||
do_test(CARD_APPTYPE_RUIM, GECKO_CARDCONTACT_TYPE_ADN, contact, null,
|
||||
ICC_USIM_TYPE2_TAG, true, true);
|
||||
do_test(CARD_APPTYPE_RUIM, GECKO_CARDCONTACT_TYPE_ADN, contact, null,
|
||||
ICC_USIM_TYPE2_TAG, false, true);
|
||||
|
||||
do_print("Test update RUIM fdn contacts with enhanced phone book");
|
||||
do_test(CARD_APPTYPE_RUIM, "fdn", contact, "1234", null, true);
|
||||
do_test(CARD_APPTYPE_RUIM, GECKO_CARDCONTACT_TYPE_FDN, contact, "1234",
|
||||
null, true);
|
||||
}
|
||||
|
||||
run_next_test();
|
||||
@ -476,7 +492,9 @@ add_test(function test_update_icc_contact_with_remove_type1_attr() {
|
||||
do_check_true(false);
|
||||
};
|
||||
|
||||
contactHelper.updateICCContact(CARD_APPTYPE_USIM, "adn", contact, null, successCb, errorCb);
|
||||
contactHelper.updateICCContact(CARD_APPTYPE_USIM,
|
||||
GECKO_CARDCONTACT_TYPE_ADN,
|
||||
contact, null, successCb, errorCb);
|
||||
}
|
||||
|
||||
do_test(ICC_USIM_TYPE1_TAG);
|
||||
@ -518,7 +536,9 @@ add_test(function test_find_free_icc_contact_sim() {
|
||||
};
|
||||
|
||||
for (let i = 0; i < MAX_RECORDS; i++) {
|
||||
contactHelper.findFreeICCContact(CARD_APPTYPE_SIM, "adn", successCb, errorCb);
|
||||
contactHelper.findFreeICCContact(CARD_APPTYPE_SIM,
|
||||
GECKO_CARDCONTACT_TYPE_ADN,
|
||||
successCb, errorCb);
|
||||
}
|
||||
// The 1st element, records[0], is null.
|
||||
do_check_eq(records.length - 1, MAX_RECORDS);
|
||||
@ -531,7 +551,8 @@ add_test(function test_find_free_icc_contact_sim() {
|
||||
errorCb = function(errorMsg) {
|
||||
do_check_true(errorMsg === "No free record found.");
|
||||
};
|
||||
contactHelper.findFreeICCContact(CARD_APPTYPE_SIM, "adn", successCb, errorCb);
|
||||
contactHelper.findFreeICCContact(CARD_APPTYPE_SIM, GECKO_CARDCONTACT_TYPE_ADN,
|
||||
successCb, errorCb);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
@ -576,7 +597,9 @@ add_test(function test_find_free_icc_contact_usim() {
|
||||
do_check_true(false);
|
||||
};
|
||||
|
||||
contactHelper.findFreeICCContact(CARD_APPTYPE_USIM, "adn", successCb, errorCb);
|
||||
contactHelper.findFreeICCContact(CARD_APPTYPE_USIM,
|
||||
GECKO_CARDCONTACT_TYPE_ADN,
|
||||
successCb, errorCb);
|
||||
|
||||
// Now the EF_ADN in the 1st phonebook set is full, so the next free contact
|
||||
// will come from the 2nd phonebook set.
|
||||
@ -584,7 +607,9 @@ add_test(function test_find_free_icc_contact_usim() {
|
||||
do_check_eq(pbrIndex, 1);
|
||||
do_check_eq(recordId, 1);
|
||||
}
|
||||
contactHelper.findFreeICCContact(CARD_APPTYPE_USIM, "adn", successCb, errorCb);
|
||||
contactHelper.findFreeICCContact(CARD_APPTYPE_USIM,
|
||||
GECKO_CARDCONTACT_TYPE_ADN,
|
||||
successCb, errorCb);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
@ -33,7 +33,7 @@ let emulator = (function() {
|
||||
|
||||
// Overwritten it so people could not call this function directly.
|
||||
runEmulatorShell = function() {
|
||||
throw "Use emulator.runShellCmd(cmd, callback) instead of runEmulatorShell";
|
||||
throw "Use emulator.runShellCmd(cmd) instead of runEmulatorShell";
|
||||
};
|
||||
|
||||
/**
|
||||
@ -157,13 +157,18 @@ let emulator = (function() {
|
||||
*
|
||||
* @param aTarget
|
||||
* A event target.
|
||||
* @param aExpectedCall
|
||||
* @param aExpectedCall [optional]
|
||||
* Expected call for event.call
|
||||
* @return Promise<DOMEvent>
|
||||
* @return Promise<TelephonyCall>
|
||||
*/
|
||||
function waitForCallsChangedEvent(aTarget, aExpectedCall) {
|
||||
return waitForEvent(aTarget, "callschanged",
|
||||
event => event.call == aExpectedCall);
|
||||
if (aExpectedCall === undefined) {
|
||||
return waitForEvent(aTarget, "callschanged").then(event => event.call);
|
||||
} else {
|
||||
return waitForEvent(aTarget, "callschanged",
|
||||
event => event.call == aExpectedCall)
|
||||
.then(event => event.call)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -441,15 +446,17 @@ let emulator = (function() {
|
||||
serviceId = typeof serviceId !== "undefined" ? serviceId : 0;
|
||||
log("Make an outgoing call: " + number + ", serviceId: " + serviceId);
|
||||
|
||||
return telephony.dial(number, serviceId)
|
||||
.then(call => {
|
||||
ok(call);
|
||||
is(call.id.number, number);
|
||||
is(call.state, "dialing");
|
||||
is(call.serviceId, serviceId);
|
||||
let outCall;
|
||||
|
||||
return waitForNamedStateEvent(call, "alerting");
|
||||
});
|
||||
return telephony.dial(number, serviceId)
|
||||
.then(call => outCall = call)
|
||||
.then(() => {
|
||||
ok(outCall instanceof TelephonyCall, "check instance");
|
||||
is(outCall.id.number, number);
|
||||
is(outCall.state, "dialing");
|
||||
is(outCall.serviceId, serviceId);
|
||||
})
|
||||
.then(() => waitForNamedStateEvent(outCall, "alerting"));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -462,13 +469,20 @@ let emulator = (function() {
|
||||
function dialEmergency(number) {
|
||||
log("Make an outgoing emergency call: " + number);
|
||||
|
||||
return telephony.dialEmergency(number)
|
||||
.then(call => {
|
||||
ok(call);
|
||||
is(call.id.number, number);
|
||||
is(call.state, "dialing");
|
||||
let outCall;
|
||||
|
||||
return waitForNamedStateEvent(call, "alerting");
|
||||
return telephony.dialEmergency(number)
|
||||
.then(call => outCall = call)
|
||||
.then(() => {
|
||||
ok(outCall instanceof TelephonyCall, "check instance");
|
||||
ok(outCall);
|
||||
is(outCall.id.number, number);
|
||||
is(outCall.state, "dialing");
|
||||
})
|
||||
.then(() => waitForNamedStateEvent(outCall, "alerting"))
|
||||
.then(() => {
|
||||
is(outCall.emergency, true, "check emergency");
|
||||
return outCall;
|
||||
});
|
||||
}
|
||||
|
||||
@ -1019,6 +1033,37 @@ let emulator = (function() {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Config radio.
|
||||
*
|
||||
* @param connection
|
||||
* MobileConnection object.
|
||||
* @param enabled
|
||||
* True to enable the radio.
|
||||
* @return Promise
|
||||
*/
|
||||
function setRadioEnabled(connection, enabled) {
|
||||
let desiredRadioState = enabled ? 'enabled' : 'disabled';
|
||||
log("Set radio: " + desiredRadioState);
|
||||
|
||||
if (connection.radioState === desiredRadioState) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
let promises = [];
|
||||
|
||||
let promise = gWaitForEvent(connection, "radiostatechange", event => {
|
||||
let state = connection.radioState;
|
||||
log("current radioState: " + state);
|
||||
return state == desiredRadioState;
|
||||
});
|
||||
promises.push(promise);
|
||||
|
||||
promises.push(connection.setRadioEnabled(enabled));
|
||||
|
||||
return Promise.all(promises);
|
||||
}
|
||||
|
||||
/**
|
||||
* Public members.
|
||||
*/
|
||||
@ -1052,6 +1097,7 @@ let emulator = (function() {
|
||||
this.gHangUpCallInConference = hangUpCallInConference;
|
||||
this.gHangUpConference = hangUpConference;
|
||||
this.gSetupConference = setupConference;
|
||||
this.gSetRadioEnabled = setRadioEnabled;
|
||||
}());
|
||||
|
||||
function _startTest(permissions, test) {
|
||||
|
@ -3,71 +3,50 @@ b2g = true
|
||||
browser = false
|
||||
qemu = true
|
||||
|
||||
[test_crash_emulator.js]
|
||||
[test_ready.js]
|
||||
[test_incoming_answer_hangup.js]
|
||||
[test_incoming_reject.js]
|
||||
[test_outgoing_answer_hangup.js]
|
||||
[test_incoming_answer_hangup_oncallschanged.js]
|
||||
[test_outgoing_answer_hangup_oncallschanged.js]
|
||||
[test_outgoing_hangup_alerting.js]
|
||||
[test_outgoing_hangup_held.js]
|
||||
[test_outgoing_radio_off.js]
|
||||
[test_outgoing_badNumber.js]
|
||||
[test_outgoing_busy.js]
|
||||
[test_outgoing_reject.js]
|
||||
[test_incoming_hold_resume.js]
|
||||
[test_outgoing_hold_resume.js]
|
||||
[test_incoming_already_connected.js]
|
||||
[test_incoming_answer_remote_hangup.js]
|
||||
[test_incoming_connecting_hangup.js]
|
||||
[test_incoming_connecting_remote_hangup.js]
|
||||
[test_incoming_hangup_held.js]
|
||||
[test_incoming_remote_cancel.js]
|
||||
[test_incoming_remote_hangup_held.js]
|
||||
[test_outgoing_already_held.js]
|
||||
[test_outgoing_answer_local_hangup.js]
|
||||
[test_outgoing_remote_hangup_held.js]
|
||||
disabled = Bug 820802
|
||||
[test_incoming_already_held.js]
|
||||
disabled = Bug 820802
|
||||
[test_swap_held_and_active.js]
|
||||
disabled = Bug 820802
|
||||
[test_incoming_onstatechange.js]
|
||||
disabled = Bug 820802
|
||||
[test_outgoing_onstatechange.js]
|
||||
disabled = Bug 821966
|
||||
[test_redundant_operations.js]
|
||||
disabled = Bug 821927
|
||||
[test_multiple_hold.js]
|
||||
disabled = Bug 821958
|
||||
[test_outgoing_emergency_in_airplane_mode.js]
|
||||
[test_emergency_label.js]
|
||||
[test_dsds_default_service_id.js]
|
||||
[test_call_mute.js]
|
||||
[test_dsds_normal_call.js]
|
||||
[test_dsds_connection_conflict.js]
|
||||
[test_audiomanager_phonestate.js]
|
||||
[test_outgoing_answer_radio_off.js]
|
||||
[test_conference_two_calls.js]
|
||||
[test_call_mute.js]
|
||||
[test_call_presentation.js]
|
||||
[test_conference_add_error.js]
|
||||
[test_conference_add_twice_error.js]
|
||||
[test_conference_remove_error.js]
|
||||
[test_conference_three_hangup_one.js]
|
||||
[test_conference_three_remove_one.js]
|
||||
[test_conference_two_calls.js]
|
||||
[test_conference_two_hangup_all.js]
|
||||
[test_conference_two_hangup_one.js]
|
||||
[test_conference_two_hold_resume.js]
|
||||
[test_conference_two_remove_one.js]
|
||||
[test_conference_three_hangup_one.js]
|
||||
[test_conference_three_remove_one.js]
|
||||
[test_conference_add_twice_error.js]
|
||||
[test_outgoing_when_two_calls_on_line.js]
|
||||
[test_call_presentation.js]
|
||||
[test_temporary_clir.js]
|
||||
[test_outgoing_error_state.js]
|
||||
[test_outgoing_auto_hold.js]
|
||||
[test_mmi.js]
|
||||
[test_mmi_change_pin.js]
|
||||
[test_mmi_call_forwarding.js]
|
||||
[test_mmi_unlock_puk.js]
|
||||
[test_incall_mmi_call_waiting.js]
|
||||
[test_crash_emulator.js]
|
||||
[test_dsds_connection_conflict.js]
|
||||
[test_dsds_default_service_id.js]
|
||||
[test_dsds_normal_call.js]
|
||||
[test_emergency.js]
|
||||
[test_emergency_label.js]
|
||||
[test_incall_mmi_call_hold.js]
|
||||
[test_incall_mmi_call_waiting.js]
|
||||
[test_incall_mmi_conference.js]
|
||||
[test_incoming_already_connected.js]
|
||||
[test_incoming_already_held.js]
|
||||
[test_incoming_answer_hangup_oncallschanged.js]
|
||||
[test_incoming_basic_operations.js]
|
||||
[test_incoming_connecting_hangup.js]
|
||||
[test_incoming_onstatechange.js]
|
||||
[test_mmi.js]
|
||||
[test_mmi_call_forwarding.js]
|
||||
[test_mmi_change_pin.js]
|
||||
[test_mmi_unlock_puk.js]
|
||||
[test_multiple_hold.js]
|
||||
[test_outgoing_already_held.js]
|
||||
[test_outgoing_answer_hangup_oncallschanged.js]
|
||||
[test_outgoing_answer_radio_off.js]
|
||||
[test_outgoing_auto_hold.js]
|
||||
[test_outgoing_badNumber.js]
|
||||
[test_outgoing_basic_operations.js]
|
||||
[test_outgoing_busy.js]
|
||||
[test_outgoing_onstatechange.js]
|
||||
[test_outgoing_radio_off.js]
|
||||
[test_outgoing_when_two_calls_on_line.js]
|
||||
[test_ready.js]
|
||||
[test_redundant_operations.js]
|
||||
[test_swap_held_and_active.js]
|
||||
[test_temporary_clir.js]
|
||||
|
@ -4,42 +4,23 @@
|
||||
MARIONETTE_TIMEOUT = 60000;
|
||||
MARIONETTE_HEAD_JS = 'head.js';
|
||||
|
||||
let outNumber = "5555551111";
|
||||
let outgoingCall;
|
||||
|
||||
function dial() {
|
||||
log("Make an outgoing call.");
|
||||
telephony.dial(outNumber).then(call => {
|
||||
outgoingCall = call;
|
||||
outgoingCall.onalerting = function onalerting(event) {
|
||||
log("Received 'alerting' call event.");
|
||||
answer();
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function answer() {
|
||||
log("Answering the outgoing call.");
|
||||
|
||||
outgoingCall.onconnected = function onconnectedOut(event) {
|
||||
log("Received 'connected' call event for the original outgoing call.");
|
||||
// just some code to keep call active for awhile
|
||||
callStartTime = Date.now();
|
||||
waitFor(cleanUp,function() {
|
||||
callDuration = Date.now() - callStartTime;
|
||||
log("Waiting while call is active, call duration (ms): " + callDuration);
|
||||
return(callDuration >= 2000);
|
||||
});
|
||||
};
|
||||
emulator.runCmdWithCallback("gsm accept " + outNumber);
|
||||
}
|
||||
|
||||
function cleanUp(){
|
||||
outgoingCall.hangUp();
|
||||
ok("passed");
|
||||
finish();
|
||||
}
|
||||
|
||||
startTest(function() {
|
||||
dial();
|
||||
let outCall;
|
||||
|
||||
gDial("5555551111")
|
||||
.then(call => outCall = call)
|
||||
.then(() => gRemoteAnswer(outCall))
|
||||
.then(() => {
|
||||
return new Promise(function(resolve, reject) {
|
||||
callStartTime = Date.now();
|
||||
waitFor(resolve,function() {
|
||||
callDuration = Date.now() - callStartTime;
|
||||
log("Waiting while call is active, call duration (ms): " + callDuration);
|
||||
return(callDuration >= 2000);
|
||||
});
|
||||
});
|
||||
})
|
||||
.then(() => gHangUp(outCall))
|
||||
.catch(error => ok(false, "Promise reject: " + error))
|
||||
.then(finish);
|
||||
});
|
||||
|
@ -4,85 +4,36 @@
|
||||
MARIONETTE_TIMEOUT = 60000;
|
||||
MARIONETTE_HEAD_JS = 'head.js';
|
||||
|
||||
let number = "911";
|
||||
let outgoing;
|
||||
let calls;
|
||||
let outCall;
|
||||
|
||||
function dial() {
|
||||
log("Make an emergency call.");
|
||||
|
||||
telephony.dialEmergency(number).then(call => {
|
||||
outgoing = call;
|
||||
ok(outgoing);
|
||||
is(outgoing.id.number, number);
|
||||
is(outgoing.state, "dialing");
|
||||
|
||||
is(outgoing, telephony.active);
|
||||
//ok(telephony.calls === calls); // bug 717414
|
||||
is(telephony.calls.length, 1);
|
||||
is(telephony.calls[0], outgoing);
|
||||
|
||||
outgoing.onalerting = function onalerting(event) {
|
||||
log("Received 'onalerting' call event.");
|
||||
is(outgoing, event.call);
|
||||
is(outgoing.state, "alerting");
|
||||
is(outgoing.emergency, true);
|
||||
|
||||
emulator.runCmdWithCallback("gsm list", function(result) {
|
||||
log("Call list is now: " + result);
|
||||
is(result[0], "outbound to " + number + " : ringing");
|
||||
answer();
|
||||
});
|
||||
};
|
||||
});
|
||||
function testEmergencyNumber() {
|
||||
return gDialEmergency("911")
|
||||
.then(call => outCall = call)
|
||||
.then(() => gRemoteAnswer(outCall))
|
||||
.then(() => gHangUp(outCall));
|
||||
}
|
||||
|
||||
function answer() {
|
||||
log("Answering the emergency call.");
|
||||
|
||||
// We get no "connecting" event when the remote party answers the call.
|
||||
|
||||
outgoing.onconnected = function onconnected(event) {
|
||||
log("Received 'connected' call event.");
|
||||
is(outgoing, event.call);
|
||||
is(outgoing.state, "connected");
|
||||
|
||||
is(outgoing, telephony.active);
|
||||
|
||||
emulator.runCmdWithCallback("gsm list", function(result) {
|
||||
log("Call list is now: " + result);
|
||||
is(result[0], "outbound to " + number + " : active");
|
||||
hangUp();
|
||||
function testNormalNumber() {
|
||||
return gDialEmergency("0912345678")
|
||||
.catch(cause => {
|
||||
is(cause, "BadNumberError");
|
||||
return gCheckAll(null, [], "", [], []);
|
||||
});
|
||||
};
|
||||
emulator.runCmdWithCallback("gsm accept " + number);
|
||||
}
|
||||
|
||||
function hangUp() {
|
||||
log("Hanging up the emergency call.");
|
||||
|
||||
// We get no "disconnecting" event when the remote party terminates the call.
|
||||
|
||||
outgoing.ondisconnected = function ondisconnected(event) {
|
||||
log("Received 'disconnected' call event.");
|
||||
is(outgoing, event.call);
|
||||
is(outgoing.state, "disconnected");
|
||||
|
||||
is(telephony.active, null);
|
||||
is(telephony.calls.length, 0);
|
||||
|
||||
emulator.runCmdWithCallback("gsm list", function(result) {
|
||||
log("Call list is now: " + result);
|
||||
cleanUp();
|
||||
function testBadNumber() {
|
||||
return gDialEmergency("not a valid emergency number")
|
||||
.catch(cause => {
|
||||
is(cause, "BadNumberError");
|
||||
return gCheckAll(null, [], "", [], []);
|
||||
});
|
||||
};
|
||||
emulator.runCmdWithCallback("gsm cancel " + number);
|
||||
}
|
||||
|
||||
function cleanUp() {
|
||||
finish();
|
||||
}
|
||||
|
||||
startTest(function() {
|
||||
dial();
|
||||
Promise.resolve()
|
||||
.then(() => testEmergencyNumber())
|
||||
.then(() => testNormalNumber())
|
||||
.then(() => testBadNumber())
|
||||
.catch(error => ok(false, "Promise reject: " + error))
|
||||
.then(finish);
|
||||
});
|
||||
|
@ -1,32 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
MARIONETTE_TIMEOUT = 60000;
|
||||
MARIONETTE_HEAD_JS = 'head.js';
|
||||
|
||||
let number = "not a valid emergency number";
|
||||
|
||||
function dial() {
|
||||
log("Make an outgoing call to an invalid number.");
|
||||
|
||||
telephony.dialEmergency(number).then(null, cause => {
|
||||
log("Received promise 'reject'");
|
||||
|
||||
is(telephony.active, null);
|
||||
is(telephony.calls.length, 0);
|
||||
is(cause, "BadNumberError");
|
||||
|
||||
emulator.runCmdWithCallback("gsm list", function(result) {
|
||||
log("Initial call list: " + result);
|
||||
cleanUp();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function cleanUp() {
|
||||
finish();
|
||||
}
|
||||
|
||||
startTest(function() {
|
||||
dial();
|
||||
});
|
@ -15,30 +15,17 @@ function setEccListProperty(list) {
|
||||
list = "''";
|
||||
}
|
||||
|
||||
let deferred = Promise.defer();
|
||||
try {
|
||||
emulator.runShellCmd(["setprop","ril.ecclist", list]).then(function() {
|
||||
deferred.resolve(list);
|
||||
});
|
||||
} catch (e) {
|
||||
deferred.reject(e);
|
||||
}
|
||||
return deferred.promise;
|
||||
return emulator.runShellCmd(["setprop","ril.ecclist", list])
|
||||
.then(list => list);
|
||||
}
|
||||
|
||||
function getEccListProperty() {
|
||||
log("Get property ril.ecclist.");
|
||||
|
||||
let deferred = Promise.defer();
|
||||
try {
|
||||
emulator.runShellCmd(["getprop","ril.ecclist"]).then(function(aResult) {
|
||||
let list = !aResult.length ? "" : aResult[0];
|
||||
deferred.resolve(list);
|
||||
return emulator.runShellCmd(["getprop","ril.ecclist"])
|
||||
.then(aResult => {
|
||||
return !aResult.length ? "" : aResult[0];
|
||||
});
|
||||
} catch (e) {
|
||||
deferred.reject(e);
|
||||
}
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function testEmergencyLabel(number, list) {
|
||||
@ -53,14 +40,10 @@ function testEmergencyLabel(number, list) {
|
||||
let outCall;
|
||||
|
||||
return gDial(number)
|
||||
.then(call => { outCall = call; })
|
||||
.then(() => {
|
||||
is(outCall.emergency, emergency, "emergency result should be correct");
|
||||
})
|
||||
.then(call => outCall = call)
|
||||
.then(() => is(outCall.emergency, emergency, "check emergency"))
|
||||
.then(() => gRemoteAnswer(outCall))
|
||||
.then(() => {
|
||||
is(outCall.emergency, emergency, "emergency result should be correct");
|
||||
})
|
||||
.then(() => is(outCall.emergency, emergency, "check emergency"))
|
||||
.then(() => gRemoteHangUp(outCall));
|
||||
}
|
||||
|
||||
|
@ -4,189 +4,44 @@
|
||||
MARIONETTE_TIMEOUT = 60000;
|
||||
MARIONETTE_HEAD_JS = 'head.js';
|
||||
|
||||
let outNumber = "5555551111";
|
||||
let inNumber = "5555552222";
|
||||
let outgoingCall;
|
||||
let incomingCall;
|
||||
let gotOriginalConnected = false;
|
||||
const outNumber = "5555551111";
|
||||
const outInfo = gOutCallStrPool(outNumber);
|
||||
let outCall;
|
||||
|
||||
function dial() {
|
||||
log("Make an outgoing call.");
|
||||
telephony.dial(outNumber).then(call => {
|
||||
outgoingCall = call;
|
||||
ok(outgoingCall);
|
||||
is(outgoingCall.id.number, outNumber);
|
||||
is(outgoingCall.state, "dialing");
|
||||
|
||||
is(outgoingCall, telephony.active);
|
||||
is(telephony.calls.length, 1);
|
||||
is(telephony.calls[0], outgoingCall);
|
||||
|
||||
outgoingCall.onalerting = function onalerting(event) {
|
||||
log("Received 'onalerting' call event.");
|
||||
is(outgoingCall, event.call);
|
||||
is(outgoingCall.state, "alerting");
|
||||
|
||||
emulator.runCmdWithCallback("gsm list", function(result) {
|
||||
log("Call list is now: " + result);
|
||||
is(result[0], "outbound to " + outNumber + " : ringing");
|
||||
answer();
|
||||
});
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function answer() {
|
||||
log("Answering the outgoing call.");
|
||||
|
||||
// We get no "connecting" event when the remote party answers the call.
|
||||
outgoingCall.onconnected = function onconnectedOut(event) {
|
||||
log("Received 'connected' call event for the original outgoing call.");
|
||||
|
||||
is(outgoingCall, event.call);
|
||||
is(outgoingCall.state, "connected");
|
||||
is(outgoingCall, telephony.active);
|
||||
|
||||
emulator.runCmdWithCallback("gsm list", function(result) {
|
||||
log("Call list is now: " + result);
|
||||
is(result[0], "outbound to " + outNumber + " : active");
|
||||
|
||||
if(!gotOriginalConnected){
|
||||
gotOriginalConnected = true;
|
||||
simulateIncoming();
|
||||
} else {
|
||||
// Received connected event for original call multiple times (fail)
|
||||
ok(false,
|
||||
"Received 'connected' event for original call multiple times");
|
||||
}
|
||||
});
|
||||
};
|
||||
emulator.runCmdWithCallback("gsm accept " + outNumber);
|
||||
}
|
||||
|
||||
// With one connected call already, simulate an incoming call
|
||||
function simulateIncoming() {
|
||||
log("Simulating an incoming call (with one call already connected).");
|
||||
|
||||
telephony.onincoming = function onincoming(event) {
|
||||
log("Received 'incoming' call event.");
|
||||
incomingCall = event.call;
|
||||
ok(incomingCall);
|
||||
is(incomingCall.id.number, inNumber);
|
||||
is(incomingCall.state, "incoming");
|
||||
|
||||
// Should be two calls now
|
||||
is(telephony.calls.length, 2);
|
||||
is(telephony.calls[0], outgoingCall);
|
||||
is(telephony.calls[1], incomingCall);
|
||||
|
||||
emulator.runCmdWithCallback("gsm list", function(result) {
|
||||
log("Call list is now: " + result);
|
||||
is(result[0], "outbound to " + outNumber + " : active");
|
||||
is(result[1], "inbound from " + inNumber + " : waiting");
|
||||
answerIncoming();
|
||||
});
|
||||
};
|
||||
emulator.runCmdWithCallback("gsm call " + inNumber);
|
||||
}
|
||||
|
||||
// Answer incoming call; original outgoing call should be held
|
||||
function answerIncoming() {
|
||||
log("Answering the incoming call.");
|
||||
|
||||
let gotConnecting = false;
|
||||
incomingCall.onconnecting = function onconnectingIn(event) {
|
||||
log("Received 'connecting' call event for incoming/2nd call.");
|
||||
is(incomingCall, event.call);
|
||||
is(incomingCall.state, "connecting");
|
||||
gotConnecting = true;
|
||||
};
|
||||
|
||||
incomingCall.onconnected = function onconnectedIn(event) {
|
||||
log("Received 'connected' call event for incoming/2nd call.");
|
||||
is(incomingCall, event.call);
|
||||
is(incomingCall.state, "connected");
|
||||
ok(gotConnecting);
|
||||
|
||||
is(incomingCall, telephony.active);
|
||||
is(outgoingCall.state, "held");
|
||||
|
||||
emulator.runCmdWithCallback("gsm list", function(result) {
|
||||
log("Call list is now: " + result);
|
||||
is(result[0], "outbound to " + outNumber + " : held");
|
||||
is(result[1], "inbound from " + inNumber + " : active");
|
||||
hangUpOutgoing();
|
||||
});
|
||||
};
|
||||
incomingCall.answer();
|
||||
}
|
||||
|
||||
// Hang-up original outgoing (now held) call
|
||||
function hangUpOutgoing() {
|
||||
log("Hanging up the original outgoing (now held) call.");
|
||||
|
||||
let gotDisconnecting = false;
|
||||
outgoingCall.ondisconnecting = function ondisconnectingOut(event) {
|
||||
log("Received 'disconnecting' call event for original outgoing call.");
|
||||
is(outgoingCall, event.call);
|
||||
is(outgoingCall.state, "disconnecting");
|
||||
gotDisconnecting = true;
|
||||
};
|
||||
|
||||
outgoingCall.ondisconnected = function ondisconnectedOut(event) {
|
||||
log("Received 'disconnected' call event for original outgoing call.");
|
||||
is(outgoingCall, event.call);
|
||||
is(outgoingCall.state, "disconnected");
|
||||
ok(gotDisconnecting);
|
||||
|
||||
// Back to one call now
|
||||
is(telephony.calls.length, 1);
|
||||
is(incomingCall.state, "connected");
|
||||
|
||||
emulator.runCmdWithCallback("gsm list", function(result) {
|
||||
log("Call list is now: " + result);
|
||||
is(result[0], "inbound from " + inNumber + " : active");
|
||||
hangUpIncoming();
|
||||
});
|
||||
};
|
||||
outgoingCall.hangUp();
|
||||
}
|
||||
|
||||
// Hang-up remaining (incoming) call
|
||||
function hangUpIncoming() {
|
||||
log("Hanging up the remaining (incoming) call.");
|
||||
|
||||
let gotDisconnecting = false;
|
||||
incomingCall.ondisconnecting = function ondisconnectingIn(event) {
|
||||
log("Received 'disconnecting' call event for remaining (incoming) call.");
|
||||
is(incomingCall, event.call);
|
||||
is(incomingCall.state, "disconnecting");
|
||||
gotDisconnecting = true;
|
||||
};
|
||||
|
||||
incomingCall.ondisconnected = function ondisconnectedIn(event) {
|
||||
log("Received 'disconnected' call event for remaining (incoming) call.");
|
||||
is(incomingCall, event.call);
|
||||
is(incomingCall.state, "disconnected");
|
||||
ok(gotDisconnecting);
|
||||
|
||||
// Zero calls left
|
||||
is(telephony.active, null);
|
||||
is(telephony.calls.length, 0);
|
||||
|
||||
emulator.runCmdWithCallback("gsm list", function(result) {
|
||||
log("Call list is now: " + result);
|
||||
cleanUp();
|
||||
});
|
||||
};
|
||||
incomingCall.hangUp();
|
||||
}
|
||||
|
||||
function cleanUp() {
|
||||
telephony.onincoming = null;
|
||||
finish();
|
||||
}
|
||||
const inNumber = "5555552222";
|
||||
const inInfo = gInCallStrPool(inNumber);
|
||||
let inCall;
|
||||
|
||||
startTest(function() {
|
||||
dial();
|
||||
gDial(outNumber)
|
||||
.then(call => outCall = call)
|
||||
.then(() => gCheckAll(outCall, [outCall], "", [], [outInfo.ringing]))
|
||||
.then(() => gRemoteAnswer(outCall))
|
||||
.then(() => gCheckAll(outCall, [outCall], "", [], [outInfo.active]))
|
||||
|
||||
// With one connected call already, simulate an incoming call
|
||||
.then(() => gRemoteDial(inNumber))
|
||||
.then(call => inCall = call)
|
||||
.then(() => gCheckAll(outCall, [outCall, inCall], "", [],
|
||||
[outInfo.active, inInfo.waiting]))
|
||||
|
||||
// Answer incoming call; original outgoing call should be held
|
||||
.then(() => {
|
||||
let p1 = gWaitForNamedStateEvent(outCall, "held");
|
||||
let p2 = gAnswer(inCall);
|
||||
return Promise.all([p1, p2]);
|
||||
})
|
||||
.then(() => gCheckAll(inCall, [outCall, inCall], "", [],
|
||||
[outInfo.held, inInfo.active]))
|
||||
|
||||
// Hang-up original outgoing (now held) call
|
||||
.then(() => gHangUp(outCall))
|
||||
.then(() => gCheckAll(inCall, [inCall], "", [], [inInfo.active]))
|
||||
|
||||
// Hang-up remaining (incoming) call
|
||||
.then(() => gHangUp(inCall))
|
||||
.then(() => gCheckAll(null, [], "", [], []))
|
||||
|
||||
.catch(error => ok(false, "Promise reject: " + error))
|
||||
.then(finish);
|
||||
});
|
||||
|
@ -4,219 +4,42 @@
|
||||
MARIONETTE_TIMEOUT = 60000;
|
||||
MARIONETTE_HEAD_JS = 'head.js';
|
||||
|
||||
let outNumber = "5555551111";
|
||||
let inNumber = "5555552222";
|
||||
let outgoingCall;
|
||||
let incomingCall;
|
||||
let gotOriginalConnected = false;
|
||||
const outNumber = "5555551111";
|
||||
const outInfo = gOutCallStrPool(outNumber);
|
||||
let outCall;
|
||||
|
||||
function dial() {
|
||||
log("Make an outgoing call.");
|
||||
telephony.dial(outNumber).then(call => {
|
||||
outgoingCall = call;
|
||||
ok(outgoingCall);
|
||||
is(outgoingCall.id.number, outNumber);
|
||||
is(outgoingCall.state, "dialing");
|
||||
|
||||
is(outgoingCall, telephony.active);
|
||||
is(telephony.calls.length, 1);
|
||||
is(telephony.calls[0], outgoingCall);
|
||||
|
||||
outgoingCall.onalerting = function onalerting(event) {
|
||||
log("Received 'onalerting' call event.");
|
||||
is(outgoingCall, event.call);
|
||||
is(outgoingCall.state, "alerting");
|
||||
|
||||
emulator.runCmdWithCallback("gsm list", function(result) {
|
||||
log("Call list is now: " + result);
|
||||
is(result[0], "outbound to " + outNumber + " : ringing");
|
||||
answer();
|
||||
});
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function answer() {
|
||||
log("Answering the outgoing call.");
|
||||
|
||||
// We get no "connecting" event when the remote party answers the call.
|
||||
outgoingCall.onconnected = function onconnectedOut(event) {
|
||||
log("Received 'connected' call event for the original outgoing call.");
|
||||
|
||||
is(outgoingCall, event.call);
|
||||
is(outgoingCall.state, "connected");
|
||||
is(outgoingCall, telephony.active);
|
||||
|
||||
emulator.runCmdWithCallback("gsm list", function(result) {
|
||||
log("Call list is now: " + result);
|
||||
is(result[0], "outbound to " + outNumber + " : active");
|
||||
|
||||
if(!gotOriginalConnected){
|
||||
gotOriginalConnected = true;
|
||||
holdCall();
|
||||
} else {
|
||||
// Received connected event for original call multiple times (fail)
|
||||
ok(false,
|
||||
"Received 'connected' event for original call multiple times");
|
||||
}
|
||||
});
|
||||
};
|
||||
emulator.runCmdWithCallback("gsm accept " + outNumber);
|
||||
}
|
||||
|
||||
function holdCall() {
|
||||
log("Putting the original (outgoing) call on hold.");
|
||||
|
||||
let gotHolding = false;
|
||||
outgoingCall.onholding = function onholding(event) {
|
||||
log("Received 'holding' call event");
|
||||
is(outgoingCall, event.call);
|
||||
is(outgoingCall.state, "holding");
|
||||
gotHolding = true;
|
||||
};
|
||||
|
||||
outgoingCall.onheld = function onheld(event) {
|
||||
log("Received 'held' call event");
|
||||
is(outgoingCall, event.call);
|
||||
is(outgoingCall.state, "held");
|
||||
ok(gotHolding);
|
||||
|
||||
is(telephony.active, null);
|
||||
is(telephony.calls.length, 1);
|
||||
is(telephony.calls[0], outgoingCall);
|
||||
|
||||
emulator.runCmdWithCallback("gsm list", function(result) {
|
||||
log("Call list is now: " + result);
|
||||
is(result[0], "outbound to " + outNumber + " : held");
|
||||
simulateIncoming();
|
||||
});
|
||||
};
|
||||
outgoingCall.hold();
|
||||
}
|
||||
|
||||
// With one call on hold, simulate an incoming call
|
||||
function simulateIncoming() {
|
||||
log("Simulating an incoming call (with one call already held).");
|
||||
|
||||
telephony.onincoming = function onincoming(event) {
|
||||
log("Received 'incoming' call event.");
|
||||
incomingCall = event.call;
|
||||
ok(incomingCall);
|
||||
is(incomingCall.id.number, inNumber);
|
||||
is(incomingCall.state, "incoming");
|
||||
|
||||
// Should be two calls now
|
||||
is(telephony.calls.length, 2);
|
||||
is(telephony.calls[0], outgoingCall);
|
||||
is(telephony.calls[1], incomingCall);
|
||||
|
||||
emulator.runCmdWithCallback("gsm list", function(result) {
|
||||
log("Call list is now: " + result);
|
||||
is(result[0], "outbound to " + outNumber + " : held");
|
||||
is(result[1], "inbound from " + inNumber + " : incoming");
|
||||
answerIncoming();
|
||||
});
|
||||
};
|
||||
emulator.runCmdWithCallback("gsm call " + inNumber);
|
||||
}
|
||||
|
||||
// Answer incoming call; original outgoing call should be held
|
||||
function answerIncoming() {
|
||||
log("Answering the incoming call.");
|
||||
|
||||
let gotConnecting = false;
|
||||
incomingCall.onconnecting = function onconnectingIn(event) {
|
||||
log("Received 'connecting' call event for incoming/2nd call.");
|
||||
is(incomingCall, event.call);
|
||||
is(incomingCall.state, "connecting");
|
||||
gotConnecting = true;
|
||||
};
|
||||
|
||||
incomingCall.onconnected = function onconnectedIn(event) {
|
||||
log("Received 'connected' call event for incoming/2nd call.");
|
||||
is(incomingCall, event.call);
|
||||
is(incomingCall.state, "connected");
|
||||
ok(gotConnecting);
|
||||
|
||||
is(incomingCall, telephony.active);
|
||||
is(outgoingCall.state, "held");
|
||||
|
||||
emulator.runCmdWithCallback("gsm list", function(result) {
|
||||
log("Call list is now: " + result);
|
||||
is(result[0], "outbound to " + outNumber + " : held");
|
||||
is(result[1], "inbound from " + inNumber + " : active");
|
||||
hangUpOutgoing();
|
||||
});
|
||||
};
|
||||
incomingCall.answer();
|
||||
}
|
||||
|
||||
// Hang-up original outgoing (now held) call
|
||||
function hangUpOutgoing() {
|
||||
log("Hanging up the original outgoing (now held) call.");
|
||||
|
||||
let gotDisconnecting = false;
|
||||
outgoingCall.ondisconnecting = function ondisconnectingOut(event) {
|
||||
log("Received 'disconnecting' call event for original outgoing call.");
|
||||
is(outgoingCall, event.call);
|
||||
is(outgoingCall.state, "disconnecting");
|
||||
gotDisconnecting = true;
|
||||
};
|
||||
|
||||
outgoingCall.ondisconnected = function ondisconnectedOut(event) {
|
||||
log("Received 'disconnected' call event for original outgoing call.");
|
||||
is(outgoingCall, event.call);
|
||||
is(outgoingCall.state, "disconnected");
|
||||
ok(gotDisconnecting);
|
||||
|
||||
// Back to one call now
|
||||
is(telephony.calls.length, 1);
|
||||
is(incomingCall.state, "connected");
|
||||
|
||||
emulator.runCmdWithCallback("gsm list", function(result) {
|
||||
log("Call list is now: " + result);
|
||||
is(result[0], "inbound from " + inNumber + " : active");
|
||||
hangUpIncoming();
|
||||
});
|
||||
};
|
||||
outgoingCall.hangUp();
|
||||
}
|
||||
|
||||
// Hang-up remaining (incoming) call
|
||||
function hangUpIncoming() {
|
||||
log("Hanging up the remaining (incoming) call.");
|
||||
|
||||
let gotDisconnecting = false;
|
||||
incomingCall.ondisconnecting = function ondisconnectingIn(event) {
|
||||
log("Received 'disconnecting' call event for remaining (incoming) call.");
|
||||
is(incomingCall, event.call);
|
||||
is(incomingCall.state, "disconnecting");
|
||||
gotDisconnecting = true;
|
||||
};
|
||||
|
||||
incomingCall.ondisconnected = function ondisconnectedIn(event) {
|
||||
log("Received 'disconnected' call event for remaining (incoming) call.");
|
||||
is(incomingCall, event.call);
|
||||
is(incomingCall.state, "disconnected");
|
||||
ok(gotDisconnecting);
|
||||
|
||||
// Zero calls left
|
||||
is(telephony.active, null);
|
||||
is(telephony.calls.length, 0);
|
||||
|
||||
emulator.runCmdWithCallback("gsm list", function(result) {
|
||||
log("Call list is now: " + result);
|
||||
cleanUp();
|
||||
});
|
||||
};
|
||||
incomingCall.hangUp();
|
||||
}
|
||||
|
||||
function cleanUp() {
|
||||
telephony.onincoming = null;
|
||||
finish();
|
||||
}
|
||||
const inNumber = "5555552222";
|
||||
const inInfo = gInCallStrPool(inNumber);
|
||||
let inCall;
|
||||
|
||||
startTest(function() {
|
||||
dial();
|
||||
gDial(outNumber)
|
||||
.then(call => outCall = call)
|
||||
.then(() => gCheckAll(outCall, [outCall], "", [], [outInfo.ringing]))
|
||||
.then(() => gRemoteAnswer(outCall))
|
||||
.then(() => gCheckAll(outCall, [outCall], "", [], [outInfo.active]))
|
||||
.then(() => gHold(outCall))
|
||||
.then(() => gCheckAll(null, [outCall], "", [], [outInfo.held]))
|
||||
|
||||
// With one call on hold, simulate an incoming call
|
||||
.then(() => gRemoteDial(inNumber))
|
||||
.then(call => inCall = call)
|
||||
.then(() => gCheckAll(null, [outCall, inCall], "", [],
|
||||
[outInfo.held, inInfo.waiting]))
|
||||
|
||||
// Answer incoming call; original outgoing call should be held
|
||||
.then(() => gAnswer(inCall))
|
||||
.then(() => gCheckAll(inCall, [outCall, inCall], "", [],
|
||||
[outInfo.held, inInfo.active]))
|
||||
|
||||
// Hang-up original outgoing (now held) call
|
||||
.then(() => gHangUp(outCall))
|
||||
.then(() => gCheckAll(inCall, [inCall], "", [], [inInfo.active]))
|
||||
|
||||
// Hang-up remaining (incoming) call
|
||||
.then(() => gHangUp(inCall))
|
||||
.then(() => gCheckAll(null, [], "", [], []))
|
||||
|
||||
.catch(error => ok(false, "Promise reject: " + error))
|
||||
.then(finish);
|
||||
});
|
||||
|
@ -1,97 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
MARIONETTE_TIMEOUT = 60000;
|
||||
MARIONETTE_HEAD_JS = 'head.js';
|
||||
|
||||
let number = "5555552368";
|
||||
let incoming;
|
||||
let calls;
|
||||
|
||||
function simulateIncoming() {
|
||||
log("Simulating an incoming call.");
|
||||
|
||||
telephony.onincoming = function onincoming(event) {
|
||||
log("Received 'incoming' call event.");
|
||||
incoming = event.call;
|
||||
ok(incoming);
|
||||
is(incoming.id.number, number);
|
||||
is(incoming.state, "incoming");
|
||||
|
||||
//ok(telephony.calls === calls); // bug 717414
|
||||
is(telephony.calls.length, 1);
|
||||
is(telephony.calls[0], incoming);
|
||||
|
||||
emulator.runCmdWithCallback("gsm list", function(result) {
|
||||
log("Call list is now: " + result);
|
||||
is(result[0], "inbound from " + number + " : incoming");
|
||||
answer();
|
||||
});
|
||||
};
|
||||
emulator.runCmdWithCallback("gsm call " + number);
|
||||
}
|
||||
|
||||
function answer() {
|
||||
log("Answering the incoming call.");
|
||||
|
||||
let gotConnecting = false;
|
||||
incoming.onconnecting = function onconnecting(event) {
|
||||
log("Received 'connecting' call event.");
|
||||
is(incoming, event.call);
|
||||
is(incoming.state, "connecting");
|
||||
gotConnecting = true;
|
||||
};
|
||||
|
||||
incoming.onconnected = function onconnected(event) {
|
||||
log("Received 'connected' call event.");
|
||||
is(incoming, event.call);
|
||||
is(incoming.state, "connected");
|
||||
ok(gotConnecting);
|
||||
|
||||
is(incoming, telephony.active);
|
||||
|
||||
emulator.runCmdWithCallback("gsm list", function(result) {
|
||||
log("Call list is now: " + result);
|
||||
is(result[0], "inbound from " + number + " : active");
|
||||
hangUp();
|
||||
});
|
||||
};
|
||||
incoming.answer();
|
||||
}
|
||||
|
||||
function hangUp() {
|
||||
log("Hanging up the incoming call.");
|
||||
|
||||
let gotDisconnecting = false;
|
||||
incoming.ondisconnecting = function ondisconnecting(event) {
|
||||
log("Received 'disconnecting' call event.");
|
||||
is(incoming, event.call);
|
||||
is(incoming.state, "disconnecting");
|
||||
gotDisconnecting = true;
|
||||
};
|
||||
|
||||
incoming.ondisconnected = function ondisconnected(event) {
|
||||
log("Received 'disconnected' call event.");
|
||||
is(incoming, event.call);
|
||||
is(incoming.state, "disconnected");
|
||||
ok(gotDisconnecting);
|
||||
|
||||
is(telephony.active, null);
|
||||
is(telephony.calls.length, 0);
|
||||
|
||||
emulator.runCmdWithCallback("gsm list", function(result) {
|
||||
log("Call list is now: " + result);
|
||||
cleanUp();
|
||||
});
|
||||
};
|
||||
incoming.hangUp();
|
||||
}
|
||||
|
||||
function cleanUp() {
|
||||
telephony.onincoming = null;
|
||||
finish();
|
||||
}
|
||||
|
||||
startTest(function() {
|
||||
simulateIncoming();
|
||||
});
|