author | Wes Kocher <wkocher@mozilla.com> |
Thu, 18 Sep 2014 16:10:03 -0700 | |
changeset 206099 | 245051c6a7ede4ddedb24d6a58b25bf4f8132026 |
parent 206028 | 9a4f85820092e7186bb8b3c7d901522ca8c84977 (current diff) |
parent 206098 | c8e325eee9e1ca005bd1727672fefdca37e241c9 (diff) |
child 206100 | ca7e71c15c4f1b302df06994695e049b8741e89f |
push id | 49338 |
push user | kwierso@gmail.com |
push date | Thu, 18 Sep 2014 23:10:09 +0000 |
treeherder | mozilla-inbound@245051c6a7ed [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | merge |
milestone | 35.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
layout/base/tests/bug558663.html | file | annotate | diff | comparison | revisions |
--- a/b2g/app/b2g.js +++ b/b2g/app/b2g.js @@ -1002,18 +1002,18 @@ pref("gfx.canvas.willReadFrequently.enab pref("browser.autofocus", false); // Enable wakelock pref("dom.wakelock.enabled", true); // Enable touch caret by default pref("touchcaret.enabled", true); -// Enable selection caret by default -pref("selectioncaret.enabled", true); +// Disable selection caret by default +pref("selectioncaret.enabled", false); // Enable sync and mozId with Firefox Accounts. pref("services.sync.fxaccounts.enabled", true); pref("identity.fxaccounts.enabled", true); // Mobile Identity API. pref("services.mobileid.server.uri", "https://msisdn.services.mozilla.com");
--- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -10,17 +10,17 @@ <!--original fetch url was git://codeaurora.org/--> <remote fetch="https://git.mozilla.org/external/caf" name="caf"/> <!--original fetch url was https://git.mozilla.org/releases--> <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/> <!-- B2G specific things. --> <project name="platform_build" path="build" remote="b2g" revision="fe92ddd450e03b38edb2d465de7897971d68ac68"> <copyfile dest="Makefile" src="core/root.mk"/> </project> - <project name="gaia" path="gaia" remote="mozillaorg" revision="d37950eb09e28aa18d0e01df9ff90574bd4337e0"/> + <project name="gaia" path="gaia" remote="mozillaorg" revision="bc2da39ccd2b82b67773f10c8da8fc8eedc483ab"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f2f293787d4a86257c9e78a35bd3f73b31b706e2"/> <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/> <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/> <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="f3e998242fb9a857cf50f5bf3a02304a530ea617"/> @@ -131,13 +131,13 @@ <project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="4e58336019b5cbcfd134caf55b142236cf986618"/> <project name="platform/frameworks/av" path="frameworks/av" revision="facca8d3e35431b66f85a4eb42bc6c5b24bd04da"/> <project name="platform/hardware/akm" path="hardware/akm" revision="6d3be412647b0eab0adff8a2768736cf4eb68039"/> <project groups="invensense" name="platform/hardware/invensense" path="hardware/invensense" revision="e6d9ab28b4f4e7684f6c07874ee819c9ea0002a2"/> <project name="platform/hardware/ril" path="hardware/ril" revision="865ce3b4a2ba0b3a31421ca671f4d6c5595f8690"/> <project name="kernel/common" path="kernel" revision="28aab3bd1139b6beea545f50dee8903c0634de84"/> <project name="platform/system/core" path="system/core" revision="53d584d4a4b4316e4de9ee5f210d662f89b44e7e"/> <project name="u-boot" path="u-boot" revision="2d7a801a3e002078f885e8085fad374a564682e5"/> - <project name="vendor/sprd/gps" path="vendor/sprd/gps" revision="7feb3df0e150053e0143ef525f6e082bda320aea"/> + <project name="vendor/sprd/gps" path="vendor/sprd/gps" revision="6974f8e771d4d8e910357a6739ab124768891e8f"/> <project name="vendor/sprd/open-source" path="vendor/sprd/open-source" revision="69c8c336794666b010e34b2f501d89118513c546"/> <project name="vendor/sprd/partner" path="vendor/sprd/partner" revision="8649c7145972251af11b0639997edfecabfc7c2e"/> <project name="vendor/sprd/proprietories" path="vendor/sprd/proprietories" revision="d2466593022f7078aaaf69026adf3367c2adb7bb"/> </manifest>
--- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -14,17 +14,17 @@ <!--original fetch url was git://github.com/apitrace/--> <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/> <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/> <!-- Gonk specific things and forks --> <project name="platform_build" path="build" remote="b2g" revision="4d1e85908d792d9468c4da7040acd191fbb51b40"> <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="d37950eb09e28aa18d0e01df9ff90574bd4337e0"/> + <project name="gaia.git" path="gaia" remote="mozillaorg" revision="bc2da39ccd2b82b67773f10c8da8fc8eedc483ab"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f2f293787d4a86257c9e78a35bd3f73b31b706e2"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/> <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="c058843242068d0df7c107e09da31b53d2e08fa6"/> <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/> <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f3e998242fb9a857cf50f5bf3a02304a530ea617"/> <!-- Stock Android things --> <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
--- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -12,17 +12,17 @@ <!--original fetch url was https://git.mozilla.org/releases--> <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/> <!-- B2G specific things. --> <project name="platform_build" path="build" remote="b2g" revision="8986df0f82e15ac2798df0b6c2ee3435400677ac"> <copyfile dest="Makefile" src="core/root.mk"/> </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="d37950eb09e28aa18d0e01df9ff90574bd4337e0"/> + <project name="gaia" path="gaia" remote="mozillaorg" revision="bc2da39ccd2b82b67773f10c8da8fc8eedc483ab"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f2f293787d4a86257c9e78a35bd3f73b31b706e2"/> <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/> <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f3e998242fb9a857cf50f5bf3a02304a530ea617"/> <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/> <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/> <!-- Stock Android things --> <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/> <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
--- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -10,17 +10,17 @@ <!--original fetch url was git://codeaurora.org/--> <remote fetch="https://git.mozilla.org/external/caf" name="caf"/> <!--original fetch url was https://git.mozilla.org/releases--> <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/> <!-- B2G specific things. --> <project name="platform_build" path="build" remote="b2g" revision="fe92ddd450e03b38edb2d465de7897971d68ac68"> <copyfile dest="Makefile" src="core/root.mk"/> </project> - <project name="gaia" path="gaia" remote="mozillaorg" revision="d37950eb09e28aa18d0e01df9ff90574bd4337e0"/> + <project name="gaia" path="gaia" remote="mozillaorg" revision="bc2da39ccd2b82b67773f10c8da8fc8eedc483ab"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f2f293787d4a86257c9e78a35bd3f73b31b706e2"/> <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/> <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/> <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="f3e998242fb9a857cf50f5bf3a02304a530ea617"/>
--- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -14,17 +14,17 @@ <!--original fetch url was git://github.com/apitrace/--> <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/> <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/> <!-- Gonk specific things and forks --> <project name="platform_build" path="build" remote="b2g" revision="4d1e85908d792d9468c4da7040acd191fbb51b40"> <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="d37950eb09e28aa18d0e01df9ff90574bd4337e0"/> + <project name="gaia.git" path="gaia" remote="mozillaorg" revision="bc2da39ccd2b82b67773f10c8da8fc8eedc483ab"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f2f293787d4a86257c9e78a35bd3f73b31b706e2"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/> <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="c058843242068d0df7c107e09da31b53d2e08fa6"/> <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/> <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f3e998242fb9a857cf50f5bf3a02304a530ea617"/> <!-- Stock Android things --> <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
--- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -10,17 +10,17 @@ <!--original fetch url was git://codeaurora.org/--> <remote fetch="https://git.mozilla.org/external/caf" name="caf"/> <!--original fetch url was https://git.mozilla.org/releases--> <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/> <!-- B2G specific things. --> <project name="platform_build" path="build" remote="b2g" revision="fe92ddd450e03b38edb2d465de7897971d68ac68"> <copyfile dest="Makefile" src="core/root.mk"/> </project> - <project name="gaia" path="gaia" remote="mozillaorg" revision="d37950eb09e28aa18d0e01df9ff90574bd4337e0"/> + <project name="gaia" path="gaia" remote="mozillaorg" revision="bc2da39ccd2b82b67773f10c8da8fc8eedc483ab"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f2f293787d4a86257c9e78a35bd3f73b31b706e2"/> <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/> <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/> <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="f3e998242fb9a857cf50f5bf3a02304a530ea617"/>
--- a/b2g/config/flame/sources.xml +++ b/b2g/config/flame/sources.xml @@ -12,17 +12,17 @@ <!--original fetch url was https://git.mozilla.org/releases--> <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/> <!-- B2G specific things. --> <project name="platform_build" path="build" remote="b2g" revision="8986df0f82e15ac2798df0b6c2ee3435400677ac"> <copyfile dest="Makefile" src="core/root.mk"/> </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="d37950eb09e28aa18d0e01df9ff90574bd4337e0"/> + <project name="gaia" path="gaia" remote="mozillaorg" revision="bc2da39ccd2b82b67773f10c8da8fc8eedc483ab"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f2f293787d4a86257c9e78a35bd3f73b31b706e2"/> <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/> <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f3e998242fb9a857cf50f5bf3a02304a530ea617"/> <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/> <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/> <!-- Stock Android things --> <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="e95b4ce22c825da44d14299e1190ea39a5260bde"/> <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="471afab478649078ad7c75ec6b252481a59e19b8"/>
--- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,9 +1,9 @@ { "git": { "git_revision": "", "remote": "", "branch": "" }, - "revision": "7075f5263087e8edd48bccd5289320d61b6ed6d7", + "revision": "cc0cc3a29b940c3b2e7434540f0e7263458a925d", "repo_path": "/integration/gaia-central" }
--- a/b2g/config/hamachi/sources.xml +++ b/b2g/config/hamachi/sources.xml @@ -12,17 +12,17 @@ <!--original fetch url was git://github.com/apitrace/--> <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/> <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/> <!-- Gonk specific things and forks --> <project name="platform_build" path="build" remote="b2g" revision="4d1e85908d792d9468c4da7040acd191fbb51b40"> <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="d37950eb09e28aa18d0e01df9ff90574bd4337e0"/> + <project name="gaia.git" path="gaia" remote="mozillaorg" revision="bc2da39ccd2b82b67773f10c8da8fc8eedc483ab"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f2f293787d4a86257c9e78a35bd3f73b31b706e2"/> <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="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/> <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f3e998242fb9a857cf50f5bf3a02304a530ea617"/> <!-- Stock Android things --> <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/> <project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
--- a/b2g/config/helix/sources.xml +++ b/b2g/config/helix/sources.xml @@ -10,17 +10,17 @@ <!--original fetch url was https://git.mozilla.org/releases--> <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/> <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/> <!-- Gonk specific things and forks --> <project name="platform_build" path="build" remote="b2g" revision="4d1e85908d792d9468c4da7040acd191fbb51b40"> <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="d37950eb09e28aa18d0e01df9ff90574bd4337e0"/> + <project name="gaia.git" path="gaia" remote="mozillaorg" revision="bc2da39ccd2b82b67773f10c8da8fc8eedc483ab"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f2f293787d4a86257c9e78a35bd3f73b31b706e2"/> <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="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/> <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/> <!-- Stock Android things --> <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/> <project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
--- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -12,17 +12,17 @@ <!--original fetch url was https://git.mozilla.org/releases--> <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/> <!-- B2G specific things. --> <project name="platform_build" path="build" remote="b2g" revision="8986df0f82e15ac2798df0b6c2ee3435400677ac"> <copyfile dest="Makefile" src="core/root.mk"/> </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="d37950eb09e28aa18d0e01df9ff90574bd4337e0"/> + <project name="gaia" path="gaia" remote="mozillaorg" revision="bc2da39ccd2b82b67773f10c8da8fc8eedc483ab"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f2f293787d4a86257c9e78a35bd3f73b31b706e2"/> <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/> <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f3e998242fb9a857cf50f5bf3a02304a530ea617"/> <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/> <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/> <!-- Stock Android things --> <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/> <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
--- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -12,17 +12,17 @@ <!--original fetch url was git://github.com/apitrace/--> <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/> <default remote="caf" revision="ics_chocolate_rb4.2" sync-j="4"/> <!-- Gonk specific things and forks --> <project name="platform_build" path="build" remote="b2g" revision="4d1e85908d792d9468c4da7040acd191fbb51b40"> <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="d37950eb09e28aa18d0e01df9ff90574bd4337e0"/> + <project name="gaia.git" path="gaia" remote="mozillaorg" revision="bc2da39ccd2b82b67773f10c8da8fc8eedc483ab"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f2f293787d4a86257c9e78a35bd3f73b31b706e2"/> <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="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/> <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f3e998242fb9a857cf50f5bf3a02304a530ea617"/> <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/> <!-- Stock Android things --> <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
--- a/browser/base/content/browser-sets.inc +++ b/browser/base/content/browser-sets.inc @@ -341,21 +341,21 @@ <key id="goForwardKb" keycode="VK_RIGHT" command="Browser:Forward" modifiers="accel" /> #endif #ifdef XP_UNIX <key id="goBackKb2" key="&goBackCmd.commandKey;" command="Browser:Back" modifiers="accel"/> <key id="goForwardKb2" key="&goForwardCmd.commandKey;" command="Browser:Forward" modifiers="accel"/> #endif <key id="goHome" keycode="VK_HOME" command="Browser:Home" modifiers="alt"/> <key keycode="VK_F5" command="Browser:Reload"/> + <key keycode="VK_F6" command="Browser:FocusNextFrame"/> + <key keycode="VK_F6" command="Browser:FocusNextFrame" modifiers="shift"/> #ifndef XP_MACOSX <key id="showAllHistoryKb" key="&showAllHistoryCmd.commandkey;" command="Browser:ShowAllHistory" modifiers="accel,shift"/> <key keycode="VK_F5" command="Browser:ReloadSkipCache" modifiers="accel"/> - <key keycode="VK_F6" command="Browser:FocusNextFrame"/> - <key keycode="VK_F6" command="Browser:FocusNextFrame" modifiers="shift"/> <key id="key_fullScreen" keycode="VK_F11" command="View:FullScreen"/> #else <key id="key_fullScreen" key="&fullScreenCmd.macCommandKey;" command="View:FullScreen" modifiers="accel,control"/> <key id="key_fullScreen_old" key="&fullScreenCmd.macCommandKey;" command="View:FullScreen" modifiers="accel,shift"/> <key keycode="VK_F11" command="View:FullScreen"/> #endif <key key="&reloadCmd.commandkey;" command="Browser:Reload" modifiers="accel" id="key_reload"/> <key key="&reloadCmd.commandkey;" command="Browser:ReloadSkipCache" modifiers="accel,shift"/>
--- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -7259,17 +7259,19 @@ var MousePosTracker = { } } }; function focusNextFrame(event) { let fm = Services.focus; let dir = event.shiftKey ? fm.MOVEFOCUS_BACKWARDDOC : fm.MOVEFOCUS_FORWARDDOC; let element = fm.moveFocus(window, null, dir, fm.FLAG_BYKEY); - if (element.ownerDocument == document) + let panelOrNotificationSelector = "popupnotification " + element.localName + ", " + + "panel " + element.localName; + if (element.ownerDocument == document && !element.matches(panelOrNotificationSelector)) focusAndSelectUrlBar(); } function BrowserOpenNewTabOrWindow(event) { if (event.shiftKey) { OpenBrowserWindow(); } else { BrowserOpenTab();
--- a/browser/base/content/searchSuggestionUI.js +++ b/browser/base/content/searchSuggestionUI.js @@ -91,46 +91,46 @@ SearchSuggestionUIController.prototype = // Update the table's rows, and the input when there is a selection. this._table.removeAttribute("aria-activedescendant"); for (let i = 0; i < this._table.children.length; i++) { let row = this._table.children[i]; if (i == idx) { row.classList.add("selected"); row.firstChild.setAttribute("aria-selected", "true"); this._table.setAttribute("aria-activedescendant", row.firstChild.id); - this.input.value = this.suggestionAtIndex(i); } else { row.classList.remove("selected"); row.firstChild.setAttribute("aria-selected", "false"); } } - - // Update the input when there is no selection. - if (idx < 0) { - this.input.value = this._stickyInputValue; - } }, get numSuggestions() { return this._table.children.length; }, + selectAndUpdateInput: function (idx) { + this.selectedIndex = idx; + this.input.value = idx >= 0 ? this.suggestionAtIndex(idx) : + this._stickyInputValue; + }, + suggestionAtIndex: function (idx) { let row = this._table.children[idx]; return row ? row.textContent : null; }, deleteSuggestionAtIndex: function (idx) { // Only form history suggestions can be deleted. if (this.isFormHistorySuggestionAtIndex(idx)) { let suggestionStr = this.suggestionAtIndex(idx); this._sendMsg("RemoveFormHistoryEntry", suggestionStr); this._table.children[idx].remove(); - this.selectedIndex = -1; + this.selectAndUpdateInput(-1); } }, isFormHistorySuggestionAtIndex: function (idx) { let row = this._table.children[idx]; return row && row.classList.contains("formHistory"); }, @@ -145,17 +145,17 @@ SearchSuggestionUIController.prototype = _onInput: function () { if (this.input.value) { this._getSuggestions(); } else { this._stickyInputValue = ""; this._hideSuggestions(); } - this.selectedIndex = -1; + this.selectAndUpdateInput(-1); }, _onKeypress: function (event) { let selectedIndexDelta = 0; switch (event.keyCode) { case event.DOM_VK_UP: if (this.numSuggestions) { selectedIndexDelta = -1; @@ -203,31 +203,35 @@ SearchSuggestionUIController.prototype = // Update the selection. let newSelectedIndex = this.selectedIndex + selectedIndexDelta; if (newSelectedIndex < -1) { newSelectedIndex = this.numSuggestions - 1; } else if (this.numSuggestions <= newSelectedIndex) { newSelectedIndex = -1; } - this.selectedIndex = newSelectedIndex; + this.selectAndUpdateInput(newSelectedIndex); // Prevent the input's caret from moving. event.preventDefault(); } }, _onFocus: function () { this._speculativeConnect(); }, _onBlur: function () { this._hideSuggestions(); }, + _onMousemove: function (event) { + this.selectedIndex = this._indexOfTableRowOrDescendent(event.target); + }, + _onMousedown: function (event) { let idx = this._indexOfTableRowOrDescendent(event.target); let suggestion = this.suggestionAtIndex(idx); this._stickyInputValue = suggestion; this.input.value = suggestion; this.input.setAttribute("selection-index", idx); this.input.setAttribute("selection-kind", "mouse"); this._hideSuggestions(); @@ -295,16 +299,17 @@ SearchSuggestionUIController.prototype = } }, _makeTableRow: function (type, suggestionStr, currentRow, searchWords) { let row = document.createElementNS(HTML_NS, "tr"); row.classList.add("searchSuggestionRow"); row.classList.add(type); row.setAttribute("role", "presentation"); + row.addEventListener("mousemove", this); row.addEventListener("mousedown", this); let entry = document.createElementNS(HTML_NS, "td"); entry.classList.add("searchSuggestionEntry"); entry.setAttribute("role", "option"); entry.id = this._idPrefix + SUGGESTION_ID_PREFIX + currentRow; entry.setAttribute("aria-selected", "false"); @@ -338,17 +343,17 @@ SearchSuggestionUIController.prototype = }, _hideSuggestions: function () { this.input.setAttribute("aria-expanded", "false"); this._table.hidden = true; while (this._table.firstElementChild) { this._table.firstElementChild.remove(); } - this.selectedIndex = -1; + this.selectAndUpdateInput(-1); }, _indexOfTableRowOrDescendent: function (row) { while (row && row.localName != "tr") { row = row.parentNode; } if (!row) { throw new Error("Element is not a row");
--- a/browser/base/content/test/general/browser_mixedcontent_securityflags.js +++ b/browser/base/content/test/general/browser_mixedcontent_securityflags.js @@ -38,24 +38,37 @@ function blockMixedContentTest() function overrideMCB() { // test mixed content flags on load (reload) gTestBrowser.addEventListener("load", mixedContentOverrideTest, true); var notification = PopupNotifications.getNotification("bad-content", gTestBrowser); ok(notification, "Mixed Content Doorhanger should appear"); notification.reshow(); ok(PopupNotifications.panel.firstChild.isMixedContentBlocked, "OK: Mixed Content is being blocked"); + + // Make sure the notification has no mixedblockdisabled attribute + ok(!PopupNotifications.panel.firstChild.hasAttribute("mixedblockdisabled"), + "Doorhanger must have no mixedblockdisabled attribute"); // Click on the doorhanger to allow mixed content (and reload page) PopupNotifications.panel.firstChild.disableMixedContentProtection(); notification.remove(); } function mixedContentOverrideTest() { gTestBrowser.removeEventListener("load", mixedContentOverrideTest, true); is(gTestBrowser.docShell.hasMixedDisplayContentLoaded, true, "hasMixedDisplayContentLoaded flag has not been set"); is(gTestBrowser.docShell.hasMixedActiveContentLoaded, true, "hasMixedActiveContentLoaded flag has not been set"); is(gTestBrowser.docShell.hasMixedDisplayContentBlocked, false, "second hasMixedDisplayContentBlocked flag has been set"); is(gTestBrowser.docShell.hasMixedActiveContentBlocked, false, "second hasMixedActiveContentBlocked flag has been set"); + + let notification = PopupNotifications.getNotification("bad-content", gTestBrowser); + ok(notification, "Mixed Content Doorhanger should appear"); + notification.reshow(); + + // Make sure the notification has the mixedblockdisabled attribute set to true + is(PopupNotifications.panel.firstChild.getAttribute("mixedblockdisabled"), "true", + "Doorhanger must have [mixedblockdisabled='true'] attribute"); + gBrowser.removeCurrentTab(); finish(); }
--- a/browser/base/content/test/general/browser_searchSuggestionUI.js +++ b/browser/base/content/test/general/browser_searchSuggestionUI.js @@ -97,16 +97,24 @@ add_task(rightArrowOrReturn("VK_RIGHT")) add_task(rightArrowOrReturn("VK_RETURN")); add_task(function* mouse() { yield setUp(); let state = yield msg("key", { key: "x", waitForSuggestions: true }); checkState(state, "x", ["xfoo", "xbar"], -1); + // Mouse over the first suggestion. + state = yield msg("mousemove", 0); + checkState(state, "x", ["xfoo", "xbar"], 0); + + // Mouse over the second suggestion. + state = yield msg("mousemove", 1); + checkState(state, "x", ["xfoo", "xbar"], 1); + // Click the second suggestion. This should make it sticky. To make sure it // sticks, trigger suggestions again and cycle through them by pressing Down // until nothing is selected again. state = yield msg("mousedown", 1); checkState(state, "xbar", [], -1); state = yield msg("key", { key: "VK_DOWN", waitForSuggestions: true }); checkState(state, "xbar", ["xbarfoo", "xbarbar"], -1);
--- a/browser/base/content/test/general/browser_trackingUI.js +++ b/browser/base/content/test/general/browser_trackingUI.js @@ -63,29 +63,37 @@ function testTrackingPage(gTestBrowser) // Make sure the doorhanger appears var notification = PopupNotifications.getNotification("bad-content", gTestBrowser); isnot(notification, null, "Tracking Content Doorhanger did appear when protection was ON and tracking was present"); notification.reshow(); // Make sure the state of the doorhanger includes blocking tracking elements isnot(PopupNotifications.panel.firstChild.isTrackingContentBlocked, 0, "Tracking Content is being blocked"); + // Make sure the notification has no trackingblockdisabled attribute + ok(!PopupNotifications.panel.firstChild.hasAttribute("trackingblockdisabled"), + "Doorhanger must have no trackingblockdisabled attribute"); + // Disable Tracking Content Protection for the page (which reloads the page) PopupNotifications.panel.firstChild.disableTrackingContentProtection(); } function testTrackingPageWhitelisted(gTestBrowser) { // Make sure the doorhanger appears var notification = PopupNotifications.getNotification("bad-content", gTestBrowser); isnot(notification, null, "Tracking Content Doorhanger did appear when protection was ON and tracking was present but white-listed"); notification.reshow(); // Make sure the state of the doorhanger does NOT include blocking tracking elements is(PopupNotifications.panel.firstChild.isTrackingContentBlocked, 0, "Tracking Content is NOT being blocked"); + + // Make sure the notification has the trackingblockdisabled attribute set to true + is(PopupNotifications.panel.firstChild.getAttribute("trackingblockdisabled"), "true", + "Doorhanger must have [trackingblockdisabled='true'] attribute"); } function testTrackingPageOFF(gTestBrowser) { // Make sure the doorhanger does NOT appear var notification = PopupNotifications.getNotification("bad-content", gTestBrowser); is(notification, null, "Tracking Content Doorhanger did NOT appear when protection was OFF and tracking was present"); }
--- a/browser/base/content/test/general/searchSuggestionUI.js +++ b/browser/base/content/test/general/searchSuggestionUI.js @@ -32,16 +32,43 @@ let messageHandlers = { ack(); }, blur: function () { gController.input.blur(); ack(); }, + mousemove: function (suggestionIdx) { + // Copied from widget/tests/test_panel_mouse_coords.xul and + // browser/base/content/test/newtab/head.js + let row = gController._table.children[suggestionIdx]; + let rect = row.getBoundingClientRect(); + let left = content.mozInnerScreenX + rect.left; + let x = left + rect.width / 2; + let y = content.mozInnerScreenY + rect.top + rect.height / 2; + + let utils = content.SpecialPowers.getDOMWindowUtils(content); + let scale = utils.screenPixelsPerCSSPixel; + + let widgetToolkit = content.SpecialPowers. + Cc["@mozilla.org/xre/app-info;1"]. + getService(content.SpecialPowers.Ci.nsIXULRuntime). + widgetToolkit; + let nativeMsg = widgetToolkit == "cocoa" ? 5 : // NSMouseMoved + widgetToolkit == "windows" ? 1 : // MOUSEEVENTF_MOVE + 3; // GDK_MOTION_NOTIFY + + row.addEventListener("mousemove", function onMove() { + row.removeEventListener("mousemove", onMove); + ack(); + }); + utils.sendNativeMouseEvent(x * scale, y * scale, nativeMsg, 0, null); + }, + mousedown: function (suggestionIdx) { gController.onClick = () => { gController.onClick = null; ack(); }; let row = gController._table.children[suggestionIdx]; content.sendMouseEvent({ type: "mousedown" }, row); },
--- a/browser/base/content/urlbarBindings.xml +++ b/browser/base/content/urlbarBindings.xml @@ -1623,17 +1623,17 @@ </setter> </property> </implementation> </binding> <binding id="bad-content-notification" extends="chrome://global/content/bindings/notification.xml#popup-notification"> <content> <xul:hbox align="start"> - <xul:image class="popup-notification-icon" xbl:inherits="popupid"/> + <xul:image class="popup-notification-icon" xbl:inherits="popupid,mixedblockdisabled,trackingblockdisabled"/> <xul:vbox> <!-- header --> <xul:vbox> <xul:description anonid="badContentBlocked.title" class="popup-notification-item-title" xbl:inherits="popupid"> </xul:description> <xul:description class="popup-notification-item-message" xbl:inherits="popupid">
--- a/browser/components/loop/MozLoopAPI.jsm +++ b/browser/components/loop/MozLoopAPI.jsm @@ -1,16 +1,17 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ "use strict"; const { classes: Cc, interfaces: Ci, utils: Cu } = Components; +Cu.import("resource://services-common/utils.js"); Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource:///modules/loop/MozLoopService.jsm"); Cu.import("resource:///modules/loop/LoopContacts.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "hookWindowCloseForPanelClose", "resource://gre/modules/MozSocialAPI.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "PluralForm", @@ -18,16 +19,19 @@ XPCOMUtils.defineLazyModuleGetter(this, XPCOMUtils.defineLazyGetter(this, "appInfo", function() { return Cc["@mozilla.org/xre/app-info;1"] .getService(Ci.nsIXULAppInfo) .QueryInterface(Ci.nsIXULRuntime); }); XPCOMUtils.defineLazyServiceGetter(this, "clipboardHelper", "@mozilla.org/widget/clipboardhelper;1", "nsIClipboardHelper"); +XPCOMUtils.defineLazyServiceGetter(this, "extProtocolSvc", + "@mozilla.org/uriloader/external-protocol-service;1", + "nsIExternalProtocolService"); this.EXPORTED_SYMBOLS = ["injectLoopAPI"]; /** * Trying to clone an Error object into a different container will yield an error. * We can work around this by copying the properties we care about onto a regular * object. * * @param {Error} error Error object to copy @@ -450,16 +454,46 @@ function injectLoopAPI(targetWindow) { channel: defaults.getCharPref("app.update.channel"), version: appInfo.version, OS: appInfo.OS }, targetWindow); } return appVersionInfo; } }, + + /** + * Composes an email via the external protocol service. + * + * @param {String} subject Subject of the email to send + * @param {String} body Body message of the email to send + */ + composeEmail: { + enumerable: true, + writable: true, + value: function(subject, body) { + let mailtoURL = "mailto:?subject=" + encodeURIComponent(subject) + "&" + + "body=" + encodeURIComponent(body); + extProtocolSvc.loadURI(CommonUtils.makeURI(mailtoURL)); + } + }, + + /** + * Adds a value to a telemetry histogram. + * + * @param {string} histogramId Name of the telemetry histogram to update. + * @param {integer} value Value to add to the histogram. + */ + telemetryAdd: { + enumerable: true, + writable: true, + value: function(histogramId, value) { + Services.telemetry.getHistogramById(histogramId).add(value); + } + }, }; function onStatusChanged(aSubject, aTopic, aData) { let event = new targetWindow.CustomEvent("LoopStatusChanged"); targetWindow.dispatchEvent(event) }; function onDOMWindowDestroyed(aSubject, aTopic, aData) {
--- a/browser/components/loop/content/js/client.js +++ b/browser/components/loop/content/js/client.js @@ -106,25 +106,32 @@ loop.Client = (function($) { * * @param {string} nickname the nickname of the future caller * @param {Function} cb Callback(err, callUrlData) */ _requestCallUrlInternal: function(nickname, cb) { this.mozLoop.hawkRequest("/call-url/", "POST", {callerId: nickname}, function (error, responseText) { if (error) { + this._telemetryAdd("LOOP_CLIENT_CALL_URL_REQUESTS_SUCCESS", false); this._failureHandler(cb, error); return; } try { var urlData = JSON.parse(responseText); - cb(null, this._validate(urlData, expectedCallUrlProperties)); + // This throws if the data is invalid, in which case only the failure + // telementry will be recorded. + var returnData = this._validate(urlData, expectedCallUrlProperties); + + this._telemetryAdd("LOOP_CLIENT_CALL_URL_REQUESTS_SUCCESS", true); + cb(null, returnData); } catch (err) { + this._telemetryAdd("LOOP_CLIENT_CALL_URL_REQUESTS_SUCCESS", false); console.log("Error requesting call info", err); cb(err); } }.bind(this)); }, /** * Block call URL based on the token identifier @@ -182,12 +189,26 @@ loop.Client = (function($) { if (err) { cb(err); return; } this._requestCallUrlInternal(nickname, cb); }.bind(this)); }, + + /** + * Adds a value to a telemetry histogram, ignoring errors. + * + * @param {string} histogramId Name of the telemetry histogram to update. + * @param {integer} value Value to add to the histogram. + */ + _telemetryAdd: function(histogramId, value) { + try { + this.mozLoop.telemetryAdd(histogramId, value); + } catch (err) { + console.error("Error recording telemetry", err); + } + }, }; return Client; })(jQuery);
--- a/browser/components/loop/content/js/panel.js +++ b/browser/components/loop/content/js/panel.js @@ -356,27 +356,21 @@ loop.panel = (function(_, mozL10n) { } catch(e) { console.log(e); this.props.notifications.errorL10n("unable_retrieve_url"); this.setState(this.getInitialState()); } } }, - _generateMailTo: function() { - return encodeURI([ - "mailto:?subject=" + __("share_email_subject3") + "&", - "body=" + __("share_email_body3", {callUrl: this.state.callUrl}) - ].join("")); - }, - handleEmailButtonClick: function(event) { this.handleLinkExfiltration(event); - // Note: side effect - document.location = event.target.dataset.mailto; + + navigator.mozLoop.composeEmail(__("share_email_subject3"), + __("share_email_body3", { callUrl: this.state.callUrl })); }, handleCopyButtonClick: function(event) { this.handleLinkExfiltration(event); // XXX the mozLoop object should be passed as a prop, to ease testing and // using a fake implementation in UI components showcase. navigator.mozLoop.copyString(this.state.callUrl); this.setState({copied: true}); @@ -404,18 +398,17 @@ loop.panel = (function(_, mozL10n) { return ( PanelLayout({summary: __("share_link_header_text")}, React.DOM.div({className: "invite"}, React.DOM.input({type: "url", value: this.state.callUrl, readOnly: "true", onCopy: this.handleLinkExfiltration, className: inputCSSClass}), React.DOM.p({className: "btn-group url-actions"}, React.DOM.button({className: "btn btn-email", disabled: !this.state.callUrl, - onClick: this.handleEmailButtonClick, - 'data-mailto': this._generateMailTo()}, + onClick: this.handleEmailButtonClick}, __("share_button") ), React.DOM.button({className: "btn btn-copy", disabled: !this.state.callUrl, onClick: this.handleCopyButtonClick}, this.state.copied ? __("copied_url_button") : __("copy_url_button") ) ) @@ -525,25 +518,22 @@ loop.panel = (function(_, mozL10n) { /** * Panel initialisation. */ function init() { // Do the initial L10n setup, we do this before anything // else to ensure the L10n environment is setup correctly. mozL10n.initialize(navigator.mozLoop); - var client = new loop.Client({ - baseServerUrl: navigator.mozLoop.serverUrl - }); + var client = new loop.Client(); var notifications = new sharedModels.NotificationCollection() React.renderComponent(PanelView({ client: client, - notifications: notifications} - ), document.querySelector("#main")); + notifications: notifications}), document.querySelector("#main")); document.body.classList.add(loop.shared.utils.getTargetPlatform()); document.body.setAttribute("dir", mozL10n.getDirection()); // Notify the window that we've finished initalization and initial layout var evtObject = document.createEvent('Event'); evtObject.initEvent('loopPanelInitialized', true, false); window.dispatchEvent(evtObject);
--- a/browser/components/loop/content/js/panel.jsx +++ b/browser/components/loop/content/js/panel.jsx @@ -356,27 +356,21 @@ loop.panel = (function(_, mozL10n) { } catch(e) { console.log(e); this.props.notifications.errorL10n("unable_retrieve_url"); this.setState(this.getInitialState()); } } }, - _generateMailTo: function() { - return encodeURI([ - "mailto:?subject=" + __("share_email_subject3") + "&", - "body=" + __("share_email_body3", {callUrl: this.state.callUrl}) - ].join("")); - }, - handleEmailButtonClick: function(event) { this.handleLinkExfiltration(event); - // Note: side effect - document.location = event.target.dataset.mailto; + + navigator.mozLoop.composeEmail(__("share_email_subject3"), + __("share_email_body3", { callUrl: this.state.callUrl })); }, handleCopyButtonClick: function(event) { this.handleLinkExfiltration(event); // XXX the mozLoop object should be passed as a prop, to ease testing and // using a fake implementation in UI components showcase. navigator.mozLoop.copyString(this.state.callUrl); this.setState({copied: true}); @@ -404,18 +398,17 @@ loop.panel = (function(_, mozL10n) { return ( <PanelLayout summary={__("share_link_header_text")}> <div className="invite"> <input type="url" value={this.state.callUrl} readOnly="true" onCopy={this.handleLinkExfiltration} className={inputCSSClass} /> <p className="btn-group url-actions"> <button className="btn btn-email" disabled={!this.state.callUrl} - onClick={this.handleEmailButtonClick} - data-mailto={this._generateMailTo()}> + onClick={this.handleEmailButtonClick}> {__("share_button")} </button> <button className="btn btn-copy" disabled={!this.state.callUrl} onClick={this.handleCopyButtonClick}> {this.state.copied ? __("copied_url_button") : __("copy_url_button")} </button> </p> @@ -525,25 +518,22 @@ loop.panel = (function(_, mozL10n) { /** * Panel initialisation. */ function init() { // Do the initial L10n setup, we do this before anything // else to ensure the L10n environment is setup correctly. mozL10n.initialize(navigator.mozLoop); - var client = new loop.Client({ - baseServerUrl: navigator.mozLoop.serverUrl - }); + var client = new loop.Client(); var notifications = new sharedModels.NotificationCollection() React.renderComponent(<PanelView client={client} - notifications={notifications} - />, document.querySelector("#main")); + notifications={notifications} />, document.querySelector("#main")); document.body.classList.add(loop.shared.utils.getTargetPlatform()); document.body.setAttribute("dir", mozL10n.getDirection()); // Notify the window that we've finished initalization and initial layout var evtObject = document.createEvent('Event'); evtObject.initEvent('loopPanelInitialized', true, false); window.dispatchEvent(evtObject);
--- a/browser/components/loop/test/desktop-local/client_test.js +++ b/browser/components/loop/test/desktop-local/client_test.js @@ -29,17 +29,18 @@ describe("loop.Client", function() { fakeToken = "fakeTokenText"; mozLoop = { getLoopCharPref: sandbox.stub() .returns(null) .withArgs("hawk-session-token") .returns(fakeToken), ensureRegistered: sinon.stub().callsArgWith(0, null), noteCallUrlExpiry: sinon.spy(), - hawkRequest: sinon.stub() + hawkRequest: sinon.stub(), + telemetryAdd: sinon.spy(), }; // Alias for clearer tests. hawkRequestStub = mozLoop.hawkRequest; client = new loop.Client({ mozLoop: mozLoop }); }); @@ -151,16 +152,40 @@ describe("loop.Client", function() { hawkRequestStub.callsArgWith(3, null, JSON.stringify(callUrlData)); client.requestCallUrl("foo", callback); sinon.assert.notCalled(mozLoop.noteCallUrlExpiry); }); + it("should call mozLoop.telemetryAdd when the request succeeds", + function(done) { + var callUrlData = { + "callUrl": "fakeCallUrl", + "expiresAt": 60 + }; + + // Sets up the hawkRequest stub to trigger the callback with no error + // and the url. + hawkRequestStub.callsArgWith(3, null, + JSON.stringify(callUrlData)); + + client.requestCallUrl("foo", function(err) { + expect(err).to.be.null; + + sinon.assert.calledOnce(mozLoop.telemetryAdd); + sinon.assert.calledWith(mozLoop.telemetryAdd, + "LOOP_CLIENT_CALL_URL_REQUESTS_SUCCESS", + true); + + done(); + }); + }); + it("should send an error when the request fails", function() { // Sets up the hawkRequest stub to trigger the callback with // an error hawkRequestStub.callsArgWith(3, fakeErrorRes); client.requestCallUrl("foo", callback); sinon.assert.calledOnce(callback); @@ -176,11 +201,29 @@ describe("loop.Client", function() { client.requestCallUrl("foo", callback); sinon.assert.calledOnce(callback); sinon.assert.calledWithMatch(callback, sinon.match(function(err) { return /Invalid data received/.test(err.message); })); }); + + it("should call mozLoop.telemetryAdd when the request fails", + function(done) { + // Sets up the hawkRequest stub to trigger the callback with + // an error + hawkRequestStub.callsArgWith(3, fakeErrorRes); + + client.requestCallUrl("foo", function(err) { + expect(err).not.to.be.null; + + sinon.assert.calledOnce(mozLoop.telemetryAdd); + sinon.assert.calledWith(mozLoop.telemetryAdd, + "LOOP_CLIENT_CALL_URL_REQUESTS_SUCCESS", + false); + + done(); + }); + }); }); }); });
--- a/browser/components/loop/test/desktop-local/conversation_test.js +++ b/browser/components/loop/test/desktop-local/conversation_test.js @@ -15,19 +15,16 @@ describe("loop.conversation", function() beforeEach(function() { sandbox = sinon.sandbox.create(); sandbox.useFakeTimers(); notifications = new loop.shared.models.NotificationCollection(); navigator.mozLoop = { doNotDisturb: true, - get serverUrl() { - return "http://example.com"; - }, getStrings: function() { return JSON.stringify({textContent: "fakeText"}); }, get locale() { return "en-US"; }, setLoopCharPref: sandbox.stub(), getLoopCharPref: sandbox.stub(),
--- a/browser/components/loop/test/desktop-local/panel_test.js +++ b/browser/components/loop/test/desktop-local/panel_test.js @@ -27,29 +27,27 @@ describe("loop.panel", function() { // https://github.com/cjohansen/Sinon.JS/issues/393 fakeXHR.xhr.onCreate = function (xhr) { requests.push(xhr); }; notifications = new loop.shared.models.NotificationCollection(); navigator.mozLoop = { doNotDisturb: true, - get serverUrl() { - return "http://example.com"; - }, getStrings: function() { return JSON.stringify({textContent: "fakeText"}); }, get locale() { return "en-US"; }, setLoopCharPref: sandbox.stub(), getLoopCharPref: sandbox.stub().returns("unseen"), copyString: sandbox.stub(), - noteCallUrlExpiry: sinon.spy() + noteCallUrlExpiry: sinon.spy(), + composeEmail: sinon.spy() }; document.mozL10n.initialize(navigator.mozLoop); }); afterEach(function() { delete navigator.mozLoop; sandbox.restore(); @@ -338,26 +336,25 @@ describe("loop.panel", function() { }); it("should reset all pending notifications", function() { sinon.assert.calledOnce(view.props.notifications.reset); }); it("should display a share button for email", function() { fakeClient.requestCallUrl = sandbox.stub(); - var mailto = 'mailto:?subject=email-subject&body=http://example.com'; var view = TestUtils.renderIntoDocument(loop.panel.CallUrlResult({ notifications: notifications, client: fakeClient })); view.setState({pending: false, callUrl: "http://example.com"}); TestUtils.findRenderedDOMComponentWithClass(view, "btn-email"); - expect(view.getDOMNode().querySelector(".btn-email").dataset.mailto) - .to.equal(encodeURI(mailto)); + TestUtils.Simulate.click(view.getDOMNode().querySelector(".btn-email")); + sinon.assert.calledOnce(navigator.mozLoop.composeEmail); }); it("should feature a copy button capable of copying the call url when clicked", function() { fakeClient.requestCallUrl = sandbox.stub(); var view = TestUtils.renderIntoDocument(loop.panel.CallUrlResult({ notifications: notifications, client: fakeClient })); @@ -403,17 +400,16 @@ describe("loop.panel", function() { })); view.setState({ pending: false, copied: false, callUrl: "http://example.com", callUrlExpiry: 6000 }); - view.getDOMNode().querySelector(".btn-email").dataset.mailto = "#"; TestUtils.Simulate.click(view.getDOMNode().querySelector(".btn-email")); sinon.assert.calledOnce(navigator.mozLoop.noteCallUrlExpiry); sinon.assert.calledWithExactly(navigator.mozLoop.noteCallUrlExpiry, 6000); }); it("should note the call url expiry when the url is copied manually",
--- a/browser/components/loop/test/mochitest/browser.ini +++ b/browser/components/loop/test/mochitest/browser.ini @@ -11,8 +11,10 @@ skip-if = e10s [browser_LoopContacts.js] [browser_mozLoop_appVersionInfo.js] [browser_mozLoop_prefs.js] [browser_mozLoop_doNotDisturb.js] [browser_mozLoop_softStart.js] skip-if = buildapp == 'mulet' [browser_toolbarbutton.js] [browser_mozLoop_pluralStrings.js] +[browser_mozLoop_telemetry.js] +skip-if = e10s
new file mode 100644 --- /dev/null +++ b/browser/components/loop/test/mochitest/browser_mozLoop_telemetry.js @@ -0,0 +1,36 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/* + * This file contains tests for the mozLoop telemetry API. + */ + +add_task(loadLoopPanel); + +/** + * Tests that boolean histograms exist and can be updated. + */ +add_task(function* test_mozLoop_telemetryAdd_boolean() { + for (let histogramId of [ + "LOOP_CLIENT_CALL_URL_REQUESTS_SUCCESS", + ]) { + let snapshot = Services.telemetry.getHistogramById(histogramId).snapshot(); + + let initialFalseCount = snapshot.counts[0]; + let initialTrueCount = snapshot.counts[1]; + + for (let value of [false, false, true]) { + gMozLoopAPI.telemetryAdd(histogramId, value); + } + + // The telemetry service updates histograms asynchronously, so we need to + // poll for the final values and time out otherwise. + info("Waiting for update of " + histogramId); + do { + yield new Promise(resolve => setTimeout(resolve, 50)); + snapshot = Services.telemetry.getHistogramById(histogramId).snapshot(); + } while (snapshot.counts[0] == initialFalseCount + 2 && + snapshot.counts[1] == initialTrueCount + 1); + ok(true, "Correctly updated " + histogramId); + } +});
--- a/browser/components/loop/test/shared/models_test.js +++ b/browser/components/loop/test/shared/models_test.js @@ -51,31 +51,23 @@ describe("loop.shared.models", function( it("should require a sdk option", function() { expect(function() { new sharedModels.ConversationModel({}, {}); }).to.Throw(Error, /missing required sdk/); }); }); describe("constructed", function() { - var conversation, fakeClient, fakeBaseServerUrl, - requestCallInfoStub, requestCallsInfoStub; + var conversation; beforeEach(function() { conversation = new sharedModels.ConversationModel({}, { sdk: fakeSDK }); conversation.set("loopToken", "fakeToken"); - fakeBaseServerUrl = "http://fakeBaseServerUrl"; - fakeClient = { - requestCallInfo: sandbox.stub(), - requestCallsInfo: sandbox.stub() - }; - requestCallInfoStub = fakeClient.requestCallInfo; - requestCallsInfoStub = fakeClient.requestCallsInfo; }); describe("#incoming", function() { it("should trigger a `call:incoming` event", function(done) { conversation.once("call:incoming", function() { done(); });
--- a/browser/components/loop/test/xpcshell/head.js +++ b/browser/components/loop/test/xpcshell/head.js @@ -21,16 +21,17 @@ const kServerPushUrl = "http://localhost const kEndPointUrl = "http://example.com/fake"; const kUAID = "f47ac11b-58ca-4372-9567-0e02b2c3d479"; // Fake loop server var loopServer; // Ensure loop is always enabled for tests Services.prefs.setBoolPref("loop.enabled", true); +Services.prefs.setBoolPref("loop.throttled", false); function setupFakeLoopServer() { loopServer = new HttpServer(); loopServer.start(-1); Services.prefs.setCharPref("services.push.serverURL", kServerPushUrl); Services.prefs.setCharPref("loop.server",
--- a/browser/components/loop/ui/ui-showcase.js +++ b/browser/components/loop/ui/ui-showcase.js @@ -123,31 +123,31 @@ React.DOM.strong(null, "Note:"), " 332px wide." ), Example({summary: "Call URL retrieved", dashed: "true", style: {width: "332px"}}, PanelView({client: mockClient, notifications: notifications, callUrl: "http://invalid.example.url/"}) ), Example({summary: "Call URL retrieved - authenticated", dashed: "true", style: {width: "332px"}}, PanelView({client: mockClient, notifications: notifications, - callUrl: "http://invalid.example.url/", + callUrl: "http://invalid.example.url/", userProfile: {email: "test@example.com"}}) ), Example({summary: "Pending call url retrieval", dashed: "true", style: {width: "332px"}}, PanelView({client: mockClient, notifications: notifications}) ), Example({summary: "Pending call url retrieval - authenticated", dashed: "true", style: {width: "332px"}}, - PanelView({client: mockClient, notifications: notifications, + PanelView({client: mockClient, notifications: notifications, userProfile: {email: "test@example.com"}}) ), Example({summary: "Error Notification", dashed: "true", style: {width: "332px"}}, PanelView({client: mockClient, notifications: errNotifications}) - ), + ), Example({summary: "Error Notification - authenticated", dashed: "true", style: {width: "332px"}}, - PanelView({client: mockClient, notifications: errNotifications, + PanelView({client: mockClient, notifications: errNotifications, userProfile: {email: "test@example.com"}}) ) ), Section({name: "IncomingCallView"}, Example({summary: "Default / incoming video call", dashed: "true", style: {width: "280px"}}, React.DOM.div({className: "fx-embedded"}, IncomingCallView({model: mockConversationModel,
--- a/browser/devtools/debugger/test/browser.ini +++ b/browser/devtools/debugger/test/browser.ini @@ -262,16 +262,17 @@ skip-if = os == "linux" || e10s # Bug 88 [browser_dbg_terminate-on-tab-close.js] [browser_dbg_tracing-01.js] [browser_dbg_tracing-02.js] [browser_dbg_tracing-03.js] [browser_dbg_tracing-04.js] [browser_dbg_tracing-05.js] [browser_dbg_tracing-06.js] [browser_dbg_tracing-07.js] +[browser_dbg_tracing-08.js] [browser_dbg_variables-view-01.js] [browser_dbg_variables-view-02.js] [browser_dbg_variables-view-03.js] [browser_dbg_variables-view-04.js] [browser_dbg_variables-view-05.js] [browser_dbg_variables-view-accessibility.js] [browser_dbg_variables-view-data.js] [browser_dbg_variables-view-edit-cancel.js]
new file mode 100644 --- /dev/null +++ b/browser/devtools/debugger/test/browser_dbg_tracing-08.js @@ -0,0 +1,59 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Test that tracing about:config doesn't produce errors. + */ + +const TAB_URL = "about:config"; + +let gPanel, gDoneChecks; + +function test() { + gDoneChecks = promise.defer(); + const tracerPref = promise.defer(); + const configPref = promise.defer(); + SpecialPowers.pushPrefEnv({'set': [["devtools.debugger.tracer", true]]}, tracerPref.resolve); + SpecialPowers.pushPrefEnv({'set': [["general.warnOnAboutConfig", false]]}, configPref.resolve); + promise.all([tracerPref.promise, configPref.promise]).then(() => { + initDebugger(TAB_URL).then(([,, aPanel]) => { + gPanel = aPanel; + gPanel.panelWin.gClient.addOneTimeListener("traces", testTraceLogs); + }).then(() => startTracing(gPanel)) + .then(generateTrace) + .then(() => waitForClientEvents(gPanel, "traces")) + .then(() => gDoneChecks.promise) + .then(() => stopTracing(gPanel)) + .then(resetPreferences) + .then(() => closeDebuggerAndFinish(gPanel)) + .then(null, aError => { + ok(false, "Got an error: " + aError.message + "\n" + aError.stack); + }); + }); +} + +function testTraceLogs(name, packet) { + info("Traces: " + packet.traces.length); + ok(packet.traces.length > 0, "Got some traces."); + ok(packet.traces.every(t => t.type != "enteredFrame" || !!t.location), + "All enteredFrame traces contain location."); + gDoneChecks.resolve(); +} + +function generateTrace(name, packet) { + // Interact with the page to cause JS execution. + let search = content.document.getElementById("textbox"); + info("Interacting with the page."); + search.value = "devtools"; +} + +function resetPreferences() { + const deferred = promise.defer(); + SpecialPowers.popPrefEnv(() => SpecialPowers.popPrefEnv(deferred.resolve)); + return deferred.promise; +} + +registerCleanupFunction(function() { + gPanel = null; + gDoneChecks = null; +});
--- a/browser/devtools/styleinspector/test/browser_ruleview_livepreview.js +++ b/browser/devtools/styleinspector/test/browser_ruleview_livepreview.js @@ -23,28 +23,28 @@ const TEST_DATA = [ ]; let test = asyncTest(function*() { yield addTab("data:text/html;charset=utf-8,test rule view live preview on user changes"); let style = '#testid {display:block;}'; let styleNode = addStyle(content.document, style); content.document.body.innerHTML = '<div id="testid">Styled Node</div><span>inline element</span>'; - let testElement = getNode("#testid"); let {toolbox, inspector, view} = yield openRuleView(); yield selectNode("#testid", inspector); for (let data of TEST_DATA) { - yield testLivePreviewData(data, view, testElement); + yield testLivePreviewData(data, view, "#testid"); } }); -function* testLivePreviewData(data, ruleView, testElement) { +function* testLivePreviewData(data, ruleView, selector) { + let testElement = getNode(selector); let idRuleEditor = getRuleViewRuleEditor(ruleView, 1); let propEditor = idRuleEditor.rule.textProps[0].editor; info("Focusing the property value inplace-editor"); let editor = yield focusEditableField(propEditor.valueSpan); is(inplaceEditor(propEditor.valueSpan), editor, "The focused editor is the value"); info("Enter a value in the editor") @@ -52,15 +52,18 @@ function* testLivePreviewData(data, rule EventUtils.sendChar(ch, ruleView.doc.defaultView); } if (data.escape) { EventUtils.synthesizeKey("VK_ESCAPE", {}); } else { EventUtils.synthesizeKey("VK_RETURN", {}); } + // This wait is an orange waiting to happen, but it might take a few event + // loop spins in either the client or parent process before we see the + // updated value. yield wait(1); // While the editor is still focused in, the display should have changed already - is(content.getComputedStyle(testElement).display, + is((yield getComputedStyleProperty(selector, null, "display")), data.expected, "Element should be previewed as " + data.expected); }
--- a/browser/devtools/styleinspector/test/browser_ruleview_pseudo-element.js +++ b/browser/devtools/styleinspector/test/browser_ruleview_pseudo-element.js @@ -16,21 +16,22 @@ let test = asyncTest(function*() { yield testTopRight(inspector, view); yield testBottomRight(inspector, view); yield testBottomLeft(inspector, view); yield testParagraph(inspector, view); yield testBody(inspector, view); }); function* testTopLeft(inspector, view) { + let selector = "#topleft"; let { rules, element, elementStyle - } = yield assertPseudoElementRulesNumbers("#topleft", inspector, view, { + } = yield assertPseudoElementRulesNumbers(selector, inspector, view, { elementRulesNb: 4, afterRulesNb: 1, beforeRulesNb: 2, firstLineRulesNb: 0, firstLetterRulesNb: 0, selectionRulesNb: 0 }); @@ -82,45 +83,45 @@ function* testTopLeft(inspector, view) { is (firstProp, elementAfterRule.textProps[elementAfterRule.textProps.length - 2], "First added property is on back of array"); is (secondProp, elementAfterRule.textProps[elementAfterRule.textProps.length - 1], "Second added property is on back of array"); yield elementAfterRule._applyingModifications; - is(defaultView.getComputedStyle(element, ":after").getPropertyValue("background-color"), + is((yield getComputedStyleProperty(selector, ":after", "background-color")), "rgb(0, 255, 0)", "Added property should have been used."); - is(defaultView.getComputedStyle(element, ":after").getPropertyValue("padding-top"), + is((yield getComputedStyleProperty(selector, ":after", "padding-top")), "100px", "Added property should have been used."); - is(defaultView.getComputedStyle(element).getPropertyValue("padding-top"), + is((yield getComputedStyleProperty(selector, null, "padding-top")), "32px", "Added property should not apply to element"); secondProp.setEnabled(false); yield elementAfterRule._applyingModifications; - is(defaultView.getComputedStyle(element, ":after").getPropertyValue("padding-top"), "0px", + is((yield getComputedStyleProperty(selector, ":after", "padding-top")), "0px", "Disabled property should have been used."); - is(defaultView.getComputedStyle(element).getPropertyValue("padding-top"), "32px", + is((yield getComputedStyleProperty(selector, null, "padding-top")), "32px", "Added property should not apply to element"); secondProp.setEnabled(true); yield elementAfterRule._applyingModifications; - is(defaultView.getComputedStyle(element, ":after").getPropertyValue("padding-top"), "100px", + is((yield getComputedStyleProperty(selector, ":after", "padding-top")), "100px", "Enabled property should have been used."); - is(defaultView.getComputedStyle(element).getPropertyValue("padding-top"), "32px", + is((yield getComputedStyleProperty(selector, null, "padding-top")), "32px", "Added property should not apply to element"); firstProp = elementRuleView.addProperty("background-color", "rgb(0, 0, 255)", ""); yield elementRule._applyingModifications; - is(defaultView.getComputedStyle(element).getPropertyValue("background-color"), "rgb(0, 0, 255)", + is((yield getComputedStyleProperty(selector, null, "background-color")), "rgb(0, 0, 255)", "Added property should have been used."); - is(defaultView.getComputedStyle(element, ":after").getPropertyValue("background-color"), "rgb(0, 255, 0)", + is((yield getComputedStyleProperty(selector, ":after", "background-color")), "rgb(0, 255, 0)", "Added prop does not apply to pseudo"); } function* testTopRight(inspector, view) { let { rules, element, elementStyle
--- a/browser/devtools/styleinspector/test/doc_frame_script.js +++ b/browser/devtools/styleinspector/test/doc_frame_script.js @@ -68,9 +68,24 @@ addMessageListener("Test:GetStyleSheetsI href: sheet.href, isContentSheet: CssLogic.isContentStylesheet(sheet) }); } sendAsyncMessage("Test:GetStyleSheetsInfoForNode", sheets); }); +/** + * Get the property value from the computed style for an element. + * @param {Object} data Expects a data object with the following properties + * - {String} selector: The selector used to obtain the element. + * - {String} pseudo: pseudo id to query, or null. + * - {String} name: name of the property + * @return {String} The value, if found, null otherwise + */ +addMessageListener("Test:GetComputedStylePropertyValue", function(msg) { + let {selector, pseudo, name} = msg.data; + let element = content.document.querySelector(selector); + let value = content.document.defaultView.getComputedStyle(element, pseudo).getPropertyValue(name); + sendAsyncMessage("Test:GetComputedStylePropertyValue", value); +}); + let dumpn = msg => dump(msg + "\n");
--- a/browser/devtools/styleinspector/test/head.js +++ b/browser/devtools/styleinspector/test/head.js @@ -381,16 +381,30 @@ function executeInContent(name, data={}, if (expectResponse) { return waitForContentMessage(name); } else { return promise.resolve(); } } /** + * Send an async message to the frame script and get back the requested + * computed style property. + * @param {String} selector: The selector used to obtain the element. + * @param {String} pseudo: pseudo id to query, or null. + * @param {String} name: name of the property. + */ +function* getComputedStyleProperty(selector, pseudo, propName) { + return yield executeInContent("Test:GetComputedStylePropertyValue", + {selector: selector, + pseudo: pseudo, + name: propName}); +} + +/** * Given an inplace editable element, click to switch it to edit mode, wait for * focus * @return a promise that resolves to the inplace-editor element when ready */ let focusEditableField = Task.async(function*(editable, xOffset=1, yOffset=1, options={}) { let onFocus = once(editable.parentNode, "focus", true); info("Clicking on editable field to turn to edit mode");
--- a/browser/modules/UITour.jsm +++ b/browser/modules/UITour.jsm @@ -1129,16 +1129,23 @@ this.UITour = { case "availableTargets": this.getAvailableTargets(aContentDocument, aCallbackID); break; case "sync": this.sendPageCallback(aContentDocument, aCallbackID, { setup: Services.prefs.prefHasUserValue("services.sync.username"), }); break; + case "appinfo": + let props = ["defaultUpdateChannel", "distributionID", "isOfficialBranding", + "isReleaseBuild", "name", "vendor", "version"]; + let appinfo = {}; + props.forEach(property => appinfo[property] = Services.appinfo[property]); + this.sendPageCallback(aContentDocument, aCallbackID, appinfo); + break; default: Cu.reportError("getConfiguration: Unknown configuration requested: " + aConfiguration); break; } }, getAvailableTargets: function(aContentDocument, aCallbackID) { let window = this.getChromeWindow(aContentDocument);
--- a/browser/modules/test/browser_UITour.js +++ b/browser/modules/test/browser_UITour.js @@ -260,15 +260,28 @@ let tests = [ is(desc.textContent, "search text", "Popup should have correct description text"); done(); }); }); gContentAPI.showInfo("urlbar", "urlbar title", "urlbar text"); }, + function test_getConfigurationVersion(done) { + function callback(result) { + let props = ["defaultUpdateChannel", "distributionID", "isOfficialBranding", + "isReleaseBuild", "name", "vendor", "version"]; + for (let property of props) { + ok(typeof(result[property]) !== undefined, "Check " + property + " isn't undefined."); + is(result[property], Services.appinfo[property], "Should have the same " + property + " property."); + } + done(); + } + + gContentAPI.getConfiguration("appinfo", callback); + }, // Make sure this test is last in the file so the appMenu gets left open and done will confirm it got tore down. function cleanupMenus(done) { gContentAPI.showMenu("appMenu"); done(); }, ];
new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..54eb9f365f75d3870858cd7d7ac3544c176a642e GIT binary patch literal 3209 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
--- a/browser/themes/linux/browser.css +++ b/browser/themes/linux/browser.css @@ -1179,16 +1179,21 @@ toolbarbutton[sdk-button="true"][cui-are .popup-notification-icon[popupid="webapps-install"] { list-style-image: url(chrome://global/skin/icons/webapps-64.png); } .popup-notification-icon[popupid="bad-content"] { list-style-image: url(chrome://browser/skin/bad-content-blocked-64.png); } +.popup-notification-icon[popupid="bad-content"][mixedblockdisabled], +.popup-notification-icon[popupid="bad-content"][trackingblockdisabled] { + list-style-image: url(chrome://browser/skin/bad-content-unblocked-64.png); +} + .popup-notification-icon[popupid="webRTC-sharingDevices"], .popup-notification-icon[popupid="webRTC-shareDevices"] { list-style-image: url(chrome://browser/skin/webRTC-shareDevice-64.png); } .popup-notification-icon[popupid="webRTC-sharingMicrophone"], .popup-notification-icon[popupid="webRTC-shareMicrophone"] { list-style-image: url(chrome://browser/skin/webRTC-shareMicrophone-64.png);
--- a/browser/themes/linux/jar.mn +++ b/browser/themes/linux/jar.mn @@ -41,16 +41,17 @@ browser.jar: skin/classic/browser/menuPanel.png skin/classic/browser/menuPanel-customize.png skin/classic/browser/menuPanel-exit.png skin/classic/browser/menuPanel-help.png skin/classic/browser/menuPanel-small.png skin/classic/browser/bad-content-blocked-16.png skin/classic/browser/bad-content-blocked-64.png skin/classic/browser/bad-content-unblocked-16.png + skin/classic/browser/bad-content-unblocked-64.png skin/classic/browser/monitor.png skin/classic/browser/monitor_16-10.png skin/classic/browser/notification-16.png skin/classic/browser/notification-64.png * skin/classic/browser/pageInfo.css skin/classic/browser/pageInfo.png skin/classic/browser/page-livemarks.png skin/classic/browser/pluginInstall-16.png
new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..54eb9f365f75d3870858cd7d7ac3544c176a642e GIT binary patch literal 3209 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
new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..e147189c4b3df0ecb0d3cb7914e1f69b17f16050 GIT binary patch literal 7488 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 KMNUMnLSTZrcN47u
--- a/browser/themes/osx/browser.css +++ b/browser/themes/osx/browser.css @@ -4039,16 +4039,27 @@ menulist.translate-infobar-element > .me list-style-image: url(chrome://browser/skin/bad-content-blocked-64.png); } @media (min-resolution: 2dppx) { .popup-notification-icon[popupid="bad-content"] { list-style-image: url(chrome://browser/skin/bad-content-blocked-64@2x.png); } } +.popup-notification-icon[popupid="bad-content"][mixedblockdisabled], +.popup-notification-icon[popupid="bad-content"][trackingblockdisabled] { + list-style-image: url(chrome://browser/skin/bad-content-unblocked-64.png); +} +@media (min-resolution: 2dppx) { + .popup-notification-icon[popupid="bad-content"][mixedblockdisabled], + .popup-notification-icon[popupid="bad-content"][trackingblockdisabled] { + list-style-image: url(chrome://browser/skin/bad-content-unblocked-64@2x.png); + } +} + .popup-notification-icon[popupid="pointerLock"] { list-style-image: url(chrome://browser/skin/pointerLock-64.png); } @media (min-resolution: 2dppx) { .popup-notification-icon[popupid="pointerLock"] { list-style-image: url(chrome://browser/skin/pointerLock-64@2x.png); } }
--- a/browser/themes/osx/jar.mn +++ b/browser/themes/osx/jar.mn @@ -67,16 +67,18 @@ browser.jar: skin/classic/browser/menuPanel-small.png skin/classic/browser/menuPanel-small@2x.png skin/classic/browser/bad-content-blocked-16.png skin/classic/browser/bad-content-blocked-16@2x.png skin/classic/browser/bad-content-blocked-64.png skin/classic/browser/bad-content-blocked-64@2x.png skin/classic/browser/bad-content-unblocked-16.png skin/classic/browser/bad-content-unblocked-16@2x.png + skin/classic/browser/bad-content-unblocked-64.png + skin/classic/browser/bad-content-unblocked-64@2x.png skin/classic/browser/panel-expander-closed.png skin/classic/browser/panel-expander-closed@2x.png skin/classic/browser/panel-expander-open.png skin/classic/browser/panel-expander-open@2x.png skin/classic/browser/panel-plus-sign.png skin/classic/browser/page-livemarks.png skin/classic/browser/page-livemarks@2x.png skin/classic/browser/pageInfo.css
new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..54eb9f365f75d3870858cd7d7ac3544c176a642e GIT binary patch literal 3209 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
--- a/browser/themes/windows/browser.css +++ b/browser/themes/windows/browser.css @@ -2197,16 +2197,21 @@ toolbarbutton.bookmark-item[dragover="tr .popup-notification-icon[popupid="webapps-install"] { list-style-image: url(chrome://global/skin/icons/webapps-64.png); } .popup-notification-icon[popupid="bad-content"] { list-style-image: url(chrome://browser/skin/bad-content-blocked-64.png); } +.popup-notification-icon[popupid="bad-content"][mixedblockdisabled], +.popup-notification-icon[popupid="bad-content"][trackingblockdisabled] { + list-style-image: url(chrome://browser/skin/bad-content-unblocked-64.png); +} + .popup-notification-icon[popupid="webRTC-sharingDevices"], .popup-notification-icon[popupid="webRTC-shareDevices"] { list-style-image: url(chrome://browser/skin/webRTC-shareDevice-64.png); } .popup-notification-icon[popupid="webRTC-sharingMicrophone"], .popup-notification-icon[popupid="webRTC-shareMicrophone"] { list-style-image: url(chrome://browser/skin/webRTC-shareMicrophone-64.png);
--- a/browser/themes/windows/jar.mn +++ b/browser/themes/windows/jar.mn @@ -51,16 +51,17 @@ browser.jar: skin/classic/browser/menuPanel-help.png skin/classic/browser/menuPanel-small.png skin/classic/browser/Metro_Glyph.png (Metro_Glyph-aero.png) skin/classic/browser/Metro_Glyph-inverted.png skin/classic/browser/Metro_Glyph-menuPanel.png skin/classic/browser/bad-content-blocked-16.png skin/classic/browser/bad-content-blocked-64.png skin/classic/browser/bad-content-unblocked-16.png + skin/classic/browser/bad-content-unblocked-64.png skin/classic/browser/monitor.png skin/classic/browser/monitor_16-10.png skin/classic/browser/notification-16.png skin/classic/browser/notification-64.png skin/classic/browser/pageInfo.css skin/classic/browser/pageInfo.png skin/classic/browser/page-livemarks.png (feeds/feedIcon16.png) skin/classic/browser/pluginInstall-16.png @@ -473,16 +474,17 @@ browser.jar: skin/classic/aero/browser/menuPanel-small.png skin/classic/aero/browser/menuPanel-small-aero.png skin/classic/aero/browser/Metro_Glyph.png (Metro_Glyph-aero.png) skin/classic/aero/browser/Metro_Glyph-inverted.png skin/classic/aero/browser/Metro_Glyph-menuPanel.png skin/classic/aero/browser/bad-content-blocked-16.png skin/classic/aero/browser/bad-content-blocked-64.png skin/classic/aero/browser/bad-content-unblocked-16.png + skin/classic/aero/browser/bad-content-unblocked-64.png skin/classic/aero/browser/monitor.png skin/classic/aero/browser/monitor_16-10.png skin/classic/aero/browser/notification-16.png skin/classic/aero/browser/notification-64.png skin/classic/aero/browser/pageInfo.css skin/classic/aero/browser/pageInfo.png (pageInfo-aero.png) skin/classic/aero/browser/page-livemarks.png (feeds/feedIcon16-aero.png) skin/classic/aero/browser/pluginInstall-16.png
--- a/chrome/nsChromeRegistryChrome.cpp +++ b/chrome/nsChromeRegistryChrome.cpp @@ -676,28 +676,36 @@ nsChromeRegistryChrome::OverlayListHash: return &entry->mArray; } #ifdef MOZ_XUL NS_IMETHODIMP nsChromeRegistryChrome::GetStyleOverlays(nsIURI *aChromeURL, nsISimpleEnumerator **aResult) { - const nsCOMArray<nsIURI>* parray = mStyleHash.GetArray(aChromeURL); + nsCOMPtr<nsIURI> chromeURLWithoutHash; + if (aChromeURL) { + aChromeURL->CloneIgnoringRef(getter_AddRefs(chromeURLWithoutHash)); + } + const nsCOMArray<nsIURI>* parray = mStyleHash.GetArray(chromeURLWithoutHash); if (!parray) return NS_NewEmptyEnumerator(aResult); return NS_NewArrayEnumerator(aResult, *parray); } NS_IMETHODIMP nsChromeRegistryChrome::GetXULOverlays(nsIURI *aChromeURL, nsISimpleEnumerator **aResult) { - const nsCOMArray<nsIURI>* parray = mOverlayHash.GetArray(aChromeURL); + nsCOMPtr<nsIURI> chromeURLWithoutHash; + if (aChromeURL) { + aChromeURL->CloneIgnoringRef(getter_AddRefs(chromeURLWithoutHash)); + } + const nsCOMArray<nsIURI>* parray = mOverlayHash.GetArray(chromeURLWithoutHash); if (!parray) return NS_NewEmptyEnumerator(aResult); return NS_NewArrayEnumerator(aResult, *parray); } #endif // MOZ_XUL nsIURI* @@ -890,17 +898,20 @@ nsChromeRegistryChrome::ManifestOverlay( } if (!CanLoadResource(overlayuri)) { LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag, "Cannot register non-local URI '%s' as an overlay.", overlay); return; } - mOverlayHash.Add(baseuri, overlayuri); + nsCOMPtr<nsIURI> baseuriWithoutHash; + baseuri->CloneIgnoringRef(getter_AddRefs(baseuriWithoutHash)); + + mOverlayHash.Add(baseuriWithoutHash, overlayuri); } void nsChromeRegistryChrome::ManifestStyle(ManifestProcessingContext& cx, int lineno, char *const * argv, bool platform, bool contentaccessible) { char* base = argv[0]; @@ -915,17 +926,20 @@ nsChromeRegistryChrome::ManifestStyle(Ma } if (!CanLoadResource(overlayuri)) { LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag, "Cannot register non-local URI '%s' as a style overlay.", overlay); return; } - mStyleHash.Add(baseuri, overlayuri); + nsCOMPtr<nsIURI> baseuriWithoutHash; + baseuri->CloneIgnoringRef(getter_AddRefs(baseuriWithoutHash)); + + mStyleHash.Add(baseuriWithoutHash, overlayuri); } void nsChromeRegistryChrome::ManifestOverride(ManifestProcessingContext& cx, int lineno, char *const * argv, bool platform, bool contentaccessible) { char* chrome = argv[0];
--- a/content/xul/document/src/nsXULPrototypeCache.cpp +++ b/content/xul/document/src/nsXULPrototypeCache.cpp @@ -126,17 +126,23 @@ nsXULPrototypeCache::Observe(nsISupports NS_WARNING("Unexpected observer topic."); } return NS_OK; } nsXULPrototypeDocument* nsXULPrototypeCache::GetPrototype(nsIURI* aURI) { - nsXULPrototypeDocument* protoDoc = mPrototypeTable.GetWeak(aURI); + if (!aURI) + return nullptr; + + nsCOMPtr<nsIURI> uriWithoutRef; + aURI->CloneIgnoringRef(getter_AddRefs(uriWithoutRef)); + + nsXULPrototypeDocument* protoDoc = mPrototypeTable.GetWeak(uriWithoutRef); if (protoDoc) return protoDoc; nsresult rv = BeginCaching(aURI); if (NS_FAILED(rv)) return nullptr; // No prototype in XUL memory cache. Spin up the cache Service. @@ -159,17 +165,23 @@ nsXULPrototypeCache::GetPrototype(nsIURI mInputStreamTable.Remove(aURI); return newProto; } nsresult nsXULPrototypeCache::PutPrototype(nsXULPrototypeDocument* aDocument) { - nsCOMPtr<nsIURI> uri = aDocument->GetURI(); + if (!aDocument->GetURI()) { + return NS_ERROR_FAILURE; + } + + nsCOMPtr<nsIURI> uri; + aDocument->GetURI()->CloneIgnoringRef(getter_AddRefs(uri)); + // Put() releases any old value and addrefs the new one mPrototypeTable.Put(uri, aDocument); return NS_OK; } nsresult nsXULPrototypeCache::PutStyleSheet(CSSStyleSheet* aStyleSheet)
--- a/docshell/test/browser/browser.ini +++ b/docshell/test/browser/browser.ini @@ -97,8 +97,9 @@ skip-if = e10s [browser_loadURI.js] skip-if = e10s # Bug ?????? - event handler checks event.target is the content document and test e10s-utils doesn't do that. [browser_onbeforeunload_navigation.js] skip-if = e10s [browser_search_notification.js] skip-if = e10s [browser_timelineMarkers-01.js] [browser_timelineMarkers-02.js] +skip-if = e10s
--- a/dom/base/nsFocusManager.cpp +++ b/dom/base/nsFocusManager.cpp @@ -31,17 +31,16 @@ #include "mozilla/dom/Selection.h" #include "nsXULPopupManager.h" #include "nsIScriptObjectPrincipal.h" #include "nsIPrincipal.h" #include "nsIObserverService.h" #include "nsIObjectFrame.h" #include "nsBindingManager.h" #include "nsStyleCoord.h" -#include "SelectionCarets.h" #include "mozilla/ContentEvents.h" #include "mozilla/dom/Element.h" #include "mozilla/EventDispatcher.h" #include "mozilla/EventStateManager.h" #include "mozilla/EventStates.h" #include "mozilla/IMEStateManager.h" #include "mozilla/LookAndFeel.h" @@ -1562,21 +1561,16 @@ nsFocusManager::Blur(nsPIDOMWindow* aWin // Keep a ref to presShell since dispatching the DOM event may cause // the document to be destroyed. nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell(); if (!presShell) { mFocusedContent = nullptr; return true; } - nsRefPtr<SelectionCarets> selectionCarets = presShell->GetSelectionCarets(); - if (selectionCarets) { - selectionCarets->SetVisibility(false); - } - bool clearFirstBlurEvent = false; if (!mFirstBlurEvent) { mFirstBlurEvent = content; clearFirstBlurEvent = true; } nsPresContext* focusedPresContext = mActiveWindow ? presShell->GetPresContext() : nullptr;
--- a/dom/imptests/editing/selecttest/test_collapse.html +++ b/dom/imptests/editing/selecttest/test_collapse.html @@ -76,14 +76,12 @@ for (var i = 0; i < testRanges.length; i range = null; } }, "Set up range " + i + " " + testRanges[i]); for (var j = 0; j < testPoints.length; j++) { tests.push(["Range " + i + " " + testRanges[i] + ", point " + j + " " + testPoints[j], range, testPointsCached[j]]); } } -setup(function () { - generate_tests(testCollapse, tests); -}, { timeout_multiplier: 2 }); +generate_tests(testCollapse, tests); testDiv.style.display = "none"; </script>
--- a/editor/reftests/reftest.list +++ b/editor/reftests/reftest.list @@ -95,23 +95,23 @@ skip-if(Android||B2G) needs-focus == 462 == 694880-1.html 694880-ref.html == 694880-2.html 694880-ref.html == 694880-3.html 694880-ref.html == 388980-1.html 388980-1-ref.html needs-focus == spellcheck-superscript-1.html spellcheck-superscript-1-ref.html skip-if(B2G) fails-if(Android) needs-focus != spellcheck-superscript-2.html spellcheck-superscript-2-ref.html # bug 783658 needs-focus == 824080-1.html 824080-1-ref.html needs-focus == 824080-2.html 824080-2-ref.html -needs-focus test-pref(selectioncaret.enabled,false) == 824080-3.html 824080-3-ref.html +needs-focus == 824080-3.html 824080-3-ref.html needs-focus != 824080-2.html 824080-3.html needs-focus == 824080-4.html 824080-4-ref.html -needs-focus test-pref(selectioncaret.enabled,false) == 824080-5.html 824080-5-ref.html +needs-focus == 824080-5.html 824080-5-ref.html needs-focus != 824080-4.html 824080-5.html needs-focus == 824080-6.html 824080-6-ref.html -needs-focus pref(selectioncaret.enabled,false) == 824080-7.html 824080-7-ref.html +needs-focus == 824080-7.html 824080-7-ref.html needs-focus != 824080-6.html 824080-7.html # Bug 674927: copy spellcheck-textarea tests to contenteditable == spellcheck-contenteditable-attr.html spellcheck-contenteditable-nofocus-ref.html fails-if(Android||B2G) needs-focus != spellcheck-contenteditable-attr.html spellcheck-contenteditable-ref.html # B2G no spellcheck underline needs-focus == spellcheck-contenteditable-focused.html spellcheck-contenteditable-ref.html needs-focus == spellcheck-contenteditable-focused-reframe.html spellcheck-contenteditable-ref.html == spellcheck-contenteditable-nofocus.html spellcheck-contenteditable-disabled-ref.html == spellcheck-contenteditable-disabled.html spellcheck-contenteditable-disabled-ref.html
deleted file mode 100644 --- a/layout/base/tests/bug558663.html +++ /dev/null @@ -1,101 +0,0 @@ -<!DOCTYPE HTML> -<html> -<!-- -https://bugzilla.mozilla.org/show_bug.cgi?id=558663 ---> -<head> - <title>Test for Bug 558663</title> -</head> -<body> -<p><a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=558663">Mozilla Bug 558663</a></p> - - <!-- 20x20 of red --> -<iframe id="iframe" src="data:text/html,<img id='image' border='0' src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAIAAAAC64paAAAAG0lEQVR42mP8z0A%2BYKJA76jmUc2jmkc1U0EzACKcASfOgGoMAAAAAElFTkSuQmCC'>"></iframe> - -<pre id="test"> -<script type="application/javascript"> - -/** Test for Bug 558663 **/ -var ok = parent.ok; -var SimpleTest = parent.SimpleTest; -var compareSnapshots = parent.compareSnapshots; -var snapshotWindow = parent.snapshotWindow; -var synthesizeMouse = parent.synthesizeMouse; - -window.addEventListener("load", runTest, false); - -function checkSnapshots(s1, s2, shouldBeEqual, testName) { - var res = compareSnapshots(s1, s2, shouldBeEqual); - if (res[0]) { - ok(true, testName + " snapshots compare correctly"); - } else { - ok(false, testName + " snapshots compare incorrectly. snapshot 1: " + - res[1] + " snapshot 2: " + res[2]); - } -} - -function runTest() { - document.getElementById("iframe").contentWindow.document.designMode = "on"; - - // The editor requires the event loop to spin after you turn on design mode - // before it takes effect. - setTimeout(continueTest, 100); -} - -function continueTest() { - var win = document.getElementById("iframe").contentWindow; - var doc = win.document; - var image = doc.getElementById("image"); - - // We want to test that clicking on the image and then clicking on one of the - // draggers doesn't make the draggers disappear. - - // clean snapshot - var before = snapshotWindow(win); - - // click to get the draggers - synthesizeMouse(image, 1, 1, {type: "mousedown"}, win); - synthesizeMouse(image, 1, 1, {type: "mouseup"}, win); - - // mouse over a dragger will change its color, so move the mouse away - synthesizeMouse(doc.documentElement, 50, 50, {type: "mousemove"}, win); - - // snapshot with hopefully draggers - var middle = snapshotWindow(win); - - // clicking on the top left dragger shouldn't change anything - synthesizeMouse(image, 1, 1, {type: "mousedown"}, win); - synthesizeMouse(image, 1, 1, {type: "mouseup"}, win); - - // mouse over a dragger will change its color, so move the mouse away - synthesizeMouse(doc.documentElement, 50, 50, {type: "mousemove"}, win); - - // snapshot with hopefully draggers again - var middle2 = snapshotWindow(win); - - // click outside the image (but inside the document) to unselect it - synthesizeMouse(doc.documentElement, 50, 50, {type: "mousedown"}, win); - synthesizeMouse(doc.documentElement, 50, 50, {type: "mouseup"}, win); - - // and then click outside the document so we don't draw a caret - synthesizeMouse(document.documentElement, 1, 1, {type: "mousedown"}, window); - synthesizeMouse(document.documentElement, 1, 1, {type: "mouseup"}, window); - - // hopefully clean snapshot - var end = snapshotWindow(win); - - // before == end && middle == middle2 && before/end != middle/middle2 - checkSnapshots(before, end, true, "before and after should be the same") - checkSnapshots(middle, middle2, true, "middle two should be the same"); - checkSnapshots(before, middle, false, "before and middle should not be the same"); - checkSnapshots(before, middle2, false, "before and middle2 should not be the same"); - checkSnapshots(middle, end, false, "middle and end should not be the same"); - checkSnapshots(middle2, end, false, "middle2 and end should not be the same"); - - SimpleTest.finish(); -} - -</script> -</pre> -</body> -</html>
--- a/layout/base/tests/mochitest.ini +++ b/layout/base/tests/mochitest.ini @@ -25,17 +25,16 @@ support-files = bug467672-2.html bug467672-2-ref.html bug467672-3.html bug467672-3-ref.html bug467672-4.html bug467672-4-ref.html bug467672-5.html bug467672-5-ref.html - bug558663.html bug570378-arabic-1.html bug570378-arabic-1-ref.html bug570378-arabic-2.html bug570378-arabic-2-ref.html bug570378-arabic-3.html bug570378-arabic-3-ref.html bug570378-arabic-4.html bug570378-arabic-4-ref.html
--- a/layout/base/tests/test_bug558663.html +++ b/layout/base/tests/test_bug558663.html @@ -1,33 +1,101 @@ -<!-- 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/. --> - -<!DOCTYPE html> +<!DOCTYPE HTML> <html> - <head> - <title>Bug 558663 test</title> - <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script> - <script type="application/javascript" src="/tests/SimpleTest/WindowSnapshot.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> - <style> - iframe { - width: 600px; - height: 400px; - } - </style> - </head> - <body> - <div id="container"></div> - </body> - <script> - SimpleTest.waitForExplicitFinish(); - // Selection caret's pref is checked only when PresShell is initialized. To turn - // off the pref, we test bug 558663 in an iframe. - SpecialPowers.pushPrefEnv({"set": [['selectioncaret.enabled', false]]}, function() { - var iframe = document.createElement("iframe"); - iframe.src = "bug558663.html"; - document.getElementById('container').appendChild(iframe); - }); - </script> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=558663 +--> +<head> + <title>Test for Bug 558663</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script> + <script type="application/javascript" src="/tests/SimpleTest/WindowSnapshot.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<p><a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=558663">Mozilla Bug 514127</a></p> + + <!-- 20x20 of red --> +<iframe id="iframe" src="data:text/html,<img id='image' border='0' src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAIAAAAC64paAAAAG0lEQVR42mP8z0A%2BYKJA76jmUc2jmkc1U0EzACKcASfOgGoMAAAAAElFTkSuQmCC'>"></iframe> + +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 558663 **/ + +SimpleTest.waitForExplicitFinish(); +window.addEventListener("load", runTest, false); + +function checkSnapshots(s1, s2, shouldBeEqual, testName) { + var res = compareSnapshots(s1, s2, shouldBeEqual); + if (res[0]) { + ok(true, testName + " snapshots compare correctly"); + } else { + ok(false, testName + " snapshots compare incorrectly. snapshot 1: " + + res[1] + " snapshot 2: " + res[2]); + } +} + +function runTest() { + document.getElementById("iframe").contentWindow.document.designMode = "on"; + + // The editor requires the event loop to spin after you turn on design mode + // before it takes effect. + setTimeout(continueTest, 100); +} + +function continueTest() { + var win = document.getElementById("iframe").contentWindow; + var doc = win.document; + var image = doc.getElementById("image"); + + // We want to test that clicking on the image and then clicking on one of the + // draggers doesn't make the draggers disappear. + + // clean snapshot + var before = snapshotWindow(win); + + // click to get the draggers + synthesizeMouse(image, 1, 1, {type: "mousedown"}, win); + synthesizeMouse(image, 1, 1, {type: "mouseup"}, win); + + // mouse over a dragger will change its color, so move the mouse away + synthesizeMouse(doc.documentElement, 50, 50, {type: "mousemove"}, win); + + // snapshot with hopefully draggers + var middle = snapshotWindow(win); + + // clicking on the top left dragger shouldn't change anything + synthesizeMouse(image, 1, 1, {type: "mousedown"}, win); + synthesizeMouse(image, 1, 1, {type: "mouseup"}, win); + + // mouse over a dragger will change its color, so move the mouse away + synthesizeMouse(doc.documentElement, 50, 50, {type: "mousemove"}, win); + + // snapshot with hopefully draggers again + var middle2 = snapshotWindow(win); + + // click outside the image (but inside the document) to unselect it + synthesizeMouse(doc.documentElement, 50, 50, {type: "mousedown"}, win); + synthesizeMouse(doc.documentElement, 50, 50, {type: "mouseup"}, win); + + // and then click outside the document so we don't draw a caret + synthesizeMouse(document.documentElement, 1, 1, {type: "mousedown"}, window); + synthesizeMouse(document.documentElement, 1, 1, {type: "mouseup"}, window); + + // hopefully clean snapshot + var end = snapshotWindow(win); + + // before == end && middle == middle2 && before/end != middle/middle2 + checkSnapshots(before, end, true, "before and after should be the same") + checkSnapshots(middle, middle2, true, "middle two should be the same"); + checkSnapshots(before, middle, false, "before and middle should not be the same"); + checkSnapshots(before, middle2, false, "before and middle2 should not be the same"); + checkSnapshots(middle, end, false, "middle and end should not be the same"); + checkSnapshots(middle2, end, false, "middle2 and end should not be the same"); + + SimpleTest.finish(); +} + +</script> +</pre> +</body> </html>
--- a/mobile/android/app/mobile.js +++ b/mobile/android/app/mobile.js @@ -139,16 +139,17 @@ pref("browser.download.manager.showAlert pref("browser.download.manager.showAlertInterval", 2000); pref("browser.download.manager.retention", 2); pref("browser.download.manager.showWhenStarting", false); pref("browser.download.manager.closeWhenDone", true); pref("browser.download.manager.openDelay", 0); pref("browser.download.manager.focusWhenStarting", false); pref("browser.download.manager.flashCount", 2); pref("browser.download.manager.displayedHistoryDays", 7); +pref("browser.download.manager.addToRecentDocs", true); /* download helper */ pref("browser.helperApps.deleteTempFileOnExit", false); /* password manager */ pref("signon.rememberSignons", true); pref("signon.expireMasterPassword", false); pref("signon.debug", false);
--- a/mobile/android/base/AndroidManifest.xml.in +++ b/mobile/android/base/AndroidManifest.xml.in @@ -35,17 +35,17 @@ <uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT"/> <uses-permission android:name="com.android.browser.permission.READ_HISTORY_BOOKMARKS"/> <uses-permission android:name="android.permission.WAKE_LOCK"/> <uses-permission android:name="android.permission.VIBRATE"/> <uses-permission android:name="@ANDROID_PACKAGE_NAME@.permissions.PASSWORD_PROVIDER"/> <uses-permission android:name="@ANDROID_PACKAGE_NAME@.permissions.BROWSER_PROVIDER"/> <uses-permission android:name="@ANDROID_PACKAGE_NAME@.permissions.FORMHISTORY_PROVIDER"/> - + <uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" /> #ifdef MOZ_WEBSMS_BACKEND <!-- WebSMS --> <uses-permission android:name="android.permission.SEND_SMS"/> <uses-permission android:name="android.permission.RECEIVE_SMS"/> <uses-permission android:name="android.permission.WRITE_SMS"/> <uses-permission android:name="android.permission.READ_SMS"/> #endif
--- a/mobile/android/base/GeckoAppShell.java +++ b/mobile/android/base/GeckoAppShell.java @@ -55,16 +55,17 @@ import org.mozilla.gecko.util.HardwareUt import org.mozilla.gecko.util.NativeEventListener; import org.mozilla.gecko.util.NativeJSContainer; import org.mozilla.gecko.util.NativeJSObject; import org.mozilla.gecko.util.ProxySelector; import org.mozilla.gecko.util.ThreadUtils; import android.app.Activity; import android.app.ActivityManager; +import android.app.DownloadManager; import android.app.PendingIntent; import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; @@ -1791,27 +1792,39 @@ public class GeckoAppShell if (!TextUtils.isEmpty(name) && !TextUtils.isEmpty(file) && file.startsWith(filter)) Log.d(LOGTAG, "[OPENFILE] " + name + "(" + split[pidColumn] + ") : " + file); } in.close(); } catch (Exception e) { } } @WrapElementForJNI - public static void scanMedia(String aFile, String aMimeType) { + public static void scanMedia(final String aFile, String aMimeType) { // If the platform didn't give us a mimetype, try to guess one from the filename if (TextUtils.isEmpty(aMimeType)) { int extPosition = aFile.lastIndexOf("."); if (extPosition > 0 && extPosition < aFile.length() - 1) { aMimeType = getMimeTypeFromExtension(aFile.substring(extPosition+1)); } } - Context context = getContext(); - GeckoMediaScannerClient.startScan(context, aFile, aMimeType); + final File f = new File(aFile); + if (AppConstants.Versions.feature12Plus) { + final DownloadManager dm = (DownloadManager) getContext().getSystemService(Context.DOWNLOAD_SERVICE); + dm.addCompletedDownload(f.getName(), + f.getName(), + !TextUtils.isEmpty(aMimeType), + aMimeType, + f.getAbsolutePath(), + f.length(), + false); + } else { + Context context = getContext(); + GeckoMediaScannerClient.startScan(context, aFile, aMimeType); + } } @WrapElementForJNI(stubName = "GetIconForExtensionWrapper") public static byte[] getIconForExtension(String aExt, int iconSize) { try { if (iconSize <= 0) iconSize = 16;
--- a/mobile/android/chrome/content/FindHelper.js +++ b/mobile/android/chrome/content/FindHelper.js @@ -73,13 +73,13 @@ var FindHelper = { Cu.reportError("Warning: selected tab changed during find!"); // fall through and restore viewport on the initial tab anyway } this._targetTab.setViewport(JSON.parse(this._initialViewport)); this._targetTab.sendViewportUpdate(); } } else { // Disabled until bug 1014113 is fixed - //ZoomHelper.zoomToRect(aData.rect, -1, false, true); + // ZoomHelper.zoomToRect(aData.rect); this._viewportChanged = true; } } };
--- a/mobile/android/chrome/content/ZoomHelper.js +++ b/mobile/android/chrome/content/ZoomHelper.js @@ -76,72 +76,71 @@ var ZoomHelper = { dw > minDifference && dw < maxDifference); }, /* Zoom to an element, optionally keeping a particular part of it * in view if it is really tall. */ zoomToElement: function(aElement, aClickY = -1, aCanZoomOut = true, aCanScrollHorizontally = true) { let rect = ElementTouchHelper.getBoundingContentRect(aElement); - ZoomHelper.zoomToRect(rect, aClickY, aCanZoomOut, aCanScrollHorizontally, aElement); - }, - zoomToRect: function(aRect, aClickY = -1, aCanZoomOut = true, aCanScrollHorizontally = true, aElement) { const margin = 15; - if(!aRect.h || !aRect.w) { - aRect.h = aRect.height; - aRect.w = aRect.width; - } - let viewport = BrowserApp.selectedTab.getViewport(); - let bRect = new Rect(aCanScrollHorizontally ? Math.max(viewport.cssPageLeft, aRect.x - margin) : viewport.cssX, - aRect.y, - aCanScrollHorizontally ? aRect.w + 2 * margin : viewport.cssWidth, - aRect.h); + rect = new Rect(aCanScrollHorizontally ? Math.max(viewport.cssPageLeft, rect.x - margin) : viewport.cssX, + rect.y, + aCanScrollHorizontally ? rect.w + 2 * margin : viewport.cssWidth, + rect.h); // constrict the rect to the screen's right edge - bRect.width = Math.min(bRect.width, viewport.cssPageRight - bRect.x); + rect.width = Math.min(rect.width, viewport.cssPageRight - rect.x); // if the rect is already taking up most of the visible area and is stretching the // width of the page, then we want to zoom out instead. if (aElement) { if (BrowserEventHandler.mReflozPref) { let zoomFactor = BrowserApp.selectedTab.getZoomToMinFontSize(aElement); - bRect.width = zoomFactor <= 1.0 ? bRect.width : gScreenWidth / zoomFactor; - bRect.height = zoomFactor <= 1.0 ? bRect.height : bRect.height / zoomFactor; - if (zoomFactor == 1.0 || ZoomHelper.isRectZoomedIn(bRect, viewport)) { + rect.width = zoomFactor <= 1.0 ? rect.width : gScreenWidth / zoomFactor; + rect.height = zoomFactor <= 1.0 ? rect.height : rect.height / zoomFactor; + if (zoomFactor == 1.0 || ZoomHelper.isRectZoomedIn(rect, viewport)) { if (aCanZoomOut) { ZoomHelper.zoomOut(); } return; } - } else if (ZoomHelper.isRectZoomedIn(bRect, viewport)) { + } else if (ZoomHelper.isRectZoomedIn(rect, viewport)) { if (aCanZoomOut) { ZoomHelper.zoomOut(); } return; } + + ZoomHelper.zoomToRect(rect, aClickY); } + }, - let rect = {}; + /* Zoom to a specific part of the screen defined by a rect, + * optionally keeping a particular part of it in view + * if it is really tall. + */ + zoomToRect: function(aRect, aClickY = -1) { + let rect = new Rect(aRect.x, + aRect.y, + aRect.width, + Math.min(aRect.width * viewport.cssHeight / viewport.cssWidth, aRect.height)); rect.type = "Browser:ZoomToRect"; - rect.x = bRect.x; - rect.y = bRect.y; - rect.w = bRect.width; - rect.h = Math.min(bRect.width * viewport.cssHeight / viewport.cssWidth, bRect.height); if (aClickY >= 0) { // if the block we're zooming to is really tall, and we want to keep a particular // part of it in view, then adjust the y-coordinate of the target rect accordingly. - // the 1.2 multiplier is just a little fuzz to compensate for bRect including horizontal + // the 1.2 multiplier is just a little fuzz to compensate for aRect including horizontal // margins but not vertical ones. let cssTapY = viewport.cssY + aClickY; - if ((bRect.height > rect.h) && (cssTapY > rect.y + (rect.h * 1.2))) { + if ((aRect.height > rect.h) && (cssTapY > rect.y + (rect.h * 1.2))) { rect.y = cssTapY - (rect.h / 2); } } if (rect.w > viewport.cssWidth || rect.h > viewport.cssHeight) { BrowserEventHandler.resetMaxLineBoxWidth(); }
--- a/toolkit/components/downloads/nsDownloadManager.cpp +++ b/toolkit/components/downloads/nsDownloadManager.cpp @@ -2760,17 +2760,17 @@ nsDownload::SetState(DownloadState aStat nsCOMPtr<nsIFile> file; nsAutoString path; if (fileURL && NS_SUCCEEDED(fileURL->GetFile(getter_AddRefs(file))) && file && NS_SUCCEEDED(file->GetPath(path))) { -#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK) +#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_ANDROID) // On Windows and Gtk, add the download to the system's "recent documents" // list, with a pref to disable. { bool addToRecentDocs = true; if (pref) pref->GetBoolPref(PREF_BDM_ADDTORECENTDOCS, &addToRecentDocs); if (addToRecentDocs && !mPrivate) { @@ -2780,16 +2780,25 @@ nsDownload::SetState(DownloadState aStat GtkRecentManager* manager = gtk_recent_manager_get_default(); gchar* uri = g_filename_to_uri(NS_ConvertUTF16toUTF8(path).get(), nullptr, nullptr); if (uri) { gtk_recent_manager_add_item(manager, uri); g_free(uri); } +#elif defined(MOZ_WIDGET_ANDROID) + nsCOMPtr<nsIMIMEInfo> mimeInfo; + nsAutoCString contentType; + GetMIMEInfo(getter_AddRefs(mimeInfo)); + + if (mimeInfo) + mimeInfo->GetMIMEType(contentType); + + mozilla::widget::android::GeckoAppShell::ScanMedia(path, NS_ConvertUTF8toUTF16(contentType)); #endif } #ifdef MOZ_ENABLE_GIO // Use GIO to store the source URI for later display in the file manager. GFile* gio_file = g_file_new_for_path(NS_ConvertUTF16toUTF8(path).get()); nsCString source_uri; mSource->GetSpec(source_uri); GFileInfo *file_info = g_file_info_new(); @@ -2809,26 +2818,16 @@ nsDownload::SetState(DownloadState aStat CFStringRef observedObject = ::CFStringCreateWithCString(kCFAllocatorDefault, NS_ConvertUTF16toUTF8(path).get(), kCFStringEncodingUTF8); CFNotificationCenterRef center = ::CFNotificationCenterGetDistributedCenter(); ::CFNotificationCenterPostNotification(center, CFSTR("com.apple.DownloadFileFinished"), observedObject, nullptr, TRUE); ::CFRelease(observedObject); #endif -#ifdef MOZ_WIDGET_ANDROID - nsCOMPtr<nsIMIMEInfo> mimeInfo; - nsAutoCString contentType; - GetMIMEInfo(getter_AddRefs(mimeInfo)); - - if (mimeInfo) - mimeInfo->GetMIMEType(contentType); - - mozilla::widget::android::GeckoAppShell::ScanMedia(path, NS_ConvertUTF8toUTF16(contentType)); -#endif } #ifdef XP_WIN // Adjust file attributes so that by default, new files are indexed // by desktop search services. Skip off those that land in the temp // folder. nsCOMPtr<nsIFile> tempDir, fileDir; rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(tempDir));
--- a/toolkit/components/jsdownloads/src/DownloadPlatform.cpp +++ b/toolkit/components/jsdownloads/src/DownloadPlatform.cpp @@ -67,33 +67,35 @@ static void gio_set_metadata_done(GObjec #endif nsresult DownloadPlatform::DownloadDone(nsIURI* aSource, nsIFile* aTarget, const nsACString& aContentType, bool aIsPrivate) { #if defined(XP_WIN) || defined(XP_MACOSX) || defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GTK) nsAutoString path; if (aTarget && NS_SUCCEEDED(aTarget->GetPath(path))) { -#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK) +#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_ANDROID) // On Windows and Gtk, add the download to the system's "recent documents" // list, with a pref to disable. { bool addToRecentDocs = Preferences::GetBool(PREF_BDM_ADDTORECENTDOCS); if (addToRecentDocs && !aIsPrivate) { #ifdef XP_WIN ::SHAddToRecentDocs(SHARD_PATHW, path.get()); #elif defined(MOZ_WIDGET_GTK) GtkRecentManager* manager = gtk_recent_manager_get_default(); gchar* uri = g_filename_to_uri(NS_ConvertUTF16toUTF8(path).get(), nullptr, nullptr); if (uri) { gtk_recent_manager_add_item(manager, uri); g_free(uri); } +#elif MOZ_WIDGET_ANDROID + mozilla::widget::android::GeckoAppShell::ScanMedia(path, NS_ConvertUTF8toUTF16(aContentType)); #endif } #ifdef MOZ_ENABLE_GIO // Use GIO to store the source URI for later display in the file manager. GFile* gio_file = g_file_new_for_path(NS_ConvertUTF16toUTF8(path).get()); nsCString source_uri; aSource->GetSpec(source_uri); GFileInfo *file_info = g_file_info_new(); @@ -113,21 +115,16 @@ nsresult DownloadPlatform::DownloadDone( CFStringRef observedObject = ::CFStringCreateWithCString(kCFAllocatorDefault, NS_ConvertUTF16toUTF8(path).get(), kCFStringEncodingUTF8); CFNotificationCenterRef center = ::CFNotificationCenterGetDistributedCenter(); ::CFNotificationCenterPostNotification(center, CFSTR("com.apple.DownloadFileFinished"), observedObject, nullptr, TRUE); ::CFRelease(observedObject); #endif -#ifdef MOZ_WIDGET_ANDROID - if (!aContentType.IsEmpty()) { - mozilla::widget::android::GeckoAppShell::ScanMedia(path, NS_ConvertUTF8toUTF16(aContentType)); - } -#endif } #ifdef XP_WIN // Adjust file attributes so that by default, new files are indexed by // desktop search services. Skip off those that land in the temp folder. nsCOMPtr<nsIFile> tempDir, fileDir; nsresult rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(tempDir)); NS_ENSURE_SUCCESS(rv, rv);
--- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -6584,16 +6584,21 @@ "description": "Tracking protection shield (0 = not shown, 1 = blocked, 2 = loaded, 3 = due to mixed content" }, "TRACKING_PROTECTION_EVENTS": { "expires_in_version": "never", "kind": "enumerated", "n_values": 3, "description": "Doorhanger shown = 0, Disable = 1, Enable = 2" }, + "LOOP_CLIENT_CALL_URL_REQUESTS_SUCCESS": { + "expires_in_version": "never", + "kind": "boolean", + "description": "Stores 1 if generating a call URL succeeded, and 0 if it failed." + }, "E10S_AUTOSTART": { "expires_in_version": "never", "kind": "boolean", "description": "Whether a session is set to autostart e10s windows" }, "E10S_WINDOW": { "expires_in_version": "never", "kind": "boolean",
--- a/toolkit/components/thumbnails/test/head.js +++ b/toolkit/components/thumbnails/test/head.js @@ -225,17 +225,17 @@ function addVisits(aPlaceInfo, aCallback places = places.concat(aPlaceInfo); } else { places.push(aPlaceInfo) } // Create mozIVisitInfo for each entry. let now = Date.now(); for (let i = 0; i < places.length; i++) { - if (typeof(places[i] == "string")) { + if (typeof(places[i]) == "string") { places[i] = { uri: Services.io.newURI(places[i], "", null) }; } if (!places[i].title) { places[i].title = "test visit for " + places[i].uri.spec; } places[i].visits = [{ transitionType: places[i].transition === undefined ? PlacesUtils.history.TRANSITION_LINK : places[i].transition,
--- a/toolkit/devtools/server/actors/timeline.js +++ b/toolkit/devtools/server/actors/timeline.js @@ -2,18 +2,17 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ "use strict"; /** * Many Gecko operations (painting, reflows, restyle, ...) can be tracked * in real time. A marker is a representation of one operation. A marker - * has a name, and start and end timestamps. Markers are stored within - * a docshell. + * has a name, and start and end timestamps. Markers are stored in docShells. * * This actor exposes this tracking mechanism to the devtools protocol. * * To start/stop recording markers: * TimelineFront.start() * TimelineFront.stop() * TimelineFront.isRecording() * @@ -23,101 +22,163 @@ */ const {Ci, Cu} = require("chrome"); const protocol = require("devtools/server/protocol"); const {method, Arg, RetVal} = protocol; const events = require("sdk/event/core"); const {setTimeout, clearTimeout} = require("sdk/timers"); +// How often do we pull markers from the docShells, and therefore, how often do +// we send events to the front (knowing that when there are no markers in the +// docShell, no event is sent). const DEFAULT_TIMELINE_DATA_PULL_TIMEOUT = 200; // ms /** - * The timeline actor pops and forwards timeline markers registered in - * a docshell. + * The timeline actor pops and forwards timeline markers registered in docshells. */ let TimelineActor = exports.TimelineActor = protocol.ActorClass({ typeName: "timeline", events: { /** - * "markers" events are emitted at regular intervals when profile markers - * are found. A marker has the following properties: - * - start {Number} - * - end {Number} + * "markers" events are emitted every DEFAULT_TIMELINE_DATA_PULL_TIMEOUT ms + * at most, when profile markers are found. A marker has the following + * properties: + * - start {Number} ms + * - end {Number} ms * - name {String} */ "markers" : { type: "markers", markers: Arg(0, "array:json") } }, initialize: function(conn, tabActor) { protocol.Actor.prototype.initialize.call(this, conn); - this.docshell = tabActor.docShell; + this.tabActor = tabActor; + + this._isRecording = false; + + // Make sure to get markers from new windows as they become available + this._onWindowReady = this._onWindowReady.bind(this); + events.on(this.tabActor, "window-ready", this._onWindowReady); }, /** * The timeline actor is the first (and last) in its hierarchy to use protocol.js * so it doesn't have a parent protocol actor that takes care of its lifetime. * So it needs a disconnect method to cleanup. */ disconnect: function() { this.destroy(); }, destroy: function() { this.stop(); - this.docshell = null; + + events.off(this.tabActor, "window-ready", this._onWindowReady); + this.tabActor = null; + protocol.Actor.prototype.destroy.call(this); }, /** + * Convert a window to a docShell. + * @param {nsIDOMWindow} + * @return {nsIDocShell} + */ + toDocShell: win => win.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebNavigation) + .QueryInterface(Ci.nsIDocShell), + + /** + * Get the list of docShells in the currently attached tabActor. + * @return {Array} + */ + get docShells() { + return this.tabActor.windows.map(this.toDocShell); + }, + + /** * At regular intervals, pop the markers from the docshell, and forward * markers if any. */ _pullTimelineData: function() { - let markers = this.docshell.popProfileTimelineMarkers(); + if (!this._isRecording) { + return; + } + + let markers = []; + for (let docShell of this.docShells) { + markers = [...markers, ...docShell.popProfileTimelineMarkers()]; + } if (markers.length > 0) { events.emit(this, "markers", markers); } + this._dataPullTimeout = setTimeout(() => { this._pullTimelineData(); }, DEFAULT_TIMELINE_DATA_PULL_TIMEOUT); }, /** - * Are we recording profile markers for the current docshell (window)? + * Are we recording profile markers currently? */ isRecording: method(function() { - return this.docshell.recordProfileTimelineMarkers; + return this._isRecording; }, { request: {}, response: { value: RetVal("boolean") } }), /** - * Start/stop recording profile markers. + * Start recording profile markers. */ start: method(function() { - if (!this.docshell.recordProfileTimelineMarkers) { - this.docshell.recordProfileTimelineMarkers = true; - this._pullTimelineData(); + if (this._isRecording) { + return; } + this._isRecording = true; + + for (let docShell of this.docShells) { + docShell.recordProfileTimelineMarkers = true; + } + + this._pullTimelineData(); }, {}), + /** + * Stop recording profile markers. + */ stop: method(function() { - if (this.docshell.recordProfileTimelineMarkers) { - this.docshell.recordProfileTimelineMarkers = false; - clearTimeout(this._dataPullTimeout); + if (!this._isRecording) { + return; + } + this._isRecording = false; + + for (let docShell of this.docShells) { + docShell.recordProfileTimelineMarkers = false; } + + clearTimeout(this._dataPullTimeout); }, {}), + + /** + * When a new window becomes available in the tabActor, start recording its + * markers if we were recording. + */ + _onWindowReady: function({window}) { + if (this._isRecording) { + this.toDocShell(window).recordProfileTimelineMarkers = true; + } + } }); exports.TimelineFront = protocol.FrontClass(TimelineActor, { initialize: function(client, {timelineActor}) { protocol.Front.prototype.initialize.call(this, client, {actor: timelineActor}); this.manage(this); },
--- a/toolkit/devtools/server/actors/tracer.js +++ b/toolkit/devtools/server/actors/tracer.js @@ -101,17 +101,16 @@ TracerActor.prototype = { get attached() { return this._attached; }, get idle() { return this._attached && this._activeTraces.size === 0; }, get tracing() { return this._attached && this._activeTraces.size > 0; }, get dbg() { if (!this._dbg) { this._dbg = this._parent.makeDebugger(); - this._dbg.onEnterFrame = this.onEnterFrame; } return this._dbg; }, /** * Buffer traces and only send them every BUFFER_SEND_DELAY milliseconds. */ _send: function(aPacket) { @@ -183,16 +182,17 @@ TracerActor.prototype = { return { error: "badParameterType", message: "No such trace type: " + traceType }; } } if (this.idle) { + this.dbg.onEnterFrame = this.onEnterFrame; this.dbg.enabled = true; this._sequence = 0; this._startTime = Date.now(); } // Start recording all requested trace types. for (let traceType of aRequest.trace) { this._requestsForTraceType[traceType]++; @@ -239,16 +239,17 @@ TracerActor.prototype = { } // Clear hit counts if no trace is requesting them. if (!this._requestsForTraceType.hitCount) { this._hitCounts.clear(); } if (this.idle) { + this._dbg.onEnterFrame = undefined; this.dbg.enabled = false; } return { type: "stoppedTrace", why: "requested", name }; @@ -259,21 +260,21 @@ TracerActor.prototype = { /** * Called by the engine when a frame is entered. Sends an unsolicited packet * to the client carrying requested trace information. * * @param aFrame Debugger.Frame * The stack frame that was entered. */ onEnterFrame: function(aFrame) { + if (aFrame.script && aFrame.script.url == "self-hosted") { + return; + } + Task.spawn(function*() { - if (aFrame.script && aFrame.script.url == "self-hosted") { - return; - } - // This function might request original (i.e. source-mapped) location, // which is asynchronous. We need to ensure that packets are sent out // in the correct order. let runInOrder = this._packetScheduler.schedule(); let packet = { type: "enteredFrame", sequence: this._sequence++
--- a/toolkit/devtools/server/tests/browser/browser.ini +++ b/toolkit/devtools/server/tests/browser/browser.ini @@ -1,19 +1,23 @@ [DEFAULT] skip-if = e10s # Bug ?????? - devtools tests disabled with e10s subsuite = devtools support-files = head.js + navigate-first.html + navigate-second.html storage-dynamic-windows.html storage-listings.html storage-unsecured-iframe.html storage-updates.html storage-secured-iframe.html - navigate-first.html - navigate-second.html + timeline-iframe-child.html + timeline-iframe-parent.html +[browser_navigateEvents.js] [browser_storage_dynamic_windows.js] [browser_storage_listings.js] [browser_storage_updates.js] -[browser_navigateEvents.js] [browser_timeline.js] skip-if = buildapp == 'mulet' +[browser_timeline_iframes.js] +skip-if = buildapp == 'mulet'
--- a/toolkit/devtools/server/tests/browser/browser_navigateEvents.js +++ b/toolkit/devtools/server/tests/browser/browser_navigateEvents.js @@ -1,22 +1,18 @@ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ -let Cu = Components.utils; -let Cc = Components.classes; -let Ci = Components.interfaces; +"use strict"; const URL1 = MAIN_DOMAIN + "navigate-first.html"; const URL2 = MAIN_DOMAIN + "navigate-second.html"; -let { DebuggerClient } = Cu.import("resource://gre/modules/devtools/dbg-client.jsm", {}); -let { DebuggerServer } = Cu.import("resource://gre/modules/devtools/dbg-server.jsm", {}); - -let devtools = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools; -let events = devtools.require("sdk/event/core"); - +let events = require("sdk/event/core"); let client; // State machine to check events order let i = 0; function assertEvent(event, data) { let x = 0; switch(i++) { case x++: @@ -92,34 +88,28 @@ function onDOMContentLoaded() { assertEvent("DOMContentLoaded"); } function onLoad() { assertEvent("load"); } function getServerTabActor(callback) { // Ensure having a minimal server - if (!DebuggerServer.initialized) { - DebuggerServer.init(function () { return true; }); - DebuggerServer.addBrowserActors(); - } + initDebuggerServer(); // Connect to this tab let transport = DebuggerServer.connectPipe(); client = new DebuggerClient(transport); - client.connect(function onConnect() { - client.listTabs(function onListTabs(aResponse) { - // Fetch the BrowserTabActor for this tab - let actorID = aResponse.tabs[aResponse.selected].actor; - client.attachTab(actorID, function(aResponse, aTabClient) { - // !Hack! Retrieve a server side object, the BrowserTabActor instance - let conn = transport._serverConnection; - let tabActor = conn.getActor(actorID); - callback(tabActor); - }); + connectDebuggerClient(client).then(form => { + let actorID = form.actor; + client.attachTab(actorID, function(aResponse, aTabClient) { + // !Hack! Retrieve a server side object, the BrowserTabActor instance + let conn = transport._serverConnection; + let tabActor = conn.getActor(actorID); + callback(tabActor); }); }); client.addListener("tabNavigated", function (aEvent, aPacket) { assertEvent("tabNavigated", aPacket); }); }
--- a/toolkit/devtools/server/tests/browser/browser_storage_dynamic_windows.js +++ b/toolkit/devtools/server/tests/browser/browser_storage_dynamic_windows.js @@ -1,16 +1,13 @@ -const Cu = Components.utils; -Cu.import("resource://gre/modules/Services.jsm"); -let tempScope = {}; -Cu.import("resource://gre/modules/devtools/dbg-client.jsm", tempScope); -Cu.import("resource://gre/modules/devtools/dbg-server.jsm", tempScope); -Cu.import("resource://gre/modules/Promise.jsm", tempScope); -let {DebuggerServer, DebuggerClient, Promise} = tempScope; -tempScope = null; +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; const {StorageFront} = require("devtools/server/actors/storage"); let gFront, gWindow; const beforeReload = { cookies: { "test1.example.org": ["c1", "cs2", "c3", "uc1"], "sectest1.example.org": ["uc1", "cs2"] @@ -55,17 +52,17 @@ function finishTests(client) { let closeConnection = () => { // Forcing GC/CC to get rid of docshells and windows created by this test. forceCollections(); client.close(() => { forceCollections(); DebuggerServer.destroy(); forceCollections(); - gFront = gWindow = DebuggerClient = DebuggerServer = null; + gFront = gWindow = null; finish(); }); } gWindow.clearIterator = gWindow.clear(() => { clearIDB(gWindow, 0, closeConnection); }); gWindow.clearIterator.next(); } @@ -301,33 +298,23 @@ function testRemoveIframe() { break; } } return reloaded.promise; } function test() { addTab(MAIN_DOMAIN + "storage-dynamic-windows.html").then(function(doc) { - try { - // Sometimes debugger server does not get destroyed correctly by previous - // tests. - DebuggerServer.destroy(); - } catch (ex) { } - DebuggerServer.init(function () { return true; }); - DebuggerServer.addBrowserActors(); + initDebuggerServer(); let createConnection = () => { let client = new DebuggerClient(DebuggerServer.connectPipe()); - client.connect(function onConnect() { - client.listTabs(function onListTabs(aResponse) { - let form = aResponse.tabs[aResponse.selected]; - gFront = StorageFront(client, form); - - gFront.listStores().then(data => testStores(data, client)); - }); + connectDebuggerClient(client).then(form => { + gFront = StorageFront(client, form); + gFront.listStores().then(data => testStores(data, client)); }); }; /** * This method iterates over iframes in a window and setups the indexed db * required for this test. */ let setupIDBInFrames = (w, i, c) => {
--- a/toolkit/devtools/server/tests/browser/browser_storage_listings.js +++ b/toolkit/devtools/server/tests/browser/browser_storage_listings.js @@ -1,18 +1,15 @@ -const Cu = Components.utils; -Cu.import("resource://gre/modules/Services.jsm"); -let tempScope = {}; -Cu.import("resource://gre/modules/devtools/dbg-client.jsm", tempScope); -Cu.import("resource://gre/modules/devtools/dbg-server.jsm", tempScope); -let {DebuggerServer, DebuggerClient} = tempScope; -tempScope = null; +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; const {StorageFront} = require("devtools/server/actors/storage"); -let {Task} = require("resource://gre/modules/Task.jsm"); let gWindow = null; const storeMap = { cookies: { "test1.example.org": [ { name: "c1", value: "foobar", @@ -343,17 +340,17 @@ function finishTests(client) { let closeConnection = () => { // Forcing GC/CC to get rid of docshells and windows created by this test. forceCollections(); client.close(() => { forceCollections(); DebuggerServer.destroy(); forceCollections(); - gWindow = DebuggerClient = DebuggerServer = null; + gWindow = null; finish(); }); } gWindow.clearIterator = gWindow.clear(() => { clearIDB(gWindow, 0, closeConnection); }); gWindow.clearIterator.next(); } @@ -635,34 +632,24 @@ let testIDBEntries = Task.async(function if (index == Object.keys(hosts).length - 1) { return; } yield testObjectStores(++index, hosts, indexedDBActor); }); function test() { addTab(MAIN_DOMAIN + "storage-listings.html").then(function(doc) { - try { - // Sometimes debugger server does not get destroyed correctly by previous - // tests. - DebuggerServer.destroy(); - } catch (ex) { } - DebuggerServer.init(function () { return true; }); - DebuggerServer.addBrowserActors(); + initDebuggerServer(); let createConnection = () => { let client = new DebuggerClient(DebuggerServer.connectPipe()); - client.connect(function onConnect() { - client.listTabs(function onListTabs(aResponse) { - let form = aResponse.tabs[aResponse.selected]; - let front = StorageFront(client, form); - - front.listStores().then(data => testStores(data)) - .then(() => finishTests(client)); - }); + connectDebuggerClient(client).then(form => { + let front = StorageFront(client, form); + front.listStores().then(data => testStores(data)) + .then(() => finishTests(client)); }); }; /** * This method iterates over iframes in a window and setups the indexed db * required for this test. */ let setupIDBInFrames = (w, i, c) => {
--- a/toolkit/devtools/server/tests/browser/browser_storage_updates.js +++ b/toolkit/devtools/server/tests/browser/browser_storage_updates.js @@ -1,16 +1,13 @@ -const Cu = Components.utils; -Cu.import("resource://gre/modules/Services.jsm"); -let tempScope = {}; -Cu.import("resource://gre/modules/devtools/dbg-client.jsm", tempScope); -Cu.import("resource://gre/modules/devtools/dbg-server.jsm", tempScope); -Cu.import("resource://gre/modules/Promise.jsm", tempScope); -let {DebuggerServer, DebuggerClient, Promise} = tempScope; -tempScope = null; +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; const {StorageFront} = require("devtools/server/actors/storage"); let gTests; let gExpected; let index = 0; const beforeReload = { cookies: ["test1.example.org", "sectest1.example.org"], @@ -20,17 +17,17 @@ const beforeReload = { function finishTests(client) { // Forcing GC/CC to get rid of docshells and windows created by this test. forceCollections(); client.close(() => { forceCollections(); DebuggerServer.destroy(); forceCollections(); - DebuggerClient = DebuggerServer = gTests = null; + gTests = null; finish(); }); } function markOutMatched(toBeEmptied, data, deleted) { if (!Object.keys(toBeEmptied).length) { info("Object empty") return; @@ -227,29 +224,20 @@ function* UpdateTests(front, win, client front.off("stores-cleared", onStoresCleared); front.off("stores-update", onStoresUpdate); finishTests(client); } function test() { addTab(MAIN_DOMAIN + "storage-updates.html").then(function(doc) { - try { - // Sometimes debugger server does not get destroyed correctly by previous - // tests. - DebuggerServer.destroy(); - } catch (ex) { } - DebuggerServer.init(function () { return true; }); - DebuggerServer.addBrowserActors(); + initDebuggerServer(); let client = new DebuggerClient(DebuggerServer.connectPipe()); - client.connect(function onConnect() { - client.listTabs(function onListTabs(aResponse) { - let form = aResponse.tabs[aResponse.selected]; - let front = StorageFront(client, form); - gTests = UpdateTests(front, doc.defaultView.wrappedJSObject, - client); - // Make an initial call to initialize the actor - front.listStores().then(() => gTests.next()); - }); + connectDebuggerClient(client).then(form => { + let front = StorageFront(client, form); + gTests = UpdateTests(front, doc.defaultView.wrappedJSObject, + client); + // Make an initial call to initialize the actor + front.listStores().then(() => gTests.next()); }); }) }
--- a/toolkit/devtools/server/tests/browser/browser_timeline.js +++ b/toolkit/devtools/server/tests/browser/browser_timeline.js @@ -1,34 +1,26 @@ /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ + "use strict"; +// Test that the timeline front's start/stop/isRecording methods work in a +// simple use case, and that markers events are sent when operations occur. + +const {TimelineFront} = require("devtools/server/actors/timeline"); + let test = asyncTest(function*() { - const {TimelineFront} = require("devtools/server/actors/timeline"); - const Cu = Components.utils; - let tempScope = {}; - Cu.import("resource://gre/modules/devtools/dbg-client.jsm", tempScope); - Cu.import("resource://gre/modules/devtools/dbg-server.jsm", tempScope); - let {DebuggerServer, DebuggerClient} = tempScope; - let doc = yield addTab("data:text/html;charset=utf-8,mop"); - DebuggerServer.init(function () { return true; }); - DebuggerServer.addBrowserActors(); + initDebuggerServer(); let client = new DebuggerClient(DebuggerServer.connectPipe()); - let onListTabs = promise.defer(); - client.connect(() => { - client.listTabs(onListTabs.resolve); - }); - let listTabs = yield onListTabs.promise; - - let form = listTabs.tabs[listTabs.selected]; + let form = yield connectDebuggerClient(client); let front = TimelineFront(client, form); let isActive = yield front.isRecording(); ok(!isActive, "Not initially recording"); doc.body.innerHeight; // flush any pending reflow yield front.start(); @@ -54,14 +46,11 @@ let test = asyncTest(function*() { ok(markers.some(m => m.name == "Paint"), "markers includes Paint"); ok(markers.some(m => m.name == "Styles"), "markers includes Restyle"); yield front.stop(); isActive = yield front.isRecording(); ok(!isActive, "Not recording after stop()"); - let onClose = promise.defer(); - client.close(onClose.resolve); - yield onClose; - + yield closeDebuggerClient(client); gBrowser.removeCurrentTab(); });
new file mode 100644 --- /dev/null +++ b/toolkit/devtools/server/tests/browser/browser_timeline_iframes.js @@ -0,0 +1,41 @@ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test the timeline front receives markers events for operations that occur in +// iframes. + +const {TimelineFront} = require("devtools/server/actors/timeline"); + +let test = asyncTest(function*() { + let doc = yield addTab(MAIN_DOMAIN + "timeline-iframe-parent.html"); + + initDebuggerServer(); + let client = new DebuggerClient(DebuggerServer.connectPipe()); + let form = yield connectDebuggerClient(client); + let front = TimelineFront(client, form); + + info("Start timeline marker recording"); + yield front.start(); + + // Check that we get markers for a few iterations of the timer that runs in + // the child frame. + for (let i = 0; i < 3; i ++) { + yield wait(300); // That's the time the child frame waits before changing styles. + let markers = yield once(front, "markers"); + ok(markers.length, "Markers were received for operations in the child frame"); + } + + info("Stop timeline marker recording"); + yield front.stop(); + yield closeDebuggerClient(client); + gBrowser.removeCurrentTab(); +}); + +function wait(ms) { + let def = promise.defer(); + setTimeout(def.resolve, ms); + return def.promise; +}
--- a/toolkit/devtools/server/tests/browser/head.js +++ b/toolkit/devtools/server/tests/browser/head.js @@ -1,28 +1,33 @@ /* 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/. */ -let tempScope = {}; -Cu.import("resource://gre/modules/devtools/Loader.jsm", tempScope); -Cu.import("resource://gre/modules/devtools/Console.jsm", tempScope); -const require = tempScope.devtools.require; -const console = tempScope.console; -tempScope = null; + +const Cc = Components.classes; +const Ci = Components.interfaces; +const Cu = Components.utils; + +Cu.import("resource://gre/modules/Services.jsm"); +const {console} = Cu.import("resource://gre/modules/devtools/Console.jsm", {}); +const {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {}); +const {devtools: {require}} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}); +const {DebuggerClient} = Cu.import("resource://gre/modules/devtools/dbg-client.jsm", {}); +const {DebuggerServer} = Cu.import("resource://gre/modules/devtools/dbg-server.jsm", {}); + const PATH = "browser/toolkit/devtools/server/tests/browser/"; const MAIN_DOMAIN = "http://test1.example.org/" + PATH; const ALT_DOMAIN = "http://sectest1.example.org/" + PATH; const ALT_DOMAIN_SECURED = "https://sectest1.example.org:443/" + PATH; -const { Promise: promise } = Cu.import("resource://gre/modules/Promise.jsm", {}); -// All test are asynchronous +// All tests are asynchronous. waitForExplicitFinish(); /** - * Define an async test based on a generator function + * Define an async test based on a generator function. */ function asyncTest(generator) { return () => Task.spawn(generator).then(null, ok.bind(null, false)).then(finish); } /** * Add a new test tab in the browser and load the given url. * @param {String} url The url to be loaded in the new tab @@ -42,16 +47,53 @@ let addTab = Task.async(function* (url) let isBlank = url == "about:blank"; waitForFocus(def.resolve, content, isBlank); yield def.promise; return tab.linkedBrowser.contentWindow.document; }); +function initDebuggerServer() { + try { + // Sometimes debugger server does not get destroyed correctly by previous + // tests. + DebuggerServer.destroy(); + } catch (ex) { } + DebuggerServer.init(() => true); + DebuggerServer.addBrowserActors(); +} + +/** + * Connect a debugger client. + * @param {DebuggerClient} + * @return {Promise} Resolves to the selected tabActor form when the client is + * connected. + */ +function connectDebuggerClient(client) { + let def = promise.defer(); + client.connect(() => { + client.listTabs(tabs => { + def.resolve(tabs.tabs[tabs.selected]); + }); + }); + return def.promise; +} + +/** + * Close a debugger client's connection. + * @param {DebuggerClient} + * @return {Promise} Resolves when the connection is closed. + */ +function closeDebuggerClient(client) { + let def = promise.defer(); + client.close(def.resolve); + return def.promise; +} + /** * Wait for eventName on target. * @param {Object} target An observable object that either supports on/off or * addEventListener/removeEventListener * @param {String} eventName * @param {Boolean} useCapture Optional, for addEventListener/removeEventListener * @return A promise that resolves when the event has been handled */
new file mode 100644 --- /dev/null +++ b/toolkit/devtools/server/tests/browser/timeline-iframe-child.html @@ -0,0 +1,19 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Timeline iframe test - child frame</title> +</head> +<body> + <h1>Child frame</h1> + <script> + var h1 = document.querySelector("h1"); + setInterval(function() { + h1.style.backgroundColor = "rgb(" + ((Math.random()*255)|0) + "," + + ((Math.random()*255)|0) + "," + + ((Math.random()*255)|0) +")"; + h1.style.width = ((Math.random()*500)|0) + "px"; + }, 300); + </script> +</body> +</html>
new file mode 100644 --- /dev/null +++ b/toolkit/devtools/server/tests/browser/timeline-iframe-parent.html @@ -0,0 +1,11 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Timeline iframe test - parent frame</title> +</head> +<body> + <h1>Parent frame</h1> + <iframe src="timeline-iframe-child.html"></iframe> +</body> +</html>
--- a/toolkit/modules/PopupNotifications.jsm +++ b/toolkit/modules/PopupNotifications.jsm @@ -546,16 +546,17 @@ PopupNotifications.prototype = { gNotificationParents.set(popupnotification, popupnotification.parentNode); else popupnotification = doc.createElementNS(XUL_NS, "popupnotification"); popupnotification.setAttribute("label", n.message); popupnotification.setAttribute("id", popupnotificationID); popupnotification.setAttribute("popupid", n.id); popupnotification.setAttribute("closebuttoncommand", "PopupNotifications._dismiss();"); + popupnotification.setAttribute("noautofocus", "true"); if (n.mainAction) { popupnotification.setAttribute("buttonlabel", n.mainAction.label); popupnotification.setAttribute("buttonaccesskey", n.mainAction.accessKey); popupnotification.setAttribute("buttoncommand", "PopupNotifications._onButtonCommand(event);"); popupnotification.setAttribute("menucommand", "PopupNotifications._onMenuCommand(event);"); popupnotification.setAttribute("closeitemcommand", "PopupNotifications._dismiss();event.stopPropagation();"); } else { popupnotification.removeAttribute("buttonlabel");
--- a/tools/profiler/shared-libraries-linux.cc +++ b/tools/profiler/shared-libraries-linux.cc @@ -10,16 +10,44 @@ #include <stdio.h> #include <string.h> #include <limits.h> #include <unistd.h> #include <fstream> #include "platform.h" #include "shared-libraries.h" +#include "common/linux/file_id.h" +#include <algorithm> + +#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) + +// Get the breakpad Id for the binary file pointed by bin_name +static std::string getId(const char *bin_name) +{ + using namespace google_breakpad; + using namespace std; + + uint8_t identifier[kMDGUIDSize]; + char id_str[37]; // magic number from file_id.h + + FileID file_id(bin_name); + if (file_id.ElfFileIdentifier(identifier)) { + FileID::ConvertIdentifierToString(identifier, id_str, ARRAY_SIZE(id_str)); + // ConvertIdentifierToString converts the identifier to a string with + // some dashes (don't ask me why), but we need it raw, so remove the dashes. + char *id_end = remove(id_str, id_str + strlen(id_str), '-'); + // Also add an extra "0" by the end. google-breakpad does it for + // consistency with PDB files so we need to do too. + return string(id_str, id_end) + '0'; + } + + return ""; +} + #if !defined(MOZ_WIDGET_GONK) // TODO fix me with proper include #include "nsDebug.h" #ifdef ANDROID #include "ElfLoader.h" // dl_phdr_info #else #include <link.h> // dl_phdr_info #endif @@ -51,17 +79,18 @@ int dl_iterate_callback(struct dl_phdr_i } unsigned long start = dl_info->dlpi_addr + dl_info->dlpi_phdr[i].p_vaddr; unsigned long end = start + dl_info->dlpi_phdr[i].p_memsz; if (start < libStart) libStart = start; if (end > libEnd) libEnd = end; } - SharedLibrary shlib(libStart, libEnd, 0, "", dl_info->dlpi_name); + const char *name = dl_info->dlpi_name; + SharedLibrary shlib(libStart, libEnd, 0, getId(name), name); info.AddSharedLibrary(shlib); return 0; } #endif SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf() { @@ -116,17 +145,17 @@ SharedLibraryInfo SharedLibraryInfo::Get #else if (strcmp(perm, "r-xp") != 0) { // Ignore entries that are writable and/or shared. // At least one graphics driver uses short-lived "rwxs" mappings // (see bug 926734 comment 5), so just checking for 'x' isn't enough. continue; } #endif - SharedLibrary shlib(start, end, offset, "", name); + SharedLibrary shlib(start, end, offset, getId(name), name); info.AddSharedLibrary(shlib); if (count > 10000) { LOG("Get maps failed"); break; } count++; } return info;