Merge mozilla-central to mozilla-inbound
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Wed, 24 Jun 2015 16:04:10 +0200
changeset 280909 d12f46ccb758b83e304ecc5e68d59eace4d0303f
parent 280908 bda3c545aa48d1006c704f0b5cfdbd2d9c583356 (current diff)
parent 280864 4cdc1a95a672aaae593448b89b1caee33a159ab7 (diff)
child 280910 5b6617a653cc6a7d3b13abafa9bb8a663b9b8d95
push id4932
push userjlund@mozilla.com
push dateMon, 10 Aug 2015 18:23:06 +0000
treeherdermozilla-beta@6dd5a4f5f745 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone41.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge mozilla-central to mozilla-inbound
--- a/b2g/config/aries/sources.xml
+++ b/b2g/config/aries/sources.xml
@@ -10,25 +10,25 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="311c4e59936a407e64509f54fecb440d8a78e3c8"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="eb0d4aefa62b20420d6fa0642515a110daca5d97"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="9515d87a841daaf28f2577e92edf5206070d2d51"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="35d2750e2e09e2b6ca00f7679ef15066856b8d15"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="8b880805d454664b3eed11d0f053cdeafa1ff06e"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="a1e239a0bb5cd1d69680bf1075883aa9a7bf2429"/>
   <project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="c7931763d41be602407ed9d71e2c0292c6597e00"/>
   <project groups="linux,x86" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="a32003194f707f66a2d8cdb913ed1869f1926c5d"/>
   <project name="device/common" path="device/common" revision="96d4d2006c4fcb2f19a3fa47ab10cb409faa017b"/>
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -10,40 +10,40 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="311c4e59936a407e64509f54fecb440d8a78e3c8"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="eb0d4aefa62b20420d6fa0642515a110daca5d97"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="9515d87a841daaf28f2577e92edf5206070d2d51"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="35d2750e2e09e2b6ca00f7679ef15066856b8d15"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="8b880805d454664b3eed11d0f053cdeafa1ff06e"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="a1e239a0bb5cd1d69680bf1075883aa9a7bf2429"/>
   <project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="c7931763d41be602407ed9d71e2c0292c6597e00"/>
   <project groups="linux,x86" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="83760d213fb3bec7b4117d266fcfbf6fe2ba14ab"/>
   <project name="device/common" path="device/common" revision="6a2995683de147791e516aae2ccb31fdfbe2ad30"/>
   <project name="device/sample" path="device/sample" revision="1a3d8efa0ad32ec8f145367a3cf0f54b97385c3c"/>
   <project name="platform/abi/cpp" path="abi/cpp" revision="18f1b5e28734183ff8073fe86dc46bc4ebba8a59"/>
   <project name="platform/bionic" path="bionic" revision="86b1f589c313422a7da1812512b9ec8d1cf9ba3c"/>
   <project name="platform/bootable/recovery" path="bootable/recovery" revision="286354e69491f7cba5b9ec6b551831fe6f85ad0d"/>
   <project name="platform/external/aac" path="external/aac" revision="fa3eba16446cc8f2f5e2dfc20d86a49dbd37299e"/>
   <project name="platform/external/bison" path="external/bison" revision="c2418b886165add7f5a31fc5609f0ce2d004a90e"/>
-  <project name="platform/external/bluetooth/bluedroid" path="external/bluetooth/bluedroid" revision="c8e99ca7e11c00f8124196fe1726a15e6e976587"/>
+  <project name="platform/external/bluetooth/bluedroid" path="external/bluetooth/bluedroid" revision="3e5570325187f5cd9f8a944cbe4a93822e8c6328"/>
   <project name="platform/external/bsdiff" path="external/bsdiff" revision="23e322ab19fb7d74c2c37e40ce364d9f709bdcee"/>
   <project name="platform/external/bzip2" path="external/bzip2" revision="1cb636bd8e9e5cdfd5d5b2909a122f6e80db62de"/>
   <project name="platform/external/checkpolicy" path="external/checkpolicy" revision="0d73ef7049feee794f14cf1af88d05dae8139914"/>
   <project name="platform/external/dhcpcd" path="external/dhcpcd" revision="84b7252b0a9d0edc9a1db1e0c518771d26b23058"/>
   <project name="platform/external/dnsmasq" path="external/dnsmasq" revision="c2f655d7b501739e05e263d45cb334f26db78079"/>
   <project name="platform/external/dropbear" path="external/dropbear" revision="a34ddbe3819bc465968f3676c734b405e655f8b7"/>
   <project name="platform/external/e2fsprogs" path="external/e2fsprogs" revision="47478a2944a2a17c7fdebe9d92573db92013125c"/>
   <project name="platform/external/elfutils" path="external/elfutils" revision="b23b2dfb354b3ccf5d1c5d39815f02e7048cf516"/>
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -14,17 +14,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="173b3104bfcbd23fc9dccd4b0035fc49aae3d444">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="311c4e59936a407e64509f54fecb440d8a78e3c8"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="eb0d4aefa62b20420d6fa0642515a110daca5d97"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="87a2d8ab9248540910e56921654367b78a587095"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="9d0e5057ee5404a31ec1bf76131cb11336a7c3b6"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -12,20 +12,20 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="4efd19d199ae52656604f794c5a77518400220fd">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="311c4e59936a407e64509f54fecb440d8a78e3c8"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="eb0d4aefa62b20420d6fa0642515a110daca5d97"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="9515d87a841daaf28f2577e92edf5206070d2d51"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="35d2750e2e09e2b6ca00f7679ef15066856b8d15"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="9025e50b9d29b3cabbbb21e1dd94d0d13121a17e"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="b89fda71fcd0fa0cf969310e75be3ea33e048b44"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="2e7d5348f35575870b3c7e567a9a9f6d66f8d6c5"/>
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -10,25 +10,25 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="311c4e59936a407e64509f54fecb440d8a78e3c8"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="eb0d4aefa62b20420d6fa0642515a110daca5d97"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="9515d87a841daaf28f2577e92edf5206070d2d51"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="35d2750e2e09e2b6ca00f7679ef15066856b8d15"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="f92a936f2aa97526d4593386754bdbf02db07a12"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="6e47ff2790f5656b5b074407829ceecf3e6188c4"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="1950e4760fa14688b83cdbb5acaa1af9f82ef434"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="ac6eb97a37035c09fb5ede0852f0881e9aadf9ad"/>
   <project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="737f591c5f95477148d26602c7be56cbea0cdeb9"/>
   <project groups="linux,x86" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="51da9b1981be481b92a59a826d4d78dc73d0989a"/>
   <project name="device/common" path="device/common" revision="798a3664597e6041985feab9aef42e98d458bc3d"/>
--- a/b2g/config/emulator-l/sources.xml
+++ b/b2g/config/emulator-l/sources.xml
@@ -10,25 +10,25 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="311c4e59936a407e64509f54fecb440d8a78e3c8"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="eb0d4aefa62b20420d6fa0642515a110daca5d97"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="9515d87a841daaf28f2577e92edf5206070d2d51"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="35d2750e2e09e2b6ca00f7679ef15066856b8d15"/>
   <!-- Stock Android things -->
   <project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="ffc05a232799fe8fcb3e47b7440b52b1fb4244c0"/>
   <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" revision="337e0ef5e40f02a1ae59b90db0548976c70a7226"/>
   <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.8" revision="8af5ff6f5dced9eb5a8127459df6c75d24342204"/>
   <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8" revision="30915518fa7ea07166efedc191a4f40aef516fe7"/>
   <project groups="pdk,linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.6" revision="96eee58e3389fb05a835310d6a06a6ba4486097a"/>
   <project groups="pdk,linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8" revision="7c8a46698171aa2e0be09edb43d15a6acf832770"/>
   <project groups="pdk,linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.8" path="prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.8" revision="24b2038be8a636fd4a5d21f0abae1e466b07bcf7"/>
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -14,17 +14,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="173b3104bfcbd23fc9dccd4b0035fc49aae3d444">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="311c4e59936a407e64509f54fecb440d8a78e3c8"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="eb0d4aefa62b20420d6fa0642515a110daca5d97"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="87a2d8ab9248540910e56921654367b78a587095"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="9d0e5057ee5404a31ec1bf76131cb11336a7c3b6"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -10,25 +10,25 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="311c4e59936a407e64509f54fecb440d8a78e3c8"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="eb0d4aefa62b20420d6fa0642515a110daca5d97"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="9515d87a841daaf28f2577e92edf5206070d2d51"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="35d2750e2e09e2b6ca00f7679ef15066856b8d15"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="8b880805d454664b3eed11d0f053cdeafa1ff06e"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="a1e239a0bb5cd1d69680bf1075883aa9a7bf2429"/>
   <project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="c7931763d41be602407ed9d71e2c0292c6597e00"/>
   <project groups="linux,x86" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="a32003194f707f66a2d8cdb913ed1869f1926c5d"/>
   <project name="device/common" path="device/common" revision="96d4d2006c4fcb2f19a3fa47ab10cb409faa017b"/>
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,9 +1,9 @@
 {
     "git": {
-        "git_revision": "311c4e59936a407e64509f54fecb440d8a78e3c8", 
+        "git_revision": "eb0d4aefa62b20420d6fa0642515a110daca5d97", 
         "remote": "https://git.mozilla.org/releases/gaia.git", 
         "branch": ""
     }, 
-    "revision": "7e585532a2935425fcddb964cb9002b18b94b3ff", 
+    "revision": "28b5133c0a062776dac8282abcc7810dc317a0bc", 
     "repo_path": "integration/gaia-central"
 }
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -12,20 +12,20 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="4efd19d199ae52656604f794c5a77518400220fd">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="311c4e59936a407e64509f54fecb440d8a78e3c8"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="eb0d4aefa62b20420d6fa0642515a110daca5d97"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="9515d87a841daaf28f2577e92edf5206070d2d51"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="35d2750e2e09e2b6ca00f7679ef15066856b8d15"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="9025e50b9d29b3cabbbb21e1dd94d0d13121a17e"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="b89fda71fcd0fa0cf969310e75be3ea33e048b44"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="2e7d5348f35575870b3c7e567a9a9f6d66f8d6c5"/>
--- a/b2g/config/nexus-5-l/sources.xml
+++ b/b2g/config/nexus-5-l/sources.xml
@@ -10,25 +10,25 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="311c4e59936a407e64509f54fecb440d8a78e3c8"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="eb0d4aefa62b20420d6fa0642515a110daca5d97"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="9515d87a841daaf28f2577e92edf5206070d2d51"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="35d2750e2e09e2b6ca00f7679ef15066856b8d15"/>
   <!-- Stock Android things -->
   <project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="ffc05a232799fe8fcb3e47b7440b52b1fb4244c0"/>
   <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" revision="337e0ef5e40f02a1ae59b90db0548976c70a7226"/>
   <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.8" revision="8af5ff6f5dced9eb5a8127459df6c75d24342204"/>
   <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8" revision="30915518fa7ea07166efedc191a4f40aef516fe7"/>
   <project groups="pdk,linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.6" revision="96eee58e3389fb05a835310d6a06a6ba4486097a"/>
   <project groups="pdk,linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8" revision="7c8a46698171aa2e0be09edb43d15a6acf832770"/>
   <project groups="pdk,linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.8" path="prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.8" revision="24b2038be8a636fd4a5d21f0abae1e466b07bcf7"/>
--- a/browser/base/content/newtab/newTab.css
+++ b/browser/base/content/newtab/newTab.css
@@ -836,16 +836,20 @@ input[type=button] {
   padding: 0;
 }
 
 .newtab-intro-image-customize #newtab-customize-title {
   display: block;
   max-height: 40px;
 }
 
+.newtab-intro-image-customize #newtab-customize-panel-anchor {
+  display: none;
+}
+
 .newtab-intro-image-customize .newtab-customize-panel-item:not([selected]):hover {
   background-color: inherit;
   color: #7A7A7A;
   background: none;
 }
 
 #newtab-intro-text > p {
   margin: 0 0 1em 0;
--- a/browser/components/loop/.eslintrc
+++ b/browser/components/loop/.eslintrc
@@ -58,18 +58,18 @@
     "no-use-before-define": 0,    // TODO: Remove (use default)
     "quotes": [2, "double", "avoid-escape"],
     "strict": 0,                  // [2, "function"],
     // eslint-plugin-react rules. These are documented at
     // <https://github.com/yannickcr/eslint-plugin-react#list-of-supported-rules>
     "react/jsx-quotes": [2, "double", "avoid-escape"],
     "react/jsx-no-undef": 2,
     // Need to fix instances where this is failing.
-    "react/jsx-sort-props": 0,
-    "react/jsx-sort-prop-types": 0,
+    "react/jsx-sort-props": 2,
+    "react/jsx-sort-prop-types": 2,
     "react/jsx-uses-vars": 2,
     // Need to fix the couple of instances which don't
     // currently pass this rule.
     "react/no-did-mount-set-state": 0,
     "react/no-did-update-set-state": 2,
     "react/no-unknown-property": 2,
     // Need to fix instances where this is currently failing
     "react/prop-types": 0,
--- a/browser/components/loop/content/js/contacts.js
+++ b/browser/components/loop/content/js/contacts.js
@@ -130,29 +130,29 @@ loop.contacts = (function(_, mozL10n) {
       return (
         React.createElement("div", {className: "contacts-gravatar-promo"}, 
           React.createElement(Button, {additionalClass: "button-close", onClick: this.handleCloseButtonClick}), 
           React.createElement("p", {dangerouslySetInnerHTML: {__html: message}, 
              onClick: this.handleLinkClick}), 
           React.createElement(ButtonGroup, null, 
             React.createElement(Button, {caption: mozL10n.get("gravatars_promo_button_nothanks"), 
                     onClick: this.handleCloseButtonClick}), 
-            React.createElement(Button, {caption: mozL10n.get("gravatars_promo_button_use"), 
-                    additionalClass: "button-accept", 
+            React.createElement(Button, {additionalClass: "button-accept", 
+                    caption: mozL10n.get("gravatars_promo_button_use"), 
                     onClick: this.handleUseButtonClick})
           )
         )
       );
     }
   });
 
   const ContactDropdown = React.createClass({displayName: "ContactDropdown",
     propTypes: {
-      handleAction: React.PropTypes.func.isRequired,
-      canEdit: React.PropTypes.bool
+      canEdit: React.PropTypes.bool,
+      handleAction: React.PropTypes.func.isRequired
     },
 
     getInitialState: function () {
       return {
         openDirUp: false
       };
     },
 
@@ -186,59 +186,63 @@ loop.contacts = (function(_, mozL10n) {
       let blockLabel = this.props.blocked ? "unblock_contact_menu_button"
                                           : "block_contact_menu_button";
 
       return (
         React.createElement("ul", {className: cx({ "dropdown-menu": true,
                             "dropdown-menu-up": this.state.openDirUp })}, 
           React.createElement("li", {className: cx({ "dropdown-menu-item": true,
                               "disabled": this.props.blocked }), 
-              onClick: this.onItemClick, 
-              "data-action": "video-call"}, 
+              "data-action": "video-call", 
+              onClick: this.onItemClick}, 
             React.createElement("i", {className: "icon icon-video-call"}), 
             mozL10n.get("video_call_menu_button")
           ), 
           React.createElement("li", {className: cx({ "dropdown-menu-item": true,
                               "disabled": this.props.blocked }), 
-              onClick: this.onItemClick, "data-action": "audio-call"}, 
+              "data-action": "audio-call", 
+              onClick: this.onItemClick}, 
             React.createElement("i", {className: "icon icon-audio-call"}), 
             mozL10n.get("audio_call_menu_button")
           ), 
           React.createElement("li", {className: cx({ "dropdown-menu-item": true,
                               "disabled": !this.props.canEdit }), 
-              onClick: this.onItemClick, "data-action": "edit"}, 
+              "data-action": "edit", 
+              onClick: this.onItemClick}, 
             React.createElement("i", {className: "icon icon-edit"}), 
             mozL10n.get("edit_contact_menu_button")
           ), 
           React.createElement("li", {className: "dropdown-menu-item", 
-              onClick: this.onItemClick, "data-action": blockAction}, 
+              "data-action": blockAction, 
+              onClick: this.onItemClick}, 
             React.createElement("i", {className: "icon icon-" + blockAction}), 
             mozL10n.get(blockLabel)
           ), 
           React.createElement("li", {className: cx({ "dropdown-menu-item": true,
                               "disabled": !this.props.canEdit }), 
-              onClick: this.onItemClick, "data-action": "remove"}, 
+               "data-action": "remove", 
+               onClick: this.onItemClick}, 
             React.createElement("i", {className: "icon icon-remove"}), 
             mozL10n.get("remove_contact_menu_button2")
           )
         )
       );
     }
   });
 
   const ContactDetail = React.createClass({displayName: "ContactDetail",
     getInitialState: function() {
       return {
         showMenu: false
       };
     },
 
     propTypes: {
-      handleContactAction: React.PropTypes.func,
-      contact: React.PropTypes.object.isRequired
+      contact: React.PropTypes.object.isRequired,
+      handleContactAction: React.PropTypes.func
     },
 
     _onBodyClick: function() {
       // Hide the menu after other click handlers have been invoked.
       setTimeout(this.hideDropdownMenu, 10);
     },
 
     showDropdownMenu: function() {
@@ -307,19 +311,19 @@ loop.contacts = (function(_, mozL10n) {
           ), 
           React.createElement("div", {className: "icons"}, 
             React.createElement("i", {className: "icon icon-video", 
                onClick: this.handleAction.bind(null, "video-call")}), 
             React.createElement("i", {className: "icon icon-caret-down", 
                onClick: this.showDropdownMenu})
           ), 
           this.state.showMenu
-            ? React.createElement(ContactDropdown, {handleAction: this.handleAction, 
+            ? React.createElement(ContactDropdown, {blocked: this.props.contact.blocked, 
                                canEdit: this.canEdit(), 
-                               blocked: this.props.contact.blocked})
+                               handleAction: this.handleAction})
             : null
           
         )
       );
     }
   });
 
   const ContactsList = React.createClass({displayName: "ContactsList",
@@ -544,18 +548,19 @@ loop.contacts = (function(_, mozL10n) {
       return contact1._guid - contact2._guid;
     },
 
     render: function() {
       let cx = React.addons.classSet;
 
       let viewForItem = item => {
         return (
-          React.createElement(ContactDetail, {key: item._guid, contact: item, 
-                         handleContactAction: this.handleContactAction})
+          React.createElement(ContactDetail, {contact: item, 
+                         handleContactAction: this.handleContactAction, 
+                         key: item._guid})
         );
       };
 
       let shownContacts = _.groupBy(this.contacts, function(contact) {
         return contact.blocked ? "blocked" : "available";
       });
 
       let showFilter = Object.getOwnPropertyNames(this.contacts).length >=
@@ -712,26 +717,33 @@ loop.contacts = (function(_, mozL10n) {
       let phoneOrEmailRequired = !this.state.email && !this.state.tel;
 
       return (
         React.createElement("div", {className: "content-area contact-form"}, 
           React.createElement("header", null, this.props.mode == "add"
                    ? mozL10n.get("add_contact_button")
                    : mozL10n.get("edit_contact_title")), 
           React.createElement("label", null, mozL10n.get("edit_contact_name_label")), 
-          React.createElement("input", {ref: "name", required: true, pattern: "\\s*\\S.*", type: "text", 
-                 className: cx({pristine: this.state.pristine}), 
+          React.createElement("input", {className: cx({pristine: this.state.pristine}), 
+                 pattern: "\\s*\\S.*", 
+                 ref: "name", 
+                 required: true, 
+                 type: "text", 
                  valueLink: this.linkState("name")}), 
           React.createElement("label", null, mozL10n.get("edit_contact_email_label")), 
-          React.createElement("input", {ref: "email", type: "email", required: phoneOrEmailRequired, 
-                 className: cx({pristine: this.state.pristine}), 
+          React.createElement("input", {className: cx({pristine: this.state.pristine}), 
+                 ref: "email", 
+                 required: phoneOrEmailRequired, 
+                 type: "email", 
                  valueLink: this.linkState("email")}), 
           React.createElement("label", null, mozL10n.get("new_contact_fxos_phone_placeholder")), 
-          React.createElement("input", {ref: "tel", type: "tel", required: phoneOrEmailRequired, 
-                 className: cx({pristine: this.state.pristine}), 
+          React.createElement("input", {className: cx({pristine: this.state.pristine}), 
+                 ref: "tel", 
+                 required: phoneOrEmailRequired, 
+                 type: "tel", 
                  valueLink: this.linkState("tel")}), 
           React.createElement(ButtonGroup, null, 
             React.createElement(Button, {additionalClass: "button-cancel", 
                     caption: mozL10n.get("cancel_button"), 
                     onClick: this.handleCancelButtonClick}), 
             React.createElement(Button, {additionalClass: "button-accept", 
                     caption: this.props.mode == "add"
                              ? mozL10n.get("add_contact_button")
--- a/browser/components/loop/content/js/contacts.jsx
+++ b/browser/components/loop/content/js/contacts.jsx
@@ -130,29 +130,29 @@ loop.contacts = (function(_, mozL10n) {
       return (
         <div className="contacts-gravatar-promo">
           <Button additionalClass="button-close" onClick={this.handleCloseButtonClick}/>
           <p dangerouslySetInnerHTML={{__html: message}}
              onClick={this.handleLinkClick}></p>
           <ButtonGroup>
             <Button caption={mozL10n.get("gravatars_promo_button_nothanks")}
                     onClick={this.handleCloseButtonClick}/>
-            <Button caption={mozL10n.get("gravatars_promo_button_use")}
-                    additionalClass="button-accept"
+            <Button additionalClass="button-accept"
+                    caption={mozL10n.get("gravatars_promo_button_use")}
                     onClick={this.handleUseButtonClick}/>
           </ButtonGroup>
         </div>
       );
     }
   });
 
   const ContactDropdown = React.createClass({
     propTypes: {
-      handleAction: React.PropTypes.func.isRequired,
-      canEdit: React.PropTypes.bool
+      canEdit: React.PropTypes.bool,
+      handleAction: React.PropTypes.func.isRequired
     },
 
     getInitialState: function () {
       return {
         openDirUp: false
       };
     },
 
@@ -186,59 +186,63 @@ loop.contacts = (function(_, mozL10n) {
       let blockLabel = this.props.blocked ? "unblock_contact_menu_button"
                                           : "block_contact_menu_button";
 
       return (
         <ul className={cx({ "dropdown-menu": true,
                             "dropdown-menu-up": this.state.openDirUp })}>
           <li className={cx({ "dropdown-menu-item": true,
                               "disabled": this.props.blocked })}
-              onClick={this.onItemClick}
-              data-action="video-call">
+              data-action="video-call"
+              onClick={this.onItemClick}>
             <i className="icon icon-video-call" />
             {mozL10n.get("video_call_menu_button")}
           </li>
           <li className={cx({ "dropdown-menu-item": true,
                               "disabled": this.props.blocked })}
-              onClick={this.onItemClick} data-action="audio-call">
+              data-action="audio-call"
+              onClick={this.onItemClick}>
             <i className="icon icon-audio-call" />
             {mozL10n.get("audio_call_menu_button")}
           </li>
           <li className={cx({ "dropdown-menu-item": true,
                               "disabled": !this.props.canEdit })}
-              onClick={this.onItemClick} data-action="edit">
+              data-action="edit"
+              onClick={this.onItemClick}>
             <i className="icon icon-edit" />
             {mozL10n.get("edit_contact_menu_button")}
           </li>
           <li className="dropdown-menu-item"
-              onClick={this.onItemClick} data-action={blockAction}>
+              data-action={blockAction}
+              onClick={this.onItemClick}>
             <i className={"icon icon-" + blockAction} />
             {mozL10n.get(blockLabel)}
           </li>
           <li className={cx({ "dropdown-menu-item": true,
                               "disabled": !this.props.canEdit })}
-              onClick={this.onItemClick} data-action="remove">
+               data-action="remove"
+               onClick={this.onItemClick}>
             <i className="icon icon-remove" />
             {mozL10n.get("remove_contact_menu_button2")}
           </li>
         </ul>
       );
     }
   });
 
   const ContactDetail = React.createClass({
     getInitialState: function() {
       return {
         showMenu: false
       };
     },
 
     propTypes: {
-      handleContactAction: React.PropTypes.func,
-      contact: React.PropTypes.object.isRequired
+      contact: React.PropTypes.object.isRequired,
+      handleContactAction: React.PropTypes.func
     },
 
     _onBodyClick: function() {
       // Hide the menu after other click handlers have been invoked.
       setTimeout(this.hideDropdownMenu, 10);
     },
 
     showDropdownMenu: function() {
@@ -307,19 +311,19 @@ loop.contacts = (function(_, mozL10n) {
           </div>
           <div className="icons">
             <i className="icon icon-video"
                onClick={this.handleAction.bind(null, "video-call")} />
             <i className="icon icon-caret-down"
                onClick={this.showDropdownMenu} />
           </div>
           {this.state.showMenu
-            ? <ContactDropdown handleAction={this.handleAction}
+            ? <ContactDropdown blocked={this.props.contact.blocked}
                                canEdit={this.canEdit()}
-                               blocked={this.props.contact.blocked} />
+                               handleAction={this.handleAction} />
             : null
           }
         </li>
       );
     }
   });
 
   const ContactsList = React.createClass({
@@ -544,18 +548,19 @@ loop.contacts = (function(_, mozL10n) {
       return contact1._guid - contact2._guid;
     },
 
     render: function() {
       let cx = React.addons.classSet;
 
       let viewForItem = item => {
         return (
-          <ContactDetail key={item._guid} contact={item}
-                         handleContactAction={this.handleContactAction} />
+          <ContactDetail contact={item}
+                         handleContactAction={this.handleContactAction}
+                         key={item._guid} />
         );
       };
 
       let shownContacts = _.groupBy(this.contacts, function(contact) {
         return contact.blocked ? "blocked" : "available";
       });
 
       let showFilter = Object.getOwnPropertyNames(this.contacts).length >=
@@ -712,26 +717,33 @@ loop.contacts = (function(_, mozL10n) {
       let phoneOrEmailRequired = !this.state.email && !this.state.tel;
 
       return (
         <div className="content-area contact-form">
           <header>{this.props.mode == "add"
                    ? mozL10n.get("add_contact_button")
                    : mozL10n.get("edit_contact_title")}</header>
           <label>{mozL10n.get("edit_contact_name_label")}</label>
-          <input ref="name" required pattern="\s*\S.*" type="text"
-                 className={cx({pristine: this.state.pristine})}
+          <input className={cx({pristine: this.state.pristine})}
+                 pattern="\s*\S.*"
+                 ref="name"
+                 required
+                 type="text"
                  valueLink={this.linkState("name")} />
           <label>{mozL10n.get("edit_contact_email_label")}</label>
-          <input ref="email" type="email" required={phoneOrEmailRequired}
-                 className={cx({pristine: this.state.pristine})}
+          <input className={cx({pristine: this.state.pristine})}
+                 ref="email"
+                 required={phoneOrEmailRequired}
+                 type="email"
                  valueLink={this.linkState("email")} />
           <label>{mozL10n.get("new_contact_fxos_phone_placeholder")}</label>
-          <input ref="tel" type="tel" required={phoneOrEmailRequired}
-                 className={cx({pristine: this.state.pristine})}
+          <input className={cx({pristine: this.state.pristine})}
+                 ref="tel"
+                 required={phoneOrEmailRequired}
+                 type="tel"
                  valueLink={this.linkState("tel")} />
           <ButtonGroup>
             <Button additionalClass="button-cancel"
                     caption={mozL10n.get("cancel_button")}
                     onClick={this.handleCancelButtonClick} />
             <Button additionalClass="button-accept"
                     caption={this.props.mode == "add"
                              ? mozL10n.get("add_contact_button")
--- a/browser/components/loop/content/js/conversation.js
+++ b/browser/components/loop/content/js/conversation.js
@@ -24,18 +24,18 @@ loop.conversation = (function(mozL10n) {
     mixins: [
       Backbone.Events,
       loop.store.StoreMixin("conversationAppStore"),
       sharedMixins.WindowCloseMixin
     ],
 
     propTypes: {
       dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
-      roomStore: React.PropTypes.instanceOf(loop.store.RoomStore),
-      mozLoop: React.PropTypes.object.isRequired
+      mozLoop: React.PropTypes.object.isRequired,
+      roomStore: React.PropTypes.instanceOf(loop.store.RoomStore)
     },
 
     getInitialState: function() {
       return this.getStoreState();
     },
 
     render: function() {
       switch(this.state.windowType) {
@@ -153,20 +153,21 @@ loop.conversation = (function(mozL10n) {
     if (hash) {
       windowId = hash[1];
     }
 
     window.addEventListener("unload", function(event) {
       dispatcher.dispatch(new sharedActions.WindowUnload());
     });
 
-    React.render(React.createElement(AppControllerView, {
-      roomStore: roomStore, 
-      dispatcher: dispatcher, 
-      mozLoop: navigator.mozLoop}), document.querySelector("#main"));
+    React.render(
+      React.createElement(AppControllerView, {
+        dispatcher: dispatcher, 
+        mozLoop: navigator.mozLoop, 
+        roomStore: roomStore}), document.querySelector("#main"));
 
     document.documentElement.setAttribute("lang", mozL10n.getLanguage());
     document.documentElement.setAttribute("dir", mozL10n.getDirection());
     document.body.setAttribute("platform", loop.shared.utils.getPlatform());
 
     dispatcher.dispatch(new sharedActions.GetWindowData({
       windowId: windowId
     }));
--- a/browser/components/loop/content/js/conversation.jsx
+++ b/browser/components/loop/content/js/conversation.jsx
@@ -24,18 +24,18 @@ loop.conversation = (function(mozL10n) {
     mixins: [
       Backbone.Events,
       loop.store.StoreMixin("conversationAppStore"),
       sharedMixins.WindowCloseMixin
     ],
 
     propTypes: {
       dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
-      roomStore: React.PropTypes.instanceOf(loop.store.RoomStore),
-      mozLoop: React.PropTypes.object.isRequired
+      mozLoop: React.PropTypes.object.isRequired,
+      roomStore: React.PropTypes.instanceOf(loop.store.RoomStore)
     },
 
     getInitialState: function() {
       return this.getStoreState();
     },
 
     render: function() {
       switch(this.state.windowType) {
@@ -153,20 +153,21 @@ loop.conversation = (function(mozL10n) {
     if (hash) {
       windowId = hash[1];
     }
 
     window.addEventListener("unload", function(event) {
       dispatcher.dispatch(new sharedActions.WindowUnload());
     });
 
-    React.render(<AppControllerView
-      roomStore={roomStore}
-      dispatcher={dispatcher}
-      mozLoop={navigator.mozLoop} />, document.querySelector("#main"));
+    React.render(
+      <AppControllerView
+        dispatcher={dispatcher}
+        mozLoop={navigator.mozLoop}
+        roomStore={roomStore} />, document.querySelector("#main"));
 
     document.documentElement.setAttribute("lang", mozL10n.getLanguage());
     document.documentElement.setAttribute("dir", mozL10n.getDirection());
     document.body.setAttribute("platform", loop.shared.utils.getPlatform());
 
     dispatcher.dispatch(new sharedActions.GetWindowData({
       windowId: windowId
     }));
--- a/browser/components/loop/content/js/conversationViews.js
+++ b/browser/components/loop/content/js/conversationViews.js
@@ -227,19 +227,20 @@ loop.conversationViews = (function(mozL1
       var dropdownMenuClassesDecline = React.addons.classSet({
         "native-dropdown-menu": true,
         "conversation-window-dropdown": true,
         "visually-hidden": !this.state.showMenu
       });
 
       return (
         React.createElement("div", {className: "call-window"}, 
-          React.createElement(CallIdentifierView, {video: this.props.callType === CALL_TYPES.AUDIO_VIDEO, 
+          React.createElement(CallIdentifierView, {
             peerIdentifier: this.props.callerId, 
-            showIcons: true}), 
+            showIcons: true, 
+            video: this.props.callType === CALL_TYPES.AUDIO_VIDEO}), 
 
           React.createElement("div", {className: "btn-group call-action-group"}, 
 
             React.createElement("div", {className: "fx-embedded-call-button-spacer"}), 
 
             React.createElement("div", {className: "btn-chevron-menu-group"}, 
               React.createElement("div", {className: "btn-group-chevron"}, 
                 React.createElement("div", {className: "btn-group"}, 
@@ -356,19 +357,19 @@ loop.conversationViews = (function(mozL1
   /**
    * View for pending conversations. Displays a cancel button and appropriate
    * pending/ringing strings.
    */
   var PendingConversationView = React.createClass({displayName: "PendingConversationView",
     mixins: [sharedMixins.AudioMixin],
 
     propTypes: {
-      dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
       callState: React.PropTypes.string,
       contact: React.PropTypes.object,
+      dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
       enableCancelButton: React.PropTypes.bool
     },
 
     getDefaultProps: function() {
       return {
         enableCancelButton: false
       };
     },
@@ -420,18 +421,18 @@ loop.conversationViews = (function(mozL1
     mixins: [
       Backbone.Events,
       loop.store.StoreMixin("conversationStore"),
       sharedMixins.AudioMixin,
       sharedMixins.WindowCloseMixin
     ],
 
     propTypes: {
+      contact: React.PropTypes.object.isRequired,
       dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
-      contact: React.PropTypes.object.isRequired,
       // This is used by the UI showcase.
       emailLinkError: React.PropTypes.bool,
       outgoing: React.PropTypes.bool.isRequired
     },
 
     getInitialState: function() {
       return {
         emailLinkError: this.props.emailLinkError,
@@ -548,45 +549,45 @@ loop.conversationViews = (function(mozL1
                     onClick: this.cancelCall}, 
               mozL10n.get("cancel_button")
             ), 
             React.createElement("button", {className: retryClasses, 
                     onClick: this.retryCall}, 
               mozL10n.get("retry_call_button")
             ), 
             React.createElement("button", {className: emailClasses, 
-                    onClick: this.emailLink, 
-                    disabled: this.state.emailLinkButtonDisabled}, 
+                    disabled: this.state.emailLinkButtonDisabled, 
+                    onClick: this.emailLink}, 
               mozL10n.get("share_button3")
             )
           )
         )
       );
     }
   });
 
   var OngoingConversationView = React.createClass({displayName: "OngoingConversationView",
     mixins: [
       loop.store.StoreMixin("conversationStore"),
       sharedMixins.MediaSetupMixin
     ],
 
     propTypes: {
-      dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
-      // local
-      video: React.PropTypes.object,
       // local
       audio: React.PropTypes.object,
-      remoteVideoEnabled: React.PropTypes.bool,
+      dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
+      // The poster URLs are for UI-showcase testing and development.
+      localPosterUrl: React.PropTypes.string,
       // This is used from the props rather than the state to make it easier for
       // the ui-showcase.
       mediaConnected: React.PropTypes.bool,
-      // The poster URLs are for UI-showcase testing and development.
-      localPosterUrl: React.PropTypes.string,
-      remotePosterUrl: React.PropTypes.string
+      remotePosterUrl: React.PropTypes.string,
+      remoteVideoEnabled: React.PropTypes.bool,
+      // local
+      video: React.PropTypes.object
     },
 
     getDefaultProps: function() {
       return {
         video: {enabled: true, visible: true},
         audio: {enabled: true, visible: true}
       };
     },
@@ -649,34 +650,34 @@ loop.conversationViews = (function(mozL1
 
       return (
         React.createElement("div", {className: "video-layout-wrapper"}, 
           React.createElement("div", {className: "conversation"}, 
             React.createElement("div", {className: "media nested"}, 
               React.createElement("div", {className: "video_wrapper remote_wrapper"}, 
                 React.createElement("div", {className: "video_inner remote focus-stream"}, 
                   React.createElement(sharedViews.MediaView, {displayAvatar: !this.shouldRenderRemoteVideo(), 
+                    mediaType: "remote", 
                     posterUrl: this.props.remotePosterUrl, 
-                    mediaType: "remote", 
                     srcVideoObject: this.state.remoteSrcVideoObject})
                 )
               ), 
               React.createElement("div", {className: localStreamClasses}, 
                 React.createElement(sharedViews.MediaView, {displayAvatar: !this.props.video.enabled, 
+                  mediaType: "local", 
                   posterUrl: this.props.localPosterUrl, 
-                  mediaType: "local", 
                   srcVideoObject: this.state.localSrcVideoObject})
               )
             ), 
             React.createElement(loop.shared.views.ConversationToolbar, {
+              audio: this.props.audio, 
               dispatcher: this.props.dispatcher, 
-              video: this.props.video, 
-              audio: this.props.audio, 
+              hangup: this.hangup, 
               publishStream: this.publishStream, 
-              hangup: this.hangup})
+              video: this.props.video})
           )
         )
       );
     }
   });
 
   /**
    * Master View Controller for outgoing calls. This manages
@@ -724,21 +725,20 @@ loop.conversationViews = (function(mozL1
       );
     },
 
     _renderViewFromCallType: function() {
       // For outgoing calls we can display the pending conversation view
       // for any state that render() doesn't manage.
       if (this.state.outgoing) {
         return (React.createElement(PendingConversationView, {
-          dispatcher: this.props.dispatcher, 
           callState: this.state.callState, 
           contact: this.state.contact, 
-          enableCancelButton: this._isCancellable()}
-        ));
+          dispatcher: this.props.dispatcher, 
+          enableCancelButton: this._isCancellable()}));
       }
 
       // For incoming calls that are in accepting state, display the
       // accept call view.
       if (this.state.callState === CALL_STATES.ALERTING) {
         return (React.createElement(AcceptCallView, {
           callType: this.state.callType, 
           callerId: this.state.callerId, 
@@ -763,30 +763,28 @@ loop.conversationViews = (function(mozL1
 
       switch (this.state.callState) {
         case CALL_STATES.CLOSE: {
           this._closeWindow();
           return null;
         }
         case CALL_STATES.TERMINATED: {
           return (React.createElement(CallFailedView, {
+            contact: this.state.contact, 
             dispatcher: this.props.dispatcher, 
-            contact: this.state.contact, 
-            outgoing: this.state.outgoing}
-          ));
+            outgoing: this.state.outgoing}));
         }
         case CALL_STATES.ONGOING: {
           return (React.createElement(OngoingConversationView, {
+            audio: {enabled: !this.state.audioMuted}, 
             dispatcher: this.props.dispatcher, 
-            video: {enabled: !this.state.videoMuted}, 
-            audio: {enabled: !this.state.audioMuted}, 
+            mediaConnected: this.state.mediaConnected, 
+            remoteSrcVideoObject: this.state.remoteSrcVideoObject, 
             remoteVideoEnabled: this.state.remoteVideoEnabled, 
-            mediaConnected: this.state.mediaConnected, 
-            remoteSrcVideoObject: this.state.remoteSrcVideoObject}
-            )
+            video: {enabled: !this.state.videoMuted}})
           );
         }
         case CALL_STATES.FINISHED: {
           this.play("terminated");
           return this._renderFeedbackView();
         }
         case CALL_STATES.INIT: {
           // We know what we are, but we haven't got the data yet.
--- a/browser/components/loop/content/js/conversationViews.jsx
+++ b/browser/components/loop/content/js/conversationViews.jsx
@@ -227,19 +227,20 @@ loop.conversationViews = (function(mozL1
       var dropdownMenuClassesDecline = React.addons.classSet({
         "native-dropdown-menu": true,
         "conversation-window-dropdown": true,
         "visually-hidden": !this.state.showMenu
       });
 
       return (
         <div className="call-window">
-          <CallIdentifierView video={this.props.callType === CALL_TYPES.AUDIO_VIDEO}
+          <CallIdentifierView
             peerIdentifier={this.props.callerId}
-            showIcons={true} />
+            showIcons={true}
+            video={this.props.callType === CALL_TYPES.AUDIO_VIDEO} />
 
           <div className="btn-group call-action-group">
 
             <div className="fx-embedded-call-button-spacer"></div>
 
             <div className="btn-chevron-menu-group">
               <div className="btn-group-chevron">
                 <div className="btn-group">
@@ -356,19 +357,19 @@ loop.conversationViews = (function(mozL1
   /**
    * View for pending conversations. Displays a cancel button and appropriate
    * pending/ringing strings.
    */
   var PendingConversationView = React.createClass({
     mixins: [sharedMixins.AudioMixin],
 
     propTypes: {
-      dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
       callState: React.PropTypes.string,
       contact: React.PropTypes.object,
+      dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
       enableCancelButton: React.PropTypes.bool
     },
 
     getDefaultProps: function() {
       return {
         enableCancelButton: false
       };
     },
@@ -420,18 +421,18 @@ loop.conversationViews = (function(mozL1
     mixins: [
       Backbone.Events,
       loop.store.StoreMixin("conversationStore"),
       sharedMixins.AudioMixin,
       sharedMixins.WindowCloseMixin
     ],
 
     propTypes: {
+      contact: React.PropTypes.object.isRequired,
       dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
-      contact: React.PropTypes.object.isRequired,
       // This is used by the UI showcase.
       emailLinkError: React.PropTypes.bool,
       outgoing: React.PropTypes.bool.isRequired
     },
 
     getInitialState: function() {
       return {
         emailLinkError: this.props.emailLinkError,
@@ -548,45 +549,45 @@ loop.conversationViews = (function(mozL1
                     onClick={this.cancelCall}>
               {mozL10n.get("cancel_button")}
             </button>
             <button className={retryClasses}
                     onClick={this.retryCall}>
               {mozL10n.get("retry_call_button")}
             </button>
             <button className={emailClasses}
-                    onClick={this.emailLink}
-                    disabled={this.state.emailLinkButtonDisabled}>
+                    disabled={this.state.emailLinkButtonDisabled}
+                    onClick={this.emailLink}>
               {mozL10n.get("share_button3")}
             </button>
           </div>
         </div>
       );
     }
   });
 
   var OngoingConversationView = React.createClass({
     mixins: [
       loop.store.StoreMixin("conversationStore"),
       sharedMixins.MediaSetupMixin
     ],
 
     propTypes: {
-      dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
-      // local
-      video: React.PropTypes.object,
       // local
       audio: React.PropTypes.object,
-      remoteVideoEnabled: React.PropTypes.bool,
+      dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
+      // The poster URLs are for UI-showcase testing and development.
+      localPosterUrl: React.PropTypes.string,
       // This is used from the props rather than the state to make it easier for
       // the ui-showcase.
       mediaConnected: React.PropTypes.bool,
-      // The poster URLs are for UI-showcase testing and development.
-      localPosterUrl: React.PropTypes.string,
-      remotePosterUrl: React.PropTypes.string
+      remotePosterUrl: React.PropTypes.string,
+      remoteVideoEnabled: React.PropTypes.bool,
+      // local
+      video: React.PropTypes.object
     },
 
     getDefaultProps: function() {
       return {
         video: {enabled: true, visible: true},
         audio: {enabled: true, visible: true}
       };
     },
@@ -649,34 +650,34 @@ loop.conversationViews = (function(mozL1
 
       return (
         <div className="video-layout-wrapper">
           <div className="conversation">
             <div className="media nested">
               <div className="video_wrapper remote_wrapper">
                 <div className="video_inner remote focus-stream">
                   <sharedViews.MediaView displayAvatar={!this.shouldRenderRemoteVideo()}
+                    mediaType="remote"
                     posterUrl={this.props.remotePosterUrl}
-                    mediaType="remote"
                     srcVideoObject={this.state.remoteSrcVideoObject} />
                 </div>
               </div>
               <div className={localStreamClasses}>
                 <sharedViews.MediaView displayAvatar={!this.props.video.enabled}
+                  mediaType="local"
                   posterUrl={this.props.localPosterUrl}
-                  mediaType="local"
                   srcVideoObject={this.state.localSrcVideoObject} />
               </div>
             </div>
             <loop.shared.views.ConversationToolbar
+              audio={this.props.audio}
               dispatcher={this.props.dispatcher}
-              video={this.props.video}
-              audio={this.props.audio}
+              hangup={this.hangup}
               publishStream={this.publishStream}
-              hangup={this.hangup} />
+              video={this.props.video} />
           </div>
         </div>
       );
     }
   });
 
   /**
    * Master View Controller for outgoing calls. This manages
@@ -724,21 +725,20 @@ loop.conversationViews = (function(mozL1
       );
     },
 
     _renderViewFromCallType: function() {
       // For outgoing calls we can display the pending conversation view
       // for any state that render() doesn't manage.
       if (this.state.outgoing) {
         return (<PendingConversationView
-          dispatcher={this.props.dispatcher}
           callState={this.state.callState}
           contact={this.state.contact}
-          enableCancelButton={this._isCancellable()}
-        />);
+          dispatcher={this.props.dispatcher}
+          enableCancelButton={this._isCancellable()} />);
       }
 
       // For incoming calls that are in accepting state, display the
       // accept call view.
       if (this.state.callState === CALL_STATES.ALERTING) {
         return (<AcceptCallView
           callType={this.state.callType}
           callerId={this.state.callerId}
@@ -763,30 +763,28 @@ loop.conversationViews = (function(mozL1
 
       switch (this.state.callState) {
         case CALL_STATES.CLOSE: {
           this._closeWindow();
           return null;
         }
         case CALL_STATES.TERMINATED: {
           return (<CallFailedView
+            contact={this.state.contact}
             dispatcher={this.props.dispatcher}
-            contact={this.state.contact}
-            outgoing={this.state.outgoing}
-          />);
+            outgoing={this.state.outgoing} />);
         }
         case CALL_STATES.ONGOING: {
           return (<OngoingConversationView
+            audio={{enabled: !this.state.audioMuted}}
             dispatcher={this.props.dispatcher}
-            video={{enabled: !this.state.videoMuted}}
-            audio={{enabled: !this.state.audioMuted}}
-            remoteVideoEnabled={this.state.remoteVideoEnabled}
             mediaConnected={this.state.mediaConnected}
             remoteSrcVideoObject={this.state.remoteSrcVideoObject}
-            />
+            remoteVideoEnabled={this.state.remoteVideoEnabled}
+            video={{enabled: !this.state.videoMuted}} />
           );
         }
         case CALL_STATES.FINISHED: {
           this.play("terminated");
           return this._renderFeedbackView();
         }
         case CALL_STATES.INIT: {
           // We know what we are, but we haven't got the data yet.
--- a/browser/components/loop/content/js/panel.js
+++ b/browser/components/loop/content/js/panel.js
@@ -15,19 +15,19 @@ loop.panel = (function(_, mozL10n) {
   var ButtonGroup = sharedViews.ButtonGroup;
   var Checkbox = sharedViews.Checkbox;
   var ContactsList = loop.contacts.ContactsList;
   var ContactDetailsForm = loop.contacts.ContactDetailsForm;
 
   var TabView = React.createClass({displayName: "TabView",
     propTypes: {
       buttonsHidden: React.PropTypes.array,
+      mozLoop: React.PropTypes.object,
       // The selectedTab prop is used by the UI showcase.
-      selectedTab: React.PropTypes.string,
-      mozLoop: React.PropTypes.object
+      selectedTab: React.PropTypes.string
     },
 
     getDefaultProps: function() {
       return {
         buttonsHidden: []
       };
     },
 
@@ -77,24 +77,24 @@ loop.panel = (function(_, mozL10n) {
         var tabName = tab.props.name;
         if (this.props.buttonsHidden.indexOf(tabName) > -1) {
           return;
         }
         var isSelected = (this.state.selectedTab == tabName);
         if (!tab.props.hidden) {
           tabButtons.push(
             React.createElement("li", {className: cx({selected: isSelected}), 
+                "data-tab-name": tabName, 
                 key: i, 
-                "data-tab-name": tabName, 
-                title: mozL10n.get(tabName + "_tab_button_tooltip"), 
-                onClick: this.handleSelectTab})
+                onClick: this.handleSelectTab, 
+                title: mozL10n.get(tabName + "_tab_button_tooltip")})
           );
         }
         tabs.push(
-          React.createElement("div", {key: i, className: cx({tab: true, selected: isSelected})}, 
+          React.createElement("div", {className: cx({tab: true, selected: isSelected}), key: i}, 
             tab.props.children
           )
         );
       }, this);
       return (
         React.createElement("div", {className: "tab-view-container"}, 
           React.createElement("ul", {className: "tab-view"}, tabButtons), 
           tabs
@@ -159,23 +159,23 @@ loop.panel = (function(_, mozL10n) {
 
       return (
         React.createElement("div", {className: "dropdown"}, 
           React.createElement("p", {className: "dnd-status", onClick: this.toggleDropdownMenu, ref: "menu-button"}, 
             React.createElement("span", null, availabilityText), 
             React.createElement("i", {className: availabilityStatus})
           ), 
           React.createElement("ul", {className: availabilityDropdown}, 
-            React.createElement("li", {onClick: this.changeAvailability("available"), 
-                className: "dropdown-menu-item dnd-make-available"}, 
+            React.createElement("li", {className: "dropdown-menu-item dnd-make-available", 
+                onClick: this.changeAvailability("available")}, 
               React.createElement("i", {className: "status status-available"}), 
               React.createElement("span", null, mozL10n.get("display_name_available_status"))
             ), 
-            React.createElement("li", {onClick: this.changeAvailability("do-not-disturb"), 
-                className: "dropdown-menu-item dnd-make-unavailable"}, 
+            React.createElement("li", {className: "dropdown-menu-item dnd-make-unavailable", 
+                onClick: this.changeAvailability("do-not-disturb")}, 
               React.createElement("i", {className: "status status-dnd"}), 
               React.createElement("span", null, mozL10n.get("display_name_dnd_status"))
             )
           )
         )
       );
     }
   });
@@ -197,19 +197,19 @@ loop.panel = (function(_, mozL10n) {
       }
       return (
         React.createElement("div", {id: "fte-getstarted"}, 
           React.createElement("header", {id: "fte-title"}, 
             mozL10n.get("first_time_experience_title", {
               "clientShortname": mozL10n.get("clientShortname2")
             })
           ), 
-          React.createElement(Button, {htmlId: "fte-button", 
-                  onClick: this.handleButtonClick, 
-                  caption: mozL10n.get("first_time_experience_button_label")})
+          React.createElement(Button, {caption: mozL10n.get("first_time_experience_button_label"), 
+                  htmlId: "fte-button", 
+                  onClick: this.handleButtonClick})
         )
       );
     }
   });
 
   /**
    * Displays a view requesting the user to sign-in again.
    */
@@ -286,19 +286,19 @@ loop.panel = (function(_, mozL10n) {
     renderPartnerLogo: function() {
       if (!this.state.showPartnerLogo) {
         return null;
       }
 
       var locale = mozL10n.getLanguage();
       navigator.mozLoop.setLoopPref("showPartnerLogo", false);
       return (
-        React.createElement("p", {id: "powered-by", className: "powered-by"}, 
+        React.createElement("p", {className: "powered-by", id: "powered-by"}, 
           mozL10n.get("powered_by_beforeLogo"), 
-          React.createElement("img", {id: "powered-by-logo", className: locale}), 
+          React.createElement("img", {className: locale, id: "powered-by-logo"}), 
           mozL10n.get("powered_by_afterLogo")
         )
       );
     },
 
     render: function() {
       if (!this.state.gettingStartedSeen || this.state.seenToS == "unseen") {
         var terms_of_use_url = navigator.mozLoop.getLoopPref("legal.ToS_url");
@@ -330,32 +330,32 @@ loop.panel = (function(_, mozL10n) {
     }
   });
 
   /**
    * Panel settings (gear) menu entry.
    */
   var SettingsDropdownEntry = React.createClass({displayName: "SettingsDropdownEntry",
     propTypes: {
-      onClick: React.PropTypes.func.isRequired,
+      displayed: React.PropTypes.bool,
+      icon: React.PropTypes.string,
       label: React.PropTypes.string.isRequired,
-      icon: React.PropTypes.string,
-      displayed: React.PropTypes.bool
+      onClick: React.PropTypes.func.isRequired
     },
 
     getDefaultProps: function() {
       return {displayed: true};
     },
 
     render: function() {
       if (!this.props.displayed) {
         return null;
       }
       return (
-        React.createElement("li", {onClick: this.props.onClick, className: "dropdown-menu-item"}, 
+        React.createElement("li", {className: "dropdown-menu-item", onClick: this.props.onClick}, 
           this.props.icon ?
             React.createElement("i", {className: "icon icon-" + this.props.icon}) :
             null, 
           React.createElement("span", null, this.props.label)
         )
       );
     }
   });
@@ -405,39 +405,39 @@ loop.panel = (function(_, mozL10n) {
 
     render: function() {
       var cx = React.addons.classSet;
 
       return (
         React.createElement("div", {className: "settings-menu dropdown"}, 
           React.createElement("a", {className: "button-settings", 
              onClick: this.toggleDropdownMenu, 
-             title: mozL10n.get("settings_menu_button_tooltip"), 
-             ref: "menu-button"}), 
+             ref: "menu-button", 
+             title: mozL10n.get("settings_menu_button_tooltip")}), 
           React.createElement("ul", {className: cx({"dropdown-menu": true, hide: !this.state.showMenu})}, 
-            React.createElement(SettingsDropdownEntry, {label: mozL10n.get("settings_menu_item_settings"), 
-                                   onClick: this.handleClickSettingsEntry, 
-                                   displayed: false, 
-                                   icon: "settings"}), 
-            React.createElement(SettingsDropdownEntry, {label: mozL10n.get("settings_menu_item_account"), 
-                                   onClick: this.handleClickAccountEntry, 
+            React.createElement(SettingsDropdownEntry, {displayed: false, 
+                                   icon: "settings", 
+                                   label: mozL10n.get("settings_menu_item_settings"), 
+                                   onClick: this.handleClickSettingsEntry}), 
+            React.createElement(SettingsDropdownEntry, {displayed: this._isSignedIn() && this.props.mozLoop.fxAEnabled, 
                                    icon: "account", 
-                                   displayed: this._isSignedIn() && this.props.mozLoop.fxAEnabled}), 
+                                   label: mozL10n.get("settings_menu_item_account"), 
+                                   onClick: this.handleClickAccountEntry}), 
             React.createElement(SettingsDropdownEntry, {icon: "tour", 
                                    label: mozL10n.get("tour_label"), 
                                    onClick: this.openGettingStartedTour}), 
-            React.createElement(SettingsDropdownEntry, {label: this._isSignedIn() ?
+            React.createElement(SettingsDropdownEntry, {displayed: this.props.mozLoop.fxAEnabled, 
+                                   icon: this._isSignedIn() ? "signout" : "signin", 
+                                   label: this._isSignedIn() ?
                                           mozL10n.get("settings_menu_item_signout") :
                                           mozL10n.get("settings_menu_item_signin"), 
-                                   onClick: this.handleClickAuthEntry, 
-                                   displayed: this.props.mozLoop.fxAEnabled, 
-                                   icon: this._isSignedIn() ? "signout" : "signin"}), 
-            React.createElement(SettingsDropdownEntry, {label: mozL10n.get("help_label"), 
-                                   onClick: this.handleHelpEntry, 
-                                   icon: "help"})
+                                   onClick: this.handleClickAuthEntry}), 
+            React.createElement(SettingsDropdownEntry, {icon: "help", 
+                                   label: mozL10n.get("help_label"), 
+                                   onClick: this.handleHelpEntry})
           )
         )
       );
     }
   });
 
   /**
    * FxA sign in/up link component.
@@ -495,17 +495,17 @@ loop.panel = (function(_, mozL10n) {
     render: function() {
       var roomUrl = this.props.roomUrls && this.props.roomUrls[0];
       if (!roomUrl) {
         return null;
       }
 
       return (
         React.createElement("div", {className: "room-entry-context-item"}, 
-          React.createElement("a", {href: roomUrl.location, title: roomUrl.description, onClick: this.handleClick}, 
+          React.createElement("a", {href: roomUrl.location, onClick: this.handleClick, title: roomUrl.description}, 
             React.createElement("img", {src: roomUrl.thumbnail || "loop/shared/img/icons-16x16.svg#globe"})
           )
         )
       );
     }
   });
 
   /**
@@ -582,45 +582,45 @@ loop.panel = (function(_, mozL10n) {
         "room-active": this._isActive()
       });
       var copyButtonClasses = React.addons.classSet({
         "copy-link": true,
         "checked": this.state.urlCopied
       });
 
       return (
-        React.createElement("div", {className: roomClasses, onMouseLeave: this.handleMouseLeave, 
-             onClick: this.handleClickEntry}, 
+        React.createElement("div", {className: roomClasses, onClick: this.handleClickEntry, 
+             onMouseLeave: this.handleMouseLeave}, 
           React.createElement("h2", null, 
             React.createElement("span", {className: "room-notification"}), 
             this.props.room.decryptedContext.roomName, 
             React.createElement("button", {className: copyButtonClasses, 
-              title: mozL10n.get("rooms_list_copy_url_tooltip"), 
-              onClick: this.handleCopyButtonClick}), 
+              onClick: this.handleCopyButtonClick, 
+              title: mozL10n.get("rooms_list_copy_url_tooltip")}), 
             React.createElement("button", {className: "delete-link", 
-              title: mozL10n.get("rooms_list_delete_tooltip"), 
-              onClick: this.handleDeleteButtonClick})
+              onClick: this.handleDeleteButtonClick, 
+              title: mozL10n.get("rooms_list_delete_tooltip")})
           ), 
           React.createElement(RoomEntryContextItem, {mozLoop: this.props.mozLoop, 
                                 roomUrls: this.props.room.decryptedContext.urls})
         )
       );
     }
   });
 
   /**
    * Room list.
    */
   var RoomList = React.createClass({displayName: "RoomList",
     mixins: [Backbone.Events, sharedMixins.WindowCloseMixin],
 
     propTypes: {
+      dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
       mozLoop: React.PropTypes.object.isRequired,
       store: React.PropTypes.instanceOf(loop.store.RoomStore).isRequired,
-      dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
       userDisplayName: React.PropTypes.string.isRequired  // for room creation
     },
 
     getInitialState: function() {
       return this.props.store.getStoreState();
     },
 
     componentDidMount: function() {
@@ -665,21 +665,20 @@ loop.panel = (function(_, mozL10n) {
 
       return (
         React.createElement("div", {className: "rooms"}, 
           React.createElement("h1", null, this._getListHeading()), 
           React.createElement("div", {className: "room-list"}, 
             this.state.rooms.map(function(room, i) {
               return (
                 React.createElement(RoomEntry, {
+                  dispatcher: this.props.dispatcher, 
                   key: room.roomToken, 
-                  dispatcher: this.props.dispatcher, 
                   mozLoop: this.props.mozLoop, 
-                  room: room}
-                )
+                  room: room})
               );
             }, this)
           ), 
           React.createElement(NewRoomView, {dispatcher: this.props.dispatcher, 
             mozLoop: this.props.mozLoop, 
             pendingOperation: this.state.pendingCreation ||
               this.state.pendingInitialRetrieval, 
             userDisplayName: this.props.userDisplayName})
@@ -783,40 +782,40 @@ loop.panel = (function(_, mozL10n) {
               allowClick: false, 
               description: this.state.description, 
               showContextTitle: false, 
               thumbnail: this.state.previewImage, 
               url: this.state.url, 
               useDesktopPaths: true})
           ), 
           React.createElement("button", {className: "btn btn-info new-room-button", 
-                  onClick: this.handleCreateButtonClick, 
-                  disabled: this.props.pendingOperation}, 
+                  disabled: this.props.pendingOperation, 
+                  onClick: this.handleCreateButtonClick}, 
             mozL10n.get("rooms_new_room_button_label")
           )
         )
       );
     }
   });
 
   /**
    * Panel view.
    */
   var PanelView = React.createClass({displayName: "PanelView",
     propTypes: {
+      dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
+      mozLoop: React.PropTypes.object.isRequired,
       notifications: React.PropTypes.object.isRequired,
-      // Mostly used for UI components showcase and unit tests
-      userProfile: React.PropTypes.object,
+      roomStore:
+        React.PropTypes.instanceOf(loop.store.RoomStore).isRequired,
+      selectedTab: React.PropTypes.string,
       // Used only for unit tests.
       showTabButtons: React.PropTypes.bool,
-      selectedTab: React.PropTypes.string,
-      dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
-      mozLoop: React.PropTypes.object.isRequired,
-      roomStore:
-        React.PropTypes.instanceOf(loop.store.RoomStore).isRequired
+      // Mostly used for UI components showcase and unit tests
+      userProfile: React.PropTypes.object
     },
 
     getInitialState: function() {
       return {
         hasEncryptionKey: this.props.mozLoop.hasEncryptionKey,
         userProfile: this.props.userProfile || this.props.mozLoop.userProfile,
         gettingStartedSeen: this.props.mozLoop.getLoopPref("gettingStarted.seen")
       };
@@ -918,18 +917,19 @@ loop.panel = (function(_, mozL10n) {
     },
 
     render: function() {
       var NotificationListView = sharedViews.NotificationListView;
 
       if (!this.state.gettingStartedSeen) {
         return (
           React.createElement("div", null, 
-            React.createElement(NotificationListView, {notifications: this.props.notifications, 
-                                  clearOnDocumentHidden: true}), 
+            React.createElement(NotificationListView, {
+              clearOnDocumentHidden: true, 
+              notifications: this.props.notifications}), 
             React.createElement(GettingStartedView, null), 
             React.createElement(ToSView, null)
           )
         );
       }
 
       if (!this.state.hasEncryptionKey) {
         return React.createElement(SignInRequestView, {mozLoop: this.props.mozLoop});
@@ -938,43 +938,54 @@ loop.panel = (function(_, mozL10n) {
       // Determine which buttons to NOT show.
       var hideButtons = [];
       if (!this.state.userProfile && !this.props.showTabButtons) {
         hideButtons.push("contacts");
       }
 
       return (
         React.createElement("div", null, 
-          React.createElement(NotificationListView, {notifications: this.props.notifications, 
-                                clearOnDocumentHidden: true}), 
-          React.createElement(TabView, {ref: "tabView", selectedTab: this.props.selectedTab, 
-            buttonsHidden: hideButtons, mozLoop: this.props.mozLoop}, 
+          React.createElement(NotificationListView, {
+            clearOnDocumentHidden: true, 
+            notifications: this.props.notifications}), 
+          React.createElement(TabView, {
+            buttonsHidden: hideButtons, 
+            mozLoop: this.props.mozLoop, 
+            ref: "tabView", 
+            selectedTab: this.props.selectedTab}, 
             React.createElement(Tab, {name: "rooms"}, 
               React.createElement(RoomList, {dispatcher: this.props.dispatcher, 
+                        mozLoop: this.props.mozLoop, 
                         store: this.props.roomStore, 
-                        userDisplayName: this._getUserDisplayName(), 
-                        mozLoop: this.props.mozLoop}), 
+                        userDisplayName: this._getUserDisplayName()}), 
               React.createElement(ToSView, null)
             ), 
             React.createElement(Tab, {name: "contacts"}, 
-              React.createElement(ContactsList, {selectTab: this.selectTab, 
-                            startForm: this.startForm, 
-                            notifications: this.props.notifications})
+              React.createElement(ContactsList, {
+                notifications: this.props.notifications, 
+                selectTab: this.selectTab, 
+                startForm: this.startForm})
             ), 
-            React.createElement(Tab, {name: "contacts_add", hidden: true}, 
-              React.createElement(ContactDetailsForm, {ref: "contacts_add", mode: "add", 
-                                  selectTab: this.selectTab})
+            React.createElement(Tab, {hidden: true, name: "contacts_add"}, 
+              React.createElement(ContactDetailsForm, {
+                mode: "add", 
+                ref: "contacts_add", 
+                selectTab: this.selectTab})
             ), 
-            React.createElement(Tab, {name: "contacts_edit", hidden: true}, 
-              React.createElement(ContactDetailsForm, {ref: "contacts_edit", mode: "edit", 
-                                  selectTab: this.selectTab})
+            React.createElement(Tab, {hidden: true, name: "contacts_edit"}, 
+              React.createElement(ContactDetailsForm, {
+                mode: "edit", 
+                ref: "contacts_edit", 
+                selectTab: this.selectTab})
             ), 
-            React.createElement(Tab, {name: "contacts_import", hidden: true}, 
-              React.createElement(ContactDetailsForm, {ref: "contacts_import", mode: "import", 
-                                  selectTab: this.selectTab})
+            React.createElement(Tab, {hidden: true, name: "contacts_import"}, 
+              React.createElement(ContactDetailsForm, {
+                mode: "import", 
+                ref: "contacts_import", 
+                selectTab: this.selectTab})
             )
           ), 
           React.createElement("div", {className: "footer"}, 
             React.createElement("div", {className: "user-details"}, 
               React.createElement(UserIdentity, {displayName: this._getUserDisplayName()}), 
               React.createElement(AvailabilityDropdown, null)
             ), 
             React.createElement("div", {className: "signin-details"}, 
@@ -999,20 +1010,20 @@ loop.panel = (function(_, mozL10n) {
     var notifications = new sharedModels.NotificationCollection();
     var dispatcher = new loop.Dispatcher();
     var roomStore = new loop.store.RoomStore(dispatcher, {
       mozLoop: navigator.mozLoop,
       notifications: notifications
     });
 
     React.render(React.createElement(PanelView, {
+      dispatcher: dispatcher, 
+      mozLoop: navigator.mozLoop, 
       notifications: notifications, 
-      roomStore: roomStore, 
-      mozLoop: navigator.mozLoop, 
-      dispatcher: dispatcher}), document.querySelector("#main"));
+      roomStore: roomStore}), document.querySelector("#main"));
 
     document.documentElement.setAttribute("lang", mozL10n.getLanguage());
     document.documentElement.setAttribute("dir", mozL10n.getDirection());
     document.body.setAttribute("platform", loop.shared.utils.getPlatform());
 
     // Notify the window that we've finished initalization and initial layout
     var evtObject = document.createEvent("Event");
     evtObject.initEvent("loopPanelInitialized", true, false);
--- a/browser/components/loop/content/js/panel.jsx
+++ b/browser/components/loop/content/js/panel.jsx
@@ -15,19 +15,19 @@ loop.panel = (function(_, mozL10n) {
   var ButtonGroup = sharedViews.ButtonGroup;
   var Checkbox = sharedViews.Checkbox;
   var ContactsList = loop.contacts.ContactsList;
   var ContactDetailsForm = loop.contacts.ContactDetailsForm;
 
   var TabView = React.createClass({
     propTypes: {
       buttonsHidden: React.PropTypes.array,
+      mozLoop: React.PropTypes.object,
       // The selectedTab prop is used by the UI showcase.
-      selectedTab: React.PropTypes.string,
-      mozLoop: React.PropTypes.object
+      selectedTab: React.PropTypes.string
     },
 
     getDefaultProps: function() {
       return {
         buttonsHidden: []
       };
     },
 
@@ -77,24 +77,24 @@ loop.panel = (function(_, mozL10n) {
         var tabName = tab.props.name;
         if (this.props.buttonsHidden.indexOf(tabName) > -1) {
           return;
         }
         var isSelected = (this.state.selectedTab == tabName);
         if (!tab.props.hidden) {
           tabButtons.push(
             <li className={cx({selected: isSelected})}
+                data-tab-name={tabName}
                 key={i}
-                data-tab-name={tabName}
-                title={mozL10n.get(tabName + "_tab_button_tooltip")}
-                onClick={this.handleSelectTab} />
+                onClick={this.handleSelectTab}
+                title={mozL10n.get(tabName + "_tab_button_tooltip")} />
           );
         }
         tabs.push(
-          <div key={i} className={cx({tab: true, selected: isSelected})}>
+          <div className={cx({tab: true, selected: isSelected})} key={i}>
             {tab.props.children}
           </div>
         );
       }, this);
       return (
         <div className="tab-view-container">
           <ul className="tab-view">{tabButtons}</ul>
           {tabs}
@@ -159,23 +159,23 @@ loop.panel = (function(_, mozL10n) {
 
       return (
         <div className="dropdown">
           <p className="dnd-status" onClick={this.toggleDropdownMenu} ref="menu-button">
             <span>{availabilityText}</span>
             <i className={availabilityStatus}></i>
           </p>
           <ul className={availabilityDropdown}>
-            <li onClick={this.changeAvailability("available")}
-                className="dropdown-menu-item dnd-make-available">
+            <li className="dropdown-menu-item dnd-make-available"
+                onClick={this.changeAvailability("available")}>
               <i className="status status-available"></i>
               <span>{mozL10n.get("display_name_available_status")}</span>
             </li>
-            <li onClick={this.changeAvailability("do-not-disturb")}
-                className="dropdown-menu-item dnd-make-unavailable">
+            <li className="dropdown-menu-item dnd-make-unavailable"
+                onClick={this.changeAvailability("do-not-disturb")}>
               <i className="status status-dnd"></i>
               <span>{mozL10n.get("display_name_dnd_status")}</span>
             </li>
           </ul>
         </div>
       );
     }
   });
@@ -197,19 +197,19 @@ loop.panel = (function(_, mozL10n) {
       }
       return (
         <div id="fte-getstarted">
           <header id="fte-title">
             {mozL10n.get("first_time_experience_title", {
               "clientShortname": mozL10n.get("clientShortname2")
             })}
           </header>
-          <Button htmlId="fte-button"
-                  onClick={this.handleButtonClick}
-                  caption={mozL10n.get("first_time_experience_button_label")} />
+          <Button caption={mozL10n.get("first_time_experience_button_label")}
+                  htmlId="fte-button"
+                  onClick={this.handleButtonClick} />
         </div>
       );
     }
   });
 
   /**
    * Displays a view requesting the user to sign-in again.
    */
@@ -286,19 +286,19 @@ loop.panel = (function(_, mozL10n) {
     renderPartnerLogo: function() {
       if (!this.state.showPartnerLogo) {
         return null;
       }
 
       var locale = mozL10n.getLanguage();
       navigator.mozLoop.setLoopPref("showPartnerLogo", false);
       return (
-        <p id="powered-by" className="powered-by">
+        <p className="powered-by" id="powered-by">
           {mozL10n.get("powered_by_beforeLogo")}
-          <img id="powered-by-logo" className={locale} />
+          <img className={locale} id="powered-by-logo" />
           {mozL10n.get("powered_by_afterLogo")}
         </p>
       );
     },
 
     render: function() {
       if (!this.state.gettingStartedSeen || this.state.seenToS == "unseen") {
         var terms_of_use_url = navigator.mozLoop.getLoopPref("legal.ToS_url");
@@ -330,32 +330,32 @@ loop.panel = (function(_, mozL10n) {
     }
   });
 
   /**
    * Panel settings (gear) menu entry.
    */
   var SettingsDropdownEntry = React.createClass({
     propTypes: {
-      onClick: React.PropTypes.func.isRequired,
+      displayed: React.PropTypes.bool,
+      icon: React.PropTypes.string,
       label: React.PropTypes.string.isRequired,
-      icon: React.PropTypes.string,
-      displayed: React.PropTypes.bool
+      onClick: React.PropTypes.func.isRequired
     },
 
     getDefaultProps: function() {
       return {displayed: true};
     },
 
     render: function() {
       if (!this.props.displayed) {
         return null;
       }
       return (
-        <li onClick={this.props.onClick} className="dropdown-menu-item">
+        <li className="dropdown-menu-item" onClick={this.props.onClick}>
           {this.props.icon ?
             <i className={"icon icon-" + this.props.icon}></i> :
             null}
           <span>{this.props.label}</span>
         </li>
       );
     }
   });
@@ -405,39 +405,39 @@ loop.panel = (function(_, mozL10n) {
 
     render: function() {
       var cx = React.addons.classSet;
 
       return (
         <div className="settings-menu dropdown">
           <a className="button-settings"
              onClick={this.toggleDropdownMenu}
-             title={mozL10n.get("settings_menu_button_tooltip")}
-             ref="menu-button" />
+             ref="menu-button"
+             title={mozL10n.get("settings_menu_button_tooltip")} />
           <ul className={cx({"dropdown-menu": true, hide: !this.state.showMenu})}>
-            <SettingsDropdownEntry label={mozL10n.get("settings_menu_item_settings")}
-                                   onClick={this.handleClickSettingsEntry}
-                                   displayed={false}
-                                   icon="settings" />
-            <SettingsDropdownEntry label={mozL10n.get("settings_menu_item_account")}
-                                   onClick={this.handleClickAccountEntry}
+            <SettingsDropdownEntry displayed={false}
+                                   icon="settings"
+                                   label={mozL10n.get("settings_menu_item_settings")}
+                                   onClick={this.handleClickSettingsEntry} />
+            <SettingsDropdownEntry displayed={this._isSignedIn() && this.props.mozLoop.fxAEnabled}
                                    icon="account"
-                                   displayed={this._isSignedIn() && this.props.mozLoop.fxAEnabled} />
+                                   label={mozL10n.get("settings_menu_item_account")}
+                                   onClick={this.handleClickAccountEntry} />
             <SettingsDropdownEntry icon="tour"
                                    label={mozL10n.get("tour_label")}
                                    onClick={this.openGettingStartedTour} />
-            <SettingsDropdownEntry label={this._isSignedIn() ?
+            <SettingsDropdownEntry displayed={this.props.mozLoop.fxAEnabled}
+                                   icon={this._isSignedIn() ? "signout" : "signin"}
+                                   label={this._isSignedIn() ?
                                           mozL10n.get("settings_menu_item_signout") :
                                           mozL10n.get("settings_menu_item_signin")}
-                                   onClick={this.handleClickAuthEntry}
-                                   displayed={this.props.mozLoop.fxAEnabled}
-                                   icon={this._isSignedIn() ? "signout" : "signin"} />
-            <SettingsDropdownEntry label={mozL10n.get("help_label")}
-                                   onClick={this.handleHelpEntry}
-                                   icon="help" />
+                                   onClick={this.handleClickAuthEntry} />
+            <SettingsDropdownEntry icon="help"
+                                   label={mozL10n.get("help_label")}
+                                   onClick={this.handleHelpEntry} />
           </ul>
         </div>
       );
     }
   });
 
   /**
    * FxA sign in/up link component.
@@ -495,17 +495,17 @@ loop.panel = (function(_, mozL10n) {
     render: function() {
       var roomUrl = this.props.roomUrls && this.props.roomUrls[0];
       if (!roomUrl) {
         return null;
       }
 
       return (
         <div className="room-entry-context-item">
-          <a href={roomUrl.location} title={roomUrl.description} onClick={this.handleClick}>
+          <a href={roomUrl.location} onClick={this.handleClick} title={roomUrl.description}>
             <img src={roomUrl.thumbnail || "loop/shared/img/icons-16x16.svg#globe"} />
           </a>
         </div>
       );
     }
   });
 
   /**
@@ -582,45 +582,45 @@ loop.panel = (function(_, mozL10n) {
         "room-active": this._isActive()
       });
       var copyButtonClasses = React.addons.classSet({
         "copy-link": true,
         "checked": this.state.urlCopied
       });
 
       return (
-        <div className={roomClasses} onMouseLeave={this.handleMouseLeave}
-             onClick={this.handleClickEntry}>
+        <div className={roomClasses} onClick={this.handleClickEntry}
+             onMouseLeave={this.handleMouseLeave}>
           <h2>
             <span className="room-notification" />
             {this.props.room.decryptedContext.roomName}
             <button className={copyButtonClasses}
-              title={mozL10n.get("rooms_list_copy_url_tooltip")}
-              onClick={this.handleCopyButtonClick} />
+              onClick={this.handleCopyButtonClick}
+              title={mozL10n.get("rooms_list_copy_url_tooltip")} />
             <button className="delete-link"
-              title={mozL10n.get("rooms_list_delete_tooltip")}
-              onClick={this.handleDeleteButtonClick} />
+              onClick={this.handleDeleteButtonClick}
+              title={mozL10n.get("rooms_list_delete_tooltip")} />
           </h2>
           <RoomEntryContextItem mozLoop={this.props.mozLoop}
                                 roomUrls={this.props.room.decryptedContext.urls} />
         </div>
       );
     }
   });
 
   /**
    * Room list.
    */
   var RoomList = React.createClass({
     mixins: [Backbone.Events, sharedMixins.WindowCloseMixin],
 
     propTypes: {
+      dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
       mozLoop: React.PropTypes.object.isRequired,
       store: React.PropTypes.instanceOf(loop.store.RoomStore).isRequired,
-      dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
       userDisplayName: React.PropTypes.string.isRequired  // for room creation
     },
 
     getInitialState: function() {
       return this.props.store.getStoreState();
     },
 
     componentDidMount: function() {
@@ -665,21 +665,20 @@ loop.panel = (function(_, mozL10n) {
 
       return (
         <div className="rooms">
           <h1>{this._getListHeading()}</h1>
           <div className="room-list">{
             this.state.rooms.map(function(room, i) {
               return (
                 <RoomEntry
+                  dispatcher={this.props.dispatcher}
                   key={room.roomToken}
-                  dispatcher={this.props.dispatcher}
                   mozLoop={this.props.mozLoop}
-                  room={room}
-                />
+                  room={room} />
               );
             }, this)
           }</div>
           <NewRoomView dispatcher={this.props.dispatcher}
             mozLoop={this.props.mozLoop}
             pendingOperation={this.state.pendingCreation ||
               this.state.pendingInitialRetrieval}
             userDisplayName={this.props.userDisplayName} />
@@ -783,40 +782,40 @@ loop.panel = (function(_, mozL10n) {
               allowClick={false}
               description={this.state.description}
               showContextTitle={false}
               thumbnail={this.state.previewImage}
               url={this.state.url}
               useDesktopPaths={true} />
           </div>
           <button className="btn btn-info new-room-button"
-                  onClick={this.handleCreateButtonClick}
-                  disabled={this.props.pendingOperation}>
+                  disabled={this.props.pendingOperation}
+                  onClick={this.handleCreateButtonClick}>
             {mozL10n.get("rooms_new_room_button_label")}
           </button>
         </div>
       );
     }
   });
 
   /**
    * Panel view.
    */
   var PanelView = React.createClass({
     propTypes: {
+      dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
+      mozLoop: React.PropTypes.object.isRequired,
       notifications: React.PropTypes.object.isRequired,
-      // Mostly used for UI components showcase and unit tests
-      userProfile: React.PropTypes.object,
+      roomStore:
+        React.PropTypes.instanceOf(loop.store.RoomStore).isRequired,
+      selectedTab: React.PropTypes.string,
       // Used only for unit tests.
       showTabButtons: React.PropTypes.bool,
-      selectedTab: React.PropTypes.string,
-      dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
-      mozLoop: React.PropTypes.object.isRequired,
-      roomStore:
-        React.PropTypes.instanceOf(loop.store.RoomStore).isRequired
+      // Mostly used for UI components showcase and unit tests
+      userProfile: React.PropTypes.object
     },
 
     getInitialState: function() {
       return {
         hasEncryptionKey: this.props.mozLoop.hasEncryptionKey,
         userProfile: this.props.userProfile || this.props.mozLoop.userProfile,
         gettingStartedSeen: this.props.mozLoop.getLoopPref("gettingStarted.seen")
       };
@@ -918,18 +917,19 @@ loop.panel = (function(_, mozL10n) {
     },
 
     render: function() {
       var NotificationListView = sharedViews.NotificationListView;
 
       if (!this.state.gettingStartedSeen) {
         return (
           <div>
-            <NotificationListView notifications={this.props.notifications}
-                                  clearOnDocumentHidden={true} />
+            <NotificationListView
+              clearOnDocumentHidden={true}
+              notifications={this.props.notifications} />
             <GettingStartedView />
             <ToSView />
           </div>
         );
       }
 
       if (!this.state.hasEncryptionKey) {
         return <SignInRequestView mozLoop={this.props.mozLoop} />;
@@ -938,43 +938,54 @@ loop.panel = (function(_, mozL10n) {
       // Determine which buttons to NOT show.
       var hideButtons = [];
       if (!this.state.userProfile && !this.props.showTabButtons) {
         hideButtons.push("contacts");
       }
 
       return (
         <div>
-          <NotificationListView notifications={this.props.notifications}
-                                clearOnDocumentHidden={true} />
-          <TabView ref="tabView" selectedTab={this.props.selectedTab}
-            buttonsHidden={hideButtons} mozLoop={this.props.mozLoop}>
+          <NotificationListView
+            clearOnDocumentHidden={true}
+            notifications={this.props.notifications} />
+          <TabView
+            buttonsHidden={hideButtons}
+            mozLoop={this.props.mozLoop}
+            ref="tabView"
+            selectedTab={this.props.selectedTab}>
             <Tab name="rooms">
               <RoomList dispatcher={this.props.dispatcher}
+                        mozLoop={this.props.mozLoop}
                         store={this.props.roomStore}
-                        userDisplayName={this._getUserDisplayName()}
-                        mozLoop={this.props.mozLoop}/>
+                        userDisplayName={this._getUserDisplayName()} />
               <ToSView />
             </Tab>
             <Tab name="contacts">
-              <ContactsList selectTab={this.selectTab}
-                            startForm={this.startForm}
-                            notifications={this.props.notifications} />
+              <ContactsList
+                notifications={this.props.notifications}
+                selectTab={this.selectTab}
+                startForm={this.startForm} />
             </Tab>
-            <Tab name="contacts_add" hidden={true}>
-              <ContactDetailsForm ref="contacts_add" mode="add"
-                                  selectTab={this.selectTab} />
+            <Tab hidden={true} name="contacts_add">
+              <ContactDetailsForm
+                mode="add"
+                ref="contacts_add"
+                selectTab={this.selectTab} />
             </Tab>
-            <Tab name="contacts_edit" hidden={true}>
-              <ContactDetailsForm ref="contacts_edit" mode="edit"
-                                  selectTab={this.selectTab} />
+            <Tab hidden={true} name="contacts_edit">
+              <ContactDetailsForm
+                mode="edit"
+                ref="contacts_edit"
+                selectTab={this.selectTab} />
             </Tab>
-            <Tab name="contacts_import" hidden={true}>
-              <ContactDetailsForm ref="contacts_import" mode="import"
-                                  selectTab={this.selectTab}/>
+            <Tab hidden={true} name="contacts_import">
+              <ContactDetailsForm
+                mode="import"
+                ref="contacts_import"
+                selectTab={this.selectTab}/>
             </Tab>
           </TabView>
           <div className="footer">
             <div className="user-details">
               <UserIdentity displayName={this._getUserDisplayName()} />
               <AvailabilityDropdown />
             </div>
             <div className="signin-details">
@@ -999,20 +1010,20 @@ loop.panel = (function(_, mozL10n) {
     var notifications = new sharedModels.NotificationCollection();
     var dispatcher = new loop.Dispatcher();
     var roomStore = new loop.store.RoomStore(dispatcher, {
       mozLoop: navigator.mozLoop,
       notifications: notifications
     });
 
     React.render(<PanelView
+      dispatcher={dispatcher}
+      mozLoop={navigator.mozLoop}
       notifications={notifications}
-      roomStore={roomStore}
-      mozLoop={navigator.mozLoop}
-      dispatcher={dispatcher} />, document.querySelector("#main"));
+      roomStore={roomStore} />, document.querySelector("#main"));
 
     document.documentElement.setAttribute("lang", mozL10n.getLanguage());
     document.documentElement.setAttribute("dir", mozL10n.getDirection());
     document.body.setAttribute("platform", loop.shared.utils.getPlatform());
 
     // Notify the window that we've finished initalization and initial layout
     var evtObject = document.createEvent("Event");
     evtObject.initEvent("loopPanelInitialized", true, false);
--- a/browser/components/loop/content/js/roomViews.js
+++ b/browser/components/loop/content/js/roomViews.js
@@ -124,18 +124,18 @@ loop.roomViews = (function(mozL10n) {
             React.createElement("i", {className: "icon icon-add-share-service"}), 
             React.createElement("span", null, mozL10n.get("share_add_service_button"))
           ), 
           this.props.socialShareProviders.length ? React.createElement("li", {className: "dropdown-menu-separator"}) : null, 
           
             this.props.socialShareProviders.map(function(provider, idx) {
               return (
                 React.createElement("li", {className: "dropdown-menu-item", 
+                    "data-provider": provider.origin, 
                     key: "provider-" + idx, 
-                    "data-provider": provider.origin, 
                     onClick: this.handleProviderClick}, 
                   React.createElement("img", {className: "icon", src: provider.iconURL}), 
                   React.createElement("span", null, provider.name)
                 )
               );
             }.bind(this))
           
         )
@@ -244,35 +244,35 @@ loop.roomViews = (function(mozL10n) {
               mozL10n.get("email_link_button")
             ), 
             React.createElement("button", {className: "btn btn-info btn-copy", 
                     onClick: this.handleCopyButtonClick}, 
               this.state.copiedUrl ? mozL10n.get("copied_url_button") :
                                       mozL10n.get("copy_url_button2")
             ), 
             React.createElement("button", {className: "btn btn-info btn-share", 
-                    ref: "anchor", 
-                    onClick: this.handleShareButtonClick}, 
+                    onClick: this.handleShareButtonClick, 
+                    ref: "anchor"}, 
               mozL10n.get("share_button3")
             )
           ), 
           React.createElement(SocialShareDropdown, {
             dispatcher: this.props.dispatcher, 
+            ref: "menu", 
             roomUrl: this.props.roomData.roomUrl, 
             show: this.state.showMenu, 
-            socialShareProviders: this.props.socialShareProviders, 
-            ref: "menu"}), 
+            socialShareProviders: this.props.socialShareProviders}), 
           React.createElement(DesktopRoomContextView, {
             dispatcher: this.props.dispatcher, 
             editMode: this.state.editMode, 
             error: this.props.error, 
-            savingContext: this.props.savingContext, 
             mozLoop: this.props.mozLoop, 
             onEditModeChange: this.handleEditModeChange, 
             roomData: this.props.roomData, 
+            savingContext: this.props.savingContext, 
             show: this.props.showContext || this.state.editMode})
         )
       );
     }
   });
 
   var DesktopRoomContextView = React.createClass({displayName: "DesktopRoomContextView",
     mixins: [React.addons.LinkedStateMixin],
@@ -514,28 +514,31 @@ loop.roomViews = (function(mozL10n) {
             React.createElement(sharedViews.Checkbox, {
               additionalClass: cx({ hide: !checkboxLabel }), 
               checked: checked, 
               disabled: checked, 
               label: checkboxLabel, 
               onChange: this.handleCheckboxChange, 
               value: location}), 
             React.createElement("form", {onSubmit: this.handleFormSubmit}, 
-              React.createElement("input", {type: "text", className: "room-context-name", 
+              React.createElement("input", {className: "room-context-name", 
                 onKeyDown: this.handleTextareaKeyDown, 
                 placeholder: mozL10n.get("context_edit_name_placeholder"), 
+                type: "text", 
                 valueLink: this.linkState("newRoomName")}), 
-              React.createElement("input", {type: "text", className: "room-context-url", 
+              React.createElement("input", {className: "room-context-url", 
+                disabled: availableContext && availableContext.url === this.state.newRoomURL, 
                 onKeyDown: this.handleTextareaKeyDown, 
                 placeholder: "https://", 
-                disabled: availableContext && availableContext.url === this.state.newRoomURL, 
+                type: "text", 
                 valueLink: this.linkState("newRoomURL")}), 
-              React.createElement("textarea", {rows: "3", type: "text", className: "room-context-comments", 
+              React.createElement("textarea", {className: "room-context-comments", 
                 onKeyDown: this.handleTextareaKeyDown, 
                 placeholder: mozL10n.get("context_edit_comments_placeholder"), 
+                rows: "3", type: "text", 
                 valueLink: this.linkState("newRoomDescription")})
             ), 
             React.createElement("button", {className: "btn btn-info", 
                     disabled: this.props.savingContext, 
                     onClick: this.handleFormSubmit}, 
               mozL10n.get("context_save_label2")
             ), 
             React.createElement("button", {className: "room-context-btn-close", 
@@ -582,19 +585,19 @@ loop.roomViews = (function(mozL10n) {
       sharedMixins.DocumentTitleMixin,
       sharedMixins.MediaSetupMixin,
       sharedMixins.RoomsAudioMixin,
       sharedMixins.WindowCloseMixin
     ],
 
     propTypes: {
       dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
-      mozLoop: React.PropTypes.object.isRequired,
       // The poster URLs are for UI-showcase testing and development.
       localPosterUrl: React.PropTypes.string,
+      mozLoop: React.PropTypes.object.isRequired,
       remotePosterUrl: React.PropTypes.string
     },
 
     componentWillUpdate: function(nextProps, nextState) {
       // The SDK needs to know about the configuration and the elements to use
       // for display. So the best way seems to pass the information here - ideally
       // the sdk wouldn't need to know this, but we can't change that.
       if (this.state.roomState !== ROOM_STATES.MEDIA_WAIT &&
@@ -764,45 +767,45 @@ loop.roomViews = (function(mozL10n) {
                 showContext: shouldRenderContextView, 
                 socialShareProviders: this.state.socialShareProviders}), 
               React.createElement("div", {className: "video-layout-wrapper"}, 
                 React.createElement("div", {className: "conversation room-conversation"}, 
                   React.createElement("div", {className: "media nested"}, 
                     React.createElement("div", {className: "video_wrapper remote_wrapper"}, 
                       React.createElement("div", {className: "video_inner remote focus-stream"}, 
                         React.createElement(sharedViews.MediaView, {displayAvatar: !this.shouldRenderRemoteVideo(), 
-                          posterUrl: this.props.remotePosterUrl, 
                           isLoading: this._shouldRenderRemoteLoading(), 
                           mediaType: "remote", 
+                          posterUrl: this.props.remotePosterUrl, 
                           srcVideoObject: this.state.remoteSrcVideoObject})
                       )
                     ), 
                     React.createElement("div", {className: localStreamClasses}, 
                       React.createElement(sharedViews.MediaView, {displayAvatar: this.state.videoMuted, 
-                        posterUrl: this.props.localPosterUrl, 
                         isLoading: this._shouldRenderLocalLoading(), 
                         mediaType: "local", 
+                        posterUrl: this.props.localPosterUrl, 
                         srcVideoObject: this.state.localSrcVideoObject})
                     )
                   ), 
                   React.createElement(sharedViews.ConversationToolbar, {
+                    audio: {enabled: !this.state.audioMuted, visible: true}, 
                     dispatcher: this.props.dispatcher, 
-                    video: {enabled: !this.state.videoMuted, visible: true}, 
-                    audio: {enabled: !this.state.audioMuted, visible: true}, 
+                    hangup: this.leaveRoom, 
                     publishStream: this.publishStream, 
-                    hangup: this.leaveRoom, 
-                    screenShare: screenShareData})
+                    screenShare: screenShareData, 
+                    video: {enabled: !this.state.videoMuted, visible: true}})
                 )
               ), 
               React.createElement(DesktopRoomContextView, {
                 dispatcher: this.props.dispatcher, 
                 error: this.state.error, 
-                savingContext: this.state.savingContext, 
                 mozLoop: this.props.mozLoop, 
                 roomData: roomData, 
+                savingContext: this.state.savingContext, 
                 show: !shouldRenderInvitationOverlay && shouldRenderContextView}), 
               React.createElement(sharedViews.TextChatView, {
                 dispatcher: this.props.dispatcher, 
                 showAlways: false, 
                 showRoomName: false})
             )
           );
         }
--- a/browser/components/loop/content/js/roomViews.jsx
+++ b/browser/components/loop/content/js/roomViews.jsx
@@ -124,18 +124,18 @@ loop.roomViews = (function(mozL10n) {
             <i className="icon icon-add-share-service"></i>
             <span>{mozL10n.get("share_add_service_button")}</span>
           </li>
           {this.props.socialShareProviders.length ? <li className="dropdown-menu-separator"/> : null}
           {
             this.props.socialShareProviders.map(function(provider, idx) {
               return (
                 <li className="dropdown-menu-item"
+                    data-provider={provider.origin}
                     key={"provider-" + idx}
-                    data-provider={provider.origin}
                     onClick={this.handleProviderClick}>
                   <img className="icon" src={provider.iconURL}/>
                   <span>{provider.name}</span>
                 </li>
               );
             }.bind(this))
           }
         </ul>
@@ -244,35 +244,35 @@ loop.roomViews = (function(mozL10n) {
               {mozL10n.get("email_link_button")}
             </button>
             <button className="btn btn-info btn-copy"
                     onClick={this.handleCopyButtonClick}>
               {this.state.copiedUrl ? mozL10n.get("copied_url_button") :
                                       mozL10n.get("copy_url_button2")}
             </button>
             <button className="btn btn-info btn-share"
-                    ref="anchor"
-                    onClick={this.handleShareButtonClick}>
+                    onClick={this.handleShareButtonClick}
+                    ref="anchor">
               {mozL10n.get("share_button3")}
             </button>
           </div>
           <SocialShareDropdown
             dispatcher={this.props.dispatcher}
+            ref="menu"
             roomUrl={this.props.roomData.roomUrl}
             show={this.state.showMenu}
-            socialShareProviders={this.props.socialShareProviders}
-            ref="menu" />
+            socialShareProviders={this.props.socialShareProviders} />
           <DesktopRoomContextView
             dispatcher={this.props.dispatcher}
             editMode={this.state.editMode}
             error={this.props.error}
-            savingContext={this.props.savingContext}
             mozLoop={this.props.mozLoop}
             onEditModeChange={this.handleEditModeChange}
             roomData={this.props.roomData}
+            savingContext={this.props.savingContext}
             show={this.props.showContext || this.state.editMode} />
         </div>
       );
     }
   });
 
   var DesktopRoomContextView = React.createClass({
     mixins: [React.addons.LinkedStateMixin],
@@ -514,28 +514,31 @@ loop.roomViews = (function(mozL10n) {
             <sharedViews.Checkbox
               additionalClass={cx({ hide: !checkboxLabel })}
               checked={checked}
               disabled={checked}
               label={checkboxLabel}
               onChange={this.handleCheckboxChange}
               value={location} />
             <form onSubmit={this.handleFormSubmit}>
-              <input type="text" className="room-context-name"
+              <input className="room-context-name"
                 onKeyDown={this.handleTextareaKeyDown}
                 placeholder={mozL10n.get("context_edit_name_placeholder")}
+                type="text"
                 valueLink={this.linkState("newRoomName")} />
-              <input type="text" className="room-context-url"
+              <input className="room-context-url"
+                disabled={availableContext && availableContext.url === this.state.newRoomURL}
                 onKeyDown={this.handleTextareaKeyDown}
                 placeholder="https://"
-                disabled={availableContext && availableContext.url === this.state.newRoomURL}
+                type="text"
                 valueLink={this.linkState("newRoomURL")} />
-              <textarea rows="3" type="text" className="room-context-comments"
+              <textarea className="room-context-comments"
                 onKeyDown={this.handleTextareaKeyDown}
                 placeholder={mozL10n.get("context_edit_comments_placeholder")}
+                rows="3" type="text"
                 valueLink={this.linkState("newRoomDescription")} />
             </form>
             <button className="btn btn-info"
                     disabled={this.props.savingContext}
                     onClick={this.handleFormSubmit}>
               {mozL10n.get("context_save_label2")}
             </button>
             <button className="room-context-btn-close"
@@ -582,19 +585,19 @@ loop.roomViews = (function(mozL10n) {
       sharedMixins.DocumentTitleMixin,
       sharedMixins.MediaSetupMixin,
       sharedMixins.RoomsAudioMixin,
       sharedMixins.WindowCloseMixin
     ],
 
     propTypes: {
       dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
-      mozLoop: React.PropTypes.object.isRequired,
       // The poster URLs are for UI-showcase testing and development.
       localPosterUrl: React.PropTypes.string,
+      mozLoop: React.PropTypes.object.isRequired,
       remotePosterUrl: React.PropTypes.string
     },
 
     componentWillUpdate: function(nextProps, nextState) {
       // The SDK needs to know about the configuration and the elements to use
       // for display. So the best way seems to pass the information here - ideally
       // the sdk wouldn't need to know this, but we can't change that.
       if (this.state.roomState !== ROOM_STATES.MEDIA_WAIT &&
@@ -764,45 +767,45 @@ loop.roomViews = (function(mozL10n) {
                 showContext={shouldRenderContextView}
                 socialShareProviders={this.state.socialShareProviders} />
               <div className="video-layout-wrapper">
                 <div className="conversation room-conversation">
                   <div className="media nested">
                     <div className="video_wrapper remote_wrapper">
                       <div className="video_inner remote focus-stream">
                         <sharedViews.MediaView displayAvatar={!this.shouldRenderRemoteVideo()}
-                          posterUrl={this.props.remotePosterUrl}
                           isLoading={this._shouldRenderRemoteLoading()}
                           mediaType="remote"
+                          posterUrl={this.props.remotePosterUrl}
                           srcVideoObject={this.state.remoteSrcVideoObject} />
                       </div>
                     </div>
                     <div className={localStreamClasses}>
                       <sharedViews.MediaView displayAvatar={this.state.videoMuted}
-                        posterUrl={this.props.localPosterUrl}
                         isLoading={this._shouldRenderLocalLoading()}
                         mediaType="local"
+                        posterUrl={this.props.localPosterUrl}
                         srcVideoObject={this.state.localSrcVideoObject} />
                     </div>
                   </div>
                   <sharedViews.ConversationToolbar
+                    audio={{enabled: !this.state.audioMuted, visible: true}}
                     dispatcher={this.props.dispatcher}
-                    video={{enabled: !this.state.videoMuted, visible: true}}
-                    audio={{enabled: !this.state.audioMuted, visible: true}}
+                    hangup={this.leaveRoom}
                     publishStream={this.publishStream}
-                    hangup={this.leaveRoom}
-                    screenShare={screenShareData} />
+                    screenShare={screenShareData}
+                    video={{enabled: !this.state.videoMuted, visible: true}} />
                 </div>
               </div>
               <DesktopRoomContextView
                 dispatcher={this.props.dispatcher}
                 error={this.state.error}
-                savingContext={this.state.savingContext}
                 mozLoop={this.props.mozLoop}
                 roomData={roomData}
+                savingContext={this.state.savingContext}
                 show={!shouldRenderInvitationOverlay && shouldRenderContextView} />
               <sharedViews.TextChatView
                 dispatcher={this.props.dispatcher}
                 showAlways={false}
                 showRoomName={false} />
             </div>
           );
         }
--- a/browser/components/loop/content/shared/js/feedbackViews.js
+++ b/browser/components/loop/content/shared/js/feedbackViews.js
@@ -19,26 +19,27 @@ loop.shared.views.FeedbackView = (functi
    * Feedback outer layout.
    *
    * Props:
    * -
    */
   var FeedbackLayout = React.createClass({displayName: "FeedbackLayout",
     propTypes: {
       children: React.PropTypes.component.isRequired,
-      title: React.PropTypes.string.isRequired,
-      reset: React.PropTypes.func // if not specified, no Back btn is shown
+      reset: React.PropTypes.func, // if not specified, no Back btn is shown
+      title: React.PropTypes.string.isRequired
     },
 
     render: function() {
       var backButton = React.createElement("div", null);
       if (this.props.reset) {
         backButton = (
-          React.createElement("button", {className: "fx-embedded-btn-back", type: "button", 
-                  onClick: this.props.reset}, 
+          React.createElement("button", {className: "fx-embedded-btn-back", 
+            onClick: this.props.reset, 
+            type: "button"}, 
             "« ", l10n.get("feedback_back_button")
           )
         );
       }
       return (
         React.createElement("div", {className: "feedback"}, 
           backButton, 
           React.createElement("h3", null, this.props.title), 
@@ -75,22 +76,25 @@ loop.shared.views.FeedbackView = (functi
         other: l10n.get("feedback_category_other2")
       };
     },
 
     _getCategoryFields: function() {
       var categories = this._getCategories();
       return Object.keys(categories).map(function(category, key) {
         return (
-          React.createElement("label", {key: key, className: "feedback-category-label"}, 
-            React.createElement("input", {type: "radio", ref: "category", name: "category", 
-                   className: "feedback-category-radio", 
-                   value: category, 
-                   onChange: this.handleCategoryChange, 
-                   checked: this.state.category === category}), 
+          React.createElement("label", {className: "feedback-category-label", key: key}, 
+            React.createElement("input", {
+              checked: this.state.category === category, 
+              className: "feedback-category-radio", 
+              name: "category", 
+              onChange: this.handleCategoryChange, 
+              ref: "category", 
+              type: "radio", 
+              value: category}), 
             categories[category]
           )
         );
       }, this);
     },
 
     /**
      * Checks if the form is ready for submission:
@@ -133,30 +137,34 @@ loop.shared.views.FeedbackView = (functi
         happy: false,
         category: this.state.category,
         description: this.state.description
       }));
     },
 
     render: function() {
       return (
-        React.createElement(FeedbackLayout, {title: l10n.get("feedback_category_list_heading"), 
-                        reset: this.props.reset}, 
+        React.createElement(FeedbackLayout, {
+          reset: this.props.reset, 
+          title: l10n.get("feedback_category_list_heading")}, 
           React.createElement("form", {onSubmit: this.handleFormSubmit}, 
             this._getCategoryFields(), 
             React.createElement("p", null, 
-              React.createElement("input", {type: "text", ref: "description", name: "description", 
-                className: "feedback-description", 
+              React.createElement("input", {className: "feedback-description", 
+                name: "description", 
                 onChange: this.handleDescriptionFieldChange, 
-                value: this.state.description, 
                 placeholder: 
-                  l10n.get("feedback_custom_category_text_placeholder")})
+                  l10n.get("feedback_custom_category_text_placeholder"), 
+                ref: "description", 
+                type: "text", 
+                value: this.state.description})
             ), 
-            React.createElement("button", {type: "submit", className: "btn btn-success", 
-                    disabled: !this._isFormReady()}, 
+            React.createElement("button", {className: "btn btn-success", 
+              disabled: !this._isFormReady(), 
+              type: "submit"}, 
               l10n.get("feedback_submit_button")
             )
           )
         )
       );
     }
   });
 
@@ -224,20 +232,20 @@ loop.shared.views.FeedbackView = (functi
    */
   var FeedbackView = React.createClass({displayName: "FeedbackView",
     mixins: [
       Backbone.Events,
       loop.store.StoreMixin("feedbackStore")
     ],
 
     propTypes: {
-      onAfterFeedbackReceived: React.PropTypes.func,
       // Used by the UI showcase.
       feedbackState: React.PropTypes.string,
-      noCloseText: React.PropTypes.bool
+      noCloseText: React.PropTypes.bool,
+      onAfterFeedbackReceived: React.PropTypes.func
     },
 
     getInitialState: function() {
       var storeState = this.getStoreState();
       return _.extend({}, storeState, {
         feedbackState: this.props.feedbackState || storeState.feedbackState
       });
     },
@@ -284,18 +292,18 @@ loop.shared.views.FeedbackView = (functi
               )
             )
           );
         }
         case FEEDBACK_STATES.DETAILS: {
           return (
             React.createElement(FeedbackForm, {
               feedbackStore: this.getStore(), 
-              reset: this.reset, 
-              pending: this.state.feedbackState === FEEDBACK_STATES.PENDING})
+              pending: this.state.feedbackState === FEEDBACK_STATES.PENDING, 
+              reset: this.reset})
             );
         }
         case FEEDBACK_STATES.PENDING:
         case FEEDBACK_STATES.SENT:
         case FEEDBACK_STATES.FAILED: {
           if (this.state.error) {
             // XXX better end user error reporting, see bug 1046738
             console.error("Error encountered while submitting feedback",
--- a/browser/components/loop/content/shared/js/feedbackViews.jsx
+++ b/browser/components/loop/content/shared/js/feedbackViews.jsx
@@ -19,26 +19,27 @@ loop.shared.views.FeedbackView = (functi
    * Feedback outer layout.
    *
    * Props:
    * -
    */
   var FeedbackLayout = React.createClass({
     propTypes: {
       children: React.PropTypes.component.isRequired,
-      title: React.PropTypes.string.isRequired,
-      reset: React.PropTypes.func // if not specified, no Back btn is shown
+      reset: React.PropTypes.func, // if not specified, no Back btn is shown
+      title: React.PropTypes.string.isRequired
     },
 
     render: function() {
       var backButton = <div />;
       if (this.props.reset) {
         backButton = (
-          <button className="fx-embedded-btn-back" type="button"
-                  onClick={this.props.reset}>
+          <button className="fx-embedded-btn-back"
+            onClick={this.props.reset}
+            type="button" >
             &laquo;&nbsp;{l10n.get("feedback_back_button")}
           </button>
         );
       }
       return (
         <div className="feedback">
           {backButton}
           <h3>{this.props.title}</h3>
@@ -75,22 +76,25 @@ loop.shared.views.FeedbackView = (functi
         other: l10n.get("feedback_category_other2")
       };
     },
 
     _getCategoryFields: function() {
       var categories = this._getCategories();
       return Object.keys(categories).map(function(category, key) {
         return (
-          <label key={key} className="feedback-category-label">
-            <input type="radio" ref="category" name="category"
-                   className="feedback-category-radio"
-                   value={category}
-                   onChange={this.handleCategoryChange}
-                   checked={this.state.category === category} />
+          <label className="feedback-category-label" key={key}>
+            <input
+              checked={this.state.category === category}
+              className="feedback-category-radio"
+              name="category"
+              onChange={this.handleCategoryChange}
+              ref="category"
+              type="radio"
+              value={category} />
             {categories[category]}
           </label>
         );
       }, this);
     },
 
     /**
      * Checks if the form is ready for submission:
@@ -133,30 +137,34 @@ loop.shared.views.FeedbackView = (functi
         happy: false,
         category: this.state.category,
         description: this.state.description
       }));
     },
 
     render: function() {
       return (
-        <FeedbackLayout title={l10n.get("feedback_category_list_heading")}
-                        reset={this.props.reset}>
+        <FeedbackLayout
+          reset={this.props.reset}
+          title={l10n.get("feedback_category_list_heading")}>
           <form onSubmit={this.handleFormSubmit}>
             {this._getCategoryFields()}
             <p>
-              <input type="text" ref="description" name="description"
-                className="feedback-description"
+              <input className="feedback-description"
+                name="description"
                 onChange={this.handleDescriptionFieldChange}
-                value={this.state.description}
                 placeholder={
-                  l10n.get("feedback_custom_category_text_placeholder")} />
+                  l10n.get("feedback_custom_category_text_placeholder")}
+                ref="description"
+                type="text"
+                value={this.state.description} />
             </p>
-            <button type="submit" className="btn btn-success"
-                    disabled={!this._isFormReady()}>
+            <button className="btn btn-success"
+              disabled={!this._isFormReady()}
+              type="submit">
               {l10n.get("feedback_submit_button")}
             </button>
           </form>
         </FeedbackLayout>
       );
     }
   });
 
@@ -224,20 +232,20 @@ loop.shared.views.FeedbackView = (functi
    */
   var FeedbackView = React.createClass({
     mixins: [
       Backbone.Events,
       loop.store.StoreMixin("feedbackStore")
     ],
 
     propTypes: {
-      onAfterFeedbackReceived: React.PropTypes.func,
       // Used by the UI showcase.
       feedbackState: React.PropTypes.string,
-      noCloseText: React.PropTypes.bool
+      noCloseText: React.PropTypes.bool,
+      onAfterFeedbackReceived: React.PropTypes.func
     },
 
     getInitialState: function() {
       var storeState = this.getStoreState();
       return _.extend({}, storeState, {
         feedbackState: this.props.feedbackState || storeState.feedbackState
       });
     },
@@ -284,18 +292,18 @@ loop.shared.views.FeedbackView = (functi
               </div>
             </FeedbackLayout>
           );
         }
         case FEEDBACK_STATES.DETAILS: {
           return (
             <FeedbackForm
               feedbackStore={this.getStore()}
-              reset={this.reset}
-              pending={this.state.feedbackState === FEEDBACK_STATES.PENDING} />
+              pending={this.state.feedbackState === FEEDBACK_STATES.PENDING}
+              reset={this.reset} />
             );
         }
         case FEEDBACK_STATES.PENDING:
         case FEEDBACK_STATES.SENT:
         case FEEDBACK_STATES.FAILED: {
           if (this.state.error) {
             // XXX better end user error reporting, see bug 1046738
             console.error("Error encountered while submitting feedback",
--- a/browser/components/loop/content/shared/js/textChatView.js
+++ b/browser/components/loop/content/shared/js/textChatView.js
@@ -102,17 +102,17 @@ loop.shared.views.TextChatView = (functi
             
               this.props.messageList.map(function(entry, i) {
                 if (entry.type === CHAT_MESSAGE_TYPES.SPECIAL) {
                   switch (entry.contentType) {
                     case CHAT_CONTENT_TYPES.ROOM_NAME:
                       return React.createElement(TextChatRoomName, {key: i, message: entry.message});
                     case CHAT_CONTENT_TYPES.CONTEXT:
                       return (
-                        React.createElement("div", {key: i, className: "context-url-view-wrapper"}, 
+                        React.createElement("div", {className: "context-url-view-wrapper", key: i}, 
                           React.createElement(sharedViews.ContextUrlView, {
                             allowClick: true, 
                             description: entry.message, 
                             dispatcher: this.props.dispatcher, 
                             showContextTitle: true, 
                             thumbnail: entry.extraData.thumbnail, 
                             url: entry.extraData.location, 
                             useDesktopPaths: false})
@@ -120,20 +120,21 @@ loop.shared.views.TextChatView = (functi
                       );
                     default:
                       console.error("Unsupported contentType", entry.contentType);
                       return null;
                   }
                 }
 
                 return (
-                  React.createElement(TextChatEntry, {key: i, 
-                                 contentType: entry.contentType, 
-                                 message: entry.message, 
-                                 type: entry.type})
+                  React.createElement(TextChatEntry, {
+                    contentType: entry.contentType, 
+                    key: i, 
+                    message: entry.message, 
+                    type: entry.type})
                 );
               }, this)
             
           )
         )
       );
     }
   });
@@ -201,20 +202,21 @@ loop.shared.views.TextChatView = (functi
     render: function() {
       if (!this.props.textChatEnabled) {
         return null;
       }
 
       return (
         React.createElement("div", {className: "text-chat-box"}, 
           React.createElement("form", {onSubmit: this.handleFormSubmit}, 
-            React.createElement("input", {type: "text", 
-                   placeholder: this.props.showPlaceholder ? mozL10n.get("chat_textbox_placeholder") : "", 
-                   onKeyDown: this.handleKeyDown, 
-                   valueLink: this.linkState("messageDetail")})
+            React.createElement("input", {
+              onKeyDown: this.handleKeyDown, 
+              placeholder: this.props.showPlaceholder ? mozL10n.get("chat_textbox_placeholder") : "", 
+              type: "text", 
+              valueLink: this.linkState("messageDetail")})
           )
         )
       );
     }
   });
 
   /**
    * Displays the text chat view. This includes the text chat messages as well
--- a/browser/components/loop/content/shared/js/textChatView.jsx
+++ b/browser/components/loop/content/shared/js/textChatView.jsx
@@ -102,17 +102,17 @@ loop.shared.views.TextChatView = (functi
             {
               this.props.messageList.map(function(entry, i) {
                 if (entry.type === CHAT_MESSAGE_TYPES.SPECIAL) {
                   switch (entry.contentType) {
                     case CHAT_CONTENT_TYPES.ROOM_NAME:
                       return <TextChatRoomName key={i} message={entry.message}/>;
                     case CHAT_CONTENT_TYPES.CONTEXT:
                       return (
-                        <div key={i} className="context-url-view-wrapper">
+                        <div className="context-url-view-wrapper" key={i}>
                           <sharedViews.ContextUrlView
                             allowClick={true}
                             description={entry.message}
                             dispatcher={this.props.dispatcher}
                             showContextTitle={true}
                             thumbnail={entry.extraData.thumbnail}
                             url={entry.extraData.location}
                             useDesktopPaths={false} />
@@ -120,20 +120,21 @@ loop.shared.views.TextChatView = (functi
                       );
                     default:
                       console.error("Unsupported contentType", entry.contentType);
                       return null;
                   }
                 }
 
                 return (
-                  <TextChatEntry key={i}
-                                 contentType={entry.contentType}
-                                 message={entry.message}
-                                 type={entry.type} />
+                  <TextChatEntry
+                    contentType={entry.contentType}
+                    key={i}
+                    message={entry.message}
+                    type={entry.type} />
                 );
               }, this)
             }
           </div>
         </div>
       );
     }
   });
@@ -201,20 +202,21 @@ loop.shared.views.TextChatView = (functi
     render: function() {
       if (!this.props.textChatEnabled) {
         return null;
       }
 
       return (
         <div className="text-chat-box">
           <form onSubmit={this.handleFormSubmit}>
-            <input type="text"
-                   placeholder={this.props.showPlaceholder ? mozL10n.get("chat_textbox_placeholder") : ""}
-                   onKeyDown={this.handleKeyDown}
-                   valueLink={this.linkState("messageDetail")} />
+            <input
+              onKeyDown={this.handleKeyDown}
+              placeholder={this.props.showPlaceholder ? mozL10n.get("chat_textbox_placeholder") : ""}
+              type="text"
+              valueLink={this.linkState("messageDetail")} />
           </form>
         </div>
       );
     }
   });
 
   /**
    * Displays the text chat view. This includes the text chat messages as well
--- a/browser/components/loop/content/shared/js/views.js
+++ b/browser/components/loop/content/shared/js/views.js
@@ -18,20 +18,20 @@ loop.shared.views = (function(_, l10n) {
    * Required props:
    * - {String}   scope   Media scope, can be "local" or "remote".
    * - {String}   type    Media type, can be "audio" or "video".
    * - {Function} action  Function to be executed on click.
    * - {Enabled}  enabled Stream activation status (default: true).
    */
   var MediaControlButton = React.createClass({displayName: "MediaControlButton",
     propTypes: {
+      action: React.PropTypes.func.isRequired,
+      enabled: React.PropTypes.bool.isRequired,
       scope: React.PropTypes.string.isRequired,
       type: React.PropTypes.string.isRequired,
-      action: React.PropTypes.func.isRequired,
-      enabled: React.PropTypes.bool.isRequired,
       visible: React.PropTypes.bool.isRequired
     },
 
     getDefaultProps: function() {
       return {enabled: true, visible: true};
     },
 
     handleClick: function() {
@@ -58,18 +58,18 @@ loop.shared.views = (function(_, l10n) {
       var suffix = "button_title";
       var msgId = [prefix, this.props.scope, this.props.type, suffix].join("_");
       return l10n.get(msgId);
     },
 
     render: function() {
       return (
         React.createElement("button", {className: this._getClasses(), 
-                title: this._getTitle(), 
-                onClick: this.handleClick})
+                onClick: this.handleClick, 
+                title: this._getTitle()})
       );
     }
   });
 
   /**
    * Screen sharing control button.
    *
    * Required props:
@@ -78,18 +78,18 @@ loop.shared.views = (function(_, l10n) {
    * - {String}          state       One of the screen sharing states, see
    *                                 loop.shared.utils.SCREEN_SHARE_STATES
    */
   var ScreenShareControlButton = React.createClass({displayName: "ScreenShareControlButton",
     mixins: [sharedMixins.DropdownMenuMixin()],
 
     propTypes: {
       dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
-      visible: React.PropTypes.bool.isRequired,
-      state: React.PropTypes.string.isRequired
+      state: React.PropTypes.string.isRequired,
+      visible: React.PropTypes.bool.isRequired
     },
 
     getInitialState: function() {
       var os = loop.shared.utils.getOS();
       var osVersion = loop.shared.utils.getOSVersion();
       // Disable screensharing on older OSX and Windows versions.
       if ((os.indexOf("mac") > -1 && osVersion.major <= 10 && osVersion.minor <= 6) ||
           (os.indexOf("win") > -1 && osVersion.major <= 5 && osVersion.minor <= 2)) {
@@ -157,21 +157,21 @@ loop.shared.views = (function(_, l10n) {
       return (
         React.createElement("div", null, 
           React.createElement("button", {className: screenShareClasses, 
                   onClick: this.handleClick, 
                   ref: "menu-button", 
                   title: this._getTitle()}, 
             isActive ? null : React.createElement("span", {className: "chevron"})
           ), 
-          React.createElement("ul", {ref: "menu", className: dropdownMenuClasses}, 
+          React.createElement("ul", {className: dropdownMenuClasses, ref: "menu"}, 
             React.createElement("li", {onClick: this._handleShareTabs}, 
               l10n.get("share_tabs_button_title2")
             ), 
-            React.createElement("li", {onClick: this._handleShareWindows, className: windowSharingClasses}, 
+            React.createElement("li", {className: windowSharingClasses, onClick: this._handleShareWindows}, 
               l10n.get("share_windows_button_title")
             )
           )
         )
       );
     }
   });
 
@@ -184,24 +184,24 @@ loop.shared.views = (function(_, l10n) {
         video: {enabled: true, visible: true},
         audio: {enabled: true, visible: true},
         screenShare: {state: SCREEN_SHARE_STATES.INACTIVE, visible: false},
         enableHangup: true
       };
     },
 
     propTypes: {
+      audio: React.PropTypes.object.isRequired,
       dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
-      video: React.PropTypes.object.isRequired,
-      audio: React.PropTypes.object.isRequired,
+      enableHangup: React.PropTypes.bool,
+      hangup: React.PropTypes.func.isRequired,
+      hangupButtonLabel: React.PropTypes.string,
+      publishStream: React.PropTypes.func.isRequired,
       screenShare: React.PropTypes.object,
-      hangup: React.PropTypes.func.isRequired,
-      publishStream: React.PropTypes.func.isRequired,
-      hangupButtonLabel: React.PropTypes.string,
-      enableHangup: React.PropTypes.bool
+      video: React.PropTypes.object.isRequired
     },
 
     handleClickHangup: function() {
       this.props.hangup();
     },
 
     handleToggleVideo: function() {
       this.props.publishStream("video", !this.props.video.enabled);
@@ -214,38 +214,39 @@ loop.shared.views = (function(_, l10n) {
     _getHangupButtonLabel: function() {
       return this.props.hangupButtonLabel || l10n.get("hangup_button_caption2");
     },
 
     render: function() {
       return (
         React.createElement("ul", {className: "conversation-toolbar"}, 
           React.createElement("li", {className: "conversation-toolbar-btn-box btn-hangup-entry"}, 
-            React.createElement("button", {className: "btn btn-hangup", onClick: this.handleClickHangup, 
-                    title: l10n.get("hangup_button_title"), 
-                    disabled: !this.props.enableHangup}, 
+            React.createElement("button", {className: "btn btn-hangup", 
+                    disabled: !this.props.enableHangup, 
+                    onClick: this.handleClickHangup, 
+                    title: l10n.get("hangup_button_title")}, 
               this._getHangupButtonLabel()
             )
           ), 
           React.createElement("li", {className: "conversation-toolbar-btn-box"}, 
             React.createElement(MediaControlButton, {action: this.handleToggleVideo, 
                                 enabled: this.props.video.enabled, 
-                                visible: this.props.video.visible, 
-                                scope: "local", type: "video"})
+                                scope: "local", type: "video", 
+                                visible: this.props.video.visible})
           ), 
           React.createElement("li", {className: "conversation-toolbar-btn-box"}, 
             React.createElement(MediaControlButton, {action: this.handleToggleAudio, 
                                 enabled: this.props.audio.enabled, 
-                                visible: this.props.audio.visible, 
-                                scope: "local", type: "audio"})
+                                scope: "local", type: "audio", 
+                                visible: this.props.audio.visible})
           ), 
           React.createElement("li", {className: "conversation-toolbar-btn-box btn-screen-share-entry"}, 
             React.createElement(ScreenShareControlButton, {dispatcher: this.props.dispatcher, 
-                                      visible: this.props.screenShare.visible, 
-                                      state: this.props.screenShare.state})
+                                      state: this.props.screenShare.state, 
+                                      visible: this.props.screenShare.visible})
           )
         )
       );
     }
   });
 
   /**
    * Conversation view.
@@ -253,21 +254,21 @@ loop.shared.views = (function(_, l10n) {
   var ConversationView = React.createClass({displayName: "ConversationView",
     mixins: [
       Backbone.Events,
       sharedMixins.AudioMixin,
       sharedMixins.MediaSetupMixin
     ],
 
     propTypes: {
-      sdk: React.PropTypes.object.isRequired,
-      video: React.PropTypes.object,
       audio: React.PropTypes.object,
       initiate: React.PropTypes.bool,
-      isDesktop: React.PropTypes.bool
+      isDesktop: React.PropTypes.bool,
+      sdk: React.PropTypes.object.isRequired,
+      video: React.PropTypes.object
     },
 
     getDefaultProps: function() {
       return {
         initiate: true,
         isDesktop: false,
         video: {enabled: true, visible: true},
         audio: {enabled: true, visible: true}
@@ -450,68 +451,69 @@ loop.shared.views = (function(_, l10n) {
         React.createElement("div", {className: "video-layout-wrapper"}, 
           React.createElement("div", {className: "conversation in-call"}, 
             React.createElement("div", {className: "media nested"}, 
               React.createElement("div", {className: "video_wrapper remote_wrapper"}, 
                 React.createElement("div", {className: "video_inner remote focus-stream"})
               ), 
               React.createElement("div", {className: localStreamClasses})
             ), 
-            React.createElement(ConversationToolbar, {video: this.state.video, 
-                                 audio: this.state.audio, 
-                                 publishStream: this.publishStream, 
-                                 hangup: this.hangup})
+            React.createElement(ConversationToolbar, {
+              audio: this.state.audio, 
+              hangup: this.hangup, 
+              publishStream: this.publishStream, 
+              video: this.state.video})
           )
         )
       );
     }
   });
 
   /**
    * Notification view.
    */
   var NotificationView = React.createClass({displayName: "NotificationView",
     mixins: [Backbone.Events],
 
     propTypes: {
-      notification: React.PropTypes.object.isRequired,
-      key: React.PropTypes.number.isRequired
+      key: React.PropTypes.number.isRequired,
+      notification: React.PropTypes.object.isRequired
     },
 
     render: function() {
       var notification = this.props.notification;
       return (
         React.createElement("div", {className: "notificationContainer"}, 
-          React.createElement("div", {key: this.props.key, 
-               className: "alert alert-" + notification.get("level")}, 
+          React.createElement("div", {className: "alert alert-" + notification.get("level"), 
+            key: this.props.key}, 
             React.createElement("span", {className: "message"}, notification.get("message"))
           ), 
           React.createElement("div", {className: "detailsBar details-" + notification.get("level"), 
                hidden: !notification.get("details")}, 
             React.createElement("button", {className: "detailsButton btn-info", 
-                    onClick: notification.get("detailsButtonCallback"), 
-                    hidden: !notification.get("detailsButtonLabel") || !notification.get("detailsButtonCallback")}, 
+                    hidden: !notification.get("detailsButtonLabel") || !notification.get("detailsButtonCallback"), 
+                    onClick: notification.get("detailsButtonCallback")}, 
               notification.get("detailsButtonLabel")
             ), 
             React.createElement("span", {className: "details"}, notification.get("details"))
           )
         )
       );
     }
   });
 
   /**
    * Notification list view.
    */
   var NotificationListView = React.createClass({displayName: "NotificationListView",
     mixins: [Backbone.Events, sharedMixins.DocumentVisibilityMixin],
 
     propTypes: {
-      notifications: React.PropTypes.object.isRequired,
-      clearOnDocumentHidden: React.PropTypes.bool
+      clearOnDocumentHidden: React.PropTypes.bool,
+      notifications: React.PropTypes.object.isRequired
     },
 
     getDefaultProps: function() {
       return {clearOnDocumentHidden: false};
     },
 
     componentDidMount: function() {
       this.listenTo(this.props.notifications, "reset add remove", function() {
@@ -548,21 +550,21 @@ loop.shared.views = (function(_, l10n) {
         
         )
       );
     }
   });
 
   var Button = React.createClass({displayName: "Button",
     propTypes: {
+      additionalClass: React.PropTypes.string,
       caption: React.PropTypes.string.isRequired,
-      onClick: React.PropTypes.func.isRequired,
       disabled: React.PropTypes.bool,
-      additionalClass: React.PropTypes.string,
-      htmlId: React.PropTypes.string
+      htmlId: React.PropTypes.string,
+      onClick: React.PropTypes.func.isRequired
     },
 
     getDefaultProps: function() {
       return {
         disabled: false,
         additionalClass: "",
         htmlId: ""
       };
@@ -570,20 +572,20 @@ loop.shared.views = (function(_, l10n) {
 
     render: function() {
       var cx = React.addons.classSet;
       var classObject = { button: true, disabled: this.props.disabled };
       if (this.props.additionalClass) {
         classObject[this.props.additionalClass] = true;
       }
       return (
-        React.createElement("button", {onClick: this.props.onClick, 
+        React.createElement("button", {className: cx(classObject), 
                 disabled: this.props.disabled, 
                 id: this.props.htmlId, 
-                className: cx(classObject)}, 
+                onClick: this.props.onClick}, 
           React.createElement("span", {className: "button-caption"}, this.props.caption), 
           this.props.children
         )
       );
     }
   });
 
   var ButtonGroup = React.createClass({displayName: "ButtonGroup",
@@ -786,18 +788,18 @@ loop.shared.views = (function(_, l10n) {
       return (
         React.createElement("div", {className: "context-content"}, 
           this.renderContextTitle(), 
           React.createElement("div", {className: "context-wrapper"}, 
             React.createElement("img", {className: "context-preview", src: thumbnail}), 
             React.createElement("span", {className: "context-description"}, 
               this.props.description, 
               React.createElement("a", {className: "context-url", 
+                 href: this.props.allowClick ? this.props.url : null, 
                  onClick: this.handleLinkClick, 
-                 href: this.props.allowClick ? this.props.url : null, 
                  rel: "noreferrer", 
                  target: "_blank"}, hostname)
             )
           )
         )
       );
     }
   });
--- a/browser/components/loop/content/shared/js/views.jsx
+++ b/browser/components/loop/content/shared/js/views.jsx
@@ -18,20 +18,20 @@ loop.shared.views = (function(_, l10n) {
    * Required props:
    * - {String}   scope   Media scope, can be "local" or "remote".
    * - {String}   type    Media type, can be "audio" or "video".
    * - {Function} action  Function to be executed on click.
    * - {Enabled}  enabled Stream activation status (default: true).
    */
   var MediaControlButton = React.createClass({
     propTypes: {
+      action: React.PropTypes.func.isRequired,
+      enabled: React.PropTypes.bool.isRequired,
       scope: React.PropTypes.string.isRequired,
       type: React.PropTypes.string.isRequired,
-      action: React.PropTypes.func.isRequired,
-      enabled: React.PropTypes.bool.isRequired,
       visible: React.PropTypes.bool.isRequired
     },
 
     getDefaultProps: function() {
       return {enabled: true, visible: true};
     },
 
     handleClick: function() {
@@ -58,18 +58,18 @@ loop.shared.views = (function(_, l10n) {
       var suffix = "button_title";
       var msgId = [prefix, this.props.scope, this.props.type, suffix].join("_");
       return l10n.get(msgId);
     },
 
     render: function() {
       return (
         <button className={this._getClasses()}
-                title={this._getTitle()}
-                onClick={this.handleClick}></button>
+                onClick={this.handleClick}
+                title={this._getTitle()}></button>
       );
     }
   });
 
   /**
    * Screen sharing control button.
    *
    * Required props:
@@ -78,18 +78,18 @@ loop.shared.views = (function(_, l10n) {
    * - {String}          state       One of the screen sharing states, see
    *                                 loop.shared.utils.SCREEN_SHARE_STATES
    */
   var ScreenShareControlButton = React.createClass({
     mixins: [sharedMixins.DropdownMenuMixin()],
 
     propTypes: {
       dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
-      visible: React.PropTypes.bool.isRequired,
-      state: React.PropTypes.string.isRequired
+      state: React.PropTypes.string.isRequired,
+      visible: React.PropTypes.bool.isRequired
     },
 
     getInitialState: function() {
       var os = loop.shared.utils.getOS();
       var osVersion = loop.shared.utils.getOSVersion();
       // Disable screensharing on older OSX and Windows versions.
       if ((os.indexOf("mac") > -1 && osVersion.major <= 10 && osVersion.minor <= 6) ||
           (os.indexOf("win") > -1 && osVersion.major <= 5 && osVersion.minor <= 2)) {
@@ -157,21 +157,21 @@ loop.shared.views = (function(_, l10n) {
       return (
         <div>
           <button className={screenShareClasses}
                   onClick={this.handleClick}
                   ref="menu-button"
                   title={this._getTitle()}>
             {isActive ? null : <span className="chevron"/>}
           </button>
-          <ul ref="menu" className={dropdownMenuClasses}>
+          <ul className={dropdownMenuClasses} ref="menu">
             <li onClick={this._handleShareTabs}>
               {l10n.get("share_tabs_button_title2")}
             </li>
-            <li onClick={this._handleShareWindows} className={windowSharingClasses}>
+            <li className={windowSharingClasses} onClick={this._handleShareWindows}>
               {l10n.get("share_windows_button_title")}
             </li>
           </ul>
         </div>
       );
     }
   });
 
@@ -184,24 +184,24 @@ loop.shared.views = (function(_, l10n) {
         video: {enabled: true, visible: true},
         audio: {enabled: true, visible: true},
         screenShare: {state: SCREEN_SHARE_STATES.INACTIVE, visible: false},
         enableHangup: true
       };
     },
 
     propTypes: {
+      audio: React.PropTypes.object.isRequired,
       dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
-      video: React.PropTypes.object.isRequired,
-      audio: React.PropTypes.object.isRequired,
+      enableHangup: React.PropTypes.bool,
+      hangup: React.PropTypes.func.isRequired,
+      hangupButtonLabel: React.PropTypes.string,
+      publishStream: React.PropTypes.func.isRequired,
       screenShare: React.PropTypes.object,
-      hangup: React.PropTypes.func.isRequired,
-      publishStream: React.PropTypes.func.isRequired,
-      hangupButtonLabel: React.PropTypes.string,
-      enableHangup: React.PropTypes.bool
+      video: React.PropTypes.object.isRequired
     },
 
     handleClickHangup: function() {
       this.props.hangup();
     },
 
     handleToggleVideo: function() {
       this.props.publishStream("video", !this.props.video.enabled);
@@ -214,38 +214,39 @@ loop.shared.views = (function(_, l10n) {
     _getHangupButtonLabel: function() {
       return this.props.hangupButtonLabel || l10n.get("hangup_button_caption2");
     },
 
     render: function() {
       return (
         <ul className="conversation-toolbar">
           <li className="conversation-toolbar-btn-box btn-hangup-entry">
-            <button className="btn btn-hangup" onClick={this.handleClickHangup}
-                    title={l10n.get("hangup_button_title")}
-                    disabled={!this.props.enableHangup}>
+            <button className="btn btn-hangup"
+                    disabled={!this.props.enableHangup}
+                    onClick={this.handleClickHangup}
+                    title={l10n.get("hangup_button_title")}>
               {this._getHangupButtonLabel()}
             </button>
           </li>
           <li className="conversation-toolbar-btn-box">
             <MediaControlButton action={this.handleToggleVideo}
                                 enabled={this.props.video.enabled}
-                                visible={this.props.video.visible}
-                                scope="local" type="video" />
+                                scope="local" type="video"
+                                visible={this.props.video.visible} />
           </li>
           <li className="conversation-toolbar-btn-box">
             <MediaControlButton action={this.handleToggleAudio}
                                 enabled={this.props.audio.enabled}
-                                visible={this.props.audio.visible}
-                                scope="local" type="audio" />
+                                scope="local" type="audio"
+                                visible={this.props.audio.visible} />
           </li>
           <li className="conversation-toolbar-btn-box btn-screen-share-entry">
             <ScreenShareControlButton dispatcher={this.props.dispatcher}
-                                      visible={this.props.screenShare.visible}
-                                      state={this.props.screenShare.state} />
+                                      state={this.props.screenShare.state}
+                                      visible={this.props.screenShare.visible} />
           </li>
         </ul>
       );
     }
   });
 
   /**
    * Conversation view.
@@ -253,21 +254,21 @@ loop.shared.views = (function(_, l10n) {
   var ConversationView = React.createClass({
     mixins: [
       Backbone.Events,
       sharedMixins.AudioMixin,
       sharedMixins.MediaSetupMixin
     ],
 
     propTypes: {
-      sdk: React.PropTypes.object.isRequired,
-      video: React.PropTypes.object,
       audio: React.PropTypes.object,
       initiate: React.PropTypes.bool,
-      isDesktop: React.PropTypes.bool
+      isDesktop: React.PropTypes.bool,
+      sdk: React.PropTypes.object.isRequired,
+      video: React.PropTypes.object
     },
 
     getDefaultProps: function() {
       return {
         initiate: true,
         isDesktop: false,
         video: {enabled: true, visible: true},
         audio: {enabled: true, visible: true}
@@ -450,68 +451,69 @@ loop.shared.views = (function(_, l10n) {
         <div className="video-layout-wrapper">
           <div className="conversation in-call">
             <div className="media nested">
               <div className="video_wrapper remote_wrapper">
                 <div className="video_inner remote focus-stream"></div>
               </div>
               <div className={localStreamClasses}></div>
             </div>
-            <ConversationToolbar video={this.state.video}
-                                 audio={this.state.audio}
-                                 publishStream={this.publishStream}
-                                 hangup={this.hangup} />
+            <ConversationToolbar
+              audio={this.state.audio}
+              hangup={this.hangup}
+              publishStream={this.publishStream}
+              video={this.state.video} />
           </div>
         </div>
       );
     }
   });
 
   /**
    * Notification view.
    */
   var NotificationView = React.createClass({
     mixins: [Backbone.Events],
 
     propTypes: {
-      notification: React.PropTypes.object.isRequired,
-      key: React.PropTypes.number.isRequired
+      key: React.PropTypes.number.isRequired,
+      notification: React.PropTypes.object.isRequired
     },
 
     render: function() {
       var notification = this.props.notification;
       return (
         <div className="notificationContainer">
-          <div key={this.props.key}
-               className={"alert alert-" + notification.get("level")}>
+          <div className={"alert alert-" + notification.get("level")}
+            key={this.props.key}>
             <span className="message">{notification.get("message")}</span>
           </div>
           <div className={"detailsBar details-" + notification.get("level")}
                hidden={!notification.get("details")}>
             <button className="detailsButton btn-info"
-                    onClick={notification.get("detailsButtonCallback")}
-                    hidden={!notification.get("detailsButtonLabel") || !notification.get("detailsButtonCallback")}>
+                    hidden={!notification.get("detailsButtonLabel") || !notification.get("detailsButtonCallback")}
+                    onClick={notification.get("detailsButtonCallback")}>
               {notification.get("detailsButtonLabel")}
             </button>
             <span className="details">{notification.get("details")}</span>
           </div>
         </div>
       );
     }
   });
 
   /**
    * Notification list view.
    */
   var NotificationListView = React.createClass({
     mixins: [Backbone.Events, sharedMixins.DocumentVisibilityMixin],
 
     propTypes: {
-      notifications: React.PropTypes.object.isRequired,
-      clearOnDocumentHidden: React.PropTypes.bool
+      clearOnDocumentHidden: React.PropTypes.bool,
+      notifications: React.PropTypes.object.isRequired
     },
 
     getDefaultProps: function() {
       return {clearOnDocumentHidden: false};
     },
 
     componentDidMount: function() {
       this.listenTo(this.props.notifications, "reset add remove", function() {
@@ -548,21 +550,21 @@ loop.shared.views = (function(_, l10n) {
         }
         </div>
       );
     }
   });
 
   var Button = React.createClass({
     propTypes: {
+      additionalClass: React.PropTypes.string,
       caption: React.PropTypes.string.isRequired,
-      onClick: React.PropTypes.func.isRequired,
       disabled: React.PropTypes.bool,
-      additionalClass: React.PropTypes.string,
-      htmlId: React.PropTypes.string
+      htmlId: React.PropTypes.string,
+      onClick: React.PropTypes.func.isRequired
     },
 
     getDefaultProps: function() {
       return {
         disabled: false,
         additionalClass: "",
         htmlId: ""
       };
@@ -570,20 +572,20 @@ loop.shared.views = (function(_, l10n) {
 
     render: function() {
       var cx = React.addons.classSet;
       var classObject = { button: true, disabled: this.props.disabled };
       if (this.props.additionalClass) {
         classObject[this.props.additionalClass] = true;
       }
       return (
-        <button onClick={this.props.onClick}
+        <button className={cx(classObject)}
                 disabled={this.props.disabled}
                 id={this.props.htmlId}
-                className={cx(classObject)}>
+                onClick={this.props.onClick}>
           <span className="button-caption">{this.props.caption}</span>
           {this.props.children}
         </button>
       );
     }
   });
 
   var ButtonGroup = React.createClass({
@@ -786,18 +788,18 @@ loop.shared.views = (function(_, l10n) {
       return (
         <div className="context-content">
           {this.renderContextTitle()}
           <div className="context-wrapper">
             <img className="context-preview" src={thumbnail} />
             <span className="context-description">
               {this.props.description}
               <a className="context-url"
+                 href={this.props.allowClick ? this.props.url : null}
                  onClick={this.handleLinkClick}
-                 href={this.props.allowClick ? this.props.url : null}
                  rel="noreferrer"
                  target="_blank">{hostname}</a>
             </span>
           </div>
         </div>
       );
     }
   });
--- a/browser/components/loop/standalone/content/js/fxOSMarketplace.js
+++ b/browser/components/loop/standalone/content/js/fxOSMarketplace.js
@@ -11,17 +11,17 @@ loop.fxOSMarketplaceViews = (function() 
    * based API that wraps a small set of functionality from the WebApps API
    * that allow us to request the installation of apps given their manifest
    * URL. We will be embedding the content of this web page within an hidden
    * iframe in case that we need to request the installation of the FxOS Loop
    * client.
    */
   var FxOSHiddenMarketplaceView = React.createClass({displayName: "FxOSHiddenMarketplaceView",
     render: function() {
-      return React.createElement("iframe", {id: "marketplace", src: this.props.marketplaceSrc, hidden: true});
+      return React.createElement("iframe", {hidden: true, id: "marketplace", src: this.props.marketplaceSrc});
     },
 
     componentDidUpdate: function() {
       // This happens only once when we change the 'src' property of the iframe.
       if (this.props.onMarketplaceMessage) {
         // The reason for listening on the global window instead of on the
         // iframe content window is because the Marketplace is doing a
         // window.top.postMessage.
--- a/browser/components/loop/standalone/content/js/fxOSMarketplace.jsx
+++ b/browser/components/loop/standalone/content/js/fxOSMarketplace.jsx
@@ -11,17 +11,17 @@ loop.fxOSMarketplaceViews = (function() 
    * based API that wraps a small set of functionality from the WebApps API
    * that allow us to request the installation of apps given their manifest
    * URL. We will be embedding the content of this web page within an hidden
    * iframe in case that we need to request the installation of the FxOS Loop
    * client.
    */
   var FxOSHiddenMarketplaceView = React.createClass({
     render: function() {
-      return <iframe id="marketplace" src={this.props.marketplaceSrc} hidden/>;
+      return <iframe hidden id="marketplace" src={this.props.marketplaceSrc} />;
     },
 
     componentDidUpdate: function() {
       // This happens only once when we change the 'src' property of the iframe.
       if (this.props.onMarketplaceMessage) {
         // The reason for listening on the global window instead of on the
         // iframe content window is because the Marketplace is doing a
         // window.top.postMessage.
--- a/browser/components/loop/standalone/content/js/standaloneRoomViews.js
+++ b/browser/components/loop/standalone/content/js/standaloneRoomViews.js
@@ -11,42 +11,42 @@ loop.standaloneRoomViews = (function(moz
   var ROOM_STATES = loop.store.ROOM_STATES;
   var sharedActions = loop.shared.actions;
   var sharedMixins = loop.shared.mixins;
   var sharedUtils = loop.shared.utils;
   var sharedViews = loop.shared.views;
 
   var StandaloneRoomInfoArea = React.createClass({displayName: "StandaloneRoomInfoArea",
     propTypes: {
-      isFirefox: React.PropTypes.bool.isRequired,
       activeRoomStore: React.PropTypes.oneOfType([
         React.PropTypes.instanceOf(loop.store.ActiveRoomStore),
         React.PropTypes.instanceOf(loop.store.FxOSActiveRoomStore)
-      ]).isRequired
+      ]).isRequired,
+      isFirefox: React.PropTypes.bool.isRequired
     },
 
     onFeedbackSent: function() {
       // We pass a tick to prevent React warnings regarding nested updates.
       setTimeout(function() {
         this.props.activeRoomStore.dispatchAction(new sharedActions.FeedbackComplete());
       }.bind(this));
     },
 
     _renderCallToActionLink: function() {
       if (this.props.isFirefox) {
         return (
-          React.createElement("a", {href: loop.config.learnMoreUrl, className: "btn btn-info"}, 
+          React.createElement("a", {className: "btn btn-info", href: loop.config.learnMoreUrl}, 
             mozL10n.get("rooms_room_full_call_to_action_label", {
               clientShortname: mozL10n.get("clientShortname2")
             })
           )
         );
       }
       return (
-        React.createElement("a", {href: loop.config.downloadFirefoxUrl, className: "btn btn-info"}, 
+        React.createElement("a", {className: "btn btn-info", href: loop.config.downloadFirefoxUrl}, 
           mozL10n.get("rooms_room_full_call_to_action_nonFx_label", {
             brandShortname: mozL10n.get("brandShortname")
           })
         )
       );
     },
 
     /**
@@ -122,19 +122,18 @@ loop.standaloneRoomViews = (function(moz
             )
           );
         }
         case ROOM_STATES.ENDED: {
           if (this.props.roomUsed) {
             return (
               React.createElement("div", {className: "ended-conversation"}, 
                 React.createElement(sharedViews.FeedbackView, {
-                  onAfterFeedbackReceived: this.onFeedbackSent, 
-                  noCloseText: true}
-                )
+                  noCloseText: true, 
+                  onAfterFeedbackReceived: this.onFeedbackSent})
               )
             );
           }
 
           // In case the room was not used (no one was here), we
           // bypass the feedback form.
           this.onFeedbackSent();
           return null;
@@ -427,63 +426,63 @@ loop.standaloneRoomViews = (function(moz
         "showing-local-streams": this.state.localSrcVideoObject ||
           this.props.localPosterUrl
       });
 
       return (
         React.createElement("div", {className: "room-conversation-wrapper"}, 
           React.createElement("div", {className: "beta-logo"}), 
           React.createElement(StandaloneRoomHeader, {dispatcher: this.props.dispatcher}), 
-          React.createElement(StandaloneRoomInfoArea, {roomState: this.state.roomState, 
+          React.createElement(StandaloneRoomInfoArea, {activeRoomStore: this.props.activeRoomStore, 
                                   failureReason: this.state.failureReason, 
+                                  isFirefox: this.props.isFirefox, 
                                   joinRoom: this.joinRoom, 
-                                  isFirefox: this.props.isFirefox, 
-                                  activeRoomStore: this.props.activeRoomStore, 
+                                  roomState: this.state.roomState, 
                                   roomUsed: this.state.used}), 
           React.createElement("div", {className: "media-layout"}, 
             React.createElement("div", {className: mediaWrapperClasses}, 
               React.createElement("span", {className: "self-view-hidden-message"}, 
                 mozL10n.get("self_view_hidden_message")
               ), 
               React.createElement("div", {className: remoteStreamClasses}, 
                 React.createElement(sharedViews.MediaView, {displayAvatar: !this.shouldRenderRemoteVideo(), 
-                  posterUrl: this.props.remotePosterUrl, 
                   isLoading: this._shouldRenderRemoteLoading(), 
                   mediaType: "remote", 
+                  posterUrl: this.props.remotePosterUrl, 
                   srcVideoObject: this.state.remoteSrcVideoObject})
               ), 
               React.createElement("div", {className: screenShareStreamClasses}, 
                 React.createElement(sharedViews.MediaView, {displayAvatar: false, 
-                  posterUrl: this.props.screenSharePosterUrl, 
                   isLoading: this._shouldRenderScreenShareLoading(), 
                   mediaType: "screen-share", 
+                  posterUrl: this.props.screenSharePosterUrl, 
                   srcVideoObject: this.state.screenShareVideoObject})
               ), 
               React.createElement(sharedViews.TextChatView, {
                 dispatcher: this.props.dispatcher, 
                 showAlways: true, 
                 showRoomName: true}), 
               React.createElement("div", {className: "local"}, 
                 React.createElement(sharedViews.MediaView, {displayAvatar: this.state.videoMuted, 
-                  posterUrl: this.props.localPosterUrl, 
                   isLoading: this._shouldRenderLocalLoading(), 
                   mediaType: "local", 
+                  posterUrl: this.props.localPosterUrl, 
                   srcVideoObject: this.state.localSrcVideoObject})
               )
             ), 
             React.createElement(sharedViews.ConversationToolbar, {
-              dispatcher: this.props.dispatcher, 
-              video: {enabled: !this.state.videoMuted,
-                      visible: this._roomIsActive()}, 
               audio: {enabled: !this.state.audioMuted,
                       visible: this._roomIsActive()}, 
-              publishStream: this.publishStream, 
+              dispatcher: this.props.dispatcher, 
+              enableHangup: this._roomIsActive(), 
               hangup: this.leaveRoom, 
               hangupButtonLabel: mozL10n.get("rooms_leave_button_label"), 
-              enableHangup: this._roomIsActive()})
+              publishStream: this.publishStream, 
+              video: {enabled: !this.state.videoMuted,
+                      visible: this._roomIsActive()}})
           ), 
           React.createElement(loop.fxOSMarketplaceViews.FxOSHiddenMarketplaceView, {
             marketplaceSrc: this.state.marketplaceSrc, 
             onMarketplaceMessage: this.state.onMarketplaceMessage}), 
           React.createElement(StandaloneRoomFooter, {dispatcher: this.props.dispatcher})
         )
       );
     }
--- a/browser/components/loop/standalone/content/js/standaloneRoomViews.jsx
+++ b/browser/components/loop/standalone/content/js/standaloneRoomViews.jsx
@@ -11,42 +11,42 @@ loop.standaloneRoomViews = (function(moz
   var ROOM_STATES = loop.store.ROOM_STATES;
   var sharedActions = loop.shared.actions;
   var sharedMixins = loop.shared.mixins;
   var sharedUtils = loop.shared.utils;
   var sharedViews = loop.shared.views;
 
   var StandaloneRoomInfoArea = React.createClass({
     propTypes: {
-      isFirefox: React.PropTypes.bool.isRequired,
       activeRoomStore: React.PropTypes.oneOfType([
         React.PropTypes.instanceOf(loop.store.ActiveRoomStore),
         React.PropTypes.instanceOf(loop.store.FxOSActiveRoomStore)
-      ]).isRequired
+      ]).isRequired,
+      isFirefox: React.PropTypes.bool.isRequired
     },
 
     onFeedbackSent: function() {
       // We pass a tick to prevent React warnings regarding nested updates.
       setTimeout(function() {
         this.props.activeRoomStore.dispatchAction(new sharedActions.FeedbackComplete());
       }.bind(this));
     },
 
     _renderCallToActionLink: function() {
       if (this.props.isFirefox) {
         return (
-          <a href={loop.config.learnMoreUrl} className="btn btn-info">
+          <a className="btn btn-info" href={loop.config.learnMoreUrl}>
             {mozL10n.get("rooms_room_full_call_to_action_label", {
               clientShortname: mozL10n.get("clientShortname2")
             })}
           </a>
         );
       }
       return (
-        <a href={loop.config.downloadFirefoxUrl} className="btn btn-info">
+        <a className="btn btn-info" href={loop.config.downloadFirefoxUrl}>
           {mozL10n.get("rooms_room_full_call_to_action_nonFx_label", {
             brandShortname: mozL10n.get("brandShortname")
           })}
         </a>
       );
     },
 
     /**
@@ -122,19 +122,18 @@ loop.standaloneRoomViews = (function(moz
             </div>
           );
         }
         case ROOM_STATES.ENDED: {
           if (this.props.roomUsed) {
             return (
               <div className="ended-conversation">
                 <sharedViews.FeedbackView
-                  onAfterFeedbackReceived={this.onFeedbackSent}
                   noCloseText={true}
-                />
+                  onAfterFeedbackReceived={this.onFeedbackSent} />
               </div>
             );
           }
 
           // In case the room was not used (no one was here), we
           // bypass the feedback form.
           this.onFeedbackSent();
           return null;
@@ -427,63 +426,63 @@ loop.standaloneRoomViews = (function(moz
         "showing-local-streams": this.state.localSrcVideoObject ||
           this.props.localPosterUrl
       });
 
       return (
         <div className="room-conversation-wrapper">
           <div className="beta-logo" />
           <StandaloneRoomHeader dispatcher={this.props.dispatcher} />
-          <StandaloneRoomInfoArea roomState={this.state.roomState}
+          <StandaloneRoomInfoArea activeRoomStore={this.props.activeRoomStore}
                                   failureReason={this.state.failureReason}
+                                  isFirefox={this.props.isFirefox}
                                   joinRoom={this.joinRoom}
-                                  isFirefox={this.props.isFirefox}
-                                  activeRoomStore={this.props.activeRoomStore}
+                                  roomState={this.state.roomState}
                                   roomUsed={this.state.used} />
           <div className="media-layout">
             <div className={mediaWrapperClasses}>
               <span className="self-view-hidden-message">
                 {mozL10n.get("self_view_hidden_message")}
               </span>
               <div className={remoteStreamClasses}>
                 <sharedViews.MediaView displayAvatar={!this.shouldRenderRemoteVideo()}
-                  posterUrl={this.props.remotePosterUrl}
                   isLoading={this._shouldRenderRemoteLoading()}
                   mediaType="remote"
+                  posterUrl={this.props.remotePosterUrl}
                   srcVideoObject={this.state.remoteSrcVideoObject} />
               </div>
               <div className={screenShareStreamClasses}>
                 <sharedViews.MediaView displayAvatar={false}
-                  posterUrl={this.props.screenSharePosterUrl}
                   isLoading={this._shouldRenderScreenShareLoading()}
                   mediaType="screen-share"
+                  posterUrl={this.props.screenSharePosterUrl}
                   srcVideoObject={this.state.screenShareVideoObject} />
               </div>
               <sharedViews.TextChatView
                 dispatcher={this.props.dispatcher}
                 showAlways={true}
                 showRoomName={true} />
               <div className="local">
                 <sharedViews.MediaView displayAvatar={this.state.videoMuted}
-                  posterUrl={this.props.localPosterUrl}
                   isLoading={this._shouldRenderLocalLoading()}
                   mediaType="local"
+                  posterUrl={this.props.localPosterUrl}
                   srcVideoObject={this.state.localSrcVideoObject} />
               </div>
             </div>
             <sharedViews.ConversationToolbar
-              dispatcher={this.props.dispatcher}
-              video={{enabled: !this.state.videoMuted,
-                      visible: this._roomIsActive()}}
               audio={{enabled: !this.state.audioMuted,
                       visible: this._roomIsActive()}}
-              publishStream={this.publishStream}
+              dispatcher={this.props.dispatcher}
+              enableHangup={this._roomIsActive()}
               hangup={this.leaveRoom}
               hangupButtonLabel={mozL10n.get("rooms_leave_button_label")}
-              enableHangup={this._roomIsActive()} />
+              publishStream={this.publishStream}
+              video={{enabled: !this.state.videoMuted,
+                      visible: this._roomIsActive()}} />
           </div>
           <loop.fxOSMarketplaceViews.FxOSHiddenMarketplaceView
             marketplaceSrc={this.state.marketplaceSrc}
             onMarketplaceMessage={this.state.onMarketplaceMessage} />
           <StandaloneRoomFooter dispatcher={this.props.dispatcher} />
         </div>
       );
     }
--- a/browser/components/loop/standalone/content/js/webapp.js
+++ b/browser/components/loop/standalone/content/js/webapp.js
@@ -243,21 +243,21 @@ loop.webapp = (function($, _, OT, mozL10
       );
     }
   });
 
   var ConversationFooter = React.createClass({displayName: "ConversationFooter",
     render: function() {
       return (
         React.createElement("div", {className: "standalone-footer container-box"}, 
-          React.createElement("div", {title: mozL10n.get("vendor_alttext",
-                                  {vendorShortname: mozL10n.get("vendorShortname")}), 
-               className: "footer-logo"}), 
+          React.createElement("div", {className: "footer-logo", 
+               title: mozL10n.get("vendor_alttext",
+                                  {vendorShortname: mozL10n.get("vendorShortname")})}), 
           React.createElement("div", {className: "footer-external-links"}, 
-            React.createElement("a", {target: "_blank", href: loop.config.generalSupportUrl}, 
+            React.createElement("a", {href: loop.config.generalSupportUrl, target: "_blank"}, 
               mozL10n.get("support_link")
             )
           )
         )
       );
     }
   });
 
@@ -369,29 +369,28 @@ loop.webapp = (function($, _, OT, mozL10
       var callState = mozL10n.get(callStateStringEntityName);
       document.title = mozL10n.get("standalone_title_with_status",
                                    {clientShortname: mozL10n.get("clientShortname2"),
                                     currentStatus: mozL10n.get(callStateStringEntityName)});
 
       return (
         React.createElement(PendingConversationView, {
           callState: callState, 
-          cancelCallback: this._cancelOutgoingCall}
-        )
+          cancelCallback: this._cancelOutgoingCall})
       );
     }
   });
 
   var InitiateCallButton = React.createClass({displayName: "InitiateCallButton",
     mixins: [sharedMixins.DropdownMenuMixin()],
 
     propTypes: {
       caption: React.PropTypes.string.isRequired,
-      startCall: React.PropTypes.func.isRequired,
-      disabled: React.PropTypes.bool
+      disabled: React.PropTypes.bool,
+      startCall: React.PropTypes.func.isRequired
     },
 
     getDefaultProps: function() {
       return {disabled: false};
     },
 
     render: function() {
       var dropdownMenuClasses = React.addons.classSet({
@@ -403,33 +402,33 @@ loop.webapp = (function($, _, OT, mozL10
         "btn-chevron": true,
         "disabled": this.props.disabled
       });
       return (
         React.createElement("div", {className: "standalone-btn-chevron-menu-group"}, 
           React.createElement("div", {className: "btn-group-chevron"}, 
             React.createElement("div", {className: "btn-group"}, 
               React.createElement("button", {className: "btn btn-constrained btn-large btn-accept", 
+                      disabled: this.props.disabled, 
                       onClick: this.props.startCall("audio-video"), 
-                      disabled: this.props.disabled, 
                       title: mozL10n.get("initiate_audio_video_call_tooltip2")}, 
                 React.createElement("span", {className: "standalone-call-btn-text"}, 
                   this.props.caption
                 ), 
                 React.createElement("span", {className: "standalone-call-btn-video-icon"})
               ), 
               React.createElement("div", {className: chevronClasses, 
                    onClick: this.toggleDropdownMenu}
               )
             ), 
             React.createElement("ul", {className: dropdownMenuClasses}, 
               React.createElement("li", null, 
                 React.createElement("button", {className: "start-audio-only-call", 
-                        onClick: this.props.startCall("audio"), 
-                        disabled: this.props.disabled}, 
+                        disabled: this.props.disabled, 
+                        onClick: this.props.startCall("audio")}, 
                   mozL10n.get("initiate_audio_call_button2")
                 )
               )
             )
           )
         )
       );
     }
@@ -437,25 +436,25 @@ loop.webapp = (function($, _, OT, mozL10
 
   /**
    * Initiate conversation view.
    */
   var InitiateConversationView = React.createClass({displayName: "InitiateConversationView",
     mixins: [Backbone.Events],
 
     propTypes: {
+      callButtonLabel: React.PropTypes.string.isRequired,
+      client: React.PropTypes.object.isRequired,
       conversation: React.PropTypes.oneOfType([
                       React.PropTypes.instanceOf(sharedModels.ConversationModel),
                       React.PropTypes.instanceOf(FxOSConversationModel)
                     ]).isRequired,
       // XXX Check more tightly here when we start injecting window.loop.*
       notifications: React.PropTypes.object.isRequired,
-      client: React.PropTypes.object.isRequired,
-      title: React.PropTypes.string.isRequired,
-      callButtonLabel: React.PropTypes.string.isRequired
+      title: React.PropTypes.string.isRequired
     },
 
     getInitialState: function() {
       return {
         urlCreationDateString: "",
         disableCallButton: false
       };
     },
@@ -572,49 +571,47 @@ loop.webapp = (function($, _, OT, mozL10
 
   /**
    * Ended conversation view.
    */
   var EndedConversationView = React.createClass({displayName: "EndedConversationView",
     propTypes: {
       conversation: React.PropTypes.instanceOf(sharedModels.ConversationModel)
                          .isRequired,
-      sdk: React.PropTypes.object.isRequired,
-      onAfterFeedbackReceived: React.PropTypes.func.isRequired
+      onAfterFeedbackReceived: React.PropTypes.func.isRequired,
+      sdk: React.PropTypes.object.isRequired
     },
 
     render: function() {
       document.title = mozL10n.get("standalone_title_with_status",
                                    {clientShortname: mozL10n.get("clientShortname2"),
                                     currentStatus: mozL10n.get("status_conversation_ended")});
       return (
         React.createElement("div", {className: "ended-conversation"}, 
           React.createElement(sharedViews.FeedbackView, {
-            onAfterFeedbackReceived: this.props.onAfterFeedbackReceived}
-          ), 
+            onAfterFeedbackReceived: this.props.onAfterFeedbackReceived}), 
           React.createElement(sharedViews.ConversationView, {
+            audio: {enabled: false, visible: false}, 
             initiate: false, 
+            model: this.props.conversation, 
             sdk: this.props.sdk, 
-            model: this.props.conversation, 
-            audio: {enabled: false, visible: false}, 
-            video: {enabled: false, visible: false}}
-          )
+            video: {enabled: false, visible: false}})
         )
       );
     }
   });
 
   var StartConversationView = React.createClass({displayName: "StartConversationView",
     render: function() {
       document.title = mozL10n.get("clientShortname2");
       return (
         React.createElement(InitiateConversationView, React.__spread({}, 
           this.props, 
-          {title: mozL10n.get("initiate_call_button_label2"), 
-          callButtonLabel: mozL10n.get("initiate_audio_video_call_button2")}))
+          {callButtonLabel: mozL10n.get("initiate_audio_video_call_button2"), 
+          title: mozL10n.get("initiate_call_button_label2")}))
       );
     }
   });
 
   var FailedConversationView = React.createClass({displayName: "FailedConversationView",
     mixins: [sharedMixins.AudioMixin],
 
     componentDidMount: function() {
@@ -623,18 +620,18 @@ loop.webapp = (function($, _, OT, mozL10
 
     render: function() {
       document.title = mozL10n.get("standalone_title_with_status",
                                    {clientShortname: mozL10n.get("clientShortname2"),
                                     currentStatus: mozL10n.get("status_error")});
       return (
         React.createElement(InitiateConversationView, React.__spread({}, 
           this.props, 
-          {title: mozL10n.get("call_failed_title"), 
-          callButtonLabel: mozL10n.get("retry_call_button")}))
+          {callButtonLabel: mozL10n.get("retry_call_button"), 
+          title: mozL10n.get("call_failed_title")}))
       );
     }
   });
 
   /**
    * This view manages the outgoing conversation views - from
    * call initiation through to the actual conversation and call end.
    *
@@ -690,57 +687,53 @@ loop.webapp = (function($, _, OT, mozL10
     /**
      * Renders the conversation views.
      */
     render: function() {
       switch (this.state.callStatus) {
         case "start": {
           return (
             React.createElement(StartConversationView, {
+              client: this.props.client, 
               conversation: this.props.conversation, 
-              notifications: this.props.notifications, 
-              client: this.props.client}
-            )
+              notifications: this.props.notifications})
           );
         }
         case "failure": {
           return (
             React.createElement(FailedConversationView, {
+              client: this.props.client, 
               conversation: this.props.conversation, 
-              notifications: this.props.notifications, 
-              client: this.props.client}
-            )
+              notifications: this.props.notifications})
           );
         }
         case "gumPrompt": {
           return React.createElement(GumPromptConversationView, null);
         }
         case "pending": {
           return React.createElement(WaitingConversationView, {websocket: this._websocket});
         }
         case "connected": {
           document.title = mozL10n.get("standalone_title_with_status",
                                        {clientShortname: mozL10n.get("clientShortname2"),
                                         currentStatus: mozL10n.get("status_in_conversation")});
           return (
             React.createElement(sharedViews.ConversationView, {
               initiate: true, 
+              model: this.props.conversation, 
               sdk: this.props.sdk, 
-              model: this.props.conversation, 
-              video: {enabled: this.props.conversation.hasVideoStream("outgoing")}}
-            )
+              video: {enabled: this.props.conversation.hasVideoStream("outgoing")}})
           );
         }
         case "end": {
           return (
             React.createElement(EndedConversationView, {
-              sdk: this.props.sdk, 
               conversation: this.props.conversation, 
-              onAfterFeedbackReceived: this.resetCallStatus()}
-            )
+              onAfterFeedbackReceived: this.resetCallStatus(), 
+              sdk: this.props.sdk})
           );
         }
         case "expired": {
           return (
             React.createElement(CallUrlExpiredView, null)
           );
         }
         default: {
@@ -934,33 +927,31 @@ loop.webapp = (function($, _, OT, mozL10
    */
   var WebappRootView = React.createClass({displayName: "WebappRootView",
 
     mixins: [sharedMixins.UrlHashChangeMixin,
              sharedMixins.DocumentLocationMixin,
              Backbone.Events],
 
     propTypes: {
+      activeRoomStore: React.PropTypes.oneOfType([
+        React.PropTypes.instanceOf(loop.store.ActiveRoomStore),
+        React.PropTypes.instanceOf(loop.store.FxOSActiveRoomStore)
+      ]).isRequired,
       client: React.PropTypes.instanceOf(loop.StandaloneClient).isRequired,
       conversation: React.PropTypes.oneOfType([
         React.PropTypes.instanceOf(sharedModels.ConversationModel),
         React.PropTypes.instanceOf(FxOSConversationModel)
       ]).isRequired,
+      dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
       notifications: React.PropTypes.instanceOf(sharedModels.NotificationCollection)
                           .isRequired,
       sdk: React.PropTypes.object.isRequired,
-
-      // XXX New types for flux style
       standaloneAppStore: React.PropTypes.instanceOf(
-        loop.store.StandaloneAppStore).isRequired,
-      activeRoomStore: React.PropTypes.oneOfType([
-        React.PropTypes.instanceOf(loop.store.ActiveRoomStore),
-        React.PropTypes.instanceOf(loop.store.FxOSActiveRoomStore)
-      ]).isRequired,
-      dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired
+        loop.store.StandaloneAppStore).isRequired
     },
 
     getInitialState: function() {
       return this.props.standaloneAppStore.getStoreState();
     },
 
     componentWillMount: function() {
       this.listenTo(this.props.standaloneAppStore, "change", function() {
@@ -983,30 +974,28 @@ loop.webapp = (function($, _, OT, mozL10
         }
         case "unsupportedBrowser": {
           return React.createElement(UnsupportedBrowserView, {isFirefox: this.state.isFirefox});
         }
         case "outgoing": {
           return (
             React.createElement(OutgoingConversationView, {
                client: this.props.client, 
+               conversation: this.props.conversation, 
                dispatcher: this.props.dispatcher, 
-               conversation: this.props.conversation, 
                notifications: this.props.notifications, 
-               sdk: this.props.sdk}
-            )
+               sdk: this.props.sdk})
           );
         }
         case "room": {
           return (
             React.createElement(loop.standaloneRoomViews.StandaloneRoomView, {
               activeRoomStore: this.props.activeRoomStore, 
               dispatcher: this.props.dispatcher, 
-              isFirefox: this.state.isFirefox}
-            )
+              isFirefox: this.state.isFirefox})
           );
         }
         case "home": {
           return React.createElement(HomeView, null);
         }
         default: {
           // The state hasn't been initialised yet, so don't display
           // anything to avoid flicker.
@@ -1102,24 +1091,23 @@ loop.webapp = (function($, _, OT, mozL10
       textChatStore: textChatStore
     });
 
     window.addEventListener("unload", function() {
       dispatcher.dispatch(new sharedActions.WindowUnload());
     });
 
     React.render(React.createElement(WebappRootView, {
+      activeRoomStore: activeRoomStore, 
       client: client, 
       conversation: conversation, 
+      dispatcher: dispatcher, 
       notifications: notifications, 
       sdk: OT, 
-      standaloneAppStore: standaloneAppStore, 
-      activeRoomStore: activeRoomStore, 
-      dispatcher: dispatcher}
-    ), document.querySelector("#main"));
+      standaloneAppStore: standaloneAppStore}), document.querySelector("#main"));
 
     // Set the 'lang' and 'dir' attributes to <html> when the page is translated
     document.documentElement.lang = mozL10n.language.code;
     document.documentElement.dir = mozL10n.language.direction;
     document.title = mozL10n.get("clientShortname2");
 
     var locationData = sharedUtils.locationData();
 
--- a/browser/components/loop/standalone/content/js/webapp.jsx
+++ b/browser/components/loop/standalone/content/js/webapp.jsx
@@ -243,21 +243,21 @@ loop.webapp = (function($, _, OT, mozL10
       );
     }
   });
 
   var ConversationFooter = React.createClass({
     render: function() {
       return (
         <div className="standalone-footer container-box">
-          <div title={mozL10n.get("vendor_alttext",
-                                  {vendorShortname: mozL10n.get("vendorShortname")})}
-               className="footer-logo"></div>
+          <div className="footer-logo"
+               title={mozL10n.get("vendor_alttext",
+                                  {vendorShortname: mozL10n.get("vendorShortname")})} />
           <div className="footer-external-links">
-            <a target="_blank" href={loop.config.generalSupportUrl}>
+            <a href={loop.config.generalSupportUrl} target="_blank">
               {mozL10n.get("support_link")}
             </a>
           </div>
         </div>
       );
     }
   });
 
@@ -369,29 +369,28 @@ loop.webapp = (function($, _, OT, mozL10
       var callState = mozL10n.get(callStateStringEntityName);
       document.title = mozL10n.get("standalone_title_with_status",
                                    {clientShortname: mozL10n.get("clientShortname2"),
                                     currentStatus: mozL10n.get(callStateStringEntityName)});
 
       return (
         <PendingConversationView
           callState={callState}
-          cancelCallback={this._cancelOutgoingCall}
-        />
+          cancelCallback={this._cancelOutgoingCall} />
       );
     }
   });
 
   var InitiateCallButton = React.createClass({
     mixins: [sharedMixins.DropdownMenuMixin()],
 
     propTypes: {
       caption: React.PropTypes.string.isRequired,
-      startCall: React.PropTypes.func.isRequired,
-      disabled: React.PropTypes.bool
+      disabled: React.PropTypes.bool,
+      startCall: React.PropTypes.func.isRequired
     },
 
     getDefaultProps: function() {
       return {disabled: false};
     },
 
     render: function() {
       var dropdownMenuClasses = React.addons.classSet({
@@ -403,33 +402,33 @@ loop.webapp = (function($, _, OT, mozL10
         "btn-chevron": true,
         "disabled": this.props.disabled
       });
       return (
         <div className="standalone-btn-chevron-menu-group">
           <div className="btn-group-chevron">
             <div className="btn-group">
               <button className="btn btn-constrained btn-large btn-accept"
+                      disabled={this.props.disabled}
                       onClick={this.props.startCall("audio-video")}
-                      disabled={this.props.disabled}
                       title={mozL10n.get("initiate_audio_video_call_tooltip2")}>
                 <span className="standalone-call-btn-text">
                   {this.props.caption}
                 </span>
                 <span className="standalone-call-btn-video-icon" />
               </button>
               <div className={chevronClasses}
                    onClick={this.toggleDropdownMenu}>
               </div>
             </div>
             <ul className={dropdownMenuClasses}>
               <li>
                 <button className="start-audio-only-call"
-                        onClick={this.props.startCall("audio")}
-                        disabled={this.props.disabled}>
+                        disabled={this.props.disabled}
+                        onClick={this.props.startCall("audio")}>
                   {mozL10n.get("initiate_audio_call_button2")}
                 </button>
               </li>
             </ul>
           </div>
         </div>
       );
     }
@@ -437,25 +436,25 @@ loop.webapp = (function($, _, OT, mozL10
 
   /**
    * Initiate conversation view.
    */
   var InitiateConversationView = React.createClass({
     mixins: [Backbone.Events],
 
     propTypes: {
+      callButtonLabel: React.PropTypes.string.isRequired,
+      client: React.PropTypes.object.isRequired,
       conversation: React.PropTypes.oneOfType([
                       React.PropTypes.instanceOf(sharedModels.ConversationModel),
                       React.PropTypes.instanceOf(FxOSConversationModel)
                     ]).isRequired,
       // XXX Check more tightly here when we start injecting window.loop.*
       notifications: React.PropTypes.object.isRequired,
-      client: React.PropTypes.object.isRequired,
-      title: React.PropTypes.string.isRequired,
-      callButtonLabel: React.PropTypes.string.isRequired
+      title: React.PropTypes.string.isRequired
     },
 
     getInitialState: function() {
       return {
         urlCreationDateString: "",
         disableCallButton: false
       };
     },
@@ -572,49 +571,47 @@ loop.webapp = (function($, _, OT, mozL10
 
   /**
    * Ended conversation view.
    */
   var EndedConversationView = React.createClass({
     propTypes: {
       conversation: React.PropTypes.instanceOf(sharedModels.ConversationModel)
                          .isRequired,
-      sdk: React.PropTypes.object.isRequired,
-      onAfterFeedbackReceived: React.PropTypes.func.isRequired
+      onAfterFeedbackReceived: React.PropTypes.func.isRequired,
+      sdk: React.PropTypes.object.isRequired
     },
 
     render: function() {
       document.title = mozL10n.get("standalone_title_with_status",
                                    {clientShortname: mozL10n.get("clientShortname2"),
                                     currentStatus: mozL10n.get("status_conversation_ended")});
       return (
         <div className="ended-conversation">
           <sharedViews.FeedbackView
-            onAfterFeedbackReceived={this.props.onAfterFeedbackReceived}
-          />
+            onAfterFeedbackReceived={this.props.onAfterFeedbackReceived} />
           <sharedViews.ConversationView
+            audio={{enabled: false, visible: false}}
             initiate={false}
+            model={this.props.conversation}
             sdk={this.props.sdk}
-            model={this.props.conversation}
-            audio={{enabled: false, visible: false}}
-            video={{enabled: false, visible: false}}
-          />
+            video={{enabled: false, visible: false}} />
         </div>
       );
     }
   });
 
   var StartConversationView = React.createClass({
     render: function() {
       document.title = mozL10n.get("clientShortname2");
       return (
         <InitiateConversationView
           {...this.props}
-          title={mozL10n.get("initiate_call_button_label2")}
-          callButtonLabel={mozL10n.get("initiate_audio_video_call_button2")}/>
+          callButtonLabel={mozL10n.get("initiate_audio_video_call_button2")}
+          title={mozL10n.get("initiate_call_button_label2")} />
       );
     }
   });
 
   var FailedConversationView = React.createClass({
     mixins: [sharedMixins.AudioMixin],
 
     componentDidMount: function() {
@@ -623,18 +620,18 @@ loop.webapp = (function($, _, OT, mozL10
 
     render: function() {
       document.title = mozL10n.get("standalone_title_with_status",
                                    {clientShortname: mozL10n.get("clientShortname2"),
                                     currentStatus: mozL10n.get("status_error")});
       return (
         <InitiateConversationView
           {...this.props}
-          title={mozL10n.get("call_failed_title")}
-          callButtonLabel={mozL10n.get("retry_call_button")} />
+          callButtonLabel={mozL10n.get("retry_call_button")}
+          title={mozL10n.get("call_failed_title")} />
       );
     }
   });
 
   /**
    * This view manages the outgoing conversation views - from
    * call initiation through to the actual conversation and call end.
    *
@@ -690,57 +687,53 @@ loop.webapp = (function($, _, OT, mozL10
     /**
      * Renders the conversation views.
      */
     render: function() {
       switch (this.state.callStatus) {
         case "start": {
           return (
             <StartConversationView
+              client={this.props.client}
               conversation={this.props.conversation}
-              notifications={this.props.notifications}
-              client={this.props.client}
-            />
+              notifications={this.props.notifications} />
           );
         }
         case "failure": {
           return (
             <FailedConversationView
+              client={this.props.client}
               conversation={this.props.conversation}
-              notifications={this.props.notifications}
-              client={this.props.client}
-            />
+              notifications={this.props.notifications} />
           );
         }
         case "gumPrompt": {
           return <GumPromptConversationView />;
         }
         case "pending": {
           return <WaitingConversationView websocket={this._websocket} />;
         }
         case "connected": {
           document.title = mozL10n.get("standalone_title_with_status",
                                        {clientShortname: mozL10n.get("clientShortname2"),
                                         currentStatus: mozL10n.get("status_in_conversation")});
           return (
             <sharedViews.ConversationView
               initiate={true}
+              model={this.props.conversation}
               sdk={this.props.sdk}
-              model={this.props.conversation}
-              video={{enabled: this.props.conversation.hasVideoStream("outgoing")}}
-            />
+              video={{enabled: this.props.conversation.hasVideoStream("outgoing")}} />
           );
         }
         case "end": {
           return (
             <EndedConversationView
-              sdk={this.props.sdk}
               conversation={this.props.conversation}
               onAfterFeedbackReceived={this.resetCallStatus()}
-            />
+              sdk={this.props.sdk} />
           );
         }
         case "expired": {
           return (
             <CallUrlExpiredView />
           );
         }
         default: {
@@ -934,33 +927,31 @@ loop.webapp = (function($, _, OT, mozL10
    */
   var WebappRootView = React.createClass({
 
     mixins: [sharedMixins.UrlHashChangeMixin,
              sharedMixins.DocumentLocationMixin,
              Backbone.Events],
 
     propTypes: {
+      activeRoomStore: React.PropTypes.oneOfType([
+        React.PropTypes.instanceOf(loop.store.ActiveRoomStore),
+        React.PropTypes.instanceOf(loop.store.FxOSActiveRoomStore)
+      ]).isRequired,
       client: React.PropTypes.instanceOf(loop.StandaloneClient).isRequired,
       conversation: React.PropTypes.oneOfType([
         React.PropTypes.instanceOf(sharedModels.ConversationModel),
         React.PropTypes.instanceOf(FxOSConversationModel)
       ]).isRequired,
+      dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
       notifications: React.PropTypes.instanceOf(sharedModels.NotificationCollection)
                           .isRequired,
       sdk: React.PropTypes.object.isRequired,
-
-      // XXX New types for flux style
       standaloneAppStore: React.PropTypes.instanceOf(
-        loop.store.StandaloneAppStore).isRequired,
-      activeRoomStore: React.PropTypes.oneOfType([
-        React.PropTypes.instanceOf(loop.store.ActiveRoomStore),
-        React.PropTypes.instanceOf(loop.store.FxOSActiveRoomStore)
-      ]).isRequired,
-      dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired
+        loop.store.StandaloneAppStore).isRequired
     },
 
     getInitialState: function() {
       return this.props.standaloneAppStore.getStoreState();
     },
 
     componentWillMount: function() {
       this.listenTo(this.props.standaloneAppStore, "change", function() {
@@ -983,30 +974,28 @@ loop.webapp = (function($, _, OT, mozL10
         }
         case "unsupportedBrowser": {
           return <UnsupportedBrowserView isFirefox={this.state.isFirefox}/>;
         }
         case "outgoing": {
           return (
             <OutgoingConversationView
                client={this.props.client}
+               conversation={this.props.conversation}
                dispatcher={this.props.dispatcher}
-               conversation={this.props.conversation}
                notifications={this.props.notifications}
-               sdk={this.props.sdk}
-            />
+               sdk={this.props.sdk} />
           );
         }
         case "room": {
           return (
             <loop.standaloneRoomViews.StandaloneRoomView
               activeRoomStore={this.props.activeRoomStore}
               dispatcher={this.props.dispatcher}
-              isFirefox={this.state.isFirefox}
-            />
+              isFirefox={this.state.isFirefox} />
           );
         }
         case "home": {
           return <HomeView />;
         }
         default: {
           // The state hasn't been initialised yet, so don't display
           // anything to avoid flicker.
@@ -1102,24 +1091,23 @@ loop.webapp = (function($, _, OT, mozL10
       textChatStore: textChatStore
     });
 
     window.addEventListener("unload", function() {
       dispatcher.dispatch(new sharedActions.WindowUnload());
     });
 
     React.render(<WebappRootView
+      activeRoomStore={activeRoomStore}
       client={client}
       conversation={conversation}
+      dispatcher={dispatcher}
       notifications={notifications}
       sdk={OT}
-      standaloneAppStore={standaloneAppStore}
-      activeRoomStore={activeRoomStore}
-      dispatcher={dispatcher}
-    />, document.querySelector("#main"));
+      standaloneAppStore={standaloneAppStore} />, document.querySelector("#main"));
 
     // Set the 'lang' and 'dir' attributes to <html> when the page is translated
     document.documentElement.lang = mozL10n.language.code;
     document.documentElement.dir = mozL10n.language.direction;
     document.title = mozL10n.get("clientShortname2");
 
     var locationData = sharedUtils.locationData();
 
--- a/browser/components/loop/ui/react-frame-component.js
+++ b/browser/components/loop/ui/react-frame-component.js
@@ -20,28 +20,28 @@ window.queuedFrames = [];
  * contents will have been rendered, and then fires a callback indicating that.
  *
  * @see onContentsRendered for the gory details about this.
  *
  * @type {ReactComponentFactory<P>}
  */
 window.Frame = React.createClass({
   propTypes: {
-    style: React.PropTypes.object,
-    head: React.PropTypes.node,
-    width: React.PropTypes.number,
-    height: React.PropTypes.number,
-    onContentsRendered: React.PropTypes.func,
     className: React.PropTypes.string,
     /* By default, <link rel="stylesheet> nodes from the containing frame's
        head will be cloned into this iframe.  However, if the link also has
        a "class" attribute, we only clone it if that class attribute is the
        same as cssClass.  This allows us to avoid injecting stylesheets that
        aren't intended for this rendering of this component. */
-    cssClass: React.PropTypes.string
+    cssClass: React.PropTypes.string,
+    head: React.PropTypes.node,
+    height: React.PropTypes.number,
+    onContentsRendered: React.PropTypes.func,
+    style: React.PropTypes.object,
+    width: React.PropTypes.number
   },
   render: function() {
     return React.createElement("iframe", {
       style: this.props.style,
       head: this.props.head,
       width: this.props.width,
       height: this.props.height,
       className: this.props.className
--- a/browser/components/loop/ui/ui-showcase.js
+++ b/browser/components/loop/ui/ui-showcase.js
@@ -380,19 +380,19 @@
     detailsButtonLabel: "Retry"
   });
 
   var SVGIcon = React.createClass({displayName: "SVGIcon",
     render: function() {
       var sizeUnit = this.props.size.split("x");
       return (
         React.createElement("img", {className: "svg-icon", 
+             height: sizeUnit[1], 
              src: "../content/shared/img/icons-" + this.props.size + ".svg#" + this.props.shapeId, 
-             width: sizeUnit[0], 
-             height: sizeUnit[1]})
+             width: sizeUnit[0]})
       );
     }
   });
 
   var SVGIcons = React.createClass({displayName: "SVGIcons",
     shapes: {
       "10x10": ["close", "close-active", "close-disabled", "dropdown",
         "dropdown-white", "dropdown-active", "dropdown-disabled", "edit",
@@ -416,35 +416,35 @@
         "tag-hover", "tag-active", "trash", "unblock", "unblock-hover", "unblock-active",
         "video", "video-hover", "video-active", "tour"
       ]
     },
 
     render: function() {
       var icons = this.shapes[this.props.size].map(function(shapeId, i) {
         return (
-          React.createElement("li", {key: this.props.size + "-" + i, className: "svg-icon-entry"}, 
+          React.createElement("li", {className: "svg-icon-entry", key: this.props.size + "-" + i}, 
             React.createElement("p", null, React.createElement(SVGIcon, {shapeId: shapeId, size: this.props.size})), 
             React.createElement("p", null, shapeId)
           )
         );
       }, this);
       return (
         React.createElement("ul", {className: "svg-icon-list"}, icons)
       );
     }
   });
 
   var FramedExample = React.createClass({displayName: "FramedExample",
     propTypes: {
-      width: React.PropTypes.number,
+      cssClass: React.PropTypes.string,
+      dashed: React.PropTypes.bool,
       height: React.PropTypes.number,
       onContentsRendered: React.PropTypes.func,
-      dashed: React.PropTypes.bool,
-      cssClass: React.PropTypes.string
+      width: React.PropTypes.number
     },
 
     makeId: function(prefix) {
       return (prefix || "") + this.props.summary.toLowerCase().replace(/\s/g, "-");
     },
 
     render: function() {
       var height = this.props.height;
@@ -459,20 +459,21 @@
       var cx = React.addons.classSet;
       return (
         React.createElement("div", {className: "example"}, 
           React.createElement("h3", {id: this.makeId()}, 
             this.props.summary, 
             React.createElement("a", {href: this.makeId("#")}, " ¶")
           ), 
           React.createElement("div", {className: "comp"}, 
-            React.createElement(Frame, {width: width, height: height, 
+            React.createElement(Frame, {className: cx({dashed: this.props.dashed}), 
+                   cssClass: this.props.cssClass, 
+                   height: height, 
                    onContentsRendered: this.props.onContentsRendered, 
-                   className: cx({dashed: this.props.dashed}), 
-                   cssClass: this.props.cssClass}, 
+                   width: width}, 
               this.props.children
             )
           )
         )
       );
     }
   });
 
@@ -496,17 +497,17 @@
         )
       );
     }
   });
 
   var Section = React.createClass({displayName: "Section",
     render: function() {
       return (
-        React.createElement("section", {id: this.props.name, className: this.props.className}, 
+        React.createElement("section", {className: this.props.className, id: this.props.name}, 
           React.createElement("h1", null, this.props.name), 
           this.props.children
         )
       );
     }
   });
 
   var ShowCase = React.createClass({displayName: "ShowCase",
@@ -539,17 +540,17 @@
         document.documentElement.setAttribute("lang", "ar");
         document.documentElement.setAttribute("dir", "rtl");
       }
 
       return (
         React.createElement("div", {className: "showcase"}, 
           React.createElement("header", null, 
             React.createElement("h1", null, "Loop UI Components Showcase"), 
-            React.createElement(Checkbox, {label: "RTL mode?", checked: this.state.rtlMode, 
+            React.createElement(Checkbox, {checked: this.state.rtlMode, label: "RTL mode?", 
               onChange: this._handleCheckboxChange}), 
             React.createElement("nav", {className: "showcase-menu"}, 
               React.Children.map(this.props.children, function(section) {
                 return (
                   React.createElement("a", {className: "btn btn-info", href: "#" + section.props.name}, 
                     section.props.name
                   )
                 );
@@ -566,252 +567,273 @@
 
     render: function() {
       return (
         React.createElement(ShowCase, null, 
           React.createElement(Section, {name: "PanelView"}, 
             React.createElement("p", {className: "note"}, 
               React.createElement("strong", null, "Note:"), " 332px wide."
             ), 
-            React.createElement(Example, {summary: "Re-sign-in view", dashed: "true", style: {width: "332px"}}, 
+            React.createElement(Example, {dashed: "true", style: {width: "332px"}, summary: "Re-sign-in view"}, 
               React.createElement(SignInRequestView, {mozLoop: mockMozLoopRooms})
             ), 
-            React.createElement(Example, {summary: "Room list tab", dashed: "true", style: {width: "332px"}}, 
-              React.createElement(PanelView, {client: mockClient, notifications: notifications, 
-                         userProfile: {email: "test@example.com"}, 
+            React.createElement(Example, {dashed: "true", style: {width: "332px"}, summary: "Room list tab"}, 
+              React.createElement(PanelView, {client: mockClient, 
+                         dispatcher: dispatcher, 
                          mozLoop: mockMozLoopRooms, 
-                         dispatcher: dispatcher, 
+                         notifications: notifications, 
                          roomStore: roomStore, 
-                         selectedTab: "rooms"})
+                         selectedTab: "rooms", 
+                         userProfile: {email: "test@example.com"}})
             ), 
-            React.createElement(Example, {summary: "Contact list tab", dashed: "true", style: {width: "332px"}}, 
-              React.createElement(PanelView, {client: mockClient, notifications: notifications, 
-                         userProfile: {email: "test@example.com"}, 
+            React.createElement(Example, {dashed: "true", style: {width: "332px"}, summary: "Contact list tab"}, 
+              React.createElement(PanelView, {client: mockClient, 
+                         dispatcher: dispatcher, 
                          mozLoop: mockMozLoopRooms, 
-                         dispatcher: dispatcher, 
+                         notifications: notifications, 
                          roomStore: roomStore, 
-                         selectedTab: "contacts"})
+                         selectedTab: "contacts", 
+                         userProfile: {email: "test@example.com"}})
             ), 
-            React.createElement(Example, {summary: "Error Notification", dashed: "true", style: {width: "332px"}}, 
-              React.createElement(PanelView, {client: mockClient, notifications: errNotifications, 
+            React.createElement(Example, {dashed: "true", style: {width: "332px"}, summary: "Error Notification"}, 
+              React.createElement(PanelView, {client: mockClient, 
+                         dispatcher: dispatcher, 
                          mozLoop: navigator.mozLoop, 
-                         dispatcher: dispatcher, 
+                         notifications: errNotifications, 
                          roomStore: roomStore})
             ), 
-            React.createElement(Example, {summary: "Error Notification - authenticated", dashed: "true", style: {width: "332px"}}, 
-              React.createElement(PanelView, {client: mockClient, notifications: errNotifications, 
-                         userProfile: {email: "test@example.com"}, 
-                         mozLoop: navigator.mozLoop, 
+            React.createElement(Example, {dashed: "true", style: {width: "332px"}, summary: "Error Notification - authenticated"}, 
+              React.createElement(PanelView, {client: mockClient, 
                          dispatcher: dispatcher, 
-                         roomStore: roomStore})
+                         mozLoop: navigator.mozLoop, 
+                         notifications: errNotifications, 
+                         roomStore: roomStore, 
+                         userProfile: {email: "test@example.com"}})
             ), 
-            React.createElement(Example, {summary: "Contact import success", dashed: "true", style: {width: "332px"}}, 
-              React.createElement(PanelView, {notifications: new loop.shared.models.NotificationCollection([{level: "success", message: "Import success"}]), 
-                         userProfile: {email: "test@example.com"}, 
+            React.createElement(Example, {dashed: "true", style: {width: "332px"}, summary: "Contact import success"}, 
+              React.createElement(PanelView, {dispatcher: dispatcher, 
                          mozLoop: mockMozLoopRooms, 
-                         dispatcher: dispatcher, 
+                         notifications: new loop.shared.models.NotificationCollection([{level: "success", message: "Import success"}]), 
                          roomStore: roomStore, 
-                         selectedTab: "contacts"})
+                         selectedTab: "contacts", 
+                         userProfile: {email: "test@example.com"}})
             ), 
-            React.createElement(Example, {summary: "Contact import error", dashed: "true", style: {width: "332px"}}, 
-              React.createElement(PanelView, {notifications: new loop.shared.models.NotificationCollection([{level: "error", message: "Import error"}]), 
-                         userProfile: {email: "test@example.com"}, 
+            React.createElement(Example, {dashed: "true", style: {width: "332px"}, summary: "Contact import error"}, 
+              React.createElement(PanelView, {dispatcher: dispatcher, 
                          mozLoop: mockMozLoopRooms, 
-                         dispatcher: dispatcher, 
+                         notifications: new loop.shared.models.NotificationCollection([{level: "error", message: "Import error"}]), 
                          roomStore: roomStore, 
-                         selectedTab: "contacts"})
+                         selectedTab: "contacts", 
+                         userProfile: {email: "test@example.com"}})
             )
           ), 
 
           React.createElement(Section, {name: "AcceptCallView"}, 
-            React.createElement(Example, {summary: "Default / incoming video call", dashed: "true", style: {width: "300px", height: "272px"}}, 
+            React.createElement(Example, {dashed: "true", style: {width: "300px", height: "272px"}, 
+                     summary: "Default / incoming video call"}, 
               React.createElement("div", {className: "fx-embedded"}, 
                 React.createElement(AcceptCallView, {callType: CALL_TYPES.AUDIO_VIDEO, 
                                 callerId: "Mr Smith", 
                                 dispatcher: dispatcher, 
                                 mozLoop: mockMozLoopRooms})
               )
             ), 
 
-            React.createElement(Example, {summary: "Default / incoming audio only call", dashed: "true", style: {width: "300px", height: "272px"}}, 
+            React.createElement(Example, {dashed: "true", style: {width: "300px", height: "272px"}, 
+                     summary: "Default / incoming audio only call"}, 
               React.createElement("div", {className: "fx-embedded"}, 
                 React.createElement(AcceptCallView, {callType: CALL_TYPES.AUDIO_ONLY, 
                                 callerId: "Mr Smith", 
                                 dispatcher: dispatcher, 
                                 mozLoop: mockMozLoopRooms})
               )
             )
           ), 
 
           React.createElement(Section, {name: "AcceptCallView-ActiveState"}, 
-            React.createElement(Example, {summary: "Default", dashed: "true", style: {width: "300px", height: "272px"}}, 
+            React.createElement(Example, {dashed: "true", style: {width: "300px", height: "272px"}, 
+                     summary: "Default"}, 
               React.createElement("div", {className: "fx-embedded"}, 
                 React.createElement(AcceptCallView, {callType: CALL_TYPES.AUDIO_VIDEO, 
                                 callerId: "Mr Smith", 
                                 dispatcher: dispatcher, 
                                 mozLoop: mockMozLoopRooms, 
                                 showMenu: true})
               )
             )
           ), 
 
           React.createElement(Section, {name: "ConversationToolbar"}, 
             React.createElement("h2", null, "Desktop Conversation Window"), 
             React.createElement("div", {className: "fx-embedded override-position"}, 
-              React.createElement(Example, {summary: "Default", style: {width: "300px", height: "26px"}}, 
-                React.createElement(ConversationToolbar, {video: {enabled: true}, 
-                                     audio: {enabled: true}, 
+              React.createElement(Example, {style: {width: "300px", height: "26px"}, summary: "Default"}, 
+                React.createElement(ConversationToolbar, {audio: {enabled: true}, 
                                      hangup: noop, 
-                                     publishStream: noop})
+                                     publishStream: noop, 
+                                     video: {enabled: true}})
               ), 
-              React.createElement(Example, {summary: "Video muted", style: {width: "300px", height: "26px"}}, 
-                React.createElement(ConversationToolbar, {video: {enabled: false}, 
-                                     audio: {enabled: true}, 
+              React.createElement(Example, {style: {width: "300px", height: "26px"}, summary: "Video muted"}, 
+                React.createElement(ConversationToolbar, {audio: {enabled: true}, 
                                      hangup: noop, 
-                                     publishStream: noop})
+                                     publishStream: noop, 
+                                     video: {enabled: false}})
               ), 
-              React.createElement(Example, {summary: "Audio muted", style: {width: "300px", height: "26px"}}, 
-                React.createElement(ConversationToolbar, {video: {enabled: true}, 
-                                     audio: {enabled: false}, 
+              React.createElement(Example, {style: {width: "300px", height: "26px"}, summary: "Audio muted"}, 
+                React.createElement(ConversationToolbar, {audio: {enabled: false}, 
                                      hangup: noop, 
-                                     publishStream: noop})
+                                     publishStream: noop, 
+                                     video: {enabled: true}})
               )
             ), 
 
             React.createElement("h2", null, "Standalone"), 
             React.createElement("div", {className: "standalone override-position"}, 
               React.createElement(Example, {summary: "Default"}, 
-                React.createElement(ConversationToolbar, {video: {enabled: true}, 
-                                     audio: {enabled: true}, 
+                React.createElement(ConversationToolbar, {audio: {enabled: true}, 
                                      hangup: noop, 
-                                     publishStream: noop})
+                                     publishStream: noop, 
+                                     video: {enabled: true}})
               ), 
               React.createElement(Example, {summary: "Video muted"}, 
-                React.createElement(ConversationToolbar, {video: {enabled: false}, 
-                                     audio: {enabled: true}, 
+                React.createElement(ConversationToolbar, {audio: {enabled: true}, 
                                      hangup: noop, 
-                                     publishStream: noop})
+                                     publishStream: noop, 
+                                     video: {enabled: false}})
               ), 
               React.createElement(Example, {summary: "Audio muted"}, 
-                React.createElement(ConversationToolbar, {video: {enabled: true}, 
-                                     audio: {enabled: false}, 
+                React.createElement(ConversationToolbar, {audio: {enabled: false}, 
                                      hangup: noop, 
-                                     publishStream: noop})
+                                     publishStream: noop, 
+                                     video: {enabled: true}})
               )
             )
           ), 
 
           React.createElement(Section, {name: "PendingConversationView (Desktop)"}, 
-            React.createElement(Example, {summary: "Connecting", dashed: "true", 
-                     style: {width: "300px", height: "272px"}}, 
+            React.createElement(Example, {dashed: "true", 
+                     style: {width: "300px", height: "272px"}, 
+                     summary: "Connecting"}, 
               React.createElement("div", {className: "fx-embedded"}, 
                 React.createElement(DesktopPendingConversationView, {callState: "gather", 
                                                 contact: mockContact, 
                                                 dispatcher: dispatcher})
               )
             )
           ), 
 
           React.createElement(Section, {name: "CallFailedView"}, 
-            React.createElement(Example, {summary: "Call Failed - Incoming", dashed: "true", 
-                     style: {width: "300px", height: "272px"}}, 
+            React.createElement(Example, {dashed: "true", 
+                     style: {width: "300px", height: "272px"}, 
+                     summary: "Call Failed - Incoming"}, 
               React.createElement("div", {className: "fx-embedded"}, 
                 React.createElement(CallFailedView, {dispatcher: dispatcher, 
                                 outgoing: false, 
                                 store: conversationStore})
               )
             ), 
-            React.createElement(Example, {summary: "Call Failed - Outgoing", dashed: "true", 
-                     style: {width: "300px", height: "272px"}}, 
+            React.createElement(Example, {dashed: "true", 
+                     style: {width: "300px", height: "272px"}, 
+                     summary: "Call Failed - Outgoing"}, 
               React.createElement("div", {className: "fx-embedded"}, 
                 React.createElement(CallFailedView, {dispatcher: dispatcher, 
                                 outgoing: true, 
                                 store: conversationStore})
               )
             ), 
-            React.createElement(Example, {summary: "Call Failed — with call URL error", dashed: "true", 
-                     style: {width: "300px", height: "272px"}}, 
+            React.createElement(Example, {dashed: "true", 
+                     style: {width: "300px", height: "272px"}, 
+                     summary: "Call Failed — with call URL error"}, 
               React.createElement("div", {className: "fx-embedded"}, 
                 React.createElement(CallFailedView, {dispatcher: dispatcher, emailLinkError: true, 
                                 outgoing: true, 
                                 store: conversationStore})
               )
             )
           ), 
 
           React.createElement(Section, {name: "OngoingConversationView"}, 
-            React.createElement(FramedExample, {width: 298, height: 254, 
-                           summary: "Desktop ongoing conversation window"}, 
+            React.createElement(FramedExample, {height: 254, 
+                           summary: "Desktop ongoing conversation window", 
+                           width: 298}, 
               React.createElement("div", {className: "fx-embedded"}, 
                 React.createElement(OngoingConversationView, {
+                  audio: {enabled: true}, 
                   dispatcher: dispatcher, 
-                  video: {enabled: true}, 
-                  audio: {enabled: true}, 
                   localPosterUrl: "sample-img/video-screen-local.png", 
+                  mediaConnected: true, 
                   remotePosterUrl: "sample-img/video-screen-remote.png", 
                   remoteVideoEnabled: true, 
-                  mediaConnected: true})
+                  video: {enabled: true}})
               )
             ), 
 
-            React.createElement(FramedExample, {width: 800, height: 600, 
-                           summary: "Desktop ongoing conversation window large"}, 
+            React.createElement(FramedExample, {height: 600, 
+                           summary: "Desktop ongoing conversation window large", 
+                           width: 800}, 
                 React.createElement("div", {className: "fx-embedded"}, 
                   React.createElement(OngoingConversationView, {
+                    audio: {enabled: true}, 
                     dispatcher: dispatcher, 
-                    video: {enabled: true}, 
-                    audio: {enabled: true}, 
                     localPosterUrl: "sample-img/video-screen-local.png", 
+                    mediaConnected: true, 
                     remotePosterUrl: "sample-img/video-screen-remote.png", 
                     remoteVideoEnabled: true, 
-                    mediaConnected: true})
+                    video: {enabled: true}})
                 )
             ), 
 
-            React.createElement(FramedExample, {width: 298, height: 254, 
-              summary: "Desktop ongoing conversation window - local face mute"}, 
+            React.createElement(FramedExample, {height: 254, 
+              summary: "Desktop ongoing conversation window - local face mute", 
+              width: 298}, 
               React.createElement("div", {className: "fx-embedded"}, 
                 React.createElement(OngoingConversationView, {
+                  audio: {enabled: true}, 
                   dispatcher: dispatcher, 
-                  video: {enabled: false}, 
-                  audio: {enabled: true}, 
+                  mediaConnected: true, 
+                  remotePosterUrl: "sample-img/video-screen-remote.png", 
                   remoteVideoEnabled: true, 
-                  remotePosterUrl: "sample-img/video-screen-remote.png", 
-                  mediaConnected: true})
+                  video: {enabled: false}})
               )
             ), 
 
-            React.createElement(FramedExample, {width: 298, height: 254, 
-              summary: "Desktop ongoing conversation window - remote face mute"}, 
+            React.createElement(FramedExample, {height: 254, 
+              summary: "Desktop ongoing conversation window - remote face mute", 
+              width: 298}, 
               React.createElement("div", {className: "fx-embedded"}, 
                 React.createElement(OngoingConversationView, {
+                  audio: {enabled: true}, 
                   dispatcher: dispatcher, 
-                  video: {enabled: true}, 
-                  audio: {enabled: true}, 
+                  localPosterUrl: "sample-img/video-screen-local.png", 
+                  mediaConnected: true, 
                   remoteVideoEnabled: false, 
-                  localPosterUrl: "sample-img/video-screen-local.png", 
-                  mediaConnected: true})
+                  video: {enabled: true}})
               )
             )
 
           ), 
 
           React.createElement(Section, {name: "FeedbackView"}, 
             React.createElement("p", {className: "note"}, 
               React.createElement("strong", null, "Note:"), " For the useable demo, you can access submitted data at ", 
               React.createElement("a", {href: "https://input.allizom.org/"}, "input.allizom.org"), "."
             ), 
-            React.createElement(Example, {summary: "Default (useable demo)", dashed: "true", style: {width: "300px", height: "272px"}}, 
+            React.createElement(Example, {dashed: "true", 
+                     style: {width: "300px", height: "272px"}, 
+                     summary: "Default (useable demo)"}, 
               React.createElement(FeedbackView, {feedbackStore: feedbackStore})
             ), 
-            React.createElement(Example, {summary: "Detailed form", dashed: "true", style: {width: "300px", height: "272px"}}, 
-              React.createElement(FeedbackView, {feedbackStore: feedbackStore, feedbackState: FEEDBACK_STATES.DETAILS})
+            React.createElement(Example, {dashed: "true", 
+                     style: {width: "300px", height: "272px"}, 
+                     summary: "Detailed form"}, 
+              React.createElement(FeedbackView, {feedbackState: FEEDBACK_STATES.DETAILS, feedbackStore: feedbackStore})
             ), 
-            React.createElement(Example, {summary: "Thank you!", dashed: "true", style: {width: "300px", height: "272px"}}, 
-              React.createElement(FeedbackView, {feedbackStore: feedbackStore, feedbackState: FEEDBACK_STATES.SENT})
+            React.createElement(Example, {dashed: "true", 
+                     style: {width: "300px", height: "272px"}, 
+                     summary: "Thank you!"}, 
+              React.createElement(FeedbackView, {feedbackState: FEEDBACK_STATES.SENT, feedbackStore: feedbackStore})
             )
           ), 
 
           React.createElement(Section, {name: "AlertMessages"}, 
             React.createElement(Example, {summary: "Various alerts"}, 
               React.createElement("div", {className: "alert alert-warning"}, 
                 React.createElement("button", {className: "close"}), 
                 React.createElement("p", {className: "message"}, 
@@ -840,319 +862,364 @@
             React.createElement(Example, {summary: "Standalone Unsupported Device"}, 
               React.createElement("div", {className: "standalone"}, 
                 React.createElement(UnsupportedDeviceView, {platform: "ios"})
               )
             )
           ), 
 
           React.createElement(Section, {name: "DesktopRoomConversationView"}, 
-            React.createElement(FramedExample, {width: 298, height: 254, 
-              summary: "Desktop room conversation (invitation, text-chat inclusion/scrollbars don't happen in real client)"}, 
+            React.createElement(FramedExample, {
+              height: 254, 
+              summary: "Desktop room conversation (invitation, text-chat inclusion/scrollbars don't happen in real client)", 
+              width: 298}, 
               React.createElement("div", {className: "fx-embedded"}, 
                 React.createElement(DesktopRoomConversationView, {
-                  roomStore: invitationRoomStore, 
                   dispatcher: dispatcher, 
+                  localPosterUrl: "sample-img/video-screen-local.png", 
                   mozLoop: navigator.mozLoop, 
-                  localPosterUrl: "sample-img/video-screen-local.png", 
-                  roomState: ROOM_STATES.INIT})
+                  roomState: ROOM_STATES.INIT, 
+                  roomStore: invitationRoomStore})
               )
             ), 
 
-            React.createElement(FramedExample, {width: 298, height: 394, dashed: true, 
-              summary: "Desktop room conversation (loading)"}, 
+            React.createElement(FramedExample, {
+              dashed: true, 
+              height: 394, 
+              summary: "Desktop room conversation (loading)", 
+              width: 298}, 
               /* Hide scrollbars here. Rotating loading div overflows and causes
                scrollbars to appear */
               React.createElement("div", {className: "fx-embedded overflow-hidden"}, 
                 React.createElement(DesktopRoomConversationView, {
-                  roomStore: desktopRoomStoreLoading, 
                   dispatcher: dispatcher, 
+                  localPosterUrl: "sample-img/video-screen-local.png", 
                   mozLoop: navigator.mozLoop, 
-                  localPosterUrl: "sample-img/video-screen-local.png", 
                   remotePosterUrl: "sample-img/video-screen-remote.png", 
-                  roomState: ROOM_STATES.HAS_PARTICIPANTS})
+                  roomState: ROOM_STATES.HAS_PARTICIPANTS, 
+                  roomStore: desktopRoomStoreLoading})
+              )
+            ), 
+
+            React.createElement(FramedExample, {height: 254, 
+                           summary: "Desktop room conversation"}, 
+              React.createElement("div", {className: "fx-embedded"}, 
+                React.createElement(DesktopRoomConversationView, {
+                  dispatcher: dispatcher, 
+                  localPosterUrl: "sample-img/video-screen-local.png", 
+                  mozLoop: navigator.mozLoop, 
+                  remotePosterUrl: "sample-img/video-screen-remote.png", 
+                  roomState: ROOM_STATES.HAS_PARTICIPANTS, 
+                  roomStore: roomStore})
               )
             ), 
 
-            React.createElement(FramedExample, {width: 298, height: 254, 
-              summary: "Desktop room conversation"}, 
+            React.createElement(FramedExample, {dashed: true, 
+                           height: 394, 
+                           summary: "Desktop room conversation local face-mute", 
+                           width: 298}, 
               React.createElement("div", {className: "fx-embedded"}, 
                 React.createElement(DesktopRoomConversationView, {
-                  roomStore: roomStore, 
                   dispatcher: dispatcher, 
                   mozLoop: navigator.mozLoop, 
-                  localPosterUrl: "sample-img/video-screen-local.png", 
                   remotePosterUrl: "sample-img/video-screen-remote.png", 
-                  roomState: ROOM_STATES.HAS_PARTICIPANTS})
+                  roomStore: desktopLocalFaceMuteRoomStore})
               )
             ), 
 
-            React.createElement(FramedExample, {width: 298, height: 394, dashed: true, 
-                           summary: "Desktop room conversation local face-mute"}, 
+            React.createElement(FramedExample, {dashed: true, height: 394, 
+                           summary: "Desktop room conversation remote face-mute", 
+                           width: 298}, 
               React.createElement("div", {className: "fx-embedded"}, 
                 React.createElement(DesktopRoomConversationView, {
-                  roomStore: desktopLocalFaceMuteRoomStore, 
                   dispatcher: dispatcher, 
+                  localPosterUrl: "sample-img/video-screen-local.png", 
                   mozLoop: navigator.mozLoop, 
-                  remotePosterUrl: "sample-img/video-screen-remote.png"})
-              )
-            ), 
-
-            React.createElement(FramedExample, {width: 298, height: 394, dashed: true, 
-                           summary: "Desktop room conversation remote face-mute"}, 
-              React.createElement("div", {className: "fx-embedded"}, 
-                React.createElement(DesktopRoomConversationView, {
-                  roomStore: desktopRemoteFaceMuteRoomStore, 
-                  dispatcher: dispatcher, 
-                  mozLoop: navigator.mozLoop, 
-                  localPosterUrl: "sample-img/video-screen-local.png"})
+                  roomStore: desktopRemoteFaceMuteRoomStore})
               )
             )
           ), 
 
           React.createElement(Section, {name: "StandaloneRoomView"}, 
-            React.createElement(FramedExample, {width: 644, height: 483, dashed: true, 
-                           cssClass: "standalone", 
-                           summary: "Standalone room conversation (ready)"}, 
+            React.createElement(FramedExample, {cssClass: "standalone", 
+                           dashed: true, 
+                           height: 483, 
+                           summary: "Standalone room conversation (ready)", 
+                           width: 644}, 
               React.createElement("div", {className: "standalone"}, 
                 React.createElement(StandaloneRoomView, {
+                  activeRoomStore: readyRoomStore, 
                   dispatcher: dispatcher, 
-                  activeRoomStore: readyRoomStore, 
-                  roomState: ROOM_STATES.READY, 
-                  isFirefox: true})
+                  isFirefox: true, 
+                  roomState: ROOM_STATES.READY})
               )
             ), 
 
-            React.createElement(FramedExample, {width: 644, height: 483, dashed: true, 
-              summary: "Standalone room conversation (joined)", 
-              cssClass: "standalone", 
-              onContentsRendered: joinedRoomStore.forcedUpdate}, 
+            React.createElement(FramedExample, {cssClass: "standalone", 
+                           dashed: true, 
+                           height: 483, 
+                           onContentsRendered: joinedRoomStore.forcedUpdate, 
+                           summary: "Standalone room conversation (joined)", 
+                           width: 644}, 
               React.createElement("div", {className: "standalone"}, 
                 React.createElement(StandaloneRoomView, {
+                  activeRoomStore: joinedRoomStore, 
                   dispatcher: dispatcher, 
-                  activeRoomStore: joinedRoomStore, 
-                  localPosterUrl: "sample-img/video-screen-local.png", 
-                  isFirefox: true})
+                  isFirefox: true, 
+                  localPosterUrl: "sample-img/video-screen-local.png"})
               )
             ), 
 
-            React.createElement(FramedExample, {width: 644, height: 483, dashed: true, 
-              summary: "Standalone room conversation (loading remote)", 
-              cssClass: "standalone", 
-              onContentsRendered: loadingRemoteVideoRoomStore.forcedUpdate}, 
+            React.createElement(FramedExample, {cssClass: "standalone", 
+                           dashed: true, 
+                           height: 483, 
+                           onContentsRendered: loadingRemoteVideoRoomStore.forcedUpdate, 
+                           summary: "Standalone room conversation (loading remote)", 
+                           width: 644}, 
               React.createElement("div", {className: "standalone"}, 
                 React.createElement(StandaloneRoomView, {
+                  activeRoomStore: loadingRemoteVideoRoomStore, 
                   dispatcher: dispatcher, 
-                  activeRoomStore: loadingRemoteVideoRoomStore, 
-                  localPosterUrl: "sample-img/video-screen-local.png", 
-                  isFirefox: true})
+                  isFirefox: true, 
+                  localPosterUrl: "sample-img/video-screen-local.png"})
               )
             ), 
 
-            React.createElement(FramedExample, {width: 644, height: 483, dashed: true, 
-                           cssClass: "standalone", 
+            React.createElement(FramedExample, {cssClass: "standalone", 
+                           dashed: true, 
+                           height: 483, 
                            onContentsRendered: updatingActiveRoomStore.forcedUpdate, 
-                           summary: "Standalone room conversation (has-participants, 644x483)"}, 
+                           summary: "Standalone room conversation (has-participants, 644x483)", 
+                           width: 644}, 
                 React.createElement("div", {className: "standalone"}, 
                   React.createElement(StandaloneRoomView, {
+                    activeRoomStore: updatingActiveRoomStore, 
                     dispatcher: dispatcher, 
-                    activeRoomStore: updatingActiveRoomStore, 
-                    roomState: ROOM_STATES.HAS_PARTICIPANTS, 
                     isFirefox: true, 
                     localPosterUrl: "sample-img/video-screen-local.png", 
-                    remotePosterUrl: "sample-img/video-screen-remote.png"})
+                    remotePosterUrl: "sample-img/video-screen-remote.png", 
+                    roomState: ROOM_STATES.HAS_PARTICIPANTS})
                 )
             ), 
 
-            React.createElement(FramedExample, {width: 644, height: 483, dashed: true, 
-                           cssClass: "standalone", 
-                           onContentsRendered: localFaceMuteRoomStore.forcedUpdate, 
-                           summary: "Standalone room conversation (local face mute, has-participants, 644x483)"}, 
+            React.createElement(FramedExample, {
+              cssClass: "standalone", 
+              dashed: true, 
+              height: 483, 
+              onContentsRendered: localFaceMuteRoomStore.forcedUpdate, 
+              summary: "Standalone room conversation (local face mute, has-participants, 644x483)", 
+              width: 644}, 
               React.createElement("div", {className: "standalone"}, 
                 React.createElement(StandaloneRoomView, {
+                  activeRoomStore: localFaceMuteRoomStore, 
                   dispatcher: dispatcher, 
-                  activeRoomStore: localFaceMuteRoomStore, 
                   isFirefox: true, 
                   localPosterUrl: "sample-img/video-screen-local.png", 
                   remotePosterUrl: "sample-img/video-screen-remote.png"})
               )
             ), 
 
-            React.createElement(FramedExample, {width: 644, height: 483, dashed: true, 
-                           cssClass: "standalone", 
-                           onContentsRendered: remoteFaceMuteRoomStore.forcedUpdate, 
-                           summary: "Standalone room conversation (remote face mute, has-participants, 644x483)"}, 
+            React.createElement(FramedExample, {
+              cssClass: "standalone", 
+              dashed: true, 
+              height: 483, 
+              onContentsRendered: remoteFaceMuteRoomStore.forcedUpdate, 
+              summary: "Standalone room conversation (remote face mute, has-participants, 644x483)", 
+              width: 644}, 
               React.createElement("div", {className: "standalone"}, 
                 React.createElement(StandaloneRoomView, {
+                  activeRoomStore: remoteFaceMuteRoomStore, 
                   dispatcher: dispatcher, 
-                  activeRoomStore: remoteFaceMuteRoomStore, 
                   isFirefox: true, 
                   localPosterUrl: "sample-img/video-screen-local.png", 
                   remotePosterUrl: "sample-img/video-screen-remote.png"})
               )
             ), 
 
-            React.createElement(FramedExample, {width: 800, height: 660, dashed: true, 
-                           cssClass: "standalone", 
-                           onContentsRendered: loadingRemoteLoadingScreenStore.forcedUpdate, 
-              summary: "Standalone room convo (has-participants, loading screen share, loading remote video, 800x660)"}, 
+            React.createElement(FramedExample, {
+              cssClass: "standalone", 
+              dashed: true, 
+              height: 660, 
+              onContentsRendered: loadingRemoteLoadingScreenStore.forcedUpdate, 
+              summary: "Standalone room convo (has-participants, loading screen share, loading remote video, 800x660)", 
+              width: 800}, 
               /* Hide scrollbars here. Rotating loading div overflows and causes
                scrollbars to appear */
                React.createElement("div", {className: "standalone overflow-hidden"}, 
                   React.createElement(StandaloneRoomView, {
+                    activeRoomStore: loadingRemoteLoadingScreenStore, 
                     dispatcher: dispatcher, 
-                    activeRoomStore: loadingRemoteLoadingScreenStore, 
-                    roomState: ROOM_STATES.HAS_PARTICIPANTS, 
                     isFirefox: true, 
                     localPosterUrl: "sample-img/video-screen-local.png", 
                     remotePosterUrl: "sample-img/video-screen-remote.png", 
-                    screenSharePosterUrl: "sample-img/video-screen-baz.png"}
-                  )
+                    roomState: ROOM_STATES.HAS_PARTICIPANTS, 
+                    screenSharePosterUrl: "sample-img/video-screen-baz.png"})
                 )
             ), 
 
-            React.createElement(FramedExample, {width: 800, height: 660, dashed: true, 
-                           cssClass: "standalone", 
-                           onContentsRendered: loadingScreenSharingRoomStore.forcedUpdate, 
-              summary: "Standalone room convo (has-participants, loading screen share, 800x660)"}, 
+            React.createElement(FramedExample, {
+              cssClass: "standalone", 
+              dashed: true, 
+              height: 660, 
+              onContentsRendered: loadingScreenSharingRoomStore.forcedUpdate, 
+              summary: "Standalone room convo (has-participants, loading screen share, 800x660)", 
+              width: 800}, 
               /* Hide scrollbars here. Rotating loading div overflows and causes
                scrollbars to appear */
                React.createElement("div", {className: "standalone overflow-hidden"}, 
                   React.createElement(StandaloneRoomView, {
+                    activeRoomStore: loadingScreenSharingRoomStore, 
                     dispatcher: dispatcher, 
-                    activeRoomStore: loadingScreenSharingRoomStore, 
-                    roomState: ROOM_STATES.HAS_PARTICIPANTS, 
                     isFirefox: true, 
                     localPosterUrl: "sample-img/video-screen-local.png", 
                     remotePosterUrl: "sample-img/video-screen-remote.png", 
-                    screenSharePosterUrl: "sample-img/video-screen-baz.png"}
-                  )
+                    roomState: ROOM_STATES.HAS_PARTICIPANTS, 
+                    screenSharePosterUrl: "sample-img/video-screen-baz.png"})
                 )
             ), 
 
-            React.createElement(FramedExample, {width: 800, height: 660, dashed: true, 
-                           cssClass: "standalone", 
-                           onContentsRendered: updatingSharingRoomStore.forcedUpdate, 
-              summary: "Standalone room convo (has-participants, receivingScreenShare, 800x660)"}, 
+            React.createElement(FramedExample, {
+              cssClass: "standalone", 
+              dashed: true, 
+              height: 660, 
+              onContentsRendered: updatingSharingRoomStore.forcedUpdate, 
+              summary: "Standalone room convo (has-participants, receivingScreenShare, 800x660)", 
+              width: 800}, 
                 React.createElement("div", {className: "standalone"}, 
                   React.createElement(StandaloneRoomView, {
+                    activeRoomStore: updatingSharingRoomStore, 
                     dispatcher: dispatcher, 
-                    activeRoomStore: updatingSharingRoomStore, 
-                    roomState: ROOM_STATES.HAS_PARTICIPANTS, 
                     isFirefox: true, 
                     localPosterUrl: "sample-img/video-screen-local.png", 
                     remotePosterUrl: "sample-img/video-screen-remote.png", 
-                    screenSharePosterUrl: "sample-img/video-screen-terminal.png"}
-                  )
+                    roomState: ROOM_STATES.HAS_PARTICIPANTS, 
+                    screenSharePosterUrl: "sample-img/video-screen-terminal.png"})
                 )
             ), 
 
-            React.createElement(FramedExample, {width: 644, height: 483, dashed: true, 
-                           cssClass: "standalone", 
-                           summary: "Standalone room conversation (full - FFx user)"}, 
+            React.createElement(FramedExample, {cssClass: "standalone", 
+                           dashed: true, 
+                           height: 483, 
+                           summary: "Standalone room conversation (full - FFx user)", 
+                           width: 644}, 
               React.createElement("div", {className: "standalone"}, 
                 React.createElement(StandaloneRoomView, {
+                  activeRoomStore: fullActiveRoomStore, 
                   dispatcher: dispatcher, 
-                  activeRoomStore: fullActiveRoomStore, 
                   isFirefox: true})
               )
             ), 
 
-            React.createElement(FramedExample, {width: 644, height: 483, dashed: true, 
-                           cssClass: "standalone", 
-                           summary: "Standalone room conversation (full - non FFx user)"}, 
+            React.createElement(FramedExample, {cssClass: "standalone", 
+                           dashed: true, 
+                           height: 483, 
+                           summary: "Standalone room conversation (full - non FFx user)", 
+                           width: 644}, 
               React.createElement("div", {className: "standalone"}, 
                 React.createElement(StandaloneRoomView, {
+                  activeRoomStore: fullActiveRoomStore, 
                   dispatcher: dispatcher, 
-                  activeRoomStore: fullActiveRoomStore, 
                   isFirefox: false})
               )
             ), 
 
-            React.createElement(FramedExample, {width: 644, height: 483, dashed: true, 
-                           cssClass: "standalone", 
-                           summary: "Standalone room conversation (feedback)"}, 
+            React.createElement(FramedExample, {cssClass: "standalone", 
+                           dashed: true, 
+                           height: 483, 
+                           summary: "Standalone room conversation (feedback)", 
+                           width: 644}, 
               React.createElement("div", {className: "standalone"}, 
                 React.createElement(StandaloneRoomView, {
+                  activeRoomStore: endedRoomStore, 
                   dispatcher: dispatcher, 
-                  activeRoomStore: endedRoomStore, 
                   feedbackStore: feedbackStore, 
                   isFirefox: false})
               )
             ), 
 
-            React.createElement(FramedExample, {width: 644, height: 483, dashed: true, 
-                           cssClass: "standalone", 
-                           summary: "Standalone room conversation (failed)"}, 
+            React.createElement(FramedExample, {cssClass: "standalone", 
+                           dashed: true, 
+                           height: 483, 
+                           summary: "Standalone room conversation (failed)", 
+                           width: 644}, 
               React.createElement("div", {className: "standalone"}, 
                 React.createElement(StandaloneRoomView, {
+                  activeRoomStore: failedRoomStore, 
                   dispatcher: dispatcher, 
-                  activeRoomStore: failedRoomStore, 
                   isFirefox: false})
               )
             )
           ), 
 
           React.createElement(Section, {name: "StandaloneRoomView (Mobile)"}, 
-            React.createElement(FramedExample, {width: 600, height: 480, cssClass: "standalone", 
-                           dashed: true, 
-                           onContentsRendered: updatingActiveRoomStore.forcedUpdate, 
-                           summary: "Standalone room conversation (has-participants, 600x480)"}, 
+            React.createElement(FramedExample, {
+              cssClass: "standalone", 
+              dashed: true, 
+              height: 480, 
+              onContentsRendered: updatingActiveRoomStore.forcedUpdate, 
+              summary: "Standalone room conversation (has-participants, 600x480)", 
+              width: 600}, 
                 React.createElement("div", {className: "standalone"}, 
                   React.createElement(StandaloneRoomView, {
+                    activeRoomStore: updatingActiveRoomStore, 
                     dispatcher: dispatcher, 
-                    activeRoomStore: updatingActiveRoomStore, 
-                    roomState: ROOM_STATES.HAS_PARTICIPANTS, 
                     isFirefox: true, 
                     localPosterUrl: "sample-img/video-screen-local.png", 
-                    remotePosterUrl: "sample-img/video-screen-remote.png"})
+                    remotePosterUrl: "sample-img/video-screen-remote.png", 
+                    roomState: ROOM_STATES.HAS_PARTICIPANTS})
                 )
             ), 
 
-            React.createElement(FramedExample, {width: 600, height: 480, 
-                           onContentsRendered: updatingSharingRoomStore.forcedUpdate, 
-              summary: "Standalone room convo (has-participants, receivingScreenShare, 600x480)"}, 
+            React.createElement(FramedExample, {
+              height: 480, 
+              onContentsRendered: updatingSharingRoomStore.forcedUpdate, 
+              summary: "Standalone room convo (has-participants, receivingScreenShare, 600x480)", 
+              width: 600}, 
                 React.createElement("div", {className: "standalone", cssClass: "standalone"}, 
                   React.createElement(StandaloneRoomView, {
+                    activeRoomStore: updatingSharingRoomStore, 
                     dispatcher: dispatcher, 
-                    activeRoomStore: updatingSharingRoomStore, 
-                    roomState: ROOM_STATES.HAS_PARTICIPANTS, 
                     isFirefox: true, 
                     localPosterUrl: "sample-img/video-screen-local.png", 
                     remotePosterUrl: "sample-img/video-screen-remote.png", 
+                    roomState: ROOM_STATES.HAS_PARTICIPANTS, 
                     screenSharePosterUrl: "sample-img/video-screen-terminal.png"})
                 )
             )
           ), 
 
           React.createElement(Section, {name: "TextChatView"}, 
-            React.createElement(FramedExample, {width: 298, height: 160, dashed: true, 
-                           summary: "TextChatView: desktop embedded"}, 
+            React.createElement(FramedExample, {dashed: true, 
+                           height: 160, 
+                           summary: "TextChatView: desktop embedded", 
+                           width: 298}, 
               React.createElement("div", {className: "fx-embedded"}, 
                 React.createElement(TextChatView, {dispatcher: dispatcher, 
                               showAlways: false, 
                               showRoomName: false})
               )
             ), 
 
-            React.createElement(FramedExample, {width: 200, height: 400, dashed: true, 
-                           cssClass: "standalone", 
-                           summary: "Standalone Text Chat conversation (200x400)"}, 
+            React.createElement(FramedExample, {cssClass: "standalone", 
+                           dashed: true, 
+                           height: 400, 
+                           summary: "Standalone Text Chat conversation (200x400)", 
+                           width: 200}, 
               React.createElement("div", {className: "standalone text-chat-example"}, 
                 React.createElement("div", {className: "media-wrapper"}, 
                   React.createElement(TextChatView, {
                     dispatcher: dispatcher, 
                     showAlways: true, 
                     showRoomName: true})
                 )
               )
             )
           ), 
 
-          React.createElement(Section, {name: "SVG icons preview", className: "svg-icons"}, 
+          React.createElement(Section, {className: "svg-icons", name: "SVG icons preview"}, 
             React.createElement(Example, {summary: "10x10"}, 
               React.createElement(SVGIcons, {size: "10x10"})
             ), 
             React.createElement(Example, {summary: "14x14"}, 
               React.createElement(SVGIcons, {size: "14x14"})
             ), 
             React.createElement(Example, {summary: "16x16"}, 
               React.createElement(SVGIcons, {size: "16x16"})
--- a/browser/components/loop/ui/ui-showcase.jsx
+++ b/browser/components/loop/ui/ui-showcase.jsx
@@ -380,19 +380,19 @@
     detailsButtonLabel: "Retry"
   });
 
   var SVGIcon = React.createClass({
     render: function() {
       var sizeUnit = this.props.size.split("x");
       return (
         <img className="svg-icon"
+             height={sizeUnit[1]}
              src={"../content/shared/img/icons-" + this.props.size + ".svg#" + this.props.shapeId}
-             width={sizeUnit[0]}
-             height={sizeUnit[1]} />
+             width={sizeUnit[0]} />
       );
     }
   });
 
   var SVGIcons = React.createClass({
     shapes: {
       "10x10": ["close", "close-active", "close-disabled", "dropdown",
         "dropdown-white", "dropdown-active", "dropdown-disabled", "edit",
@@ -416,35 +416,35 @@
         "tag-hover", "tag-active", "trash", "unblock", "unblock-hover", "unblock-active",
         "video", "video-hover", "video-active", "tour"
       ]
     },
 
     render: function() {
       var icons = this.shapes[this.props.size].map(function(shapeId, i) {
         return (
-          <li key={this.props.size + "-" + i} className="svg-icon-entry">
+          <li className="svg-icon-entry" key={this.props.size + "-" + i}>
             <p><SVGIcon shapeId={shapeId} size={this.props.size} /></p>
             <p>{shapeId}</p>
           </li>
         );
       }, this);
       return (
         <ul className="svg-icon-list">{icons}</ul>
       );
     }
   });
 
   var FramedExample = React.createClass({
     propTypes: {
-      width: React.PropTypes.number,
+      cssClass: React.PropTypes.string,
+      dashed: React.PropTypes.bool,
       height: React.PropTypes.number,
       onContentsRendered: React.PropTypes.func,
-      dashed: React.PropTypes.bool,
-      cssClass: React.PropTypes.string
+      width: React.PropTypes.number
     },
 
     makeId: function(prefix) {
       return (prefix || "") + this.props.summary.toLowerCase().replace(/\s/g, "-");
     },
 
     render: function() {
       var height = this.props.height;
@@ -459,20 +459,21 @@
       var cx = React.addons.classSet;
       return (
         <div className="example">
           <h3 id={this.makeId()}>
             {this.props.summary}
             <a href={this.makeId("#")}>&nbsp;¶</a>
           </h3>
           <div className="comp">
-            <Frame width={width} height={height}
+            <Frame className={cx({dashed: this.props.dashed})}
+                   cssClass={this.props.cssClass}
+                   height={height}
                    onContentsRendered={this.props.onContentsRendered}
-                   className={cx({dashed: this.props.dashed})}
-                   cssClass={this.props.cssClass}>
+                   width={width}>
               {this.props.children}
             </Frame>
           </div>
         </div>
       );
     }
   });
 
@@ -496,17 +497,17 @@
         </div>
       );
     }
   });
 
   var Section = React.createClass({
     render: function() {
       return (
-        <section id={this.props.name} className={this.props.className}>
+        <section className={this.props.className} id={this.props.name}>
           <h1>{this.props.name}</h1>
           {this.props.children}
         </section>
       );
     }
   });
 
   var ShowCase = React.createClass({
@@ -539,17 +540,17 @@
         document.documentElement.setAttribute("lang", "ar");
         document.documentElement.setAttribute("dir", "rtl");
       }
 
       return (
         <div className="showcase">
           <header>
             <h1>Loop UI Components Showcase</h1>
-            <Checkbox label="RTL mode?" checked={this.state.rtlMode}
+            <Checkbox checked={this.state.rtlMode} label="RTL mode?"
               onChange={this._handleCheckboxChange} />
             <nav className="showcase-menu">{
               React.Children.map(this.props.children, function(section) {
                 return (
                   <a className="btn btn-info" href={"#" + section.props.name}>
                     {section.props.name}
                   </a>
                 );
@@ -566,252 +567,273 @@
 
     render: function() {
       return (
         <ShowCase>
           <Section name="PanelView">
             <p className="note">
               <strong>Note:</strong> 332px wide.
             </p>
-            <Example summary="Re-sign-in view" dashed="true" style={{width: "332px"}}>
+            <Example dashed="true" style={{width: "332px"}} summary="Re-sign-in view">
               <SignInRequestView mozLoop={mockMozLoopRooms} />
             </Example>
-            <Example summary="Room list tab" dashed="true" style={{width: "332px"}}>
-              <PanelView client={mockClient} notifications={notifications}
-                         userProfile={{email: "test@example.com"}}
+            <Example dashed="true" style={{width: "332px"}} summary="Room list tab">
+              <PanelView client={mockClient}
+                         dispatcher={dispatcher}
                          mozLoop={mockMozLoopRooms}
-                         dispatcher={dispatcher}
+                         notifications={notifications}
                          roomStore={roomStore}
-                         selectedTab="rooms" />
+                         selectedTab="rooms"
+                         userProfile={{email: "test@example.com"}} />
             </Example>
-            <Example summary="Contact list tab" dashed="true" style={{width: "332px"}}>
-              <PanelView client={mockClient} notifications={notifications}
-                         userProfile={{email: "test@example.com"}}
+            <Example dashed="true" style={{width: "332px"}} summary="Contact list tab">
+              <PanelView client={mockClient}
+                         dispatcher={dispatcher}
                          mozLoop={mockMozLoopRooms}
-                         dispatcher={dispatcher}
+                         notifications={notifications}
                          roomStore={roomStore}
-                         selectedTab="contacts" />
+                         selectedTab="contacts"
+                         userProfile={{email: "test@example.com"}} />
             </Example>
-            <Example summary="Error Notification" dashed="true" style={{width: "332px"}}>
-              <PanelView client={mockClient} notifications={errNotifications}
+            <Example dashed="true" style={{width: "332px"}} summary="Error Notification">
+              <PanelView client={mockClient}
+                         dispatcher={dispatcher}
                          mozLoop={navigator.mozLoop}
-                         dispatcher={dispatcher}
+                         notifications={errNotifications}
                          roomStore={roomStore} />
             </Example>
-            <Example summary="Error Notification - authenticated" dashed="true" style={{width: "332px"}}>
-              <PanelView client={mockClient} notifications={errNotifications}
-                         userProfile={{email: "test@example.com"}}
-                         mozLoop={navigator.mozLoop}
+            <Example dashed="true" style={{width: "332px"}} summary="Error Notification - authenticated">
+              <PanelView client={mockClient}
                          dispatcher={dispatcher}
-                         roomStore={roomStore} />
+                         mozLoop={navigator.mozLoop}
+                         notifications={errNotifications}
+                         roomStore={roomStore}
+                         userProfile={{email: "test@example.com"}} />
             </Example>
-            <Example summary="Contact import success" dashed="true" style={{width: "332px"}}>
-              <PanelView notifications={new loop.shared.models.NotificationCollection([{level: "success", message: "Import success"}])}
-                         userProfile={{email: "test@example.com"}}
+            <Example dashed="true" style={{width: "332px"}} summary="Contact import success">
+              <PanelView dispatcher={dispatcher}
                          mozLoop={mockMozLoopRooms}
-                         dispatcher={dispatcher}
+                         notifications={new loop.shared.models.NotificationCollection([{level: "success", message: "Import success"}])}
                          roomStore={roomStore}
-                         selectedTab="contacts" />
+                         selectedTab="contacts"
+                         userProfile={{email: "test@example.com"}} />
             </Example>
-            <Example summary="Contact import error" dashed="true" style={{width: "332px"}}>
-              <PanelView notifications={new loop.shared.models.NotificationCollection([{level: "error", message: "Import error"}])}
-                         userProfile={{email: "test@example.com"}}
+            <Example dashed="true" style={{width: "332px"}} summary="Contact import error">
+              <PanelView dispatcher={dispatcher}
                          mozLoop={mockMozLoopRooms}
-                         dispatcher={dispatcher}
+                         notifications={new loop.shared.models.NotificationCollection([{level: "error", message: "Import error"}])}
                          roomStore={roomStore}
-                         selectedTab="contacts" />
+                         selectedTab="contacts"
+                         userProfile={{email: "test@example.com"}} />
             </Example>
           </Section>
 
           <Section name="AcceptCallView">
-            <Example summary="Default / incoming video call" dashed="true" style={{width: "300px", height: "272px"}}>
+            <Example dashed="true" style={{width: "300px", height: "272px"}}
+                     summary="Default / incoming video call">
               <div className="fx-embedded">
                 <AcceptCallView callType={CALL_TYPES.AUDIO_VIDEO}
                                 callerId="Mr Smith"
                                 dispatcher={dispatcher}
                                 mozLoop={mockMozLoopRooms} />
               </div>
             </Example>
 
-            <Example summary="Default / incoming audio only call" dashed="true" style={{width: "300px", height: "272px"}}>
+            <Example dashed="true" style={{width: "300px", height: "272px"}}
+                     summary="Default / incoming audio only call">
               <div className="fx-embedded">
                 <AcceptCallView callType={CALL_TYPES.AUDIO_ONLY}
                                 callerId="Mr Smith"
                                 dispatcher={dispatcher}
                                 mozLoop={mockMozLoopRooms} />
               </div>
             </Example>
           </Section>
 
           <Section name="AcceptCallView-ActiveState">
-            <Example summary="Default" dashed="true" style={{width: "300px", height: "272px"}}>
+            <Example dashed="true" style={{width: "300px", height: "272px"}}
+                     summary="Default">
               <div className="fx-embedded" >
                 <AcceptCallView callType={CALL_TYPES.AUDIO_VIDEO}
                                 callerId="Mr Smith"
                                 dispatcher={dispatcher}
                                 mozLoop={mockMozLoopRooms}
                                 showMenu={true} />
               </div>
             </Example>
           </Section>
 
           <Section name="ConversationToolbar">
             <h2>Desktop Conversation Window</h2>
             <div className="fx-embedded override-position">
-              <Example summary="Default" style={{width: "300px", height: "26px"}}>
-                <ConversationToolbar video={{enabled: true}}
-                                     audio={{enabled: true}}
+              <Example style={{width: "300px", height: "26px"}} summary="Default">
+                <ConversationToolbar audio={{enabled: true}}
                                      hangup={noop}
-                                     publishStream={noop} />
+                                     publishStream={noop}
+                                     video={{enabled: true}} />
               </Example>
-              <Example summary="Video muted" style={{width: "300px", height: "26px"}}>
-                <ConversationToolbar video={{enabled: false}}
-                                     audio={{enabled: true}}
+              <Example style={{width: "300px", height: "26px"}} summary="Video muted">
+                <ConversationToolbar audio={{enabled: true}}
                                      hangup={noop}
-                                     publishStream={noop} />
+                                     publishStream={noop}
+                                     video={{enabled: false}} />
               </Example>
-              <Example summary="Audio muted" style={{width: "300px", height: "26px"}}>
-                <ConversationToolbar video={{enabled: true}}
-                                     audio={{enabled: false}}
+              <Example style={{width: "300px", height: "26px"}} summary="Audio muted">
+                <ConversationToolbar audio={{enabled: false}}
                                      hangup={noop}
-                                     publishStream={noop} />
+                                     publishStream={noop}
+                                     video={{enabled: true}} />
               </Example>
             </div>
 
             <h2>Standalone</h2>
             <div className="standalone override-position">
               <Example summary="Default">
-                <ConversationToolbar video={{enabled: true}}
-                                     audio={{enabled: true}}
+                <ConversationToolbar audio={{enabled: true}}
                                      hangup={noop}
-                                     publishStream={noop} />
+                                     publishStream={noop}
+                                     video={{enabled: true}} />
               </Example>
               <Example summary="Video muted">
-                <ConversationToolbar video={{enabled: false}}
-                                     audio={{enabled: true}}
+                <ConversationToolbar audio={{enabled: true}}
                                      hangup={noop}
-                                     publishStream={noop} />
+                                     publishStream={noop}
+                                     video={{enabled: false}} />
               </Example>
               <Example summary="Audio muted">
-                <ConversationToolbar video={{enabled: true}}
-                                     audio={{enabled: false}}
+                <ConversationToolbar audio={{enabled: false}}
                                      hangup={noop}
-                                     publishStream={noop} />
+                                     publishStream={noop}
+                                     video={{enabled: true}} />
               </Example>
             </div>
           </Section>
 
           <Section name="PendingConversationView (Desktop)">
-            <Example summary="Connecting" dashed="true"
-                     style={{width: "300px", height: "272px"}}>
+            <Example dashed="true"
+                     style={{width: "300px", height: "272px"}}
+                     summary="Connecting">
               <div className="fx-embedded">
                 <DesktopPendingConversationView callState={"gather"}
                                                 contact={mockContact}
                                                 dispatcher={dispatcher} />
               </div>
             </Example>
           </Section>
 
           <Section name="CallFailedView">
-            <Example summary="Call Failed - Incoming" dashed="true"
-                     style={{width: "300px", height: "272px"}}>
+            <Example dashed="true"
+                     style={{width: "300px", height: "272px"}}
+                     summary="Call Failed - Incoming">
               <div className="fx-embedded">
                 <CallFailedView dispatcher={dispatcher}
                                 outgoing={false}
                                 store={conversationStore} />
               </div>
             </Example>
-            <Example summary="Call Failed - Outgoing" dashed="true"
-                     style={{width: "300px", height: "272px"}}>
+            <Example dashed="true"
+                     style={{width: "300px", height: "272px"}}
+                     summary="Call Failed - Outgoing">
               <div className="fx-embedded">
                 <CallFailedView dispatcher={dispatcher}
                                 outgoing={true}
                                 store={conversationStore} />
               </div>
             </Example>
-            <Example summary="Call Failed — with call URL error" dashed="true"
-                     style={{width: "300px", height: "272px"}}>
+            <Example dashed="true"
+                     style={{width: "300px", height: "272px"}}
+                     summary="Call Failed — with call URL error">
               <div className="fx-embedded">
                 <CallFailedView dispatcher={dispatcher} emailLinkError={true}
                                 outgoing={true}
                                 store={conversationStore} />
               </div>
             </Example>
           </Section>
 
           <Section name="OngoingConversationView">
-            <FramedExample width={298} height={254}
-                           summary="Desktop ongoing conversation window">
+            <FramedExample height={254}
+                           summary="Desktop ongoing conversation window"
+                           width={298}>
               <div className="fx-embedded">
                 <OngoingConversationView
+                  audio={{enabled: true}}
                   dispatcher={dispatcher}
-                  video={{enabled: true}}
-                  audio={{enabled: true}}
                   localPosterUrl="sample-img/video-screen-local.png"
+                  mediaConnected={true}
                   remotePosterUrl="sample-img/video-screen-remote.png"
                   remoteVideoEnabled={true}
-                  mediaConnected={true} />
+                  video={{enabled: true}} />
               </div>
             </FramedExample>
 
-            <FramedExample width={800} height={600}
-                           summary="Desktop ongoing conversation window large">
+            <FramedExample height={600}
+                           summary="Desktop ongoing conversation window large"
+                           width={800}>
                 <div className="fx-embedded">
                   <OngoingConversationView
+                    audio={{enabled: true}}
                     dispatcher={dispatcher}
-                    video={{enabled: true}}
-                    audio={{enabled: true}}
                     localPosterUrl="sample-img/video-screen-local.png"
+                    mediaConnected={true}
                     remotePosterUrl="sample-img/video-screen-remote.png"
                     remoteVideoEnabled={true}
-                    mediaConnected={true} />
+                    video={{enabled: true}} />
                 </div>
             </FramedExample>
 
-            <FramedExample width={298} height={254}
-              summary="Desktop ongoing conversation window - local face mute">
+            <FramedExample height={254}
+              summary="Desktop ongoing conversation window - local face mute"
+              width={298} >
               <div className="fx-embedded">
                 <OngoingConversationView
+                  audio={{enabled: true}}
                   dispatcher={dispatcher}
-                  video={{enabled: false}}
-                  audio={{enabled: true}}
+                  mediaConnected={true}
+                  remotePosterUrl="sample-img/video-screen-remote.png"
                   remoteVideoEnabled={true}
-                  remotePosterUrl="sample-img/video-screen-remote.png"
-                  mediaConnected={true} />
+                  video={{enabled: false}} />
               </div>
             </FramedExample>
 
-            <FramedExample width={298} height={254}
-              summary="Desktop ongoing conversation window - remote face mute">
+            <FramedExample height={254}
+              summary="Desktop ongoing conversation window - remote face mute"
+              width={298} >
               <div className="fx-embedded">
                 <OngoingConversationView
+                  audio={{enabled: true}}
                   dispatcher={dispatcher}
-                  video={{enabled: true}}
-                  audio={{enabled: true}}
+                  localPosterUrl="sample-img/video-screen-local.png"
+                  mediaConnected={true}
                   remoteVideoEnabled={false}
-                  localPosterUrl="sample-img/video-screen-local.png"
-                  mediaConnected={true} />
+                  video={{enabled: true}} />
               </div>
             </FramedExample>
 
           </Section>
 
           <Section name="FeedbackView">
             <p className="note">
               <strong>Note:</strong> For the useable demo, you can access submitted data at&nbsp;
               <a href="https://input.allizom.org/">input.allizom.org</a>.
             </p>
-            <Example summary="Default (useable demo)" dashed="true" style={{width: "300px", height: "272px"}}>
+            <Example dashed="true"
+                     style={{width: "300px", height: "272px"}}
+                     summary="Default (useable demo)">
               <FeedbackView feedbackStore={feedbackStore} />
             </Example>
-            <Example summary="Detailed form" dashed="true" style={{width: "300px", height: "272px"}}>
-              <FeedbackView feedbackStore={feedbackStore} feedbackState={FEEDBACK_STATES.DETAILS} />
+            <Example dashed="true"
+                     style={{width: "300px", height: "272px"}}
+                     summary="Detailed form">
+              <FeedbackView feedbackState={FEEDBACK_STATES.DETAILS} feedbackStore={feedbackStore} />
             </Example>
-            <Example summary="Thank you!" dashed="true" style={{width: "300px", height: "272px"}}>
-              <FeedbackView feedbackStore={feedbackStore} feedbackState={FEEDBACK_STATES.SENT} />
+            <Example dashed="true"
+                     style={{width: "300px", height: "272px"}}
+                     summary="Thank you!">
+              <FeedbackView feedbackState={FEEDBACK_STATES.SENT} feedbackStore={feedbackStore}/>
             </Example>
           </Section>
 
           <Section name="AlertMessages">
             <Example summary="Various alerts">
               <div className="alert alert-warning">
                 <button className="close"></button>
                 <p className="message">
@@ -840,319 +862,364 @@
             <Example summary="Standalone Unsupported Device">
               <div className="standalone">
                 <UnsupportedDeviceView platform="ios"/>
               </div>
             </Example>
           </Section>
 
           <Section name="DesktopRoomConversationView">
-            <FramedExample width={298} height={254}
-              summary="Desktop room conversation (invitation, text-chat inclusion/scrollbars don't happen in real client)">
+            <FramedExample
+              height={254}
+              summary="Desktop room conversation (invitation, text-chat inclusion/scrollbars don't happen in real client)"
+              width={298}>
               <div className="fx-embedded">
                 <DesktopRoomConversationView
-                  roomStore={invitationRoomStore}
                   dispatcher={dispatcher}
+                  localPosterUrl="sample-img/video-screen-local.png"
                   mozLoop={navigator.mozLoop}
-                  localPosterUrl="sample-img/video-screen-local.png"
-                  roomState={ROOM_STATES.INIT} />
+                  roomState={ROOM_STATES.INIT}
+                  roomStore={invitationRoomStore} />
               </div>
             </FramedExample>
 
-            <FramedExample width={298} height={394} dashed={true}
-              summary="Desktop room conversation (loading)">
+            <FramedExample
+              dashed={true}
+              height={394}
+              summary="Desktop room conversation (loading)"
+              width={298}>
               {/* Hide scrollbars here. Rotating loading div overflows and causes
                scrollbars to appear */}
               <div className="fx-embedded overflow-hidden">
                 <DesktopRoomConversationView
-                  roomStore={desktopRoomStoreLoading}
                   dispatcher={dispatcher}
+                  localPosterUrl="sample-img/video-screen-local.png"
                   mozLoop={navigator.mozLoop}
-                  localPosterUrl="sample-img/video-screen-local.png"
                   remotePosterUrl="sample-img/video-screen-remote.png"
-                  roomState={ROOM_STATES.HAS_PARTICIPANTS} />
+                  roomState={ROOM_STATES.HAS_PARTICIPANTS}
+                  roomStore={desktopRoomStoreLoading} />
+              </div>
+            </FramedExample>
+
+            <FramedExample height={254}
+                           summary="Desktop room conversation">
+              <div className="fx-embedded">
+                <DesktopRoomConversationView
+                  dispatcher={dispatcher}
+                  localPosterUrl="sample-img/video-screen-local.png"
+                  mozLoop={navigator.mozLoop}
+                  remotePosterUrl="sample-img/video-screen-remote.png"
+                  roomState={ROOM_STATES.HAS_PARTICIPANTS}
+                  roomStore={roomStore} />
               </div>
             </FramedExample>
 
-            <FramedExample width={298} height={254}
-              summary="Desktop room conversation">
+            <FramedExample dashed={true}
+                           height={394}
+                           summary="Desktop room conversation local face-mute"
+                           width={298}>
               <div className="fx-embedded">
                 <DesktopRoomConversationView
-                  roomStore={roomStore}
                   dispatcher={dispatcher}
                   mozLoop={navigator.mozLoop}
-                  localPosterUrl="sample-img/video-screen-local.png"
                   remotePosterUrl="sample-img/video-screen-remote.png"
-                  roomState={ROOM_STATES.HAS_PARTICIPANTS} />
+                  roomStore={desktopLocalFaceMuteRoomStore} />
               </div>
             </FramedExample>
 
-            <FramedExample width={298} height={394} dashed={true}
-                           summary="Desktop room conversation local face-mute">
+            <FramedExample dashed={true} height={394}
+                           summary="Desktop room conversation remote face-mute"
+                           width={298} >
               <div className="fx-embedded">
                 <DesktopRoomConversationView
-                  roomStore={desktopLocalFaceMuteRoomStore}
                   dispatcher={dispatcher}
+                  localPosterUrl="sample-img/video-screen-local.png"
                   mozLoop={navigator.mozLoop}
-                  remotePosterUrl="sample-img/video-screen-remote.png" />
-              </div>
-            </FramedExample>
-
-            <FramedExample width={298} height={394} dashed={true}
-                           summary="Desktop room conversation remote face-mute">
-              <div className="fx-embedded">
-                <DesktopRoomConversationView
-                  roomStore={desktopRemoteFaceMuteRoomStore}
-                  dispatcher={dispatcher}
-                  mozLoop={navigator.mozLoop}
-                  localPosterUrl="sample-img/video-screen-local.png" />
+                  roomStore={desktopRemoteFaceMuteRoomStore} />
               </div>
             </FramedExample>
           </Section>
 
           <Section name="StandaloneRoomView">
-            <FramedExample width={644} height={483} dashed={true}
-                           cssClass="standalone"
-                           summary="Standalone room conversation (ready)">
+            <FramedExample cssClass="standalone"
+                           dashed={true}
+                           height={483}
+                           summary="Standalone room conversation (ready)"
+                           width={644} >
               <div className="standalone">
                 <StandaloneRoomView
+                  activeRoomStore={readyRoomStore}
                   dispatcher={dispatcher}
-                  activeRoomStore={readyRoomStore}
-                  roomState={ROOM_STATES.READY}
-                  isFirefox={true} />
+                  isFirefox={true}
+                  roomState={ROOM_STATES.READY} />
               </div>
             </FramedExample>
 
-            <FramedExample width={644} height={483} dashed={true}
-              summary="Standalone room conversation (joined)"
-              cssClass="standalone"
-              onContentsRendered={joinedRoomStore.forcedUpdate}>
+            <FramedExample cssClass="standalone"
+                           dashed={true}
+                           height={483}
+                           onContentsRendered={joinedRoomStore.forcedUpdate}
+                           summary="Standalone room conversation (joined)"
+                           width={644}>
               <div className="standalone">
                 <StandaloneRoomView
+                  activeRoomStore={joinedRoomStore}
                   dispatcher={dispatcher}
-                  activeRoomStore={joinedRoomStore}
-                  localPosterUrl="sample-img/video-screen-local.png"
-                  isFirefox={true} />
+                  isFirefox={true}
+                  localPosterUrl="sample-img/video-screen-local.png" />
               </div>
             </FramedExample>
 
-            <FramedExample width={644} height={483} dashed={true}
-              summary="Standalone room conversation (loading remote)"
-              cssClass="standalone"
-              onContentsRendered={loadingRemoteVideoRoomStore.forcedUpdate}>
+            <FramedExample cssClass="standalone"
+                           dashed={true}
+                           height={483}
+                           onContentsRendered={loadingRemoteVideoRoomStore.forcedUpdate}
+                           summary="Standalone room conversation (loading remote)"
+                           width={644}>
               <div className="standalone">
                 <StandaloneRoomView
+                  activeRoomStore={loadingRemoteVideoRoomStore}
                   dispatcher={dispatcher}
-                  activeRoomStore={loadingRemoteVideoRoomStore}
-                  localPosterUrl="sample-img/video-screen-local.png"
-                  isFirefox={true} />
+                  isFirefox={true}
+                  localPosterUrl="sample-img/video-screen-local.png" />
               </div>
             </FramedExample>
 
-            <FramedExample width={644} height={483} dashed={true}
-                           cssClass="standalone"
+            <FramedExample cssClass="standalone"
+                           dashed={true}
+                           height={483}
                            onContentsRendered={updatingActiveRoomStore.forcedUpdate}
-                           summary="Standalone room conversation (has-participants, 644x483)">
+                           summary="Standalone room conversation (has-participants, 644x483)"
+                           width={644} >
                 <div className="standalone">
                   <StandaloneRoomView
+                    activeRoomStore={updatingActiveRoomStore}
                     dispatcher={dispatcher}
-                    activeRoomStore={updatingActiveRoomStore}
-                    roomState={ROOM_STATES.HAS_PARTICIPANTS}
                     isFirefox={true}
                     localPosterUrl="sample-img/video-screen-local.png"
-                    remotePosterUrl="sample-img/video-screen-remote.png" />
+                    remotePosterUrl="sample-img/video-screen-remote.png"
+                    roomState={ROOM_STATES.HAS_PARTICIPANTS} />
                 </div>
             </FramedExample>
 
-            <FramedExample width={644} height={483} dashed={true}
-                           cssClass="standalone"
-                           onContentsRendered={localFaceMuteRoomStore.forcedUpdate}
-                           summary="Standalone room conversation (local face mute, has-participants, 644x483)">
+            <FramedExample
+              cssClass="standalone"
+              dashed={true}
+              height={483}
+              onContentsRendered={localFaceMuteRoomStore.forcedUpdate}
+              summary="Standalone room conversation (local face mute, has-participants, 644x483)"
+              width={644}>
               <div className="standalone">
                 <StandaloneRoomView
+                  activeRoomStore={localFaceMuteRoomStore}
                   dispatcher={dispatcher}
-                  activeRoomStore={localFaceMuteRoomStore}
                   isFirefox={true}
                   localPosterUrl="sample-img/video-screen-local.png"
                   remotePosterUrl="sample-img/video-screen-remote.png" />
               </div>
             </FramedExample>
 
-            <FramedExample width={644} height={483} dashed={true}
-                           cssClass="standalone"
-                           onContentsRendered={remoteFaceMuteRoomStore.forcedUpdate}
-                           summary="Standalone room conversation (remote face mute, has-participants, 644x483)">
+            <FramedExample
+              cssClass="standalone"
+              dashed={true}
+              height={483}
+              onContentsRendered={remoteFaceMuteRoomStore.forcedUpdate}
+              summary="Standalone room conversation (remote face mute, has-participants, 644x483)"
+              width={644}>
               <div className="standalone">
                 <StandaloneRoomView
+                  activeRoomStore={remoteFaceMuteRoomStore}
                   dispatcher={dispatcher}
-                  activeRoomStore={remoteFaceMuteRoomStore}
                   isFirefox={true}
                   localPosterUrl="sample-img/video-screen-local.png"
                   remotePosterUrl="sample-img/video-screen-remote.png" />
               </div>
             </FramedExample>
 
-            <FramedExample width={800} height={660} dashed={true}
-                           cssClass="standalone"
-                           onContentsRendered={loadingRemoteLoadingScreenStore.forcedUpdate}
-              summary="Standalone room convo (has-participants, loading screen share, loading remote video, 800x660)">
+            <FramedExample
+              cssClass="standalone"
+              dashed={true}
+              height={660}
+              onContentsRendered={loadingRemoteLoadingScreenStore.forcedUpdate}
+              summary="Standalone room convo (has-participants, loading screen share, loading remote video, 800x660)"
+              width={800}>
               {/* Hide scrollbars here. Rotating loading div overflows and causes
                scrollbars to appear */}
                <div className="standalone overflow-hidden">
                   <StandaloneRoomView
+                    activeRoomStore={loadingRemoteLoadingScreenStore}
                     dispatcher={dispatcher}
-                    activeRoomStore={loadingRemoteLoadingScreenStore}
-                    roomState={ROOM_STATES.HAS_PARTICIPANTS}
                     isFirefox={true}
                     localPosterUrl="sample-img/video-screen-local.png"
                     remotePosterUrl="sample-img/video-screen-remote.png"
-                    screenSharePosterUrl="sample-img/video-screen-baz.png"
-                  />
+                    roomState={ROOM_STATES.HAS_PARTICIPANTS}
+                    screenSharePosterUrl="sample-img/video-screen-baz.png" />
                 </div>
             </FramedExample>
 
-            <FramedExample width={800} height={660} dashed={true}
-                           cssClass="standalone"
-                           onContentsRendered={loadingScreenSharingRoomStore.forcedUpdate}
-              summary="Standalone room convo (has-participants, loading screen share, 800x660)">
+            <FramedExample
+              cssClass="standalone"
+              dashed={true}
+              height={660}
+              onContentsRendered={loadingScreenSharingRoomStore.forcedUpdate}
+              summary="Standalone room convo (has-participants, loading screen share, 800x660)"
+              width={800}>
               {/* Hide scrollbars here. Rotating loading div overflows and causes
                scrollbars to appear */}
                <div className="standalone overflow-hidden">
                   <StandaloneRoomView
+                    activeRoomStore={loadingScreenSharingRoomStore}
                     dispatcher={dispatcher}
-                    activeRoomStore={loadingScreenSharingRoomStore}
-                    roomState={ROOM_STATES.HAS_PARTICIPANTS}
                     isFirefox={true}
                     localPosterUrl="sample-img/video-screen-local.png"
                     remotePosterUrl="sample-img/video-screen-remote.png"
-                    screenSharePosterUrl="sample-img/video-screen-baz.png"
-                  />
+                    roomState={ROOM_STATES.HAS_PARTICIPANTS}
+                    screenSharePosterUrl="sample-img/video-screen-baz.png" />
                 </div>
             </FramedExample>
 
-            <FramedExample width={800} height={660} dashed={true}
-                           cssClass="standalone"
-                           onContentsRendered={updatingSharingRoomStore.forcedUpdate}
-              summary="Standalone room convo (has-participants, receivingScreenShare, 800x660)">
+            <FramedExample
+              cssClass="standalone"
+              dashed={true}
+              height={660}
+              onContentsRendered={updatingSharingRoomStore.forcedUpdate}
+              summary="Standalone room convo (has-participants, receivingScreenShare, 800x660)"
+              width={800}>
                 <div className="standalone">
                   <StandaloneRoomView
+                    activeRoomStore={updatingSharingRoomStore}
                     dispatcher={dispatcher}
-                    activeRoomStore={updatingSharingRoomStore}
-                    roomState={ROOM_STATES.HAS_PARTICIPANTS}
                     isFirefox={true}
                     localPosterUrl="sample-img/video-screen-local.png"
                     remotePosterUrl="sample-img/video-screen-remote.png"
-                    screenSharePosterUrl="sample-img/video-screen-terminal.png"
-                  />
+                    roomState={ROOM_STATES.HAS_PARTICIPANTS}
+                    screenSharePosterUrl="sample-img/video-screen-terminal.png" />
                 </div>
             </FramedExample>
 
-            <FramedExample width={644} height={483} dashed={true}
-                           cssClass="standalone"
-                           summary="Standalone room conversation (full - FFx user)">
+            <FramedExample cssClass="standalone"
+                           dashed={true}
+                           height={483}
+                           summary="Standalone room conversation (full - FFx user)"
+                           width={644} >
               <div className="standalone">
                 <StandaloneRoomView
+                  activeRoomStore={fullActiveRoomStore}
                   dispatcher={dispatcher}
-                  activeRoomStore={fullActiveRoomStore}
                   isFirefox={true} />
               </div>
             </FramedExample>
 
-            <FramedExample width={644} height={483} dashed={true}
-                           cssClass="standalone"
-                           summary="Standalone room conversation (full - non FFx user)">
+            <FramedExample cssClass="standalone"
+                           dashed={true}
+                           height={483}
+                           summary="Standalone room conversation (full - non FFx user)"
+                           width={644} >
               <div className="standalone">
                 <StandaloneRoomView
+                  activeRoomStore={fullActiveRoomStore}
                   dispatcher={dispatcher}
-                  activeRoomStore={fullActiveRoomStore}
                   isFirefox={false} />
               </div>
             </FramedExample>
 
-            <FramedExample width={644} height={483} dashed={true}
-                           cssClass="standalone"
-                           summary="Standalone room conversation (feedback)">
+            <FramedExample cssClass="standalone"
+                           dashed={true}
+                           height={483}
+                           summary="Standalone room conversation (feedback)"
+                           width={644}>
               <div className="standalone">
                 <StandaloneRoomView
+                  activeRoomStore={endedRoomStore}
                   dispatcher={dispatcher}
-                  activeRoomStore={endedRoomStore}
                   feedbackStore={feedbackStore}
                   isFirefox={false} />
               </div>
             </FramedExample>
 
-            <FramedExample width={644} height={483} dashed={true}
-                           cssClass="standalone"
-                           summary="Standalone room conversation (failed)">
+            <FramedExample cssClass="standalone"
+                           dashed={true}
+                           height={483}
+                           summary="Standalone room conversation (failed)"
+                           width={644} >
               <div className="standalone">
                 <StandaloneRoomView
+                  activeRoomStore={failedRoomStore}
                   dispatcher={dispatcher}
-                  activeRoomStore={failedRoomStore}
                   isFirefox={false} />
               </div>
             </FramedExample>
           </Section>
 
           <Section name="StandaloneRoomView (Mobile)">
-            <FramedExample width={600} height={480} cssClass="standalone"
-                           dashed={true}
-                           onContentsRendered={updatingActiveRoomStore.forcedUpdate}
-                           summary="Standalone room conversation (has-participants, 600x480)">
+            <FramedExample
+              cssClass="standalone"
+              dashed={true}
+              height={480}
+              onContentsRendered={updatingActiveRoomStore.forcedUpdate}
+              summary="Standalone room conversation (has-participants, 600x480)"
+              width={600}>
                 <div className="standalone">
                   <StandaloneRoomView
+                    activeRoomStore={updatingActiveRoomStore}
                     dispatcher={dispatcher}
-                    activeRoomStore={updatingActiveRoomStore}
-                    roomState={ROOM_STATES.HAS_PARTICIPANTS}
                     isFirefox={true}
                     localPosterUrl="sample-img/video-screen-local.png"
-                    remotePosterUrl="sample-img/video-screen-remote.png" />
+                    remotePosterUrl="sample-img/video-screen-remote.png"
+                    roomState={ROOM_STATES.HAS_PARTICIPANTS} />
                 </div>
             </FramedExample>
 
-            <FramedExample width={600} height={480}
-                           onContentsRendered={updatingSharingRoomStore.forcedUpdate}
-              summary="Standalone room convo (has-participants, receivingScreenShare, 600x480)">
+            <FramedExample
+              height={480}
+              onContentsRendered={updatingSharingRoomStore.forcedUpdate}
+              summary="Standalone room convo (has-participants, receivingScreenShare, 600x480)"
+              width={600} >
                 <div className="standalone" cssClass="standalone">
                   <StandaloneRoomView
+                    activeRoomStore={updatingSharingRoomStore}
                     dispatcher={dispatcher}
-                    activeRoomStore={updatingSharingRoomStore}
-                    roomState={ROOM_STATES.HAS_PARTICIPANTS}
                     isFirefox={true}
                     localPosterUrl="sample-img/video-screen-local.png"
                     remotePosterUrl="sample-img/video-screen-remote.png"
+                    roomState={ROOM_STATES.HAS_PARTICIPANTS}
                     screenSharePosterUrl="sample-img/video-screen-terminal.png" />
                 </div>
             </FramedExample>
           </Section>
 
           <Section name="TextChatView">
-            <FramedExample width={298} height={160} dashed={true}
-                           summary="TextChatView: desktop embedded">
+            <FramedExample dashed={true}
+                           height={160}
+                           summary="TextChatView: desktop embedded"
+                           width={298}>
               <div className="fx-embedded">
                 <TextChatView dispatcher={dispatcher}
                               showAlways={false}
                               showRoomName={false} />
               </div>
             </FramedExample>
 
-            <FramedExample width={200} height={400} dashed={true}
-                           cssClass="standalone"
-                           summary="Standalone Text Chat conversation (200x400)">
+            <FramedExample cssClass="standalone"
+                           dashed={true}
+                           height={400}
+                           summary="Standalone Text Chat conversation (200x400)"
+                           width={200}>
               <div className="standalone text-chat-example">
                 <div className="media-wrapper">
                   <TextChatView
                     dispatcher={dispatcher}
                     showAlways={true}
                     showRoomName={true} />
                 </div>
               </div>
             </FramedExample>
           </Section>
 
-          <Section name="SVG icons preview" className="svg-icons">
+          <Section className="svg-icons" name="SVG icons preview">
             <Example summary="10x10">
               <SVGIcons size="10x10"/>
             </Example>
             <Example summary="14x14">
               <SVGIcons size="14x14" />
             </Example>
             <Example summary="16x16">
               <SVGIcons size="16x16"/>
--- a/browser/devtools/debugger/debugger-controller.js
+++ b/browser/devtools/debugger/debugger-controller.js
@@ -1203,32 +1203,32 @@ SourceScripts.prototype = {
   _cache: new Map(),
 
   /**
    * Connect to the current thread client.
    */
   connect: function() {
     dumpn("SourceScripts is connecting...");
     this.debuggerClient.addListener("newGlobal", this._onNewGlobal);
-    this.debuggerClient.addListener("newSource", this._onNewSource);
+    this.activeThread.addListener("newSource", this._onNewSource);
     this.activeThread.addListener("blackboxchange", this._onBlackBoxChange);
     this.activeThread.addListener("prettyprintchange", this._onPrettyPrintChange);
     this.handleTabNavigation();
   },
 
   /**
    * Disconnect from the client.
    */
   disconnect: function() {
     if (!this.activeThread) {
       return;
     }
     dumpn("SourceScripts is disconnecting...");
     this.debuggerClient.removeListener("newGlobal", this._onNewGlobal);
-    this.debuggerClient.removeListener("newSource", this._onNewSource);
+    this.activeThread.removeListener("newSource", this._onNewSource);
     this.activeThread.removeListener("blackboxchange", this._onBlackBoxChange);
     this.activeThread.addListener("prettyprintchange", this._onPrettyPrintChange);
   },
 
   /**
    * Clears all the cached source contents.
    */
   clearCache: function() {
--- a/browser/devtools/debugger/test/browser_dbg_chrome-debugging.js
+++ b/browser/devtools/debugger/test/browser_dbg_chrome-debugging.js
@@ -40,22 +40,22 @@ function test() {
 
     testChromeActor();
   });
 }
 
 function testChromeActor() {
   gClient.getProcess().then(aResponse => {
     gClient.addListener("newGlobal", onNewGlobal);
-    gClient.addListener("newSource", onNewSource);
 
     let actor = aResponse.form.actor;
     gClient.attachTab(actor, (response, tabClient) => {
       tabClient.attachThread(null, (aResponse, aThreadClient) => {
         gThreadClient = aThreadClient;
+        gThreadClient.addListener("newSource", onNewSource);
 
         if (aResponse.error) {
           ok(false, "Couldn't attach to the chrome debugger.");
           gAttached.reject();
         } else {
           ok(true, "Attached to the chrome debugger.");
           gAttached.resolve();
 
@@ -73,17 +73,17 @@ function onNewGlobal() {
   gClient.removeListener("newGlobal", onNewGlobal);
   gNewGlobal.resolve();
 }
 
 function onNewSource(aEvent, aPacket) {
   if (aPacket.source.url.startsWith("chrome:")) {
     ok(true, "Received a new chrome source: " + aPacket.source.url);
 
-    gClient.removeListener("newSource", onNewSource);
+    gThreadClient.removeListener("newSource", onNewSource);
     gNewChromeSource.resolve();
   }
 }
 
 function resumeAndCloseConnection() {
   let deferred = promise.defer();
   gThreadClient.resume(() => gClient.close(deferred.resolve));
   return deferred.promise;
--- a/browser/devtools/inspector/test/browser_inspector_highlighter-options.js
+++ b/browser/devtools/inspector/test/browser_inspector_highlighter-options.js
@@ -138,16 +138,56 @@ const TEST_DATA = [
       let {points} = yield getHighlighterRegionPath("margin", toolbox.highlighter);
       points = points[0];
 
       is(Math.ceil(topY1), points[0][1], "Top guide's y1 is correct");
       is(Math.floor(rightX1), points[1][0], "Right guide's x1 is correct");
       is(Math.floor(bottomY1), points[2][1], "Bottom guide's y1 is correct");
       is(Math.ceil(leftX1), points[3][0], "Left guide's x1 is correct");
     }
+  },
+  {
+    desc: "When showOnly is used, other regions can be faded",
+    options: {showOnly: "margin", onlyRegionArea: true},
+    checkHighlighter: function*(toolbox) {
+      let h = toolbox.highlighter;
+
+      for (let region of ["margin", "border", "padding", "content"]) {
+        let {d} = yield getHighlighterRegionPath(region, h);
+        ok(d, "Region " + region + " is shown (it has a d attribute)");
+
+        let faded = yield getHighlighterNodeAttribute(h,
+                          "box-model-" + region, "faded");
+        if (region === "margin") {
+          ok(!faded, "The margin region is not faded");
+        } else {
+          is(faded, "true", "Region " + region + " is faded");
+        }
+      }
+    }
+  },
+  {
+    desc: "When showOnly is used, other regions can be faded (2)",
+    options: {showOnly: "padding", onlyRegionArea: true},
+    checkHighlighter: function*(toolbox) {
+      let h = toolbox.highlighter;
+
+      for (let region of ["margin", "border", "padding", "content"]) {
+        let {d} = yield getHighlighterRegionPath(region, h);
+        ok(d, "Region " + region + " is shown (it has a d attribute)");
+
+        let faded = yield getHighlighterNodeAttribute(h,
+                          "box-model-" + region, "faded");
+        if (region === "padding") {
+          ok(!faded, "The padding region is not faded");
+        } else {
+          is(faded, "true", "Region " + region + " is faded");
+        }
+      }
+    }
   }
 ];
 
 add_task(function*() {
   let {inspector, toolbox} = yield openInspectorForURL(TEST_URL);
 
   let divFront = yield getNodeFront("div", inspector);
 
--- a/browser/devtools/layoutview/view.js
+++ b/browser/devtools/layoutview/view.js
@@ -548,17 +548,21 @@ LayoutView.prototype = {
 let elts;
 
 let onmouseover = function(e) {
   let region = e.target.getAttribute("data-box");
   if (!region) {
     return false;
   }
 
-  this.layoutview.showBoxModel({region});
+  this.layoutview.showBoxModel({
+    region,
+    showOnly: region,
+    onlyRegionArea: true
+  });
 
   return false;
 }.bind(window);
 
 let onmouseout = function() {
   this.layoutview.hideBoxModel();
   return false;
 }.bind(window);
--- a/browser/devtools/shared/widgets/VariablesView.jsm
+++ b/browser/devtools/shared/widgets/VariablesView.jsm
@@ -1538,17 +1538,17 @@ Scope.prototype = {
 
   /**
    * Sort in ascending order
    * This only needs to compare non-numbers since it is dealing with an array
    * which numeric-based indices are placed in order.
    *
    * @param string a
    * @param string b
-   * @return number 
+   * @return number
    *         -1 if a is less than b, 0 if no change in order, +1 if a is greater than 0
    */
   _naturalSort: function(a,b) {
     if (isNaN(parseFloat(a)) && isNaN(parseFloat(b))) {
       return a < b ? -1 : 1;
     }
    },
 
--- a/browser/devtools/webconsole/console-output.js
+++ b/browser/devtools/webconsole/console-output.js
@@ -337,16 +337,20 @@ ConsoleOutput.prototype = {
    * Open an URL in a new tab.
    * @see WebConsole.openLink() in hudservice.js
    */
   openLink: function()
   {
     this.owner.owner.openLink.apply(this.owner.owner, arguments);
   },
 
+  openLocationInDebugger: function ({url, line}) {
+    return this.owner.owner.viewSourceInDebugger(url, line);
+  },
+
   /**
    * Open the variables view to inspect an object actor.
    * @see JSTerm.openVariablesView() in webconsole.js
    */
   openVariablesView: function()
   {
     this.owner.jsterm.openVariablesView.apply(this.owner.jsterm, arguments);
   },
@@ -2491,43 +2495,69 @@ Widgets.JSObject.prototype = Heritage.ex
   _anchor: function(text, options = {})
   {
     if (!options.onClick) {
       // If the anchor has an URL, open it in a new tab. If not, show the
       // current object actor.
       options.onClick = options.href ? this._onClickAnchor : this._onClick;
     }
 
+    options.onContextMenu = options.onContextMenu || this._onContextMenu;
+
     let anchor = this.el("a", {
       class: options.className,
       draggable: false,
       href: options.href || "#",
     }, text);
 
     this.message._addLinkCallback(anchor, options.onClick);
 
+    anchor.addEventListener("contextmenu", options.onContextMenu.bind(this));
+
     if (options.appendTo) {
       options.appendTo.appendChild(anchor);
     } else if (!("appendTo" in options) && this.element) {
       this.element.appendChild(anchor);
     }
 
     return anchor;
   },
 
+  openObjectInVariablesView: function()
+  {
+    this.output.openVariablesView({
+      label: VariablesView.getString(this.objectActor, { concise: true }),
+      objectActor: this.objectActor,
+      autofocus: true,
+    });
+  },
+
   /**
    * The click event handler for objects shown inline.
    * @private
    */
   _onClick: function()
   {
-    this.output.openVariablesView({
-      label: VariablesView.getString(this.objectActor, { concise: true }),
-      objectActor: this.objectActor,
-      autofocus: true,
+    this.openObjectInVariablesView();
+  },
+
+  _onContextMenu: function(ev) {
+    // TODO offer a nice API for the context menu.
+    // Probably worth to take a look at Firebug's way
+    // https://github.com/firebug/firebug/blob/master/extension/content/firebug/chrome/menu.js
+    let doc = ev.target.ownerDocument;
+    let cmPopup = doc.getElementById("output-contextmenu");
+    let openInVarViewCmd = doc.getElementById("menu_openInVarView");
+    let openVarView = this.openObjectInVariablesView.bind(this);
+    openInVarViewCmd.addEventListener("command", openVarView);
+    openInVarViewCmd.removeAttribute("disabled");
+    cmPopup.addEventListener("popuphiding", function onPopupHiding() {
+      cmPopup.removeEventListener("popuphiding", onPopupHiding);
+      openInVarViewCmd.removeEventListener("command", openVarView);
+      openInVarViewCmd.setAttribute("disabled", "true");
     });
   },
 
   /**
    * Add a string to the message.
    *
    * @private
    * @param string str
@@ -2685,16 +2715,26 @@ Widgets.ObjectRenderers.add({
         this._text(", ");
       }
       this.element.appendChild(this.el("span.cm-def", param));
       shown++;
     }
 
     this._text(")");
   },
+
+  _onClick: function () {
+    let location = this.objectActor.location;
+    if (location) {
+      this.output.openLocationInDebugger(location);
+    }
+    else {
+      this.openObjectInVariablesView();
+    }
+  }
 }); // Widgets.ObjectRenderers.byClass.Function
 
 /**
  * The widget used for displaying ArrayLike objects.
  */
 Widgets.ObjectRenderers.add({
   byKind: "ArrayLike",
 
--- a/browser/devtools/webconsole/test/browser.ini
+++ b/browser/devtools/webconsole/test/browser.ini
@@ -119,16 +119,18 @@ support-files =
   test-bug_923281_console_log_filter.html
   test-bug_923281_test1.js
   test-bug_923281_test2.js
   test-bug_939783_console_trace_duplicates.html
   test-bug-952277-highlight-nodes-in-vview.html
   test-bug-609872-cd-iframe-parent.html
   test-bug-609872-cd-iframe-child.html
   test-bug-989025-iframe-parent.html
+  test-bug_1050691_click_function_to_source.html
+  test-bug_1050691_click_function_to_source.js
   test-console-api-stackframe.html
   test_bug_1010953_cspro.html^headers^
   test_bug_1010953_cspro.html
   test_bug1045902_console_csp_ignore_reflected_xss_message.html^headers^
   test_bug1045902_console_csp_ignore_reflected_xss_message.html
   test_bug1092055_shouldwarn.js^headers^
   test_bug1092055_shouldwarn.js
   test_bug1092055_shouldwarn.html
@@ -382,8 +384,10 @@ skip-if = e10s # Bug 1042253 - webconsol
 [browser_webconsole_autocomplete_crossdomain_iframe.js]
 [browser_webconsole_console_custom_styles.js]
 [browser_webconsole_console_api_stackframe.js]
 [browser_webconsole_column_numbers.js]
 [browser_console_open_or_focus.js]
 [browser_webconsole_bug_922212_console_dirxml.js]
 [browser_webconsole_shows_reqs_in_netmonitor.js]
 [browser_netmonitor_shows_reqs_in_webconsole.js]
+[browser_webconsole_bug_1050691_click_function_to_source.js]
+[browser_webconsole_context_menu_open_in_var_view.js]
new file mode 100644
--- /dev/null
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_1050691_click_function_to_source.js
@@ -0,0 +1,60 @@
+/* vim:set ts=2 sw=2 sts=2 et: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// Tests that clicking on a function displays its source in the debugger.
+
+"use strict";
+
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/test-bug_1050691_click_function_to_source.html";
+
+let test = asyncTest(function*() {
+  yield loadTab(TEST_URI);
+  let hud = yield openConsole();
+
+  yield testWithoutDebuggerOpen(hud);
+
+  // Open the Debugger panel.
+  let debuggerPanel = yield openDebugger();
+  // And right after come back to the Console panel.
+  yield openConsole();
+  yield testWithDebuggerOpen(hud, debuggerPanel);
+});
+
+function* testWithoutDebuggerOpen(hud) {
+  let clickable = yield printFunction(hud);
+  let onVariablesViewOpen = hud.jsterm.once("variablesview-fetched");
+  synthesizeClick(clickable, hud);
+  return onVariablesViewOpen;
+}
+
+function* testWithDebuggerOpen(hud, debuggerPanel) {
+  let clickable = yield printFunction(hud);
+  let panelWin = debuggerPanel.panelWin;
+  let onEditorLocationSet = panelWin.once(panelWin.EVENTS.EDITOR_LOCATION_SET);
+  synthesizeClick(clickable, hud);
+  yield onEditorLocationSet;
+  ok(isDebuggerCaretPos(debuggerPanel, 7),
+    "Clicking on a function should go to its source in the debugger view");
+}
+
+function synthesizeClick(clickable, hud) {
+  EventUtils.synthesizeMouse(clickable, 2, 2, {}, hud.iframeWindow);
+}
+
+let printFunction = Task.async(function* (hud) {
+  hud.jsterm.clearOutput();
+  content.wrappedJSObject.foo();
+  let [result] = yield waitForMessages({
+    webconsole: hud,
+    messages: [{
+      category: CATEGORY_WEBDEV,
+      severity: SEVERITY_LOG,
+    }],
+  });
+  let msg = [...result.matched][0];
+  let clickable = msg.querySelector("a");
+  ok(clickable, "clickable item for object should exist");
+  return clickable;
+});
--- a/browser/devtools/webconsole/test/browser_webconsole_closure_inspection.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_closure_inspection.js
@@ -34,17 +34,17 @@ function test()
         });
 
         let button = content.document.querySelector("button");
         ok(button, "button element found");
         EventUtils.synthesizeMouseAtCenter(button, {}, content);
 
         return deferred.promise;
       });
-    })
+    });
   });
 }
 
 function consoleOpened(hud)
 {
   gWebConsole = hud;
   gJSTerm = hud.jsterm;
   gJSTerm.execute("window.george.getName");
@@ -60,17 +60,25 @@ function consoleOpened(hud)
 }
 
 function onExecuteGetName(aResults)
 {
   let clickable = aResults[0].clickableElements[0];
   ok(clickable, "clickable object found");
 
   gJSTerm.once("variablesview-fetched", onGetNameFetch);
-  EventUtils.synthesizeMouse(clickable, 2, 2, {}, gWebConsole.iframeWindow);
+  let contextMenu =
+      gWebConsole.iframeWindow.document.getElementById("output-contextmenu");
+  waitForContextMenu(contextMenu, clickable, () => {
+    let openInVarView = contextMenu.querySelector("#menu_openInVarView");
+    ok(openInVarView.disabled === false,
+       "the \"Open In Variables View\" context menu item should be clickable");
+    // EventUtils.synthesizeMouseAtCenter seems to fail here in Mac OSX
+    openInVarView.click();
+  });
 }
 
 function onGetNameFetch(aEvent, aVar)
 {
   gVariablesView = aVar._variablesView;
   ok(gVariablesView, "variables view object");
 
   findVariableViewProperties(aVar, [
new file mode 100644
--- /dev/null
+++ b/browser/devtools/webconsole/test/browser_webconsole_context_menu_open_in_var_view.js
@@ -0,0 +1,51 @@
+/* vim:set ts=2 sw=2 sts=2 et: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// Tests that the "Open in Variables View" context menu item is enabled
+// only for objects.
+
+"use strict";
+
+const TEST_URI = `data:text/html,<script>
+  console.log("foo");
+  console.log("foo", window);
+</script>`;
+
+let test = asyncTest(function*() {
+  yield loadTab(TEST_URI);
+  let hud = yield openConsole();
+
+  let [result] = yield waitForMessages({
+    webconsole: hud,
+    messages: [{
+      category: CATEGORY_WEBDEV,
+      severity: SEVERITY_LOG,
+      count: 2,
+      text: /foo/
+    }],
+  });
+
+  let [msgWithText, msgWithObj] = [...result.matched];
+  ok(msgWithText && msgWithObj, "Two messages should have appeared");
+
+  let contextMenu = hud.iframeWindow.
+    document.getElementById("output-contextmenu");
+  let openInVarViewItem = contextMenu.querySelector("#menu_openInVarView");
+  let obj = msgWithObj.querySelector(".cm-variable");
+  let text = msgWithText.querySelector(".console-string");
+
+  yield waitForContextMenu(contextMenu, obj, () => {
+    ok(openInVarViewItem.disabled === false, "The \"Open In Variables View\" " +
+      "context menu item should be available for objects");
+  }, () => {
+    ok(openInVarViewItem.disabled === true, "The \"Open In Variables View\" " +
+      "context menu item should be disabled on popup hiding");
+  });
+
+  yield waitForContextMenu(contextMenu, text, () => {
+    ok(openInVarViewItem.disabled === true, "The \"Open In Variables View\" " +
+      "context menu item should be disabled for texts");
+  });
+});
--- a/browser/devtools/webconsole/test/head.js
+++ b/browser/devtools/webconsole/test/head.js
@@ -221,16 +221,18 @@ let closeConsole = Task.async(function* 
  * @param function aOnHidden
  *        Function to invoke on popuphidden event.
  * @return object
  *         A Promise object that is resolved after the popuphidden event
  *         callback is invoked.
  */
 function waitForContextMenu(aPopup, aButton, aOnShown, aOnHidden)
 {
+  let deferred = promise.defer();
+
   function onPopupShown() {
     info("onPopupShown");
     aPopup.removeEventListener("popupshown", onPopupShown);
 
     aOnShown && aOnShown();
 
     // Use executeSoon() to get out of the popupshown event.
     aPopup.addEventListener("popuphidden", onPopupHidden);
@@ -240,21 +242,20 @@ function waitForContextMenu(aPopup, aBut
     info("onPopupHidden");
     aPopup.removeEventListener("popuphidden", onPopupHidden);
 
     aOnHidden && aOnHidden();
 
     deferred.resolve(aPopup);
   }
 
-  let deferred = promise.defer();
   aPopup.addEventListener("popupshown", onPopupShown);
 
   info("wait for the context menu to open");
-  let eventDetails = { type: "contextmenu", button: 2};
+  let eventDetails = {type: "contextmenu", button: 2};
   EventUtils.synthesizeMouse(aButton, 2, 2, eventDetails,
                              aButton.ownerDocument.defaultView);
   return deferred.promise;
 }
 
 /**
  * Listen for a new tab to open and return a promise that resolves when one
  * does and completes the load event.
@@ -820,17 +821,17 @@ function openDebugger(aOptions = {})
   if (!aOptions.tab) {
     aOptions.tab = gBrowser.selectedTab;
   }
 
   let deferred = promise.defer();
 
   let target = TargetFactory.forTab(aOptions.tab);
   let toolbox = gDevTools.getToolbox(target);
-  let dbgPanelAlreadyOpen = toolbox.getPanel("jsdebugger");
+  let dbgPanelAlreadyOpen = toolbox && toolbox.getPanel("jsdebugger");
 
   gDevTools.showToolbox(target, "jsdebugger").then(function onSuccess(aToolbox) {
     let panel = aToolbox.getCurrentPanel();
     let panelWin = panel.panelWin;
 
     panel._view.Variables.lazyEmpty = false;
 
     let resolveObject = {
@@ -852,16 +853,34 @@ function openDebugger(aOptions = {})
     console.debug("failed to open the toolbox for 'jsdebugger'", aReason);
     deferred.reject(aReason);
   });
 
   return deferred.promise;
 }
 
 /**
+ * Returns true if the caret in the debugger editor is placed at the specified
+ * position.
+ * @param  aPanel The debugger panel.
+ * @param {number} aLine The line number.
+ * @param {number} [aCol] The column number.
+ * @returns {boolean}
+ */
+function isDebuggerCaretPos(aPanel, aLine, aCol = 1) {
+  let editor = aPanel.panelWin.DebuggerView.editor;
+  let cursor = editor.getCursor();
+
+  // Source editor starts counting line and column numbers from 0.
+  info("Current editor caret position: " + (cursor.line + 1) + ", " +
+    (cursor.ch + 1));
+  return cursor.line == (aLine - 1) && cursor.ch == (aCol - 1);
+}
+
+/**
  * Wait for messages in the Web Console output.
  *
  * @param object aOptions
  *        Options for what you want to wait for:
  *        - webconsole: the webconsole instance you work with.
  *        - matchCondition: "any" or "all". Default: "all". The promise
  *        returned by this function resolves when all of the messages are
  *        matched, if the |matchCondition| is "all". If you set the condition to
new file mode 100644
--- /dev/null
+++ b/browser/devtools/webconsole/test/test-bug_1050691_click_function_to_source.html
@@ -0,0 +1,11 @@
+<!DOCTYPE HTML>
+<html dir="ltr" xml:lang="en-US" lang="en-US">
+  <head>
+    <meta charset="utf-8">
+    <title>Click on function should point to source</title>
+    <!-- Any copyright is dedicated to the Public Domain.
+       - http://creativecommons.org/publicdomain/zero/1.0/ -->
+    <script type="text/javascript" src="test-bug_1050691_click_function_to_source.js"></script>
+  </head>
+  <body></body>
+</html>
new file mode 100644
--- /dev/null
+++ b/browser/devtools/webconsole/test/test-bug_1050691_click_function_to_source.js
@@ -0,0 +1,10 @@
+/**
+ * this
+ * is
+ * a
+ * function
+ */
+function foo() {
+  console.log(foo);
+}
+
--- a/browser/devtools/webconsole/webconsole.xul
+++ b/browser/devtools/webconsole/webconsole.xul
@@ -71,16 +71,18 @@ function goUpdateConsoleCommands() {
       <menuitem id="saveBodiesContextMenu" type="checkbox" label="&saveBodies.label;"
                 accesskey="&saveBodies.accesskey;"/>
       <menuitem id="menu_openURL" label="&openURL.label;"
                 accesskey="&openURL.accesskey;" command="consoleCmd_openURL"
                 selection="network" selectionType="single"/>
       <menuitem id="menu_copyURL" label="&copyURLCmd.label;"
                 accesskey="&copyURLCmd.accesskey;" command="consoleCmd_copyURL"
                 selection="network" selectionType="single"/>
+      <menuitem id="menu_openInVarView" label="&openInVarViewCmd.label;"
+        accesskey="&openInVarViewCmd.accesskey;" disabled="true"/>
       <menuitem id="cMenu_copy"/>
       <menuitem id="cMenu_selectAll"/>
     </menupopup>
   </popupset>
 
   <tooltip id="aHTMLTooltip" page="true"/>
 
   <box class="hud-outer-wrapper devtools-responsive-container theme-body" flex="1">
--- a/browser/locales/en-US/chrome/browser/devtools/webConsole.dtd
+++ b/browser/locales/en-US/chrome/browser/devtools/webConsole.dtd
@@ -102,8 +102,10 @@
 <!ENTITY fullZoomResetCmd.commandkey2   "">
 
 <!ENTITY copyURLCmd.label     "Copy Link Location">
 <!ENTITY copyURLCmd.accesskey "a">
 
 <!ENTITY closeCmd.key         "W">
 <!ENTITY findCmd.key          "F">
 <!ENTITY clearOutputCtrl.key  "L">
+<!ENTITY openInVarViewCmd.label "Open in Variables View">
+<!ENTITY openInVarViewCmd.accesskey "V">
--- a/mobile/android/base/resources/menu-large-v11/browser_app_menu.xml
+++ b/mobile/android/base/resources/menu-large-v11/browser_app_menu.xml
@@ -1,14 +1,18 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!-- This Source Code Form is subject to the terms of the Mozilla Public
    - License, v. 2.0. If a copy of the MPL was not distributed with this
    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
 
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
+<!-- We disable AlwaysShowAction because we interpret the menu
+     attributes ourselves and thus the warning isn't relevant to us. -->
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+      xmlns:tools="http://schemas.android.com/tools"
+      tools:ignore="AlwaysShowAction">
 
     <item android:id="@+id/reload"
           android:icon="@drawable/new_tablet_ic_menu_reload"
           android:title="@string/reload"
           android:showAsAction="always"/>
 
     <item android:id="@+id/back"
           android:icon="@drawable/ic_menu_back"
--- a/mobile/android/base/resources/menu-v11/browser_app_menu.xml
+++ b/mobile/android/base/resources/menu-v11/browser_app_menu.xml
@@ -1,14 +1,18 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!-- This Source Code Form is subject to the terms of the Mozilla Public
    - License, v. 2.0. If a copy of the MPL was not distributed with this
    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
 
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
+<!-- We disable AlwaysShowAction because we interpret the menu
+     attributes ourselves and thus the warning isn't relevant to us. -->
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+      xmlns:tools="http://schemas.android.com/tools"
+      tools:ignore="AlwaysShowAction">
 
     <item android:id="@+id/back"
           android:icon="@drawable/ic_menu_back"
           android:title="@string/back"
           android:showAsAction="always"/>
 
     <item android:id="@+id/forward"
           android:icon="@drawable/ic_menu_forward"
--- a/mobile/android/base/resources/menu-xlarge-v11/browser_app_menu.xml
+++ b/mobile/android/base/resources/menu-xlarge-v11/browser_app_menu.xml
@@ -1,14 +1,18 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!-- This Source Code Form is subject to the terms of the Mozilla Public
    - License, v. 2.0. If a copy of the MPL was not distributed with this
    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
 
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
+<!-- We disable AlwaysShowAction because we interpret the menu
+     attributes ourselves and thus the warning isn't relevant to us. -->
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+      xmlns:tools="http://schemas.android.com/tools"
+      tools:ignore="AlwaysShowAction">
 
     <item android:id="@+id/reload"
           android:icon="@drawable/new_tablet_ic_menu_reload"
           android:title="@string/reload"
           android:showAsAction="always"/>
 
     <item android:id="@+id/back"
           android:icon="@drawable/ic_menu_back"
--- a/mobile/android/chrome/content/aboutPrivateBrowsing.xhtml
+++ b/mobile/android/chrome/content/aboutPrivateBrowsing.xhtml
@@ -26,17 +26,17 @@
 
   <body class="private">
     <img class="masq" src="chrome://browser/skin/images/privatebrowsing-mask.png" />
 
     <h1 class="showPrivate">&privatebrowsingpage.title;</h1>
     <h1 class="showNormal">&privatebrowsingpage.title.normal;</h1>
 
     <div class="contentSection">
-      <p class="showPrivate">&privatebrowsingpage.description.private;</p>
+      <p class="showPrivate">&privatebrowsingpage.description.private2;</p>
       <p class="showNormal">&privatebrowsingpage.description.normal;</p>
 
       <p class="showPrivate"><a href="https://support.mozilla.org/kb/private-browsing-firefox-android">&privatebrowsingpage.link.private;</a></p>
       <p class="showNormal"><a href="#" id="newPrivateTabLink">&privatebrowsingpage.link.normal;</a></p>
     </div>
 
   </body>
 </html>
--- a/mobile/android/locales/en-US/chrome/aboutPrivateBrowsing.dtd
+++ b/mobile/android/locales/en-US/chrome/aboutPrivateBrowsing.dtd
@@ -5,12 +5,12 @@
 <!ENTITY privatebrowsingpage.title "Private Browsing">
 <!ENTITY privatebrowsingpage.title.normal "You are not in private browsing">
 
 <!ENTITY privatebrowsingpage.issueDesc.normal2 "In private browsing, we won't keep any of your browsing history or cookies.">
 <!ENTITY privatebrowsingpage.issueDesc.private2 "We won't keep any of your browsing history or cookies.">
 
 <!ENTITY privatebrowsingpage.description2 "Bookmarks you add and files you download will still be saved on your device.">
 <!ENTITY privatebrowsingpage.description.normal "&privatebrowsingpage.issueDesc.normal2; &privatebrowsingpage.description2;">
-<!ENTITY privatebrowsingpage.description.private "&privatebrowsingpage.issueDesc.private2; &privatebrowsingpage.description2;">
+<!ENTITY privatebrowsingpage.description.private2 "&privatebrowsingpage.issueDesc.private2; &privatebrowsingpage.description2;">
 
 <!ENTITY privatebrowsingpage.link.private "Want to learn more?">
 <!ENTITY privatebrowsingpage.link.normal "Open a new private tab">
--- a/toolkit/components/search/SearchSuggestionController.jsm
+++ b/toolkit/components/search/SearchSuggestionController.jsm
@@ -123,17 +123,17 @@ this.SearchSuggestionController.prototyp
       throw new Error("The privateMode argument is required to avoid unintentional privacy leaks");
     }
     if (!(engine instanceof Ci.nsISearchEngine)) {
       throw new Error("Invalid search engine");
     }
     if (!this.maxLocalResults && !this.maxRemoteResults) {
       throw new Error("Zero results expected, what are you trying to do?");
     }
-    if (this.maxLocalResults < 0 || this.remoteResult < 0) {
+    if (this.maxLocalResults < 0 || this.maxRemoteResults < 0) {
       throw new Error("Number of requested results must be positive");
     }
 
     // Array of promises to resolve before returning results.
     let promises = [];
     this._searchString = searchTerm;
 
     // Remote results
--- a/toolkit/devtools/DevToolsUtils.js
+++ b/toolkit/devtools/DevToolsUtils.js
@@ -45,17 +45,17 @@ exports.safeErrorString = function safeE
 /**
  * Report that |aWho| threw an exception, |aException|.
  */
 exports.reportException = function reportException(aWho, aException) {
   let msg = aWho + " threw an exception: " + exports.safeErrorString(aException);
 
   dump(msg + "\n");
 
-  if (Cu.reportError) {
+  if (Cu && Cu.reportError) {
     /*
      * Note that the xpcshell test harness registers an observer for
      * console messages, so when we're running tests, this will cause
      * the test to quit.
      */
     Cu.reportError(msg);
   }
 }
--- a/toolkit/devtools/client/dbg-client.jsm
+++ b/toolkit/devtools/client/dbg-client.jsm
@@ -219,17 +219,16 @@ const UnsolicitedNotifications = {
   "eventNotification": "eventNotification",
   "fileActivity": "fileActivity",
   "lastPrivateContextExited": "lastPrivateContextExited",
   "logMessage": "logMessage",
   "networkEvent": "networkEvent",
   "networkEventUpdate": "networkEventUpdate",
   "newGlobal": "newGlobal",
   "newScript": "newScript",
-  "newSource": "newSource",
   "tabDetached": "tabDetached",
   "tabListChanged": "tabListChanged",
   "reflowActivity": "reflowActivity",
   "addonListChanged": "addonListChanged",
   "tabNavigated": "tabNavigated",
   "frameUpdate": "frameUpdate",
   "pageError": "pageError",
   "documentLoad": "documentLoad",
@@ -1618,17 +1617,16 @@ function ThreadClient(aClient, aActor) {
   this._parent = aClient;
   this.client = aClient instanceof DebuggerClient ? aClient : aClient.client;
   this._actor = aActor;
   this._frameCache = [];
   this._scriptCache = {};
   this._pauseGrips = {};
   this._threadGrips = {};
   this.request = this.client.request;
-  this.events = [];
 }
 
 ThreadClient.prototype = {
   _state: "paused",
   get state() { return this._state; },
   get paused() { return this._state === "paused"; },
 
   _pauseOnExceptions: false,
@@ -2165,17 +2163,19 @@ ThreadClient.prototype = {
    * @param actors [string]
    *        List of actor ID of the queried objects.
    */
   getPrototypesAndProperties: DebuggerClient.requester({
     type: "prototypesAndProperties",
     actors: args(0)
   }, {
     telemetry: "PROTOTYPESANDPROPERTIES"
-  })
+  }),
+
+  events: ["newSource"]
 };
 
 eventSource(ThreadClient.prototype);
 
 /**
  * Creates a tracing profiler client for the remote debugging protocol
  * server. This client is a front to the trace actor created on the
  * server side, hiding the protocol details in a traditional
--- a/toolkit/devtools/server/actors/addon.js
+++ b/toolkit/devtools/server/actors/addon.js
@@ -20,17 +20,17 @@ loader.lazyRequireGetter(this, "WebConso
 
 loader.lazyImporter(this, "AddonManager", "resource://gre/modules/AddonManager.jsm");
 
 function BrowserAddonActor(aConnection, aAddon) {
   this.conn = aConnection;
   this._addon = aAddon;
   this._contextPool = new ActorPool(this.conn);
   this.conn.addActorPool(this._contextPool);
-  this._threadActor = null;
+  this.threadActor = null;
   this._global = null;
 
   this._shouldAddNewGlobalAsDebuggee = this._shouldAddNewGlobalAsDebuggee.bind(this);
 
   this.makeDebugger = makeDebugger.bind(null, {
     findDebuggees: this._findDebuggees.bind(this),
     shouldAddNewGlobalAsDebuggee: this._shouldAddNewGlobalAsDebuggee
   });
@@ -50,27 +50,27 @@ BrowserAddonActor.prototype = {
     return this._addon.id;
   },
 
   get url() {
     return this._addon.sourceURI ? this._addon.sourceURI.spec : undefined;
   },
 
   get attached() {
-    return this._threadActor;
+    return this.threadActor;
   },
 
   get global() {
     return this._global;
   },
 
   get sources() {
     if (!this._sources) {
       dbg_assert(this.threadActor, "threadActor should exist when creating sources.");
-      this._sources = new TabSources(this._threadActor, this._allowSource);
+      this._sources = new TabSources(this.threadActor, this._allowSource);
     }
     return this._sources;
   },
 
 
   form: function BAA_form() {
     dbg_assert(this.actorID, "addon should have an actorID.");
     if (!this._consoleActor) {
@@ -130,31 +130,31 @@ BrowserAddonActor.prototype = {
   },
 
   onAttach: function BAA_onAttach() {
     if (this.exited) {
       return { type: "exited" };
     }
 
     if (!this.attached) {
-      this._threadActor = new AddonThreadActor(this.conn, this);
-      this._contextPool.addActor(this._threadActor);
+      this.threadActor = new AddonThreadActor(this.conn, this);
+      this._contextPool.addActor(this.threadActor);
     }
 
-    return { type: "tabAttached", threadActor: this._threadActor.actorID };
+    return { type: "tabAttached", threadActor: this.threadActor.actorID };
   },
 
   onDetach: function BAA_onDetach() {
     if (!this.attached) {
       return { error: "wrongState" };
     }
 
-    this._contextPool.removeActor(this._threadActor);
+    this._contextPool.removeActor(this.threadActor);
 
-    this._threadActor = null;
+    this.threadActor = null;
     this._sources = null;
 
     return { type: "detached" };
   },
 
   preNest: function() {
     let e = Services.wm.getEnumerator(null);
     while (e.hasMoreElements()) {
--- a/toolkit/devtools/server/actors/child-process.js
+++ b/toolkit/devtools/server/actors/child-process.js
@@ -13,17 +13,17 @@ const { ActorPool } = require("devtools/
 const Services = require("Services");
 const { dbg_assert } = require("devtools/toolkit/DevToolsUtils");
 const { TabSources } = require("./utils/TabSources");
 
 function ChildProcessActor(aConnection) {
   this.conn = aConnection;
   this._contextPool = new ActorPool(this.conn);
   this.conn.addActorPool(this._contextPool);
-  this._threadActor = null;
+  this.threadActor = null;
 
   // Use a see-everything debugger
   this.makeDebugger = makeDebugger.bind(null, {
     findDebuggees: dbg => dbg.findAllGlobals(),
     shouldAddNewGlobalAsDebuggee: global => true
   });
 
   // Scope into which the webconsole executes:
@@ -51,39 +51,39 @@ ChildProcessActor.prototype = {
   },
 
   get window() {
     return this._consoleScope;
   },
 
   get sources() {
     if (!this._sources) {
-      dbg_assert(this._threadActor, "threadActor should exist when creating sources.");
-      this._sources = new TabSources(this._threadActor);
+      dbg_assert(this.threadActor, "threadActor should exist when creating sources.");
+      this._sources = new TabSources(this.threadActor);
     }
     return this._sources;
   },
 
   form: function() {
     if (!this._consoleActor) {
       this._consoleActor = new WebConsoleActor(this.conn, this);
       this._contextPool.addActor(this._consoleActor);
     }
 
-    if (!this._threadActor) {
-      this._threadActor = new ChromeDebuggerActor(this.conn, this);
-      this._contextPool.addActor(this._threadActor);
+    if (!this.threadActor) {
+      this.threadActor = new ChromeDebuggerActor(this.conn, this);
+      this._contextPool.addActor(this.threadActor);
     }
 
     return {
       actor: this.actorID,
       name: "Content process",
 
       consoleActor: this._consoleActor.actorID,
-      chromeDebugger: this._threadActor.actorID,
+      chromeDebugger: this.threadActor.actorID,
 
       traits: {
         highlightable: false,
         networkMonitor: false,
       },
     };
   },
 
--- a/toolkit/devtools/server/actors/highlighter.css
+++ b/toolkit/devtools/server/actors/highlighter.css
@@ -30,16 +30,22 @@
 }
 
 /* Box model highlighter */
 
 :-moz-native-anonymous .box-model-regions {
   opacity: 0.6;
 }
 
+/* Box model regions can be faded (see the onlyRegionArea option in
+   highlighter.js) in order to only display certain regions. */
+:-moz-native-anonymous .box-model-regions [faded] {
+  display: none;
+}
+
 :-moz-native-anonymous .box-model-content {
   fill: #87ceeb;
 }
 
 :-moz-native-anonymous .box-model-padding {
   fill: #6a5acd;
 }
 
--- a/toolkit/devtools/server/actors/highlighter.js
+++ b/toolkit/devtools/server/actors/highlighter.js
@@ -229,17 +229,18 @@ let HighlighterActor = exports.Highlight
       this._highlighter.hide();
     }
   }, {
     request: {
       node: Arg(0, "domnode"),
       region: Option(1),
       hideInfoBar: Option(1),
       hideGuides: Option(1),
-      showOnly: Option(1)
+      showOnly: Option(1),
+      onlyRegionArea: Option(1)
     }
   }),
 
   /**
    * Hide the box model highlighting if it was shown before
    */
   hideBoxModel: method(function() {
     this._highlighter.hide();
@@ -1040,17 +1041,22 @@ AutoRefreshHighlighter.prototype = {
  *   This specifies the region that the guides should outline.
  *   Defaults to "content"
  * - hideGuides {Boolean}
  *   Defaults to false
  * - hideInfoBar {Boolean}
  *   Defaults to false
  * - showOnly {String}
  *   "content", "padding", "border" or "margin"
- *    If set, only this region will be highlighted
+ *   If set, only this region will be highlighted. Use with onlyRegionArea to
+ *   only highlight the area of the region.
+ * - onlyRegionArea {Boolean}
+ *   This can be set to true to make each region's box only highlight the area
+ *   of the corresponding region rather than the area of nested regions too.
+ *   This is useful when used with showOnly.
  *
  * Structure:
  * <div class="highlighter-container">
  *   <div class="box-model-root">
  *     <svg class="box-model-elements" hidden="true">
  *       <g class="box-model-regions">
  *         <path class="box-model-margin" points="..." />
  *         <path class="box-model-border" points="..." />
@@ -1422,59 +1428,100 @@ BoxModelHighlighter.prototype = Heritage
 
   /**
    * Update the box model as per the current node.
    *
    * @return {boolean}
    *         True if the current node has a box model to be highlighted
    */
   _updateBoxModel: function() {
-    this.options.region = this.options.region || "content";
-
-    if (this._nodeNeedsHighlighting()) {
-      for (let boxType of BOX_MODEL_REGIONS) {
-        let box = this.getElement(boxType);
-
-        if (this.regionFill[boxType]) {
-          box.setAttribute("style", "fill:" + this.regionFill[boxType]);
-        } else {
-          box.setAttribute("style", "");
-        }
-
-        if (!this.options.showOnly || this.options.showOnly === boxType) {
-          // Highlighting all quads.
-          let path = [];
-          for (let {p1, p2, p3, p4} of this.currentQuads[boxType]) {
-            path.push("M" + p1.x + "," + p1.y + " " +
-                      "L" + p2.x + "," + p2.y + " " +
-                      "L" + p3.x + "," + p3.y + " " +
-                      "L" + p4.x + "," + p4.y);
-          }
-
-          box.setAttribute("d", path.join(" "));
+    let options = this.options;
+    options.region = options.region || "content";
+
+    if (!this._nodeNeedsHighlighting()) {
+      this._hideBoxModel();
+      return false;
+    }
+
+    for (let i = 0; i < BOX_MODEL_REGIONS.length; i++) {
+      let boxType = BOX_MODEL_REGIONS[i];
+      let nextBoxType = BOX_MODEL_REGIONS[i + 1];
+      let box = this.getElement(boxType);
+
+      if (this.regionFill[boxType]) {
+        box.setAttribute("style", "fill:" + this.regionFill[boxType]);
+      } else {
+        box.setAttribute("style", "");
+      }
+
+      // Highlight all quads for this region by setting the "d" attribute of the
+      // corresponding <path>.
+      let path = [];
+      for (let j = 0; j < this.currentQuads[boxType].length; j++) {
+        let boxQuad = this.currentQuads[boxType][j];
+        let nextBoxQuad = this.currentQuads[nextBoxType]
+                          ? this.currentQuads[nextBoxType][j]
+                          : null;
+        path.push(this._getBoxPathCoordinates(boxQuad, nextBoxQuad));
+      }
+
+      box.setAttribute("d", path.join(" "));
+      box.removeAttribute("faded");
+
+      // If showOnly is defined, either hide the other regions, or fade them out
+      // if onlyRegionArea is set too.
+      if (options.showOnly && options.showOnly !== boxType) {
+        if (options.onlyRegionArea) {
+          box.setAttribute("faded", "true");
         } else {
           box.removeAttribute("d");
         }
-
-        if (boxType === this.options.region && !this.options.hideGuides) {
-          this._showGuides(boxType);
-        } else if (this.options.hideGuides) {
-          this._hideGuides();
-        }
+      }
+
+      if (boxType === options.region && !options.hideGuides) {
+        this._showGuides(boxType);
+      } else if (options.hideGuides) {
+        this._hideGuides();
       }
-
-      // Un-zoom the root wrapper if the page was zoomed.
-      let rootId = this.ID_CLASS_PREFIX + "root";
-      this.markup.scaleRootElement(this.currentNode, rootId);
-
-      return true;
     }
 
-    this._hideBoxModel();
-    return false;
+    // Un-zoom the root wrapper if the page was zoomed.
+    let rootId = this.ID_CLASS_PREFIX + "root";
+    this.markup.scaleRootElement(this.currentNode, rootId);
+
+    return true;
+  },
+
+  _getBoxPathCoordinates: function(boxQuad, nextBoxQuad) {
+    let {p1, p2, p3, p4} = boxQuad;
+
+    let path;
+    if (!nextBoxQuad || !this.options.onlyRegionArea) {
+      // If this is the content box (inner-most box) or if we're not being asked
+      // to highlight only region areas, then draw a simple rectangle.
+      path = "M" + p1.x + "," + p1.y + " " +
+             "L" + p2.x + "," + p2.y + " " +
+             "L" + p3.x + "," + p3.y + " " +
+             "L" + p4.x + "," + p4.y;
+    } else {
+      // Otherwise, just draw the region itself, not a filled rectangle.
+      let {p1: np1, p2: np2, p3: np3, p4: np4} = nextBoxQuad;
+      path = "M" + p1.x + "," + p1.y + " " +
+             "L" + p2.x + "," + p2.y + " " +
+             "L" + p3.x + "," + p3.y + " " +
+             "L" + p4.x + "," + p4.y + " " +
+             "L" + p1.x + "," + p1.y + " " +
+             "L" + np1.x + "," + np1.y + " " +
+             "L" + np4.x + "," + np4.y + " " +
+             "L" + np3.x + "," + np3.y + " " +
+             "L" + np2.x + "," + np2.y + " " +
+             "L" + np1.x + "," + np1.y;
+    }
+
+    return path;
   },
 
   _nodeNeedsHighlighting: function() {
     let hasNoQuads = !this.currentQuads.margin.length &&
                      !this.currentQuads.border.length &&
                      !this.currentQuads.padding.length &&
                      !this.currentQuads.content.length;
     if (!this.currentNode ||
--- a/toolkit/devtools/server/actors/object.js
+++ b/toolkit/devtools/server/actors/object.js
@@ -37,35 +37,39 @@ const OBJECT_PREVIEW_MAX_ITEMS = 10;
  *          - createEnvironmentActor
  *              Creates and return an environment actor
  *          - getGripDepth
  *              An actor's grip depth getter
  *          - incrementGripDepth
  *              Increment the actor's grip depth
  *          - decrementGripDepth
  *              Decrement the actor's grip depth
+ *          - globalDebugObject
+ *              The Debuggee Global Object as given by the ThreadActor
  */
 function ObjectActor(obj, {
   createValueGrip,
   sources,
   createEnvironmentActor,
   getGripDepth,
   incrementGripDepth,
-  decrementGripDepth
+  decrementGripDepth,
+  getGlobalDebugObject
 }) {
   dbg_assert(!obj.optimizedOut,
     "Should not create object actors for optimized out values!");
   this.obj = obj;
   this.hooks = {
     createValueGrip,
     sources,
     createEnvironmentActor,
     getGripDepth,
     incrementGripDepth,
-    decrementGripDepth
+    decrementGripDepth,
+    getGlobalDebugObject
   };
   this.iterators = new Set();
 }
 
 ObjectActor.prototype = {
   actorPrefix: "obj",
 
   /**
@@ -799,16 +803,27 @@ DebuggerServer.ObjectActorPreviewers = {
       dumpn(e);
     }
 
     if (userDisplayName && typeof userDisplayName.value == "string" &&
         userDisplayName.value) {
       grip.userDisplayName = hooks.createValueGrip(userDisplayName.value);
     }
 
+    let dbgGlobal = hooks.getGlobalDebugObject();
+    if (dbgGlobal) {
+      let script = dbgGlobal.makeDebuggeeValue(obj.unsafeDereference()).script;
+      if (script) {
+        grip.location = {
+          url: script.url,
+          line: script.startLine
+        };
+      }
+    }
+
     return true;
   }],
 
   RegExp: [function({obj, hooks}, grip) {
     // Avoid having any special preview for the RegExp.prototype itself.
     if (!obj.proto || obj.proto.class != "RegExp") {
       return false;
     }
--- a/toolkit/devtools/server/actors/promises.js
+++ b/toolkit/devtools/server/actors/promises.js
@@ -140,17 +140,19 @@ let PromisesActor = protocol.ActorClass(
       getGripDepth: () => this._gripDepth,
       incrementGripDepth: () => this._gripDepth++,
       decrementGripDepth: () => this._gripDepth--,
       createValueGrip: v =>
         createValueGrip(v, this._navigationLifetimePool, this.objectGrip),
       sources: () => DevToolsUtils.reportException("PromisesActor",
         Error("sources not yet implemented")),
       createEnvironmentActor: () => DevToolsUtils.reportException(
-        "PromisesActor", Error("createEnvironmentActor not yet implemented"))
+        "PromisesActor", Error("createEnvironmentActor not yet implemented")),
+      getGlobalDebugObject: () => DevToolsUtils.reportException(
+        "PromisesActor", Error("getGlobalDebugObject not yet implemented")),
     });
 
     this._navigationLifetimePool.addActor(actor);
     this._navigationLifetimePool.objectActors.set(promise, actor);
 
     return actor;
   },
 
--- a/toolkit/devtools/server/actors/script.js
+++ b/toolkit/devtools/server/actors/script.js
@@ -457,16 +457,19 @@ ThreadActor.prototype = {
       this._dbg.on("newGlobal", this.onNewGlobal);
       // Keep the debugger disabled until a client attaches.
       this._dbg.enabled = this._state != "detached";
     }
     return this._dbg;
   },
 
   get globalDebugObject() {
+    if (!this._parent.window) {
+      return null;
+    }
     return this.dbg.makeGlobalObjectReference(this._parent.window);
   },
 
   get state() {
     return this._state;
   },
 
   get attached() {
@@ -1671,17 +1674,18 @@ ThreadActor.prototype = {
       decrementGripDepth: () => this._gripDepth--,
       createValueGrip: v => createValueGrip(v, this._pausePool,
         this.pauseObjectGrip),
       sources: () => this.sources,
       createEnvironmentActor: (env, pool) =>
         this.createEnvironmentActor(env, pool),
       promote: () => this.threadObjectGrip(actor),
       isThreadLifetimePool: () =>
-        actor.registeredPool !== this.threadLifetimePool
+        actor.registeredPool !== this.threadLifetimePool,
+      getGlobalDebugObject: () => this.globalDebugObject
     });
     aPool.addActor(actor);
     aPool.objectActors.set(aValue, actor);
     return actor.grip();
   },
 
   /**
    * Create a grip for the given debuggee object with a pause lifetime.
--- a/toolkit/devtools/server/actors/webconsole.js
+++ b/toolkit/devtools/server/actors/webconsole.js
@@ -300,16 +300,20 @@ WebConsoleActor.prototype =
    * The Web Console Commands names cache.
    * @private
    * @type array
    */
   _webConsoleCommandsCache: null,
 
   actorPrefix: "console",
 
+  get globalDebugObject() {
+    return this.parentActor.threadActor.globalDebugObject;
+  },
+
   grip: function WCA_grip()
   {
     return { actor: this.actorID };
   },
 
   hasNativeConsoleAPI: function WCA_hasNativeConsoleAPI(aWindow) {
     let isNative = false;
     try {
@@ -445,17 +449,18 @@ WebConsoleActor.prototype =
   {
     let actor = new ObjectActor(aObject, {
       getGripDepth: () => this._gripDepth,
       incrementGripDepth: () => this._gripDepth++,
       decrementGripDepth: () => this._gripDepth--,
       createValueGrip: v => this.createValueGrip(v),
       sources: () => DevToolsUtils.reportException("WebConsoleActor",
         Error("sources not yet implemented")),
-      createEnvironmentActor: (env) => this.createEnvironmentActor(env)
+      createEnvironmentActor: (env) => this.createEnvironmentActor(env),
+      getGlobalDebugObject: () => this.globalDebugObject
     });
     aPool.addActor(actor);
     return actor.grip();
   },
 
   /**
    * Create a grip for the given string.
    *
--- a/toolkit/devtools/server/tests/unit/head_dbg.js
+++ b/toolkit/devtools/server/tests/unit/head_dbg.js
@@ -70,19 +70,19 @@ function findTab(tabs, title) {
   return null;
 }
 
 function attachTab(client, tab) {
   dump("Attaching to tab with title '" + tab.title + "'.\n");
   return rdpRequest(client, client.attachTab, tab.actor);
 }
 
-function waitForNewSource(client, url) {
+function waitForNewSource(threadClient, url) {
   dump("Waiting for new source with url '" + url + "'.\n");
-  return waitForEvent(client, "newSource", function (packet) {
+  return waitForEvent(threadClient, "newSource", function (packet) {
     return packet.source.url === url;
   });
 }
 
 function attachThread(tabClient, options = {}) {
   dump("Attaching to thread.\n");
   return rdpRequest(tabClient, tabClient.attachThread, options);
 }
--- a/toolkit/devtools/server/tests/unit/test_get-executable-lines-source-map.js
+++ b/toolkit/devtools/server/tests/unit/test_get-executable-lines-source-map.js
@@ -26,17 +26,17 @@ function run_test() {
       }
     );
   });
 
   do_test_pending();
 }
 
 function test_executable_lines() {
-  gClient.addOneTimeListener("newSource", function _onNewSource(evt, packet) {
+  gThreadClient.addOneTimeListener("newSource", function _onNewSource(evt, packet) {
     do_check_eq(evt, "newSource");
 
     gThreadClient.getSources(function ({error, sources}) {
       do_check_true(!error);
       let source = gThreadClient.source(sources[0]);
       source.getExecutableLines(function(lines){
         do_check_true(arrays_equal([1, 2, 4, 6], lines));
         finishClient(gClient);
--- a/toolkit/devtools/server/tests/unit/test_get-executable-lines.js
+++ b/toolkit/devtools/server/tests/unit/test_get-executable-lines.js
@@ -26,17 +26,17 @@ function run_test() {
       }
     );
   });
 
   do_test_pending();
 }
 
 function test_executable_lines() {
-  gClient.addOneTimeListener("newSource", function _onNewSource(evt, packet) {
+  gThreadClient.addOneTimeListener("newSource", function _onNewSource(evt, packet) {
     do_check_eq(evt, "newSource");
 
     gThreadClient.getSources(function ({error, sources}) {
       do_check_true(!error);
       let source = gThreadClient.source(sources[0]);
       source.getExecutableLines(function(lines){
         do_check_true(arrays_equal([2, 3, 5, 6, 7, 8, 12, 14, 16], lines));
         finishClient(gClient);
@@ -47,9 +47,9 @@ function test_executable_lines() {
   let code = readFile("sourcemapped.js");
 
   Components.utils.evalInSandbox(code, gDebuggee, "1.8",
     SOURCE_MAPPED_FILE, 1);
 }
 
 function arrays_equal(a,b) {
   return !(a<b || b<a);
-}
\ No newline at end of file
+}
--- a/toolkit/devtools/server/tests/unit/test_new_source-01.js
+++ b/toolkit/devtools/server/tests/unit/test_new_source-01.js
@@ -20,17 +20,17 @@ function run_test()
       test_simple_new_source();
     });
   });
   do_test_pending();
 }
 
 function test_simple_new_source()
 {
-  gClient.addOneTimeListener("newSource", function (aEvent, aPacket) {
+  gThreadClient.addOneTimeListener("newSource", function (aEvent, aPacket) {
     do_check_eq(aEvent, "newSource");
     do_check_eq(aPacket.type, "newSource");
     do_check_true(!!aPacket.source);
     do_check_true(!!aPacket.source.url.match(/test_new_source-01.js$/));
 
     finishClient(gClient);
   });
 
--- a/toolkit/devtools/server/tests/unit/test_setBreakpoint-on-column-with-no-offsets-at-end-of-line.js
+++ b/toolkit/devtools/server/tests/unit/test_setBreakpoint-on-column-with-no-offsets-at-end-of-line.js
@@ -16,17 +16,17 @@ function run_test() {
     yield connect(client);
 
     let { tabs } = yield listTabs(client);
     let tab = findTab(tabs, "test");
     let [, tabClient] = yield attachTab(client, tab);
     let [, threadClient] = yield attachThread(tabClient);
     yield resume(threadClient);
 
-    let promise = waitForNewSource(client, SOURCE_URL);
+    let promise = waitForNewSource(threadClient, SOURCE_URL);
     loadSubScript(SOURCE_URL, global);
     let { source } = yield promise;
     let sourceClient = threadClient.source(source);
 
     let location = { line: 4, column: 23 };
     let [packet, breakpointClient] = yield setBreakpoint(sourceClient, location);
     do_check_true(packet.isPending);
     do_check_false("actualLocation" in packet);
--- a/toolkit/devtools/server/tests/unit/test_setBreakpoint-on-column-with-no-offsets-at-end-of-script.js
+++ b/toolkit/devtools/server/tests/unit/test_setBreakpoint-on-column-with-no-offsets-at-end-of-script.js
@@ -16,17 +16,17 @@ function run_test() {
     yield connect(client);
 
     let { tabs } = yield listTabs(client);
     let tab = findTab(tabs, "test");
     let [, tabClient] = yield attachTab(client, tab);
     let [, threadClient] = yield attachThread(tabClient);
     yield resume(threadClient);
 
-    let promise = waitForNewSource(client, SOURCE_URL);
+    let promise = waitForNewSource(threadClient, SOURCE_URL);
     loadSubScript(SOURCE_URL, global);
     let { source } = yield promise;
     let sourceClient = threadClient.source(source);
 
     let location = { line: 4, column: 38 };
     let [packet, breakpointClient] = yield setBreakpoint(sourceClient, location);
     do_check_false(packet.isPending);
     do_check_true("actualLocation" in packet);
--- a/toolkit/devtools/server/tests/unit/test_setBreakpoint-on-column-with-no-offsets.js
+++ b/toolkit/devtools/server/tests/unit/test_setBreakpoint-on-column-with-no-offsets.js
@@ -16,17 +16,17 @@ function run_test() {
     yield connect(client);
 
     let { tabs } = yield listTabs(client);
     let tab = findTab(tabs, "test");
     let [, tabClient] = yield attachTab(client, tab);
     let [, threadClient] = yield attachThread(tabClient);
     yield resume(threadClient);
 
-    let promise = waitForNewSource(client, SOURCE_URL);
+    let promise = waitForNewSource(threadClient, SOURCE_URL);
     loadSubScript(SOURCE_URL, global);
     let { source } = yield promise;
     let sourceClient = threadClient.source(source);
 
     let location = { line: 4, column: 17 };
     let [packet, breakpointClient] = yield setBreakpoint(sourceClient, location);
     do_check_false(packet.isPending);
     do_check_true("actualLocation" in packet);
--- a/toolkit/devtools/server/tests/unit/test_setBreakpoint-on-column.js
+++ b/toolkit/devtools/server/tests/unit/test_setBreakpoint-on-column.js
@@ -16,17 +16,17 @@ function run_test() {
     yield connect(client);
 
     let { tabs } = yield listTabs(client);
     let tab = findTab(tabs, "test");
     let [, tabClient] = yield attachTab(client, tab);
     let [, threadClient] = yield attachThread(tabClient);
     yield resume(threadClient);
 
-    let promise = waitForNewSource(client, SOURCE_URL);
+    let promise = waitForNewSource(threadClient, SOURCE_URL);
     loadSubScript(SOURCE_URL, global);
     let { source } = yield promise;
     let sourceClient = threadClient.source(source);
 
     let location = { line: 4, column: 17 };
     let [packet, breakpointClient] = yield setBreakpoint(sourceClient, location);
     do_check_false(packet.isPending);
     do_check_false("actualLocation" in packet);
--- a/toolkit/devtools/server/tests/unit/test_setBreakpoint-on-line-with-multiple-offsets.js
+++ b/toolkit/devtools/server/tests/unit/test_setBreakpoint-on-line-with-multiple-offsets.js
@@ -17,17 +17,17 @@ function run_test() {
 
     let { tabs } = yield listTabs(client);
     let tab = findTab(tabs, "test");
     let [, tabClient] = yield attachTab(client, tab);
 
     let [, threadClient] = yield attachThread(tabClient);
     yield resume(threadClient);
 
-    let promise = waitForNewSource(client, SOURCE_URL);
+    let promise = waitForNewSource(threadClient, SOURCE_URL);
     loadSubScript(SOURCE_URL, global);
     let { source } = yield promise;
     let sourceClient = threadClient.source(source);
 
     let location = { line: 4 };
     let [packet, breakpointClient] = yield setBreakpoint(sourceClient, location);
     do_check_false(packet.isPending);
     do_check_false("actualLocation" in packet);
--- a/toolkit/devtools/server/tests/unit/test_setBreakpoint-on-line-with-multiple-statements.js
+++ b/toolkit/devtools/server/tests/unit/test_setBreakpoint-on-line-with-multiple-statements.js
@@ -17,17 +17,17 @@ function run_test() {
 
     let { tabs } = yield listTabs(client);
     let tab = findTab(tabs, "test");
     let [, tabClient] = yield attachTab(client, tab);
 
     let [, threadClient] = yield attachThread(tabClient);
     yield resume(threadClient);
 
-    let promise = waitForNewSource(client, SOURCE_URL);
+    let promise = waitForNewSource(threadClient, SOURCE_URL);
     loadSubScript(SOURCE_URL, global);
     let { source } = yield promise;
     let sourceClient = threadClient.source(source);
 
     let location = { line: 4 };
     let [packet, breakpointClient] = yield setBreakpoint(sourceClient, location);
     do_check_false(packet.isPending);
     do_check_false("actualLocation" in packet);
--- a/toolkit/devtools/server/tests/unit/test_setBreakpoint-on-line-with-no-offsets-at-end-of-script.js
+++ b/toolkit/devtools/server/tests/unit/test_setBreakpoint-on-line-with-no-offsets-at-end-of-script.js
@@ -16,17 +16,17 @@ function run_test() {
     yield connect(client);
 
     let { tabs } = yield listTabs(client);
     let tab = findTab(tabs, "test");
     let [, tabClient] = yield attachTab(client, tab);
     let [, threadClient] = yield attachThread(tabClient);
     yield resume(threadClient);
 
-    let promise = waitForNewSource(client, SOURCE_URL);
+    let promise = waitForNewSource(threadClient, SOURCE_URL);
     loadSubScript(SOURCE_URL, global);
     let { source } = yield promise;
     let sourceClient = threadClient.source(source);
 
     let location = { line: 7 };
     let [packet, breakpointClient] = yield setBreakpoint(sourceClient, location);
     do_check_false(packet.isPending); // NOTE: Change this when bug 1148356 lands
     do_check_true("actualLocation" in packet);
--- a/toolkit/devtools/server/tests/unit/test_setBreakpoint-on-line-with-no-offsets.js
+++ b/toolkit/devtools/server/tests/unit/test_setBreakpoint-on-line-with-no-offsets.js
@@ -16,17 +16,17 @@ function run_test() {
     yield connect(client);
 
     let { tabs } = yield listTabs(client);
     let tab = findTab(tabs, "test");
     let [, tabClient] = yield attachTab(client, tab);
     let [, threadClient] = yield attachThread(tabClient);
     yield resume(threadClient);
 
-    let promise = waitForNewSource(client, SOURCE_URL);
+    let promise = waitForNewSource(threadClient, SOURCE_URL);
     loadSubScript(SOURCE_URL, global);
     let { source } = yield promise;
     let sourceClient = threadClient.source(source);
 
     let location = { line: 5 };
     let [packet, breakpointClient] = yield setBreakpoint(sourceClient, location);
     do_check_false(packet.isPending);
     do_check_true("actualLocation" in packet);
--- a/toolkit/devtools/server/tests/unit/test_setBreakpoint-on-line.js
+++ b/toolkit/devtools/server/tests/unit/test_setBreakpoint-on-line.js
@@ -17,17 +17,17 @@ function run_test() {
 
     let { tabs } = yield listTabs(client);
     let tab = findTab(tabs, "test");
     let [, tabClient] = yield attachTab(client, tab);
 
     let [, threadClient] = yield attachThread(tabClient);
     yield resume(threadClient);
 
-    let promise = waitForNewSource(client, SOURCE_URL);
+    let promise = waitForNewSource(threadClient, SOURCE_URL);
     loadSubScript(SOURCE_URL, global);
     let { source } = yield promise;
     let sourceClient = threadClient.source(source);
 
     let location = { line: 5 };
     let [packet, breakpointClient] = yield setBreakpoint(sourceClient, location);
     do_check_false(packet.isPending);
     do_check_false("actualLocation" in packet);
--- a/toolkit/devtools/server/tests/unit/test_sourcemaps-01.js
+++ b/toolkit/devtools/server/tests/unit/test_sourcemaps-01.js
@@ -28,17 +28,17 @@ function run_test()
 function test_simple_source_map()
 {
   // Because we are source mapping, we should be notified of a.js, b.js, and
   // c.js as sources, and shouldn't receive abc.js or test_sourcemaps-01.js.
   let expectedSources = new Set(["http://example.com/www/js/a.js",
                                  "http://example.com/www/js/b.js",
                                  "http://example.com/www/js/c.js"]);
 
-  gClient.addListener("newSource", function _onNewSource(aEvent, aPacket) {
+  gThreadClient.addListener("newSource", function _onNewSource(aEvent, aPacket) {
     do_check_eq(aEvent, "newSource");
     do_check_eq(aPacket.type, "newSource");
     do_check_true(!!aPacket.source);
 
     do_check_true(expectedSources.has(aPacket.source.url),
                   "The source url should be one of our original sources.");
     expectedSources.delete(aPacket.source.url);
 
--- a/toolkit/devtools/server/tests/unit/test_sourcemaps-03.js
+++ b/toolkit/devtools/server/tests/unit/test_sourcemaps-03.js
@@ -89,22 +89,22 @@ function testBreakpointMapping(aName, aC
 function test_simple_source_map()
 {
   let expectedSources = new Set([
     "http://example.com/www/js/a.js",
     "http://example.com/www/js/b.js",
     "http://example.com/www/js/c.js"
   ]);
 
-  gClient.addListener("newSource", function _onNewSource(aEvent, aPacket) {
+  gThreadClient.addListener("newSource", function _onNewSource(aEvent, aPacket) {
     expectedSources.delete(aPacket.source.url);
     if (expectedSources.size > 0) {
       return;
     }
-    gClient.removeListener("newSource", _onNewSource);
+    gThreadClient.removeListener("newSource", _onNewSource);
 
     testBreakpointMapping("a", function () {
       testBreakpointMapping("b", function () {
         testBreakpointMapping("c", function () {
           finishClient(gClient);
         });
       });
     });
--- a/toolkit/devtools/server/tests/unit/test_sourcemaps-04.js
+++ b/toolkit/devtools/server/tests/unit/test_sourcemaps-04.js
@@ -22,17 +22,17 @@ function run_test()
       test_absolute_source_map();
     });
   });
   do_test_pending();
 }
 
 function test_absolute_source_map()
 {
-  gClient.addOneTimeListener("newSource", function _onNewSource(aEvent, aPacket) {
+  gThreadClient.addOneTimeListener("newSource", function _onNewSource(aEvent, aPacket) {
     do_check_eq(aEvent, "newSource");
     do_check_eq(aPacket.type, "newSource");
     do_check_true(!!aPacket.source);
 
     do_check_true(aPacket.source.url.indexOf("sourcemapped.coffee") !== -1,
                   "The new source should be a coffee file.");
     do_check_eq(aPacket.source.url.indexOf("sourcemapped.js"), -1,
                 "The new source should not be a js file.");
--- a/toolkit/devtools/server/tests/unit/test_sourcemaps-05.js
+++ b/toolkit/devtools/server/tests/unit/test_sourcemaps-05.js
@@ -22,17 +22,17 @@ function run_test()
       test_relative_source_map();
     });
   });
   do_test_pending();
 }
 
 function test_relative_source_map()
 {
-  gClient.addOneTimeListener("newSource", function _onNewSource(aEvent, aPacket) {
+  gThreadClient.addOneTimeListener("newSource", function _onNewSource(aEvent, aPacket) {
     do_check_eq(aEvent, "newSource");
     do_check_eq(aPacket.type, "newSource");
     do_check_true(!!aPacket.source);
 
     do_check_true(aPacket.source.url.indexOf("sourcemapped.coffee") !== -1,
                   "The new source should be a coffee file.");
     do_check_eq(aPacket.source.url.indexOf("sourcemapped.js"), -1,
                 "The new source should not be a js file.");
--- a/toolkit/devtools/server/tests/unit/test_sourcemaps-06.js
+++ b/toolkit/devtools/server/tests/unit/test_sourcemaps-06.js
@@ -25,21 +25,21 @@ function run_test()
   });
   do_test_pending();
 }
 
 function test_source_content()
 {
   let numNewSources = 0;
 
-  gClient.addListener("newSource", function _onNewSource(aEvent, aPacket) {
+  gThreadClient.addListener("newSource", function _onNewSource(aEvent, aPacket) {
     if (++numNewSources !== 3) {
       return;
     }
-    gClient.removeListener("newSource", _onNewSource);
+    gThreadClient.removeListener("newSource", _onNewSource);
 
     gThreadClient.getSources(function (aResponse) {
       do_check_true(!aResponse.error, "Should not get an error");
 
       testContents(aResponse.sources, 0, (timesCalled) => {
         do_check_eq(timesCalled, 3);
         finishClient(gClient);
       });
--- a/toolkit/devtools/server/tests/unit/test_sourcemaps-07.js
+++ b/toolkit/devtools/server/tests/unit/test_sourcemaps-07.js
@@ -24,17 +24,17 @@ function run_test()
   });
   do_test_pending();
 }
 
 function test_cached_original_sources()
 {
   writeFile("temp.js", "initial content");
 
-  gClient.addOneTimeListener("newSource", onNewSource);
+  gThreadClient.addOneTimeListener("newSource", onNewSource);
 
   let node = new SourceNode(1, 0,
                             getFileUrl("temp.js"),
                             "function funcFromTemp() {}\n");
   let { code, map } = node.toStringWithSourceMap({
     file: "abc.js"
   });
   code += "//# sourceMappingURL=data:text/json;base64," + btoa(map.toString());
--- a/toolkit/devtools/server/tests/unit/test_sourcemaps-08.js
+++ b/toolkit/devtools/server/tests/unit/test_sourcemaps-08.js
@@ -23,17 +23,17 @@ function run_test()
       test_source_maps();
     });
   });
   do_test_pending();
 }
 
 function test_source_maps()
 {
-  gClient.addOneTimeListener("newSource", function (aEvent, aPacket) {
+  gThreadClient.addOneTimeListener("newSource", function (aEvent, aPacket) {
     let sourceClient = gThreadClient.source(aPacket.source);
     sourceClient.source(function ({error, source}) {
       do_check_true(!error, "should be able to grab the source");
       do_check_eq(source, "foo",
                   "Should load the source from the sourcesContent field");
       finishClient(gClient);
     });
   });
--- a/toolkit/devtools/server/tests/unit/test_sourcemaps-09.js
+++ b/toolkit/devtools/server/tests/unit/test_sourcemaps-09.js
@@ -24,17 +24,17 @@ function run_test()
   });
   do_test_pending();
 }
 
 function test_minified()
 {
   let newSourceFired = false;
 
-  gClient.addOneTimeListener("newSource", function _onNewSource(aEvent, aPacket) {
+  gThreadClient.addOneTimeListener("newSource", function _onNewSource(aEvent, aPacket) {
     do_check_eq(aEvent, "newSource");
     do_check_eq(aPacket.type, "newSource");
     do_check_true(!!aPacket.source);
 
     do_check_eq(aPacket.source.url, "http://example.com/foo.js",
                 "The new source should be foo.js");
     do_check_eq(aPacket.source.url.indexOf("foo.min.js"), -1,
                 "The new source should not be the minified file");
--- a/toolkit/devtools/server/tests/unit/test_sourcemaps-13.js
+++ b/toolkit/devtools/server/tests/unit/test_sourcemaps-13.js
@@ -72,17 +72,17 @@ function setup_new_code() {
                             "function temporary2() {}\n");
   let { code, map } = node.toStringWithSourceMap({
     file: getFileUrl(TEMP_GENERATED_SOURCE, true)
   });
 
   code += "\n//# sourceMappingURL=" + getFileUrl(MAP_FILE_NAME, true);
   writeFile(MAP_FILE_NAME, map.toString());
 
-  gClient.addOneTimeListener("newSource", test_new_sources);
+  gThreadClient.addOneTimeListener("newSource", test_new_sources);
   Cu.evalInSandbox(code,
                    gDebuggee,
                    "1.8",
                    getFileUrl(TEMP_GENERATED_SOURCE, true),
                    1);
 }
 
 function test_new_sources() {
--- a/toolkit/devtools/server/tests/unit/testactors.js
+++ b/toolkit/devtools/server/tests/unit/testactors.js
@@ -90,17 +90,17 @@ function TestTabActor(aConnection, aGlob
   });
 }
 
 TestTabActor.prototype = {
   constructor: TestTabActor,
   actorPrefix: "TestTabActor",
 
   get window() {
-    return { wrappedJSObject: this._global };
+    return this._global;
   },
 
   get url() {
     return this._global.__name;
   },
 
   get sources() {
     if (!this._sources) {