author | Wes Kocher <wkocher@mozilla.com> |
Thu, 19 Mar 2015 19:30:20 -0700 | |
changeset 234586 | 4d2d97b3ba34d95b0d29ce099f8f5dc0a2ae722d |
parent 234585 | ae2217c25ceee746befcc7a1abeb0acb94bbd089 (current diff) |
parent 234570 | 02ca416c13a5d084f20b10147635bdc6c4f3932a (diff) |
child 234587 | b2e71f32548fa5aebaa8a55ffb00e26ee3f1046d |
child 234605 | cdec6c4e2995b280a7975754f877e83983d2af87 |
child 234649 | 349a36b7e97ef2c6360f3602375a96536c35bf42 |
child 234675 | ceaac3da2eff663f326dbf863029756ac8b93dff |
push id | 28448 |
push user | kwierso@gmail.com |
push date | Fri, 20 Mar 2015 03:54:14 +0000 |
treeherder | mozilla-central@4d2d97b3ba34 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | merge |
milestone | 39.0a1 |
first release with | nightly linux32
4d2d97b3ba34
/
39.0a1
/
20150320030211
/
files
nightly linux64
4d2d97b3ba34
/
39.0a1
/
20150320030211
/
files
nightly mac
4d2d97b3ba34
/
39.0a1
/
20150320030211
/
files
nightly win32
4d2d97b3ba34
/
39.0a1
/
20150320030211
/
files
nightly win64
4d2d97b3ba34
/
39.0a1
/
20150320030211
/
files
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
releases | nightly linux32
39.0a1
/
20150320030211
/
pushlog to previous
nightly linux64
39.0a1
/
20150320030211
/
pushlog to previous
nightly mac
39.0a1
/
20150320030211
/
pushlog to previous
nightly win32
39.0a1
/
20150320030211
/
pushlog to previous
nightly win64
39.0a1
/
20150320030211
/
pushlog to previous
|
testing/docker/tester/hgrc | file | annotate | diff | comparison | revisions |
--- a/b2g/chrome/content/devtools/debugger.js +++ b/b2g/chrome/content/devtools/debugger.js @@ -18,16 +18,21 @@ XPCOMUtils.defineLazyGetter(this, "devto }); XPCOMUtils.defineLazyGetter(this, "B2GTabList", function() { const { B2GTabList } = devtools.require("resource://gre/modules/DebuggerActors.js"); return B2GTabList; }); +// Load the discovery module eagerly, so that it can set a device name at +// startup. This does not cause discovery to start listening for packets, as +// that only happens once DevTools is enabled. +devtools.require("devtools/toolkit/discovery/discovery"); + let RemoteDebugger = { _listening: false, /** * Prompt the user to accept or decline the incoming connection. * * @param session object * The session object will contain at least the following fields:
--- a/b2g/components/DirectoryProvider.js +++ b/b2g/components/DirectoryProvider.js @@ -10,16 +10,17 @@ const Cr = Components.results; Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Services.jsm"); const XRE_OS_UPDATE_APPLY_TO_DIR = "OSUpdApplyToD" const UPDATE_ARCHIVE_DIR = "UpdArchD" const LOCAL_DIR = "/data/local"; const UPDATES_DIR = "updates/0"; const FOTA_DIR = "updates/fota"; +const COREAPPSDIR_PREF = "b2g.coreappsdir" XPCOMUtils.defineLazyServiceGetter(Services, "env", "@mozilla.org/process/environment;1", "nsIEnvironment"); XPCOMUtils.defineLazyServiceGetter(Services, "um", "@mozilla.org/updates/update-manager;1", "nsIUpdateManager"); @@ -92,22 +93,37 @@ DirectoryProvider.prototype = { if (prop == XRE_OS_UPDATE_APPLY_TO_DIR) { // getUpdateDir will set persistent to false since it may toggle between // /data/local/ and /mnt/sdcard based on free space and/or availability // of the sdcard. // before apply, check if free space is 1.1 times of update.mar return this.getUpdateDir(persistent, FOTA_DIR, 1.1); } #else - // In desktop builds, coreAppsDir is the same as the profile directory. - // We just need to get the path from the parent, and it is then used to - // build jar:remoteopenfile:// uris. + // In desktop builds, coreAppsDir is the same as the profile + // directory unless otherwise specified. We just need to get the + // path from the parent, and it is then used to build + // jar:remoteopenfile:// uris. if (prop == "coreAppsDir") { - let appsDir = Services.dirsvc.get("ProfD", Ci.nsIFile); - appsDir.append("webapps"); + let coreAppsDirPref; + try { + coreAppsDirPref = Services.prefs.getCharPref(COREAPPSDIR_PREF); + } catch (e) { + // coreAppsDirPref may not exist if we're on an older version + // of gaia, so just fail silently. + } + let appsDir; + // If pref doesn't exist or isn't set, default to old value + if (!coreAppsDirPref || coreAppsDirPref == "") { + appsDir = Services.dirsvc.get("ProfD", Ci.nsIFile); + appsDir.append("webapps"); + } else { + appsDir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile) + appsDir.initWithPath(coreAppsDirPref); + } persistent.value = true; return appsDir; } else if (prop == "ProfD") { let inParent = Cc["@mozilla.org/xre/app-info;1"] .getService(Ci.nsIXULRuntime) .processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT; if (inParent) { // Just bail out to use the default from toolkit.
--- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -10,25 +10,25 @@ <!--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="ef937d1aca7c4cf89ecb5cc43ae8c21c2000a9db"> <copyfile dest="Makefile" src="core/root.mk"/> </project> - <project name="gaia" path="gaia" remote="mozillaorg" revision="c39e15f631de80c69467fda0d4ea0bcda9e194ca"/> + <project name="gaia" path="gaia" remote="mozillaorg" revision="8837f94418d69a0b06c1f4843b0779e2bb72165a"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="86cd7486d8e50eaac8ef6fe2f51f09d25194577b"/> <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/> <project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/> <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/> <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/> - <project name="apitrace" path="external/apitrace" remote="apitrace" revision="40f5ce12859076b63307480ff2f0bbdf42bbf258"/> + <project name="apitrace" path="external/apitrace" remote="apitrace" revision="acca7d20b79978cff975e755e5e0bac9f731a6f7"/> <!-- Stock Android things --> <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/> <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/> <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="8b880805d454664b3eed11d0f053cdeafa1ff06e"/> <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="a1e239a0bb5cd1d69680bf1075883aa9a7bf2429"/> <project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="c7931763d41be602407ed9d71e2c0292c6597e00"/> <project groups="linux,x86" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="83760d213fb3bec7b4117d266fcfbf6fe2ba14ab"/> <project name="device/common" path="device/common" revision="6a2995683de147791e516aae2ccb31fdfbe2ad30"/> @@ -133,12 +133,12 @@ <project name="platform/frameworks/av" path="frameworks/av" revision="fd359e3a74a658d9eaab1c683440ba5412535777"/> <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="df636d2c31ad4434a7de2565359ad982b3767118"/> <project name="platform/system/core" path="system/core" revision="a626f6c0ef9e88586569331bd7387b569eaa5ed2"/> <project name="u-boot" path="u-boot" revision="f1502910977ac88f43da7bf9277c3523ad4b0b2f"/> <project name="vendor/sprd/gps" path="vendor/sprd/gps" revision="4c59900937dc2e978b7b14b7f1ea617e3d5d550e"/> - <project name="vendor/sprd/open-source" path="vendor/sprd/open-source" revision="1344e9e5b9d0b6c8f7909731f9d14fabeb1bdc8f"/> + <project name="vendor/sprd/open-source" path="vendor/sprd/open-source" revision="8a81f598126f4153b80c1a2425343174b6cffd79"/> <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="173b3104bfcbd23fc9dccd4b0035fc49aae3d444"> <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="c39e15f631de80c69467fda0d4ea0bcda9e194ca"/> + <project name="gaia.git" path="gaia" remote="mozillaorg" revision="8837f94418d69a0b06c1f4843b0779e2bb72165a"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="86cd7486d8e50eaac8ef6fe2f51f09d25194577b"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/> <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="93f9ba577f68d772093987c2f1c0a4ae293e1802"/> <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="527d1c939ee57deb7192166e56e2a3fffa8cb087"/> <project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/> <project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/> <!-- 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,20 +12,20 @@ <!--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="4efd19d199ae52656604f794c5a77518400220fd"> <copyfile dest="Makefile" src="core/root.mk"/> </project> <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> - <project name="gaia" path="gaia" remote="mozillaorg" revision="c39e15f631de80c69467fda0d4ea0bcda9e194ca"/> + <project name="gaia" path="gaia" remote="mozillaorg" revision="8837f94418d69a0b06c1f4843b0779e2bb72165a"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="86cd7486d8e50eaac8ef6fe2f51f09d25194577b"/> <project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/> - <project name="apitrace" path="external/apitrace" remote="apitrace" revision="40f5ce12859076b63307480ff2f0bbdf42bbf258"/> + <project name="apitrace" path="external/apitrace" remote="apitrace" revision="acca7d20b79978cff975e755e5e0bac9f731a6f7"/> <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"/> <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="9025e50b9d29b3cabbbb21e1dd94d0d13121a17e"/> <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="b89fda71fcd0fa0cf969310e75be3ea33e048b44"/> <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="2e7d5348f35575870b3c7e567a9a9f6d66f8d6c5"/>
--- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -10,25 +10,25 @@ <!--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="ef937d1aca7c4cf89ecb5cc43ae8c21c2000a9db"> <copyfile dest="Makefile" src="core/root.mk"/> </project> - <project name="gaia" path="gaia" remote="mozillaorg" revision="c39e15f631de80c69467fda0d4ea0bcda9e194ca"/> + <project name="gaia" path="gaia" remote="mozillaorg" revision="8837f94418d69a0b06c1f4843b0779e2bb72165a"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="86cd7486d8e50eaac8ef6fe2f51f09d25194577b"/> <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/> <project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/> <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/> <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/> - <project name="apitrace" path="external/apitrace" remote="apitrace" revision="40f5ce12859076b63307480ff2f0bbdf42bbf258"/> + <project name="apitrace" path="external/apitrace" remote="apitrace" revision="acca7d20b79978cff975e755e5e0bac9f731a6f7"/> <!-- Stock Android things --> <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="f92a936f2aa97526d4593386754bdbf02db07a12"/> <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="6e47ff2790f5656b5b074407829ceecf3e6188c4"/> <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="1950e4760fa14688b83cdbb5acaa1af9f82ef434"/> <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="ac6eb97a37035c09fb5ede0852f0881e9aadf9ad"/> <project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="737f591c5f95477148d26602c7be56cbea0cdeb9"/> <project groups="linux,x86" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="51da9b1981be481b92a59a826d4d78dc73d0989a"/> <project name="device/common" path="device/common" revision="798a3664597e6041985feab9aef42e98d458bc3d"/>
--- a/b2g/config/emulator-l/sources.xml +++ b/b2g/config/emulator-l/sources.xml @@ -10,25 +10,25 @@ <!--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="52775e03a2d8532429dff579cb2cd56718e488c3"> <copyfile dest="Makefile" src="core/root.mk"/> </project> - <project name="gaia" path="gaia" remote="mozillaorg" revision="c39e15f631de80c69467fda0d4ea0bcda9e194ca"/> + <project name="gaia" path="gaia" remote="mozillaorg" revision="8837f94418d69a0b06c1f4843b0779e2bb72165a"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="86cd7486d8e50eaac8ef6fe2f51f09d25194577b"/> <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/> <project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/> <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/> <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/> - <project name="apitrace" path="external/apitrace" remote="apitrace" revision="40f5ce12859076b63307480ff2f0bbdf42bbf258"/> + <project name="apitrace" path="external/apitrace" remote="apitrace" revision="acca7d20b79978cff975e755e5e0bac9f731a6f7"/> <!-- Stock Android things --> <project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="50d1ca4ab8add54523b7bc692860d57e8ee4c0d1"/> <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" revision="fb3845864573857677f9b500040a8f011eaf5078"/> <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.8" revision="354496e8eddd28c743d8e02c02eeab02958367e6"/> <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8" revision="b37c91354272b7413a0dc058b7445e677921d39e"/> <project groups="pdk,linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.6" revision="a227c92e0170bcf2296a63386956946b0dd78ca7"/> <project groups="pdk,linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8" revision="884626610186b6dbea52cec5194b1c4bcfe1cb98"/> <project groups="pdk,linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.8" path="prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.8" revision="29f9b82faa1af9730f52e933dca848546cbea84c"/>
--- 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="173b3104bfcbd23fc9dccd4b0035fc49aae3d444"> <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="c39e15f631de80c69467fda0d4ea0bcda9e194ca"/> + <project name="gaia.git" path="gaia" remote="mozillaorg" revision="8837f94418d69a0b06c1f4843b0779e2bb72165a"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="86cd7486d8e50eaac8ef6fe2f51f09d25194577b"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/> <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="93f9ba577f68d772093987c2f1c0a4ae293e1802"/> <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="527d1c939ee57deb7192166e56e2a3fffa8cb087"/> <project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/> <project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/> <!-- 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,25 +10,25 @@ <!--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="ef937d1aca7c4cf89ecb5cc43ae8c21c2000a9db"> <copyfile dest="Makefile" src="core/root.mk"/> </project> - <project name="gaia" path="gaia" remote="mozillaorg" revision="c39e15f631de80c69467fda0d4ea0bcda9e194ca"/> + <project name="gaia" path="gaia" remote="mozillaorg" revision="8837f94418d69a0b06c1f4843b0779e2bb72165a"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="86cd7486d8e50eaac8ef6fe2f51f09d25194577b"/> <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/> <project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/> <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/> <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/> - <project name="apitrace" path="external/apitrace" remote="apitrace" revision="40f5ce12859076b63307480ff2f0bbdf42bbf258"/> + <project name="apitrace" path="external/apitrace" remote="apitrace" revision="acca7d20b79978cff975e755e5e0bac9f731a6f7"/> <!-- Stock Android things --> <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/> <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/> <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="8b880805d454664b3eed11d0f053cdeafa1ff06e"/> <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="a1e239a0bb5cd1d69680bf1075883aa9a7bf2429"/> <project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="c7931763d41be602407ed9d71e2c0292c6597e00"/> <project groups="linux,x86" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="a32003194f707f66a2d8cdb913ed1869f1926c5d"/> <project name="device/common" path="device/common" revision="96d4d2006c4fcb2f19a3fa47ab10cb409faa017b"/>
--- a/b2g/config/flame/sources.xml +++ b/b2g/config/flame/sources.xml @@ -12,20 +12,20 @@ <!--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="4efd19d199ae52656604f794c5a77518400220fd"> <copyfile dest="Makefile" src="core/root.mk"/> </project> <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> - <project name="gaia" path="gaia" remote="mozillaorg" revision="c39e15f631de80c69467fda0d4ea0bcda9e194ca"/> + <project name="gaia" path="gaia" remote="mozillaorg" revision="8837f94418d69a0b06c1f4843b0779e2bb72165a"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="86cd7486d8e50eaac8ef6fe2f51f09d25194577b"/> <project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/> - <project name="apitrace" path="external/apitrace" remote="apitrace" revision="40f5ce12859076b63307480ff2f0bbdf42bbf258"/> + <project name="apitrace" path="external/apitrace" remote="apitrace" revision="acca7d20b79978cff975e755e5e0bac9f731a6f7"/> <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"/> <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/> <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/> <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="8b880805d454664b3eed11d0f053cdeafa1ff06e"/>
--- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,9 +1,9 @@ { "git": { - "git_revision": "c39e15f631de80c69467fda0d4ea0bcda9e194ca", + "git_revision": "8837f94418d69a0b06c1f4843b0779e2bb72165a", "remote": "https://git.mozilla.org/releases/gaia.git", "branch": "" }, - "revision": "a7732a117f9499b15cc27c022a11cd75ef71f477", + "revision": "e034a24fa2dcff4623dce2d91f7828d582abf50d", "repo_path": "integration/gaia-central" }
--- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -12,20 +12,20 @@ <!--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="4efd19d199ae52656604f794c5a77518400220fd"> <copyfile dest="Makefile" src="core/root.mk"/> </project> <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> - <project name="gaia" path="gaia" remote="mozillaorg" revision="c39e15f631de80c69467fda0d4ea0bcda9e194ca"/> + <project name="gaia" path="gaia" remote="mozillaorg" revision="8837f94418d69a0b06c1f4843b0779e2bb72165a"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="86cd7486d8e50eaac8ef6fe2f51f09d25194577b"/> <project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/> - <project name="apitrace" path="external/apitrace" remote="apitrace" revision="40f5ce12859076b63307480ff2f0bbdf42bbf258"/> + <project name="apitrace" path="external/apitrace" remote="apitrace" revision="acca7d20b79978cff975e755e5e0bac9f731a6f7"/> <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"/> <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="9025e50b9d29b3cabbbb21e1dd94d0d13121a17e"/> <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="b89fda71fcd0fa0cf969310e75be3ea33e048b44"/> <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="2e7d5348f35575870b3c7e567a9a9f6d66f8d6c5"/>
--- a/b2g/config/nexus-5-l/sources.xml +++ b/b2g/config/nexus-5-l/sources.xml @@ -10,25 +10,25 @@ <!--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="52775e03a2d8532429dff579cb2cd56718e488c3"> <copyfile dest="Makefile" src="core/root.mk"/> </project> - <project name="gaia" path="gaia" remote="mozillaorg" revision="c39e15f631de80c69467fda0d4ea0bcda9e194ca"/> + <project name="gaia" path="gaia" remote="mozillaorg" revision="8837f94418d69a0b06c1f4843b0779e2bb72165a"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="86cd7486d8e50eaac8ef6fe2f51f09d25194577b"/> <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/> <project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/> <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/> <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/> - <project name="apitrace" path="external/apitrace" remote="apitrace" revision="40f5ce12859076b63307480ff2f0bbdf42bbf258"/> + <project name="apitrace" path="external/apitrace" remote="apitrace" revision="acca7d20b79978cff975e755e5e0bac9f731a6f7"/> <!-- Stock Android things --> <project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="50d1ca4ab8add54523b7bc692860d57e8ee4c0d1"/> <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" revision="fb3845864573857677f9b500040a8f011eaf5078"/> <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.8" revision="354496e8eddd28c743d8e02c02eeab02958367e6"/> <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8" revision="b37c91354272b7413a0dc058b7445e677921d39e"/> <project groups="pdk,linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.6" revision="a227c92e0170bcf2296a63386956946b0dd78ca7"/> <project groups="pdk,linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8" revision="884626610186b6dbea52cec5194b1c4bcfe1cb98"/> <project groups="pdk,linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.8" path="prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.8" revision="29f9b82faa1af9730f52e933dca848546cbea84c"/> @@ -137,17 +137,16 @@ <project name="platform_frameworks_av" path="frameworks/av" remote="b2g" revision="ea531874885eed7f68802048218ed86dde927f58"/> <project name="platform_frameworks_base" path="frameworks/base" remote="b2g" revision="df7e0cfbbc7e954ed26c73ac17832a5ff035f046"/> <project name="platform_frameworks_wilhelm" path="frameworks/wilhelm" remote="b2g" revision="73f7e7f12c8c5459f7a39e2fa343f083c942864d"/> <project name="platform_system_core" path="system/core" remote="b2g" revision="4df51d9abf6cc9a6ec49b965e621699e0e6dc4fb"/> <default remote="caf" revision="refs/tags/android-5.0.0_r6" sync-j="4"/> <!-- Nexus 5 specific things --> <project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="ba62cc8b78c30d36181b8060a2016cc8da166236"/> <project name="device-hammerhead" path="device/lge/hammerhead" remote="b2g" revision="c37663f828891cf7a49451a04f3f1ce7f7e5c054"/> - <project name="device/qcom/common" path="device/qcom/common" remote="caf" revision="3697e5acf25629b82658334e3f8ee3b6df5becab"/> <project name="device_lge_hammerhead-kernel" path="device/lge/hammerhead-kernel" remote="b2g" revision="1268f640184df5ef759ada669f101a613451673a"/> <project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="0cb8574d338bf9f15b45ace7c08ad6deae9673ee"/> <project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="16abda2258c9aa1ed78f00bb0a9b2b43b4cb919e"/> <project name="platform/hardware/broadcom/libbt" path="hardware/broadcom/libbt" revision="3e856528121ae0af0ca26c97cb563160c7e16d85"/> <project name="platform/hardware/broadcom/wlan" path="hardware/broadcom/wlan" revision="d9e716e14e685f4fc124ae591a1cd0899bc4d7b5"/> <project name="platform/hardware/qcom/audio" path="hardware/qcom/audio" revision="505aa92674337b76ce7d038800f2a6d7dc340ac9"/> <project name="hardware_qcom_display" path="hardware/qcom/display" remote="b2g" revision="c43952000d57f08b93a0e4fb77052871ce587976"/> <project name="platform/hardware/qcom/keymaster" path="hardware/qcom/keymaster" revision="028649652cd8f8f18cfb47d34bd78c435eb030ca"/>
--- a/browser/base/content/browser-loop.js +++ b/browser/base/content/browser-loop.js @@ -364,17 +364,17 @@ XPCOMUtils.defineLazyModuleGetter(this, this._tabChangeListeners = new Set(); gBrowser.addEventListener("select", this); } this._tabChangeListeners.add(listener); this._maybeShowBrowserSharingInfoBar(); // Get the first window Id for the listener. - listener(null, gBrowser.selectedTab.linkedBrowser.outerWindowID); + listener(null, gBrowser.selectedBrowser.outerWindowID); }, /** * Removes a listener from browser sharing. * * @param {Function} listener The listener to remove from the list. */ removeBrowserSharingListener: function(listener) { @@ -458,17 +458,17 @@ XPCOMUtils.defineLazyModuleGetter(this, /** * Hides the infobar, permanantly if requested. * * @param {Boolean} permanently Flag that determines if the infobar will never * been shown again. Defaults to `false`. * @return {Boolean} |true| if the infobar was hidden here. */ _hideBrowserSharingInfoBar: function(permanently = false, browser) { - browser = browser || gBrowser.selectedTab.linkedBrowser; + browser = browser || gBrowser.selectedBrowser; let box = gBrowser.getNotificationBox(browser); let notification = box.getNotificationWithValue(kBrowserSharingNotificationId); let removed = false; if (notification) { box.removeNotification(notification); removed = true; } @@ -492,17 +492,17 @@ XPCOMUtils.defineLazyModuleGetter(this, // Hide the infobar from the previous tab. if (event.fromTab) { wasVisible = this._hideBrowserSharingInfoBar(false, event.fromTab.linkedBrowser); } // We've changed the tab, so get the new window id. for (let listener of this._tabChangeListeners) { try { - listener(null, gBrowser.selectedTab.linkedBrowser.outerWindowID); + listener(null, gBrowser.selectedBrowser.outerWindowID); } catch (ex) { Cu.reportError("Tab switch caused an error: " + ex.message); } }; if (wasVisible) { // If the infobar was visible before, we should show it again after the // switch.
--- a/browser/base/content/content.js +++ b/browser/base/content/content.js @@ -480,17 +480,17 @@ let AboutHomeListener = { AboutHomeListener.init(this); let AboutReaderListener = { _articlePromise: null, init: function() { addEventListener("AboutReaderContentLoaded", this, false, true); - addEventListener("pageshow", this, false); + addEventListener("DOMContentLoaded", this, false); addEventListener("pagehide", this, false); addMessageListener("Reader:ParseDocument", this); }, receiveMessage: function(message) { switch (message.name) { case "Reader:ParseDocument": this._articlePromise = ReaderMode.parseDocument(content.document).catch(Cu.reportError); @@ -520,17 +520,17 @@ let AboutReaderListener = { new AboutReader(global, content, this._articlePromise); } break; case "pagehide": sendAsyncMessage("Reader:UpdateReaderButton", { isArticle: false }); break; - case "pageshow": + case "DOMContentLoaded": if (!ReaderMode.isEnabledForParseOnLoad || this.isAboutReader) { return; } let isArticle = ReaderMode.isProbablyReaderable(content.document); sendAsyncMessage("Reader:UpdateReaderButton", { isArticle: isArticle }); } }
--- a/browser/base/content/test/general/browser_autocomplete_enter_race.js +++ b/browser/base/content/test/general/browser_autocomplete_enter_race.js @@ -17,12 +17,12 @@ add_task(function*() { yield new Promise(resolve => waitForFocus(resolve, window)); yield promiseAutocompleteResultPopup("keyword bear"); gURLBar.focus(); EventUtils.synthesizeKey("d", {}); EventUtils.synthesizeKey("VK_RETURN", {}); yield promiseTabLoadEvent(gBrowser.selectedTab); - is(gBrowser.selectedTab.linkedBrowser.currentURI.spec, + is(gBrowser.selectedBrowser.currentURI.spec, "http://example.com/?q=beard", "Latest typed characters should have been used"); });
--- a/browser/components/loop/MozLoopAPI.jsm +++ b/browser/components/loop/MozLoopAPI.jsm @@ -278,17 +278,17 @@ function injectLoopAPI(targetWindow) { * * @param {Function} listener The listener to handle the windowId changes. */ addBrowserSharingListener: { enumerable: true, writable: true, value: function(listener) { let win = Services.wm.getMostRecentWindow("navigator:browser"); - let browser = win && win.gBrowser.selectedTab.linkedBrowser; + let browser = win && win.gBrowser.selectedBrowser; if (!win || !browser) { // This may happen when an undocked conversation window is the only // window left. let err = new Error("No tabs available to share."); MozLoopService.log.error(err); listener(cloneValueInto(err, targetWindow)); return; }
--- a/browser/components/loop/test/mochitest/browser_mozLoop_sharingListeners.js +++ b/browser/components/loop/test/mochitest/browser_mozLoop_sharingListeners.js @@ -137,17 +137,17 @@ add_task(function* test_infoBar() { yield promiseWindowIdReceivedNewTab(); Assert.strictEqual(gBrowser.selectedTab, createdTabs[1], "The second tab created should be selected now"); // Add one sharing listener, which should show the infobar. yield promiseWindowIdReceivedOnAdd(handlers[0]); let getInfoBar = function() { - let box = gBrowser.getNotificationBox(gBrowser.selectedTab.linkedBrowser); + let box = gBrowser.getNotificationBox(gBrowser.selectedBrowser); return box.getNotificationWithValue(kBrowserSharingNotificationId); }; let testBarProps = function() { let bar = getInfoBar(); // Start with some basic assertions for the bar. Assert.ok(bar, "The notification bar should be visible");
--- a/browser/components/preferences/in-content/content.js +++ b/browser/components/preferences/in-content/content.js @@ -21,17 +21,17 @@ var gContentPane = { // Show translation preferences if we may: const prefName = "browser.translation.ui.show"; if (Services.prefs.getBoolPref(prefName)) { let row = document.getElementById("translationBox"); row.removeAttribute("hidden"); } - setEventListener("font.language.group", "change", + setEventListener("font.language.group", "blur", gContentPane._rebuildFonts); setEventListener("popupPolicyButton", "command", gContentPane.showPopupExceptions); setEventListener("advancedFonts", "command", gContentPane.configureFonts); setEventListener("colors", "command", gContentPane.configureColors); setEventListener("chooseLanguage", "command",
--- a/browser/components/sessionstore/ContentRestore.jsm +++ b/browser/components/sessionstore/ContentRestore.jsm @@ -275,93 +275,35 @@ ContentRestoreInternal.prototype = { this.resetRestore(); finishCallback(); } }); }, /** - * Accumulates a list of frames that need to be restored for the given browser - * element. A frame is only restored if its current URL matches the one saved - * in the session data. Each frame to be restored is returned along with its - * associated session data. - * - * @param browser the browser being restored - * @return an array of [frame, data] pairs - */ - getFramesToRestore: function (content, data) { - function hasExpectedURL(aDocument, aURL) { - return !aURL || aURL.replace(/#.*/, "") == aDocument.location.href.replace(/#.*/, ""); - } - - let frameList = []; - - function enumerateFrame(content, data) { - // Skip the frame if the user has navigated away before loading finished. - if (!hasExpectedURL(content.document, data.url)) { - return; - } - - frameList.push([content, data]); - - for (let i = 0; i < content.frames.length; i++) { - if (data.children && data.children[i]) { - enumerateFrame(content.frames[i], data.children[i]); - } - } - } - - enumerateFrame(content, data); - - return frameList; - }, - - /** * Finish restoring the tab by filling in form data and setting the scroll * position. The restore is complete when this function exits. It should be * called when the "load" event fires for the restoring tab. */ restoreDocument: function () { this._epoch = 0; if (!this._restoringDocument) { return; } let {entry, pageStyle, formdata, scrollPositions} = this._restoringDocument; this._restoringDocument = null; - let window = this.docShell.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindow); - let frameList = this.getFramesToRestore(window, entry); + let window = this.docShell.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDOMWindow); - // Support the old pageStyle format. - if (typeof(pageStyle) === "string") { - PageStyle.restore(this.docShell, frameList, pageStyle); - } else { - PageStyle.restoreTree(this.docShell, pageStyle); - } - + PageStyle.restoreTree(this.docShell, pageStyle); FormData.restoreTree(window, formdata); ScrollPosition.restoreTree(window, scrollPositions); - - // We need to support the old form and scroll data for a while at least. - for (let [frame, data] of frameList) { - if (data.hasOwnProperty("formdata") || data.hasOwnProperty("innerHTML")) { - let formdata = data.formdata || {}; - formdata.url = data.url; - - if (data.hasOwnProperty("innerHTML")) { - formdata.innerHTML = data.innerHTML; - } - - FormData.restore(frame, formdata); - } - - ScrollPosition.restore(frame, data.scroll || ""); - } }, /** * Cancel an ongoing restore. This function can be called any time between * restoreHistory and restoreDocument. * * This function is called externally (if a restore is canceled) and * internally (when the loads for a restore have finished). In the latter
--- a/browser/components/sessionstore/PageStyle.jsm +++ b/browser/components/sessionstore/PageStyle.jsm @@ -11,20 +11,16 @@ const Ci = Components.interfaces; /** * The external API exported by this module. */ this.PageStyle = Object.freeze({ collect: function (docShell, frameTree) { return PageStyleInternal.collect(docShell, frameTree); }, - restore: function (docShell, frameList, pageStyle) { - PageStyleInternal.restore(docShell, frameList, pageStyle); - }, - restoreTree: function (docShell, data) { PageStyleInternal.restoreTree(docShell, data); } }); // Signifies that author style level is disabled for the page. const NO_STYLE = "_nostyle"; @@ -51,39 +47,16 @@ let PageStyleInternal = { result = result || {}; result.disabled = true; } return result && Object.keys(result).length ? result : null; }, /** - * Restore the selected style sheet of all the frames in frameList - * to match |pageStyle|. - * @param docShell the root docshell of all the frames - * @param frameList a list of [frame, data] pairs, where frame is a - * DOM window and data is the session restore data associated with - * it. - * @param pageStyle the title of the style sheet to apply - */ - restore: function (docShell, frameList, pageStyle) { - let disabled = pageStyle == NO_STYLE; - - let markupDocumentViewer = - docShell.contentViewer; - markupDocumentViewer.authorStyleDisabled = disabled; - - for (let [frame, data] of frameList) { - Array.forEach(frame.document.styleSheets, function(aSS) { - aSS.disabled = aSS.title && aSS.title != pageStyle; - }); - } - }, - - /** * Restores pageStyle data for the current frame hierarchy starting at the * |docShell's| current DOMWindow using the given pageStyle |data|. * * Warning: If the current frame hierarchy doesn't match that of the given * |data| object we will silently discard data for unreachable frames. We may * as well assign page styles to the wrong frames if some were reordered or * removed. *
--- a/browser/components/sessionstore/test/browser.ini +++ b/browser/components/sessionstore/test/browser.ini @@ -130,19 +130,16 @@ skip-if = true [browser_466937.js] [browser_467409-backslashplosion.js] [browser_477657.js] [browser_480893.js] [browser_485482.js] [browser_485563.js] [browser_490040.js] [browser_491168.js] -# Disabled for too many intermittent failures. -# Can be re-enabled once bug 930202 lands. -skip-if = true [browser_491577.js] [browser_495495.js] [browser_500328.js] [browser_514751.js] [browser_522375.js] [browser_522545.js] [browser_524745.js] [browser_528776.js]
--- a/browser/components/sessionstore/test/browser_467409-backslashplosion.js +++ b/browser/components/sessionstore/test/browser_467409-backslashplosion.js @@ -14,24 +14,24 @@ // 2b. Check that formdata doesn't require JSON.parse // // 3. [backwards compat] Use a stringified state as formdata when opening about:sessionrestore // 3a. Make sure there are nodes in the tree on about:sessionrestore (skipped, checking formdata is sufficient) // 3b. Check that there are no backslashes in the formdata // 3c. Check that formdata doesn't require JSON.parse const CRASH_STATE = {windows: [{tabs: [{entries: [{url: "about:mozilla" }]}]}]}; -const STATE = {entries: [createEntry(CRASH_STATE)]}; -const STATE2 = {entries: [createEntry({windows: [{tabs: [STATE]}]})]}; -const STATE3 = {entries: [createEntry(JSON.stringify(CRASH_STATE))]}; +const STATE = createEntries(CRASH_STATE); +const STATE2 = createEntries({windows: [{tabs: [STATE]}]}); +const STATE3 = createEntries(JSON.stringify(CRASH_STATE)); -function createEntry(sessionData) { +function createEntries(sessionData) { return { - url: "about:sessionrestore", - formdata: {id: {sessionData: sessionData}} + entries: [{url: "about:sessionrestore"}], + formdata: {id: {sessionData: sessionData}, url: "about:sessionrestore"} }; } add_task(function test_nested_about_sessionrestore() { // Prepare a blank tab. let tab = gBrowser.addTab("about:blank"); let browser = tab.linkedBrowser; yield promiseBrowserLoaded(browser);
--- a/browser/components/sessionstore/test/browser_491168.js +++ b/browser/components/sessionstore/test/browser_491168.js @@ -1,41 +1,42 @@ -/* 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/. */ - -function test() { - /** Test for Bug 491168 **/ +"use strict"; - waitForExplicitFinish(); +const REFERRER1 = "http://example.org/?" + Date.now(); +const REFERRER2 = "http://example.org/?" + Math.random(); - const REFERRER1 = "http://example.org/?" + Date.now(); - const REFERRER2 = "http://example.org/?" + Math.random(); - - let tab = gBrowser.addTab(); - gBrowser.selectedTab = tab; - +add_task(function* () { + // Add a new tab. + let tab = gBrowser.selectedTab = gBrowser.addTab("about:blank"); let browser = tab.linkedBrowser; - promiseBrowserLoaded(browser).then(() => { - let tabState = JSON.parse(ss.getTabState(tab)); - is(tabState.entries[0].referrer, REFERRER1, - "Referrer retrieved via getTabState matches referrer set via loadURI."); - - tabState.entries[0].referrer = REFERRER2; - - promiseTabState(tab, tabState).then(() => { - is(window.content.document.referrer, REFERRER2, "document.referrer matches referrer set via setTabState."); + yield promiseBrowserLoaded(browser); - gBrowser.removeTab(tab); - - let newTab = ss.undoCloseTab(window, 0); - promiseTabRestored(newTab).then(() => { - is(window.content.document.referrer, REFERRER2, "document.referrer is still correct after closing and reopening the tab."); - gBrowser.removeTab(newTab); - - finish(); - }); - }); - }); - + // Load a new URI with a specific referrer. let referrerURI = Services.io.newURI(REFERRER1, null, null); browser.loadURI("http://example.org", referrerURI, null); + yield promiseBrowserLoaded(browser); + + TabState.flush(browser); + let tabState = JSON.parse(ss.getTabState(tab)); + is(tabState.entries[0].referrer, REFERRER1, + "Referrer retrieved via getTabState matches referrer set via loadURI."); + + tabState.entries[0].referrer = REFERRER2; + yield promiseTabState(tab, tabState); + + is((yield promiseDocumentReferrer()), REFERRER2, + "document.referrer matches referrer set via setTabState."); + gBrowser.removeCurrentTab(); + + // Restore the closed tab. + tab = ss.undoCloseTab(window, 0); + yield promiseTabRestored(tab); + + is((yield promiseDocumentReferrer()), REFERRER2, + "document.referrer is still correct after closing and reopening the tab."); + gBrowser.removeCurrentTab(); +}); + +function promiseDocumentReferrer() { + return ContentTask.spawn(gBrowser.selectedBrowser, null, function* () { + return content.document.referrer; + }); }
--- a/browser/components/sessionstore/test/browser_590563.js +++ b/browser/components/sessionstore/test/browser_590563.js @@ -1,25 +1,23 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ function test() { - let oldState = { + let sessionData = { windows: [{ tabs: [ { entries: [{ url: "about:mozilla" }], hidden: true }, { entries: [{ url: "about:blank" }], hidden: false } ] }] }; - let pageData = { - url: "about:sessionrestore", - formdata: { id: { "sessionData": oldState } } - }; - let state = { windows: [{ tabs: [{ entries: [pageData] }] }] }; + let url = "about:sessionrestore"; + let formdata = {id: {sessionData}, url}; + let state = { windows: [{ tabs: [{ entries: [{url}], formdata }] }] }; waitForExplicitFinish(); newWindowWithState(state, function (win) { registerCleanupFunction(function () win.close()); is(gBrowser.tabs.length, 1, "The total number of tabs should be 1"); is(gBrowser.visibleTabs.length, 1, "The total number of visible tabs should be 1");
--- a/browser/components/sessionstore/test/browser_662743.js +++ b/browser/components/sessionstore/test/browser_662743.js @@ -56,17 +56,19 @@ function test() { testTabRestoreData(formData[i], expectedValues[i], callback); } } function testTabRestoreData(aFormData, aExpectedValue, aCallback) { let testURL = getRootDirectory(gTestPath) + "browser_662743_sample.html"; let tab = gBrowser.addTab(testURL); - let tabState = { entries: [{ url: testURL, formdata: aFormData}] }; + + aFormData.url = testURL; + let tabState = { entries: [{ url: testURL, }], formdata: aFormData }; promiseBrowserLoaded(tab.linkedBrowser).then(() => { promiseTabState(tab, tabState).then(() => { let doc = tab.linkedBrowser.contentDocument; let select = doc.getElementById("select_id"); let value = select.options[select.selectedIndex].value; // Flush to make sure we have the latest form data.
--- a/browser/components/sessionstore/test/browser_739805.js +++ b/browser/components/sessionstore/test/browser_739805.js @@ -1,13 +1,14 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ +let url = "data:text/html;charset=utf-8,<input%20id='foo'>"; let tabState = { - entries: [{url: "data:text/html;charset=utf-8,<input%20id='foo'>", formdata: { id: { "foo": "bar" } } }] + entries: [{ url }], formdata: { id: { "foo": "bar" }, url } }; function test() { waitForExplicitFinish(); Services.prefs.setBoolPref("browser.sessionstore.restore_on_demand", true); registerCleanupFunction(function () { if (gBrowser.tabs.length > 1) @@ -19,18 +20,17 @@ function test() { let browser = tab.linkedBrowser; promiseBrowserLoaded(browser).then(() => { isnot(gBrowser.selectedTab, tab, "newly created tab is not selected"); ss.setTabState(tab, JSON.stringify(tabState)); is(browser.__SS_restoreState, TAB_STATE_NEEDS_RESTORE, "tab needs restoring"); - let state = JSON.parse(ss.getTabState(tab)); - let formdata = state.entries[0].formdata; + let {formdata} = JSON.parse(ss.getTabState(tab)); is(formdata && formdata.id["foo"], "bar", "tab state's formdata is valid"); promiseTabRestored(tab).then(() => { let input = browser.contentDocument.getElementById("foo"); is(input.value, "bar", "formdata has been restored correctly"); finish(); });
--- a/browser/components/sessionstore/test/browser_aboutSessionRestore.js +++ b/browser/components/sessionstore/test/browser_aboutSessionRestore.js @@ -2,19 +2,20 @@ http://creativecommons.org/publicdomain/zero/1.0/ */ "use strict"; const CRASH_SHENTRY = {url: "about:mozilla"}; const CRASH_TAB = {entries: [CRASH_SHENTRY]}; const CRASH_STATE = {windows: [{tabs: [CRASH_TAB]}]}; -const TAB_FORMDATA = {id: {sessionData: CRASH_STATE}}; -const TAB_SHENTRY = {url: "about:sessionrestore", formdata: TAB_FORMDATA}; -const TAB_STATE = {entries: [TAB_SHENTRY]}; +const TAB_URL = "about:sessionrestore"; +const TAB_FORMDATA = {url: TAB_URL, id: {sessionData: CRASH_STATE}}; +const TAB_SHENTRY = {url: TAB_URL}; +const TAB_STATE = {entries: [TAB_SHENTRY], formdata: TAB_FORMDATA}; const FRAME_SCRIPT = "data:," + "content.document.getElementById('errorTryAgain').click()"; add_task(function* () { // Prepare a blank tab. let tab = gBrowser.addTab("about:blank"); let browser = tab.linkedBrowser;
--- a/browser/components/sessionstore/test/browser_formdata.js +++ b/browser/components/sessionstore/test/browser_formdata.js @@ -54,64 +54,16 @@ add_task(function test_formdata() { [{state: {formdata}}] = JSON.parse(ss.getClosedTabData(window)); ok(!formdata, "form data has *not* been stored"); // Restore the default privacy level. Services.prefs.clearUserPref("browser.sessionstore.privacy_level"); }); /** - * This test ensures that we maintain backwards compatibility with the form - * data format used pre Fx 29. - */ -add_task(function test_old_format() { - const URL = "data:text/html;charset=utf-8,<input%20id=input>"; - const VALUE = "value-" + Math.random(); - - // Create a tab with an iframe containing an input field. - let tab = gBrowser.addTab(URL); - let browser = tab.linkedBrowser; - yield promiseBrowserLoaded(browser); - - // Check that the form value is restored. - let state = {entries: [{url: URL, formdata: {id: {input: VALUE}}}]}; - yield promiseTabState(tab, state); - is((yield getInputValue(browser, "input")), VALUE, "form data restored"); - - // Cleanup. - gBrowser.removeTab(tab); -}); - -/** - * This test ensures that we maintain backwards compatibility with the form - * data form used pre Fx 29, esp. the .innerHTML property for editable docs. - */ -add_task(function test_old_format_inner_html() { - const URL = "data:text/html;charset=utf-8,<h1>mozilla</h1>" + - "<script>document.designMode='on'</script>"; - const VALUE = "<h1>value-" + Math.random() + "</h1>"; - - // Create a tab with an iframe containing an input field. - let tab = gBrowser.addTab(URL); - let browser = tab.linkedBrowser; - yield promiseBrowserLoaded(browser); - - // Restore the tab state. - let state = {entries: [{url: URL, innerHTML: VALUE}]}; - yield promiseTabState(tab, state); - - // Check that the innerHTML value was restored. - let html = yield getInnerHTML(browser); - is(html, VALUE, "editable document has been restored correctly"); - - // Cleanup. - gBrowser.removeTab(tab); -}); - -/** * This test ensures that a malicious website can't trick us into restoring * form data into a wrong website and that we always check the stored URL * before doing so. */ add_task(function test_url_check() { const URL = "data:text/html;charset=utf-8,<input%20id=input>"; const VALUE = "value-" + Math.random();
--- a/browser/components/sessionstore/test/browser_formdata_format.js +++ b/browser/components/sessionstore/test/browser_formdata_format.js @@ -66,17 +66,19 @@ function test() { testTabRestoreData(formData[i], expectedValues[i], callback); } } function testTabRestoreData(aFormData, aExpectedValue, aCallback) { let URL = ROOT + "browser_formdata_format_sample.html"; let tab = gBrowser.addTab("about:blank"); let browser = tab.linkedBrowser; - let tabState = { entries: [{ url: URL, formdata: aFormData}] }; + + aFormData.url = URL; + let tabState = { entries: [{ url: URL }], formdata: aFormData }; Task.spawn(function () { yield promiseBrowserLoaded(tab.linkedBrowser); yield promiseTabState(tab, tabState); TabState.flush(tab.linkedBrowser); let restoredTabState = JSON.parse(ss.getTabState(tab)); let restoredFormData = restoredTabState.formdata;
--- a/browser/components/sessionstore/test/browser_scrollPositions.js +++ b/browser/components/sessionstore/test/browser_scrollPositions.js @@ -97,39 +97,15 @@ add_task(function test_scroll_nested() { yield sendMessage(browser, "ss-test:setScrollPosition", {x: 0, y: 0, frame: 1}); checkScroll(tab, null, "no scroll stored"); // Cleanup. gBrowser.removeTab(tab); gBrowser.removeTab(tab2); }); -/** - * This test ensures that by moving scroll positions out of tabData.entries[] - * we still support the old scroll data format stored per shistory entry. - */ -add_task(function test_scroll_old_format() { - const TAB_STATE = { entries: [{url: URL, scroll: SCROLL_STR}] }; - - // Add a blank tab. - let tab = gBrowser.addTab("about:blank"); - let browser = tab.linkedBrowser; - yield promiseBrowserLoaded(browser); - - // Apply the tab state with the old format. - yield promiseTabState(tab, TAB_STATE); - - // Check that the scroll positions has been applied. - let scroll = yield sendMessage(browser, "ss-test:getScrollPosition"); - is(JSON.stringify(scroll), JSON.stringify({x: SCROLL_X, y: SCROLL_Y}), - "scroll position has been restored correctly"); - - // Cleanup. - gBrowser.removeTab(tab); -}); - function checkScroll(tab, expected, msg) { let browser = tab.linkedBrowser; TabState.flush(browser); let scroll = JSON.parse(ss.getTabState(tab)).scroll || null; is(JSON.stringify(scroll), JSON.stringify(expected), msg); }
--- a/browser/devtools/responsivedesign/test/browser_responsive_cmd.js +++ b/browser/devtools/responsivedesign/test/browser_responsive_cmd.js @@ -5,17 +5,17 @@ // // Whitelisting this test. // As part of bug 1077403, the leaking uncaught rejection should be fixed. // thisTestLeaksUncaughtRejectionsAndShouldBeFixed("destroy"); function test() { function isOpen() { - return gBrowser.getBrowserContainer(gBrowser.selectedTab.linkedBrowser) + return gBrowser.getBrowserContainer(gBrowser.selectedBrowser) .hasAttribute("responsivemode"); } helpers.addTabWithToolbar("data:text/html;charset=utf-8,hi", function(options) { return helpers.audit(options, [ { setup: "resize toggle", check: {
--- a/browser/devtools/styleinspector/css-parsing-utils.js +++ b/browser/devtools/styleinspector/css-parsing-utils.js @@ -10,24 +10,36 @@ const cssTokenizer = require("devtools/ /** * Returns the string enclosed in quotes */ function quoteString(string) { let hasDoubleQuotes = string.contains('"'); let hasSingleQuotes = string.contains("'"); + let quote = '"'; if (hasDoubleQuotes && !hasSingleQuotes) { - // In this case, no escaping required, just enclose in single-quotes - return "'" + string + "'"; + quote = "'"; } - // In all other cases, enclose in double-quotes, and escape any double-quote - // that may be in the string - return '"' + string.replace(/"/g, '\"') + '"'; + // Quote special characters as specified by the CSS grammar. + // See http://www.w3.org/TR/CSS2/syndata.html#tokenization + // and http://www.w3.org/TR/CSS2/syndata.html#strings + return quote + + string.replace(/[\\"]/g, match => { + switch (match) { + case '\\': + return '\\\\'; + case '"': + if (quote == '"') + return '\\"'; + return match; + } + }) + + quote; } /** * Returns an array of CSS declarations given an string. * For example, parseDeclarations("width: 1px; height: 1px") would return * [{name:"width", value: "1px"}, {name: "height", "value": "1px"}] * * The input string is assumed to only contain declarations so { and } characters
--- a/browser/devtools/styleinspector/test/unit/test_parseDeclarations.js +++ b/browser/devtools/styleinspector/test/unit/test_parseDeclarations.js @@ -150,17 +150,17 @@ const TEST_DATA = [ {input: "color: #333", expected: [{name: "color", value: "#333", priority: ""}]}, {input: "color: #456789", expected: [{name: "color", value: "#456789", priority: ""}]}, {input: "wat: #XYZ", expected: [{name: "wat", value: "#XYZ", priority: ""}]}, // Test string/url quotes escaping {input: "content: \"this is a 'string'\"", expected: [{name: "content", value: "\"this is a 'string'\"", priority: ""}]}, {input: 'content: "this is a \\"string\\""', expected: [{name: "content", value: '\'this is a "string"\'', priority: ""}]}, {input: "content: 'this is a \"string\"'", expected: [{name: "content", value: '\'this is a "string"\'', priority: ""}]}, {input: "content: 'this is a \\'string\\'", expected: [{name: "content", value: '"this is a \'string\'"', priority: ""}]}, - {input: "content: 'this \\' is a \" really strange string'", expected: [{name: "content", value: '"this \' is a \" really strange string"', priority: ""}]}, + {input: "content: 'this \\' is a \" really strange string'", expected: [{name: "content", value: '"this \' is a \\\" really strange string"', priority: ""}]}, { input: "content: \"a not s\\\ o very long title\"", expected: [ {name: "content", value: '"a not s\ o very long title"', priority: ""} ] },
--- a/browser/devtools/styleinspector/test/unit/test_parseSingleValue.js +++ b/browser/devtools/styleinspector/test/unit/test_parseSingleValue.js @@ -42,16 +42,23 @@ const TEST_DATA = [ } }, { input: "\"content!important\"", expected: { value: "\"content!important\"", priority: "" } + }, + { + input: "\"all the \\\"'\\\\ special characters\"", + expected: { + value: "\"all the \\\"'\\\\ special characters\"", + priority: "" + } } ]; function run_test() { for (let test of TEST_DATA) { do_print("Test input value " + test.input); try { let output = parseSingleValue(test.input);
--- a/browser/devtools/webide/modules/runtimes.js +++ b/browser/devtools/webide/modules/runtimes.js @@ -448,16 +448,20 @@ WiFiRuntime.prototype = { type: RuntimeTypes.WIFI, connect: function(connection) { let service = discovery.getRemoteService("devtools", this.deviceName); if (!service) { return promise.reject(new Error("Can't find device: " + this.name)); } connection.advertisement = service; connection.authenticator.sendOOB = this.sendOOB; + // Disable the default connection timeout, since QR scanning can take an + // unknown amount of time. This prevents spurious errors (even after + // eventual success) from being shown. + connection.timeoutDelay = 0; connection.connect(); return promise.resolve(); }, get id() { return this.deviceName; }, get name() { return this.deviceName;
--- a/dom/apps/AppsUtils.jsm +++ b/dom/apps/AppsUtils.jsm @@ -920,16 +920,20 @@ ManifestHelper.prototype = { } return icon; }, fullLaunchPath: function(aStartPoint) { // If no start point is specified, we use the root launch path. // In all error cases, we just return null. if ((aStartPoint || "") === "") { + // W3C start_url takes precedence over mozApps launch_path + if (this._localeProp("start_url")) { + return this._baseURI.resolve(this._localeProp("start_url") || "/"); + } return this._baseURI.resolve(this._localeProp("launch_path") || "/"); } // Search for the l10n entry_points property. let entryPoints = this._localeProp("entry_points"); if (!entryPoints) { return null; }
--- a/dom/apps/Webapps.jsm +++ b/dom/apps/Webapps.jsm @@ -774,17 +774,17 @@ this.DOMApplicationRegistry = { appMigrator.observe(null, "webapps-before-update-merge", null); } catch(e) { debug("Exception running app migration: "); debug(e.name + " " + e.message); debug("Skipping app migration."); } } -#ifdef MOZ_WIDGET_GONK +#ifdef MOZ_B2G yield this.installSystemApps(); #endif // At first run, install preloaded apps and set up their permissions. for (let id in this.webapps) { let isPreinstalled = this.installPreinstalledApp(id); this.removeIfHttpsDuplicate(id); if (!this.webapps[id]) {
new file mode 100644 --- /dev/null +++ b/dom/apps/tests/unit/test_manifestHelper.js @@ -0,0 +1,23 @@ +// Test that W3C start_url takes precedence over mozApps launch_path +function run_test() { + Components.utils.import("resource:///modules/AppsUtils.jsm"); + + let manifest1 = { + launch_path: "other.html" + }; + + let manifest2 = { + start_url: "start.html", + launch_path: "other.html" + }; + + var helper = new ManifestHelper(manifest1, "http://foo.com", + "http://foo.com/manifest.json"); + var path = helper.fullLaunchPath(); + do_check_true(path == "http://foo.com/other.html"); + + helper = new ManifestHelper(manifest2, "http://foo.com", + "http://foo.com/manifest.json"); + path = helper.fullLaunchPath(); + do_check_true(path == "http://foo.com/start.html"); +}
--- a/dom/apps/tests/unit/xpcshell.ini +++ b/dom/apps/tests/unit/xpcshell.ini @@ -1,7 +1,8 @@ [DEFAULT] head = tail = [test_has_widget_criterion.js] [test_inter_app_comm_service.js] [test_manifestSanitizer.js] +[test_manifestHelper.js]
--- a/dom/mobilemessage/tests/marionette/test_getthreads.js +++ b/dom/mobilemessage/tests/marionette/test_getthreads.js @@ -1,407 +1,182 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ -MARIONETTE_TIMEOUT = 40000; - -SpecialPowers.addPermission("sms", true, document); -SpecialPowers.setBoolPref("dom.sms.enabled", true); - -let manager = window.navigator.mozMobileMessage; -ok(manager instanceof MozMobileMessageManager, - "manager is instance of " + manager.constructor); +MARIONETTE_TIMEOUT = 90000; +MARIONETTE_HEAD_JS = 'head.js'; -let pendingEmulatorCmdCount = 0; -function sendSmsToEmulator(from, text, callback) { - ++pendingEmulatorCmdCount; +/** + * Create messages to be tested. + * + * @param aMessages + * An array of + * { 'incoming': [false|true], + * 'address': [Phone Number] + * 'text': [Text Body] }; + * + * @return A deferred promise. + */ +function createMessages(aMessages) { + let promise = Promise.resolve(); + aMessages.forEach((aMessage) => { + promise = promise.then((aMessage.incoming) ? + () => sendTextSmsToEmulatorAndWait(aMessage.address, aMessage.text) : + () => sendSmsWithSuccess(aMessage.address, aMessage.text)); + }); - let cmd = "sms send " + from + " " + text; - runEmulatorCmd(cmd, function(result) { - --pendingEmulatorCmdCount; - - callback(result[0] == "OK"); - }); + return promise; } -let tasks = { - // List of test fuctions. Each of them should call |tasks.next()| when - // completed or |tasks.finish()| to jump to the last one. - _tasks: [], - _nextTaskIndex: 0, - - push: function(func) { - this._tasks.push(func); - }, - - next: function() { - let index = this._nextTaskIndex++; - let task = this._tasks[index]; - try { - task.apply(null, Array.slice(arguments)); - } catch (ex) { - ok(false, "test task[" + index + "] throws: " + ex); - // Run last task as clean up if possible. - if (index != this._tasks.length - 1) { - this.finish(); - } - } - }, - - finish: function() { - this._tasks[this._tasks.length - 1](); - }, - - run: function() { - this.next(); - } -}; - -function getAllMessages(callback, filter, reverse) { - let messages = []; - let request = manager.getMessages(filter, reverse || false); - request.onsuccess = function(event) { - if (!request.done) { - messages.push(request.result); - request.continue(); - return; - } - - window.setTimeout(callback.bind(null, messages), 0); - } -} +function checkThreads(aMessages, aNotMerged) { + return getAllThreads().then((aThreads) => { + let threadCount = aThreads.length; -function deleteAllMessages() { - getAllMessages(function deleteAll(messages) { - let message = messages.shift(); - if (!message) { - ok(true, "all messages deleted"); - tasks.next(); - return; - } - - let request = manager.delete(message.id); - request.onsuccess = deleteAll.bind(null, messages); - request.onerror = function(event) { - ok(false, "failed to delete all messages"); - tasks.finish(); - } - }); -} + if (aNotMerged) { + // Threads are retrieved in reversed order of 'lastTimestamp'. + aThreads.reverse(); + is(threadCount, aMessages.length, "Number of Threads."); + for (let i = 0; i < threadCount; i++) { + let thread = aThreads[i]; + let message = aMessages[i]; + is(thread.unreadCount, message.incoming ? 1 : 0, "Unread Count."); + is(thread.participants.length, 1, "Number of Participants."); + is(thread.participants[0], message.address, "Participants."); + is(thread.body, message.text, "Thread Body."); + } -function sendMessage(to, body) { - manager.onsent = function() { - manager.onsent = null; - tasks.next(); - }; - let request = manager.send(to, body); - request.onerror = tasks.finish.bind(tasks); -} - -function receiveMessage(from, body) { - manager.onreceived = function() { - manager.onreceived = null; - tasks.next(); - }; - sendSmsToEmulator(from, body, function(success) { - if (!success) { - tasks.finish(); - } - }); -} - -function getAllThreads(callback) { - let threads = []; - - let cursor = manager.getThreads(); - ok(cursor instanceof DOMCursor, - "cursor is instanceof " + cursor.constructor); - - cursor.onsuccess = function(event) { - if (!cursor.done) { - threads.push(cursor.result); - cursor.continue(); return; } - window.setTimeout(callback.bind(null, threads), 0); - }; + let lastBody = aMessages[aMessages.length - 1].text; + let unreadCount = 0; + let mergedThread = aThreads[0]; + aMessages.forEach((aMessage) => { + if (aMessage.incoming) { + unreadCount++; + } + }); + is(threadCount, 1, "Number of Threads."); + is(mergedThread.unreadCount, unreadCount, "Unread Count."); + is(mergedThread.participants.length, 1, "Number of Participants."); + is(mergedThread.participants[0], aMessages[0].address, "Participants."); + // Thread is updated according to the device 'timestamp' of the message record + // instead of the one from SMSC, so 'mergedThread.body' is expected to be the + // same to the body for the last saved SMS. + // See https://hg.mozilla.org/mozilla-central/annotate/436686833af0/dom/mobilemessage/gonk/MobileMessageDB.jsm#l2247 + is(mergedThread.body, lastBody, "Thread Body."); + }); } -function checkThread(bodies, lastBody, unreadCount, participants, - thread, callback) { - log("Validating MozMobileMessageThread attributes " + - JSON.stringify([bodies, lastBody, unreadCount, participants])); - - ok(thread, "current thread should be valid."); - - ok(thread.id, "thread id", "thread.id"); - log("Got thread " + thread.id); - - if (lastBody != null) { - is(thread.body, lastBody, "thread.body"); - } - - is(thread.unreadCount, unreadCount, "thread.unreadCount"); - - ok(Array.isArray(thread.participants), "thread.participants is array"); - is(thread.participants.length, participants.length, - "thread.participants.length"); - for (let i = 0; i < participants.length; i++) { - is(thread.participants[i], participants[i], - "thread.participants[" + i + "]"); - } - - // Check whether the thread does contain all the messages it supposed to have. - let filter = { threadId: thread.id }; - getAllMessages(function(messages) { - is(messages.length, bodies.length, "messages.length and bodies.length"); - - for (let message of messages) { - let index = bodies.indexOf(message.body); - ok(index >= 0, "message.body '" + message.body + - "' should be found in bodies array."); - bodies.splice(index, 1); - } - - is(bodies.length, 0, "bodies array length"); - - window.setTimeout(callback, 0); - }, filter, false); +function testGetThreads(aMessages, aNotMerged) { + aNotMerged = !!aNotMerged; + log("aMessages: " + JSON.stringify(aMessages)); + log("aNotMerged: " + aNotMerged); + return createMessages(aMessages) + .then(() => checkThreads(aMessages, aNotMerged)) + .then(() => deleteAllMessages()); } -tasks.push(deleteAllMessages); - -tasks.push(getAllThreads.bind(null, function(threads) { - is(threads.length, 0, "Empty thread list at beginning."); - tasks.next(); -})); - -// Populate MobileMessageDB with messages. -let checkFuncs = []; - -// [Thread 1] -// One message only, body = "thread 1"; -// All sent message, unreadCount = 0; -// One participant only, participants = ["5555211001"]. -tasks.push(sendMessage.bind(null, "5555211001", "thread 1")); -checkFuncs.push(checkThread.bind(null, ["thread 1"], - "thread 1", 0, ["5555211001"])); - -// [Thread 2] -// Two messages, body = "thread 2-2"; -// All sent message, unreadCount = 0; -// One participant with two aliased addresses, participants = ["5555211002"]. -tasks.push(sendMessage.bind(null, "5555211002", "thread 2-1")); -tasks.push(sendMessage.bind(null, "+15555211002", "thread 2-2")); -checkFuncs.push(checkThread.bind(null, ["thread 2-1", "thread 2-2"], - "thread 2-2", 0, ["5555211002"])); - -// [Thread 3] -// Two messages, body = "thread 3-2"; -// All sent message, unreadCount = 0; -// One participant with two aliased addresses, participants = ["+15555211003"]. -tasks.push(sendMessage.bind(null, "+15555211003", "thread 3-1")); -tasks.push(sendMessage.bind(null, "5555211003", "thread 3-2")); -checkFuncs.push(checkThread.bind(null, ["thread 3-1", "thread 3-2"], - "thread 3-2", 0, ["+15555211003"])); - -// [Thread 4] -// One message only, body = "thread 4"; -// All received message, unreadCount = 1; -// One participant only, participants = ["5555211004"]. -tasks.push(receiveMessage.bind(null, "5555211004", "thread 4")); -checkFuncs.push(checkThread.bind(null, ["thread 4"], - "thread 4", 1, ["5555211004"])); - -// [Thread 5] -// -// Thread body should be set to text body of the last message in this -// thread. However due to BUG 840051, we're having SMSC time as message -// timestamp and SMSC time resolution is 1 second. So it's likely that the two -// messages have the same timestamp and we just can't tell which is the later -// one. -// -// All received message, unreadCount = 2; -// One participant with two aliased addresses, participants = ["5555211005"]. -tasks.push(receiveMessage.bind(null, "5555211005", "thread 5-1")); -tasks.push(receiveMessage.bind(null, "+15555211005", "thread 5-2")); -checkFuncs.push(checkThread.bind(null, ["thread 5-1", "thread 5-2"], - null, 2, ["5555211005"])); - -// [Thread 6] -// -// Thread body should be set to text body of the last message in this -// thread. However due to BUG 840051, we're having SMSC time as message -// timestamp and SMSC time resolution is 1 second. So it's likely that the two -// messages have the same timestamp and we just can't tell which is the later -// one. -// -// All received message, unreadCount = 2; -// One participant with two aliased addresses, participants = ["+15555211006"]. -tasks.push(receiveMessage.bind(null, "+15555211006", "thread 6-1")); -tasks.push(receiveMessage.bind(null, "5555211006", "thread 6-2")); -checkFuncs.push(checkThread.bind(null, ["thread 6-1", "thread 6-2"], - null, 2, ["+15555211006"])); - -// [Thread 7] -// -// Thread body should be set to text body of the last message in this -// thread. However due to BUG 840051, there might be time difference between -// SMSC and device time. So the result of comparing the timestamps of sent and -// received message may not follow the order of requests and may result in -// UNEXPECTED-FAIL in following tests. -// -// Two received message, unreadCount = 2; -// One participant with two aliased addresses, participants = ["5555211007"]. -tasks.push(sendMessage.bind(null, "5555211007", "thread 7-1")); -tasks.push(sendMessage.bind(null, "+15555211007", "thread 7-2")); -tasks.push(receiveMessage.bind(null, "5555211007", "thread 7-3")); -tasks.push(receiveMessage.bind(null, "+15555211007", "thread 7-4")); -checkFuncs.push(checkThread.bind(null, ["thread 7-1", "thread 7-2", - "thread 7-3", "thread 7-4"], - null, 2, ["5555211007"])); - -// [Thread 8] -// -// Thread body should be set to text body of the last message in this -// thread. However due to BUG 840051, there might be time difference between -// SMSC and device time. So the result of comparing the timestamps of sent and -// received message may not follow the order of requests and may result in -// UNEXPECTED-FAIL in following tests. -// -// Two received message, unreadCount = 2; -// One participant with two aliased addresses, participants = ["5555211008"]. -tasks.push(receiveMessage.bind(null, "5555211008", "thread 8-1")); -tasks.push(receiveMessage.bind(null, "+15555211008", "thread 8-2")); -tasks.push(sendMessage.bind(null, "5555211008", "thread 8-3")); -tasks.push(sendMessage.bind(null, "+15555211008", "thread 8-4")); -checkFuncs.push(checkThread.bind(null, ["thread 8-1", "thread 8-2", - "thread 8-3", "thread 8-4"], - null, 2, ["5555211008"])); - -// [Thread 9] -// Three sent message, unreadCount = 0; -// One participant with three aliased addresses, participants = ["+15555211009"]. -tasks.push(sendMessage.bind(null, "+15555211009", "thread 9-1")); -tasks.push(sendMessage.bind(null, "01115555211009", "thread 9-2")); -tasks.push(sendMessage.bind(null, "5555211009", "thread 9-3")); -checkFuncs.push(checkThread.bind(null, ["thread 9-1", "thread 9-2", - "thread 9-3"], - "thread 9-3", 0, ["+15555211009"])); - -// [Thread 10] -// Three sent message, unreadCount = 0; -// One participant with three aliased addresses, participants = ["+15555211010"]. -tasks.push(sendMessage.bind(null, "+15555211010", "thread 10-1")); -tasks.push(sendMessage.bind(null, "5555211010", "thread 10-2")); -tasks.push(sendMessage.bind(null, "01115555211010", "thread 10-3")); -checkFuncs.push(checkThread.bind(null, ["thread 10-1", "thread 10-2", - "thread 10-3"], - "thread 10-3", 0, ["+15555211010"])); - -// [Thread 11] -// Three sent message, unreadCount = 0; -// One participant with three aliased addresses, participants = ["01115555211011"]. -tasks.push(sendMessage.bind(null, "01115555211011", "thread 11-1")); -tasks.push(sendMessage.bind(null, "5555211011", "thread 11-2")); -tasks.push(sendMessage.bind(null, "+15555211011", "thread 11-3")); -checkFuncs.push(checkThread.bind(null, ["thread 11-1", "thread 11-2", - "thread 11-3"], - "thread 11-3", 0, ["01115555211011"])); - -// [Thread 12] -// Three sent message, unreadCount = 0; -// One participant with three aliased addresses, participants = ["01115555211012"]. -tasks.push(sendMessage.bind(null, "01115555211012", "thread 12-1")); -tasks.push(sendMessage.bind(null, "+15555211012", "thread 12-2")); -tasks.push(sendMessage.bind(null, "5555211012", "thread 12-3")); -checkFuncs.push(checkThread.bind(null, ["thread 12-1", "thread 12-2", - "thread 12-3"], - "thread 12-3", 0, ["01115555211012"])); - -// [Thread 13] -// Three sent message, unreadCount = 0; -// One participant with three aliased addresses, participants = ["5555211013"]. -tasks.push(sendMessage.bind(null, "5555211013", "thread 13-1")); -tasks.push(sendMessage.bind(null, "+15555211013", "thread 13-2")); -tasks.push(sendMessage.bind(null, "01115555211013", "thread 13-3")); -checkFuncs.push(checkThread.bind(null, ["thread 13-1", "thread 13-2", - "thread 13-3"], - "thread 13-3", 0, ["5555211013"])); - -// [Thread 14] -// Three sent message, unreadCount = 0; -// One participant with three aliased addresses, participants = ["5555211014"]. -tasks.push(sendMessage.bind(null, "5555211014", "thread 14-1")); -tasks.push(sendMessage.bind(null, "01115555211014", "thread 14-2")); -tasks.push(sendMessage.bind(null, "+15555211014", "thread 14-3")); -checkFuncs.push(checkThread.bind(null, ["thread 14-1", "thread 14-2", - "thread 14-3"], - "thread 14-3", 0, ["5555211014"])); - -//[Thread 15] -//Three sent message, unreadCount = 0; -//One participant but might be merged to 555211015, participants = ["5555211015"]. -tasks.push(sendMessage.bind(null, "5555211015", "thread 15-1")); -checkFuncs.push(checkThread.bind(null, ["thread 15-1"], - "thread 15-1", 0, ["5555211015"])); - -//[Thread 16] -//Three sent message, unreadCount = 0; -//One participant but might be merged to 5555211015, participants = ["555211015"]. -tasks.push(sendMessage.bind(null, "555211015", "thread 16-1")); -checkFuncs.push(checkThread.bind(null, ["thread 16-1"], - "thread 16-1", 0, ["555211015"])); - -//[Thread 17] -//Three sent message, unreadCount = 0; -//One participant with two aliased addresses, participants = ["555211017"]. -tasks.push(sendMessage.bind(null, "+5511555211017", "thread 17-1")); -tasks.push(sendMessage.bind(null, "555211017", "thread 17-2")); -checkFuncs.push(checkThread.bind(null, ["thread 17-1", "thread 17-2"], - "thread 17-2", 0, ["+5511555211017"])); - -//[Thread 18] -//Three sent message, unreadCount = 0; -//One participant with two aliased addresses, participants = ["555211018"]. -tasks.push(sendMessage.bind(null, "555211018", "thread 18-1")); -tasks.push(sendMessage.bind(null, "+5511555211018", "thread 18-2")); -checkFuncs.push(checkThread.bind(null, ["thread 18-1", "thread 18-2"], - "thread 18-2", 0, ["555211018"])); - -// Check threads. -tasks.push(getAllThreads.bind(null, function(threads) { - is(threads.length, checkFuncs.length, "number of threads got"); - - // Reverse threads as we iterate over them in reverse order - threads.reverse(); - - (function callback() { - if (!threads.length) { - tasks.next(); - return; - } - - checkFuncs.shift()(threads.shift(), callback); - })(); -})); - -tasks.push(deleteAllMessages); - -tasks.push(getAllThreads.bind(null, function(threads) { - is(threads.length, 0, "Empty thread list at the end."); - tasks.next(); -})); - -// WARNING: All tasks should be pushed before this!!! -tasks.push(function cleanUp() { - if (pendingEmulatorCmdCount) { - window.setTimeout(cleanUp, 100); - return; - } - - SpecialPowers.removePermission("sms", document); - SpecialPowers.clearUserPref("dom.sms.enabled"); - finish(); +startTestCommon(function testCaseMain() { + // [Thread 1] + // One message only, body = "thread 1"; + // All sent message, unreadCount = 0; + // One participant only, participants = ["5555211001"]. + return testGetThreads([{ incoming: false, address: "5555211001", text: "thread 1" }]) + // [Thread 2] + // Two messages, body = "thread 2-2"; + // All sent message, unreadCount = 0; + // One participant with two aliased addresses, participants = ["5555211002"]. + .then(() => testGetThreads([{ incoming: false, address: "5555211002", text: "thread 2-1" }, + { incoming: false, address: "+15555211002", text: "thread 2-2" }])) + // [Thread 3] + // Two messages, body = "thread 3-2"; + // All sent message, unreadCount = 0; + // One participant with two aliased addresses, participants = ["+15555211003"]. + .then(() => testGetThreads([{ incoming: false, address: "+15555211003", text: "thread 3-1" }, + { incoming: false, address: "5555211003", text: "thread 3-2" }])) + // [Thread 4] + // One message only, body = "thread 4"; + // All received message, unreadCount = 1; + // One participant only, participants = ["5555211004"]. + .then(() => testGetThreads([{ incoming: true, address: "5555211004", text: "thread 4" }])) + // [Thread 5] + // All received messages, unreadCount = 2; + // One participant with two aliased addresses, participants = ["5555211005"]. + .then(() => testGetThreads([{ incoming: true, address: "5555211005", text: "thread 5-1" }, + { incoming: true, address: "+15555211005", text: "thread 5-2" },])) + // [Thread 6] + // All received messages, unreadCount = 2; + // One participant with two aliased addresses, participants = ["+15555211006"]. + .then(() => testGetThreads([{ incoming: true, address: "+15555211006", text: "thread 6-1" }, + { incoming: true, address: "5555211006", text: "thread 6-2" }])) + // [Thread 7] + // 2 sent and then 2 received messages, unreadCount = 2; + // One participant with two aliased addresses, participants = ["5555211007"]. + .then(() => testGetThreads([{ incoming: false, address: "5555211007", text: "thread 7-1" }, + { incoming: false, address: "+15555211007", text: "thread 7-2" }, + { incoming: true, address: "5555211007", text: "thread 7-3" }, + { incoming: true, address: "+15555211007", text: "thread 7-4" }])) + // [Thread 8] + // 2 received and then 2 sent messages, unreadCount = 2; + // One participant with two aliased addresses, participants = ["5555211008"]. + .then(() => testGetThreads([{ incoming: true, address: "5555211008", text: "thread 8-1" }, + { incoming: true, address: "+15555211008", text: "thread 8-2" }, + { incoming: false, address: "5555211008", text: "thread 8-3" }, + { incoming: false, address: "+15555211008", text: "thread 8-4" }])) + // [Thread 9] + // Three sent message, unreadCount = 0; + // One participant with three aliased addresses, participants = ["+15555211009"]. + .then(() => testGetThreads([{ incoming: false, address: "+15555211009", text: "thread 9-1" }, + { incoming: false, address: "01115555211009", text: "thread 9-2" }, + { incoming: false, address: "5555211009", text: "thread 9-3" }])) + // [Thread 10] + // Three sent message, unreadCount = 0; + // One participant with three aliased addresses, participants = ["+15555211010"]. + .then(() => testGetThreads([{ incoming: false, address: "+15555211010", text: "thread 10-1" }, + { incoming: false, address: "5555211010", text: "thread 10-2" }, + { incoming: false, address: "01115555211010", text: "thread 10-3" }])) + // [Thread 11] + // Three sent message, unreadCount = 0; + // One participant with three aliased addresses, participants = ["01115555211011"]. + .then(() => testGetThreads([{ incoming: false, address: "01115555211011", text: "thread 11-1" }, + { incoming: false, address: "5555211011", text: "thread 11-2" }, + { incoming: false, address: "+15555211011", text: "thread 11-3" }])) + // [Thread 12] + // Three sent message, unreadCount = 0; + // One participant with three aliased addresses, participants = ["01115555211012"]. + .then(() => testGetThreads([{ incoming: false, address: "01115555211012", text: "thread 12-1" }, + { incoming: false, address: "+15555211012", text: "thread 12-2" }, + { incoming: false, address: "5555211012", text: "thread 12-3" }])) + // [Thread 13] + // Three sent message, unreadCount = 0; + // One participant with three aliased addresses, participants = ["5555211013"]. + .then(() => testGetThreads([{ incoming: false, address: "5555211013", text: "thread 13-1" }, + { incoming: false, address: "+15555211013", text: "thread 13-2" }, + { incoming: false, address: "01115555211013", text: "thread 13-3" }])) + // [Thread 14] + // Three sent message, unreadCount = 0; + // One participant with three aliased addresses, participants = ["5555211014"]. + .then(() => testGetThreads([{ incoming: false, address: "5555211014", text: "thread 14-1" }, + { incoming: false, address: "01115555211014", text: "thread 14-2" }, + { incoming: false, address: "+15555211014", text: "thread 14-3" }])) + // [Thread 15] + // One sent message, unreadCount = 0; + // One participant but might be merged to 555211015, participants = ["5555211015"]. + // [Thread 16] + // One sent message, unreadCount = 0; + // One participant but might be merged to 5555211015, participants = ["555211015"]. + .then(() => testGetThreads([{ incoming: false, address: "5555211015", text: "thread 15-1" }, + { incoming: false, address: "555211015", text: "thread 16-1" }], + true)) + // [Thread 17] + // Brazil number format: +55-aa-nnnnnnnn. (2-digit area code and 8-digit number) + // Two sent messages, unreadCount = 0; + // One participant with two aliased addresses, participants = ["+551155211017"]. + .then(() => testGetThreads([{ incoming: false, address: "+551155211017", text: "thread 17-1" }, + { incoming: false, address: "1155211017", text: "thread 17-2" }])) + // [Thread 18] + // Brazil number format: +55-aa-nnnnnnnn. (2-digit area code and 8-digit number) + // All sent messages, unreadCount = 0; + // One participant with two aliased addresses, participants = ["1155211018"]. + .then(() => testGetThreads([{ incoming: false, address: "1155211018", text: "thread 18-1" }, + { incoming: false, address: "+551155211018", text: "thread 18-2" }])); }); - -tasks.run();
--- a/mobile/android/base/BrowserApp.java +++ b/mobile/android/base/BrowserApp.java @@ -2977,23 +2977,24 @@ public class BrowserApp extends GeckoApp MenuUtils.safeSetEnabled(aMenu, R.id.site_settings, false); MenuUtils.safeSetEnabled(aMenu, R.id.add_to_launcher, false); return true; } final boolean inGuestMode = GeckoProfile.get(this).inGuestMode(); - bookmark.setEnabled(!AboutPages.isAboutReader(tab.getURL())); + final boolean isAboutReader = AboutPages.isAboutReader(tab.getURL()); + bookmark.setEnabled(!isAboutReader); bookmark.setVisible(!inGuestMode); bookmark.setCheckable(true); bookmark.setChecked(tab.isBookmark()); bookmark.setIcon(resolveBookmarkIconID(tab.isBookmark())); - reader.setEnabled(true); + reader.setEnabled(isAboutReader || !AboutPages.isAboutPage(tab.getURL())); reader.setVisible(!inGuestMode); reader.setCheckable(true); final boolean isPageInReadingList = tab.isInReadingList(); reader.setChecked(isPageInReadingList); reader.setIcon(resolveReadingListIconID(isPageInReadingList)); reader.setTitle(resolveReadingListTitleID(isPageInReadingList)); back.setEnabled(tab.canDoBack());
--- a/mobile/android/base/GeckoProfile.java +++ b/mobile/android/base/GeckoProfile.java @@ -1,27 +1,31 @@ /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- * 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/. */ package org.mozilla.gecko; +import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.FileReader; +import java.io.FileWriter; import java.io.IOException; import java.io.OutputStreamWriter; import java.nio.charset.Charset; import java.util.Enumeration; import java.util.HashMap; import java.util.Hashtable; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.json.JSONException; +import org.json.JSONArray; import org.mozilla.gecko.GeckoProfileDirectories.NoMozillaDirectoryException; import org.mozilla.gecko.GeckoProfileDirectories.NoSuchProfileException; import org.mozilla.gecko.db.BrowserDB; import org.mozilla.gecko.db.LocalBrowserDB; import org.mozilla.gecko.db.StubBrowserDB; import org.mozilla.gecko.distribution.Distribution; import org.mozilla.gecko.mozglue.RobocopTarget; import org.mozilla.gecko.firstrun.FirstrunPane; @@ -609,16 +613,52 @@ public final class GeckoProfile { return readFile(sessionFile); } } catch (IOException ioe) { Log.e(LOGTAG, "Unable to read session file", ioe); } return null; } + public void writeFile(final String filename, final String data) { + File file = new File(getDir(), filename); + BufferedWriter bufferedWriter = null; + try { + bufferedWriter = new BufferedWriter(new FileWriter(file, false)); + bufferedWriter.write(data); + } catch (IOException e) { + Log.e(LOGTAG, "Unable to write to file", e); + } finally { + try { + if (bufferedWriter != null) { + bufferedWriter.close(); + } + } catch (IOException e) { + Log.e(LOGTAG, "Error closing writer while writing to file", e); + } + } + } + + public JSONArray readJSONArrayFromFile(final String filename) { + String fileContent; + try { + fileContent = readFile(filename); + } catch (IOException expected) { + return new JSONArray(); + } + + JSONArray jsonArray; + try { + jsonArray = new JSONArray(fileContent); + } catch (JSONException e) { + jsonArray = new JSONArray(); + } + return jsonArray; + } + public String readFile(String filename) throws IOException { File dir = getDir(); if (dir == null) { throw new IOException("No profile directory found"); } File target = new File(dir, filename); return readFile(target); }
--- a/mobile/android/base/ReadingListHelper.java +++ b/mobile/android/base/ReadingListHelper.java @@ -222,17 +222,16 @@ public final class ReadingListHelper imp * A page can be removed from the ReadingList by panel context menu, * or by tapping the readinglist-remove icon in the ReaderMode banner. */ private void handleRemoveFromList(final String url) { ThreadUtils.postToBackgroundThread(new Runnable() { @Override public void run() { readingListAccessor.removeReadingListItemWithURL(context.getContentResolver(), url); - GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Reader:Removed", url)); showToast(R.string.page_removed, Toast.LENGTH_SHORT); } }); } /** * Gecko (ReaderMode) requests the page ReadingList status, to display * the proper ReaderMode banner icon (readinglist-add / readinglist-remove).
--- a/mobile/android/base/db/LocalReadingListAccessor.java +++ b/mobile/android/base/db/LocalReadingListAccessor.java @@ -7,16 +7,20 @@ package org.mozilla.gecko.db; import android.content.ContentResolver; import android.content.ContentUris; import android.content.ContentValues; import android.content.Context; import android.database.ContentObserver; import android.database.Cursor; import android.net.Uri; import android.util.Log; +import org.mozilla.gecko.AboutPages; +import org.mozilla.gecko.GeckoAppShell; +import org.mozilla.gecko.GeckoEvent; +import org.mozilla.gecko.ReaderModeUtils; import org.mozilla.gecko.db.BrowserContract.ReadingListItems; import org.mozilla.gecko.mozglue.RobocopTarget; @RobocopTarget public class LocalReadingListAccessor implements ReadingListAccessor { private static final String LOG_TAG = "GeckoReadingListAcc"; @@ -64,17 +68,19 @@ public class LocalReadingListAccessor im return cr.query(mReadingListUriWithProfile, new String[] { ReadingListItems._ID, ReadingListItems.URL }, ITEMS_TO_FETCH, null, SORT_ORDER_RECENT_FIRST); } @Override - public boolean isReadingListItem(ContentResolver cr, String uri) { + public boolean isReadingListItem(final ContentResolver cr, String uri) { + uri = stripURI(uri); + final Cursor c = cr.query(mReadingListUriWithProfile, new String[] { ReadingListItems._ID }, ReadingListItems.URL + " = ? OR " + ReadingListItems.RESOLVED_URL + " = ?", new String[] { uri, uri }, null); if (c == null) { Log.e(LOG_TAG, "Null cursor in isReadingListItem"); @@ -93,23 +99,31 @@ public class LocalReadingListAccessor im public long addReadingListItem(ContentResolver cr, ContentValues values) { // Check that required fields are present. for (String field: ReadingListItems.REQUIRED_FIELDS) { if (!values.containsKey(field)) { throw new IllegalArgumentException("Missing required field for reading list item: " + field); } } + // URL is a required field so no key check needed. + final String url = stripURI(values.getAsString(ReadingListItems.URL)); + values.put(ReadingListItems.URL, url); + // We're adding locally, so we can specify these. values.put(ReadingListItems.ADDED_ON, System.currentTimeMillis()); values.put(ReadingListItems.ADDED_BY, ReadingListProvider.PLACEHOLDER_THIS_DEVICE); // We never un-delete (and we can't; we wipe as we go). // Re-add if necessary and allow the server to resolve conflicts. - return ContentUris.parseId(cr.insert(mReadingListUriWithProfile, values)); + final long id = ContentUris.parseId(cr.insert(mReadingListUriWithProfile, values)); + + GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Reader:Added", url)); + + return id; } @Override public long addBasicReadingListItem(ContentResolver cr, String url, String title) { if (url == null) { throw new IllegalArgumentException("URL must not be null."); } final ContentValues values = new ContentValues(); @@ -124,33 +138,43 @@ public class LocalReadingListAccessor im } @Override public void updateReadingListItem(ContentResolver cr, ContentValues values) { if (!values.containsKey(ReadingListItems._ID)) { throw new IllegalArgumentException("Cannot update reading list item without an ID"); } + if (values.containsKey(ReadingListItems.URL)) { + values.put(ReadingListItems.URL, stripURI(values.getAsString(ReadingListItems.URL))); + } + final int updated = cr.update(mReadingListUriWithProfile, values, ReadingListItems._ID + " = ? ", new String[] { values.getAsString(ReadingListItems._ID) }); Log.d(LOG_TAG, "Updated " + updated + " reading list rows."); } @Override - public void removeReadingListItemWithURL(ContentResolver cr, String uri) { + public void removeReadingListItemWithURL(final ContentResolver cr, String uri) { + uri = stripURI(uri); cr.delete(mReadingListUriWithProfile, ReadingListItems.URL + " = ? OR " + ReadingListItems.RESOLVED_URL + " = ?", new String[]{ uri, uri }); + + GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Reader:Removed", uri)); } @Override public void deleteItem(ContentResolver cr, long itemID) { + // TODO: For completness, we should send a "Reader:Removed" + // GeckoEvent, but we don't have the uri. Luckily, this is + // only called in testing at the moment. cr.delete(ContentUris.appendId(mReadingListUriWithProfile.buildUpon(), itemID).build(), null, null); } @Override public void registerContentObserver(Context context, ContentObserver observer) { context.getContentResolver().registerContentObserver(mReadingListUriWithProfile, false, observer); } @@ -172,9 +196,16 @@ public class LocalReadingListAccessor im values.put(ReadingListItems.CONTENT_STATUS, ReadingListItems.STATUS_FETCHED_ARTICLE); values.put(ReadingListItems.RESOLVED_URL, resolvedURL); values.put(ReadingListItems.RESOLVED_TITLE, resolvedTitle); values.put(ReadingListItems.EXCERPT, excerpt); // The ContentProvider will take care of updating the sync metadata. cr.update(mReadingListUriWithProfile, values, ReadingListItems._ID + " = " + itemID, null); } + + /** + * Gets the URI from an about:reader URI if applicable, else returns the URI. + */ + private String stripURI(final String uri) { + return !AboutPages.isAboutReader(uri) ? uri : ReaderModeUtils.getUrlFromAboutReader(uri); + } }
--- a/mobile/android/base/moz.build +++ b/mobile/android/base/moz.build @@ -417,16 +417,17 @@ gbjar.sources += [ 'sqlite/ByteBufferInputStream.java', 'sqlite/MatrixBlobCursor.java', 'sqlite/SQLiteBridge.java', 'sqlite/SQLiteBridgeException.java', 'SuggestClient.java', 'SurfaceBits.java', 'Tab.java', 'tabqueue/TabQueueDispatcher.java', + 'tabqueue/TabQueueHelper.java', 'tabqueue/TabQueueService.java', 'Tabs.java', 'tabs/PrivateTabsPanel.java', 'tabs/TabCurve.java', 'tabs/TabHistoryController.java', 'tabs/TabHistoryFragment.java', 'tabs/TabHistoryItemRow.java', 'tabs/TabHistoryPage.java',
new file mode 100644 --- /dev/null +++ b/mobile/android/base/tabqueue/TabQueueHelper.java @@ -0,0 +1,40 @@ +/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*- + * 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/. */ + +package org.mozilla.gecko.tabqueue; + +import org.mozilla.gecko.GeckoProfile; +import org.mozilla.gecko.util.ThreadUtils; + +import android.text.TextUtils; +import android.util.Log; +import org.json.JSONArray; +import org.json.JSONException; + +import java.io.IOException; + +public class TabQueueHelper { + private static final String LOGTAG = "Gecko" + TabQueueHelper.class.getSimpleName(); + + public static final String FILE_NAME = "tab_queue_url_list.json"; + + /** + * Reads file and converts any content to JSON, adds passed in URL to the data and writes back to the file, + * creating the file if it doesn't already exist. This should not be run on the UI thread. + * + * @param profile + * @param url URL to add + * @param filename filename to add URL to + */ + public static void queueURL(final GeckoProfile profile, final String url, final String filename) { + ThreadUtils.assertNotOnUiThread(); + + JSONArray jsonArray = profile.readJSONArrayFromFile(filename); + + jsonArray.put(url); + + profile.writeFile(filename, jsonArray.toString()); + } +} \ No newline at end of file
--- a/mobile/android/base/tabqueue/TabQueueService.java +++ b/mobile/android/base/tabqueue/TabQueueService.java @@ -15,20 +15,25 @@ import android.os.IBinder; import android.util.Log; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.WindowManager; import android.widget.Button; import android.widget.TextView; import org.mozilla.gecko.BrowserApp; +import org.mozilla.gecko.GeckoProfile; import org.mozilla.gecko.R; import org.mozilla.gecko.mozglue.ContextUtils; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + + /** * On launch this Service displays a View over the currently running process with an action to open the url in Fennec * immediately. If the user takes no action, allowing the runnable to be processed after the specified * timeout (TOAST_TIMEOUT), the url is added to a file which is then read in Fennec on next launch, this allows the * user to quickly queue urls to open without having to open Fennec each time. If the Service receives an Intent whilst * the created View is still active, the old url is immediately processed and the View is re-purposed with the new * Intent data. * <p/> @@ -41,34 +46,38 @@ import org.mozilla.gecko.mozglue.Context * meaning that we can't quickly queue the current data and re-purpose the View. The asynchronous nature of the * IntentService is another prohibitive factor. * <p/> * General approach taken is similar to the FB chat heads functionality: * http://stackoverflow.com/questions/15975988/what-apis-in-android-is-facebook-using-to-create-chat-heads */ public class TabQueueService extends Service { private static final String LOGTAG = "Gecko" + TabQueueService.class.getSimpleName(); + private static final long TOAST_TIMEOUT = 3000; + private WindowManager windowManager; private View toastLayout; private Button openNowButton; private Handler tabQueueHandler; private WindowManager.LayoutParams toastLayoutParams; private volatile StopServiceRunnable stopServiceRunnable; private HandlerThread handlerThread; + private ExecutorService executorService; @Override public IBinder onBind(Intent intent) { // Not used return null; } @Override public void onCreate() { super.onCreate(); + executorService = Executors.newSingleThreadExecutor(); handlerThread = new HandlerThread("TabQueueHandlerThread"); handlerThread.start(); tabQueueHandler = new Handler(handlerThread.getLooper()); windowManager = (WindowManager) getSystemService(WINDOW_SERVICE); LayoutInflater layoutInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE); @@ -103,24 +112,24 @@ public class TabQueueService extends Ser stopServiceRunnable.run(false); } else { windowManager.addView(toastLayout, toastLayoutParams); } stopServiceRunnable = new StopServiceRunnable(startId) { @Override public void onRun() { - addUrlToTabQueue(intent); + addURLToTabQueue(intent, TabQueueHelper.FILE_NAME); stopServiceRunnable = null; } }; openNowButton.setOnClickListener(new View.OnClickListener() { @Override - public void onClick(View view) { + public void onClick(final View view) { tabQueueHandler.removeCallbacks(stopServiceRunnable); stopServiceRunnable = null; Intent forwardIntent = new Intent(intent); forwardIntent.setClass(getApplicationContext(), BrowserApp.class); forwardIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(forwardIntent); @@ -133,27 +142,33 @@ public class TabQueueService extends Ser return START_FLAG_REDELIVERY; } private void removeView() { windowManager.removeView(toastLayout); } - private void addUrlToTabQueue(Intent intentParam) { - if (intentParam == null) { - // This should never happen, but let's return silently instead of crash if it does. + private void addURLToTabQueue(final Intent intent, final String filename) { + if (intent == null) { + // This should never happen, but let's return silently instead of crashing if it does. Log.w(LOGTAG, "Error adding URL to tab queue - invalid intent passed in."); return; } - final ContextUtils.SafeIntent intent = new ContextUtils.SafeIntent(intentParam); - final String intentData = intent.getDataString(); + final ContextUtils.SafeIntent safeIntent = new ContextUtils.SafeIntent(intent); + final String intentData = safeIntent.getDataString(); - // TODO Add url to tab queue here - bug 1134235 - Log.d(LOGTAG, "Adding URL to tab queue: " + intentData); + // As we're doing disk IO, let's run this stuff in a separate thread. + executorService.submit(new Runnable() { + @Override + public void run() { + final GeckoProfile profile = GeckoProfile.get(getApplicationContext()); + TabQueueHelper.queueURL(profile, intentData, filename); + } + }); } @Override public void onDestroy() { super.onDestroy(); tabQueueHandler = null; handlerThread.quit(); } @@ -161,21 +176,21 @@ public class TabQueueService extends Ser /** * A modified Runnable which additionally removes the view from the window view hierarchy and stops the service * when run, unless explicitly instructed not to. */ private abstract class StopServiceRunnable implements Runnable { private final int startId; - public StopServiceRunnable(int startId) { + public StopServiceRunnable(final int startId) { this.startId = startId; } - public void run(boolean shouldStopService) { + public void run(final boolean shouldStopService) { onRun(); if (shouldStopService) { removeView(); } stopSelfResult(startId); }
--- a/mobile/android/chrome/content/Reader.js +++ b/mobile/android/chrome/content/Reader.js @@ -22,16 +22,23 @@ let Reader = { observe: function Reader_observe(aMessage, aTopic, aData) { switch (aTopic) { case "Reader:FetchContent": { let data = JSON.parse(aData); this._fetchContent(data.url, data.id); break; } + + case "Reader:Added": { + let mm = window.getGroupMessageManager("browsers"); + mm.broadcastAsyncMessage("Reader:Added", { url: aData }); + break; + } + case "Reader:Removed": { ReaderMode.removeArticleFromCache(aData).catch(e => Cu.reportError("Error removing article from cache: " + e)); let mm = window.getGroupMessageManager("browsers"); mm.broadcastAsyncMessage("Reader:Removed", { url: aData }); break; } } @@ -247,18 +254,16 @@ let Reader = { Messaging.sendRequestForResult({ type: "Reader:AddToList", url: truncate(article.url, MAX_URI_LENGTH), title: truncate(article.title, MAX_TITLE_LENGTH), length: article.length, excerpt: article.excerpt, status: article.status, }).then((url) => { - let mm = window.getGroupMessageManager("browsers"); - mm.broadcastAsyncMessage("Reader:Added", { url: url }); ReaderMode.storeArticleInCache(article).catch(e => Cu.reportError("Error storing article in cache: " + e)); }).catch(Cu.reportError); }, /** * Gets an article for a given URL. This method will download and parse a document * if it does not find the article in the tab data or the cache. *
--- a/mobile/android/chrome/content/browser.js +++ b/mobile/android/chrome/content/browser.js @@ -141,17 +141,17 @@ let lazilyLoadedObserverScripts = [ ["MemoryObserver", ["memory-pressure", "Memory:Dump"], "chrome://browser/content/MemoryObserver.js"], ["ConsoleAPI", ["console-api-log-event"], "chrome://browser/content/ConsoleAPI.js"], ["FindHelper", ["FindInPage:Opened", "FindInPage:Closed", "Tab:Selected"], "chrome://browser/content/FindHelper.js"], ["PermissionsHelper", ["Permissions:Get", "Permissions:Clear"], "chrome://browser/content/PermissionsHelper.js"], ["FeedHandler", ["Feeds:Subscribe"], "chrome://browser/content/FeedHandler.js"], ["Feedback", ["Feedback:Show"], "chrome://browser/content/Feedback.js"], ["SelectionHandler", ["TextSelection:Get"], "chrome://browser/content/SelectionHandler.js"], ["EmbedRT", ["GeckoView:ImportScript"], "chrome://browser/content/EmbedRT.js"], - ["Reader", ["Reader:FetchContent", "Reader:Removed"], "chrome://browser/content/Reader.js"], + ["Reader", ["Reader:FetchContent", "Reader:Added", "Reader:Removed"], "chrome://browser/content/Reader.js"], ]; if (AppConstants.MOZ_WEBRTC) { lazilyLoadedObserverScripts.push( ["WebrtcUI", ["getUserMedia:request", "recording-device-events"], "chrome://browser/content/WebrtcUI.js"]) } lazilyLoadedObserverScripts.forEach(function (aScript) { let [name, notifications, script] = aScript; @@ -3972,16 +3972,140 @@ Tab.prototype = { } if (!this.metatags[type] || this.metatags[type + "_quality"] < quality) { this.metatags[type] = value; this.metatags[type + "_quality"] = quality; } }, + sanitizeRelString: function(linkRel) { + // Sanitize the rel string + let list = []; + if (linkRel) { + list = linkRel.toLowerCase().split(/\s+/); + let hash = {}; + list.forEach(function(value) { hash[value] = true; }); + list = []; + for (let rel in hash) + list.push("[" + rel + "]"); + } + return list; + }, + + makeFaviconMessage: function(eventTarget) { + // We want to get the largest icon size possible for our UI. + let maxSize = 0; + + // We use the sizes attribute if available + // see http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#rel-icon + if (eventTarget.hasAttribute("sizes")) { + let sizes = eventTarget.getAttribute("sizes").toLowerCase(); + + if (sizes == "any") { + // Since Java expects an integer, use -1 to represent icons with sizes="any" + maxSize = -1; + } else { + let tokens = sizes.split(" "); + tokens.forEach(function(token) { + // TODO: check for invalid tokens + let [w, h] = token.split("x"); + maxSize = Math.max(maxSize, Math.max(w, h)); + }); + } + } + return { + type: "Link:Favicon", + tabID: this.id, + href: resolveGeckoURI(eventTarget.href), + size: maxSize, + mime: eventTarget.getAttribute("type") || "" + }; + }, + + makeFeedMessage: function(eventTarget, targetType) { + try { + // urlSecurityCeck will throw if things are not OK + ContentAreaUtils.urlSecurityCheck(eventTarget.href, + eventTarget.ownerDocument.nodePrincipal, + Ci.nsIScriptSecurityManager.DISALLOW_INHERIT_PRINCIPAL); + + if (!this.browser.feeds) + this.browser.feeds = []; + + this.browser.feeds.push({ + href: eventTarget.href, + title: eventTarget.title, + type: targetType + }); + + return { + type: "Link:Feed", + tabID: this.id + }; + } catch (e) { + return null; + } + }, + + makeOpenSearchMessage: function(eventTarget) { + let type = eventTarget.type && eventTarget.type.toLowerCase(); + // Replace all starting or trailing spaces or spaces before "*;" globally w/ "". + type = type.replace(/^\s+|\s*(?:;.*)?$/g, ""); + + // Check that type matches opensearch. + let isOpenSearch = (type == "application/opensearchdescription+xml"); + if (isOpenSearch && eventTarget.title && /^(?:https?|ftp):/i.test(eventTarget.href)) { + Services.search.init(() => { + let visibleEngines = Services.search.getVisibleEngines(); + // NOTE: Engines are currently identified by name, but this can be changed + // when Engines are identified by URL (see bug 335102). + if (visibleEngines.some(function(e) { + return e.name == eventTarget.title; + })) { + // This engine is already present, do nothing. + return null; + } + + if (this.browser.engines) { + // This engine has already been handled, do nothing. + if (this.browser.engines.some(function(e) { + return e.url == eventTarget.href; + })) { + return null; + } + } else { + this.browser.engines = []; + } + + // Get favicon. + let iconURL = eventTarget.ownerDocument.documentURIObject.prePath + "/favicon.ico"; + + let newEngine = { + title: eventTarget.title, + url: eventTarget.href, + iconURL: iconURL + }; + + this.browser.engines.push(newEngine); + + // Don't send a message to display engines if we've already handled an engine. + if (this.browser.engines.length > 1) + return null; + + // Broadcast message that this tab contains search engines that should be visible. + return { + type: "Link:OpenSearch", + tabID: this.id, + visible: true + }; + }); + } + }, + handleEvent: function(aEvent) { switch (aEvent.type) { case "DOMContentLoaded": { let target = aEvent.originalTarget; // ignore on frames and other documents if (target != this.browser.contentDocument) return; @@ -4061,143 +4185,44 @@ Tab.prototype = { this.addMetadata("tileColor", target.content, this.METADATA_GOOD_MATCH); break; } break; case "DOMLinkAdded": case "DOMLinkChanged": { + let jsonMessage = null; let target = aEvent.originalTarget; if (!target.href || target.disabled) return; // Ignore on frames and other documents if (target.ownerDocument != this.browser.contentDocument) return; - // Sanitize the rel string - let list = []; - if (target.rel) { - list = target.rel.toLowerCase().split(/\s+/); - let hash = {}; - list.forEach(function(value) { hash[value] = true; }); - list = []; - for (let rel in hash) - list.push("[" + rel + "]"); - } - + // Sanitize rel link + let list = this.sanitizeRelString(target.rel); if (list.indexOf("[icon]") != -1) { - // We want to get the largest icon size possible for our UI. - let maxSize = 0; - - // We use the sizes attribute if available - // see http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#rel-icon - if (target.hasAttribute("sizes")) { - let sizes = target.getAttribute("sizes").toLowerCase(); - - if (sizes == "any") { - // Since Java expects an integer, use -1 to represent icons with sizes="any" - maxSize = -1; - } else { - let tokens = sizes.split(" "); - tokens.forEach(function(token) { - // TODO: check for invalid tokens - let [w, h] = token.split("x"); - maxSize = Math.max(maxSize, Math.max(w, h)); - }); - } - } - - let json = { - type: "Link:Favicon", - tabID: this.id, - href: resolveGeckoURI(target.href), - size: maxSize, - mime: target.getAttribute("type") || "" - }; - Messaging.sendRequest(json); + jsonMessage = this.makeFaviconMessage(target); } else if (list.indexOf("[alternate]") != -1 && aEvent.type == "DOMLinkAdded") { let type = target.type.toLowerCase().replace(/^\s+|\s*(?:;.*)?$/g, ""); let isFeed = (type == "application/rss+xml" || type == "application/atom+xml"); if (!isFeed) return; - try { - // urlSecurityCeck will throw if things are not OK - ContentAreaUtils.urlSecurityCheck(target.href, target.ownerDocument.nodePrincipal, Ci.nsIScriptSecurityManager.DISALLOW_INHERIT_PRINCIPAL); - - if (!this.browser.feeds) - this.browser.feeds = []; - this.browser.feeds.push({ href: target.href, title: target.title, type: type }); - - let json = { - type: "Link:Feed", - tabID: this.id - }; - Messaging.sendRequest(json); - } catch (e) {} + jsonMessage = this.makeFeedMessage(target, type); } else if (list.indexOf("[search]" != -1) && aEvent.type == "DOMLinkAdded") { - let type = target.type && target.type.toLowerCase(); - - // Replace all starting or trailing spaces or spaces before "*;" globally w/ "". - type = type.replace(/^\s+|\s*(?:;.*)?$/g, ""); - - // Check that type matches opensearch. - let isOpenSearch = (type == "application/opensearchdescription+xml"); - if (isOpenSearch && target.title && /^(?:https?|ftp):/i.test(target.href)) { - Services.search.init(() => { - let visibleEngines = Services.search.getVisibleEngines(); - // NOTE: Engines are currently identified by name, but this can be changed - // when Engines are identified by URL (see bug 335102). - if (visibleEngines.some(function(e) { - return e.name == target.title; - })) { - // This engine is already present, do nothing. - return; - } - - if (this.browser.engines) { - // This engine has already been handled, do nothing. - if (this.browser.engines.some(function(e) { - return e.url == target.href; - })) { - return; - } - } else { - this.browser.engines = []; - } - - // Get favicon. - let iconURL = target.ownerDocument.documentURIObject.prePath + "/favicon.ico"; - - let newEngine = { - title: target.title, - url: target.href, - iconURL: iconURL - }; - - this.browser.engines.push(newEngine); - - // Don't send a message to display engines if we've already handled an engine. - if (this.browser.engines.length > 1) - return; - - // Broadcast message that this tab contains search engines that should be visible. - let newEngineMessage = { - type: "Link:OpenSearch", - tabID: this.id, - visible: true - }; - - Messaging.sendRequest(newEngineMessage); - }); - } + jsonMessage = this.makeOpenSearchMessage(target); } + if (!jsonMessage) + return; + + Messaging.sendRequest(jsonMessage); break; } case "DOMTitleChanged": { if (!aEvent.isTrusted) return; // ignore on frames and other documents
--- a/mozglue/build/WindowsDllBlocklist.cpp +++ b/mozglue/build/WindowsDllBlocklist.cpp @@ -164,16 +164,19 @@ static DllBlockInfo sWindowsDllBlocklist { "activedetect64.dll", UNVERSIONED }, { "windowsapihookdll32.dll", UNVERSIONED }, { "windowsapihookdll64.dll", UNVERSIONED }, // Flash crashes with RealNetworks RealDownloader, bug 1132663 { "rndlnpshimswf.dll", ALL_VERSIONS }, { "rndlmainbrowserrecordplugin.dll", ALL_VERSIONS }, + // Crashes with CyberLink YouCam, bug 1136968 + { "ycwebcamerasource.ax", MAKE_VERSION(2, 0, 0, 1611) }, + { nullptr, 0 } }; #ifndef STATUS_DLL_NOT_FOUND #define STATUS_DLL_NOT_FOUND ((DWORD)0xC0000135L) #endif // define this for very verbose dll load debug spew
--- a/testing/docker/tester/Dockerfile +++ b/testing/docker/tester/Dockerfile @@ -1,27 +1,28 @@ FROM quay.io/mozilla/base-test:0.0.5 MAINTAINER Jonas Finnemann Jensen <jopsen@gmail.com> # Add utilities and configuration COPY b2g-desktop-config.py /home/worker/b2g-desktop-config.py COPY dot-config /home/worker/.config COPY dot-pulse /home/worker/.pulse -COPY hgrc /home/worker/.hgrc COPY bin /home/worker/bin COPY mozharness_configs /home/worker/mozharness_configs COPY buildprops.json /home/worker/buildprops.json +ADD https://s3-us-west-2.amazonaws.com/test-caching/packages/linux64-stackwalk /usr/local/bin/linux64-minidump_stackwalk ADD https://raw.githubusercontent.com/taskcluster/buildbot-step/master/buildbot_step /home/worker/bin/buildbot_step # Run test setup script RUN chmod u+x /home/worker/bin/buildbot_step +RUN chmod u+x /usr/local/bin/linux64-minidump_stackwalk RUN apt-get install -y python-pip && pip install virtualenv; RUN mkdir Documents; mkdir Pictures; mkdir Music; mkdir Videos; mkdir artifacts RUN chown -R worker:worker /home/worker/* /home/worker/.* -RUN npm install -g taskcluster-vcs@2.3.1 +RUN npm install -g taskcluster-vcs@2.3.4 ENV PATH $PATH:/home/worker/bin # TODO Re-enable worker when bug 1093833 lands #USER worker # Set a default command useful for debugging CMD ["/bin/bash", "--login"]
--- a/testing/docker/tester/VERSION +++ b/testing/docker/tester/VERSION @@ -1,1 +1,1 @@ -0.2.6 +0.2.8
deleted file mode 100644 --- a/testing/docker/tester/hgrc +++ /dev/null @@ -1,2 +0,0 @@ -[extensions] -share =
--- a/testing/docker/tester/mozharness_configs/remove_executables.py +++ b/testing/docker/tester/mozharness_configs/remove_executables.py @@ -1,3 +1,6 @@ config = { + # We bake this directly into the tester image now... + "download_minidump_stackwalk": False, + "minidump_stackwalk_path": "/usr/local/bin/linux64-minidump_stackwalk", "exes": {} }
--- a/testing/taskcluster/tasks/test.yml +++ b/testing/taskcluster/tasks/test.yml @@ -11,24 +11,22 @@ task: provisionerId: aws-provisioner schedulerId: task-graph-scheduler scopes: - 'docker-worker:image:{{#docker_image}}tester{{/docker_image}}' - 'queue:define-task:aws-provisioner/test-c4-2xlarge' - 'queue:create-task:aws-provisioner/test-c4-2xlarge' - 'docker-worker:cache:tc-vcs' - - 'docker-worker:cache:buildshare' payload: image: '{{#docker_image}}tester{{/docker_image}}' maxRunTime: 3600 cache: tc-vcs: '/home/worker/.tc-vcs' - buildshare: '/builds/' env: GAIA_HEAD_REPOSITORY: '{{{gaia_head_repository}}}' GAIA_BASE_REPOSITORY: '{{{gaia_base_repository}}}' GAIA_REF: '{{{gaia_ref}}}' GAIA_REV: '{{{gaia_rev}}}' MOZHARNESS_REPOSITORY: '{{mozharness_repository}}' MOZHARNESS_REV: '{{mozharness_rev}}'
--- a/testing/taskcluster/tasks/tests/b2g_build_test.yml +++ b/testing/taskcluster/tasks/tests/b2g_build_test.yml @@ -10,16 +10,17 @@ task: command: - entrypoint # entrypoint ensures we are running in xvfb - ./bin/pull_gaia.sh && - > python ./mozharness/scripts/gaia_build_integration.py --no-read-buildbot-config --config-file ./mozharness/configs/b2g/gaia_integration_config.py --config-file ./mozharness_configs/gaia_integration_override.py + --config-file ./mozharness_configs/remove_executables.py --installer-url {{build_url}} --test-url {{tests_url}} --download-symbols ondemand --gaia-repo https://hg.mozilla.org/integration/gaia-central --gaia-dir /home/worker --xre-url https://s3-us-west-2.amazonaws.com/test-caching/packages/xre.linux-x86_64.zip artifacts: 'public/build':
--- a/testing/taskcluster/tasks/tests/b2g_build_unit.yml +++ b/testing/taskcluster/tasks/tests/b2g_build_unit.yml @@ -10,16 +10,17 @@ task: command: - entrypoint - ./bin/pull_gaia.sh && - > python ./mozharness/scripts/gaia_build_unit.py --no-read-buildbot-config --config-file ./mozharness/configs/b2g/gaia_integration_config.py --config-file ./mozharness_configs/gaia_integration_override.py + --config-file ./mozharness_configs/remove_executables.py --download-symbols ondemand --installer-url {{build_url}} --test-url {{tests_url}} --gaia-repo https://hg.mozilla.org/integration/gaia-central --gaia-dir /home/worker artifacts: 'public/build': type: directory
--- a/testing/taskcluster/tasks/tests/b2g_emulator_cpp_unit.yml +++ b/testing/taskcluster/tasks/tests/b2g_emulator_cpp_unit.yml @@ -9,16 +9,17 @@ task: workerType: b2gtest-emulator payload: command: - entrypoint - > python ./mozharness/scripts/b2g_emulator_unittest.py --config-file ./mozharness/configs/b2g/emulator_automation_config.py --config-file ./mozharness_configs/emulator_override.py + --config-file ./mozharness_configs/remove_executables.py --download-symbols ondemand --test-suite cppunittest --installer-url {{build_url}} --test-url {{tests_url}} --xre-url https://s3-us-west-2.amazonaws.com/test-caching/packages/xre_linux_x86.zip artifacts: 'public/build': type: directory
--- a/testing/taskcluster/tasks/tests/b2g_emulator_crashtest.yml +++ b/testing/taskcluster/tasks/tests/b2g_emulator_crashtest.yml @@ -10,16 +10,17 @@ task: payload: maxRunTime: 3600 command: - entrypoint - > python ./mozharness/scripts/b2g_emulator_unittest.py --config-file ./mozharness/configs/b2g/emulator_automation_config.py --config-file ./mozharness_configs/emulator_override.py + --config-file ./mozharness_configs/remove_executables.py --download-symbols ondemand --test-suite crashtest --installer-url {{build_url}} --test-url {{tests_url}} --xre-url https://s3-us-west-2.amazonaws.com/test-caching/packages/xre_linux_x86.zip --this-chunk {{chunk}} --total-chunk {{total_chunks}} artifacts:
--- a/testing/taskcluster/tasks/tests/b2g_emulator_js_reftest.yml +++ b/testing/taskcluster/tasks/tests/b2g_emulator_js_reftest.yml @@ -9,16 +9,17 @@ task: workerType: b2gtest-emulator payload: command: - entrypoint - > python ./mozharness/scripts/b2g_emulator_unittest.py --config-file ./mozharness/configs/b2g/emulator_automation_config.py --config-file ./mozharness_configs/emulator_override.py + --config-file ./mozharness_configs/remove_executables.py --download-symbols ondemand --test-suite jsreftest --installer-url {{build_url}} --test-url {{tests_url}} --xre-url https://s3-us-west-2.amazonaws.com/test-caching/packages/xre_linux_x86.zip --this-chunk {{chunk}} --total-chunk {{total_chunks}} artifacts:
--- a/testing/taskcluster/tasks/tests/b2g_emulator_mochitest.yml +++ b/testing/taskcluster/tasks/tests/b2g_emulator_mochitest.yml @@ -11,16 +11,17 @@ task: maxRunTime: 7200 command: - entrypoint - > python ./mozharness/scripts/b2g_emulator_unittest.py --config-file ./mozharness/configs/b2g/emulator_automation_config.py --config-file ./mozharness_configs/gaia_integration_override.py --config-file ./mozharness_configs/emulator_override.py + --config-file ./mozharness_configs/remove_executables.py --download-symbols ondemand --test-suite mochitest --installer-url {{build_url}} --test-url {{tests_url}} --xre-url https://s3-us-west-2.amazonaws.com/test-caching/packages/xre_linux_x86.zip --this-chunk {{chunk}} --total-chunk {{total_chunks}} artifacts:
--- a/testing/taskcluster/tasks/tests/b2g_emulator_mochitest_media.yml +++ b/testing/taskcluster/tasks/tests/b2g_emulator_mochitest_media.yml @@ -10,16 +10,17 @@ task: payload: command: - entrypoint - > python ./mozharness/scripts/b2g_emulator_unittest.py --config-file ./mozharness/configs/b2g/emulator_automation_config.py --config-file ./mozharness_configs/gaia_integration_override.py --config-file ./mozharness_configs/emulator_override.py + --config-file ./mozharness_configs/remove_executables.py --download-symbols ondemand --test-suite mochitest --test-path dom/media/tests/ --installer-url {{build_url}} --test-url {{tests_url}} --xre-url https://s3-us-west-2.amazonaws.com/test-caching/packages/xre_linux_x86.zip artifacts: 'public/build':
--- a/testing/taskcluster/tasks/tests/b2g_emulator_reftest.yml +++ b/testing/taskcluster/tasks/tests/b2g_emulator_reftest.yml @@ -9,16 +9,17 @@ task: workerType: b2gtest-emulator payload: command: - entrypoint - > python ./mozharness/scripts/b2g_emulator_unittest.py --config-file ./mozharness/configs/b2g/emulator_automation_config.py --config-file ./mozharness_configs/emulator_override.py + --config-file ./mozharness_configs/remove_executables.py --download-symbols ondemand --test-suite reftest --installer-url {{build_url}} --test-url {{tests_url}} --xre-url https://s3-us-west-2.amazonaws.com/test-caching/packages/xre_linux_x86.zip --this-chunk {{chunk}} --total-chunk {{total_chunks}} artifacts:
--- a/testing/taskcluster/tasks/tests/b2g_emulator_xpcshell.yml +++ b/testing/taskcluster/tasks/tests/b2g_emulator_xpcshell.yml @@ -10,16 +10,17 @@ task: payload: maxRunTime: 6000 command: - entrypoint - > python ./mozharness/scripts/b2g_emulator_unittest.py --config-file ./mozharness/configs/b2g/emulator_automation_config.py --config-file ./mozharness_configs/emulator_override.py + --config-file ./mozharness_configs/remove_executables.py --download-symbols ondemand --test-suite xpcshell --installer-url {{build_url}} --test-url {{tests_url}} --xre-url https://s3-us-west-2.amazonaws.com/test-caching/packages/xre_linux_x86.zip artifacts: 'public/build': type: directory
--- a/testing/taskcluster/tasks/tests/b2g_emulator_xpcshell_chunked.yml +++ b/testing/taskcluster/tasks/tests/b2g_emulator_xpcshell_chunked.yml @@ -10,16 +10,17 @@ task: payload: maxRunTime: 6000 command: - entrypoint - > python ./mozharness/scripts/b2g_emulator_unittest.py --config-file ./mozharness/configs/b2g/emulator_automation_config.py --config-file ./mozharness_configs/emulator_override.py + --config-file ./mozharness_configs/remove_executables.py --download-symbols ondemand --test-suite xpcshell --installer-url {{build_url}} --test-url {{tests_url}} --xre-url https://s3-us-west-2.amazonaws.com/test-caching/packages/xre_linux_x86.zip --this-chunk {{chunk}} --total-chunk {{total_chunks}} artifacts:
--- a/testing/taskcluster/tasks/tests/b2g_gaia_js_integration_tests.yml +++ b/testing/taskcluster/tasks/tests/b2g_gaia_js_integration_tests.yml @@ -10,16 +10,17 @@ task: command: - entrypoint # entrypoint ensures we are running in xvfb - ./bin/pull_gaia.sh && - > python ./mozharness/scripts/gaia_integration.py --no-read-buildbot-config --config-file b2g/gaia_integration_config.py --config-file ./mozharness_configs/gaia_integration_override.py + --config-file ./mozharness_configs/remove_executables.py --installer-url {{build_url}} --test-url {{tests_url}} --download-symbols ondemand --total-chunk {{total_chunks}} --this-chunk {{chunk}} --gaia-repo https://hg.mozilla.org/integration/gaia-central --gaia-dir /home/worker artifacts:
--- a/testing/taskcluster/tasks/tests/b2g_gaia_ui_test_accessibility.yml +++ b/testing/taskcluster/tasks/tests/b2g_gaia_ui_test_accessibility.yml @@ -10,16 +10,17 @@ task: command: - entrypoint # entrypoint ensures we are running in xvfb - ./bin/pull_gaia.sh && - > python ./mozharness/scripts/marionette.py --no-read-buildbot-config --config-file marionette/gaia_ui_test_prod_config.py --config-file ./mozharness_configs/gaia_integration_override.py + --config-file ./mozharness_configs/remove_executables.py --installer-url {{build_url}} --test-url {{tests_url}} --download-symbols ondemand --gip-suite accessibility --gaia-repo https://hg.mozilla.org/integration/gaia-central --gaia-dir /home/worker --xre-url https://s3-us-west-2.amazonaws.com/test-caching/packages/xre.linux-x86_64.zip artifacts:
--- a/testing/taskcluster/tasks/tests/b2g_gaia_ui_test_functional.yml +++ b/testing/taskcluster/tasks/tests/b2g_gaia_ui_test_functional.yml @@ -10,16 +10,17 @@ task: command: - entrypoint # entrypoint ensures we are running in xvfb - ./bin/pull_gaia.sh && - > python ./mozharness/scripts/marionette.py --no-read-buildbot-config --config-file marionette/gaia_ui_test_prod_config.py --config-file ./mozharness_configs/gaia_integration_override.py + --config-file ./mozharness_configs/remove_executables.py --installer-url {{build_url}} --test-url {{tests_url}} --download-symbols ondemand --gip-suite functional --total-chunk {{total_chunks}} --this-chunk {{chunk}} --gaia-repo https://hg.mozilla.org/integration/gaia-central --gaia-dir /home/worker
--- a/testing/taskcluster/tasks/tests/b2g_gaia_ui_test_unit.yml +++ b/testing/taskcluster/tasks/tests/b2g_gaia_ui_test_unit.yml @@ -10,16 +10,17 @@ task: command: - entrypoint # entrypoint ensures we are running in xvfb - ./bin/pull_gaia.sh && - > python ./mozharness/scripts/marionette.py --no-read-buildbot-config --config-file marionette/gaia_ui_test_prod_config.py --config-file ./mozharness_configs/gaia_integration_override.py + --config-file ./mozharness_configs/remove_executables.py --installer-url {{build_url}} --test-url {{tests_url}} --download-symbols ondemand --gip-suite unit --gaia-repo https://hg.mozilla.org/integration/gaia-central --gaia-dir /home/worker --xre-url https://s3-us-west-2.amazonaws.com/test-caching/packages/xre.linux-x86_64.zip artifacts:
--- a/testing/taskcluster/tasks/tests/b2g_gaia_unit.yml +++ b/testing/taskcluster/tasks/tests/b2g_gaia_unit.yml @@ -10,16 +10,17 @@ task: command: - entrypoint - ./bin/pull_gaia.sh && - > python ./mozharness/scripts/gaia_unit.py --no-read-buildbot-config --config-file ./mozharness/configs/b2g/gaia_unit_production_config.py --config-file ./mozharness_configs/gaia_integration_override.py + --config-file ./mozharness_configs/remove_executables.py --download-symbols ondemand --installer-url {{build_url}} --test-url {{tests_url}} --gaia-repo https://hg.mozilla.org/integration/gaia-central --gaia-dir /home/worker --xre-url https://s3-us-west-2.amazonaws.com/test-caching/packages/xre.linux-x86_64.zip artifacts: 'public/build':
--- a/testing/taskcluster/tasks/tests/b2g_gaia_unit_oop.yml +++ b/testing/taskcluster/tasks/tests/b2g_gaia_unit_oop.yml @@ -10,16 +10,17 @@ task: command: - entrypoint - ./bin/pull_gaia.sh && - > python ./mozharness/scripts/gaia_unit.py --no-read-buildbot-config --config-file ./mozharness/configs/b2g/gaia_unit_production_config.py --config-file ./mozharness_configs/gaia_integration_override.py + --config-file ./mozharness_configs/remove_executables.py --browser-arg -oop --download-symbols ondemand --installer-url {{build_url}} --test-url {{tests_url}} --gaia-repo https://hg.mozilla.org/integration/gaia-central --gaia-dir /home/worker --xre-url https://s3-us-west-2.amazonaws.com/test-caching/packages/xre.linux-x86_64.zip artifacts:
--- a/testing/taskcluster/tasks/tests/b2g_gip_oop.yml +++ b/testing/taskcluster/tasks/tests/b2g_gip_oop.yml @@ -10,16 +10,17 @@ task: command: - entrypoint # entrypoint ensures we are running in xvfb - ./bin/pull_gaia.sh && - > python ./mozharness/scripts/marionette.py --no-read-buildbot-config --config-file marionette/gaia_ui_test_prod_config.py --config-file ./mozharness_configs/gaia_integration_override.py + --config-file ./mozharness_configs/remove_executables.py --app-arg -oop --installer-url {{build_url}} --test-url {{tests_url}} --download-symbols ondemand --gaia-repo https://hg.mozilla.org/integration/gaia-central --gaia-dir /home/worker --xre-url https://s3-us-west-2.amazonaws.com/test-caching/packages/xre.linux-x86_64.zip artifacts:
--- a/testing/taskcluster/tasks/tests/b2g_mochitest.yml +++ b/testing/taskcluster/tasks/tests/b2g_mochitest.yml @@ -8,16 +8,17 @@ task: payload: command: - entrypoint # entrypoint ensures we are running in xvfb - > python ./mozharness/scripts/b2g_desktop_unittest.py --no-read-buildbot-config --config-file /home/worker/b2g-desktop-config.py + --config-file ./mozharness_configs/remove_executables.py --installer-url {{build_url}} --test-url {{tests_url}} --download-symbols ondemand --test-suite mochitest --total-chunk={{total_chunks}} --this-chunk={{chunk}} artifacts: 'public/build':
--- a/testing/taskcluster/tasks/tests/mulet_gaia_js_integration_tests.yml +++ b/testing/taskcluster/tasks/tests/mulet_gaia_js_integration_tests.yml @@ -11,16 +11,17 @@ task: - entrypoint # entrypoint ensures we are running in xvfb - ./bin/pull_gaia.sh && - > python ./mozharness/scripts/gaia_integration.py --application firefox --no-read-buildbot-config --config-file b2g/gaia_integration_config.py --config-file ./mozharness_configs/gaia_integration_override.py + --config-file ./mozharness_configs/remove_executables.py --installer-url {{build_url}} --test-url {{tests_url}} --download-symbols ondemand --total-chunk {{total_chunks}} --this-chunk {{chunk}} --gaia-repo {{gaia_head_repository}} --gaia-dir /home/worker artifacts:
--- a/testing/taskcluster/tasks/tests/mulet_mochitests.yml +++ b/testing/taskcluster/tasks/tests/mulet_mochitests.yml @@ -9,16 +9,17 @@ task: payload: command: - entrypoint # entrypoint ensures we are running in xvfb - > python ./mozharness/scripts/desktop_unittest.py --no-read-buildbot-config --config-file ./mozharness/configs/unittests/linux_unittest.py --config-file ./mozharness_configs/linux_mulet_config.py + --config-file ./mozharness_configs/remove_executables.py --installer-url {{build_url}} --test-url {{tests_url}} --download-symbols ondemand --mochitest-suite plain-chunked --total-chunk={{total_chunks}} --this-chunk={{chunk}} artifacts: 'public/build':
--- a/toolkit/components/alerts/resources/content/alert.js +++ b/toolkit/components/alerts/resources/content/alert.js @@ -40,16 +40,25 @@ function prefillAlertInfo() { // arguments[9] --> an optional callback listener (nsIObserver) switch (window.arguments.length) { default: case 10: gAlertListener = window.arguments[9]; case 9: gReplacedWindow = window.arguments[8]; + case 8: + if (window.arguments[7]) { + document.getElementById('alertTitleLabel').setAttribute('lang', window.arguments[7]); + document.getElementById('alertTextLabel').setAttribute('lang', window.arguments[7]); + } + case 7: + if (window.arguments[6]) { + document.getElementById('alertNotification').style.direction = window.arguments[6]; + } case 6: gOrigin = window.arguments[5]; case 5: gAlertCookie = window.arguments[4]; case 4: gAlertTextClickable = window.arguments[3]; if (gAlertTextClickable) { document.getElementById('alertNotification').setAttribute('clickable', true);
--- a/toolkit/components/feeds/test/xpcshell.ini +++ b/toolkit/components/feeds/test/xpcshell.ini @@ -1,12 +1,11 @@ [DEFAULT] head = head.js tail = -firefox-appdir = browser skip-if = toolkit == 'android' || toolkit == 'gonk' support-files = xml/rfc4287/author_namespaces.xml xml/rfc4287/entry_link_IANA.xml xml/rfc4287/feed_author_email_2.xml xml/rfc4287/feed_logo.xml xml/rfc4287/entry_author.xml xml/rfc4287/entry_link_otherURI_alt.xml
--- a/toolkit/components/passwordmgr/LoginRecipes.jsm +++ b/toolkit/components/passwordmgr/LoginRecipes.jsm @@ -225,13 +225,17 @@ let LoginRecipesContent = { }, }; const DEFAULT_RECIPES = { "siteRecipes": [ { "description": "okta uses a hidden password field to disable filling", "hosts": ["mozilla.okta.com"], - "passwordSelector": "#pass-signin", - "pathRegex": "^(|\/login\/(login.htm|do\-login))$" + "passwordSelector": "#pass-signin" }, + { + "description": "anthem uses a hidden password and username field to disable filling", + "hosts": ["www.anthem.com"], + "passwordSelector": "#LoginContent_txtLoginPass" + } ] };
--- a/toolkit/devtools/client/connection-manager.js +++ b/toolkit/devtools/client/connection-manager.js @@ -12,16 +12,18 @@ const EventEmitter = require("devtools/t const DevToolsUtils = require("devtools/toolkit/DevToolsUtils"); Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/devtools/dbg-client.jsm"); Cu.import("resource://gre/modules/devtools/dbg-server.jsm"); DevToolsUtils.defineLazyModuleGetter(this, "Task", "resource://gre/modules/Task.jsm"); +const REMOTE_TIMEOUT = "devtools.debugger.remote-timeout"; + /** * Connection Manager. * * To use this module: * const {ConnectionManager} = require("devtools/client/connection-manager"); * * # ConnectionManager * @@ -47,16 +49,18 @@ DevToolsUtils.defineLazyModuleGetter(thi * . disconnect() Disconnect if connected. Expect a "disconnecting" event * * Properties: * . host IP address or hostname * . port Port * . logs Current logs. "newlog" event notifies new available logs * . store Reference to a local data store (see below) * . keepConnecting Should the connection keep trying to connect? + * . timeoutDelay When should we give up (in ms)? + * 0 means wait forever. * . encryption Should the connection be encrypted? * . authentication What authentication scheme should be used? * . authenticator The |Authenticator| instance used. Overriding * properties of this instance may be useful to * customize authentication UX for a specific use case. * . advertisement The server's advertisement if found by discovery * . status Connection status: * Connection.Status.CONNECTED @@ -228,18 +232,21 @@ Connection.prototype = { host: this.host, port: this.port, encryption: this.encryption, authenticator: this.authenticator }); return settings; }, + timeoutDelay: Services.prefs.getIntPref(REMOTE_TIMEOUT), + resetOptions() { this.keepConnecting = false; + this.timeoutDelay = Services.prefs.getIntPref(REMOTE_TIMEOUT); this.encryption = false; this.authentication = null; this.advertisement = null; }, disconnect: function(force) { if (this.status == Connection.Status.DESTROYED) { return; @@ -263,18 +270,19 @@ Connection.prototype = { this._customTransport = transport; if (this._customTransport) { this.log("connecting (custom transport)"); } else { this.log("connecting to " + this.host + ":" + this.port); } this._setStatus(Connection.Status.CONNECTING); - let delay = Services.prefs.getIntPref("devtools.debugger.remote-timeout"); - this._timeoutID = setTimeout(this._onTimeout, delay); + if (this.timeoutDelay > 0) { + this._timeoutID = setTimeout(this._onTimeout, this.timeoutDelay); + } this._clientConnect(); } else { let msg = "Can't connect. Client is not fully disconnected"; this.log(msg); throw new Error(msg); } },
--- a/toolkit/devtools/webconsole/test/test_page_errors.html +++ b/toolkit/devtools/webconsole/test/test_page_errors.html @@ -67,16 +67,21 @@ function onAttach(aState, aResponse) aState.dbgClient.addListener("pageError", onPageError); doPageErrors(); } let pageErrors = []; function onPageError(aState, aType, aPacket) { + if (!aPacket.pageError.sourceName.contains("test_page_errors")) { + info("Ignoring error from unknown source: " + aPacket.pageError.sourceName); + return; + } + is(aPacket.from, aState.actor, "page error actor"); pageErrors.push(aPacket.pageError); if (pageErrors.length != expectedPageErrors.length) { return; } aState.dbgClient.removeListener("pageError", onPageError);
--- a/toolkit/modules/sessionstore/FormData.jsm +++ b/toolkit/modules/sessionstore/FormData.jsm @@ -81,20 +81,16 @@ function isValidCCNumber(value) { * The public API exported by this module that allows to collect * and restore form data for a document and its subframes. */ this.FormData = Object.freeze({ collect: function (frame) { return FormDataInternal.collect(frame); }, - restore: function (frame, data) { - FormDataInternal.restore(frame, data); - }, - restoreTree: function (root, data) { FormDataInternal.restoreTree(root, data); } }); /** * This module's internal API. */
--- a/toolkit/modules/sessionstore/ScrollPosition.jsm +++ b/toolkit/modules/sessionstore/ScrollPosition.jsm @@ -4,22 +4,35 @@ "use strict"; this.EXPORTED_SYMBOLS = ["ScrollPosition"]; const Ci = Components.interfaces; /** - * It provides methods to collect and restore scroll positions for single - * frames and frame trees. + * It provides methods to collect scroll positions from single frames and to + * restore scroll positions for frame trees. * * This is a child process module. */ this.ScrollPosition = Object.freeze({ + collect(frame) { + return ScrollPositionInternal.collect(frame); + }, + + restoreTree(root, data) { + ScrollPositionInternal.restoreTree(root, data); + } +}); + +/** + * This module's internal API. + */ +let ScrollPositionInternal = { /** * Collects scroll position data for any given |frame| in the frame hierarchy. * * @param frame (DOMWindow) * * @return {scroll: "x,y"} e.g. {scroll: "100,200"} * Returns null when there is no scroll data we want to store for the * given |frame|. @@ -82,9 +95,9 @@ this.ScrollPosition = Object.freeze({ let frames = root.frames; data.children.forEach((child, index) => { if (child && index < frames.length) { this.restoreTree(frames[index], child); } }); } -}); +};