Merge m-c to inbound. a=merge

CLOSED TREE
This commit is contained in:
Ryan VanderMeulen 2015-05-01 10:50:07 -04:00
commit f3e32f8fe2
223 changed files with 4436 additions and 5420 deletions

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="2eda36a4795012a5d1275b77ebb20ac377c8cd26"> <project name="platform_build" path="build" remote="b2g" revision="2eda36a4795012a5d1275b77ebb20ac377c8cd26">
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="759a1f935a6a81c32ad66e39a6353b334dfa4f91"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="8e64346ce8197b50b815a294278797bc144aa3e6"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/> <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
@ -134,7 +134,7 @@
<project name="platform/hardware/akm" path="hardware/akm" revision="6d3be412647b0eab0adff8a2768736cf4eb68039"/> <project name="platform/hardware/akm" path="hardware/akm" revision="6d3be412647b0eab0adff8a2768736cf4eb68039"/>
<project groups="invensense" name="platform/hardware/invensense" path="hardware/invensense" revision="e6d9ab28b4f4e7684f6c07874ee819c9ea0002a2"/> <project groups="invensense" name="platform/hardware/invensense" path="hardware/invensense" revision="e6d9ab28b4f4e7684f6c07874ee819c9ea0002a2"/>
<project name="platform/hardware/ril" path="hardware/ril" revision="865ce3b4a2ba0b3a31421ca671f4d6c5595f8690"/> <project name="platform/hardware/ril" path="hardware/ril" revision="865ce3b4a2ba0b3a31421ca671f4d6c5595f8690"/>
<project name="kernel/common" path="kernel" revision="0be9cc12cd81b145e1471016c19722429ff9285e"/> <project name="kernel/common" path="kernel" revision="a2977758950865feb5980996d8e889677dea3bd4"/>
<project name="platform/system/core" path="system/core" revision="7992618bd4ee33ce96897675a5c0a9b619122f13"/> <project name="platform/system/core" path="system/core" revision="7992618bd4ee33ce96897675a5c0a9b619122f13"/>
<project name="u-boot" path="u-boot" revision="f1502910977ac88f43da7bf9277c3523ad4b0b2f"/> <project name="u-boot" path="u-boot" revision="f1502910977ac88f43da7bf9277c3523ad4b0b2f"/>
<project name="vendor/sprd/gps" path="vendor/sprd/gps" revision="7d6e1269be7186b2073fa568958b357826692c4b"/> <project name="vendor/sprd/gps" path="vendor/sprd/gps" revision="7d6e1269be7186b2073fa568958b357826692c4b"/>

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="759a1f935a6a81c32ad66e39a6353b334dfa4f91"/> <project name="gaia.git" path="gaia" remote="mozillaorg" revision="8e64346ce8197b50b815a294278797bc144aa3e6"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="9a9797062c6001d6346504161c51187a2968466b"/> <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="9a9797062c6001d6346504161c51187a2968466b"/>

View File

@ -17,7 +17,7 @@
</project> </project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="759a1f935a6a81c32ad66e39a6353b334dfa4f91"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="8e64346ce8197b50b815a294278797bc144aa3e6"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="adb24954bf8068f21705b570450475d183336b2d"/> <project name="moztt" path="external/moztt" remote="b2g" revision="adb24954bf8068f21705b570450475d183336b2d"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="0627790166dccd8dd370fa7d9f434ed9fc027fb4"/> <project name="apitrace" path="external/apitrace" remote="apitrace" revision="0627790166dccd8dd370fa7d9f434ed9fc027fb4"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="2eda36a4795012a5d1275b77ebb20ac377c8cd26"> <project name="platform_build" path="build" remote="b2g" revision="2eda36a4795012a5d1275b77ebb20ac377c8cd26">
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="759a1f935a6a81c32ad66e39a6353b334dfa4f91"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="8e64346ce8197b50b815a294278797bc144aa3e6"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/> <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33"> <project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="759a1f935a6a81c32ad66e39a6353b334dfa4f91"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="8e64346ce8197b50b815a294278797bc144aa3e6"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/> <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="759a1f935a6a81c32ad66e39a6353b334dfa4f91"/> <project name="gaia.git" path="gaia" remote="mozillaorg" revision="8e64346ce8197b50b815a294278797bc144aa3e6"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="9a9797062c6001d6346504161c51187a2968466b"/> <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="9a9797062c6001d6346504161c51187a2968466b"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="2eda36a4795012a5d1275b77ebb20ac377c8cd26"> <project name="platform_build" path="build" remote="b2g" revision="2eda36a4795012a5d1275b77ebb20ac377c8cd26">
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="759a1f935a6a81c32ad66e39a6353b334dfa4f91"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="8e64346ce8197b50b815a294278797bc144aa3e6"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/> <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
@ -125,7 +125,7 @@
<!-- Flame specific things --> <!-- Flame specific things -->
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="1bb28abbc215f45220620af5cd60a8ac1be93722"/> <project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="1bb28abbc215f45220620af5cd60a8ac1be93722"/>
<project name="device/qcom/common" path="device/qcom/common" revision="2501e5940ba69ece7654ff85611c76ae5bda299c"/> <project name="device/qcom/common" path="device/qcom/common" revision="2501e5940ba69ece7654ff85611c76ae5bda299c"/>
<project name="device-flame" path="device/t2m/flame" remote="b2g" revision="b83fc73de7b64594cd74b33e498bf08332b5d87b"/> <project name="device-flame" path="device/t2m/flame" remote="b2g" revision="a9f3f8fb8b0844724de32426b7bcc4e6dc4fa2ed"/>
<project name="codeaurora_kernel_msm" path="kernel" remote="b2g" revision="0865bc4134b67220df4058625fba29305d6b10c3"/> <project name="codeaurora_kernel_msm" path="kernel" remote="b2g" revision="0865bc4134b67220df4058625fba29305d6b10c3"/>
<project name="kernel_lk" path="bootable/bootloader/lk" remote="b2g" revision="fda40423ffa573dc6cafd3780515010cb2a086be"/> <project name="kernel_lk" path="bootable/bootloader/lk" remote="b2g" revision="fda40423ffa573dc6cafd3780515010cb2a086be"/>
<project name="platform_bootable_recovery" path="bootable/recovery" remote="b2g" revision="d5e53ed6f22fa06052351dc03510af9473af01ea"/> <project name="platform_bootable_recovery" path="bootable/recovery" remote="b2g" revision="d5e53ed6f22fa06052351dc03510af9473af01ea"/>

View File

@ -17,7 +17,7 @@
</project> </project>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/> <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="759a1f935a6a81c32ad66e39a6353b334dfa4f91"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="8e64346ce8197b50b815a294278797bc144aa3e6"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="adb24954bf8068f21705b570450475d183336b2d"/> <project name="moztt" path="external/moztt" remote="b2g" revision="adb24954bf8068f21705b570450475d183336b2d"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="0627790166dccd8dd370fa7d9f434ed9fc027fb4"/> <project name="apitrace" path="external/apitrace" remote="apitrace" revision="0627790166dccd8dd370fa7d9f434ed9fc027fb4"/>

View File

@ -1,9 +1,9 @@
{ {
"git": { "git": {
"git_revision": "759a1f935a6a81c32ad66e39a6353b334dfa4f91", "git_revision": "8e64346ce8197b50b815a294278797bc144aa3e6",
"remote": "https://git.mozilla.org/releases/gaia.git", "remote": "https://git.mozilla.org/releases/gaia.git",
"branch": "" "branch": ""
}, },
"revision": "d88d79f407d14635451063c4397724d836efcbaa", "revision": "1bbaa54b674c42e0d8b2fe31d8b0080901811fa0",
"repo_path": "integration/gaia-central" "repo_path": "integration/gaia-central"
} }

View File

@ -17,7 +17,7 @@
</project> </project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="759a1f935a6a81c32ad66e39a6353b334dfa4f91"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="8e64346ce8197b50b815a294278797bc144aa3e6"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="adb24954bf8068f21705b570450475d183336b2d"/> <project name="moztt" path="external/moztt" remote="b2g" revision="adb24954bf8068f21705b570450475d183336b2d"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="0627790166dccd8dd370fa7d9f434ed9fc027fb4"/> <project name="apitrace" path="external/apitrace" remote="apitrace" revision="0627790166dccd8dd370fa7d9f434ed9fc027fb4"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33"> <project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="759a1f935a6a81c32ad66e39a6353b334dfa4f91"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="8e64346ce8197b50b815a294278797bc144aa3e6"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/> <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -1327,8 +1327,8 @@ pref("services.sync.prefs.sync.xpinstall.whitelist.required", true);
// Developer edition preferences // Developer edition preferences
#ifdef MOZ_DEV_EDITION #ifdef MOZ_DEV_EDITION
pref("lightweightThemes.selectedThemeID", "firefox-devedition@mozilla.org"); sticky_pref("lightweightThemes.selectedThemeID", "firefox-devedition@mozilla.org");
pref("browser.devedition.theme.enabled", true); sticky_pref("browser.devedition.theme.enabled", true);
#endif #endif
// Developer edition promo preferences // Developer edition promo preferences
@ -1443,6 +1443,15 @@ pref("devtools.performance.ui.show-idle-blocks", true);
pref("devtools.performance.ui.enable-memory", false); pref("devtools.performance.ui.enable-memory", false);
pref("devtools.performance.ui.enable-framerate", true); pref("devtools.performance.ui.enable-framerate", true);
pref("devtools.performance.ui.show-jit-optimizations", false); pref("devtools.performance.ui.show-jit-optimizations", false);
// If in aurora (40.0, will revert for 40.1), set default
// to retro mode.
// TODO bug 1160313
#if MOZ_UPDATE_CHANNEL == aurora
pref("devtools.performance.ui.retro-mode", true);
#else
pref("devtools.performance.ui.retro-mode", false);
#endif
// The default cache UI setting // The default cache UI setting
pref("devtools.cache.disabled", false); pref("devtools.cache.disabled", false);
@ -1507,9 +1516,9 @@ pref("devtools.webaudioeditor.inspectorWidth", 300);
// Default theme ("dark" or "light") // Default theme ("dark" or "light")
#ifdef MOZ_DEV_EDITION #ifdef MOZ_DEV_EDITION
pref("devtools.theme", "dark"); sticky_pref("devtools.theme", "dark");
#else #else
pref("devtools.theme", "light"); sticky_pref("devtools.theme", "light");
#endif #endif
// Display the introductory text // Display the introductory text
@ -1646,10 +1655,10 @@ pref("browser.newtabpage.rows", 3);
pref("browser.newtabpage.columns", 5); pref("browser.newtabpage.columns", 5);
// directory tiles download URL // directory tiles download URL
pref("browser.newtabpage.directory.source", "https://tiles.services.mozilla.com/v2/links/fetch/%LOCALE%"); pref("browser.newtabpage.directory.source", "https://tiles.services.mozilla.com/v3/links/fetch/%LOCALE%/%CHANNEL%");
// endpoint to send newtab click and view pings // endpoint to send newtab click and view pings
pref("browser.newtabpage.directory.ping", "https://tiles.services.mozilla.com/v2/links/"); pref("browser.newtabpage.directory.ping", "https://tiles.services.mozilla.com/v3/links/");
// Enable the DOM fullscreen API. // Enable the DOM fullscreen API.
pref("full-screen-api.enabled", true); pref("full-screen-api.enabled", true);
@ -1863,7 +1872,7 @@ pref("browser.polaris.enabled", false);
pref("privacy.trackingprotection.ui.enabled", false); pref("privacy.trackingprotection.ui.enabled", false);
#endif #endif
#ifdef NIGHTLY_BUILD #ifdef E10S_TESTING_ONLY
// At the moment, autostart.2 is used, while autostart.1 is unused. // At the moment, autostart.2 is used, while autostart.1 is unused.
// We leave it here set to false to reset users' defaults and allow // We leave it here set to false to reset users' defaults and allow
// us to change everybody to true in the future, when desired. // us to change everybody to true in the future, when desired.
@ -1871,7 +1880,7 @@ pref("browser.tabs.remote.autostart.1", false);
pref("browser.tabs.remote.autostart.2", true); pref("browser.tabs.remote.autostart.2", true);
#endif #endif
#ifdef NIGHTLY_BUILD #ifdef E10S_TESTING_ONLY
// Enable e10s add-on interposition by default. // Enable e10s add-on interposition by default.
pref("extensions.interposition.enabled", true); pref("extensions.interposition.enabled", true);
pref("extensions.interposition.prefetching", true); pref("extensions.interposition.prefetching", true);
@ -1900,6 +1909,7 @@ pref("browser.readinglist.sidebarEverOpened", false);
pref("readinglist.scheduler.enabled", false); pref("readinglist.scheduler.enabled", false);
pref("readinglist.server", "https://readinglist.services.mozilla.com/v1"); pref("readinglist.server", "https://readinglist.services.mozilla.com/v1");
pref("browser.reader.detectedFirstArticle", false);
// Don't limit how many nodes we care about on desktop: // Don't limit how many nodes we care about on desktop:
pref("reader.parse-node-limit", 0); pref("reader.parse-node-limit", 0);

View File

@ -133,7 +133,7 @@ Site.prototype = {
if (this.link.targetedSite) { if (this.link.targetedSite) {
this.node.setAttribute("suggested", true); this.node.setAttribute("suggested", true);
let targetedSite = `<strong> ${this.link.targetedSite} </strong>`; let targetedSite = `<strong> ${this.link.targetedName} </strong>`;
this._querySelector(".newtab-suggested").innerHTML = this._querySelector(".newtab-suggested").innerHTML =
`<div class='newtab-suggested-bounds'> ${newTabString("suggested.button", [targetedSite])} </div>`; `<div class='newtab-suggested-bounds'> ${newTabString("suggested.button", [targetedSite])} </div>`;
} }

View File

@ -555,7 +555,9 @@ addEventListener("unload", () => {
}, false); }, false);
addMessageListener("Browser:AppTab", function(message) { addMessageListener("Browser:AppTab", function(message) {
docShell.isAppTab = message.data.isAppTab; if (docShell) {
docShell.isAppTab = message.data.isAppTab;
}
}); });
let WebBrowserChrome = { let WebBrowserChrome = {

View File

@ -6,30 +6,6 @@ Components.utils.import("resource://gre/modules/Promise.jsm", this);
let chatbar = document.getElementById("pinnedchats"); let chatbar = document.getElementById("pinnedchats");
function waitForCondition(condition, errorMsg) {
let deferred = Promise.defer();
var tries = 0;
var interval = setInterval(function() {
if (tries >= 30) {
ok(false, errorMsg);
moveOn();
}
var conditionPassed;
try {
conditionPassed = condition();
} catch (e) {
ok(false, e + "\n" + e.stack);
conditionPassed = false;
}
if (conditionPassed) {
moveOn();
}
tries++;
}, 100);
var moveOn = function() { clearInterval(interval); deferred.resolve(); };
return deferred.promise;
}
add_chat_task(function* testOpenCloseChat() { add_chat_task(function* testOpenCloseChat() {
let chatbox = yield promiseOpenChat("http://example.com"); let chatbox = yield promiseOpenChat("http://example.com");
Assert.strictEqual(chatbox, chatbar.selectedChat); Assert.strictEqual(chatbox, chatbar.selectedChat);
@ -115,7 +91,7 @@ add_chat_task(function* testSecondTopLevelWindow() {
secondWindow.close(); secondWindow.close();
}); });
// Test that chats are created in the correct window. // Test that findChromeWindowForChats() returns the expected window.
add_chat_task(function* testChatWindowChooser() { add_chat_task(function* testChatWindowChooser() {
let chat = yield promiseOpenChat("http://example.com"); let chat = yield promiseOpenChat("http://example.com");
Assert.equal(numChatsInWindow(window), 1, "first window has the chat"); Assert.equal(numChatsInWindow(window), 1, "first window has the chat");
@ -124,42 +100,34 @@ add_chat_task(function* testChatWindowChooser() {
let secondWindow = OpenBrowserWindow(); let secondWindow = OpenBrowserWindow();
yield promiseOneEvent(secondWindow, "load"); yield promiseOneEvent(secondWindow, "load");
Assert.equal(secondWindow, Chat.findChromeWindowForChats(null), "Second window is the preferred chat window"); Assert.equal(secondWindow, Chat.findChromeWindowForChats(null), "Second window is the preferred chat window");
Assert.equal(numChatsInWindow(secondWindow), 0, "second window starts with no chats");
yield promiseOpenChat("http://example.com#2");
Assert.equal(numChatsInWindow(secondWindow), 1, "second window now has chats");
Assert.equal(numChatsInWindow(window), 1, "first window still has 1 chat");
chat.close();
// a bit heavy handed, but handy fixing bug 1090633 // focus the first window, and check it will be selected for future chats.
yield waitForCondition(function () !chat.parentNode, "chat has been detached"); // Bug 1090633 - there are lots of issues around focus, especially when the
Assert.equal(numChatsInWindow(window), 0, "first window now has no chats"); // browser itself doesn't have focus. We can end up with
// now open another chat - it should still open in the second. // Services.wm.getMostRecentWindow("navigator:browser") returning a different
yield promiseOpenChat("http://example.com#3"); // window than, say, Services.focus.activeWindow. But the focus manager isn't
Assert.equal(numChatsInWindow(window), 0, "first window still has no chats"); // the point of this test.
Assert.equal(numChatsInWindow(secondWindow), 2, "second window has both chats"); // So we simply keep focusing the first window until it is reported as the
// most recent.
do {
dump("trying to force window to become the most recent.\n");
secondWindow.focus();
window.focus();
yield promiseWaitForFocus();
} while (Services.wm.getMostRecentWindow("navigator:browser") != window)
// focus the first window, and open yet another chat - it Assert.equal(window, Chat.findChromeWindowForChats(null), "First window now the preferred chat window");
// should open in the first window.
window.focus();
yield promiseWaitForFocus();
chat = yield promiseOpenChat("http://example.com#4");
Assert.equal(numChatsInWindow(window), 1, "first window got new chat");
chat.close();
Assert.equal(numChatsInWindow(window), 0, "first window has no chats");
let privateWindow = OpenBrowserWindow({private: true}); let privateWindow = OpenBrowserWindow({private: true});
yield promiseOneEvent(privateWindow, "load") yield promiseOneEvent(privateWindow, "load")
// open a last chat - the focused window can't accept // The focused window can't accept chats (it's a private window), so the
// chats (it's a private window), so the chat should open // chat should open in the window that was selected before. This will be
// in the window that was selected before. This is known // either window or secondWindow (linux may choose a different one) but the
// to be broken on Linux. // point is that the window is *not* the private one.
chat = yield promiseOpenChat("http://example.com#5"); Assert.ok(Chat.findChromeWindowForChats(null) == window ||
let os = Services.appinfo.OS; Chat.findChromeWindowForChats(null) == secondWindow,
const BROKEN_WM_Z_ORDER = os != "WINNT" && os != "Darwin"; "Private window isn't selected for new chats.");
let fn = BROKEN_WM_Z_ORDER ? todo : ok;
fn(numChatsInWindow(window) == 1, "first window got the chat");
chat.close();
privateWindow.close(); privateWindow.close();
secondWindow.close(); secondWindow.close();
}); });

View File

@ -10,12 +10,16 @@ const CHAT_URL = "https://example.com/browser/browser/base/content/test/chat/cha
// Is the currently opened tab focused? // Is the currently opened tab focused?
function isTabFocused() { function isTabFocused() {
let tabb = gBrowser.getBrowserForTab(gBrowser.selectedTab); let tabb = gBrowser.getBrowserForTab(gBrowser.selectedTab);
return Services.focus.focusedWindow == tabb.contentWindow; // focus sucks in tests - our window may have lost focus.
let elt = Services.focus.getFocusedElementForWindow(window, false, {});
return elt == tabb;
} }
// Is the specified chat focused? // Is the specified chat focused?
function isChatFocused(chat) { function isChatFocused(chat) {
return chat.chatbar._isChatFocused(chat); // focus sucks in tests - our window may have lost focus.
let elt = Services.focus.getFocusedElementForWindow(window, false, {});
return elt == chat.content;
} }
let chatbar = document.getElementById("pinnedchats"); let chatbar = document.getElementById("pinnedchats");

View File

@ -32,19 +32,29 @@ add_task(function* test_reader_button() {
TEST_PREFS.forEach(([name, value]) => { TEST_PREFS.forEach(([name, value]) => {
Services.prefs.setBoolPref(name, value); Services.prefs.setBoolPref(name, value);
}); });
Services.prefs.setBoolPref("browser.reader.detectedFirstArticle", false);
let tab = gBrowser.selectedTab = gBrowser.addTab(); let tab = gBrowser.selectedTab = gBrowser.addTab();
is_element_hidden(readerButton, "Reader mode button is not present on a new tab"); is_element_hidden(readerButton, "Reader mode button is not present on a new tab");
ok(!UITour.isInfoOnTarget(window, "readerMode-urlBar"),
"Info panel shouldn't appear without the reader mode button");
ok(!Services.prefs.getBoolPref("browser.reader.detectedFirstArticle"),
"Shouldn't have detected the first article");
// Point tab to a test page that is reader-able. // Point tab to a test page that is reader-able.
let url = TEST_PATH + "readerModeArticle.html"; let url = TEST_PATH + "readerModeArticle.html";
yield promiseTabLoadEvent(tab, url); yield promiseTabLoadEvent(tab, url);
yield promiseWaitForCondition(() => !readerButton.hidden); yield promiseWaitForCondition(() => !readerButton.hidden);
is_element_visible(readerButton, "Reader mode button is present on a reader-able page"); is_element_visible(readerButton, "Reader mode button is present on a reader-able page");
ok(UITour.isInfoOnTarget(window, "readerMode-urlBar"),
"Info panel should be anchored at the reader mode button");
ok(Services.prefs.getBoolPref("browser.reader.detectedFirstArticle"),
"Should have detected the first article");
// Switch page into reader mode. // Switch page into reader mode.
readerButton.click(); readerButton.click();
yield promiseTabLoadEvent(tab); yield promiseTabLoadEvent(tab);
ok(!UITour.isInfoOnTarget(window, "readerMode-urlBar"), "Info panel should have closed");
let readerUrl = gBrowser.selectedBrowser.currentURI.spec; let readerUrl = gBrowser.selectedBrowser.currentURI.spec;
ok(readerUrl.startsWith("about:reader"), "about:reader loaded after clicking reader mode button"); ok(readerUrl.startsWith("about:reader"), "about:reader loaded after clicking reader mode button");

View File

@ -18,6 +18,8 @@ gDirectorySource = "data:application/json," + JSON.stringify({
}); });
function runTests() { function runTests() {
let origGetFrecentSitesName = DirectoryLinksProvider.getFrecentSitesName;
DirectoryLinksProvider.getFrecentSitesName = () => "";
let origIsTopPlacesSite = NewTabUtils.isTopPlacesSite; let origIsTopPlacesSite = NewTabUtils.isTopPlacesSite;
NewTabUtils.isTopPlacesSite = (site) => false; NewTabUtils.isTopPlacesSite = (site) => false;
@ -84,4 +86,5 @@ function runTests() {
yield blockCell(1); yield blockCell(1);
yield addNewTabPageTab(); yield addNewTabPageTab();
checkGrid("1,2,3,4,5,6,7,8,9"); checkGrid("1,2,3,4,5,6,7,8,9");
DirectoryLinksProvider.getFrecentSitesName = origGetFrecentSitesName;
} }

View File

@ -26,8 +26,11 @@ gDirectorySource = "data:application/json," + JSON.stringify({
}); });
function runTests() { function runTests() {
let origGetFrecentSitesName = DirectoryLinksProvider.getFrecentSitesName;
DirectoryLinksProvider.getFrecentSitesName = () => "";
let origEnhanced = NewTabUtils.allPages.enhanced; let origEnhanced = NewTabUtils.allPages.enhanced;
registerCleanupFunction(() => { registerCleanupFunction(() => {
DirectoryLinksProvider.getFrecentSitesName = origGetFrecentSitesName;
Services.prefs.clearUserPref(PRELOAD_PREF); Services.prefs.clearUserPref(PRELOAD_PREF);
NewTabUtils.allPages.enhanced = origEnhanced; NewTabUtils.allPages.enhanced = origEnhanced;
}); });

View File

@ -1,15 +1,14 @@
# We still need to fix warnings in this file. # This file currently uses a non-standard (and not on a standards track)
MozLoopWorker.js # if statement within catch.
# This file currently uses es7 features modules/MozLoopWorker.js
MozLoopAPI.jsm # This file currently uses es7 features eslint issue:
# https://github.com/eslint/espree/issues/125
modules/MozLoopAPI.jsm
# Libs we don't need to check # Libs we don't need to check
content/libs content/libs
content/shared/libs content/shared/libs
standalone/content/libs standalone/content/libs
standalone/node_modules standalone/node_modules
# We should look at turning these on when we fix the warnings
test/xpcshell
test/mochitest
# Libs we don't need to check # Libs we don't need to check
test/shared/vendor test/shared/vendor

View File

@ -1,3 +1,5 @@
// Note: there are extra allowances for files used solely in Firefox desktop,
// see content/js/.eslintrc and modules/.eslintrc
{ {
"plugins": [ "plugins": [
"react" "react"
@ -5,18 +7,6 @@
"ecmaFeatures": { "ecmaFeatures": {
"forOf": true, "forOf": true,
"jsx": true, "jsx": true,
// These are on for this directory for .jsm and content/js files.
// If adding more items here, consider turning them off for the following
// files if they aren't supported by all browsers.
// content/shared/.eslintrc
// content/standalone/.eslintrc
"blockBindings": true,
"arrowFunctions": true,
"destructuring": true,
"generators": true,
"spread": true,
"restParams": true,
"objectLiteralShorthandMethods": true
}, },
"env": { "env": {
"browser": true, "browser": true,
@ -43,49 +33,50 @@
// problems they find, one at a time. // problems they find, one at a time.
// Eslint built-in rules are documented at <http://eslint.org/docs/rules/> // Eslint built-in rules are documented at <http://eslint.org/docs/rules/>
"camelcase": 0, "camelcase": 0, // TODO: Remove (use default)
"comma-dangle": 0, "comma-dangle": 0, // TODO: Remove (use default)
"comma-spacing": 0, "comma-spacing": 0, // TODO: Remove (use default)
"consistent-return": 0, "consistent-return": 0, // TODO: Remove (use default)
"curly": 0, "curly": 0, // TODO: Remove (use default)
"dot-notation": 0, "dot-notation": 0, // TODO: Remove (use default)
"eol-last": 0, "eol-last": 0, // TODO: Remove (use default)
"eqeqeq": 0, "eqeqeq": 0, // TBD. Might need to be separate for content & chrome
"global-strict": 0, "global-strict": 0, // Leave as zero (this will be unsupported in eslint 1.0.0)
"key-spacing": 0, "key-spacing": 0, // TODO: Remove (use default)
"new-cap": 0, "new-cap": 0, // TODO: Remove (use default)
"no-catch-shadow": 0, "no-catch-shadow": 0, // TODO: Remove (use default)
"no-console": 0, "no-console": 0, // Leave as 0. We use console logging in content code.
"no-empty": 0, "no-empty": 0, // TODO: Remove (use default)
"no-extra-bind": 0, "no-extra-bind": 0, // Leave as 0
"no-extra-boolean-cast": 0, "no-extra-boolean-cast": 0, // TODO: Remove (use default)
"no-extra-semi": 0, "no-extra-semi": 0, // TODO: Remove (use default)
"no-multi-spaces": 0, "no-multi-spaces": 0, // TBD.
"no-new": 0, "no-new": 0, // TODO: Remove (use default)
"no-redeclare": 0, "no-redeclare": 0, // TODO: Remove (use default)
"no-return-assign": 0, "no-return-assign": 0, // TODO: Remove (use default)
"no-shadow": 0, "no-shadow": 0, // TODO: Remove (use default)
"no-spaced-func": 0, "no-spaced-func": 0, // TODO: Remove (use default)
"no-trailing-spaces": 0, "no-trailing-spaces": 0, // TODO: Remove (use default)
"no-undef": 0, "no-undef": 0, // TODO: Remove (use default)
"no-underscore-dangle": 0, "no-underscore-dangle": 0, // Leave as 0. Commonly used for private variables.
"no-unused-expressions": 0, "no-unused-expressions": 0, // TODO: Remove (use default)
"no-unused-vars": 0, "no-unused-vars": 0, // TODO: Remove (use default)
"no-use-before-define": 0, "no-use-before-define": 0, // TODO: Remove (use default)
"no-wrap-func": 0, "no-wrap-func": 0, // TODO: Remove (use default)
"quotes": 0, "quotes": 0, // [2, "double", "avoid-escape"],
"semi": 0, "semi": 0, // TODO: Remove (use default)
"semi-spacing": 0, "semi-spacing": 0, // TODO: Remove (use default)
"space-infix-ops": 0, "space-infix-ops": 0, // TODO: Remove (use default)
"space-return-throw-case": 0, "space-return-throw-case": 0, // TODO: Remove (use default)
"strict": 0, "strict": 0, // [2, "function"],
"yoda": 0, "yoda": 0, // [2, "never"],
// eslint-plugin-react rules. These are documented at // eslint-plugin-react rules. These are documented at
// <https://github.com/yannickcr/eslint-plugin-react#list-of-supported-rules> // <https://github.com/yannickcr/eslint-plugin-react#list-of-supported-rules>
"react/jsx-quotes": [2, "double", "avoid-escape"], "react/jsx-quotes": [2, "double", "avoid-escape"],
"react/jsx-no-undef": 2, "react/jsx-no-undef": 2,
// Need to fix instances where this is failing. // Need to fix instances where this is failing.
"react/jsx-sort-props": 0, "react/jsx-sort-props": 0,
"react/jsx-sort-prop-types": 0,
"react/jsx-uses-vars": 2, "react/jsx-uses-vars": 2,
// Need to fix the couple of instances which don't // Need to fix the couple of instances which don't
// currently pass this rule. // currently pass this rule.
@ -101,6 +92,7 @@
"react/react-in-jsx-scope": 0, "react/react-in-jsx-scope": 0,
// These ones we don't want to ever enable // These ones we don't want to ever enable
"react/display-name": 0, "react/display-name": 0,
"react/jsx-boolean-value": 0,
"react/no-multi-comp": 0 "react/no-multi-comp": 0
} }
} }

View File

@ -54,7 +54,7 @@ If you install eslint and the react plugin globally:
You can also run it by hand in the browser/components/loop directory: You can also run it by hand in the browser/components/loop directory:
eslint -ext .js -ext .jsx --ext .jsm . eslint --ext .js --ext .jsx --ext .jsm .
Front-End Unit Tests Front-End Unit Tests
==================== ====================

View File

@ -0,0 +1,15 @@
{
"ecmaFeatures": {
// These are on for this directory for .jsm and content/js files.
"blockBindings": true,
"arrowFunctions": true,
"destructuring": true,
"generators": true,
"spread": true,
"restParams": true,
"objectLiteralShorthandMethods": true
},
"rules": {
"generator-star-spacing": [2, "after"]
}
}

View File

@ -222,7 +222,7 @@ loop.contacts = (function(_, mozL10n) {
"disabled": !this.props.canEdit }), "disabled": !this.props.canEdit }),
onClick: this.onItemClick, "data-action": "remove"}, onClick: this.onItemClick, "data-action": "remove"},
React.createElement("i", {className: "icon icon-remove"}), React.createElement("i", {className: "icon icon-remove"}),
mozL10n.get("remove_contact_menu_button") mozL10n.get("remove_contact_menu_button2")
) )
) )
); );
@ -587,7 +587,7 @@ loop.contacts = (function(_, mozL10n) {
React.createElement(ButtonGroup, null, React.createElement(ButtonGroup, null,
React.createElement(Button, {caption: this.state.importBusy React.createElement(Button, {caption: this.state.importBusy
? mozL10n.get("importing_contacts_progress_button") ? mozL10n.get("importing_contacts_progress_button")
: mozL10n.get("import_contacts_button"), : mozL10n.get("import_contacts_button2"),
disabled: this.state.importBusy, disabled: this.state.importBusy,
onClick: this.handleImportButtonClick}, onClick: this.handleImportButtonClick},
React.createElement("div", {className: cx({"contact-import-spinner": true, React.createElement("div", {className: cx({"contact-import-spinner": true,

View File

@ -222,7 +222,7 @@ loop.contacts = (function(_, mozL10n) {
"disabled": !this.props.canEdit })} "disabled": !this.props.canEdit })}
onClick={this.onItemClick} data-action="remove"> onClick={this.onItemClick} data-action="remove">
<i className="icon icon-remove" /> <i className="icon icon-remove" />
{mozL10n.get("remove_contact_menu_button")} {mozL10n.get("remove_contact_menu_button2")}
</li> </li>
</ul> </ul>
); );
@ -587,7 +587,7 @@ loop.contacts = (function(_, mozL10n) {
<ButtonGroup> <ButtonGroup>
<Button caption={this.state.importBusy <Button caption={this.state.importBusy
? mozL10n.get("importing_contacts_progress_button") ? mozL10n.get("importing_contacts_progress_button")
: mozL10n.get("import_contacts_button")} : mozL10n.get("import_contacts_button2")}
disabled={this.state.importBusy} disabled={this.state.importBusy}
onClick={this.handleImportButtonClick}> onClick={this.handleImportButtonClick}>
<div className={cx({"contact-import-spinner": true, <div className={cx({"contact-import-spinner": true,

View File

@ -11,10 +11,11 @@ var loop = loop || {};
loop.roomViews = (function(mozL10n) { loop.roomViews = (function(mozL10n) {
"use strict"; "use strict";
var sharedActions = loop.shared.actions;
var sharedMixins = loop.shared.mixins;
var ROOM_STATES = loop.store.ROOM_STATES; var ROOM_STATES = loop.store.ROOM_STATES;
var SCREEN_SHARE_STATES = loop.shared.utils.SCREEN_SHARE_STATES; var SCREEN_SHARE_STATES = loop.shared.utils.SCREEN_SHARE_STATES;
var sharedActions = loop.shared.actions;
var sharedMixins = loop.shared.mixins;
var sharedUtils = loop.shared.utils;
var sharedViews = loop.shared.views; var sharedViews = loop.shared.views;
/** /**
@ -312,13 +313,25 @@ loop.roomViews = (function(mozL10n) {
var thumbnail = URL && URL.thumbnail || ""; var thumbnail = URL && URL.thumbnail || "";
var URLDescription = URL && URL.description || ""; var URLDescription = URL && URL.description || "";
var location = URL && URL.location || ""; var location = URL && URL.location || "";
var locationData = null;
if (location) {
locationData = sharedUtils.formatURL(location);
}
if (!locationData) {
return null;
}
return ( return (
React.createElement("div", {className: "room-context"}, React.createElement("div", {className: "room-context"},
React.createElement("img", {className: "room-context-thumbnail", src: thumbnail}), React.createElement("img", {className: "room-context-thumbnail", src: thumbnail}),
React.createElement("div", {className: "room-context-content"}, React.createElement("div", {className: "room-context-content"},
React.createElement("div", {className: "room-context-label"}, mozL10n.get("context_inroom_label")), React.createElement("div", {className: "room-context-label"}, mozL10n.get("context_inroom_label")),
React.createElement("div", {className: "room-context-description"}, URLDescription), React.createElement("div", {className: "room-context-description"}, URLDescription),
React.createElement("a", {className: "room-context-url", href: location, target: "_blank"}, location), React.createElement("a", {className: "room-context-url",
href: location,
target: "_blank",
title: locationData.location}, locationData.hostname),
this.props.roomData.roomDescription ? this.props.roomData.roomDescription ?
React.createElement("div", {className: "room-context-comment"}, this.props.roomData.roomDescription) : React.createElement("div", {className: "room-context-comment"}, this.props.roomData.roomDescription) :
null, null,

View File

@ -11,10 +11,11 @@ var loop = loop || {};
loop.roomViews = (function(mozL10n) { loop.roomViews = (function(mozL10n) {
"use strict"; "use strict";
var sharedActions = loop.shared.actions;
var sharedMixins = loop.shared.mixins;
var ROOM_STATES = loop.store.ROOM_STATES; var ROOM_STATES = loop.store.ROOM_STATES;
var SCREEN_SHARE_STATES = loop.shared.utils.SCREEN_SHARE_STATES; var SCREEN_SHARE_STATES = loop.shared.utils.SCREEN_SHARE_STATES;
var sharedActions = loop.shared.actions;
var sharedMixins = loop.shared.mixins;
var sharedUtils = loop.shared.utils;
var sharedViews = loop.shared.views; var sharedViews = loop.shared.views;
/** /**
@ -312,13 +313,25 @@ loop.roomViews = (function(mozL10n) {
var thumbnail = URL && URL.thumbnail || ""; var thumbnail = URL && URL.thumbnail || "";
var URLDescription = URL && URL.description || ""; var URLDescription = URL && URL.description || "";
var location = URL && URL.location || ""; var location = URL && URL.location || "";
var locationData = null;
if (location) {
locationData = sharedUtils.formatURL(location);
}
if (!locationData) {
return null;
}
return ( return (
<div className="room-context"> <div className="room-context">
<img className="room-context-thumbnail" src={thumbnail}/> <img className="room-context-thumbnail" src={thumbnail}/>
<div className="room-context-content"> <div className="room-context-content">
<div className="room-context-label">{mozL10n.get("context_inroom_label")}</div> <div className="room-context-label">{mozL10n.get("context_inroom_label")}</div>
<div className="room-context-description">{URLDescription}</div> <div className="room-context-description">{URLDescription}</div>
<a className="room-context-url" href={location} target="_blank">{location}</a> <a className="room-context-url"
href={location}
target="_blank"
title={locationData.location}>{locationData.hostname}</a>
{this.props.roomData.roomDescription ? {this.props.roomData.roomDescription ?
<div className="room-context-comment">{this.props.roomData.roomDescription}</div> : <div className="room-context-comment">{this.props.roomData.roomDescription}</div> :
null} null}

View File

@ -1,14 +0,0 @@
{
"ecmaFeatures": {
// Turn off top-level items needed for the jsm files, but not wanted
// for shared code as we can't support them.
"blockBindings": false,
"arrowFunctions": false,
"destructuring": false,
"forOf": true,
"generators": false,
"spread": false,
"restParams": false,
"objectLiteralShorthandMethods": false
}
}

View File

@ -789,7 +789,7 @@ loop.OTSdkDriver = (function() {
bucket = buckets.MORE_THAN_5M; bucket = buckets.MORE_THAN_5M;
} }
this.mozLoop.telemetryAddValue("LOOP_TWO_WAY_MEDIA_CONN_LENGTH", bucket); this.mozLoop.telemetryAddValue("LOOP_TWO_WAY_MEDIA_CONN_LENGTH_1", bucket);
this._setTwoWayMediaStartTime(this.CONNECTION_START_TIME_ALREADY_NOTED); this._setTwoWayMediaStartTime(this.CONNECTION_START_TIME_ALREADY_NOTED);
this._connectionLengthNotedCalls++; this._connectionLengthNotedCalls++;
@ -857,7 +857,7 @@ loop.OTSdkDriver = (function() {
return; return;
} }
this.mozLoop.telemetryAddValue("LOOP_SHARING_STATE_CHANGE", bucket); this.mozLoop.telemetryAddValue("LOOP_SHARING_STATE_CHANGE_1", bucket);
} }
}; };

View File

@ -271,6 +271,33 @@ var inChrome = typeof Components != "undefined" && "utils" in Components;
}; };
} }
/**
* Formats a url for display purposes. This includes converting the
* domain to punycode, and then decoding the url.
*
* @param {String} url The url to format.
* @return {Object} An object containing the hostname and full location.
*/
function formatURL(url) {
// We're using new URL to pass this through the browser's ACE/punycode
// processing system. If the browser considers a url to need to be
// punycode encoded for it to be displayed, then new URL will do that for
// us. This saves us needing our own punycode library.
var urlObject;
try {
urlObject = new URL(url);
} catch (ex) {
console.error("Error occurred whilst parsing URL:", ex);
return null;
}
// Finally, ensure we look good.
return {
hostname: urlObject.hostname,
location: decodeURI(urlObject.href)
};
}
/** /**
* Generates and opens a mailto: url with call URL information prefilled. * Generates and opens a mailto: url with call URL information prefilled.
* Note: This only works for Desktop. * Note: This only works for Desktop.
@ -536,6 +563,7 @@ var inChrome = typeof Components != "undefined" && "utils" in Components;
ROOM_INFO_FAILURES: ROOM_INFO_FAILURES, ROOM_INFO_FAILURES: ROOM_INFO_FAILURES,
composeCallUrlEmail: composeCallUrlEmail, composeCallUrlEmail: composeCallUrlEmail,
formatDate: formatDate, formatDate: formatDate,
formatURL: formatURL,
getBoolPreference: getBoolPreference, getBoolPreference: getBoolPreference,
getOS: getOS, getOS: getOS,
getOSVersion: getOSVersion, getOSVersion: getOSVersion,

View File

@ -0,0 +1,17 @@
{
"ecmaFeatures": {
"arrowFunctions": true,
"blockBindings": true,
"destructuring": true,
"generators": true,
"restParams": true,
"spread": true,
"objectLiteralShorthandMethods": true,
},
"rules": {
"generator-star-spacing": [2, "after"],
// We should fix the errors and enable this (set to 2)
"no-var": 0,
"strict": [2, "global"]
}
}

View File

@ -13,18 +13,18 @@ BROWSER_CHROME_MANIFESTS += [
] ]
EXTRA_JS_MODULES.loop += [ EXTRA_JS_MODULES.loop += [
'CardDavImporter.jsm',
'content/shared/js/crypto.js', 'content/shared/js/crypto.js',
'content/shared/js/utils.js', 'content/shared/js/utils.js',
'GoogleImporter.jsm', 'modules/CardDavImporter.jsm',
'LoopCalls.jsm', 'modules/GoogleImporter.jsm',
'LoopContacts.jsm', 'modules/LoopCalls.jsm',
'LoopRooms.jsm', 'modules/LoopContacts.jsm',
'LoopStorage.jsm', 'modules/LoopRooms.jsm',
'MozLoopAPI.jsm', 'modules/LoopStorage.jsm',
'MozLoopPushHandler.jsm', 'modules/MozLoopAPI.jsm',
'MozLoopService.jsm', 'modules/MozLoopPushHandler.jsm',
'MozLoopWorker.js', 'modules/MozLoopService.jsm',
'modules/MozLoopWorker.js',
] ]
with Files('**'): with Files('**'):

View File

@ -1,14 +0,0 @@
{
"ecmaFeatures": {
// Turn off top-level items needed for the jsm files, but not wanted
// for shared code as we can't support them.
"blockBindings": false,
"arrowFunctions": false,
"destructuring": false,
"forOf": true,
"generators": false,
"spread": false,
"restParams": false,
"objectLiteralShorthandMethods": false
}
}

View File

@ -16,6 +16,7 @@ loop.standaloneRoomViews = (function(mozL10n) {
var ROOM_STATES = loop.store.ROOM_STATES; var ROOM_STATES = loop.store.ROOM_STATES;
var sharedActions = loop.shared.actions; var sharedActions = loop.shared.actions;
var sharedMixins = loop.shared.mixins; var sharedMixins = loop.shared.mixins;
var sharedUtils = loop.shared.utils;
var sharedViews = loop.shared.views; var sharedViews = loop.shared.views;
var StandaloneRoomInfoArea = React.createClass({displayName: "StandaloneRoomInfoArea", var StandaloneRoomInfoArea = React.createClass({displayName: "StandaloneRoomInfoArea",
@ -248,7 +249,10 @@ loop.standaloneRoomViews = (function(mozL10n) {
return null; return null;
} }
var location = this.props.roomContextUrl.location; var locationInfo = sharedUtils.formatURL(this.props.roomContextUrl.location);
if (!locationInfo) {
return null;
}
var cx = React.addons.classSet; var cx = React.addons.classSet;
@ -262,9 +266,10 @@ loop.standaloneRoomViews = (function(mozL10n) {
React.createElement("img", {src: this.props.roomContextUrl.thumbnail}), React.createElement("img", {src: this.props.roomContextUrl.thumbnail}),
React.createElement("div", {className: "standalone-context-url-description-wrapper"}, React.createElement("div", {className: "standalone-context-url-description-wrapper"},
this.props.roomContextUrl.description, this.props.roomContextUrl.description,
React.createElement("br", null), React.createElement("a", {href: location, React.createElement("br", null), React.createElement("a", {href: locationInfo.location,
onClick: this.recordClick, onClick: this.recordClick,
target: "_blank"}, location) target: "_blank",
title: locationInfo.location}, locationInfo.hostname)
) )
) )
); );

View File

@ -16,6 +16,7 @@ loop.standaloneRoomViews = (function(mozL10n) {
var ROOM_STATES = loop.store.ROOM_STATES; var ROOM_STATES = loop.store.ROOM_STATES;
var sharedActions = loop.shared.actions; var sharedActions = loop.shared.actions;
var sharedMixins = loop.shared.mixins; var sharedMixins = loop.shared.mixins;
var sharedUtils = loop.shared.utils;
var sharedViews = loop.shared.views; var sharedViews = loop.shared.views;
var StandaloneRoomInfoArea = React.createClass({ var StandaloneRoomInfoArea = React.createClass({
@ -248,7 +249,10 @@ loop.standaloneRoomViews = (function(mozL10n) {
return null; return null;
} }
var location = this.props.roomContextUrl.location; var locationInfo = sharedUtils.formatURL(this.props.roomContextUrl.location);
if (!locationInfo) {
return null;
}
var cx = React.addons.classSet; var cx = React.addons.classSet;
@ -262,9 +266,10 @@ loop.standaloneRoomViews = (function(mozL10n) {
<img src={this.props.roomContextUrl.thumbnail} /> <img src={this.props.roomContextUrl.thumbnail} />
<div className="standalone-context-url-description-wrapper"> <div className="standalone-context-url-description-wrapper">
{this.props.roomContextUrl.description} {this.props.roomContextUrl.description}
<br /><a href={location} <br /><a href={locationInfo.location}
onClick={this.recordClick} onClick={this.recordClick}
target="_blank">{location}</a> target="_blank"
title={locationInfo.location}>{locationInfo.hostname}</a>
</div> </div>
</div> </div>
); );

View File

@ -12,8 +12,8 @@
}, },
"dependencies": {}, "dependencies": {},
"devDependencies": { "devDependencies": {
"eslint": "0.18.x", "eslint": "0.20.x",
"eslint-plugin-react": "2.0.x", "eslint-plugin-react": "2.2.x",
"express": "3.x" "express": "3.x"
}, },
"scripts": { "scripts": {

View File

@ -0,0 +1,7 @@
{
"rules": {
// This is useful for some of the tests, e.g.
// expect(new Foo()).to.Throw(/error/)
"no-new": 0
}
}

View File

@ -242,6 +242,23 @@ describe("loop.roomViews", function () {
expect(view.getDOMNode().querySelector(".room-context")).to.not.eql(null); expect(view.getDOMNode().querySelector(".room-context")).to.not.eql(null);
}); });
it("should format the context url for display", function() {
sandbox.stub(sharedUtils, "formatURL").returns({
location: "location",
hostname: "hostname"
});
view = mountTestComponent({
showContext: true,
roomData: {
roomContextUrls: [fakeContextURL]
}
});
expect(view.getDOMNode().querySelector(".room-context-url").textContent)
.eql("hostname");
});
}); });
}); });

View File

@ -0,0 +1,17 @@
{
"ecmaFeatures": {
"arrowFunctions": true,
"blockBindings": true,
"destructuring": true,
"generators": true,
"restParams": true,
"spread": true,
"objectLiteralShorthandMethods": true,
},
"rules": {
"generator-star-spacing": [2, "after"],
// We should fix the errors and enable this (set to 2)
"no-var": 0,
"strict": [2, "global"]
}
}

View File

@ -1,6 +1,8 @@
/* Any copyright is dedicated to the Public Domain. /* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */ http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const {CardDavImporter} = Cu.import("resource:///modules/loop/CardDavImporter.jsm", {}); const {CardDavImporter} = Cu.import("resource:///modules/loop/CardDavImporter.jsm", {});
const kAuth = { const kAuth = {

View File

@ -1,6 +1,8 @@
/* Any copyright is dedicated to the Public Domain. /* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */ http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const {GoogleImporter} = Cu.import("resource:///modules/loop/GoogleImporter.jsm", {}); const {GoogleImporter} = Cu.import("resource:///modules/loop/GoogleImporter.jsm", {});
let importer = new GoogleImporter(); let importer = new GoogleImporter();

View File

@ -1,6 +1,8 @@
/* Any copyright is dedicated to the Public Domain. /* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */ http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const {LoopContacts} = Cu.import("resource:///modules/loop/LoopContacts.jsm", {}); const {LoopContacts} = Cu.import("resource:///modules/loop/LoopContacts.jsm", {});
const {LoopStorage} = Cu.import("resource:///modules/loop/LoopStorage.jsm", {}); const {LoopStorage} = Cu.import("resource:///modules/loop/LoopStorage.jsm", {});
@ -221,8 +223,13 @@ add_task(function* () {
Assert.ok(!err, "There shouldn't be an error"); Assert.ok(!err, "There shouldn't be an error");
Assert.equal(result.length, toRetrieve.length, "Result list should be the same " + Assert.equal(result.length, toRetrieve.length, "Result list should be the same " +
"size as the list of items to retrieve"); "size as the list of items to retrieve");
function resultFilter(c) {
return c._guid == this._guid;
}
for (let contact of toRetrieve) { for (let contact of toRetrieve) {
let found = result.filter(c => c._guid == contact._guid); let found = result.filter(resultFilter.bind(contact));
Assert.ok(found.length, "Contact " + contact._guid + " should be in the list"); Assert.ok(found.length, "Contact " + contact._guid + " should be in the list");
compareContacts(found[0], contact); compareContacts(found[0], contact);
} }

View File

@ -6,6 +6,8 @@
* effects - rather than just testing MozLoopAPI alone. * effects - rather than just testing MozLoopAPI alone.
*/ */
"use strict";
Components.utils.import("resource://gre/modules/Promise.jsm", this); Components.utils.import("resource://gre/modules/Promise.jsm", this);
add_task(loadLoopPanel); add_task(loadLoopPanel);

View File

@ -6,6 +6,8 @@
* effects - rather than just testing MozLoopAPI alone. * effects - rather than just testing MozLoopAPI alone.
*/ */
"use strict";
Components.utils.import("resource://gre/modules/Promise.jsm", this); Components.utils.import("resource://gre/modules/Promise.jsm", this);
add_task(loadLoopPanel); add_task(loadLoopPanel);

View File

@ -1,21 +1,23 @@
/* Any copyright is dedicated to the Public Domain. /* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */ http://creativecommons.org/publicdomain/zero/1.0/ */
/** /**
* This is an integration test from navigator.mozLoop through to the end * This is an integration test from navigator.mozLoop through to the end
* effects - rather than just testing MozLoopAPI alone. * effects - rather than just testing MozLoopAPI alone.
*/ */
Components.utils.import("resource://gre/modules/Promise.jsm", this); "use strict";
add_task(loadLoopPanel); Components.utils.import("resource://gre/modules/Promise.jsm", this);
add_task(function* test_mozLoop_pluralStrings() { add_task(loadLoopPanel);
Assert.ok(gMozLoopAPI, "mozLoop should exist");
add_task(function* test_mozLoop_pluralStrings() {
var strings = JSON.parse(gMozLoopAPI.getStrings("feedback_window_will_close_in2")); Assert.ok(gMozLoopAPI, "mozLoop should exist");
Assert.equal(gMozLoopAPI.getPluralForm(0, strings.textContent),
"This window will close in {{countdown}} seconds"); var strings = JSON.parse(gMozLoopAPI.getStrings("feedback_window_will_close_in2"));
Assert.equal(gMozLoopAPI.getPluralForm(1, strings.textContent), Assert.equal(gMozLoopAPI.getPluralForm(0, strings.textContent),
"This window will close in {{countdown}} second"); "This window will close in {{countdown}} seconds");
}); Assert.equal(gMozLoopAPI.getPluralForm(1, strings.textContent),
"This window will close in {{countdown}} second");
});

View File

@ -6,6 +6,8 @@
* effects - rather than just testing MozLoopAPI alone. * effects - rather than just testing MozLoopAPI alone.
*/ */
"use strict";
Components.utils.import("resource://gre/modules/Promise.jsm", this); Components.utils.import("resource://gre/modules/Promise.jsm", this);
add_task(loadLoopPanel); add_task(loadLoopPanel);

View File

@ -6,6 +6,8 @@
* effects - rather than just testing MozLoopAPI alone. * effects - rather than just testing MozLoopAPI alone.
*/ */
"use strict";
Cu.import("resource://gre/modules/Promise.jsm"); Cu.import("resource://gre/modules/Promise.jsm");
const {SocialService} = Cu.import("resource://gre/modules/SocialService.jsm", {}); const {SocialService} = Cu.import("resource://gre/modules/SocialService.jsm", {});

View File

@ -4,6 +4,9 @@
/* /*
* This file contains tests for the mozLoop telemetry API. * This file contains tests for the mozLoop telemetry API.
*/ */
"use strict";
Components.utils.import("resource://gre/modules/Promise.jsm", this); Components.utils.import("resource://gre/modules/Promise.jsm", this);
add_task(loadLoopPanel); add_task(loadLoopPanel);
@ -23,7 +26,7 @@ add_task(function* test_initialize() {
* Tests that enumerated bucket histograms exist and can be updated. * Tests that enumerated bucket histograms exist and can be updated.
*/ */
add_task(function* test_mozLoop_telemetryAdd_buckets() { add_task(function* test_mozLoop_telemetryAdd_buckets() {
let histogramId = "LOOP_TWO_WAY_MEDIA_CONN_LENGTH"; let histogramId = "LOOP_TWO_WAY_MEDIA_CONN_LENGTH_1";
let histogram = Services.telemetry.getHistogramById(histogramId); let histogram = Services.telemetry.getHistogramById(histogramId);
let CONN_LENGTH = gMozLoopAPI.TWO_WAY_MEDIA_CONN_LENGTH; let CONN_LENGTH = gMozLoopAPI.TWO_WAY_MEDIA_CONN_LENGTH;
@ -49,7 +52,7 @@ add_task(function* test_mozLoop_telemetryAdd_buckets() {
}); });
add_task(function* test_mozLoop_telemetryAdd_sharing_buckets() { add_task(function* test_mozLoop_telemetryAdd_sharing_buckets() {
let histogramId = "LOOP_SHARING_STATE_CHANGE"; let histogramId = "LOOP_SHARING_STATE_CHANGE_1";
let histogram = Services.telemetry.getHistogramById(histogramId); let histogram = Services.telemetry.getHistogramById(histogramId);
const SHARING_STATES = gMozLoopAPI.SHARING_STATE_CHANGE; const SHARING_STATES = gMozLoopAPI.SHARING_STATE_CHANGE;

View File

@ -1,6 +1,8 @@
/* Any copyright is dedicated to the Public Domain. /* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */ http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const HAWK_TOKEN_LENGTH = 64; const HAWK_TOKEN_LENGTH = 64;
const { const {
LOOP_SESSION_TYPE, LOOP_SESSION_TYPE,
@ -123,8 +125,8 @@ function loadLoopPanel(aOverrideOptions = {}) {
let loopPanel = document.getElementById("loop-notification-panel"); let loopPanel = document.getElementById("loop-notification-panel");
loopPanel.setAttribute("animate", "false"); loopPanel.setAttribute("animate", "false");
// Now get the actual API. // Now get the actual API loaded into gMozLoopAPI.
yield promiseGetMozLoopAPI(); return promiseGetMozLoopAPI();
} }
function promiseOAuthParamsSetup(baseURL, params) { function promiseOAuthParamsSetup(baseURL, params) {
@ -319,7 +321,7 @@ const mockDb = {
callback(null, details); callback(null, details);
}, },
remove: function(guid, callback) { remove: function(guid, callback) {
if (!guid in this._store) { if (!(guid in this._store)) {
callback(new Error("Could not find _guid '" + guid + "' in database")); callback(new Error("Could not find _guid '" + guid + "' in database"));
return; return;
} }

View File

@ -473,7 +473,7 @@ describe("loop.OTSdkDriver", function () {
sinon.assert.calledOnce(mozLoop.telemetryAddValue); sinon.assert.calledOnce(mozLoop.telemetryAddValue);
sinon.assert.calledWith(mozLoop.telemetryAddValue, sinon.assert.calledWith(mozLoop.telemetryAddValue,
"LOOP_TWO_WAY_MEDIA_CONN_LENGTH", "LOOP_TWO_WAY_MEDIA_CONN_LENGTH_1",
mozLoop.TWO_WAY_MEDIA_CONN_LENGTH.SHORTER_THAN_10S); mozLoop.TWO_WAY_MEDIA_CONN_LENGTH.SHORTER_THAN_10S);
}); });
@ -485,7 +485,7 @@ describe("loop.OTSdkDriver", function () {
sinon.assert.calledOnce(mozLoop.telemetryAddValue); sinon.assert.calledOnce(mozLoop.telemetryAddValue);
sinon.assert.calledWith(mozLoop.telemetryAddValue, sinon.assert.calledWith(mozLoop.telemetryAddValue,
"LOOP_TWO_WAY_MEDIA_CONN_LENGTH", "LOOP_TWO_WAY_MEDIA_CONN_LENGTH_1",
mozLoop.TWO_WAY_MEDIA_CONN_LENGTH.BETWEEN_10S_AND_30S); mozLoop.TWO_WAY_MEDIA_CONN_LENGTH.BETWEEN_10S_AND_30S);
}); });
@ -497,7 +497,7 @@ describe("loop.OTSdkDriver", function () {
sinon.assert.calledOnce(mozLoop.telemetryAddValue); sinon.assert.calledOnce(mozLoop.telemetryAddValue);
sinon.assert.calledWith(mozLoop.telemetryAddValue, sinon.assert.calledWith(mozLoop.telemetryAddValue,
"LOOP_TWO_WAY_MEDIA_CONN_LENGTH", "LOOP_TWO_WAY_MEDIA_CONN_LENGTH_1",
mozLoop.TWO_WAY_MEDIA_CONN_LENGTH.BETWEEN_30S_AND_5M); mozLoop.TWO_WAY_MEDIA_CONN_LENGTH.BETWEEN_30S_AND_5M);
}); });
@ -508,7 +508,7 @@ describe("loop.OTSdkDriver", function () {
sinon.assert.calledOnce(mozLoop.telemetryAddValue); sinon.assert.calledOnce(mozLoop.telemetryAddValue);
sinon.assert.calledWith(mozLoop.telemetryAddValue, sinon.assert.calledWith(mozLoop.telemetryAddValue,
"LOOP_TWO_WAY_MEDIA_CONN_LENGTH", "LOOP_TWO_WAY_MEDIA_CONN_LENGTH_1",
mozLoop.TWO_WAY_MEDIA_CONN_LENGTH.MORE_THAN_5M); mozLoop.TWO_WAY_MEDIA_CONN_LENGTH.MORE_THAN_5M);
}); });
@ -530,7 +530,7 @@ describe("loop.OTSdkDriver", function () {
sinon.assert.calledOnce(mozLoop.telemetryAddValue); sinon.assert.calledOnce(mozLoop.telemetryAddValue);
sinon.assert.calledWithExactly(mozLoop.telemetryAddValue, sinon.assert.calledWithExactly(mozLoop.telemetryAddValue,
"LOOP_SHARING_STATE_CHANGE", "LOOP_SHARING_STATE_CHANGE_1",
mozLoop.SHARING_STATE_CHANGE.WINDOW_ENABLED); mozLoop.SHARING_STATE_CHANGE.WINDOW_ENABLED);
}); });
@ -539,7 +539,7 @@ describe("loop.OTSdkDriver", function () {
sinon.assert.calledOnce(mozLoop.telemetryAddValue); sinon.assert.calledOnce(mozLoop.telemetryAddValue);
sinon.assert.calledWithExactly(mozLoop.telemetryAddValue, sinon.assert.calledWithExactly(mozLoop.telemetryAddValue,
"LOOP_SHARING_STATE_CHANGE", "LOOP_SHARING_STATE_CHANGE_1",
mozLoop.SHARING_STATE_CHANGE.BROWSER_ENABLED); mozLoop.SHARING_STATE_CHANGE.BROWSER_ENABLED);
}); });
@ -548,7 +548,7 @@ describe("loop.OTSdkDriver", function () {
sinon.assert.calledOnce(mozLoop.telemetryAddValue); sinon.assert.calledOnce(mozLoop.telemetryAddValue);
sinon.assert.calledWithExactly(mozLoop.telemetryAddValue, sinon.assert.calledWithExactly(mozLoop.telemetryAddValue,
"LOOP_SHARING_STATE_CHANGE", "LOOP_SHARING_STATE_CHANGE_1",
mozLoop.SHARING_STATE_CHANGE.WINDOW_DISABLED); mozLoop.SHARING_STATE_CHANGE.WINDOW_DISABLED);
}); });
@ -557,7 +557,7 @@ describe("loop.OTSdkDriver", function () {
sinon.assert.calledOnce(mozLoop.telemetryAddValue); sinon.assert.calledOnce(mozLoop.telemetryAddValue);
sinon.assert.calledWithExactly(mozLoop.telemetryAddValue, sinon.assert.calledWithExactly(mozLoop.telemetryAddValue,
"LOOP_SHARING_STATE_CHANGE", "LOOP_SHARING_STATE_CHANGE_1",
mozLoop.SHARING_STATE_CHANGE.BROWSER_DISABLED); mozLoop.SHARING_STATE_CHANGE.BROWSER_DISABLED);
}); });
}); });

View File

@ -145,6 +145,31 @@ describe("loop.shared.utils", function() {
}); });
}); });
describe("#formatURL", function() {
it("should decode encoded URIs", function() {
expect(sharedUtils.formatURL("http://invalid.com/?a=Foo%20Bar"))
.eql({
location: "http://invalid.com/?a=Foo Bar",
hostname: "invalid.com"
});
});
it("should change some idn urls to ascii encoded", function() {
// Note, this is based on the browser's list of what does/doesn't get
// altered for punycode, so if the list changes this could change in the
// future.
expect(sharedUtils.formatURL("http://\u0261oogle.com/"))
.eql({
location: "http://xn--oogle-qmc.com/",
hostname: "xn--oogle-qmc.com"
});
});
it("should return null if it the url is not valid", function() {
expect(sharedUtils.formatURL("hinvalid//url")).eql(null);
});
});
describe("#composeCallUrlEmail", function() { describe("#composeCallUrlEmail", function() {
var composeEmail; var composeEmail;

View File

@ -13,6 +13,7 @@ describe("loop.standaloneRoomViews", function() {
var FEEDBACK_STATES = loop.store.FEEDBACK_STATES; var FEEDBACK_STATES = loop.store.FEEDBACK_STATES;
var ROOM_INFO_FAILURES = loop.shared.utils.ROOM_INFO_FAILURES; var ROOM_INFO_FAILURES = loop.shared.utils.ROOM_INFO_FAILURES;
var sharedActions = loop.shared.actions; var sharedActions = loop.shared.actions;
var sharedUtils = loop.shared.utils;
var sandbox, dispatcher, activeRoomStore, feedbackStore, dispatch; var sandbox, dispatcher, activeRoomStore, feedbackStore, dispatch;
@ -96,6 +97,26 @@ describe("loop.standaloneRoomViews", function() {
expect(view.getDOMNode().querySelector(".standalone-context-url")).not.eql(null); expect(view.getDOMNode().querySelector(".standalone-context-url")).not.eql(null);
}); });
it("should format the url for display", function() {
sandbox.stub(sharedUtils, "formatURL").returns({
location: "location",
hostname: "hostname"
});
var view = mountTestComponent({
roomName: "Mike's room",
roomContextUrls: [{
description: "Mark's super page",
location: "http://invalid.com",
thumbnail: "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
}]
});
expect(view.getDOMNode()
.querySelector(".standalone-context-url-description-wrapper > a").textContent)
.eql("hostname");
});
it("should not display context information if no urls are supplied", function() { it("should not display context information if no urls are supplied", function() {
var view = mountTestComponent({ var view = mountTestComponent({
roomName: "Mike's room" roomName: "Mike's room"

View File

@ -0,0 +1,17 @@
{
"ecmaFeatures": {
"arrowFunctions": true,
"blockBindings": true,
"destructuring": true,
"generators": true,
"restParams": true,
"spread": true,
"objectLiteralShorthandMethods": true,
},
"rules": {
"generator-star-spacing": [2, "after"],
// We should fix the errors and enable this (set to 2)
"no-var": 0,
"strict": [2, "global"]
}
}

View File

@ -1,6 +1,8 @@
/* Any copyright is dedicated to the Public Domain. /* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */ http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm");

View File

@ -1,222 +1,223 @@
/* Any copyright is dedicated to the Public Domain. /* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */ http://creativecommons.org/publicdomain/zero/1.0/ */
{
let dummyCallback = () => {};
let mockWebSocket = new MockWebSocketChannel();
let pushServerRequestCount = 0;
add_test(function test_initalize_offline() { "use strict";
Services.io.offline = true;
do_check_false(MozLoopPushHandler.initialize());
Services.io.offline = false;
run_next_test();
});
add_test(function test_initalize_missing_chanid() { let dummyCallback = () => {};
Assert.throws(() => MozLoopPushHandler.register(null, dummyCallback, dummyCallback)); let mockWebSocket = new MockWebSocketChannel();
run_next_test(); let pushServerRequestCount = 0;
});
add_test(function test_initalize_missing_regcallback() { add_test(function test_initalize_offline() {
Assert.throws(() => MozLoopPushHandler.register("chan-1", null, dummyCallback)); Services.io.offline = true;
run_next_test(); do_check_false(MozLoopPushHandler.initialize());
}); Services.io.offline = false;
run_next_test();
});
add_test(function test_initalize_missing_notifycallback() { add_test(function test_initalize_missing_chanid() {
Assert.throws(() => MozLoopPushHandler.register("chan-1", dummyCallback, null)); Assert.throws(() => MozLoopPushHandler.register(null, dummyCallback, dummyCallback));
run_next_test(); run_next_test();
}); });
add_test(function test_initalize_websocket() { add_test(function test_initalize_missing_regcallback() {
do_check_true(MozLoopPushHandler.initialize({mockWebSocket: mockWebSocket})); Assert.throws(() => MozLoopPushHandler.register("chan-1", null, dummyCallback));
MozLoopPushHandler.register( run_next_test();
"chan-1", });
function(err, url, id) {
Assert.equal(err, null, "err should be null to indicate success");
Assert.equal(url, kEndPointUrl, "Should return push server application URL");
Assert.equal(id, "chan-1", "Should have channel id = chan-1");
Assert.equal(mockWebSocket.uri.prePath, kServerPushUrl,
"Should have the url from preferences");
Assert.equal(mockWebSocket.origin, kServerPushUrl,
"Should have the origin url from preferences");
Assert.equal(mockWebSocket.protocol, "push-notification",
"Should have the protocol set to push-notifications");
mockWebSocket.notify(15);
},
function(version, id) {
Assert.equal(version, 15, "Should have version number 15");
Assert.equal(id, "chan-1", "Should have channel id = chan-1");
run_next_test();
});
});
add_test(function test_register_twice_same_channel() { add_test(function test_initalize_missing_notifycallback() {
MozLoopPushHandler.register( Assert.throws(() => MozLoopPushHandler.register("chan-1", dummyCallback, null));
"chan-2", run_next_test();
function(err, url, id) { });
Assert.equal(err, null, "Should return null for success");
Assert.equal(url, kEndPointUrl, "Should return push server application URL");
Assert.equal(id, "chan-2", "Should have channel id = chan-2");
Assert.equal(mockWebSocket.uri.prePath, kServerPushUrl,
"Should have the url from preferences");
Assert.equal(mockWebSocket.origin, kServerPushUrl,
"Should have the origin url from preferences");
Assert.equal(mockWebSocket.protocol, "push-notification",
"Should have the protocol set to push-notifications");
// Register again for the same channel add_test(function test_initalize_websocket() {
MozLoopPushHandler.register( do_check_true(MozLoopPushHandler.initialize({mockWebSocket: mockWebSocket}));
"chan-2", MozLoopPushHandler.register(
function(err, url, id) { "chan-1",
Assert.equal(err, null, "Should return null for success"); function(err, url, id) {
Assert.equal(id, "chan-2", "Should have channel id = chan-2"); Assert.equal(err, null, "err should be null to indicate success");
run_next_test(); Assert.equal(url, kEndPointUrl, "Should return push server application URL");
}, Assert.equal(id, "chan-1", "Should have channel id = chan-1");
dummyCallback Assert.equal(mockWebSocket.uri.prePath, kServerPushUrl,
); "Should have the url from preferences");
}, Assert.equal(mockWebSocket.origin, kServerPushUrl,
dummyCallback "Should have the origin url from preferences");
); Assert.equal(mockWebSocket.protocol, "push-notification",
}); "Should have the protocol set to push-notifications");
mockWebSocket.notify(15);
// Test that the PushHander will re-connect after the near-end disconnect. },
// The uaID is cleared to force re-registration of all notification channels. function(version, id) {
add_test(function test_reconnect_websocket() { Assert.equal(version, 15, "Should have version number 15");
MozLoopPushHandler.uaID = undefined; Assert.equal(id, "chan-1", "Should have channel id = chan-1");
mockWebSocket.stop(); run_next_test();
// Previously registered onRegistration callbacks will fire and be checked (see above).
});
// Test that the PushHander will re-connect after the far-end disconnect.
// The uaID is cleared to force re-regsitration of all notification channels.
add_test(function test_reopen_websocket() {
MozLoopPushHandler.uaID = undefined;
MozLoopPushHandler.registeredChannels = {}; //Do this to force a new registration callback.
mockWebSocket.serverClose();
// Previously registered onRegistration callbacks will fire and be checked (see above).
});
// Force a re-registration cycle and have the PushServer return a 500.
// A retry should occur and the registration then complete.
add_test(function test_retry_registration() {
MozLoopPushHandler.uaID = undefined;
mockWebSocket.initRegStatus = 500;
mockWebSocket.stop();
});
add_test(function test_reconnect_no_registration() {
let regCnt = 0;
MozLoopPushHandler.shutdown();
MozLoopPushHandler.initialize({mockWebSocket: mockWebSocket});
MozLoopPushHandler.register(
"test-chan",
function(err, url, id) {
Assert.equal(++regCnt, 1, "onRegistered should only be called once");
Assert.equal(err, null, "err should be null to indicate success");
Assert.equal(url, kEndPointUrl, "Should return push server application URL");
Assert.equal(id, "test-chan", "Should have channel id = test-chan");
mockWebSocket.stop();
setTimeout(run_next_test(), 0);
},
dummyCallback
);
});
add_test(function test_ping_websocket() {
let pingReceived = false,
socketClosed = false;
mockWebSocket.defaultMsgHandler = (msg) => {
pingReceived = true;
// Do not send a ping response.
}
mockWebSocket.close = () => {
socketClosed = true;
}
MozLoopPushHandler.shutdown();
MozLoopPushHandler.initialize({mockWebSocket: mockWebSocket});
MozLoopPushHandler.register(
"test-chan",
function(err, url) {
Assert.equal(err, null, "err should be null to indicate success");
waitForCondition(() => pingReceived).then(() => {
waitForCondition(() => socketClosed).then(() => {
run_next_test();
}, () => {
do_throw("should have closed the websocket");
});
}, () => {
do_throw("should have sent ping");
});
},
dummyCallback
);
});
add_test(function test_retry_pushurl() {
MozLoopPushHandler.shutdown();
loopServer.registerPathHandler("/push-server-config", (request, response) => {
// The PushHandler should retry the request for the push-server-config for
// each of these cases without throwing an error.
let n = 0;
switch (++pushServerRequestCount) {
case ++n:
// Non-200 response
response.setStatusLine(null, 500, "Retry");
response.processAsync();
response.finish();
break;
case ++n:
// missing parameter
response.setStatusLine(null, 200, "OK");
response.write(JSON.stringify({pushServerURI: null}));
response.processAsync();
response.finish();
break;
case ++n:
// json parse error
response.setStatusLine(null, 200, "OK");
response.processAsync();
response.finish();
break;
case ++n:
response.setStatusLine(null, 200, "OK");
response.write(JSON.stringify({pushServerURI: kServerPushUrl}));
response.processAsync();
response.finish();
run_next_test();
break;
}
}); });
});
do_check_true(MozLoopPushHandler.initialize({mockWebSocket: mockWebSocket})); add_test(function test_register_twice_same_channel() {
}); MozLoopPushHandler.register(
"chan-2",
function(err, url, id) {
Assert.equal(err, null, "Should return null for success");
Assert.equal(url, kEndPointUrl, "Should return push server application URL");
Assert.equal(id, "chan-2", "Should have channel id = chan-2");
Assert.equal(mockWebSocket.uri.prePath, kServerPushUrl,
"Should have the url from preferences");
Assert.equal(mockWebSocket.origin, kServerPushUrl,
"Should have the origin url from preferences");
Assert.equal(mockWebSocket.protocol, "push-notification",
"Should have the protocol set to push-notifications");
function run_test() { // Register again for the same channel
setupFakeLoopServer(); MozLoopPushHandler.register(
"chan-2",
function(err, url, id) {
Assert.equal(err, null, "Should return null for success");
Assert.equal(id, "chan-2", "Should have channel id = chan-2");
run_next_test();
},
dummyCallback
);
},
dummyCallback
);
});
loopServer.registerPathHandler("/push-server-config", (request, response) => { // Test that the PushHander will re-connect after the near-end disconnect.
// The uaID is cleared to force re-registration of all notification channels.
add_test(function test_reconnect_websocket() {
MozLoopPushHandler.uaID = undefined;
mockWebSocket.stop();
// Previously registered onRegistration callbacks will fire and be checked (see above).
});
// Test that the PushHander will re-connect after the far-end disconnect.
// The uaID is cleared to force re-regsitration of all notification channels.
add_test(function test_reopen_websocket() {
MozLoopPushHandler.uaID = undefined;
MozLoopPushHandler.registeredChannels = {}; //Do this to force a new registration callback.
mockWebSocket.serverClose();
// Previously registered onRegistration callbacks will fire and be checked (see above).
});
// Force a re-registration cycle and have the PushServer return a 500.
// A retry should occur and the registration then complete.
add_test(function test_retry_registration() {
MozLoopPushHandler.uaID = undefined;
mockWebSocket.initRegStatus = 500;
mockWebSocket.stop();
});
add_test(function test_reconnect_no_registration() {
let regCnt = 0;
MozLoopPushHandler.shutdown();
MozLoopPushHandler.initialize({mockWebSocket: mockWebSocket});
MozLoopPushHandler.register(
"test-chan",
function(err, url, id) {
Assert.equal(++regCnt, 1, "onRegistered should only be called once");
Assert.equal(err, null, "err should be null to indicate success");
Assert.equal(url, kEndPointUrl, "Should return push server application URL");
Assert.equal(id, "test-chan", "Should have channel id = test-chan");
mockWebSocket.stop();
setTimeout(run_next_test(), 0);
},
dummyCallback
);
});
add_test(function test_ping_websocket() {
let pingReceived = false,
socketClosed = false;
mockWebSocket.defaultMsgHandler = (msg) => {
pingReceived = true;
// Do not send a ping response.
}
mockWebSocket.close = () => {
socketClosed = true;
}
MozLoopPushHandler.shutdown();
MozLoopPushHandler.initialize({mockWebSocket: mockWebSocket});
MozLoopPushHandler.register(
"test-chan",
function(err, url) {
Assert.equal(err, null, "err should be null to indicate success");
waitForCondition(() => pingReceived).then(() => {
waitForCondition(() => socketClosed).then(() => {
run_next_test();
}, () => {
do_throw("should have closed the websocket");
});
}, () => {
do_throw("should have sent ping");
});
},
dummyCallback
);
});
add_test(function test_retry_pushurl() {
MozLoopPushHandler.shutdown();
loopServer.registerPathHandler("/push-server-config", (request, response) => {
// The PushHandler should retry the request for the push-server-config for
// each of these cases without throwing an error.
let n = 0;
switch (++pushServerRequestCount) {
case ++n:
// Non-200 response
response.setStatusLine(null, 500, "Retry");
response.processAsync();
response.finish();
break;
case ++n:
// missing parameter
response.setStatusLine(null, 200, "OK");
response.write(JSON.stringify({pushServerURI: null}));
response.processAsync();
response.finish();
break;
case ++n:
// json parse error
response.setStatusLine(null, 200, "OK");
response.processAsync();
response.finish();
break;
case ++n:
response.setStatusLine(null, 200, "OK"); response.setStatusLine(null, 200, "OK");
response.write(JSON.stringify({pushServerURI: kServerPushUrl})); response.write(JSON.stringify({pushServerURI: kServerPushUrl}));
response.processAsync(); response.processAsync();
response.finish(); response.finish();
});
Services.prefs.setCharPref("services.push.serverURL", kServerPushUrl); run_next_test();
Services.prefs.setIntPref("loop.retry_delay.start", 10); // 10 ms break;
Services.prefs.setIntPref("loop.retry_delay.limit", 20); // 20 ms }
Services.prefs.setIntPref("loop.ping.interval", 50); // 50 ms });
Services.prefs.setIntPref("loop.ping.timeout", 20); // 20 ms
do_register_cleanup(function() { do_check_true(MozLoopPushHandler.initialize({mockWebSocket: mockWebSocket}));
Services.prefs.clearUserPref("services.push.serverULR"); });
Services.prefs.clearUserPref("loop.retry_delay.start");
Services.prefs.clearUserPref("loop.retry_delay.limit");
Services.prefs.clearUserPref("loop.ping.interval");
Services.prefs.clearUserPref("loop.ping.timeout");
});
run_next_test(); function run_test() {
}; setupFakeLoopServer();
}
loopServer.registerPathHandler("/push-server-config", (request, response) => {
response.setStatusLine(null, 200, "OK");
response.write(JSON.stringify({pushServerURI: kServerPushUrl}));
response.processAsync();
response.finish();
});
Services.prefs.setCharPref("services.push.serverURL", kServerPushUrl);
Services.prefs.setIntPref("loop.retry_delay.start", 10); // 10 ms
Services.prefs.setIntPref("loop.retry_delay.limit", 20); // 20 ms
Services.prefs.setIntPref("loop.ping.interval", 50); // 50 ms
Services.prefs.setIntPref("loop.ping.timeout", 20); // 20 ms
do_register_cleanup(function() {
Services.prefs.clearUserPref("services.push.serverULR");
Services.prefs.clearUserPref("loop.retry_delay.start");
Services.prefs.clearUserPref("loop.retry_delay.limit");
Services.prefs.clearUserPref("loop.ping.interval");
Services.prefs.clearUserPref("loop.ping.timeout");
});
run_next_test();
};

View File

@ -2,6 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file, * 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/. */ * You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
Cu.import("resource://services-common/utils.js"); Cu.import("resource://services-common/utils.js");
Cu.import("resource:///modules/loop/LoopRooms.jsm"); Cu.import("resource:///modules/loop/LoopRooms.jsm");
Cu.import("resource:///modules/Chat.jsm"); Cu.import("resource:///modules/Chat.jsm");

View File

@ -2,6 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file, * 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/. */ * You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { LoopCallsInternal } = Cu.import("resource:///modules/loop/LoopCalls.jsm", {}); const { LoopCallsInternal } = Cu.import("resource:///modules/loop/LoopCalls.jsm", {});
XPCOMUtils.defineLazyModuleGetter(this, "Chat", XPCOMUtils.defineLazyModuleGetter(this, "Chat",

View File

@ -2,6 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file, * 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/. */ * You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
XPCOMUtils.defineLazyModuleGetter(this, "Chat", XPCOMUtils.defineLazyModuleGetter(this, "Chat",
"resource:///modules/Chat.jsm"); "resource:///modules/Chat.jsm");
let openChatOrig = Chat.open; let openChatOrig = Chat.open;

View File

@ -2,6 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file, * 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/. */ * You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
XPCOMUtils.defineLazyModuleGetter(this, "Chat", XPCOMUtils.defineLazyModuleGetter(this, "Chat",
"resource:///modules/Chat.jsm"); "resource:///modules/Chat.jsm");
let openChatOrig = Chat.open; let openChatOrig = Chat.open;
@ -41,7 +43,7 @@ add_test(function test_do_not_disturb_disabled_should_open_chat_window() {
mockPushHandler.notify(1, MozLoopService.channelIDs.callsFxA); mockPushHandler.notify(1, MozLoopService.channelIDs.callsFxA);
waitForCondition(function() opened).then(() => { waitForCondition(() => opened).then(() => {
run_next_test(); run_next_test();
}, () => { }, () => {
do_throw("should have opened a chat window"); do_throw("should have opened a chat window");

View File

@ -2,6 +2,8 @@
http://creativecommons.org/publicdomain/zero/1.0/ */ http://creativecommons.org/publicdomain/zero/1.0/ */
/* global Services, Assert */ /* global Services, Assert */
"use strict";
const kGuestKeyPref = "loop.key"; const kGuestKeyPref = "loop.key";
const kFxAKeyPref = "loop.key.fxa"; const kFxAKeyPref = "loop.key.fxa";

View File

@ -1,13 +1,15 @@
/* Any copyright is dedicated to the Public Domain. /* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */ http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
let startTimerCalled = false; let startTimerCalled = false;
/** /**
* Tests that registration doesn't happen when the expiry time is * Tests that registration doesn't happen when the expiry time is
* not set. * not set.
*/ */
add_task(function test_initialize_no_expiry() { add_task(function* test_initialize_no_expiry() {
startTimerCalled = false; startTimerCalled = false;
let initializedPromise = yield MozLoopService.initialize(); let initializedPromise = yield MozLoopService.initialize();

View File

@ -1,6 +1,8 @@
/* Any copyright is dedicated to the Public Domain. /* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */ http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
function test_locale() { function test_locale() {
// Set the pref to something controlled. // Set the pref to something controlled.
Services.prefs.setCharPref("general.useragent.locale", "ab-CD"); Services.prefs.setCharPref("general.useragent.locale", "ab-CD");

View File

@ -2,6 +2,8 @@
http://creativecommons.org/publicdomain/zero/1.0/ */ http://creativecommons.org/publicdomain/zero/1.0/ */
/*global XPCOMUtils, Services, Assert */ /*global XPCOMUtils, Services, Assert */
"use strict";
var fakeCharPrefName = "color"; var fakeCharPrefName = "color";
var fakeBoolPrefName = "boolean"; var fakeBoolPrefName = "boolean";
var fakePrefValue = "green"; var fakePrefValue = "green";

View File

@ -2,6 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file, * 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/. */ * You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
XPCOMUtils.defineLazyModuleGetter(this, "Chat", XPCOMUtils.defineLazyModuleGetter(this, "Chat",
"resource:///modules/Chat.jsm"); "resource:///modules/Chat.jsm");
@ -20,7 +22,7 @@ add_test(function test_openChatWindow_on_notification() {
mockPushHandler.notify(1, MozLoopService.channelIDs.callsFxA); mockPushHandler.notify(1, MozLoopService.channelIDs.callsFxA);
waitForCondition(function() opened).then(() => { waitForCondition(() => opened).then(() => {
do_check_true(opened, "should open a chat window"); do_check_true(opened, "should open a chat window");
do_check_eq(Services.prefs.getCharPref("loop.seenToS"), "seen", do_check_eq(Services.prefs.getCharPref("loop.seenToS"), "seen",

View File

@ -1,6 +1,8 @@
/* Any copyright is dedicated to the Public Domain. /* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */ http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
Cu.import("resource://services-common/utils.js"); Cu.import("resource://services-common/utils.js");
/** /**

View File

@ -1,6 +1,8 @@
/* Any copyright is dedicated to the Public Domain. /* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */ http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
Cu.import("resource://gre/modules/Task.jsm"); Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://services-common/utils.js"); Cu.import("resource://services-common/utils.js");

View File

@ -1,6 +1,8 @@
/* Any copyright is dedicated to the Public Domain. /* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */ http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const FAKE_FXA_TOKEN_DATA = JSON.stringify({ const FAKE_FXA_TOKEN_DATA = JSON.stringify({
"token_type": "bearer", "token_type": "bearer",
"access_token": "1bad3e44b12f77a88fe09f016f6a37c42e40f974bc7a8b432bb0d2f0e37e1752", "access_token": "1bad3e44b12f77a88fe09f016f6a37c42e40f974bc7a8b432bb0d2f0e37e1752",
@ -20,7 +22,7 @@ const LOOP_INITIAL_DELAY_PREF = "loop.initialDelay";
* This file is to test restart+reauth. * This file is to test restart+reauth.
*/ */
add_task(function test_initialize_with_no_guest_rooms_and_no_auth_token() { add_task(function* test_initialize_with_no_guest_rooms_and_no_auth_token() {
// Set time to be 2 seconds in the past. // Set time to be 2 seconds in the past.
var nowSeconds = Date.now() / 1000; var nowSeconds = Date.now() / 1000;
Services.prefs.setBoolPref(LOOP_CREATED_ROOM_PREF, false); Services.prefs.setBoolPref(LOOP_CREATED_ROOM_PREF, false);
@ -34,7 +36,7 @@ add_task(function test_initialize_with_no_guest_rooms_and_no_auth_token() {
}); });
}); });
add_task(function test_initialize_with_created_room_and_no_auth_token() { add_task(function* test_initialize_with_created_room_and_no_auth_token() {
Services.prefs.setBoolPref(LOOP_CREATED_ROOM_PREF, true); Services.prefs.setBoolPref(LOOP_CREATED_ROOM_PREF, true);
Services.prefs.clearUserPref(LOOP_FXA_TOKEN_PREF); Services.prefs.clearUserPref(LOOP_FXA_TOKEN_PREF);
@ -50,7 +52,7 @@ add_task(function test_initialize_with_created_room_and_no_auth_token() {
}); });
}); });
add_task(function test_initialize_with_invalid_fxa_token() { add_task(function* test_initialize_with_invalid_fxa_token() {
Services.prefs.setCharPref(LOOP_FXA_PROFILE_PREF, FAKE_FXA_PROFILE); Services.prefs.setCharPref(LOOP_FXA_PROFILE_PREF, FAKE_FXA_PROFILE);
Services.prefs.setCharPref(LOOP_FXA_TOKEN_PREF, FAKE_FXA_TOKEN_DATA); Services.prefs.setCharPref(LOOP_FXA_TOKEN_PREF, FAKE_FXA_TOKEN_DATA);
@ -83,7 +85,7 @@ add_task(function test_initialize_with_invalid_fxa_token() {
}); });
}); });
add_task(function test_initialize_with_fxa_token() { add_task(function* test_initialize_with_fxa_token() {
Services.prefs.setCharPref(LOOP_FXA_PROFILE_PREF, FAKE_FXA_PROFILE); Services.prefs.setCharPref(LOOP_FXA_PROFILE_PREF, FAKE_FXA_PROFILE);
Services.prefs.setCharPref(LOOP_FXA_TOKEN_PREF, FAKE_FXA_TOKEN_DATA); Services.prefs.setCharPref(LOOP_FXA_TOKEN_PREF, FAKE_FXA_TOKEN_DATA);

View File

@ -1,6 +1,8 @@
/* Any copyright is dedicated to the Public Domain. /* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */ http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const LOOP_HAWK_PREF = "loop.hawk-session-token"; const LOOP_HAWK_PREF = "loop.hawk-session-token";
const fakeSessionToken1 = "1bad3e44b12f77a88fe09f016f6a37c42e40f974bc7a8b432bb0d2f0e37e1751"; const fakeSessionToken1 = "1bad3e44b12f77a88fe09f016f6a37c42e40f974bc7a8b432bb0d2f0e37e1751";
const fakeSessionToken2 = "1bad3e44b12f77a88fe09f016f6a37c42e40f974bc7a8b432bb0d2f0e37e1750"; const fakeSessionToken2 = "1bad3e44b12f77a88fe09f016f6a37c42e40f974bc7a8b432bb0d2f0e37e1750";

View File

@ -1,6 +1,8 @@
/* Any copyright is dedicated to the Public Domain. /* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */ http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/** /**
* Test that things behave reasonably when a reasonable Hawk-Session-Token * Test that things behave reasonably when a reasonable Hawk-Session-Token
* header is returned with the registration response. * header is returned with the registration response.

View File

@ -1,6 +1,8 @@
/* Any copyright is dedicated to the Public Domain. /* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */ http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
add_test(function test_registration_uses_hawk_session_token() { add_test(function test_registration_uses_hawk_session_token() {
Services.prefs.setCharPref("loop.hawk-session-token", Services.prefs.setCharPref("loop.hawk-session-token",
"1bad3e44b12f77a88fe09f016f6a37c42e40f974bc7a8b432bb0d2f0e37e1750"); "1bad3e44b12f77a88fe09f016f6a37c42e40f974bc7a8b432bb0d2f0e37e1750");

View File

@ -1,6 +1,8 @@
/* Any copyright is dedicated to the Public Domain. /* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */ http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// XXX should report error if Hawk-Session-Token is lexically invalid // XXX should report error if Hawk-Session-Token is lexically invalid
// (not a string of 64 hex digits) to help resist other possible injection // (not a string of 64 hex digits) to help resist other possible injection
// attacks. For now, however, we're just checking if it's the right length. // attacks. For now, however, we're just checking if it's the right length.

View File

@ -1004,12 +1004,14 @@ let gEditItemOverlay = {
aLastModified, aItemType) { aLastModified, aItemType) {
if (aProperty == "tags" && this._paneInfo.visibleRows.has("tagsRow")) if (aProperty == "tags" && this._paneInfo.visibleRows.has("tagsRow"))
this._onTagsChange(aItemId); this._onTagsChange(aItemId);
else if (this._paneInfo.isItem && aProperty == "title") else if (!this._paneInfo.isItem || this._paneInfo.itemId != aItemId)
this._onItemTitleChange(aItemId, aValue);
else (!this._paneInfo.isItem || this._paneInfo.itemId != aItemId)
return; return;
switch (aProperty) { switch (aProperty) {
case "title":
if (this._paneInfo.isItem)
this._onItemTitleChange(aItemId, aValue);
break;
case "uri": case "uri":
let newURI = NetUtil.newURI(aValue); let newURI = NetUtil.newURI(aValue);
if (!newURI.equals(this._paneInfo.uri)) { if (!newURI.equals(this._paneInfo.uri)) {

View File

@ -1468,6 +1468,12 @@ this.UITour = {
showInfoPanel.bind(this, this._correctAnchor(aAnchor.node))); showInfoPanel.bind(this, this._correctAnchor(aAnchor.node)));
}, },
isInfoOnTarget(aChromeWindow, aTargetName) {
let document = aChromeWindow.document;
let tooltip = document.getElementById("UITourTooltip");
return tooltip.getAttribute("targetName") == aTargetName && tooltip.state != "closed";
},
hideInfo: function(aWindow) { hideInfo: function(aWindow) {
let document = aWindow.document; let document = aWindow.document;

View File

@ -26,6 +26,9 @@ loader.lazyRequireGetter(this, "MarkersOverview",
loader.lazyRequireGetter(this, "EventEmitter", loader.lazyRequireGetter(this, "EventEmitter",
"devtools/toolkit/event-emitter"); "devtools/toolkit/event-emitter");
// TODO get rid of retro mode in bug 1160313
loader.lazyRequireGetter(this, "Services");
/** /**
* For line graphs * For line graphs
*/ */
@ -165,6 +168,24 @@ const GRAPH_DEFINITIONS = {
} }
}; };
// TODO get rid of retro mode in bug 1160313
const GRAPH_DEFINITIONS_RETRO = {
memory: {
constructor: MemoryGraph,
selector: "#memory-overview",
},
framerate: {
constructor: FramerateGraph,
selector: "#time-framerate",
needsBlueprints: true,
primaryLink: true
},
timeline: {
constructor: TimelineGraph,
selector: "#markers-overview",
}
};
/** /**
* A controller for orchestrating the performance's tool overview graphs. Constructs, * A controller for orchestrating the performance's tool overview graphs. Constructs,
* syncs, toggles displays and defines the memory, framerate and timeline view. * syncs, toggles displays and defines the memory, framerate and timeline view.
@ -177,7 +198,9 @@ const GRAPH_DEFINITIONS = {
function GraphsController ({ definition, root, getBlueprint, getTheme }) { function GraphsController ({ definition, root, getBlueprint, getTheme }) {
this._graphs = {}; this._graphs = {};
this._enabled = new Set(); this._enabled = new Set();
this._definition = definition || GRAPH_DEFINITIONS; // TODO get rid of retro mode in bug 1160313
let RETRO_MODE = Services.prefs.getBoolPref("devtools.performance.ui.retro-mode");
this._definition = definition || (RETRO_MODE ? GRAPH_DEFINITIONS_RETRO : GRAPH_DEFINITIONS);
this._root = root; this._root = root;
this._getBlueprint = getBlueprint; this._getBlueprint = getBlueprint;
this._getTheme = getTheme; this._getTheme = getTheme;

View File

@ -284,11 +284,16 @@ let PerformanceController = {
* when the front has started to record. * when the front has started to record.
*/ */
startRecording: Task.async(function *() { startRecording: Task.async(function *() {
// Store retro-mode here so we can easily list true/false
// values for reverting.
// TODO bug 1160313
let superMode = !this.getOption("retro-mode");
let options = { let options = {
withMarkers: true, withMarkers: superMode ? true : false,
withMemory: this.getOption("enable-memory"), withMemory: superMode ? this.getOption("enable-memory") : false,
withTicks: this.getOption("enable-framerate"), withTicks: this.getOption("enable-framerate"),
withAllocations: this.getOption("enable-memory"), withAllocations: superMode ? this.getOption("enable-memory") : false,
allocationsSampleProbability: this.getPref("memory-sample-probability"), allocationsSampleProbability: this.getPref("memory-sample-probability"),
allocationsMaxLogLength: this.getPref("memory-max-log-length"), allocationsMaxLogLength: this.getPref("memory-max-log-length"),
bufferSize: this.getPref("profiler-buffer-size"), bufferSize: this.getPref("profiler-buffer-size"),

View File

@ -122,5 +122,10 @@ support-files =
[browser_profiler_tree-view-06.js] [browser_profiler_tree-view-06.js]
[browser_profiler_tree-view-07.js] [browser_profiler_tree-view-07.js]
[browser_profiler_tree-view-08.js] [browser_profiler_tree-view-08.js]
[browser_timeline_blueprint.js] [browser_timeline-blueprint.js]
[browser_timeline_filters.js] [browser_timeline-filters.js]
[browser_timeline-waterfall-background.js]
[browser_timeline-waterfall-generic.js]
[browser_timeline-waterfall-sidebar.js]
# remove in bug 1160313
[browser_retro-test.js]

View File

@ -0,0 +1,49 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that only js-calltree view is on, default, and many things are hidden
* when in retro mode.
*/
const HIDDEN_OPTIONS = ["option-enable-memory", "option-invert-flame-graph", "option-show-jit-optimizations", "option-flatten-tree-recursion"];
Services.prefs.setBoolPref("devtools.performance.ui.retro-mode", true);
function spawnTest () {
let { panel } = yield initPerformance(SIMPLE_URL);
let { EVENTS, DetailsView, PerformanceController, $, $$, JsCallTreeView } = panel.panelWin;
yield startRecording(panel);
yield stopRecording(panel);
let model = PerformanceController.getCurrentRecording();
ok(model.getMemory().length === 0, "model did not record memory.");
ok(model.getTicks().length !== 0, "model did get ticks.");
ok(model.getAllocations().sites.length === 0, "model did get allocation data.");
ok(model.getAllocations().timestamps.length === 0, "model did get allocation data.");
ok(model.getAllocations().frames.length === 0, "model did get allocation data.");
ok(model.getAllocations().counts.length === 0, "model did get allocation data.");
ok(DetailsView.isViewSelected(JsCallTreeView),
"The jscalltree view is selected by default");
for (let option of $$("#performance-options-menupopup > menuitem")) {
if (HIDDEN_OPTIONS.indexOf(option.id) !== -1) {
ok(option.hidden === true, `${option.id} should be hidden.`);
} else {
ok(option.hidden === false, `${option.id} should be visible.`);
}
}
for (let viewbutton of $$("#performance-toolbar-controls-detail-views > toolbarbutton")) {
ok (viewbutton.hidden === true, `${viewbutton.id} should be hidden.`);
}
ok($("#markers-overview").hidden, "markers overview should be hidden.");
ok($("#memory-overview").hidden, "memory overview should be hidden.");
ok(!$("#time-framerate").hidden, "framerate should be shown.");
yield teardown(panel);
finish();
}

View File

@ -0,0 +1,53 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if the waterfall background is a 1px high canvas stretching across
* the container bounds.
*/
function spawnTest () {
let { target, panel } = yield initPerformance(SIMPLE_URL);
let { $, EVENTS, PerformanceController, OverviewView, DetailsView, WaterfallView } = panel.panelWin;
yield startRecording(panel);
ok(true, "Recording has started.");
let updated = 0;
OverviewView.on(EVENTS.OVERVIEW_RENDERED, () => updated++);
ok((yield waitUntil(() => updated > 0)),
"The overview graphs were updated a bunch of times.");
ok((yield waitUntil(() => PerformanceController.getCurrentRecording().getMarkers().length > 0)),
"There are some markers available.");
let rendered = Promise.all([
DetailsView.selectView("waterfall"),
once(WaterfallView, EVENTS.WATERFALL_RENDERED)
]);
yield stopRecording(panel);
ok(true, "Recording has ended.");
yield rendered;
// Test the waterfall background.
let parentWidth = $("#waterfall-view").getBoundingClientRect().width;
let sidebarWidth = $(".waterfall-sidebar").getBoundingClientRect().width;
let detailsWidth = $("#waterfall-details").getBoundingClientRect().width;
let waterfallWidth = WaterfallView.waterfall._waterfallWidth;
is(waterfallWidth, parentWidth - sidebarWidth - detailsWidth,
"The waterfall width is correct.")
ok(WaterfallView.waterfall._canvas,
"A canvas should be created after the recording ended.");
ok(WaterfallView.waterfall._ctx,
"A 2d context should be created after the recording ended.");
is(WaterfallView.waterfall._canvas.width, waterfallWidth,
"The canvas width is correct.");
is(WaterfallView.waterfall._canvas.height, 1,
"The canvas height is correct.");
yield teardown(panel);
finish();
}

View File

@ -5,22 +5,22 @@
* Tests if the waterfall is properly built after finishing a recording. * Tests if the waterfall is properly built after finishing a recording.
*/ */
add_task(function*() { function spawnTest () {
let { target, panel } = yield initTimelinePanel(SIMPLE_URL); let { target, panel } = yield initPerformance(SIMPLE_URL);
let { $, $$, EVENTS, TimelineController } = panel.panelWin; let { $, $$, EVENTS, PerformanceController, OverviewView, WaterfallView } = panel.panelWin;
yield TimelineController.toggleRecording(); yield startRecording(panel);
ok(true, "Recording has started."); ok(true, "Recording has started.");
let updated = 0; let updated = 0;
panel.panelWin.on(EVENTS.OVERVIEW_UPDATED, () => updated++); OverviewView.on(EVENTS.OVERVIEW_RENDERED, () => updated++);
ok((yield waitUntil(() => updated > 0)), ok((yield waitUntil(() => updated > 0)),
"The overview graphs were updated a bunch of times."); "The overview graphs were updated a bunch of times.");
ok((yield waitUntil(() => TimelineController.getMarkers().length > 0)), ok((yield waitUntil(() => PerformanceController.getCurrentRecording().getMarkers().length > 0)),
"There are some markers available."); "There are some markers available.");
yield TimelineController.toggleRecording(); yield stopRecording(panel);
ok(true, "Recording has ended."); ok(true, "Recording has ended.");
// Test the header container. // Test the header container.
@ -62,4 +62,6 @@ add_task(function*() {
"Some marker waterfall nodes should have been created."); "Some marker waterfall nodes should have been created.");
ok($$(".waterfall-marker-item:not(spacer) > .waterfall-marker-bar").length, ok($$(".waterfall-marker-item:not(spacer) > .waterfall-marker-bar").length,
"Some marker color bars should have been created inside the waterfall."); "Some marker color bars should have been created inside the waterfall.");
}); yield teardown(panel);
finish();
}

View File

@ -5,35 +5,34 @@
* Tests if the sidebar is properly updated when a marker is selected. * Tests if the sidebar is properly updated when a marker is selected.
*/ */
add_task(function*() { function spawnTest () {
let { target, panel } = yield initTimelinePanel(SIMPLE_URL); let { target, panel } = yield initPerformance(SIMPLE_URL);
let { $, $$, EVENTS, TimelineController, TimelineView, TIMELINE_BLUEPRINT} = panel.panelWin; let { $, $$, EVENTS, PerformanceController, OverviewView } = panel.panelWin;
let { L10N } = devtools.require("devtools/shared/timeline/global"); let { L10N, TIMELINE_BLUEPRINT } = devtools.require("devtools/shared/timeline/global");
yield TimelineController.toggleRecording(); yield startRecording(panel);
ok(true, "Recording has started."); ok(true, "Recording has started.");
yield waitUntil(() => { yield waitUntil(() => {
// Wait until we get 3 different markers. // Wait until we get 3 different markers.
let markers = TimelineController.getMarkers(); let markers = PerformanceController.getCurrentRecording().getMarkers();
return markers.some(m => m.name == "Styles") && return markers.some(m => m.name == "Styles") &&
markers.some(m => m.name == "Reflow") && markers.some(m => m.name == "Reflow") &&
markers.some(m => m.name == "Paint"); markers.some(m => m.name == "Paint");
}); });
yield TimelineController.toggleRecording(); yield stopRecording(panel);
ok(true, "Recording has ended."); ok(true, "Recording has ended.");
// Select everything // Select everything
TimelineView.markersOverview.setSelection({ start: 0, end: TimelineView.markersOverview.width }) OverviewView.graphs.get("timeline").setSelection({ start: 0, end: OverviewView.graphs.get("timeline").width })
let bars = $$(".waterfall-marker-item:not(spacer) > .waterfall-marker-bar"); let bars = $$(".waterfall-marker-item:not(spacer) > .waterfall-marker-bar");
let markers = TimelineController.getMarkers(); let markers = PerformanceController.getCurrentRecording().getMarkers();
ok(bars.length > 2, "got at least 3 markers"); ok(bars.length > 2, "got at least 3 markers");
let sidebar = $("#timeline-waterfall-details"); let sidebar = $("#waterfall-details");
for (let i = 0; i < bars.length; i++) { for (let i = 0; i < bars.length; i++) {
let bar = bars[i]; let bar = bars[i];
bar.click(); bar.click();
@ -41,7 +40,7 @@ add_task(function*() {
let name = TIMELINE_BLUEPRINT[m.name].label; let name = TIMELINE_BLUEPRINT[m.name].label;
is($("#timeline-waterfall-details .marker-details-type").getAttribute("value"), name, is($("#waterfall-details .marker-details-type").getAttribute("value"), name,
"sidebar title matches markers name"); "sidebar title matches markers name");
let printedStartTime = $(".marker-details-start .marker-details-labelvalue").getAttribute("value"); let printedStartTime = $(".marker-details-start .marker-details-labelvalue").getAttribute("value");
@ -55,4 +54,6 @@ add_task(function*() {
is(toMs(m.end), printedEndTime, "sidebar end time is valid"); is(toMs(m.end), printedEndTime, "sidebar end time is valid");
is(toMs(m.end - m.start), printedDuration, "sidebar duration is valid"); is(toMs(m.end - m.start), printedDuration, "sidebar duration is valid");
} }
}); yield teardown(panel);
finish();
}

View File

@ -56,6 +56,7 @@ let DEFAULT_PREFS = [
"devtools.performance.memory.max-log-length", "devtools.performance.memory.max-log-length",
"devtools.performance.profiler.buffer-size", "devtools.performance.profiler.buffer-size",
"devtools.performance.profiler.sample-frequency-khz", "devtools.performance.profiler.sample-frequency-khz",
"devtools.performance.ui.retro-mode",
].reduce((prefs, pref) => { ].reduce((prefs, pref) => {
prefs[pref] = Preferences.get(pref); prefs[pref] = Preferences.get(pref);
return prefs; return prefs;
@ -67,6 +68,10 @@ Services.prefs.setBoolPref("devtools.performance.enabled", true);
// be affected by this pref. // be affected by this pref.
Services.prefs.setBoolPref("devtools.debugger.log", false); Services.prefs.setBoolPref("devtools.debugger.log", false);
// Disable retro mode.
// TODO bug 1160313
Services.prefs.setBoolPref("devtools.performance.ui.retro-mode", false);
/** /**
* Call manually in tests that use frame script utils after initializing * Call manually in tests that use frame script utils after initializing
* the tool. Must be called after initializing so we can detect * the tool. Must be called after initializing so we can detect

View File

@ -71,6 +71,12 @@ let DetailsSubview = {
*/ */
observedPrefs: [], observedPrefs: [],
/**
* Flag specifying if this view should update while the overview selection
* area is actively being dragged by the mouse.
*/
shouldUpdateWhileMouseIsActive: false,
/** /**
* Called when recording stops or is selected. * Called when recording stops or is selected.
*/ */
@ -90,7 +96,14 @@ let DetailsSubview = {
*/ */
_onOverviewRangeChange: function (_, interval) { _onOverviewRangeChange: function (_, interval) {
if (DetailsView.isViewSelected(this)) { if (DetailsView.isViewSelected(this)) {
let debounced = () => this.render(interval); let debounced = () => {
if (!this.shouldUpdateWhileMouseIsActive && OverviewView.isMouseActive) {
// Don't render yet, while the selection is still being dragged.
setNamedTimeout("range-change-debounce", this.rangeChangeDebounceTime, debounced);
} else {
this.render(interval);
}
};
setNamedTimeout("range-change-debounce", this.rangeChangeDebounceTime, debounced); setNamedTimeout("range-change-debounce", this.rangeChangeDebounceTime, debounced);
} else { } else {
this.shouldUpdateWhenShown = true; this.shouldUpdateWhenShown = true;

View File

@ -13,7 +13,7 @@ let JsCallTreeView = Heritage.extend(DetailsSubview, {
"show-platform-data" "show-platform-data"
], ],
rangeChangeDebounceTime: 50, // ms rangeChangeDebounceTime: 75, // ms
/** /**
* Sets up the view with event binding. * Sets up the view with event binding.

View File

@ -9,6 +9,8 @@
*/ */
let JsFlameGraphView = Heritage.extend(DetailsSubview, { let JsFlameGraphView = Heritage.extend(DetailsSubview, {
shouldUpdateWhileMouseIsActive: true,
rerenderPrefs: [ rerenderPrefs: [
"invert-flame-graph", "invert-flame-graph",
"flatten-tree-recursion", "flatten-tree-recursion",

View File

@ -9,6 +9,8 @@
*/ */
let MemoryFlameGraphView = Heritage.extend(DetailsSubview, { let MemoryFlameGraphView = Heritage.extend(DetailsSubview, {
shouldUpdateWhileMouseIsActive: true,
rerenderPrefs: [ rerenderPrefs: [
"invert-flame-graph", "invert-flame-graph",
"flatten-tree-recursion", "flatten-tree-recursion",

View File

@ -16,7 +16,7 @@ let WaterfallView = Heritage.extend(DetailsSubview, {
"hidden-markers" "hidden-markers"
], ],
rangeChangeDebounceTime: 10, // ms rangeChangeDebounceTime: 75, // ms
/** /**
* Sets up the view with event binding. * Sets up the view with event binding.
@ -74,6 +74,11 @@ let WaterfallView = Heritage.extend(DetailsSubview, {
*/ */
_onMarkerSelected: function (event, marker) { _onMarkerSelected: function (event, marker) {
let recording = PerformanceController.getCurrentRecording(); let recording = PerformanceController.getCurrentRecording();
// Race condition in tests due to lazy rendering of markers in the
// waterfall? intermittent bug 1157523
if (!recording) {
return;
}
let frames = recording.getFrames(); let frames = recording.getFrames();
if (event === "selected") { if (event === "selected") {

View File

@ -94,9 +94,12 @@ let DetailsView = {
let invalidCurrentView = false; let invalidCurrentView = false;
for (let [name, { view }] of Iterator(this.components)) { for (let [name, { view }] of Iterator(this.components)) {
let isSupported = this._isViewSupported(name, false); // TODO bug 1160313 get rid of retro mode checks.
let isRetro = PerformanceController.getOption("retro-mode");
let isSupported = isRetro ? name === "js-calltree" : this._isViewSupported(name, false);
$(`toolbarbutton[data-view=${name}]`).hidden = !isSupported; // TODO bug 1160313 hide all view buttons, but let js-calltree still be "supported"
$(`toolbarbutton[data-view=${name}]`).hidden = isRetro ? true : !isSupported;
// If the view is currently selected and not supported, go back to the // If the view is currently selected and not supported, go back to the
// default view. // default view.

View File

@ -92,6 +92,16 @@ let OverviewView = {
yield this.graphs.destroy(); yield this.graphs.destroy();
}), }),
/**
* Returns true if any of the overview graphs have mouse dragging active,
* false otherwise.
*/
get isMouseActive() {
return (this.markersOverview && this.markersOverview.isMouseActive) ||
(this.memoryOverview && this.memoryOverview.isMouseActive) ||
(this.framerateGraph && this.framerateGraph.isMouseActive);
},
/** /**
* Disabled in the event we're using a Timeline mock, so we'll have no * Disabled in the event we're using a Timeline mock, so we'll have no
* timeline, ticks or memory data to show, so just block rendering and hide * timeline, ticks or memory data to show, so just block rendering and hide

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